diff --git a/.env b/.env index 55f47e18df..00d48ed6a2 100644 --- a/.env +++ b/.env @@ -10,13 +10,16 @@ NEXT_PUBLIC_API_BASE_URL=${API_BASE_URL} NEXT_PUBLIC_API_DOCS_URL=http://prowler-api:8080/api/v1/docs AUTH_TRUST_HOST=true UI_PORT=3000 -# Temp URL for feeds need to use actual -RSS_FEED_URL=https://prowler.com/blog/rss # openssl rand -base64 32 AUTH_SECRET="N/c6mnaS5+SWq81+819OrzQZlmx1Vxtp/orjttJSmw8=" # Google Tag Manager ID NEXT_PUBLIC_GOOGLE_TAG_MANAGER_ID="" +#### Code Review Configuration #### +# Enable Claude Code standards validation on pre-push hook +# Set to 'true' to validate changes against AGENTS.md standards via Claude Code +# Set to 'false' to skip validation +CODE_REVIEW_ENABLED=true #### Prowler API Configuration #### PROWLER_API_VERSION="stable" @@ -29,6 +32,14 @@ POSTGRES_ADMIN_PASSWORD=postgres POSTGRES_USER=prowler POSTGRES_PASSWORD=postgres POSTGRES_DB=prowler_db +# Read replica settings (optional) +# POSTGRES_REPLICA_HOST=postgres-db +# POSTGRES_REPLICA_PORT=5432 +# POSTGRES_REPLICA_USER=prowler +# POSTGRES_REPLICA_PASSWORD=postgres +# POSTGRES_REPLICA_DB=prowler_db +# POSTGRES_REPLICA_MAX_ATTEMPTS=3 +# POSTGRES_REPLICA_RETRY_BASE_DELAY=0.5 # Celery-Prowler task settings TASK_RETRY_DELAY_SECONDS=0.1 @@ -85,55 +96,23 @@ DJANGO_CACHE_MAX_AGE=3600 DJANGO_STALE_WHILE_REVALIDATE=60 DJANGO_MANAGE_DB_PARTITIONS=True # openssl genrsa -out private.pem 2048 -DJANGO_TOKEN_SIGNING_KEY="-----BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDs4e+kt7SnUJek -6V5r9zMGzXCoU5qnChfPiqu+BgANyawz+MyVZPs6RCRfeo6tlCknPQtOziyXYM2I -7X+qckmuzsjqp8+u+o1mw3VvUuJew5k2SQLPYwsiTzuFNVJEOgRo3hywGiGwS2iv -/5nh2QAl7fq2qLqZEXQa5+/xJlQggS1CYxOJgggvLyra50QZlBvPve/AxKJ/EV/Q -irWTZU5lLNI8sH2iZR05vQeBsxZ0dCnGMT+vGl+cGkqrvzQzKsYbDmabMcfTYhYi -78fpv6A4uharJFHayypYBjE39PwhMyyeycrNXlpm1jpq+03HgmDuDMHydk1tNwuT -nEC7m7iNAgMBAAECggEAA2m48nJcJbn9SVi8bclMwKkWmbJErOnyEGEy2sTK3Of+ -NWx9BB0FmqAPNxn0ss8K7cANKOhDD7ZLF9E2MO4/HgfoMKtUzHRbM7MWvtEepldi -nnvcUMEgULD8Dk4HnqiIVjt3BdmGiTv46OpBnRWrkSBV56pUL+7msZmMZTjUZvh2 -ZWv0+I3gtDIjo2Zo/FiwDV7CfwRjJarRpYUj/0YyuSA4FuOUYl41WAX1I301FKMH -xo3jiAYi1s7IneJ16OtPpOA34Wg5F6ebm/UO0uNe+iD4kCXKaZmxYQPh5tfB0Qa3 -qj1T7GNpFNyvtG7VVdauhkb8iu8X/wl6PCwbg0RCKQKBgQD9HfpnpH0lDlHMRw9K -X7Vby/1fSYy1BQtlXFEIPTN/btJ/asGxLmAVwJ2HAPXWlrfSjVAH7CtVmzN7v8oj -HeIHfeSgoWEu1syvnv2AMaYSo03UjFFlfc/GUxF7DUScRIhcJUPCP8jkAROz9nFv -DByNjUL17Q9r43DmDiRsy0IFqQKBgQDvlJ9Uhl+Sp7gRgKYwa/IG0+I4AduAM+Gz -Dxbm52QrMGMTjaJFLmLHBUZ/ot+pge7tZZGws8YR8ufpyMJbMqPjxhIvRRa/p1Tf -E3TQPW93FMsHUvxAgY3MV5MzXFPhlNAKb+akP/RcXUhetGAuZKLubtDCWa55ZQuL -wj2OS+niRQKBgE7K8zUqNi6/22S8xhy/2GPgB1qPObbsABUofK0U6CAGLo6te+gc -6Jo84IyzFtQbDNQFW2Fr+j1m18rw9AqkdcUhQndiZS9AfG07D+zFB86LeWHt4DS4 -ymIRX8Kvaak/iDcu/n3Mf0vCrhB6aetImObTj4GgrwlFvtJOmrYnO8EpAoGAIXXP -Xt25gWD9OyyNiVu6HKwA/zN7NYeJcRmdaDhO7B1A6R0x2Zml4AfjlbXoqOLlvLAf -zd79vcoAC82nH1eOPiSOq51plPDI0LMF8IN0CtyTkn1Lj7LIXA6rF1RAvtOqzppc -SvpHpZK9pcRpXnFdtBE0BMDDtl6fYzCIqlP94UUCgYEAnhXbAQMF7LQifEm34Dx8 -BizRMOKcqJGPvbO2+Iyt50O5X6onU2ITzSV1QHtOvAazu+B1aG9pEuBFDQ+ASxEu -L9ruJElkOkb/o45TSF6KCsHd55ReTZ8AqnRjf5R+lyzPqTZCXXb8KTcRvWT4zQa3 -VxyT2PnaSqEcexWUy4+UXoQ= ------END PRIVATE KEY-----" +DJANGO_TOKEN_SIGNING_KEY="" # openssl rsa -in private.pem -pubout -out public.pem -DJANGO_TOKEN_VERIFYING_KEY="-----BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7OHvpLe0p1CXpOlea/cz -Bs1wqFOapwoXz4qrvgYADcmsM/jMlWT7OkQkX3qOrZQpJz0LTs4sl2DNiO1/qnJJ -rs7I6qfPrvqNZsN1b1LiXsOZNkkCz2MLIk87hTVSRDoEaN4csBohsEtor/+Z4dkA -Je36tqi6mRF0Gufv8SZUIIEtQmMTiYIILy8q2udEGZQbz73vwMSifxFf0Iq1k2VO -ZSzSPLB9omUdOb0HgbMWdHQpxjE/rxpfnBpKq780MyrGGw5mmzHH02IWIu/H6b+g -OLoWqyRR2ssqWAYxN/T8ITMsnsnKzV5aZtY6avtNx4Jg7gzB8nZNbTcLk5xAu5u4 -jQIDAQAB ------END PUBLIC KEY-----" +DJANGO_TOKEN_VERIFYING_KEY="" # openssl rand -base64 32 DJANGO_SECRETS_ENCRYPTION_KEY="oE/ltOhp/n1TdbHjVmzcjDPLcLA41CVI/4Rk+UB5ESc=" DJANGO_BROKER_VISIBILITY_TIMEOUT=86400 DJANGO_SENTRY_DSN= +DJANGO_THROTTLE_TOKEN_OBTAIN=50/minute # Sentry settings SENTRY_ENVIRONMENT=local SENTRY_RELEASE=local +NEXT_PUBLIC_SENTRY_ENVIRONMENT=${SENTRY_ENVIRONMENT} + #### Prowler release version #### -NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v5.10.0 +NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v5.12.2 # Social login credentials SOCIAL_GOOGLE_OAUTH_CALLBACK_URL="${AUTH_URL}/api/auth/callback/google" @@ -152,3 +131,12 @@ LANGSMITH_TRACING=false LANGSMITH_ENDPOINT="https://api.smith.langchain.com" LANGSMITH_API_KEY="" LANGCHAIN_PROJECT="" + +# RSS Feed Configuration +# Multiple feed sources can be configured as a JSON array (must be valid JSON, no trailing commas) +# Each source requires: id, name, type (github_releases|blog|custom), url, and enabled flag +# IMPORTANT: Must be a single line with valid JSON (no newlines, no trailing commas) +# Example with one source: +RSS_FEED_SOURCES='[{"id":"prowler-releases","name":"Prowler Releases","type":"github_releases","url":"https://github.com/prowler-cloud/prowler/releases.atom","enabled":true}]' +# Example with multiple sources (no trailing comma after last item): +# RSS_FEED_SOURCES='[{"id":"prowler-releases","name":"Prowler Releases","type":"github_releases","url":"https://github.com/prowler-cloud/prowler/releases.atom","enabled":true},{"id":"prowler-blog","name":"Prowler Blog","type":"blog","url":"https://prowler.com/blog/rss","enabled":false}]' 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..3e3510496f 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 or is already in our [Public Roadmap](https://roadmap.prowler.com/roadmap) + 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..790f3ef0e6 --- /dev/null +++ b/.github/actions/setup-python-poetry/action.yml @@ -0,0 +1,93 @@ +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 (prowler repo only) + if: github.event_name == 'pull_request' && github.base_ref == 'master' && github.repository == 'prowler-cloud/prowler' + 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 poetry.lock with latest Prowler commit + if: github.repository_owner == 'prowler-cloud' && github.repository != 'prowler-cloud/prowler' + 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 SDK resolved_reference to latest commit (prowler repo on push) + if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'prowler-cloud/prowler' + 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 (prowler repo only) + if: github.repository == 'prowler-cloud/prowler' + 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 + + - name: Update Prowler Cloud API Client + if: github.repository_owner == 'prowler-cloud' && github.repository != 'prowler-cloud/prowler' + shell: bash + working-directory: ${{ inputs.working-directory }} + run: | + poetry remove prowler-cloud-api-client + poetry add ./prowler-cloud-api-client diff --git a/.github/actions/slack-notification/README.md b/.github/actions/slack-notification/README.md new file mode 100644 index 0000000000..ce8843df2a --- /dev/null +++ b/.github/actions/slack-notification/README.md @@ -0,0 +1,198 @@ +# Slack Notification Action + +A generic and flexible GitHub composite action for sending Slack notifications using JSON template files. Supports both standalone messages and message updates, with automatic status detection. + +## Features + +- **Template-based**: All messages use JSON template files for consistency +- **Automatic status detection**: Pass `step-outcome` to auto-calculate success/failure +- **Message updates**: Supports updating existing messages (using `chat.update`) +- **Simple API**: Clean and minimal interface +- **Reusable**: Use across all workflows and scenarios +- **Maintainable**: Centralized message templates + +## Use Cases + +1. **Container releases**: Track push start and completion with automatic status +2. **Deployments**: Track deployment progress with rich Block Kit formatting +3. **Custom notifications**: Any scenario where you need to notify Slack + +## Inputs + +| Input | Description | Required | Default | +|-------|-------------|----------|---------| +| `slack-bot-token` | Slack bot token for authentication | Yes | - | +| `payload-file-path` | Path to JSON file with the Slack message payload | Yes | - | +| `update-ts` | Message timestamp to update (leave empty for new messages) | No | `''` | +| `step-outcome` | Step outcome for automatic status detection (sets STATUS_EMOJI and STATUS_TEXT env vars) | No | `''` | + +## Outputs + +| Output | Description | +|--------|-------------| +| `ts` | Timestamp of the Slack message (use for updates) | + +## Usage Examples + +### Example 1: Container Release with Automatic Status Detection + +Using JSON template files with automatic status detection: + +```yaml +# Send start notification +- name: Notify container push started + if: github.event_name == 'release' + uses: ./.github/actions/slack-notification + env: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + COMPONENT: API + RELEASE_TAG: ${{ env.RELEASE_TAG }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + payload-file-path: "./.github/scripts/slack-messages/container-release-started.json" + +# Do the work +- name: Build and push container + if: github.event_name == 'release' + id: container-push + uses: docker/build-push-action@... + with: + push: true + tags: ... + +# Send completion notification with automatic status detection +- name: Notify container push completed + if: github.event_name == 'release' && always() + uses: ./.github/actions/slack-notification + env: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + COMPONENT: API + RELEASE_TAG: ${{ env.RELEASE_TAG }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + payload-file-path: "./.github/scripts/slack-messages/container-release-completed.json" + step-outcome: ${{ steps.container-push.outcome }} +``` + +**Benefits:** +- No status calculation needed in workflow +- Reusable template files +- Clean and concise +- Automatic `STATUS_EMOJI` and `STATUS_TEXT` env vars set by action +- Consistent message format across all workflows + +### Example 2: Deployment with Message Update Pattern + +```yaml +# Send initial deployment message +- name: Notify deployment started + id: slack-start + uses: ./.github/actions/slack-notification + env: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + COMPONENT: API + ENVIRONMENT: PRODUCTION + COMMIT_HASH: ${{ github.sha }} + VERSION_DEPLOYED: latest + GITHUB_ACTOR: ${{ github.actor }} + GITHUB_WORKFLOW: ${{ github.workflow }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + payload-file-path: "./.github/scripts/slack-messages/deployment-started.json" + +# Run deployment +- name: Deploy + id: deploy + run: terraform apply -auto-approve + +# Determine additional status variables +- name: Determine deployment status + if: always() + id: deploy-status + run: | + if [[ "${{ steps.deploy.outcome }}" == "success" ]]; then + echo "STATUS_COLOR=28a745" >> $GITHUB_ENV + echo "STATUS=Completed" >> $GITHUB_ENV + else + echo "STATUS_COLOR=fc3434" >> $GITHUB_ENV + echo "STATUS=Failed" >> $GITHUB_ENV + fi + +# Update the same message with final status +- name: Update deployment notification + if: always() + uses: ./.github/actions/slack-notification + env: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + MESSAGE_TS: ${{ steps.slack-start.outputs.ts }} + COMPONENT: API + ENVIRONMENT: PRODUCTION + COMMIT_HASH: ${{ github.sha }} + VERSION_DEPLOYED: latest + GITHUB_ACTOR: ${{ github.actor }} + GITHUB_WORKFLOW: ${{ github.workflow }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + STATUS: ${{ env.STATUS }} + STATUS_COLOR: ${{ env.STATUS_COLOR }} + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + update-ts: ${{ steps.slack-start.outputs.ts }} + payload-file-path: "./.github/scripts/slack-messages/deployment-completed.json" + step-outcome: ${{ steps.deploy.outcome }} +``` + +## Automatic Status Detection + +When you provide `step-outcome` input, the action automatically sets these environment variables: + +| Outcome | STATUS_EMOJI | STATUS_TEXT | +|---------|--------------|-------------| +| success | `[āœ“]` | `completed successfully!` | +| failure | `[āœ—]` | `failed` | + +These variables are then available in your payload template files. + +## Template File Format + +All template files must be valid JSON and support environment variable substitution. Example: + +```json +{ + "channel": "$SLACK_CHANNEL_ID", + "text": "$STATUS_EMOJI $COMPONENT container release $RELEASE_TAG push $STATUS_TEXT <$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID|View run>" +} +``` + +See available templates in [`.github/scripts/slack-messages/`](../../scripts/slack-messages/). + +## Requirements + +- Slack Bot Token with scopes: `chat:write`, `chat:write.public` +- Slack Channel ID where messages will be posted +- JSON template files for your messages + +## Benefits + +- **Consistency**: All notifications use standardized templates +- **Automatic status handling**: No need to calculate success/failure in workflows +- **Clean workflows**: Minimal boilerplate code +- **Reusable templates**: One template for all components +- **Easy to maintain**: Change template once, applies everywhere +- **Version controlled**: All message formats in git + +## Related Resources + +- [Slack Block Kit Builder](https://app.slack.com/block-kit-builder) +- [Slack API Method Documentation](https://docs.slack.dev/tools/slack-github-action/sending-techniques/sending-data-slack-api-method/) +- [Message templates documentation](../../scripts/slack-messages/README.md) diff --git a/.github/actions/slack-notification/action.yml b/.github/actions/slack-notification/action.yml new file mode 100644 index 0000000000..1427fed3e0 --- /dev/null +++ b/.github/actions/slack-notification/action.yml @@ -0,0 +1,74 @@ +name: 'Slack Notification' +description: 'Generic action to send Slack notifications with optional message updates and automatic status detection' +inputs: + slack-bot-token: + description: 'Slack bot token for authentication' + required: true + payload-file-path: + description: 'Path to JSON file with the Slack message payload' + required: true + update-ts: + description: 'Message timestamp to update (only for updates, leave empty for new messages)' + required: false + default: '' + step-outcome: + description: 'Outcome of a step to determine status (success/failure) - automatically sets STATUS_TEXT and STATUS_COLOR env vars' + required: false + default: '' +outputs: + ts: + description: 'Timestamp of the Slack message' + value: ${{ steps.slack-notification.outputs.ts }} +runs: + using: 'composite' + steps: + - name: Determine status + id: status + shell: bash + run: | + if [[ "${{ inputs.step-outcome }}" == "success" ]]; then + echo "STATUS_TEXT=Completed" >> $GITHUB_ENV + echo "STATUS_COLOR=#6aa84f" >> $GITHUB_ENV + elif [[ "${{ inputs.step-outcome }}" == "failure" ]]; then + echo "STATUS_TEXT=Failed" >> $GITHUB_ENV + echo "STATUS_COLOR=#fc3434" >> $GITHUB_ENV + else + # No outcome provided - pending/in progress state + echo "STATUS_COLOR=#dbab09" >> $GITHUB_ENV + fi + + - name: Send Slack notification (new message) + if: inputs.update-ts == '' + id: slack-notification-post + uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1 + env: + SLACK_PAYLOAD_FILE_PATH: ${{ inputs.payload-file-path }} + with: + method: chat.postMessage + token: ${{ inputs.slack-bot-token }} + payload-file-path: ${{ inputs.payload-file-path }} + payload-templated: true + errors: true + + - name: Update Slack notification + if: inputs.update-ts != '' + id: slack-notification-update + uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1 + env: + SLACK_PAYLOAD_FILE_PATH: ${{ inputs.payload-file-path }} + with: + method: chat.update + token: ${{ inputs.slack-bot-token }} + payload-file-path: ${{ inputs.payload-file-path }} + payload-templated: true + errors: true + + - name: Set output + id: slack-notification + shell: bash + run: | + if [[ "${{ inputs.update-ts }}" == "" ]]; then + echo "ts=${{ steps.slack-notification-post.outputs.ts }}" >> $GITHUB_OUTPUT + else + echo "ts=${{ inputs.update-ts }}" >> $GITHUB_OUTPUT + fi diff --git a/.github/actions/trivy-scan/action.yml b/.github/actions/trivy-scan/action.yml new file mode 100644 index 0000000000..e3c2404748 --- /dev/null +++ b/.github/actions/trivy-scan/action.yml @@ -0,0 +1,164 @@ +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: Cache Trivy vulnerability database + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: ~/.cache/trivy + key: trivy-db-${{ runner.os }}-${{ github.run_id }} + restore-keys: | + trivy-db-${{ runner.os }}- + + - 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' + scanners: 'vuln' + timeout: '5m' + + - name: Run Trivy vulnerability scan (SARIF) + if: inputs.upload-sarif == 'true' && github.event_name == 'push' + 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' + scanners: 'vuln' + timeout: '5m' + + - name: Upload Trivy results to GitHub Security tab + if: inputs.upload-sarif == 'true' && github.event_name == 'push' + uses: github/codeql-action/upload-sarif@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5 + with: + sarif_file: 'trivy-results.sarif' + category: 'trivy-container' + + - 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/codeql/sdk-codeql-config.yml b/.github/codeql/sdk-codeql-config.yml index 7982398f42..4c933ecbda 100644 --- a/.github/codeql/sdk-codeql-config.yml +++ b/.github/codeql/sdk-codeql-config.yml @@ -1,4 +1,18 @@ -name: "SDK - CodeQL Config" +name: 'SDK: CodeQL Config' +paths: + - 'prowler/' + paths-ignore: - - "api/" - - "ui/" + - 'api/' + - 'ui/' + - 'dashboard/' + - 'mcp_server/' + - 'tests/**' + - 'util/**' + - 'contrib/**' + - 'examples/**' + - 'prowler/**/__pycache__/**' + - 'prowler/**/*.md' + +queries: + - uses: security-and-quality diff --git a/.github/codeql/ui-codeql-config.yml b/.github/codeql/ui-codeql-config.yml index fa4f80cae5..2eb4eebe87 100644 --- a/.github/codeql/ui-codeql-config.yml +++ b/.github/codeql/ui-codeql-config.yml @@ -1,3 +1,17 @@ -name: "UI - CodeQL Config" +name: 'UI: CodeQL Config' paths: - - "ui/" + - 'ui/' + +paths-ignore: + - 'ui/node_modules/**' + - 'ui/.next/**' + - 'ui/out/**' + - 'ui/tests/**' + - 'ui/**/*.test.ts' + - 'ui/**/*.test.tsx' + - 'ui/**/*.spec.ts' + - 'ui/**/*.spec.tsx' + - 'ui/**/*.md' + +queries: + - uses: security-and-quality diff --git a/.github/labeler.yml b/.github/labeler.yml index 688992e7e6..9a56691628 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -37,6 +37,16 @@ provider/iac: - any-glob-to-any-file: "prowler/providers/iac/**" - any-glob-to-any-file: "tests/providers/iac/**" +provider/mongodbatlas: + - changed-files: + - any-glob-to-any-file: "prowler/providers/mongodbatlas/**" + - any-glob-to-any-file: "tests/providers/mongodbatlas/**" + +provider/oci: + - changed-files: + - any-glob-to-any-file: "prowler/providers/oraclecloud/**" + - any-glob-to-any-file: "tests/providers/oraclecloud/**" + github_actions: - changed-files: - any-glob-to-any-file: ".github/workflows/*" @@ -52,11 +62,13 @@ mutelist: - any-glob-to-any-file: "prowler/providers/azure/lib/mutelist/**" - any-glob-to-any-file: "prowler/providers/gcp/lib/mutelist/**" - any-glob-to-any-file: "prowler/providers/kubernetes/lib/mutelist/**" + - any-glob-to-any-file: "prowler/providers/mongodbatlas/lib/mutelist/**" - any-glob-to-any-file: "tests/lib/mutelist/**" - any-glob-to-any-file: "tests/providers/aws/lib/mutelist/**" - any-glob-to-any-file: "tests/providers/azure/lib/mutelist/**" - any-glob-to-any-file: "tests/providers/gcp/lib/mutelist/**" - any-glob-to-any-file: "tests/providers/kubernetes/lib/mutelist/**" + - any-glob-to-any-file: "tests/providers/mongodbatlas/lib/mutelist/**" integration/s3: - changed-files: @@ -103,6 +115,10 @@ component/ui: - changed-files: - any-glob-to-any-file: "ui/**" +component/mcp-server: + - changed-files: + - any-glob-to-any-file: "mcp_server/**" + compliance: - changed-files: - any-glob-to-any-file: "prowler/compliance/**" @@ -112,3 +128,7 @@ compliance: review-django-migrations: - changed-files: - any-glob-to-any-file: "api/src/backend/api/migrations/**" + +metadata-review: + - changed-files: + - any-glob-to-any-file: "**/*.metadata.json" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 94122d8349..497c4d6214 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -22,6 +22,13 @@ Please add a detailed description of how to review this PR. - [ ] Review if is needed to change the [Readme.md](https://github.com/prowler-cloud/prowler/blob/master/README.md) - [ ] Ensure new entries are added to [CHANGELOG.md](https://github.com/prowler-cloud/prowler/blob/master/prowler/CHANGELOG.md), if applicable. +#### UI +- [ ] All issue/task requirements work as expected on the UI +- [ ] Screenshots/Video of the functionality flow (if applicable) - Mobile (X < 640px) +- [ ] Screenshots/Video of the functionality flow (if applicable) - Table (640px > X < 1024px) +- [ ] Screenshots/Video of the functionality flow (if applicable) - Desktop (X > 1024px) +- [ ] Ensure new entries are added to [CHANGELOG.md](https://github.com/prowler-cloud/prowler/blob/master/ui/CHANGELOG.md), if applicable. + #### API - [ ] Verify if API specs need to be regenerated. - [ ] Check if version updates are required (e.g., specs, Poetry, etc.). diff --git a/.github/scripts/slack-messages/README.md b/.github/scripts/slack-messages/README.md new file mode 100644 index 0000000000..e7fcf00fdd --- /dev/null +++ b/.github/scripts/slack-messages/README.md @@ -0,0 +1,462 @@ +# Slack Message Templates + +This directory contains reusable message templates for Slack notifications sent from GitHub Actions workflows. + +## Usage + +These JSON templates are used with the `slackapi/slack-github-action` using the Slack API method (`chat.postMessage` and `chat.update`). All templates support rich Block Kit formatting and message updates. + +### Available Templates + +**Container Releases** +- `container-release-started.json`: Simple one-line notification when container push starts +- `container-release-completed.json`: Simple one-line notification when container release completes + +**Deployments** +- `deployment-started.json`: Deployment start notification with Block Kit formatting +- `deployment-completed.json`: Deployment completion notification (updates the start message) + +All templates use the Slack API method and require a Slack Bot Token. + +## Setup Requirements + +1. Create a Slack App (or use existing) +2. Add Bot Token Scopes: `chat:write`, `chat:write.public` +3. Install the app to your workspace +4. Get the Bot Token from OAuth & Permissions page +5. Add secrets: + - `SLACK_BOT_TOKEN`: Your bot token + - `SLACK_CHANNEL_ID`: The channel ID where messages will be posted + +Reference: [Sending data using a Slack API method](https://docs.slack.dev/tools/slack-github-action/sending-techniques/sending-data-slack-api-method/) + +## Environment Variables + +### Required Secrets (GitHub Secrets) +- `SLACK_BOT_TOKEN`: Passed as `token` parameter to the action (not as env variable) +- `SLACK_CHANNEL_ID`: Used in payload as env variable + +### Container Release Variables (configured as env) +- `COMPONENT`: Component name (e.g., "API", "SDK", "UI", "MCP") +- `RELEASE_TAG` / `PROWLER_VERSION`: The release tag or version being deployed +- `GITHUB_SERVER_URL`: Provided by GitHub context +- `GITHUB_REPOSITORY`: Provided by GitHub context +- `GITHUB_RUN_ID`: Provided by GitHub context +- `STATUS_EMOJI`: Status symbol (calculated: `[āœ“]` for success, `[āœ—]` for failure) +- `STATUS_TEXT`: Status text (calculated: "completed successfully!" or "failed") + +### Deployment Variables (configured as env) +- `COMPONENT`: Component name (e.g., "API", "SDK", "UI", "MCP") +- `ENVIRONMENT`: Environment name (e.g., "DEVELOPMENT", "PRODUCTION") +- `COMMIT_HASH`: Commit hash being deployed +- `VERSION_DEPLOYED`: Version being deployed +- `GITHUB_ACTOR`: User who triggered the workflow +- `GITHUB_WORKFLOW`: Workflow name +- `GITHUB_SERVER_URL`: Provided by GitHub context +- `GITHUB_REPOSITORY`: Provided by GitHub context +- `GITHUB_RUN_ID`: Provided by GitHub context + +All other variables (MESSAGE_TS, STATUS, STATUS_COLOR, STATUS_EMOJI, etc.) are calculated internally within the workflow and should NOT be configured as environment variables. + +## Example Workflow Usage + +### Using the Generic Slack Notification Action (Recommended) + +**Recommended approach**: Use the generic reusable action `.github/actions/slack-notification` which provides maximum flexibility: + +#### Example 1: Container Release (Start + Completion) + +```yaml +# Send start notification +- name: Notify container push started + if: github.event_name == 'release' + uses: ./.github/actions/slack-notification + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + payload: | + { + "channel": "${{ secrets.SLACK_CHANNEL_ID }}", + "text": "API container release ${{ env.RELEASE_TAG }} push started... <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View run>" + } + +# Build and push container +- name: Build and push container + if: github.event_name == 'release' + id: container-push + uses: docker/build-push-action@... + with: + push: true + tags: ... + +# Calculate status +- name: Determine push status + if: github.event_name == 'release' && always() + id: push-status + run: | + if [[ "${{ steps.container-push.outcome }}" == "success" ]]; then + echo "emoji=[āœ“]" >> $GITHUB_OUTPUT + echo "text=completed successfully!" >> $GITHUB_OUTPUT + else + echo "emoji=[āœ—]" >> $GITHUB_OUTPUT + echo "text=failed" >> $GITHUB_OUTPUT + fi + +# Send completion notification +- name: Notify container push completed + if: github.event_name == 'release' && always() + uses: ./.github/actions/slack-notification + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + payload: | + { + "channel": "${{ secrets.SLACK_CHANNEL_ID }}", + "text": "${{ steps.push-status.outputs.emoji }} API container release ${{ env.RELEASE_TAG }} push ${{ steps.push-status.outputs.text }} <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View run>" + } +``` + +#### Example 2: Simple One-Time Message + +```yaml +- name: Send notification + uses: ./.github/actions/slack-notification + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + payload: | + { + "channel": "${{ secrets.SLACK_CHANNEL_ID }}", + "text": "Deployment completed successfully!" + } +``` + +#### Example 3: Deployment with Message Update Pattern + +```yaml +# Send initial deployment message +- name: Notify deployment started + id: slack-start + uses: ./.github/actions/slack-notification + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + payload: | + { + "channel": "${{ secrets.SLACK_CHANNEL_ID }}", + "text": "API deployment to PRODUCTION started", + "attachments": [ + { + "color": "dbab09", + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "API | Deployment to PRODUCTION" + } + }, + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "*Status:*\nIn Progress" + } + ] + } + ] + } + ] + } + +# Run deployment +- name: Deploy + id: deploy + run: terraform apply -auto-approve + +# Calculate status +- name: Determine status + if: always() + id: status + run: | + if [[ "${{ steps.deploy.outcome }}" == "success" ]]; then + echo "color=28a745" >> $GITHUB_OUTPUT + echo "emoji=[āœ“]" >> $GITHUB_OUTPUT + echo "status=Completed" >> $GITHUB_OUTPUT + else + echo "color=fc3434" >> $GITHUB_OUTPUT + echo "emoji=[āœ—]" >> $GITHUB_OUTPUT + echo "status=Failed" >> $GITHUB_OUTPUT + fi + +# Update the same message with final status +- name: Update deployment notification + if: always() + uses: ./.github/actions/slack-notification + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + update-ts: ${{ steps.slack-start.outputs.ts }} + payload: | + { + "channel": "${{ secrets.SLACK_CHANNEL_ID }}", + "ts": "${{ steps.slack-start.outputs.ts }}", + "text": "${{ steps.status.outputs.emoji }} API deployment to PRODUCTION ${{ steps.status.outputs.status }}", + "attachments": [ + { + "color": "${{ steps.status.outputs.color }}", + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "API | Deployment to PRODUCTION" + } + }, + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "*Status:*\n${{ steps.status.outputs.emoji }} ${{ steps.status.outputs.status }}" + } + ] + } + ] + } + ] + } +``` + +**Benefits of using the generic action:** +- Maximum flexibility: Build any payload you need directly in the workflow +- No template files needed: Everything inline +- Supports all scenarios: one-time messages, start/update patterns, rich Block Kit +- Easy to customize per use case +- Generic: Works for containers, deployments, or any notification type + +For more details, see [Slack Notification Action](../../actions/slack-notification/README.md). + +### Using Message Templates (Alternative Approach) + +Simple one-line notifications for container releases: + +```yaml +# Step 1: Notify when push starts +- name: Notify container push started + if: github.event_name == 'release' + uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1 + env: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + COMPONENT: API + RELEASE_TAG: ${{ env.RELEASE_TAG }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + with: + method: chat.postMessage + token: ${{ secrets.SLACK_BOT_TOKEN }} + payload-file-path: "./.github/scripts/slack-messages/container-release-started.json" + +# Step 2: Build and push container +- name: Build and push container + id: container-push + uses: docker/build-push-action@... + with: + push: true + tags: ... + +# Step 3: Determine push status +- name: Determine push status + if: github.event_name == 'release' && always() + id: push-status + run: | + if [[ "${{ steps.container-push.outcome }}" == "success" ]]; then + echo "status-emoji=[āœ“]" >> $GITHUB_OUTPUT + echo "status-text=completed successfully!" >> $GITHUB_OUTPUT + else + echo "status-emoji=[āœ—]" >> $GITHUB_OUTPUT + echo "status-text=failed" >> $GITHUB_OUTPUT + fi + +# Step 4: Notify when push completes (success or failure) +- name: Notify container push completed + if: github.event_name == 'release' && always() + uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1 + env: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + COMPONENT: API + RELEASE_TAG: ${{ env.RELEASE_TAG }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + STATUS_EMOJI: ${{ steps.push-status.outputs.status-emoji }} + STATUS_TEXT: ${{ steps.push-status.outputs.status-text }} + with: + method: chat.postMessage + token: ${{ secrets.SLACK_BOT_TOKEN }} + payload-file-path: "./.github/scripts/slack-messages/container-release-completed.json" +``` + +### Deployment with Update Pattern + +For deployments that start with one message and update it with the final status: + +```yaml +# Step 1: Send deployment start notification +- name: Notify Deployment Start + id: slack-notification-start + uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1 + env: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + COMPONENT: API + ENVIRONMENT: PRODUCTION + COMMIT_HASH: ${{ github.sha }} + VERSION_DEPLOYED: latest + GITHUB_ACTOR: ${{ github.actor }} + GITHUB_WORKFLOW: ${{ github.workflow }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + with: + method: chat.postMessage + token: ${{ secrets.SLACK_BOT_TOKEN }} + payload-file-path: "./.github/scripts/slack-messages/deployment-started.json" + +# Step 2: Run your deployment steps +- name: Terraform Plan + id: terraform-plan + run: terraform plan + +- name: Terraform Apply + id: terraform-apply + run: terraform apply -auto-approve + +# Step 3: Determine status (calculated internally, not configured) +- name: Determine Status + if: always() + id: determine-status + run: | + if [[ "${{ steps.terraform-apply.outcome }}" == "success" ]]; then + echo "status=Completed" >> $GITHUB_OUTPUT + echo "status-color=28a745" >> $GITHUB_OUTPUT + echo "status-emoji=[āœ“]" >> $GITHUB_OUTPUT + echo "plan-emoji=[āœ“]" >> $GITHUB_OUTPUT + echo "apply-emoji=[āœ“]" >> $GITHUB_OUTPUT + elif [[ "${{ steps.terraform-plan.outcome }}" == "failure" || "${{ steps.terraform-apply.outcome }}" == "failure" ]]; then + echo "status=Failed" >> $GITHUB_OUTPUT + echo "status-color=fc3434" >> $GITHUB_OUTPUT + echo "status-emoji=[āœ—]" >> $GITHUB_OUTPUT + if [[ "${{ steps.terraform-plan.outcome }}" == "failure" ]]; then + echo "plan-emoji=[āœ—]" >> $GITHUB_OUTPUT + else + echo "plan-emoji=[āœ“]" >> $GITHUB_OUTPUT + fi + if [[ "${{ steps.terraform-apply.outcome }}" == "failure" ]]; then + echo "apply-emoji=[āœ—]" >> $GITHUB_OUTPUT + else + echo "apply-emoji=[āœ“]" >> $GITHUB_OUTPUT + fi + else + echo "status=Failed" >> $GITHUB_OUTPUT + echo "status-color=fc3434" >> $GITHUB_OUTPUT + echo "status-emoji=[āœ—]" >> $GITHUB_OUTPUT + echo "plan-emoji=[?]" >> $GITHUB_OUTPUT + echo "apply-emoji=[?]" >> $GITHUB_OUTPUT + fi + +# Step 4: Update the same Slack message (using calculated values) +- name: Notify Deployment Result + if: always() + uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1 + env: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + MESSAGE_TS: ${{ steps.slack-notification-start.outputs.ts }} + COMPONENT: API + ENVIRONMENT: PRODUCTION + COMMIT_HASH: ${{ github.sha }} + VERSION_DEPLOYED: latest + GITHUB_ACTOR: ${{ github.actor }} + GITHUB_WORKFLOW: ${{ github.workflow }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + STATUS: ${{ steps.determine-status.outputs.status }} + STATUS_COLOR: ${{ steps.determine-status.outputs.status-color }} + STATUS_EMOJI: ${{ steps.determine-status.outputs.status-emoji }} + PLAN_EMOJI: ${{ steps.determine-status.outputs.plan-emoji }} + APPLY_EMOJI: ${{ steps.determine-status.outputs.apply-emoji }} + TERRAFORM_PLAN_OUTCOME: ${{ steps.terraform-plan.outcome }} + TERRAFORM_APPLY_OUTCOME: ${{ steps.terraform-apply.outcome }} + with: + method: chat.update + token: ${{ secrets.SLACK_BOT_TOKEN }} + payload-file-path: "./.github/scripts/slack-messages/deployment-completed.json" +``` + +**Note**: Variables like `STATUS`, `STATUS_COLOR`, `STATUS_EMOJI`, `PLAN_EMOJI`, `APPLY_EMOJI` are calculated by the `determine-status` step based on the outcomes of previous steps. They should NOT be manually configured. + +## Key Features + +### Benefits of Using Slack API Method + +- **Rich Block Kit Formatting**: Full support for Slack's Block Kit including headers, sections, fields, colors, and attachments +- **Message Updates**: Update the same message instead of posting multiple messages (using `chat.update` with `ts`) +- **Consistent Experience**: Same look and feel as Prowler Cloud notifications +- **Flexible**: Easy to customize message appearance by editing JSON templates + +### Differences from Webhook Method + +| Feature | webhook-trigger | Slack API (chat.postMessage) | +|---------|-----------------|------------------------------| +| Setup | Workflow Builder webhook | Slack Bot Token + Channel ID | +| Formatting | Plain text/simple | Full Block Kit support | +| Message Update | No | Yes (with chat.update) | +| Authentication | Webhook URL | Bot Token | +| Scopes Required | None | chat:write, chat:write.public | + +## Message Appearance + +### Container Release (Simple One-Line) + +**Start message:** +``` +API container release 4.5.0 push started... View run +``` + +**Completion message (success):** +``` +[āœ“] API container release 4.5.0 push completed successfully! View run +``` + +**Completion message (failure):** +``` +[āœ—] API container release 4.5.0 push failed View run +``` + +All messages are simple one-liners with a clickable "View run" link. The completion message adapts to show success `[āœ“]` or failure `[āœ—]` based on the outcome of the container push. + +### Deployment Start +- Header: Component and environment +- Yellow bar (color: `dbab09`) +- Status: In Progress +- Details: Commit, version, actor, workflow +- Link: Direct link to deployment run + +### Deployment Completion +- Header: Component and environment +- Green bar for success (color: `28a745`) / Red bar for failure (color: `fc3434`) +- Status: [āœ“] Completed or [āœ—] Failed +- Details: All deployment info plus terraform outcomes +- Link: Direct link to deployment run + +## Adding New Templates + +1. Create a new JSON file with Block Kit structure +2. Use environment variable placeholders (e.g., `$VAR_NAME`) +3. Include `channel` and `text` fields (required) +4. Add `blocks` or `attachments` for rich formatting +5. For update templates, include `ts` field as `$MESSAGE_TS` +6. Document the template in this README +7. Reference it in your workflow using `payload-file-path` + +## Reference + +- [Slack Block Kit Builder](https://app.slack.com/block-kit-builder) +- [Slack API Method Documentation](https://docs.slack.dev/tools/slack-github-action/sending-techniques/sending-data-slack-api-method/) diff --git a/.github/scripts/slack-messages/container-release-completed.json b/.github/scripts/slack-messages/container-release-completed.json new file mode 100644 index 0000000000..c1fc147191 --- /dev/null +++ b/.github/scripts/slack-messages/container-release-completed.json @@ -0,0 +1,17 @@ +{ + "channel": "${{ env.SLACK_CHANNEL_ID }}", + "attachments": [ + { + "color": "${{ env.STATUS_COLOR }}", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "*Status:*\n${{ env.STATUS_TEXT }}\n\n${{ env.COMPONENT }} container release ${{ env.RELEASE_TAG }} push ${{ env.STATUS_TEXT }}\n\n<${{ env.GITHUB_SERVER_URL }}/${{ env.GITHUB_REPOSITORY }}/actions/runs/${{ env.GITHUB_RUN_ID }}|View run>" + } + } + ] + } + ] +} diff --git a/.github/scripts/slack-messages/container-release-started.json b/.github/scripts/slack-messages/container-release-started.json new file mode 100644 index 0000000000..f67129e3ba --- /dev/null +++ b/.github/scripts/slack-messages/container-release-started.json @@ -0,0 +1,17 @@ +{ + "channel": "${{ env.SLACK_CHANNEL_ID }}", + "attachments": [ + { + "color": "${{ env.STATUS_COLOR }}", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "*Status:*\nStarted\n\n${{ env.COMPONENT }} container release ${{ env.RELEASE_TAG }} push started...\n\n<${{ env.GITHUB_SERVER_URL }}/${{ env.GITHUB_REPOSITORY }}/actions/runs/${{ env.GITHUB_RUN_ID }}|View run>" + } + } + ] + } + ] +} 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-build-lint-push-containers.yml b/.github/workflows/api-build-lint-push-containers.yml deleted file mode 100644 index 0fe6d4a0b9..0000000000 --- a/.github/workflows/api-build-lint-push-containers.yml +++ /dev/null @@ -1,115 +0,0 @@ -name: API - Build and Push containers - -on: - push: - branches: - - "master" - paths: - - "api/**" - - "prowler/**" - - ".github/workflows/api-build-lint-push-containers.yml" - - # Uncomment the code below to test this action on PRs - # pull_request: - # branches: - # - "master" - # paths: - # - "api/**" - # - ".github/workflows/api-build-lint-push-containers.yml" - - release: - types: [published] - -env: - # Tags - LATEST_TAG: latest - RELEASE_TAG: ${{ github.event.release.tag_name }} - STABLE_TAG: stable - - WORKING_DIRECTORY: ./api - - # Container Registries - PROWLERCLOUD_DOCKERHUB_REPOSITORY: prowlercloud - PROWLERCLOUD_DOCKERHUB_IMAGE: prowler-api - -jobs: - repository-check: - name: Repository check - runs-on: ubuntu-latest - outputs: - is_repo: ${{ steps.repository_check.outputs.is_repo }} - steps: - - name: Repository check - id: repository_check - working-directory: /tmp - run: | - if [[ ${{ github.repository }} == "prowler-cloud/prowler" ]] - then - echo "is_repo=true" >> "${GITHUB_OUTPUT}" - else - echo "This action only runs for prowler-cloud/prowler" - echo "is_repo=false" >> "${GITHUB_OUTPUT}" - fi - - # Build Prowler OSS container - container-build-push: - needs: repository-check - if: needs.repository-check.outputs.is_repo == 'true' - runs-on: ubuntu-latest - defaults: - run: - working-directory: ${{ env.WORKING_DIRECTORY }} - - steps: - - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Set short git commit SHA - id: vars - run: | - shortSha=$(git rev-parse --short ${{ github.sha }}) - echo "SHORT_SHA=${shortSha}" >> $GITHUB_ENV - - - name: Login to DockerHub - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - - name: Build and push container image (latest) - # Comment the following line for testing - if: github.event_name == 'push' - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: ${{ env.WORKING_DIRECTORY }} - # Set push: false for testing - push: true - tags: | - ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.LATEST_TAG }} - ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.SHORT_SHA }} - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Build and push container image (release) - if: github.event_name == 'release' - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: ${{ env.WORKING_DIRECTORY }} - push: true - tags: | - ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.RELEASE_TAG }} - ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.STABLE_TAG }} - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Trigger deployment - if: github.event_name == 'push' - uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3.0.0 - with: - token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} - repository: ${{ secrets.CLOUD_DISPATCH }} - event-type: prowler-api-deploy - client-payload: '{"sha": "${{ github.sha }}", "short_sha": "${{ env.SHORT_SHA }}"}' diff --git a/.github/workflows/api-code-quality.yml b/.github/workflows/api-code-quality.yml new file mode 100644 index 0000000000..a9dddaa3aa --- /dev/null +++ b/.github/workflows/api-code-quality.yml @@ -0,0 +1,71 @@ +name: 'API: Code Quality' + +on: + push: + branches: + - 'master' + - 'v5.*' + pull_request: + branches: + - 'master' + - 'v5.*' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + API_WORKING_DIR: ./api + +jobs: + api-code-quality: + runs-on: ubuntu-latest + timeout-minutes: 30 + 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: Check for API changes + id: check-changes + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + api/** + .github/workflows/api-code-quality.yml + files_ignore: | + api/docs/** + api/README.md + api/CHANGELOG.md + + - name: Setup Python with Poetry + if: steps.check-changes.outputs.any_changed == 'true' + uses: ./.github/actions/setup-python-poetry + with: + python-version: ${{ matrix.python-version }} + working-directory: ./api + + - name: Poetry check + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry check --lock + + - name: Ruff lint + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run ruff check . --exclude contrib + + - name: Ruff format + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run ruff format --check . --exclude contrib + + - name: Pylint + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run pylint --disable=W,C,R,E -j 0 -rn -sn src/ diff --git a/.github/workflows/api-codeql.yml b/.github/workflows/api-codeql.yml index 8d0a81c8b6..16ea82538e 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 + api-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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5 - with: - languages: ${{ matrix.language }} - config-file: ./.github/codeql/api-codeql-config.yml + - name: Initialize CodeQL + uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + with: + languages: ${{ matrix.language }} + config-file: ./.github/codeql/api-codeql-config.yml - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5 - with: - category: "/language:${{matrix.language}}" + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + with: + category: '/language:${{ matrix.language }}' diff --git a/.github/workflows/api-container-build-push.yml b/.github/workflows/api-container-build-push.yml new file mode 100644 index 0000000000..3b3b4a4222 --- /dev/null +++ b/.github/workflows/api-container-build-push.yml @@ -0,0 +1,177 @@ +name: 'API: Container Build and Push' + +on: + push: + branches: + - 'master' + paths: + - 'api/**' + - 'prowler/**' + - '.github/workflows/api-build-lint-push-containers.yml' + release: + types: + - 'published' + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +env: + # Tags + LATEST_TAG: latest + RELEASE_TAG: ${{ github.event.release.tag_name }} + STABLE_TAG: stable + WORKING_DIRECTORY: ./api + + # Container registries + PROWLERCLOUD_DOCKERHUB_REPOSITORY: prowlercloud + PROWLERCLOUD_DOCKERHUB_IMAGE: prowler-api + +jobs: + setup: + if: github.repository == 'prowler-cloud/prowler' + runs-on: ubuntu-latest + timeout-minutes: 5 + outputs: + short-sha: ${{ steps.set-short-sha.outputs.short-sha }} + steps: + - name: Calculate short SHA + id: set-short-sha + run: echo "short-sha=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT + + container-build-push: + needs: setup + runs-on: ${{ matrix.runner }} + strategy: + matrix: + include: + - platform: linux/amd64 + runner: ubuntu-latest + arch: amd64 + - platform: linux/arm64 + runner: ubuntu-24.04-arm + arch: arm64 + timeout-minutes: 30 + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Login to DockerHub + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Build and push API container for ${{ matrix.arch }} + if: github.event_name == 'push' || github.event_name == 'release' + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: ${{ env.WORKING_DIRECTORY }} + push: true + platforms: ${{ matrix.platform }} + tags: | + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-${{ matrix.arch }} + cache-from: type=gha,scope=${{ matrix.arch }} + cache-to: type=gha,mode=max,scope=${{ matrix.arch }} + + - name: Notify container push started + if: github.event_name == 'release' + uses: ./.github/actions/slack-notification + env: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_PLATFORM_DEPLOYMENTS }} + COMPONENT: API + RELEASE_TAG: ${{ env.RELEASE_TAG }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + payload-file-path: "./.github/scripts/slack-messages/container-release-started.json" + + - name: Notify container push completed + if: github.event_name == 'release' && always() + uses: ./.github/actions/slack-notification + env: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_PLATFORM_DEPLOYMENTS }} + COMPONENT: API + RELEASE_TAG: ${{ env.RELEASE_TAG }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + payload-file-path: "./.github/scripts/slack-messages/container-release-completed.json" + step-outcome: ${{ steps.container-push.outcome }} + + # Create and push multi-architecture manifest + create-manifest: + needs: [setup, container-build-push] + if: github.event_name == 'push' || github.event_name == 'release' + runs-on: ubuntu-latest + + steps: + - name: Login to DockerHub + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Create and push manifests for push event + if: github.event_name == 'push' + run: | + docker buildx imagetools create \ + -t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.LATEST_TAG }} \ + -t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }} \ + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-amd64 \ + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-arm64 + + - name: Create and push manifests for release event + if: github.event_name == 'release' + run: | + docker buildx imagetools create \ + -t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.RELEASE_TAG }} \ + -t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.STABLE_TAG }} \ + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-amd64 \ + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-arm64 + + - name: Install regctl + if: always() + uses: regclient/actions/regctl-installer@f61d18f46c86af724a9c804cb9ff2a6fec741c7c # main + + - name: Cleanup intermediate architecture tags + if: always() + run: | + echo "Cleaning up intermediate tags..." + regctl tag delete "${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-amd64" || true + regctl tag delete "${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-arm64" || true + echo "Cleanup completed" + + trigger-deployment: + if: github.event_name == 'push' + needs: [setup, container-build-push] + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: read + + steps: + - name: Trigger API deployment + uses: peter-evans/repository-dispatch@5fc4efd1a4797ddb68ffd0714a238564e4cc0e6f # v4.0.0 + with: + token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} + repository: ${{ secrets.CLOUD_DISPATCH }} + event-type: api-prowler-deployment + client-payload: '{"sha": "${{ github.sha }}", "short_sha": "${{ needs.setup.outputs.short-sha }}"}' diff --git a/.github/workflows/api-container-checks.yml b/.github/workflows/api-container-checks.yml new file mode 100644 index 0000000000..d069b0d5a6 --- /dev/null +++ b/.github/workflows/api-container-checks.yml @@ -0,0 +1,89 @@ +name: 'API: Container Checks' + +on: + push: + branches: + - 'master' + - 'v5.*' + pull_request: + branches: + - 'master' + - 'v5.*' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + API_WORKING_DIR: ./api + IMAGE_NAME: prowler-api + +jobs: + api-dockerfile-lint: + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Check if Dockerfile changed + id: dockerfile-changed + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: api/Dockerfile + + - name: Lint Dockerfile with Hadolint + if: steps.dockerfile-changed.outputs.any_changed == 'true' + uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0 + with: + dockerfile: api/Dockerfile + ignore: DL3013 + + api-container-build-and-scan: + 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: Check for API changes + id: check-changes + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: api/** + files_ignore: | + api/docs/** + api/README.md + api/CHANGELOG.md + + - name: Set up Docker Buildx + if: steps.check-changes.outputs.any_changed == 'true' + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Build container + if: steps.check-changes.outputs.any_changed == 'true' + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: ${{ env.API_WORKING_DIR }} + push: false + load: true + tags: ${{ env.IMAGE_NAME }}:${{ github.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Scan container with Trivy + if: github.repository == 'prowler-cloud/prowler' && steps.check-changes.outputs.any_changed == 'true' + 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/api-pull-request.yml b/.github/workflows/api-pull-request.yml deleted file mode 100644 index 339149f94b..0000000000 --- a/.github/workflows/api-pull-request.yml +++ /dev/null @@ -1,239 +0,0 @@ -name: API - Pull Request - -on: - push: - branches: - - "master" - - "v5.*" - paths: - - ".github/workflows/api-pull-request.yml" - - "api/**" - pull_request: - branches: - - "master" - - "v5.*" - paths: - - ".github/workflows/api-pull-request.yml" - - "api/**" - -env: - POSTGRES_HOST: localhost - POSTGRES_PORT: 5432 - POSTGRES_ADMIN_USER: prowler - POSTGRES_ADMIN_PASSWORD: S3cret - POSTGRES_USER: prowler_user - POSTGRES_PASSWORD: prowler - POSTGRES_DB: postgres-db - VALKEY_HOST: localhost - VALKEY_PORT: 6379 - VALKEY_DB: 0 - API_WORKING_DIR: ./api - IMAGE_NAME: prowler-api - IGNORE_FILES: | - api/docs/** - api/README.md - api/CHANGELOG.md - -jobs: - test: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.12"] - - # Service containers to run with `test` - services: - # Label used to access the service container - postgres: - image: postgres - env: - POSTGRES_HOST: ${{ env.POSTGRES_HOST }} - POSTGRES_PORT: ${{ env.POSTGRES_PORT }} - 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: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - valkey: - image: valkey/valkey:7-alpine3.19 - env: - 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: >- - --health-cmd "valkey-cli ping" - --health-interval 10s - --health-timeout 5s - --health-retries 5 - - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Test if changes are in not ignored paths - id: are-non-ignored-files-changed - uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5 - with: - files: | - api/** - .github/workflows/api-pull-request.yml - files_ignore: ${{ env.IGNORE_FILES }} - - - name: Replace @master with current branch in pyproject.toml - working-directory: ./api - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - 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 poetry.lock after the branch name change - working-directory: ./api - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry lock - - - 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' - 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: Set up Python ${{ matrix.python-version }} - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 - with: - python-version: ${{ matrix.python-version }} - cache: "poetry" - - - name: Install system dependencies for xmlsec - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - sudo apt-get update - sudo apt-get install -y libxml2-dev libxmlsec1-dev libxmlsec1-openssl pkg-config - - - 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: Upload coverage reports to Codecov - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - with: - flags: api - test-container-build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Test if changes are in not ignored paths - id: are-non-ignored-files-changed - uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5 - with: - files: api/** - files_ignore: ${{ env.IGNORE_FILES }} - - 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' - 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 - cache-from: type=gha - cache-to: type=gha,mode=max diff --git a/.github/workflows/api-security.yml b/.github/workflows/api-security.yml new file mode 100644 index 0000000000..33134ec9c9 --- /dev/null +++ b/.github/workflows/api-security.yml @@ -0,0 +1,69 @@ +name: 'API: Security' + +on: + push: + branches: + - 'master' + - 'v5.*' + pull_request: + branches: + - 'master' + - 'v5.*' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + API_WORKING_DIR: ./api + +jobs: + api-security-scans: + 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: Check for API changes + id: check-changes + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + api/** + .github/workflows/api-security.yml + files_ignore: | + api/docs/** + api/README.md + api/CHANGELOG.md + + - name: Setup Python with Poetry + if: steps.check-changes.outputs.any_changed == 'true' + uses: ./.github/actions/setup-python-poetry + with: + python-version: ${{ matrix.python-version }} + working-directory: ./api + + - name: Bandit + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run bandit -q -lll -x '*_test.py,./contrib/' -r . + + - name: Safety + if: steps.check-changes.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 + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run vulture --exclude "contrib,tests,conftest.py" --min-confidence 100 . diff --git a/.github/workflows/api-tests.yml b/.github/workflows/api-tests.yml new file mode 100644 index 0000000000..daeb79abac --- /dev/null +++ b/.github/workflows/api-tests.yml @@ -0,0 +1,107 @@ +name: 'API: Tests' + +on: + push: + branches: + - 'master' + - 'v5.*' + pull_request: + branches: + - 'master' + - 'v5.*' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + POSTGRES_HOST: localhost + POSTGRES_PORT: 5432 + POSTGRES_ADMIN_USER: prowler + POSTGRES_ADMIN_PASSWORD: S3cret + POSTGRES_USER: prowler_user + POSTGRES_PASSWORD: prowler + POSTGRES_DB: postgres-db + VALKEY_HOST: localhost + VALKEY_PORT: 6379 + VALKEY_DB: 0 + API_WORKING_DIR: ./api + +jobs: + api-tests: + runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + contents: read + strategy: + matrix: + python-version: + - '3.12' + defaults: + run: + working-directory: ./api + + services: + postgres: + image: postgres + env: + POSTGRES_HOST: ${{ env.POSTGRES_HOST }} + POSTGRES_PORT: ${{ env.POSTGRES_PORT }} + POSTGRES_USER: ${{ env.POSTGRES_USER }} + POSTGRES_PASSWORD: ${{ env.POSTGRES_PASSWORD }} + POSTGRES_DB: ${{ env.POSTGRES_DB }} + ports: + - 5432:5432 + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + valkey: + image: valkey/valkey:7-alpine3.19 + env: + VALKEY_HOST: ${{ env.VALKEY_HOST }} + VALKEY_PORT: ${{ env.VALKEY_PORT }} + VALKEY_DB: ${{ env.VALKEY_DB }} + ports: + - 6379:6379 + options: >- + --health-cmd "valkey-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Check for API changes + id: check-changes + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + api/** + .github/workflows/api-tests.yml + files_ignore: | + api/docs/** + api/README.md + api/CHANGELOG.md + + - name: Setup Python with Poetry + if: steps.check-changes.outputs.any_changed == 'true' + uses: ./.github/actions/setup-python-poetry + with: + python-version: ${{ matrix.python-version }} + working-directory: ./api + + - name: Run tests with pytest + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run pytest --cov=./src/backend --cov-report=xml src/backend + + - name: Upload coverage reports to Codecov + if: steps.check-changes.outputs.any_changed == 'true' + uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + flags: api diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 2aa0a49c09..974d919fc6 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -1,28 +1,33 @@ -name: Prowler - Automatic Backport +name: 'Tools: Backport' on: pull_request_target: - branches: ['master'] - types: ['labeled', 'closed'] + branches: + - 'master' + types: + - 'labeled' + - 'closed' + +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 +36,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' - uses: sorenlouv/backport-github-action@ad888e978060bc1b2798690dd9d03c4036560947 # v9.5.1 + - name: Backport PR + if: steps.label_check.outputs.label_check == 'success' + uses: sorenlouv/backport-github-action@516854e7c9f962b9939085c9a92ea28411d1ae90 # v10.2.0 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/build-documentation-on-pr.yml b/.github/workflows/build-documentation-on-pr.yml deleted file mode 100644 index 20553b87af..0000000000 --- a/.github/workflows/build-documentation-on-pr.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Prowler - Pull Request Documentation Link - -on: - pull_request: - branches: - - 'master' - - 'v3' - paths: - - 'docs/**' - - '.github/workflows/build-documentation-on-pr.yml' - -env: - PR_NUMBER: ${{ github.event.pull_request.number }} - -jobs: - documentation-link: - name: Documentation Link - runs-on: ubuntu-latest - steps: - - name: Find existing documentation comment - uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3.1.0 - id: find-comment - with: - issue-number: ${{ env.PR_NUMBER }} - comment-author: 'github-actions[bot]' - body-includes: '' - - - name: Create or update PR comment with the Prowler Documentation URI - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0 - with: - comment-id: ${{ steps.find-comment.outputs.comment-id }} - issue-number: ${{ env.PR_NUMBER }} - body: | - - You can check the documentation for this PR here -> [Prowler Documentation](https://prowler-prowler-docs--${{ env.PR_NUMBER }}.com.readthedocs.build/projects/prowler-open-source/en/${{ env.PR_NUMBER }}/) - edit-mode: replace diff --git a/.github/workflows/comment-label-update.yml b/.github/workflows/comment-label-update.yml new file mode 100644 index 0000000000..9bddd6a9dd --- /dev/null +++ b/.github/workflows/comment-label-update.yml @@ -0,0 +1,39 @@ +name: 'Tools: Comment Label Update' + +on: + issue_comment: + types: + - 'created' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.issue.number }} + cancel-in-progress: false + +jobs: + update-labels: + if: contains(github.event.issue.labels.*.name, 'status/awaiting-response') + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + issues: write + pull-requests: write + + steps: + - name: Remove 'status/awaiting-response' label + env: + GH_TOKEN: ${{ github.token }} + ISSUE_NUMBER: ${{ github.event.issue.number }} + run: | + echo "Removing 'status/awaiting-response' label from #$ISSUE_NUMBER" + gh api /repos/${{ github.repository }}/issues/$ISSUE_NUMBER/labels/status%2Fawaiting-response \ + -X DELETE + + - name: Add 'status/waiting-for-revision' label + env: + GH_TOKEN: ${{ github.token }} + ISSUE_NUMBER: ${{ github.event.issue.number }} + run: | + echo "Adding 'status/waiting-for-revision' label to #$ISSUE_NUMBER" + gh api /repos/${{ github.repository }}/issues/$ISSUE_NUMBER/labels \ + -X POST \ + -f labels[]='status/waiting-for-revision' diff --git a/.github/workflows/conventional-commit.yml b/.github/workflows/conventional-commit.yml index cdc3e52de5..58e1653b74 100644 --- a/.github/workflows/conventional-commit.yml +++ b/.github/workflows/conventional-commit.yml @@ -1,23 +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 - uses: agenthunt/conventional-commit-checker-action@9e552d650d0e205553ec7792d447929fc78e012b # v2.0.0 + - name: Check PR title format + uses: agenthunt/conventional-commit-checker-action@f1823f632e95a64547566dcd2c7da920e67117ad # v2.0.1 with: - pr-title-regex: '^([^\s(]+)(?:\(([^)]+)\))?: (.+)' + 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 8160c7028a..80b49e3279 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 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: fetch-depth: 0 - - name: TruffleHog OSS - uses: trufflesecurity/trufflehog@a05cf0859455b5b16317ee22d809887a4043cdf0 # v3.90.2 + + - name: Scan for secrets with TruffleHog + uses: trufflesecurity/trufflehog@b84c3d14d189e16da175e2c27fa8136603783ffc # v3.90.12 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 6507474ec8..85ccd34cc2 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -1,17 +1,92 @@ -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@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0 + - name: Apply labels to PR + uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1 + with: + sync-labels: true + + label-community: + name: Add 'community' label if the PR is from a community contributor + needs: labeler + if: github.repository == 'prowler-cloud/prowler' && github.event.action == 'opened' + runs-on: ubuntu-latest + permissions: + pull-requests: write + + steps: + - name: Check if author is org member + id: check_membership + env: + AUTHOR: ${{ github.event.pull_request.user.login }} + run: | + # Hardcoded list of prowler-cloud organization members + # This list includes members who have set their organization membership as private + ORG_MEMBERS=( + "AdriiiPRodri" + "Alan-TheGentleman" + "alejandrobailo" + "amitsharm" + "andoniaf" + "cesararroba" + "Chan9390" + "danibarranqueroo" + "HugoPBrito" + "jfagoagas" + "josemazo" + "lydiavilchez" + "mmuller88" + "MrCloudSec" + "pedrooot" + "prowler-bot" + "puchy22" + "rakan-pro" + "RosaRivasProwler" + "StylusFrost" + "toniblyx" + "vicferpoy" + ) + + echo "Checking if $AUTHOR is a member of prowler-cloud organization" + + # Check if author is in the org members list + if printf '%s\n' "${ORG_MEMBERS[@]}" | grep -q "^${AUTHOR}$"; then + echo "is_member=true" >> $GITHUB_OUTPUT + echo "$AUTHOR is an organization member" + else + echo "is_member=false" >> $GITHUB_OUTPUT + echo "$AUTHOR is not an organization member" + fi + + - name: Add community label + if: steps.check_membership.outputs.is_member == 'false' + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + GH_TOKEN: ${{ github.token }} + run: | + echo "Adding 'community' label to PR #$PR_NUMBER" + gh api /repos/${{ github.repository }}/issues/${{ github.event.number }}/labels \ + -X POST \ + -f labels[]='community' diff --git a/.github/workflows/mcp-container-build-push.yml b/.github/workflows/mcp-container-build-push.yml new file mode 100644 index 0000000000..27bc3e84e0 --- /dev/null +++ b/.github/workflows/mcp-container-build-push.yml @@ -0,0 +1,183 @@ +name: 'MCP: Container Build and Push' + +on: + push: + branches: + - 'master' + paths: + - 'mcp_server/**' + - '.github/workflows/mcp-container-build-push.yml' + release: + types: + - 'published' + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +env: + # Tags + LATEST_TAG: latest + RELEASE_TAG: ${{ github.event.release.tag_name }} + STABLE_TAG: stable + WORKING_DIRECTORY: ./mcp_server + + # Container registries + PROWLERCLOUD_DOCKERHUB_REPOSITORY: prowlercloud + PROWLERCLOUD_DOCKERHUB_IMAGE: prowler-mcp + +jobs: + setup: + if: github.repository == 'prowler-cloud/prowler' + runs-on: ubuntu-latest + timeout-minutes: 5 + outputs: + short-sha: ${{ steps.set-short-sha.outputs.short-sha }} + steps: + - name: Calculate short SHA + id: set-short-sha + run: echo "short-sha=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT + + container-build-push: + needs: setup + runs-on: ${{ matrix.runner }} + strategy: + matrix: + include: + - platform: linux/amd64 + runner: ubuntu-latest + arch: amd64 + - platform: linux/arm64 + runner: ubuntu-24.04-arm + arch: arm64 + timeout-minutes: 30 + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Login to DockerHub + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Build and push MCP container for ${{ matrix.arch }} + if: github.event_name == 'push' || github.event_name == 'release' + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: ${{ env.WORKING_DIRECTORY }} + push: true + platforms: ${{ matrix.platform }} + tags: | + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-${{ matrix.arch }} + labels: | + org.opencontainers.image.title=Prowler MCP Server + org.opencontainers.image.description=Model Context Protocol server for Prowler + org.opencontainers.image.vendor=ProwlerPro, Inc. + org.opencontainers.image.source=https://github.com/${{ github.repository }} + org.opencontainers.image.revision=${{ github.sha }} + org.opencontainers.image.created=${{ github.event_name == 'release' && github.event.release.published_at || github.event.head_commit.timestamp }} + ${{ github.event_name == 'release' && format('org.opencontainers.image.version={0}', env.RELEASE_TAG) || '' }} + cache-from: type=gha,scope=${{ matrix.arch }} + cache-to: type=gha,mode=max,scope=${{ matrix.arch }} + + - name: Notify container push started + if: github.event_name == 'release' + uses: ./.github/actions/slack-notification + env: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_PLATFORM_DEPLOYMENTS }} + COMPONENT: MCP + RELEASE_TAG: ${{ env.RELEASE_TAG }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + payload-file-path: "./.github/scripts/slack-messages/container-release-started.json" + + - name: Notify container push completed + if: github.event_name == 'release' && always() + uses: ./.github/actions/slack-notification + env: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_PLATFORM_DEPLOYMENTS }} + COMPONENT: MCP + RELEASE_TAG: ${{ env.RELEASE_TAG }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + payload-file-path: "./.github/scripts/slack-messages/container-release-completed.json" + step-outcome: ${{ steps.container-push.outcome }} + + # Create and push multi-architecture manifest + create-manifest: + needs: [setup, container-build-push] + if: github.event_name == 'push' || github.event_name == 'release' + runs-on: ubuntu-latest + + steps: + - name: Login to DockerHub + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Create and push manifests for push event + if: github.event_name == 'push' + run: | + docker buildx imagetools create \ + -t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.LATEST_TAG }} \ + -t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }} \ + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-amd64 \ + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-arm64 + + - name: Create and push manifests for release event + if: github.event_name == 'release' + run: | + docker buildx imagetools create \ + -t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.RELEASE_TAG }} \ + -t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.STABLE_TAG }} \ + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-amd64 \ + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-arm64 + + - name: Install regctl + if: always() + uses: regclient/actions/regctl-installer@main + + - name: Cleanup intermediate architecture tags + if: always() + run: | + echo "Cleaning up intermediate tags..." + regctl tag delete "${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-amd64" || true + regctl tag delete "${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-arm64" || true + echo "Cleanup completed" + + trigger-deployment: + if: github.event_name == 'push' + needs: [setup, container-build-push] + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: read + + steps: + - name: Trigger MCP deployment + uses: peter-evans/repository-dispatch@5fc4efd1a4797ddb68ffd0714a238564e4cc0e6f # v4.0.0 + with: + token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} + repository: ${{ secrets.CLOUD_DISPATCH }} + event-type: mcp-prowler-deployment + client-payload: '{"sha": "${{ github.sha }}", "short_sha": "${{ needs.setup.outputs.short-sha }}"}' diff --git a/.github/workflows/mcp-container-checks.yml b/.github/workflows/mcp-container-checks.yml new file mode 100644 index 0000000000..3310cd8c5a --- /dev/null +++ b/.github/workflows/mcp-container-checks.yml @@ -0,0 +1,87 @@ +name: 'MCP: Container Checks' + +on: + push: + branches: + - 'master' + - 'v5.*' + pull_request: + branches: + - 'master' + - 'v5.*' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + MCP_WORKING_DIR: ./mcp_server + IMAGE_NAME: prowler-mcp + +jobs: + mcp-dockerfile-lint: + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Check if Dockerfile changed + id: dockerfile-changed + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: mcp_server/Dockerfile + + - name: Lint Dockerfile with Hadolint + if: steps.dockerfile-changed.outputs.any_changed == 'true' + uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0 + with: + dockerfile: mcp_server/Dockerfile + + mcp-container-build-and-scan: + 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: Check for MCP changes + id: check-changes + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: mcp_server/** + files_ignore: | + mcp_server/README.md + mcp_server/CHANGELOG.md + + - name: Set up Docker Buildx + if: steps.check-changes.outputs.any_changed == 'true' + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Build MCP container + if: steps.check-changes.outputs.any_changed == 'true' + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: ${{ env.MCP_WORKING_DIR }} + push: false + load: true + tags: ${{ env.IMAGE_NAME }}:${{ github.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Scan MCP container with Trivy + if: github.repository == 'prowler-cloud/prowler' && steps.check-changes.outputs.any_changed == 'true' + 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/pr-check-changelog.yml b/.github/workflows/pr-check-changelog.yml new file mode 100644 index 0000000000..d1a3220402 --- /dev/null +++ b/.github/workflows/pr-check-changelog.yml @@ -0,0 +1,103 @@ +name: 'Tools: Check Changelog' + +on: + pull_request: + types: + - 'opened' + - 'synchronize' + - 'reopened' + - 'labeled' + - 'unlabeled' + branches: + - 'master' + - 'v5.*' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + check-changelog: + if: contains(github.event.pull_request.labels.*.name, 'no-changelog') == false + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + pull-requests: write + env: + MONITORED_FOLDERS: 'api ui prowler mcp_server' + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + + - name: Get changed files + id: changed-files + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + api/** + ui/** + prowler/** + mcp_server/** + + - name: Check for folder changes and changelog presence + id: check-folders + run: | + missing_changelogs="" + + # Check api folder + if [[ "${{ steps.changed-files.outputs.any_changed }}" == "true" ]]; then + for folder in $MONITORED_FOLDERS; do + # Get files changed in this folder + changed_in_folder=$(echo "${{ steps.changed-files.outputs.all_changed_files }}" | tr ' ' '\n' | grep "^${folder}/" || true) + + if [ -n "$changed_in_folder" ]; then + echo "Detected changes in ${folder}/" + + # Check if CHANGELOG.md was updated + if ! echo "$changed_in_folder" | grep -q "^${folder}/CHANGELOG.md$"; then + echo "No changelog update found for ${folder}/" + missing_changelogs="${missing_changelogs}- \`${folder}\`"$'\n' + fi + fi + done + fi + + { + echo "missing_changelogs<> $GITHUB_OUTPUT + + - name: Find existing changelog comment + if: github.event.pull_request.head.repo.full_name == github.repository + id: find-comment + uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4.0.0 + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'github-actions[bot]' + body-includes: '' + + - name: Update PR comment with changelog status + if: github.event.pull_request.head.repo.full_name == github.repository + uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0 + with: + issue-number: ${{ github.event.pull_request.number }} + comment-id: ${{ steps.find-comment.outputs.comment-id }} + edit-mode: replace + body: | + + ${{ steps.check-folders.outputs.missing_changelogs != '' && format('āš ļø **Changes detected in the following folders without a corresponding update to the `CHANGELOG.md`:** + + {0} + + Please add an entry to the corresponding `CHANGELOG.md` file to maintain a clear history of changes.', steps.check-folders.outputs.missing_changelogs) || 'āœ… All necessary `CHANGELOG.md` files have been updated.' }} + + - name: Fail if changelog is missing + if: steps.check-folders.outputs.missing_changelogs != '' + run: | + echo "::error::Missing changelog updates in some folders" + exit 1 diff --git a/.github/workflows/pr-conflict-checker.yml b/.github/workflows/pr-conflict-checker.yml index 2071dbaa78..c46fafc2d0 100644 --- a/.github/workflows/pr-conflict-checker.yml +++ b/.github/workflows/pr-conflict-checker.yml @@ -1,40 +1,40 @@ -name: Prowler - PR Conflict Checker +name: 'Tools: PR Conflict Checker' on: - pull_request: - types: - - opened - - synchronize - - reopened - branches: - - "master" - - "v5.*" pull_request_target: types: - - opened - - synchronize - - reopened + - 'opened' + - 'synchronize' + - 'reopened' branches: - - "master" - - "v5.*" + - 'master' + - 'v5.*' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + cancel-in-progress: true jobs: - conflict-checker: + check-conflicts: runs-on: ubuntu-latest + timeout-minutes: 15 permissions: contents: read pull-requests: write + issues: write steps: - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Checkout PR head + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 - name: Get changed files id: changed-files - uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5 + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 with: - files: | - ** + files: '**' - name: Check for conflict markers id: conflict-check @@ -49,10 +49,10 @@ jobs: if [ -f "$file" ]; then echo "Checking file: $file" - # Look for conflict markers - if grep -l "^<<<<<<<\|^=======\|^>>>>>>>" "$file" 2>/dev/null; then + # Look for conflict markers (more precise regex) + if grep -qE '^(<<<<<<<|=======|>>>>>>>)' "$file" 2>/dev/null; then echo "Conflict markers found in: $file" - CONFLICT_FILES="$CONFLICT_FILES$file " + CONFLICT_FILES="${CONFLICT_FILES}- \`${file}\`"$'\n' HAS_CONFLICTS=true fi fi @@ -60,107 +60,64 @@ jobs: if [ "$HAS_CONFLICTS" = true ]; then echo "has_conflicts=true" >> $GITHUB_OUTPUT - echo "conflict_files=$CONFLICT_FILES" >> $GITHUB_OUTPUT - echo "Conflict markers detected in files: $CONFLICT_FILES" + { + echo "conflict_files<> $GITHUB_OUTPUT + echo "Conflict markers detected" else echo "has_conflicts=false" >> $GITHUB_OUTPUT echo "No conflict markers found in changed files" fi - - name: Add conflict label - if: steps.conflict-check.outputs.has_conflicts == 'true' - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - with: - github-token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} - script: | - const { data: labels } = await github.rest.issues.listLabelsOnIssue({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - }); + - name: Manage conflict label + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_NUMBER: ${{ github.event.pull_request.number }} + HAS_CONFLICTS: ${{ steps.conflict-check.outputs.has_conflicts }} + run: | + LABEL_NAME="has-conflicts" - const hasConflictLabel = labels.some(label => label.name === 'has-conflicts'); + # Add or remove label based on conflict status + if [ "$HAS_CONFLICTS" = "true" ]; then + echo "Adding conflict label to PR #${PR_NUMBER}..." + gh pr edit "$PR_NUMBER" --add-label "$LABEL_NAME" --repo ${{ github.repository }} || true + else + echo "Removing conflict label from PR #${PR_NUMBER}..." + gh pr edit "$PR_NUMBER" --remove-label "$LABEL_NAME" --repo ${{ github.repository }} || true + fi - if (!hasConflictLabel) { - await github.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - labels: ['has-conflicts'] - }); - console.log('Added has-conflicts label'); - } else { - console.log('has-conflicts label already exists'); - } - - - name: Remove conflict label - if: steps.conflict-check.outputs.has_conflicts == 'false' - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - with: - script: | - try { - await github.rest.issues.removeLabel({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - name: 'has-conflicts' - }); - console.log('Removed has-conflicts label'); - } catch (error) { - if (error.status === 404) { - console.log('has-conflicts label was not present'); - } else { - throw error; - } - } - - - name: Find existing conflict comment - if: steps.conflict-check.outputs.has_conflicts == 'true' - uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3.1.0 + - name: Find existing comment + uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4.0.0 id: find-comment with: issue-number: ${{ github.event.pull_request.number }} comment-author: 'github-actions[bot]' - body-regex: '(āš ļø \*\*Conflict Markers Detected\*\*|āœ… \*\*Conflict Markers Resolved\*\*)' + body-includes: '' - - name: Create or update conflict comment - if: steps.conflict-check.outputs.has_conflicts == 'true' - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0 + - name: Create or update comment + uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0 with: comment-id: ${{ steps.find-comment.outputs.comment-id }} issue-number: ${{ github.event.pull_request.number }} edit-mode: replace body: | - āš ļø **Conflict Markers Detected** + + ${{ steps.conflict-check.outputs.has_conflicts == 'true' && 'āš ļø **Conflict Markers Detected**' || 'āœ… **Conflict Markers Resolved**' }} - This pull request contains unresolved conflict markers in the following files: - ``` - ${{ steps.conflict-check.outputs.conflict_files }} - ``` + ${{ steps.conflict-check.outputs.has_conflicts == 'true' && format('This pull request contains unresolved conflict markers in the following files: + + {0} Please resolve these conflicts by: 1. Locating the conflict markers: `<<<<<<<`, `=======`, and `>>>>>>>` 2. Manually editing the files to resolve the conflicts 3. Removing all conflict markers - 4. Committing and pushing the changes + 4. Committing and pushing the changes', steps.conflict-check.outputs.conflict_files) || 'All conflict markers have been successfully resolved in this pull request.' }} - - name: Find existing conflict comment when resolved - if: steps.conflict-check.outputs.has_conflicts == 'false' - uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3.1.0 - id: find-resolved-comment - with: - issue-number: ${{ github.event.pull_request.number }} - comment-author: 'github-actions[bot]' - body-regex: '(āš ļø \*\*Conflict Markers Detected\*\*|āœ… \*\*Conflict Markers Resolved\*\*)' - - - name: Update comment when conflicts resolved - if: steps.conflict-check.outputs.has_conflicts == 'false' && steps.find-resolved-comment.outputs.comment-id != '' - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0 - with: - comment-id: ${{ steps.find-resolved-comment.outputs.comment-id }} - issue-number: ${{ github.event.pull_request.number }} - edit-mode: replace - body: | - āœ… **Conflict Markers Resolved** - - All conflict markers have been successfully resolved in this pull request. + - name: Fail workflow if conflicts detected + if: steps.conflict-check.outputs.has_conflicts == 'true' + run: | + echo "::error::Workflow failed due to conflict markers detected in the PR" + exit 1 diff --git a/.github/workflows/pull-request-merged.yml b/.github/workflows/pr-merged.yml similarity index 50% rename from .github/workflows/pull-request-merged.yml rename to .github/workflows/pr-merged.yml index 8f6f73a379..d8255026e6 100644 --- a/.github/workflows/pull-request-merged.yml +++ b/.github/workflows/pr-merged.yml @@ -1,28 +1,32 @@ -name: Prowler - Merged Pull Request +name: 'Tools: PR Merged' on: pull_request_target: - branches: ['master'] - types: ['closed'] + branches: + - 'master' + types: + - 'closed' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + cancel-in-progress: false jobs: trigger-cloud-pull-request: - name: Trigger Cloud Pull Request if: github.event.pull_request.merged == true && github.repository == 'prowler-cloud/prowler' runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - ref: ${{ github.event.pull_request.merge_commit_sha }} - - - name: Set short git commit SHA + - name: Calculate short commit SHA id: vars run: | - shortSha=$(git rev-parse --short ${{ github.event.pull_request.merge_commit_sha }}) - echo "SHORT_SHA=${shortSha}" >> $GITHUB_ENV + SHORT_SHA="${{ github.event.pull_request.merge_commit_sha }}" + echo "SHORT_SHA=${SHORT_SHA::7}" >> $GITHUB_ENV - - name: Trigger pull request - uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3.0.0 + - name: Trigger Cloud repository pull request + uses: peter-evans/repository-dispatch@5fc4efd1a4797ddb68ffd0714a238564e4cc0e6f # v4.0.0 with: token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} repository: ${{ secrets.CLOUD_DISPATCH }} @@ -31,8 +35,12 @@ jobs: { "PROWLER_COMMIT_SHA": "${{ github.event.pull_request.merge_commit_sha }}", "PROWLER_COMMIT_SHORT_SHA": "${{ env.SHORT_SHA }}", + "PROWLER_PR_NUMBER": "${{ github.event.pull_request.number }}", "PROWLER_PR_TITLE": ${{ toJson(github.event.pull_request.title) }}, "PROWLER_PR_LABELS": ${{ toJson(github.event.pull_request.labels.*.name) }}, "PROWLER_PR_BODY": ${{ toJson(github.event.pull_request.body) }}, - "PROWLER_PR_URL": ${{ toJson(github.event.pull_request.html_url) }} + "PROWLER_PR_URL": ${{ toJson(github.event.pull_request.html_url) }}, + "PROWLER_PR_MERGED_BY": "${{ github.event.pull_request.merged_by.login }}", + "PROWLER_PR_BASE_BRANCH": "${{ github.event.pull_request.base.ref }}", + "PROWLER_PR_HEAD_BRANCH": "${{ github.event.pull_request.head.ref }}" } diff --git a/.github/workflows/prowler-release-preparation.yml b/.github/workflows/prepare-release.yml similarity index 51% rename from .github/workflows/prowler-release-preparation.yml rename to .github/workflows/prepare-release.yml index 6008a25795..ae039bd5a6 100644 --- a/.github/workflows/prowler-release-preparation.yml +++ b/.github/workflows/prepare-release.yml @@ -1,6 +1,6 @@ -name: Prowler - Release Preparation +name: 'Tools: Prepare Release' -run-name: Prowler Release Preparation for ${{ inputs.prowler_version }} +run-name: 'Prepare Release for Prowler ${{ inputs.prowler_version }}' on: workflow_dispatch: @@ -10,37 +10,42 @@ on: required: true type: string +concurrency: + group: ${{ github.workflow }}-${{ inputs.prowler_version }} + cancel-in-progress: false + env: - PROWLER_VERSION: ${{ github.event.inputs.prowler_version }} + PROWLER_VERSION: ${{ inputs.prowler_version }} jobs: prepare-release: - if: github.repository == 'prowler-cloud/prowler' + if: github.event_name == 'workflow_dispatch' && github.repository == 'prowler-cloud/prowler' runs-on: ubuntu-latest + timeout-minutes: 30 permissions: contents: write pull-requests: write steps: - - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: fetch-depth: 0 token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} - name: Set up Python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 with: python-version: '3.12' - name: Install Poetry run: | - python3 -m pip install --user poetry + python3 -m pip install --user poetry==2.1.1 echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Configure Git run: | - git config --global user.name "prowler-bot" - git config --global user.email "179230569+prowler-bot@users.noreply.github.com" + git config --global user.name 'prowler-bot' + git config --global user.email '179230569+prowler-bot@users.noreply.github.com' - name: Parse version and determine branch run: | @@ -59,29 +64,17 @@ jobs: BRANCH_NAME="v${MAJOR_VERSION}.${MINOR_VERSION}" echo "BRANCH_NAME=${BRANCH_NAME}" >> "${GITHUB_ENV}" - # Calculate UI version (1.X.X format - matches Prowler minor version) - UI_VERSION="1.${MINOR_VERSION}.${PATCH_VERSION}" - echo "UI_VERSION=${UI_VERSION}" >> "${GITHUB_ENV}" - - # Calculate API version (1.X.X format - one minor version ahead) - API_MINOR_VERSION=$((MINOR_VERSION + 1)) - API_VERSION="1.${API_MINOR_VERSION}.${PATCH_VERSION}" - echo "API_VERSION=${API_VERSION}" >> "${GITHUB_ENV}" - echo "Prowler version: $PROWLER_VERSION" echo "Branch name: $BRANCH_NAME" - echo "UI version: $UI_VERSION" - echo "API version: $API_VERSION" echo "Is minor release: $([ $PATCH_VERSION -eq 0 ] && echo 'true' || echo 'false')" else echo "Invalid version syntax: '$PROWLER_VERSION' (must be N.N.N)" >&2 exit 1 fi - - name: Checkout existing branch for patch release - if: ${{ env.PATCH_VERSION != '0' }} + - name: Checkout release branch run: | - echo "Patch release detected, checking out existing branch $BRANCH_NAME..." + echo "Checking out branch $BRANCH_NAME for release $PROWLER_VERSION..." if git show-ref --verify --quiet "refs/heads/$BRANCH_NAME"; then echo "Branch $BRANCH_NAME exists locally, checking out..." git checkout "$BRANCH_NAME" @@ -89,139 +82,66 @@ jobs: echo "Branch $BRANCH_NAME exists remotely, checking out..." git checkout -b "$BRANCH_NAME" "origin/$BRANCH_NAME" else - echo "ERROR: Branch $BRANCH_NAME should exist for patch release $PROWLER_VERSION" + echo "ERROR: Branch $BRANCH_NAME does not exist. For minor releases (X.Y.0), create it manually first. For patch releases (X.Y.Z), the branch should already exist." exit 1 fi - - name: Verify version in pyproject.toml + - name: Read changelog versions from release branch run: | - CURRENT_VERSION=$(grep '^version = ' pyproject.toml | sed -E 's/version = "([^"]+)"/\1/' | tr -d '[:space:]') - PROWLER_VERSION_TRIMMED=$(echo "$PROWLER_VERSION" | tr -d '[:space:]') - if [ "$CURRENT_VERSION" != "$PROWLER_VERSION_TRIMMED" ]; then - echo "ERROR: Version mismatch in pyproject.toml (expected: '$PROWLER_VERSION_TRIMMED', found: '$CURRENT_VERSION')" - exit 1 - fi - echo "āœ“ pyproject.toml version: $CURRENT_VERSION" + # Function to extract the latest version from changelog + extract_latest_version() { + local changelog_file="$1" + if [ -f "$changelog_file" ]; then + # Extract the first version entry (most recent) from changelog + # Format: ## [version] (1.2.3) or ## [vversion] (v1.2.3) + local version=$(grep -m 1 '^## \[' "$changelog_file" | sed 's/^## \[\(.*\)\].*/\1/' | sed 's/^v//' | tr -d '[:space:]') + echo "$version" + else + echo "" + fi + } - - name: Verify version in prowler/config/config.py - run: | - CURRENT_VERSION=$(grep '^prowler_version = ' prowler/config/config.py | sed -E 's/prowler_version = "([^"]+)"/\1/' | tr -d '[:space:]') - PROWLER_VERSION_TRIMMED=$(echo "$PROWLER_VERSION" | tr -d '[:space:]') - if [ "$CURRENT_VERSION" != "$PROWLER_VERSION_TRIMMED" ]; then - echo "ERROR: Version mismatch in prowler/config/config.py (expected: '$PROWLER_VERSION_TRIMMED', found: '$CURRENT_VERSION')" - exit 1 - fi - echo "āœ“ prowler/config/config.py version: $CURRENT_VERSION" + # Read actual versions from changelogs (source of truth) + UI_VERSION=$(extract_latest_version "ui/CHANGELOG.md") + API_VERSION=$(extract_latest_version "api/CHANGELOG.md") + SDK_VERSION=$(extract_latest_version "prowler/CHANGELOG.md") + MCP_VERSION=$(extract_latest_version "mcp_server/CHANGELOG.md") - - name: Verify version in api/pyproject.toml - run: | - CURRENT_API_VERSION=$(grep '^version = ' api/pyproject.toml | sed -E 's/version = "([^"]+)"/\1/' | tr -d '[:space:]') - API_VERSION_TRIMMED=$(echo "$API_VERSION" | tr -d '[:space:]') - if [ "$CURRENT_API_VERSION" != "$API_VERSION_TRIMMED" ]; then - echo "ERROR: API version mismatch in api/pyproject.toml (expected: '$API_VERSION_TRIMMED', found: '$CURRENT_API_VERSION')" - exit 1 - fi - echo "āœ“ api/pyproject.toml version: $CURRENT_API_VERSION" + echo "UI_VERSION=${UI_VERSION}" >> "${GITHUB_ENV}" + echo "API_VERSION=${API_VERSION}" >> "${GITHUB_ENV}" + echo "SDK_VERSION=${SDK_VERSION}" >> "${GITHUB_ENV}" + echo "MCP_VERSION=${MCP_VERSION}" >> "${GITHUB_ENV}" - - name: Verify prowler dependency in api/pyproject.toml - if: ${{ env.PATCH_VERSION != '0' }} - run: | - CURRENT_PROWLER_REF=$(grep 'prowler @ git+https://github.com/prowler-cloud/prowler.git@' api/pyproject.toml | sed -E 's/.*@([^"]+)".*/\1/' | tr -d '[:space:]') - BRANCH_NAME_TRIMMED=$(echo "$BRANCH_NAME" | tr -d '[:space:]') - if [ "$CURRENT_PROWLER_REF" != "$BRANCH_NAME_TRIMMED" ]; then - echo "ERROR: Prowler dependency mismatch in api/pyproject.toml (expected: '$BRANCH_NAME_TRIMMED', found: '$CURRENT_PROWLER_REF')" - exit 1 - fi - echo "āœ“ api/pyproject.toml prowler dependency: $CURRENT_PROWLER_REF" - - - name: Verify version in api/src/backend/api/v1/views.py - run: | - CURRENT_API_VERSION=$(grep 'spectacular_settings.VERSION = ' api/src/backend/api/v1/views.py | sed -E 's/.*spectacular_settings.VERSION = "([^"]+)".*/\1/' | tr -d '[:space:]') - API_VERSION_TRIMMED=$(echo "$API_VERSION" | tr -d '[:space:]') - if [ "$CURRENT_API_VERSION" != "$API_VERSION_TRIMMED" ]; then - echo "ERROR: API version mismatch in views.py (expected: '$API_VERSION_TRIMMED', found: '$CURRENT_API_VERSION')" - exit 1 - fi - echo "āœ“ api/src/backend/api/v1/views.py version: $CURRENT_API_VERSION" - - - name: Checkout existing release branch for minor release - if: ${{ env.PATCH_VERSION == '0' }} - run: | - echo "Minor release detected (patch = 0), checking out existing branch $BRANCH_NAME..." - if git show-ref --verify --quiet "refs/remotes/origin/$BRANCH_NAME"; then - echo "Branch $BRANCH_NAME exists remotely, checking out..." - git checkout -b "$BRANCH_NAME" "origin/$BRANCH_NAME" + if [ -n "$UI_VERSION" ]; then + echo "Read UI version from changelog: $UI_VERSION" else - echo "ERROR: Branch $BRANCH_NAME should exist for minor release $PROWLER_VERSION. Please create it manually first." - exit 1 + echo "Warning: No UI version found in ui/CHANGELOG.md" fi - - name: Prepare prowler dependency update for minor release - if: ${{ env.PATCH_VERSION == '0' }} - run: | - CURRENT_PROWLER_REF=$(grep 'prowler @ git+https://github.com/prowler-cloud/prowler.git@' api/pyproject.toml | sed -E 's/.*@([^"]+)".*/\1/' | tr -d '[:space:]') - BRANCH_NAME_TRIMMED=$(echo "$BRANCH_NAME" | tr -d '[:space:]') - - # Create a temporary branch for the PR - TEMP_BRANCH="update-api-dependency-$BRANCH_NAME_TRIMMED-$(date +%s)" - echo "TEMP_BRANCH=$TEMP_BRANCH" >> $GITHUB_ENV - - # Switch back to master and create temp branch - git checkout master - git checkout -b "$TEMP_BRANCH" - - # Minor release: update the dependency to use the release branch - echo "Updating prowler dependency from '$CURRENT_PROWLER_REF' to '$BRANCH_NAME_TRIMMED'" - sed -i "s|prowler @ git+https://github.com/prowler-cloud/prowler.git@[^\"]*\"|prowler @ git+https://github.com/prowler-cloud/prowler.git@$BRANCH_NAME_TRIMMED\"|" api/pyproject.toml - - # Verify the change was made - UPDATED_PROWLER_REF=$(grep 'prowler @ git+https://github.com/prowler-cloud/prowler.git@' api/pyproject.toml | sed -E 's/.*@([^"]+)".*/\1/' | tr -d '[:space:]') - if [ "$UPDATED_PROWLER_REF" != "$BRANCH_NAME_TRIMMED" ]; then - echo "ERROR: Failed to update prowler dependency in api/pyproject.toml" - exit 1 + if [ -n "$API_VERSION" ]; then + echo "Read API version from changelog: $API_VERSION" + else + echo "Warning: No API version found in api/CHANGELOG.md" fi - # Update poetry lock file - echo "Updating poetry.lock file..." - cd api - poetry lock - cd .. + if [ -n "$SDK_VERSION" ]; then + echo "Read SDK version from changelog: $SDK_VERSION" + else + echo "Warning: No SDK version found in prowler/CHANGELOG.md" + fi - # Commit and push the temporary branch - git add api/pyproject.toml api/poetry.lock - git commit -m "chore(api): update prowler dependency to $BRANCH_NAME_TRIMMED for release $PROWLER_VERSION" - git push origin "$TEMP_BRANCH" + if [ -n "$MCP_VERSION" ]; then + echo "Read MCP version from changelog: $MCP_VERSION" + else + echo "Warning: No MCP version found in mcp_server/CHANGELOG.md" + fi - echo "āœ“ Prepared prowler dependency update to: $UPDATED_PROWLER_REF" + echo "UI version: $UI_VERSION" + echo "API version: $API_VERSION" + echo "SDK version: $SDK_VERSION" + echo "MCP version: $MCP_VERSION" - - name: Create Pull Request against release branch - if: ${{ env.PATCH_VERSION == '0' }} - uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 - with: - token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} - branch: ${{ env.TEMP_BRANCH }} - base: ${{ env.BRANCH_NAME }} - title: "chore(api): Update prowler dependency to ${{ env.BRANCH_NAME }} for release ${{ env.PROWLER_VERSION }}" - body: | - ### Description - - Updates the API prowler dependency for release ${{ env.PROWLER_VERSION }}. - - **Changes:** - - Updates `api/pyproject.toml` prowler dependency from `@master` to `@${{ env.BRANCH_NAME }}` - - Updates `api/poetry.lock` file with resolved dependencies - - This PR should be merged into the `${{ env.BRANCH_NAME }}` release branch. - - ### License - - By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. - author: prowler-bot <179230569+prowler-bot@users.noreply.github.com> - labels: | - component/api - no-changelog - - - name: Extract changelog entries + - name: Extract and combine changelog entries run: | set -e @@ -247,54 +167,232 @@ jobs: # Remove --- separators sed -i '/^---$/d' "$output_file" - # Remove trailing empty lines - sed -i '/^$/d' "$output_file" + # Remove only trailing empty lines (not all empty lines) + sed -i -e :a -e '/^\s*$/d;N;ba' "$output_file" } - # Extract changelogs - echo "Extracting changelog entries..." - extract_changelog "prowler/CHANGELOG.md" "$PROWLER_VERSION" "prowler_changelog.md" - extract_changelog "api/CHANGELOG.md" "$API_VERSION" "api_changelog.md" - extract_changelog "ui/CHANGELOG.md" "$UI_VERSION" "ui_changelog.md" + # Calculate expected versions for this release + if [[ $PROWLER_VERSION =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then + EXPECTED_UI_VERSION="1.${BASH_REMATCH[2]}.${BASH_REMATCH[3]}" + EXPECTED_API_VERSION="1.$((${BASH_REMATCH[2]} + 1)).${BASH_REMATCH[3]}" - # Combine changelogs in order: UI, API, SDK + echo "Expected UI version for this release: $EXPECTED_UI_VERSION" + echo "Expected API version for this release: $EXPECTED_API_VERSION" + fi + + # Determine if components have changes for this specific release + # UI has changes if its current version matches what we expect for this release + if [ -n "$UI_VERSION" ] && [ "$UI_VERSION" = "$EXPECTED_UI_VERSION" ]; then + echo "HAS_UI_CHANGES=true" >> $GITHUB_ENV + echo "āœ“ UI changes detected - version matches expected: $UI_VERSION" + extract_changelog "ui/CHANGELOG.md" "$UI_VERSION" "ui_changelog.md" + else + echo "HAS_UI_CHANGES=false" >> $GITHUB_ENV + echo "ℹ No UI changes for this release (current: $UI_VERSION, expected: $EXPECTED_UI_VERSION)" + touch "ui_changelog.md" + fi + + # API has changes if its current version matches what we expect for this release + if [ -n "$API_VERSION" ] && [ "$API_VERSION" = "$EXPECTED_API_VERSION" ]; then + echo "HAS_API_CHANGES=true" >> $GITHUB_ENV + echo "āœ“ API changes detected - version matches expected: $API_VERSION" + extract_changelog "api/CHANGELOG.md" "$API_VERSION" "api_changelog.md" + else + echo "HAS_API_CHANGES=false" >> $GITHUB_ENV + echo "ℹ No API changes for this release (current: $API_VERSION, expected: $EXPECTED_API_VERSION)" + touch "api_changelog.md" + fi + + # SDK has changes if its current version matches the input version + if [ -n "$SDK_VERSION" ] && [ "$SDK_VERSION" = "$PROWLER_VERSION" ]; then + echo "HAS_SDK_CHANGES=true" >> $GITHUB_ENV + echo "āœ“ SDK changes detected - version matches input: $SDK_VERSION" + extract_changelog "prowler/CHANGELOG.md" "$PROWLER_VERSION" "prowler_changelog.md" + else + echo "HAS_SDK_CHANGES=false" >> $GITHUB_ENV + echo "ℹ No SDK changes for this release (current: $SDK_VERSION, input: $PROWLER_VERSION)" + touch "prowler_changelog.md" + fi + + # MCP has changes if the changelog references this Prowler version + # Check if the changelog contains "(Prowler X.Y.Z)" or "(Prowler UNRELEASED)" + if [ -f "mcp_server/CHANGELOG.md" ]; then + MCP_PROWLER_REF=$(grep -m 1 "^## \[.*\] (Prowler" mcp_server/CHANGELOG.md | sed -E 's/.*\(Prowler ([^)]+)\).*/\1/' | tr -d '[:space:]') + if [ "$MCP_PROWLER_REF" = "$PROWLER_VERSION" ] || [ "$MCP_PROWLER_REF" = "UNRELEASED" ]; then + echo "HAS_MCP_CHANGES=true" >> $GITHUB_ENV + echo "āœ“ MCP changes detected - Prowler reference: $MCP_PROWLER_REF (version: $MCP_VERSION)" + extract_changelog "mcp_server/CHANGELOG.md" "$MCP_VERSION" "mcp_changelog.md" + else + echo "HAS_MCP_CHANGES=false" >> $GITHUB_ENV + echo "ℹ No MCP changes for this release (Prowler reference: $MCP_PROWLER_REF, input: $PROWLER_VERSION)" + touch "mcp_changelog.md" + fi + else + echo "HAS_MCP_CHANGES=false" >> $GITHUB_ENV + echo "ℹ No MCP changelog found" + touch "mcp_changelog.md" + fi + + # Combine changelogs in order: UI, API, SDK, MCP > combined_changelog.md - if [ -s "ui_changelog.md" ]; then + if [ "$HAS_UI_CHANGES" = "true" ] && [ -s "ui_changelog.md" ]; then echo "## UI" >> combined_changelog.md echo "" >> combined_changelog.md cat ui_changelog.md >> combined_changelog.md echo "" >> combined_changelog.md fi - if [ -s "api_changelog.md" ]; then + if [ "$HAS_API_CHANGES" = "true" ] && [ -s "api_changelog.md" ]; then echo "## API" >> combined_changelog.md echo "" >> combined_changelog.md cat api_changelog.md >> combined_changelog.md echo "" >> combined_changelog.md fi - if [ -s "prowler_changelog.md" ]; then + if [ "$HAS_SDK_CHANGES" = "true" ] && [ -s "prowler_changelog.md" ]; then echo "## SDK" >> combined_changelog.md echo "" >> combined_changelog.md cat prowler_changelog.md >> combined_changelog.md echo "" >> combined_changelog.md fi + if [ "$HAS_MCP_CHANGES" = "true" ] && [ -s "mcp_changelog.md" ]; then + echo "## MCP" >> combined_changelog.md + echo "" >> combined_changelog.md + cat mcp_changelog.md >> combined_changelog.md + echo "" >> combined_changelog.md + fi + + # Add fallback message if no changelogs were added + if [ ! -s combined_changelog.md ]; then + echo "No component changes detected for this release." >> combined_changelog.md + fi + echo "Combined changelog preview:" cat combined_changelog.md + - name: Verify SDK version in pyproject.toml + run: | + CURRENT_VERSION=$(grep '^version = ' pyproject.toml | sed -E 's/version = "([^"]+)"/\1/' | tr -d '[:space:]') + PROWLER_VERSION_TRIMMED=$(echo "$PROWLER_VERSION" | tr -d '[:space:]') + if [ "$CURRENT_VERSION" != "$PROWLER_VERSION_TRIMMED" ]; then + echo "ERROR: Version mismatch in pyproject.toml (expected: '$PROWLER_VERSION_TRIMMED', found: '$CURRENT_VERSION')" + exit 1 + fi + echo "āœ“ pyproject.toml version: $CURRENT_VERSION" + + - name: Verify SDK version in prowler/config/config.py + run: | + CURRENT_VERSION=$(grep '^prowler_version = ' prowler/config/config.py | sed -E 's/prowler_version = "([^"]+)"/\1/' | tr -d '[:space:]') + PROWLER_VERSION_TRIMMED=$(echo "$PROWLER_VERSION" | tr -d '[:space:]') + if [ "$CURRENT_VERSION" != "$PROWLER_VERSION_TRIMMED" ]; then + echo "ERROR: Version mismatch in prowler/config/config.py (expected: '$PROWLER_VERSION_TRIMMED', found: '$CURRENT_VERSION')" + exit 1 + fi + echo "āœ“ prowler/config/config.py version: $CURRENT_VERSION" + + - name: Verify API version in api/pyproject.toml + if: ${{ env.HAS_API_CHANGES == 'true' }} + run: | + CURRENT_API_VERSION=$(grep '^version = ' api/pyproject.toml | sed -E 's/version = "([^"]+)"/\1/' | tr -d '[:space:]') + API_VERSION_TRIMMED=$(echo "$API_VERSION" | tr -d '[:space:]') + if [ "$CURRENT_API_VERSION" != "$API_VERSION_TRIMMED" ]; then + echo "ERROR: API version mismatch in api/pyproject.toml (expected: '$API_VERSION_TRIMMED', found: '$CURRENT_API_VERSION')" + exit 1 + fi + echo "āœ“ api/pyproject.toml version: $CURRENT_API_VERSION" + + - name: Verify API prowler dependency in api/pyproject.toml + if: ${{ env.PATCH_VERSION != '0' && env.HAS_API_CHANGES == 'true' }} + run: | + CURRENT_PROWLER_REF=$(grep 'prowler @ git+https://github.com/prowler-cloud/prowler.git@' api/pyproject.toml | sed -E 's/.*@([^"]+)".*/\1/' | tr -d '[:space:]') + BRANCH_NAME_TRIMMED=$(echo "$BRANCH_NAME" | tr -d '[:space:]') + if [ "$CURRENT_PROWLER_REF" != "$BRANCH_NAME_TRIMMED" ]; then + echo "ERROR: Prowler dependency mismatch in api/pyproject.toml (expected: '$BRANCH_NAME_TRIMMED', found: '$CURRENT_PROWLER_REF')" + exit 1 + fi + echo "āœ“ api/pyproject.toml prowler dependency: $CURRENT_PROWLER_REF" + + - name: Verify API version in api/src/backend/api/v1/views.py + if: ${{ env.HAS_API_CHANGES == 'true' }} + run: | + CURRENT_API_VERSION=$(grep 'spectacular_settings.VERSION = ' api/src/backend/api/v1/views.py | sed -E 's/.*spectacular_settings.VERSION = "([^"]+)".*/\1/' | tr -d '[:space:]') + API_VERSION_TRIMMED=$(echo "$API_VERSION" | tr -d '[:space:]') + if [ "$CURRENT_API_VERSION" != "$API_VERSION_TRIMMED" ]; then + echo "ERROR: API version mismatch in views.py (expected: '$API_VERSION_TRIMMED', found: '$CURRENT_API_VERSION')" + exit 1 + fi + echo "āœ“ api/src/backend/api/v1/views.py version: $CURRENT_API_VERSION" + + - name: Update API prowler dependency for minor release + if: ${{ env.PATCH_VERSION == '0' }} + run: | + CURRENT_PROWLER_REF=$(grep 'prowler @ git+https://github.com/prowler-cloud/prowler.git@' api/pyproject.toml | sed -E 's/.*@([^"]+)".*/\1/' | tr -d '[:space:]') + BRANCH_NAME_TRIMMED=$(echo "$BRANCH_NAME" | tr -d '[:space:]') + + # Minor release: update the dependency to use the release branch + echo "Updating prowler dependency from '$CURRENT_PROWLER_REF' to '$BRANCH_NAME_TRIMMED'" + sed -i "s|prowler @ git+https://github.com/prowler-cloud/prowler.git@[^\"]*\"|prowler @ git+https://github.com/prowler-cloud/prowler.git@$BRANCH_NAME_TRIMMED\"|" api/pyproject.toml + + # Verify the change was made + UPDATED_PROWLER_REF=$(grep 'prowler @ git+https://github.com/prowler-cloud/prowler.git@' api/pyproject.toml | sed -E 's/.*@([^"]+)".*/\1/' | tr -d '[:space:]') + if [ "$UPDATED_PROWLER_REF" != "$BRANCH_NAME_TRIMMED" ]; then + echo "ERROR: Failed to update prowler dependency in api/pyproject.toml" + exit 1 + fi + + # Update poetry lock file + echo "Updating poetry.lock file..." + cd api + poetry lock + cd .. + + echo "āœ“ Prepared prowler dependency update to: $UPDATED_PROWLER_REF" + + - name: Create PR for API dependency update + if: ${{ env.PATCH_VERSION == '0' }} + uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 + with: + token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} + commit-message: 'chore(api): update prowler dependency to ${{ env.BRANCH_NAME }} for release ${{ env.PROWLER_VERSION }}' + branch: update-api-dependency-${{ env.BRANCH_NAME }}-${{ github.run_number }} + base: ${{ env.BRANCH_NAME }} + add-paths: | + api/pyproject.toml + api/poetry.lock + title: "chore(api): Update prowler dependency to ${{ env.BRANCH_NAME }} for release ${{ env.PROWLER_VERSION }}" + body: | + ### Description + + Updates the API prowler dependency for release ${{ env.PROWLER_VERSION }}. + + **Changes:** + - Updates `api/pyproject.toml` prowler dependency from `@master` to `@${{ env.BRANCH_NAME }}` + - Updates `api/poetry.lock` file with resolved dependencies + + This PR should be merged into the `${{ env.BRANCH_NAME }}` release branch. + + ### License + + By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. + author: prowler-bot <179230569+prowler-bot@users.noreply.github.com> + labels: | + component/api + no-changelog + - name: Create draft release - uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8 # v2.3.2 + uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1 with: tag_name: ${{ env.PROWLER_VERSION }} name: Prowler ${{ env.PROWLER_VERSION }} body_path: combined_changelog.md draft: true - target_commitish: ${{ env.PATCH_VERSION == '0' && 'master' || env.BRANCH_NAME }} + target_commitish: ${{ env.BRANCH_NAME }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Clean up temporary files + if: always() run: | - rm -f prowler_changelog.md api_changelog.md ui_changelog.md combined_changelog.md + rm -f prowler_changelog.md api_changelog.md ui_changelog.md mcp_changelog.md combined_changelog.md diff --git a/.github/workflows/pull-request-check-changelog.yml b/.github/workflows/pull-request-check-changelog.yml deleted file mode 100644 index c4e0fa31c0..0000000000 --- a/.github/workflows/pull-request-check-changelog.yml +++ /dev/null @@ -1,77 +0,0 @@ -name: Prowler - Check Changelog - -on: - pull_request: - types: [opened, synchronize, reopened, labeled, unlabeled] - -jobs: - check-changelog: - if: contains(github.event.pull_request.labels.*.name, 'no-changelog') == false - runs-on: ubuntu-latest - permissions: - id-token: write - contents: read - pull-requests: write - env: - MONITORED_FOLDERS: "api ui prowler" - - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - fetch-depth: 0 - - - name: Get list of changed files - id: changed_files - run: | - git fetch origin ${{ github.base_ref }} - git diff --name-only origin/${{ github.base_ref }}...HEAD > changed_files.txt - cat changed_files.txt - - - name: Check for folder changes and changelog presence - id: check_folders - run: | - missing_changelogs="" - - for folder in $MONITORED_FOLDERS; do - if grep -q "^${folder}/" changed_files.txt; then - echo "Detected changes in ${folder}/" - if ! grep -q "^${folder}/CHANGELOG.md$" changed_files.txt; then - echo "No changelog update found for ${folder}/" - missing_changelogs="${missing_changelogs}- \`${folder}\`\n" - fi - fi - done - - echo "missing_changelogs<> $GITHUB_OUTPUT - echo -e "${missing_changelogs}" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - - name: Find existing changelog comment - if: github.event.pull_request.head.repo.full_name == github.repository - id: find_comment - uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e #v3.1.0 - with: - issue-number: ${{ github.event.pull_request.number }} - comment-author: 'github-actions[bot]' - body-includes: '' - - - name: Update PR comment with changelog status - if: github.event.pull_request.head.repo.full_name == github.repository - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0 - with: - issue-number: ${{ github.event.pull_request.number }} - comment-id: ${{ steps.find_comment.outputs.comment-id }} - edit-mode: replace - body: | - - ${{ steps.check_folders.outputs.missing_changelogs != '' && format('āš ļø **Changes detected in the following folders without a corresponding update to the `CHANGELOG.md`:** - - {0} - - Please add an entry to the corresponding `CHANGELOG.md` file to maintain a clear history of changes.', steps.check_folders.outputs.missing_changelogs) || 'āœ… All necessary `CHANGELOG.md` files have been updated. Great job! šŸŽ‰' }} - - - name: Fail if changelog is missing - if: steps.check_folders.outputs.missing_changelogs != '' - run: | - echo "ERROR: Missing changelog updates in some folders." - exit 1 diff --git a/.github/workflows/sdk-build-lint-push-containers.yml b/.github/workflows/sdk-build-lint-push-containers.yml deleted file mode 100644 index ec1d71a0cb..0000000000 --- a/.github/workflows/sdk-build-lint-push-containers.yml +++ /dev/null @@ -1,186 +0,0 @@ -name: SDK - Build and Push containers - -on: - push: - branches: - # For `v3-latest` - - "v3" - # For `v4-latest` - - "v4.6" - # For `latest` - - "master" - paths-ignore: - - ".github/**" - - "README.md" - - "docs/**" - - "ui/**" - - "api/**" - - release: - types: [published] - -env: - #Ā AWS Configuration - AWS_REGION_STG: eu-west-1 - AWS_REGION_PLATFORM: eu-west-1 - AWS_REGION: us-east-1 - - # Container's configuration - IMAGE_NAME: prowler - DOCKERFILE_PATH: ./Dockerfile - - # Tags - LATEST_TAG: latest - STABLE_TAG: stable - # The RELEASE_TAG is set during runtime in releases - RELEASE_TAG: "" - # The PROWLER_VERSION and PROWLER_VERSION_MAJOR are set during runtime in releases - PROWLER_VERSION: "" - PROWLER_VERSION_MAJOR: "" - # TEMPORARY_TAG: temporary - - # Python configuration - PYTHON_VERSION: 3.12 - - # Container Registries - PROWLERCLOUD_DOCKERHUB_REPOSITORY: prowlercloud - PROWLERCLOUD_DOCKERHUB_IMAGE: prowler - -jobs: - # Build Prowler OSS container - container-build-push: - # needs: dockerfile-linter - runs-on: ubuntu-latest - outputs: - prowler_version_major: ${{ steps.get-prowler-version.outputs.PROWLER_VERSION_MAJOR }} - prowler_version: ${{ steps.get-prowler-version.outputs.PROWLER_VERSION }} - env: - POETRY_VIRTUALENVS_CREATE: "false" - - steps: - - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Setup Python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 - with: - python-version: ${{ env.PYTHON_VERSION }} - - - name: Install Poetry - run: | - pipx install poetry==2.* - pipx inject poetry poetry-bumpversion - - - name: Get Prowler version - id: get-prowler-version - run: | - PROWLER_VERSION="$(poetry version -s 2>/dev/null)" - echo "PROWLER_VERSION=${PROWLER_VERSION}" >> "${GITHUB_ENV}" - echo "PROWLER_VERSION=${PROWLER_VERSION}" >> "${GITHUB_OUTPUT}" - - # Store prowler version major just for the release - PROWLER_VERSION_MAJOR="${PROWLER_VERSION%%.*}" - echo "PROWLER_VERSION_MAJOR=${PROWLER_VERSION_MAJOR}" >> "${GITHUB_ENV}" - echo "PROWLER_VERSION_MAJOR=${PROWLER_VERSION_MAJOR}" >> "${GITHUB_OUTPUT}" - - case ${PROWLER_VERSION_MAJOR} in - 3) - echo "LATEST_TAG=v3-latest" >> "${GITHUB_ENV}" - echo "STABLE_TAG=v3-stable" >> "${GITHUB_ENV}" - ;; - - - 4) - echo "LATEST_TAG=v4-latest" >> "${GITHUB_ENV}" - echo "STABLE_TAG=v4-stable" >> "${GITHUB_ENV}" - ;; - - 5) - echo "LATEST_TAG=latest" >> "${GITHUB_ENV}" - echo "STABLE_TAG=stable" >> "${GITHUB_ENV}" - ;; - - *) - # Fallback if any other version is present - echo "Releasing another Prowler major version, aborting..." - exit 1 - ;; - esac - - - name: Login to DockerHub - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Login to Public ECR - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - registry: public.ecr.aws - username: ${{ secrets.PUBLIC_ECR_AWS_ACCESS_KEY_ID }} - password: ${{ secrets.PUBLIC_ECR_AWS_SECRET_ACCESS_KEY }} - env: - AWS_REGION: ${{ env.AWS_REGION }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - - name: Build and push container image (latest) - if: github.event_name == 'push' - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - push: true - tags: | - ${{ secrets.DOCKER_HUB_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.LATEST_TAG }} - ${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.LATEST_TAG }} - ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.LATEST_TAG }} - file: ${{ env.DOCKERFILE_PATH }} - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Build and push container image (release) - if: github.event_name == 'release' - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - # Use local context to get changes - # https://github.com/docker/build-push-action#path-context - context: . - push: true - tags: | - ${{ secrets.DOCKER_HUB_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.PROWLER_VERSION }} - ${{ secrets.DOCKER_HUB_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.STABLE_TAG }} - ${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.PROWLER_VERSION }} - ${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ env.STABLE_TAG }} - ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.PROWLER_VERSION }} - ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.STABLE_TAG }} - file: ${{ env.DOCKERFILE_PATH }} - cache-from: type=gha - cache-to: type=gha,mode=max - - dispatch-action: - needs: container-build-push - runs-on: ubuntu-latest - steps: - - name: Get latest commit info (latest) - if: github.event_name == 'push' - run: | - LATEST_COMMIT_HASH=$(echo ${{ github.event.after }} | cut -b -7) - echo "LATEST_COMMIT_HASH=${LATEST_COMMIT_HASH}" >> $GITHUB_ENV - - - name: Dispatch event (latest) - if: github.event_name == 'push' && needs.container-build-push.outputs.prowler_version_major == '3' - run: | - curl https://api.github.com/repos/${{ secrets.DISPATCH_OWNER }}/${{ secrets.DISPATCH_REPO }}/dispatches \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - --data '{"event_type":"dispatch","client_payload":{"version":"v3-latest", "tag": "${{ env.LATEST_COMMIT_HASH }}"}}' - - - name: Dispatch event (release) - if: github.event_name == 'release' && needs.container-build-push.outputs.prowler_version_major == '3' - run: | - curl https://api.github.com/repos/${{ secrets.DISPATCH_OWNER }}/${{ secrets.DISPATCH_REPO }}/dispatches \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - --data '{"event_type":"dispatch","client_payload":{"version":"release", "tag":"${{ needs.container-build-push.outputs.prowler_version }}"}}' diff --git a/.github/workflows/sdk-bump-version.yml b/.github/workflows/sdk-bump-version.yml index 5ec3fe8d19..0291502ab6 100644 --- a/.github/workflows/sdk-bump-version.yml +++ b/.github/workflows/sdk-bump-version.yml @@ -1,146 +1,218 @@ -name: SDK - Bump Version +name: 'SDK: Bump Version' on: release: - types: [published] + types: + - 'published' +concurrency: + group: ${{ github.workflow }}-${{ github.event.release.tag_name }} + cancel-in-progress: false env: PROWLER_VERSION: ${{ github.event.release.tag_name }} BASE_BRANCH: master jobs: - bump-version: - name: Bump Version + detect-release-type: runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: read + outputs: + is_minor: ${{ steps.detect.outputs.is_minor }} + is_patch: ${{ steps.detect.outputs.is_patch }} + major_version: ${{ steps.detect.outputs.major_version }} + minor_version: ${{ steps.detect.outputs.minor_version }} + patch_version: ${{ steps.detect.outputs.patch_version }} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Get Prowler version - shell: bash + - name: Detect release type and parse version + id: detect run: | if [[ $PROWLER_VERSION =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then MAJOR_VERSION=${BASH_REMATCH[1]} MINOR_VERSION=${BASH_REMATCH[2]} - FIX_VERSION=${BASH_REMATCH[3]} + PATCH_VERSION=${BASH_REMATCH[3]} - # Export version components to GitHub environment - echo "MAJOR_VERSION=${MAJOR_VERSION}" >> "${GITHUB_ENV}" - echo "MINOR_VERSION=${MINOR_VERSION}" >> "${GITHUB_ENV}" - echo "FIX_VERSION=${FIX_VERSION}" >> "${GITHUB_ENV}" + echo "major_version=${MAJOR_VERSION}" >> "${GITHUB_OUTPUT}" + echo "minor_version=${MINOR_VERSION}" >> "${GITHUB_OUTPUT}" + echo "patch_version=${PATCH_VERSION}" >> "${GITHUB_OUTPUT}" - if (( MAJOR_VERSION == 5 )); then - if (( FIX_VERSION == 0 )); then - echo "Minor Release: $PROWLER_VERSION" + if (( MAJOR_VERSION != 5 )); then + echo "::error::Releasing another Prowler major version, aborting..." + exit 1 + fi - # Set up next minor version for master - BUMP_VERSION_TO=${MAJOR_VERSION}.$((MINOR_VERSION + 1)).${FIX_VERSION} - echo "BUMP_VERSION_TO=${BUMP_VERSION_TO}" >> "${GITHUB_ENV}" - - TARGET_BRANCH=${BASE_BRANCH} - echo "TARGET_BRANCH=${TARGET_BRANCH}" >> "${GITHUB_ENV}" - - # Set up patch version for version branch - PATCH_VERSION_TO=${MAJOR_VERSION}.${MINOR_VERSION}.1 - echo "PATCH_VERSION_TO=${PATCH_VERSION_TO}" >> "${GITHUB_ENV}" - - VERSION_BRANCH=v${MAJOR_VERSION}.${MINOR_VERSION} - echo "VERSION_BRANCH=${VERSION_BRANCH}" >> "${GITHUB_ENV}" - - echo "Bumping to next minor version: ${BUMP_VERSION_TO} in branch ${TARGET_BRANCH}" - echo "Bumping to next patch version: ${PATCH_VERSION_TO} in branch ${VERSION_BRANCH}" - else - echo "Patch Release: $PROWLER_VERSION" - - BUMP_VERSION_TO=${MAJOR_VERSION}.${MINOR_VERSION}.$((FIX_VERSION + 1)) - echo "BUMP_VERSION_TO=${BUMP_VERSION_TO}" >> "${GITHUB_ENV}" - - TARGET_BRANCH=v${MAJOR_VERSION}.${MINOR_VERSION} - echo "TARGET_BRANCH=${TARGET_BRANCH}" >> "${GITHUB_ENV}" - - echo "Bumping to next patch version: ${BUMP_VERSION_TO} in branch ${TARGET_BRANCH}" - fi + if (( PATCH_VERSION == 0 )); then + echo "is_minor=true" >> "${GITHUB_OUTPUT}" + echo "is_patch=false" >> "${GITHUB_OUTPUT}" + echo "āœ“ Minor release detected: $PROWLER_VERSION" else - echo "Releasing another Prowler major version, aborting..." - exit 1 + echo "is_minor=false" >> "${GITHUB_OUTPUT}" + echo "is_patch=true" >> "${GITHUB_OUTPUT}" + echo "āœ“ Patch release detected: $PROWLER_VERSION" fi else - echo "Invalid version syntax: '$PROWLER_VERSION' (must be N.N.N)" >&2 + echo "::error::Invalid version syntax: '$PROWLER_VERSION' (must be X.Y.Z)" exit 1 fi - - name: Bump versions in files + bump-minor-version: + needs: detect-release-type + if: needs.detect-release-type.outputs.is_minor == 'true' + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + pull-requests: write + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Calculate next minor version run: | - echo "Using PROWLER_VERSION=$PROWLER_VERSION" - echo "Using BUMP_VERSION_TO=$BUMP_VERSION_TO" + MAJOR_VERSION=${{ needs.detect-release-type.outputs.major_version }} + MINOR_VERSION=${{ needs.detect-release-type.outputs.minor_version }} - set -e + NEXT_MINOR_VERSION=${MAJOR_VERSION}.$((MINOR_VERSION + 1)).0 + echo "NEXT_MINOR_VERSION=${NEXT_MINOR_VERSION}" >> "${GITHUB_ENV}" - echo "Bumping version in pyproject.toml ..." - sed -i "s|version = \"${PROWLER_VERSION}\"|version = \"${BUMP_VERSION_TO}\"|" pyproject.toml + echo "Current version: $PROWLER_VERSION" + echo "Next minor version: $NEXT_MINOR_VERSION" - echo "Bumping version in prowler/config/config.py ..." - sed -i "s|prowler_version = \"${PROWLER_VERSION}\"|prowler_version = \"${BUMP_VERSION_TO}\"|" prowler/config/config.py + - name: Bump versions in files for master + run: | + set -e - echo "Bumping version in .env ..." - sed -i "s|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${PROWLER_VERSION}|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${BUMP_VERSION_TO}|" .env + sed -i "s|version = \"${PROWLER_VERSION}\"|version = \"${NEXT_MINOR_VERSION}\"|" pyproject.toml + sed -i "s|prowler_version = \"${PROWLER_VERSION}\"|prowler_version = \"${NEXT_MINOR_VERSION}\"|" prowler/config/config.py + sed -i "s|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${PROWLER_VERSION}|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${NEXT_MINOR_VERSION}|" .env - git --no-pager diff + echo "Files modified:" + git --no-pager diff - - name: Create Pull Request + - name: Create PR for next minor version to master uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 with: - author: prowler-bot <179230569+prowler-bot@users.noreply.github.com> - token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} - base: ${{ env.TARGET_BRANCH }} - commit-message: "chore(release): Bump version to v${{ env.BUMP_VERSION_TO }}" - branch: "version-bump-to-v${{ env.BUMP_VERSION_TO }}" - title: "chore(release): Bump version to v${{ env.BUMP_VERSION_TO }}" - labels: no-changelog - body: | - ### Description + author: prowler-bot <179230569+prowler-bot@users.noreply.github.com> + token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} + base: master + commit-message: 'chore(release): Bump version to v${{ env.NEXT_MINOR_VERSION }}' + branch: version-bump-to-v${{ env.NEXT_MINOR_VERSION }} + title: 'chore(release): Bump version to v${{ env.NEXT_MINOR_VERSION }}' + labels: no-changelog + body: | + ### Description - Bump Prowler version to v${{ env.BUMP_VERSION_TO }} + Bump Prowler version to v${{ env.NEXT_MINOR_VERSION }} after releasing v${{ env.PROWLER_VERSION }}. - ### License + ### License - By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. + By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. - - name: Handle patch version for minor release - if: env.FIX_VERSION == '0' + - name: Checkout version branch + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + ref: v${{ needs.detect-release-type.outputs.major_version }}.${{ needs.detect-release-type.outputs.minor_version }} + + - name: Calculate first patch version run: | - echo "Using PROWLER_VERSION=$PROWLER_VERSION" - echo "Using PATCH_VERSION_TO=$PATCH_VERSION_TO" + MAJOR_VERSION=${{ needs.detect-release-type.outputs.major_version }} + MINOR_VERSION=${{ needs.detect-release-type.outputs.minor_version }} - set -e + FIRST_PATCH_VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.1 + VERSION_BRANCH=v${MAJOR_VERSION}.${MINOR_VERSION} - echo "Bumping version in pyproject.toml ..." - sed -i "s|version = \"${PROWLER_VERSION}\"|version = \"${PATCH_VERSION_TO}\"|" pyproject.toml + echo "FIRST_PATCH_VERSION=${FIRST_PATCH_VERSION}" >> "${GITHUB_ENV}" + echo "VERSION_BRANCH=${VERSION_BRANCH}" >> "${GITHUB_ENV}" - echo "Bumping version in prowler/config/config.py ..." - sed -i "s|prowler_version = \"${PROWLER_VERSION}\"|prowler_version = \"${PATCH_VERSION_TO}\"|" prowler/config/config.py + echo "First patch version: $FIRST_PATCH_VERSION" + echo "Version branch: $VERSION_BRANCH" - echo "Bumping version in .env ..." - sed -i "s|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${PROWLER_VERSION}|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${PATCH_VERSION_TO}|" .env + - name: Bump versions in files for version branch + run: | + set -e - git --no-pager diff + sed -i "s|version = \"${PROWLER_VERSION}\"|version = \"${FIRST_PATCH_VERSION}\"|" pyproject.toml + sed -i "s|prowler_version = \"${PROWLER_VERSION}\"|prowler_version = \"${FIRST_PATCH_VERSION}\"|" prowler/config/config.py + sed -i "s|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${PROWLER_VERSION}|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${FIRST_PATCH_VERSION}|" .env - - name: Create Pull Request for patch version - if: env.FIX_VERSION == '0' + echo "Files modified:" + git --no-pager diff + + - name: Create PR for first patch version to version branch uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 with: - author: prowler-bot <179230569+prowler-bot@users.noreply.github.com> - token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} - base: ${{ env.VERSION_BRANCH }} - commit-message: "chore(release): Bump version to v${{ env.PATCH_VERSION_TO }}" - branch: "version-bump-to-v${{ env.PATCH_VERSION_TO }}" - title: "chore(release): Bump version to v${{ env.PATCH_VERSION_TO }}" - labels: no-changelog - body: | - ### Description + author: prowler-bot <179230569+prowler-bot@users.noreply.github.com> + token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} + base: ${{ env.VERSION_BRANCH }} + commit-message: 'chore(release): Bump version to v${{ env.FIRST_PATCH_VERSION }}' + branch: version-bump-to-v${{ env.FIRST_PATCH_VERSION }} + title: 'chore(release): Bump version to v${{ env.FIRST_PATCH_VERSION }}' + labels: no-changelog + body: | + ### Description - Bump Prowler version to v${{ env.PATCH_VERSION_TO }} + Bump Prowler version to v${{ env.FIRST_PATCH_VERSION }} in version branch after releasing v${{ env.PROWLER_VERSION }}. - ### License + ### License - By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. + By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. + + bump-patch-version: + needs: detect-release-type + if: needs.detect-release-type.outputs.is_patch == 'true' + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + pull-requests: write + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Calculate next patch version + run: | + MAJOR_VERSION=${{ needs.detect-release-type.outputs.major_version }} + MINOR_VERSION=${{ needs.detect-release-type.outputs.minor_version }} + PATCH_VERSION=${{ needs.detect-release-type.outputs.patch_version }} + + NEXT_PATCH_VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.$((PATCH_VERSION + 1)) + VERSION_BRANCH=v${MAJOR_VERSION}.${MINOR_VERSION} + + echo "NEXT_PATCH_VERSION=${NEXT_PATCH_VERSION}" >> "${GITHUB_ENV}" + echo "VERSION_BRANCH=${VERSION_BRANCH}" >> "${GITHUB_ENV}" + + echo "Current version: $PROWLER_VERSION" + echo "Next patch version: $NEXT_PATCH_VERSION" + echo "Target branch: $VERSION_BRANCH" + + - name: Bump versions in files for version branch + run: | + set -e + + sed -i "s|version = \"${PROWLER_VERSION}\"|version = \"${NEXT_PATCH_VERSION}\"|" pyproject.toml + sed -i "s|prowler_version = \"${PROWLER_VERSION}\"|prowler_version = \"${NEXT_PATCH_VERSION}\"|" prowler/config/config.py + sed -i "s|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${PROWLER_VERSION}|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${NEXT_PATCH_VERSION}|" .env + + echo "Files modified:" + git --no-pager diff + + - name: Create PR for next patch version to version branch + uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 + with: + author: prowler-bot <179230569+prowler-bot@users.noreply.github.com> + token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} + base: ${{ env.VERSION_BRANCH }} + commit-message: 'chore(release): Bump version to v${{ env.NEXT_PATCH_VERSION }}' + branch: version-bump-to-v${{ env.NEXT_PATCH_VERSION }} + title: 'chore(release): Bump version to v${{ env.NEXT_PATCH_VERSION }}' + labels: no-changelog + body: | + ### Description + + Bump Prowler version to v${{ env.NEXT_PATCH_VERSION }} after releasing v${{ env.PROWLER_VERSION }}. + + ### License + + By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. diff --git a/.github/workflows/sdk-code-quality.yml b/.github/workflows/sdk-code-quality.yml new file mode 100644 index 0000000000..b32324d8cb --- /dev/null +++ b/.github/workflows/sdk-code-quality.yml @@ -0,0 +1,90 @@ +name: 'SDK: Code Quality' + +on: + push: + branches: + - 'master' + - 'v5.*' + pull_request: + branches: + - 'master' + - 'v5.*' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + sdk-code-quality: + if: github.repository == 'prowler-cloud/prowler' + runs-on: ubuntu-latest + timeout-minutes: 20 + permissions: + contents: read + strategy: + matrix: + python-version: + - '3.9' + - '3.10' + - '3.11' + - '3.12' + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Check for SDK changes + id: check-changes + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: ./** + files_ignore: | + .github/** + prowler/CHANGELOG.md + docs/** + permissions/** + api/** + ui/** + dashboard/** + mcp_server/** + README.md + mkdocs.yml + .backportrc.json + .env + docker-compose* + examples/** + .gitignore + contrib/** + + - name: Install Poetry + if: steps.check-changes.outputs.any_changed == 'true' + run: pipx install poetry==2.1.1 + + - name: Set up Python ${{ matrix.python-version }} + if: steps.check-changes.outputs.any_changed == 'true' + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: ${{ matrix.python-version }} + cache: 'poetry' + + - name: Install dependencies + if: steps.check-changes.outputs.any_changed == 'true' + run: | + poetry install --no-root + poetry run pip list + + - name: Check Poetry lock file + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry check --lock + + - name: Lint with flake8 + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run flake8 . --ignore=E266,W503,E203,E501,W605,E128 --exclude contrib,ui,api + + - name: Check format with black + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run black --exclude api ui --check . + + - name: Lint with pylint + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run pylint --disable=W,C,R,E -j 0 -rn -sn prowler/ diff --git a/.github/workflows/sdk-codeql.yml b/.github/workflows/sdk-codeql.yml index 3f720a23d5..590ba52d34 100644 --- a/.github/workflows/sdk-codeql.yml +++ b/.github/workflows/sdk-codeql.yml @@ -1,44 +1,41 @@ -# 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: SDK - CodeQL +name: 'SDK: CodeQL' on: push: branches: - - "master" - - "v3" - - "v4.*" - - "v5.*" - paths-ignore: - - 'ui/**' - - 'api/**' - - '.github/**' + - 'master' + - 'v5.*' + paths: + - 'prowler/**' + - 'tests/**' + - 'pyproject.toml' + - '.github/workflows/sdk-codeql.yml' + - '.github/codeql/sdk-codeql-config.yml' + - '!prowler/CHANGELOG.md' pull_request: branches: - - "master" - - "v3" - - "v4.*" - - "v5.*" - paths-ignore: - - 'ui/**' - - 'api/**' - - '.github/**' + - 'master' + - 'v5.*' + paths: + - 'prowler/**' + - 'tests/**' + - 'pyproject.toml' + - '.github/workflows/sdk-codeql.yml' + - '.github/codeql/sdk-codeql-config.yml' + - '!prowler/CHANGELOG.md' schedule: - cron: '00 12 * * *' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: - analyze: - name: Analyze + sdk-analyze: + if: github.repository == 'prowler-cloud/prowler' + name: CodeQL Security Analysis runs-on: ubuntu-latest + timeout-minutes: 30 permissions: actions: read contents: read @@ -47,21 +44,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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5 - with: - languages: ${{ matrix.language }} - config-file: ./.github/codeql/sdk-codeql-config.yml + - name: Initialize CodeQL + uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + with: + languages: ${{ matrix.language }} + config-file: ./.github/codeql/sdk-codeql-config.yml - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5 - with: - category: "/language:${{matrix.language}}" + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + with: + category: '/language:${{ matrix.language }}' diff --git a/.github/workflows/sdk-container-build-push.yml b/.github/workflows/sdk-container-build-push.yml new file mode 100644 index 0000000000..72b57ac246 --- /dev/null +++ b/.github/workflows/sdk-container-build-push.yml @@ -0,0 +1,266 @@ +name: 'SDK: Container Build and Push' + +on: + push: + branches: + - 'v3' # For v3-latest + - 'v4.6' # For v4-latest + - 'master' # For latest + paths-ignore: + - '.github/**' + - '!.github/workflows/sdk-container-build-push.yml' + - 'README.md' + - 'docs/**' + - 'ui/**' + - 'api/**' + release: + types: + - 'published' + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +env: + # Container configuration + IMAGE_NAME: prowler + DOCKERFILE_PATH: ./Dockerfile + + # Python configuration + PYTHON_VERSION: '3.12' + + # Tags (dynamically set based on version) + LATEST_TAG: latest + STABLE_TAG: stable + + # Container registries + PROWLERCLOUD_DOCKERHUB_REPOSITORY: prowlercloud + PROWLERCLOUD_DOCKERHUB_IMAGE: prowler + + # AWS configuration (for ECR) + AWS_REGION: us-east-1 + +jobs: + container-build-push: + if: github.repository == 'prowler-cloud/prowler' + runs-on: ${{ matrix.runner }} + strategy: + matrix: + include: + - platform: linux/amd64 + runner: ubuntu-latest + arch: amd64 + - platform: linux/arm64 + runner: ubuntu-24.04-arm + arch: arm64 + timeout-minutes: 45 + permissions: + contents: read + packages: write + outputs: + prowler_version: ${{ steps.get-prowler-version.outputs.prowler_version }} + prowler_version_major: ${{ steps.get-prowler-version.outputs.prowler_version_major }} + latest_tag: ${{ steps.get-prowler-version.outputs.latest_tag }} + stable_tag: ${{ steps.get-prowler-version.outputs.stable_tag }} + env: + POETRY_VIRTUALENVS_CREATE: 'false' + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Install Poetry + run: | + pipx install poetry==2.1.1 + pipx inject poetry poetry-bumpversion + + - name: Get Prowler version and set tags + id: get-prowler-version + run: | + PROWLER_VERSION="$(poetry version -s 2>/dev/null)" + echo "prowler_version=${PROWLER_VERSION}" >> "${GITHUB_OUTPUT}" + echo "PROWLER_VERSION=${PROWLER_VERSION}" >> "${GITHUB_ENV}" + + # Extract major version + PROWLER_VERSION_MAJOR="${PROWLER_VERSION%%.*}" + echo "prowler_version_major=${PROWLER_VERSION_MAJOR}" >> "${GITHUB_OUTPUT}" + echo "PROWLER_VERSION_MAJOR=${PROWLER_VERSION_MAJOR}" >> "${GITHUB_ENV}" + + # Set version-specific tags + case ${PROWLER_VERSION_MAJOR} in + 3) + echo "LATEST_TAG=v3-latest" >> "${GITHUB_ENV}" + echo "STABLE_TAG=v3-stable" >> "${GITHUB_ENV}" + echo "latest_tag=v3-latest" >> "${GITHUB_OUTPUT}" + echo "stable_tag=v3-stable" >> "${GITHUB_OUTPUT}" + echo "āœ“ Prowler v3 detected - tags: v3-latest, v3-stable" + ;; + 4) + echo "LATEST_TAG=v4-latest" >> "${GITHUB_ENV}" + echo "STABLE_TAG=v4-stable" >> "${GITHUB_ENV}" + echo "latest_tag=v4-latest" >> "${GITHUB_OUTPUT}" + echo "stable_tag=v4-stable" >> "${GITHUB_OUTPUT}" + echo "āœ“ Prowler v4 detected - tags: v4-latest, v4-stable" + ;; + 5) + echo "LATEST_TAG=latest" >> "${GITHUB_ENV}" + echo "STABLE_TAG=stable" >> "${GITHUB_ENV}" + echo "latest_tag=latest" >> "${GITHUB_OUTPUT}" + echo "stable_tag=stable" >> "${GITHUB_OUTPUT}" + echo "āœ“ Prowler v5 detected - tags: latest, stable" + ;; + *) + echo "::error::Unsupported Prowler major version: ${PROWLER_VERSION_MAJOR}" + exit 1 + ;; + esac + + - name: Login to DockerHub + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Login to Public ECR + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 + with: + registry: public.ecr.aws + username: ${{ secrets.PUBLIC_ECR_AWS_ACCESS_KEY_ID }} + password: ${{ secrets.PUBLIC_ECR_AWS_SECRET_ACCESS_KEY }} + env: + AWS_REGION: ${{ env.AWS_REGION }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Build and push SDK container for ${{ matrix.arch }} + if: github.event_name == 'push' || github.event_name == 'release' + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: . + file: ${{ env.DOCKERFILE_PATH }} + push: true + platforms: ${{ matrix.platform }} + tags: | + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.LATEST_TAG }}-${{ matrix.arch }} + cache-from: type=gha,scope=${{ matrix.arch }} + cache-to: type=gha,mode=max,scope=${{ matrix.arch }} + + - name: Notify container push started + if: github.event_name == 'release' + uses: ./.github/actions/slack-notification + env: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_PLATFORM_DEPLOYMENTS }} + COMPONENT: SDK + RELEASE_TAG: ${{ env.PROWLER_VERSION }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + payload-file-path: "./.github/scripts/slack-messages/container-release-started.json" + + - name: Notify container push completed + if: github.event_name == 'release' && always() + uses: ./.github/actions/slack-notification + env: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_PLATFORM_DEPLOYMENTS }} + COMPONENT: SDK + RELEASE_TAG: ${{ env.PROWLER_VERSION }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + payload-file-path: "./.github/scripts/slack-messages/container-release-completed.json" + step-outcome: ${{ steps.container-push.outcome }} + + # Create and push multi-architecture manifest + create-manifest: + needs: [container-build-push] + if: github.event_name == 'push' || github.event_name == 'release' + runs-on: ubuntu-latest + + steps: + - name: Login to DockerHub + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Create and push manifests for push event + if: github.event_name == 'push' + run: | + docker buildx imagetools create \ + -t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.container-build-push.outputs.latest_tag }} \ + -t ${{ secrets.DOCKER_HUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.container-build-push.outputs.latest_tag }} \ + -t ${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.container-build-push.outputs.latest_tag }} \ + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.container-build-push.outputs.latest_tag }}-amd64 \ + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.container-build-push.outputs.latest_tag }}-arm64 + + - name: Create and push manifests for release event + if: github.event_name == 'release' + run: | + docker buildx imagetools create \ + -t ${{ secrets.DOCKER_HUB_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ needs.container-build-push.outputs.prowler_version }} \ + -t ${{ secrets.DOCKER_HUB_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ needs.container-build-push.outputs.stable_tag }} \ + -t ${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ needs.container-build-push.outputs.prowler_version }} \ + -t ${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.IMAGE_NAME }}:${{ needs.container-build-push.outputs.stable_tag }} \ + -t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.container-build-push.outputs.prowler_version }} \ + -t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.container-build-push.outputs.stable_tag }} \ + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.container-build-push.outputs.latest_tag }}-amd64 \ + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.container-build-push.outputs.latest_tag }}-arm64 + + - name: Install regctl + if: always() + uses: regclient/actions/regctl-installer@main + + - name: Cleanup intermediate architecture tags + if: always() + run: | + echo "Cleaning up intermediate tags..." + regctl tag delete "${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.container-build-push.outputs.latest_tag }}-amd64" || true + regctl tag delete "${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.container-build-push.outputs.latest_tag }}-arm64" || true + echo "Cleanup completed" + + dispatch-v3-deployment: + if: needs.container-build-push.outputs.prowler_version_major == '3' + needs: container-build-push + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: read + + steps: + - name: Calculate short SHA + id: short-sha + run: echo "short_sha=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT + + - name: Dispatch v3 deployment (latest) + if: github.event_name == 'push' + uses: peter-evans/repository-dispatch@5fc4efd1a4797ddb68ffd0714a238564e4cc0e6f # v4.0.0 + with: + token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} + repository: ${{ secrets.DISPATCH_OWNER }}/${{ secrets.DISPATCH_REPO }} + event-type: dispatch + client-payload: '{"version":"v3-latest","tag":"${{ steps.short-sha.outputs.short_sha }}"}' + + - name: Dispatch v3 deployment (release) + if: github.event_name == 'release' + uses: peter-evans/repository-dispatch@5fc4efd1a4797ddb68ffd0714a238564e4cc0e6f # v4.0.0 + with: + token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} + repository: ${{ secrets.DISPATCH_OWNER }}/${{ secrets.DISPATCH_REPO }} + event-type: dispatch + client-payload: '{"version":"release","tag":"${{ needs.container-build-push.outputs.prowler_version }}"}' diff --git a/.github/workflows/sdk-container-checks.yml b/.github/workflows/sdk-container-checks.yml new file mode 100644 index 0000000000..4e8a7cf2ad --- /dev/null +++ b/.github/workflows/sdk-container-checks.yml @@ -0,0 +1,103 @@ +name: 'SDK: Container Checks' + +on: + push: + branches: + - 'master' + - 'v5.*' + pull_request: + branches: + - 'master' + - 'v5.*' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + IMAGE_NAME: prowler + +jobs: + sdk-dockerfile-lint: + if: github.repository == 'prowler-cloud/prowler' + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Check if Dockerfile changed + id: dockerfile-changed + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: Dockerfile + + - name: Lint Dockerfile with Hadolint + if: steps.dockerfile-changed.outputs.any_changed == 'true' + uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0 + with: + dockerfile: Dockerfile + ignore: DL3013 + + sdk-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: Check for SDK changes + id: check-changes + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: ./** + files_ignore: | + .github/** + prowler/CHANGELOG.md + docs/** + permissions/** + api/** + ui/** + dashboard/** + mcp_server/** + README.md + mkdocs.yml + .backportrc.json + .env + docker-compose* + examples/** + .gitignore + contrib/** + + - name: Set up Docker Buildx + if: steps.check-changes.outputs.any_changed == 'true' + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Build SDK container + if: steps.check-changes.outputs.any_changed == 'true' + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: . + push: false + load: true + tags: ${{ env.IMAGE_NAME }}:${{ github.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Scan SDK container with Trivy + if: steps.check-changes.outputs.any_changed == 'true' + 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/sdk-pull-request.yml b/.github/workflows/sdk-pull-request.yml deleted file mode 100644 index f6d9df6cd5..0000000000 --- a/.github/workflows/sdk-pull-request.yml +++ /dev/null @@ -1,256 +0,0 @@ -name: SDK - Pull Request - -on: - push: - branches: - - "master" - - "v3" - - "v4.*" - - "v5.*" - pull_request: - branches: - - "master" - - "v3" - - "v4.*" - - "v5.*" -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Test if changes are in not ignored paths - id: are-non-ignored-files-changed - uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5 - with: - files: ./** - files_ignore: | - .github/** - docs/** - permissions/** - api/** - ui/** - prowler/CHANGELOG.md - README.md - mkdocs.yml - .backportrc.json - .env - docker-compose* - examples/** - .gitignore - - - name: Install poetry - 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: Set up Python ${{ matrix.python-version }} - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 - with: - python-version: ${{ matrix.python-version }} - cache: "poetry" - - - name: Install dependencies - 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 - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry check --lock - - - name: Lint with flake8 - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry run flake8 . --ignore=E266,W503,E203,E501,W605,E128 --exclude contrib,ui,api - - - name: Checking format with black - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry run black --exclude api ui --check . - - - name: Lint with pylint - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry run pylint --disable=W,C,R,E -j 0 -rn -sn prowler/ - - - name: Bandit - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry run bandit -q -lll -x '*_test.py,./contrib/,./api/,./ui' -r . - - - name: Safety - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry run safety check --ignore 70612 -r pyproject.toml - - - name: Vulture - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry run vulture --exclude "contrib,api,ui" --min-confidence 100 . - - - name: Dockerfile - Check if Dockerfile has changed - id: dockerfile-changed-files - uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5 - with: - files: | - Dockerfile - - - name: Hadolint - if: steps.dockerfile-changed-files.outputs.any_changed == 'true' - run: | - /tmp/hadolint Dockerfile --ignore=DL3013 - - # Test AWS - - name: AWS - Check if any file has changed - id: aws-changed-files - uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5 - with: - files: | - ./prowler/providers/aws/** - ./tests/providers/aws/** - .poetry.lock - - - name: AWS - Test - if: steps.aws-changed-files.outputs.any_changed == 'true' - run: | - poetry run pytest -n auto --cov=./prowler/providers/aws --cov-report=xml:aws_coverage.xml tests/providers/aws - - # Test Azure - - name: Azure - Check if any file has changed - id: azure-changed-files - uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5 - with: - files: | - ./prowler/providers/azure/** - ./tests/providers/azure/** - .poetry.lock - - - name: Azure - Test - if: steps.azure-changed-files.outputs.any_changed == 'true' - run: | - poetry run pytest -n auto --cov=./prowler/providers/azure --cov-report=xml:azure_coverage.xml tests/providers/azure - - # Test GCP - - name: GCP - Check if any file has changed - id: gcp-changed-files - uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5 - with: - files: | - ./prowler/providers/gcp/** - ./tests/providers/gcp/** - .poetry.lock - - - name: GCP - Test - if: steps.gcp-changed-files.outputs.any_changed == 'true' - run: | - poetry run pytest -n auto --cov=./prowler/providers/gcp --cov-report=xml:gcp_coverage.xml tests/providers/gcp - - # Test Kubernetes - - name: Kubernetes - Check if any file has changed - id: kubernetes-changed-files - uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5 - with: - files: | - ./prowler/providers/kubernetes/** - ./tests/providers/kubernetes/** - .poetry.lock - - - name: Kubernetes - Test - if: steps.kubernetes-changed-files.outputs.any_changed == 'true' - run: | - poetry run pytest -n auto --cov=./prowler/providers/kubernetes --cov-report=xml:kubernetes_coverage.xml tests/providers/kubernetes - - # Test GitHub - - name: GitHub - Check if any file has changed - id: github-changed-files - uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5 - with: - files: | - ./prowler/providers/github/** - ./tests/providers/github/** - .poetry.lock - - - name: GitHub - Test - if: steps.github-changed-files.outputs.any_changed == 'true' - run: | - poetry run pytest -n auto --cov=./prowler/providers/github --cov-report=xml:github_coverage.xml tests/providers/github - - # Test NHN - - name: NHN - Check if any file has changed - id: nhn-changed-files - uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5 - with: - files: | - ./prowler/providers/nhn/** - ./tests/providers/nhn/** - .poetry.lock - - - name: NHN - Test - if: steps.nhn-changed-files.outputs.any_changed == 'true' - run: | - poetry run pytest -n auto --cov=./prowler/providers/nhn --cov-report=xml:nhn_coverage.xml tests/providers/nhn - - # Test M365 - - name: M365 - Check if any file has changed - id: m365-changed-files - uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5 - with: - files: | - ./prowler/providers/m365/** - ./tests/providers/m365/** - .poetry.lock - - - name: M365 - Test - if: steps.m365-changed-files.outputs.any_changed == 'true' - run: | - poetry run pytest -n auto --cov=./prowler/providers/m365 --cov-report=xml:m365_coverage.xml tests/providers/m365 - - # Test IaC - - name: IaC - Check if any file has changed - id: iac-changed-files - uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5 - with: - files: | - ./prowler/providers/iac/** - ./tests/providers/iac/** - .poetry.lock - - - name: IaC - Test - if: steps.iac-changed-files.outputs.any_changed == 'true' - run: | - poetry run pytest -n auto --cov=./prowler/providers/iac --cov-report=xml:iac_coverage.xml tests/providers/iac - - # Common Tests - - name: Lib - Test - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry run pytest -n auto --cov=./prowler/lib --cov-report=xml:lib_coverage.xml tests/lib - - - name: Config - Test - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry run pytest -n auto --cov=./prowler/config --cov-report=xml:config_coverage.xml tests/config - - # Codecov - - name: Upload coverage reports to Codecov - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - with: - flags: prowler - files: ./aws_coverage.xml,./azure_coverage.xml,./gcp_coverage.xml,./kubernetes_coverage.xml,./github_coverage.xml,./nhn_coverage.xml,./m365_coverage.xml,./lib_coverage.xml,./config_coverage.xml diff --git a/.github/workflows/sdk-pypi-release.yml b/.github/workflows/sdk-pypi-release.yml index 07d6ca5a6f..0f74ba054c 100644 --- a/.github/workflows/sdk-pypi-release.yml +++ b/.github/workflows/sdk-pypi-release.yml @@ -1,98 +1,119 @@ -name: SDK - PyPI release +name: 'SDK: PyPI Release' on: release: - types: [published] + types: + - 'published' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.release.tag_name }} + cancel-in-progress: false env: RELEASE_TAG: ${{ github.event.release.tag_name }} - PYTHON_VERSION: 3.11 - # CACHE: "poetry" + PYTHON_VERSION: '3.12' jobs: - repository-check: - name: Repository check + validate-release: + if: github.repository == 'prowler-cloud/prowler' runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: read outputs: - is_repo: ${{ steps.repository_check.outputs.is_repo }} - steps: - - name: Repository check - id: repository_check - working-directory: /tmp - run: | - if [[ ${{ github.repository }} == "prowler-cloud/prowler" ]] - then - echo "is_repo=true" >> "${GITHUB_OUTPUT}" - else - echo "This action only runs for prowler-cloud/prowler" - echo "is_repo=false" >> "${GITHUB_OUTPUT}" - fi + prowler_version: ${{ steps.parse-version.outputs.version }} + major_version: ${{ steps.parse-version.outputs.major }} - release-prowler-job: - runs-on: ubuntu-latest - needs: repository-check - if: needs.repository-check.outputs.is_repo == 'true' - env: - POETRY_VIRTUALENVS_CREATE: "false" - name: Release Prowler to PyPI steps: - - name: Repository check - working-directory: /tmp - run: | - if [[ "${{ github.repository }}" != "prowler-cloud/prowler" ]]; then - echo "This action only runs for prowler-cloud/prowler" - exit 1 - fi - - - name: Get Prowler version + - name: Parse and validate version + id: parse-version run: | PROWLER_VERSION="${{ env.RELEASE_TAG }}" + echo "version=${PROWLER_VERSION}" >> "${GITHUB_OUTPUT}" - case ${PROWLER_VERSION%%.*} in - 3) - echo "Releasing Prowler v3 with tag ${PROWLER_VERSION}" + # Extract major version + MAJOR_VERSION="${PROWLER_VERSION%%.*}" + echo "major=${MAJOR_VERSION}" >> "${GITHUB_OUTPUT}" + + # Validate major version + case ${MAJOR_VERSION} in + 3|4|5) + echo "āœ“ Releasing Prowler v${MAJOR_VERSION} with tag ${PROWLER_VERSION}" ;; - 4) - echo "Releasing Prowler v4 with tag ${PROWLER_VERSION}" - ;; - 5) - echo "Releasing Prowler v5 with tag ${PROWLER_VERSION}" - ;; - *) - echo "Releasing another Prowler major version, aborting..." + *) + echo "::error::Unsupported Prowler major version: ${MAJOR_VERSION}" exit 1 ;; esac - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + publish-prowler: + needs: validate-release + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + id-token: write + environment: + name: pypi-prowler + url: https://pypi.org/project/prowler/${{ needs.validate-release.outputs.prowler_version }}/ - - name: Install dependencies - run: | - pipx install poetry==2.1.1 + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - name: Setup Python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + - name: Install Poetry + run: pipx install poetry==2.1.1 + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 with: python-version: ${{ env.PYTHON_VERSION }} - # cache: ${{ env.CACHE }} + cache: 'poetry' - name: Build Prowler package - run: | - poetry build + run: poetry build - name: Publish Prowler package to PyPI - run: | - poetry config pypi-token.pypi ${{ secrets.PYPI_API_TOKEN }} - poetry publish + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 + with: + print-hash: true - - name: Replicate PyPI package + publish-prowler-cloud: + needs: validate-release + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + id-token: write + environment: + name: pypi-prowler-cloud + url: https://pypi.org/project/prowler-cloud/${{ needs.validate-release.outputs.prowler_version }}/ + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Install Poetry + run: pipx install poetry==2.1.1 + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: ${{ env.PYTHON_VERSION }} + cache: 'poetry' + + - name: Install toml package + run: pip install toml + + - name: Replicate PyPI package for prowler-cloud run: | - rm -rf ./dist && rm -rf ./build && rm -rf prowler.egg-info - pip install toml + rm -rf ./dist ./build prowler.egg-info python util/replicate_pypi_package.py - poetry build + + - name: Build prowler-cloud package + run: poetry build - name: Publish prowler-cloud package to PyPI - run: | - poetry config pypi-token.pypi ${{ secrets.PYPI_API_TOKEN }} - poetry publish + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 + with: + print-hash: true diff --git a/.github/workflows/sdk-refresh-aws-services-regions.yml b/.github/workflows/sdk-refresh-aws-services-regions.yml index 036b75bb84..884b677294 100644 --- a/.github/workflows/sdk-refresh-aws-services-regions.yml +++ b/.github/workflows/sdk-refresh-aws-services-regions.yml @@ -1,68 +1,90 @@ -# This is a basic workflow to help you get started with Actions - -name: SDK - Refresh AWS services' regions +name: 'SDK: Refresh AWS Regions' on: schedule: - - cron: "0 9 * * 1" # runs at 09:00 UTC every Monday + - cron: '0 9 * * 1' # Every Monday at 09:00 UTC + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false env: - GITHUB_BRANCH: "master" - AWS_REGION_DEV: us-east-1 + PYTHON_VERSION: '3.12' + AWS_REGION: 'us-east-1' -# A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on + refresh-aws-regions: + if: github.repository == 'prowler-cloud/prowler' runs-on: ubuntu-latest + timeout-minutes: 15 permissions: id-token: write pull-requests: write contents: write - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - ref: ${{ env.GITHUB_BRANCH }} - - name: setup python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: - python-version: 3.9 #install the python needed + ref: 'master' + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: ${{ env.PYTHON_VERSION }} + cache: 'pip' - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install boto3 + run: pip install boto3 - - name: Configure AWS Credentials -- DEV - uses: aws-actions/configure-aws-credentials@b47578312673ae6fa5b5096b330d9fbac3d116df # v4.2.1 + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5.1.0 with: - aws-region: ${{ env.AWS_REGION_DEV }} + aws-region: ${{ env.AWS_REGION }} role-to-assume: ${{ secrets.DEV_IAM_ROLE_ARN }} - role-session-name: refresh-AWS-regions-dev + role-session-name: prowler-refresh-aws-regions - # Runs a single command using the runners shell - - name: Run a one-line script - run: python3 util/update_aws_services_regions.py + - name: Update AWS services regions + run: python util/update_aws_services_regions.py - # Create pull request - - name: Create Pull Request + - name: Create pull request + id: create-pr uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 with: - author: prowler-bot <179230569+prowler-bot@users.noreply.github.com> token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} - commit-message: "feat(regions_update): Update regions for AWS services" - branch: "aws-services-regions-updated-${{ github.sha }}" - labels: "status/waiting-for-revision, severity/low, provider/aws" - title: "chore(regions_update): Changes in regions for AWS services" + author: 'prowler-bot <179230569+prowler-bot@users.noreply.github.com>' + committer: 'github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>' + commit-message: 'feat(aws): update regions for AWS services' + branch: 'aws-regions-update-${{ github.run_number }}' + title: 'feat(aws): Update regions for AWS services' + labels: | + status/waiting-for-revision + severity/low + provider/aws + no-changelog body: | ### Description - This PR updates the regions for AWS services. + Automated update of AWS service regions from the official AWS IP ranges. + + **Trigger:** ${{ github.event_name == 'schedule' && 'Scheduled (weekly)' || github.event_name == 'workflow_dispatch' && 'Manual' || 'Workflow update' }} + **Run:** [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) + + ### Checklist + + - [x] This is an automated update from AWS official sources + - [x] No manual review of region data required ### License By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. + + - name: PR creation result + run: | + if [[ "${{ steps.create-pr.outputs.pull-request-number }}" ]]; then + echo "āœ“ Pull request #${{ steps.create-pr.outputs.pull-request-number }} created successfully" + echo "URL: ${{ steps.create-pr.outputs.pull-request-url }}" + else + echo "āœ“ No changes detected - AWS regions are up to date" + fi diff --git a/.github/workflows/sdk-security.yml b/.github/workflows/sdk-security.yml new file mode 100644 index 0000000000..a15bd2539f --- /dev/null +++ b/.github/workflows/sdk-security.yml @@ -0,0 +1,77 @@ +name: 'SDK: Security' + +on: + push: + branches: + - 'master' + - 'v5.*' + pull_request: + branches: + - 'master' + - 'v5.*' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + sdk-security-scans: + 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: Check for SDK changes + id: check-changes + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: ./** + files_ignore: | + .github/** + prowler/CHANGELOG.md + docs/** + permissions/** + api/** + ui/** + dashboard/** + mcp_server/** + README.md + mkdocs.yml + .backportrc.json + .env + docker-compose* + examples/** + .gitignore + contrib/** + + - name: Install Poetry + if: steps.check-changes.outputs.any_changed == 'true' + run: pipx install poetry==2.1.1 + + - name: Set up Python 3.12 + if: steps.check-changes.outputs.any_changed == 'true' + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: '3.12' + cache: 'poetry' + + - name: Install dependencies + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry install --no-root + + - name: Security scan with Bandit + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run bandit -q -lll -x '*_test.py,./contrib/,./api/,./ui' -r . + + - name: Security scan with Safety + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run safety check --ignore 70612 -r pyproject.toml + + - name: Dead code detection with Vulture + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run vulture --exclude "contrib,api,ui" --min-confidence 100 . diff --git a/.github/workflows/sdk-tests.yml b/.github/workflows/sdk-tests.yml new file mode 100644 index 0000000000..b01c5e7778 --- /dev/null +++ b/.github/workflows/sdk-tests.yml @@ -0,0 +1,360 @@ +name: 'SDK: Tests' + +on: + push: + branches: + - 'master' + - 'v5.*' + pull_request: + branches: + - 'master' + - 'v5.*' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + sdk-tests: + if: github.repository == 'prowler-cloud/prowler' + runs-on: ubuntu-latest + timeout-minutes: 120 + permissions: + contents: read + strategy: + matrix: + python-version: + - '3.9' + - '3.10' + - '3.11' + - '3.12' + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Check for SDK changes + id: check-changes + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: ./** + files_ignore: | + .github/** + prowler/CHANGELOG.md + docs/** + permissions/** + api/** + ui/** + dashboard/** + mcp_server/** + README.md + mkdocs.yml + .backportrc.json + .env + docker-compose* + examples/** + .gitignore + contrib/** + + - name: Install Poetry + if: steps.check-changes.outputs.any_changed == 'true' + run: pipx install poetry==2.1.1 + + - name: Set up Python ${{ matrix.python-version }} + if: steps.check-changes.outputs.any_changed == 'true' + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: ${{ matrix.python-version }} + cache: 'poetry' + + - name: Install dependencies + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry install --no-root + + # AWS Provider + - name: Check if AWS files changed + if: steps.check-changes.outputs.any_changed == 'true' + id: changed-aws + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + ./prowler/**/aws/** + ./tests/**/aws/** + ./poetry.lock + + - name: Run AWS tests + if: steps.changed-aws.outputs.any_changed == 'true' + run: poetry run pytest -n auto --cov=./prowler/providers/aws --cov-report=xml:aws_coverage.xml tests/providers/aws + + - name: Upload AWS coverage to Codecov + if: steps.changed-aws.outputs.any_changed == 'true' + uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + flags: prowler-py${{ matrix.python-version }}-aws + files: ./aws_coverage.xml + + # Azure Provider + - name: Check if Azure files changed + if: steps.check-changes.outputs.any_changed == 'true' + id: changed-azure + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + ./prowler/**/azure/** + ./tests/**/azure/** + ./poetry.lock + + - name: Run Azure tests + if: steps.changed-azure.outputs.any_changed == 'true' + run: poetry run pytest -n auto --cov=./prowler/providers/azure --cov-report=xml:azure_coverage.xml tests/providers/azure + + - name: Upload Azure coverage to Codecov + if: steps.changed-azure.outputs.any_changed == 'true' + uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + flags: prowler-py${{ matrix.python-version }}-azure + files: ./azure_coverage.xml + + # GCP Provider + - name: Check if GCP files changed + if: steps.check-changes.outputs.any_changed == 'true' + id: changed-gcp + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + ./prowler/**/gcp/** + ./tests/**/gcp/** + ./poetry.lock + + - name: Run GCP tests + if: steps.changed-gcp.outputs.any_changed == 'true' + run: poetry run pytest -n auto --cov=./prowler/providers/gcp --cov-report=xml:gcp_coverage.xml tests/providers/gcp + + - name: Upload GCP coverage to Codecov + if: steps.changed-gcp.outputs.any_changed == 'true' + uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + flags: prowler-py${{ matrix.python-version }}-gcp + files: ./gcp_coverage.xml + + # Kubernetes Provider + - name: Check if Kubernetes files changed + if: steps.check-changes.outputs.any_changed == 'true' + id: changed-kubernetes + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + ./prowler/**/kubernetes/** + ./tests/**/kubernetes/** + ./poetry.lock + + - name: Run Kubernetes tests + if: steps.changed-kubernetes.outputs.any_changed == 'true' + run: poetry run pytest -n auto --cov=./prowler/providers/kubernetes --cov-report=xml:kubernetes_coverage.xml tests/providers/kubernetes + + - name: Upload Kubernetes coverage to Codecov + if: steps.changed-kubernetes.outputs.any_changed == 'true' + uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + flags: prowler-py${{ matrix.python-version }}-kubernetes + files: ./kubernetes_coverage.xml + + # GitHub Provider + - name: Check if GitHub files changed + if: steps.check-changes.outputs.any_changed == 'true' + id: changed-github + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + ./prowler/**/github/** + ./tests/**/github/** + ./poetry.lock + + - name: Run GitHub tests + if: steps.changed-github.outputs.any_changed == 'true' + run: poetry run pytest -n auto --cov=./prowler/providers/github --cov-report=xml:github_coverage.xml tests/providers/github + + - name: Upload GitHub coverage to Codecov + if: steps.changed-github.outputs.any_changed == 'true' + uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + flags: prowler-py${{ matrix.python-version }}-github + files: ./github_coverage.xml + + # NHN Provider + - name: Check if NHN files changed + if: steps.check-changes.outputs.any_changed == 'true' + id: changed-nhn + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + ./prowler/**/nhn/** + ./tests/**/nhn/** + ./poetry.lock + + - name: Run NHN tests + if: steps.changed-nhn.outputs.any_changed == 'true' + run: poetry run pytest -n auto --cov=./prowler/providers/nhn --cov-report=xml:nhn_coverage.xml tests/providers/nhn + + - name: Upload NHN coverage to Codecov + if: steps.changed-nhn.outputs.any_changed == 'true' + uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + flags: prowler-py${{ matrix.python-version }}-nhn + files: ./nhn_coverage.xml + + # M365 Provider + - name: Check if M365 files changed + if: steps.check-changes.outputs.any_changed == 'true' + id: changed-m365 + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + ./prowler/**/m365/** + ./tests/**/m365/** + ./poetry.lock + + - name: Run M365 tests + if: steps.changed-m365.outputs.any_changed == 'true' + run: poetry run pytest -n auto --cov=./prowler/providers/m365 --cov-report=xml:m365_coverage.xml tests/providers/m365 + + - name: Upload M365 coverage to Codecov + if: steps.changed-m365.outputs.any_changed == 'true' + uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + flags: prowler-py${{ matrix.python-version }}-m365 + files: ./m365_coverage.xml + + # IaC Provider + - name: Check if IaC files changed + if: steps.check-changes.outputs.any_changed == 'true' + id: changed-iac + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + ./prowler/**/iac/** + ./tests/**/iac/** + ./poetry.lock + + - name: Run IaC tests + if: steps.changed-iac.outputs.any_changed == 'true' + run: poetry run pytest -n auto --cov=./prowler/providers/iac --cov-report=xml:iac_coverage.xml tests/providers/iac + + - name: Upload IaC coverage to Codecov + if: steps.changed-iac.outputs.any_changed == 'true' + uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + flags: prowler-py${{ matrix.python-version }}-iac + files: ./iac_coverage.xml + + # MongoDB Atlas Provider + - name: Check if MongoDB Atlas files changed + if: steps.check-changes.outputs.any_changed == 'true' + id: changed-mongodbatlas + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + ./prowler/**/mongodbatlas/** + ./tests/**/mongodbatlas/** + ./poetry.lock + + - name: Run MongoDB Atlas tests + if: steps.changed-mongodbatlas.outputs.any_changed == 'true' + run: poetry run pytest -n auto --cov=./prowler/providers/mongodbatlas --cov-report=xml:mongodbatlas_coverage.xml tests/providers/mongodbatlas + + - name: Upload MongoDB Atlas coverage to Codecov + if: steps.changed-mongodbatlas.outputs.any_changed == 'true' + uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + flags: prowler-py${{ matrix.python-version }}-mongodbatlas + files: ./mongodbatlas_coverage.xml + + # OCI Provider + - name: Check if OCI files changed + if: steps.check-changes.outputs.any_changed == 'true' + id: changed-oraclecloud + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + ./prowler/**/oraclecloud/** + ./tests/**/oraclecloud/** + ./poetry.lock + + - name: Run OCI tests + if: steps.changed-oraclecloud.outputs.any_changed == 'true' + run: poetry run pytest -n auto --cov=./prowler/providers/oraclecloud --cov-report=xml:oraclecloud_coverage.xml tests/providers/oraclecloud + + - name: Upload OCI coverage to Codecov + if: steps.changed-oraclecloud.outputs.any_changed == 'true' + uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + flags: prowler-py${{ matrix.python-version }}-oraclecloud + files: ./oraclecloud_coverage.xml + + # Lib + - name: Check if Lib files changed + if: steps.check-changes.outputs.any_changed == 'true' + id: changed-lib + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + ./prowler/lib/** + ./tests/lib/** + ./poetry.lock + + - name: Run Lib tests + if: steps.changed-lib.outputs.any_changed == 'true' + run: poetry run pytest -n auto --cov=./prowler/lib --cov-report=xml:lib_coverage.xml tests/lib + + - name: Upload Lib coverage to Codecov + if: steps.changed-lib.outputs.any_changed == 'true' + uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + flags: prowler-py${{ matrix.python-version }}-lib + files: ./lib_coverage.xml + + # Config + - name: Check if Config files changed + if: steps.check-changes.outputs.any_changed == 'true' + id: changed-config + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + ./prowler/config/** + ./tests/config/** + ./poetry.lock + + - name: Run Config tests + if: steps.changed-config.outputs.any_changed == 'true' + run: poetry run pytest -n auto --cov=./prowler/config --cov-report=xml:config_coverage.xml tests/config + + - name: Upload Config coverage to Codecov + if: steps.changed-config.outputs.any_changed == 'true' + uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + flags: prowler-py${{ matrix.python-version }}-config + files: ./config_coverage.xml diff --git a/.github/workflows/ui-build-lint-push-containers.yml b/.github/workflows/ui-build-lint-push-containers.yml deleted file mode 100644 index bce6ba6a07..0000000000 --- a/.github/workflows/ui-build-lint-push-containers.yml +++ /dev/null @@ -1,121 +0,0 @@ -name: UI - Build and Push containers - -on: - push: - branches: - - "master" - paths: - - "ui/**" - - ".github/workflows/ui-build-lint-push-containers.yml" - - # Uncomment the below code to test this action on PRs - # pull_request: - # branches: - # - "master" - # paths: - # - "ui/**" - # - ".github/workflows/ui-build-lint-push-containers.yml" - - release: - types: [published] - -env: - # Tags - LATEST_TAG: latest - RELEASE_TAG: ${{ github.event.release.tag_name }} - STABLE_TAG: stable - - WORKING_DIRECTORY: ./ui - - # Container Registries - PROWLERCLOUD_DOCKERHUB_REPOSITORY: prowlercloud - PROWLERCLOUD_DOCKERHUB_IMAGE: prowler-ui - NEXT_PUBLIC_API_BASE_URL: http://prowler-api:8080/api/v1 - -jobs: - repository-check: - name: Repository check - runs-on: ubuntu-latest - outputs: - is_repo: ${{ steps.repository_check.outputs.is_repo }} - steps: - - name: Repository check - id: repository_check - working-directory: /tmp - run: | - if [[ ${{ github.repository }} == "prowler-cloud/prowler" ]] - then - echo "is_repo=true" >> "${GITHUB_OUTPUT}" - else - echo "This action only runs for prowler-cloud/prowler" - echo "is_repo=false" >> "${GITHUB_OUTPUT}" - fi - - # Build Prowler OSS container - container-build-push: - needs: repository-check - if: needs.repository-check.outputs.is_repo == 'true' - runs-on: ubuntu-latest - defaults: - run: - working-directory: ${{ env.WORKING_DIRECTORY }} - - steps: - - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Set short git commit SHA - id: vars - run: | - shortSha=$(git rev-parse --short ${{ github.sha }}) - echo "SHORT_SHA=${shortSha}" >> $GITHUB_ENV - - - name: Login to DockerHub - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - - name: Build and push container image (latest) - # Comment the following line for testing - if: github.event_name == 'push' - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: ${{ env.WORKING_DIRECTORY }} - build-args: | - NEXT_PUBLIC_PROWLER_RELEASE_VERSION=${{ env.SHORT_SHA }} - NEXT_PUBLIC_API_BASE_URL=${{ env.NEXT_PUBLIC_API_BASE_URL }} - # Set push: false for testing - push: true - tags: | - ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.LATEST_TAG }} - ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.SHORT_SHA }} - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Build and push container image (release) - if: github.event_name == 'release' - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: ${{ env.WORKING_DIRECTORY }} - build-args: | - NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${{ env.RELEASE_TAG }} - NEXT_PUBLIC_API_BASE_URL=${{ env.NEXT_PUBLIC_API_BASE_URL }} - push: true - tags: | - ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.RELEASE_TAG }} - ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.STABLE_TAG }} - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Trigger deployment - if: github.event_name == 'push' - uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3.0.0 - with: - token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} - repository: ${{ secrets.CLOUD_DISPATCH }} - event-type: prowler-ui-deploy - client-payload: '{"sha": "${{ github.sha }}", "short_sha": "${{ env.SHORT_SHA }}"}' diff --git a/.github/workflows/ui-codeql.yml b/.github/workflows/ui-codeql.yml index e594ddc7fc..2b55cf673c 100644 --- a/.github/workflows/ui-codeql.yml +++ b/.github/workflows/ui-codeql.yml @@ -1,36 +1,37 @@ -# 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: UI - CodeQL +name: 'UI: CodeQL' on: push: branches: - - "master" - - "v5.*" + - 'master' + - 'v5.*' paths: - - "ui/**" + - 'ui/**' + - '.github/workflows/ui-codeql.yml' + - '.github/codeql/ui-codeql-config.yml' + - '!ui/CHANGELOG.md' pull_request: branches: - - "master" - - "v5.*" + - 'master' + - 'v5.*' paths: - - "ui/**" + - 'ui/**' + - '.github/workflows/ui-codeql.yml' + - '.github/codeql/ui-codeql-config.yml' + - '!ui/CHANGELOG.md' schedule: - - cron: "00 12 * * *" + - cron: '00 12 * * *' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: - analyze: - name: Analyze + ui-analyze: + if: github.repository == 'prowler-cloud/prowler' + name: CodeQL Security Analysis runs-on: ubuntu-latest + timeout-minutes: 30 permissions: actions: read contents: read @@ -39,21 +40,20 @@ jobs: strategy: fail-fast: false matrix: - language: ["javascript"] - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + language: + - 'javascript-typescript' steps: - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5 + uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 with: languages: ${{ matrix.language }} config-file: ./.github/codeql/ui-codeql-config.yml - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5 + uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 with: - category: "/language:${{matrix.language}}" + category: '/language:${{ matrix.language }}' diff --git a/.github/workflows/ui-container-build-push.yml b/.github/workflows/ui-container-build-push.yml new file mode 100644 index 0000000000..34cddc900d --- /dev/null +++ b/.github/workflows/ui-container-build-push.yml @@ -0,0 +1,196 @@ +name: 'UI: Container Build and Push' + +on: + push: + branches: + - 'master' + paths: + - 'ui/**' + - '.github/workflows/ui-container-build-push.yml' + release: + types: + - 'published' + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +env: + # Tags + LATEST_TAG: latest + RELEASE_TAG: ${{ github.event.release.tag_name }} + STABLE_TAG: stable + WORKING_DIRECTORY: ./ui + + # Container registries + PROWLERCLOUD_DOCKERHUB_REPOSITORY: prowlercloud + PROWLERCLOUD_DOCKERHUB_IMAGE: prowler-ui + + # Build args + NEXT_PUBLIC_API_BASE_URL: http://prowler-api:8080/api/v1 + +jobs: + setup: + if: github.repository == 'prowler-cloud/prowler' + runs-on: ubuntu-latest + timeout-minutes: 5 + outputs: + short-sha: ${{ steps.set-short-sha.outputs.short-sha }} + steps: + - name: Calculate short SHA + id: set-short-sha + run: echo "short-sha=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT + + container-build-push: + needs: setup + runs-on: ${{ matrix.runner }} + strategy: + matrix: + include: + - platform: linux/amd64 + runner: ubuntu-latest + arch: amd64 + - platform: linux/arm64 + runner: ubuntu-24.04-arm + arch: arm64 + timeout-minutes: 30 + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Login to DockerHub + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Build and push UI container for ${{ matrix.arch }} + if: github.event_name == 'push' + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: ${{ env.WORKING_DIRECTORY }} + build-args: | + NEXT_PUBLIC_PROWLER_RELEASE_VERSION=${{ needs.setup.outputs.short-sha }} + NEXT_PUBLIC_API_BASE_URL=${{ env.NEXT_PUBLIC_API_BASE_URL }} + push: true + platforms: ${{ matrix.platform }} + tags: | + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-${{ matrix.arch }} + cache-from: type=gha,scope=${{ matrix.arch }} + cache-to: type=gha,mode=max,scope=${{ matrix.arch }} + + - name: Build and push UI container for ${{ matrix.arch }} + if: github.event_name == 'push' || github.event_name == 'release' + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: ${{ env.WORKING_DIRECTORY }} + build-args: | + NEXT_PUBLIC_PROWLER_RELEASE_VERSION=${{ github.event_name == 'release' && format('v{0}', env.RELEASE_TAG) || needs.setup.outputs.short_sha }} + NEXT_PUBLIC_API_BASE_URL=${{ env.NEXT_PUBLIC_API_BASE_URL }} + push: true + tags: | + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Notify container push started + if: github.event_name == 'release' + uses: ./.github/actions/slack-notification + env: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_PLATFORM_DEPLOYMENTS }} + COMPONENT: UI + RELEASE_TAG: ${{ env.RELEASE_TAG }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + payload-file-path: "./.github/scripts/slack-messages/container-release-started.json" + + - name: Notify container push completed + if: github.event_name == 'release' && always() + uses: ./.github/actions/slack-notification + env: + SLACK_CHANNEL_ID: ${{ secrets.SLACK_PLATFORM_DEPLOYMENTS }} + COMPONENT: UI + RELEASE_TAG: ${{ env.RELEASE_TAG }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + payload-file-path: "./.github/scripts/slack-messages/container-release-completed.json" + step-outcome: ${{ steps.container-push.outcome }} + + # Create and push multi-architecture manifest + create-manifest: + needs: [setup, container-build-push] + if: github.event_name == 'push' || github.event_name == 'release' + runs-on: ubuntu-latest + + steps: + - name: Login to DockerHub + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Create and push manifests for push event + if: github.event_name == 'push' + run: | + docker buildx imagetools create \ + -t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.LATEST_TAG }} \ + -t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }} \ + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-amd64 \ + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-arm64 + + - name: Create and push manifests for release event + if: github.event_name == 'release' + run: | + docker buildx imagetools create \ + -t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.RELEASE_TAG }} \ + -t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.STABLE_TAG }} \ + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-amd64 \ + ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-arm64 + + - name: Install regctl + if: always() + uses: regclient/actions/regctl-installer@main + + - name: Cleanup intermediate architecture tags + if: always() + run: | + echo "Cleaning up intermediate tags..." + regctl tag delete "${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-amd64" || true + regctl tag delete "${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.short-sha }}-arm64" || true + echo "Cleanup completed" + + trigger-deployment: + if: github.event_name == 'push' + needs: [setup, container-build-push] + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: read + + steps: + - name: Trigger UI deployment + uses: peter-evans/repository-dispatch@5fc4efd1a4797ddb68ffd0714a238564e4cc0e6f # v4.0.0 + with: + token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} + repository: ${{ secrets.CLOUD_DISPATCH }} + event-type: ui-prowler-deployment + client-payload: '{"sha": "${{ github.sha }}", "short_sha": "${{ needs.setup.outputs.short-sha }}"}' diff --git a/.github/workflows/ui-container-checks.yml b/.github/workflows/ui-container-checks.yml new file mode 100644 index 0000000000..e436c3974a --- /dev/null +++ b/.github/workflows/ui-container-checks.yml @@ -0,0 +1,91 @@ +name: 'UI: Container Checks' + +on: + push: + branches: + - 'master' + - 'v5.*' + pull_request: + branches: + - 'master' + - 'v5.*' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + UI_WORKING_DIR: ./ui + IMAGE_NAME: prowler-ui + +jobs: + ui-dockerfile-lint: + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Check if Dockerfile changed + id: dockerfile-changed + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: ui/Dockerfile + + - name: Lint Dockerfile with Hadolint + if: steps.dockerfile-changed.outputs.any_changed == 'true' + uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0 + with: + dockerfile: ui/Dockerfile + ignore: DL3018 + + ui-container-build-and-scan: + 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: Check for UI changes + id: check-changes + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: ui/** + files_ignore: | + ui/CHANGELOG.md + ui/README.md + + - name: Set up Docker Buildx + if: steps.check-changes.outputs.any_changed == 'true' + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Build UI container + if: steps.check-changes.outputs.any_changed == 'true' + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: ${{ env.UI_WORKING_DIR }} + target: prod + push: false + load: true + tags: ${{ env.IMAGE_NAME }}:${{ github.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max + build-args: | + NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_51LwpXXXX + + - name: Scan UI container with Trivy + if: github.repository == 'prowler-cloud/prowler' && steps.check-changes.outputs.any_changed == 'true' + 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/ui-e2e-tests.yml b/.github/workflows/ui-e2e-tests.yml index 543857a511..ed3b692819 100644 --- a/.github/workflows/ui-e2e-tests.yml +++ b/.github/workflows/ui-e2e-tests.yml @@ -18,9 +18,27 @@ jobs: AUTH_TRUST_HOST: true NEXTAUTH_URL: 'http://localhost:3000' NEXT_PUBLIC_API_BASE_URL: 'http://localhost:8080/api/v1' + E2E_ADMIN_USER: ${{ secrets.E2E_ADMIN_USER }} + E2E_ADMIN_PASSWORD: ${{ secrets.E2E_ADMIN_PASSWORD }} + E2E_AWS_PROVIDER_ACCOUNT_ID: ${{ secrets.E2E_AWS_PROVIDER_ACCOUNT_ID }} + E2E_AWS_PROVIDER_ACCESS_KEY: ${{ secrets.E2E_AWS_PROVIDER_ACCESS_KEY }} + E2E_AWS_PROVIDER_SECRET_KEY: ${{ secrets.E2E_AWS_PROVIDER_SECRET_KEY }} + E2E_AWS_PROVIDER_ROLE_ARN: ${{ secrets.E2E_AWS_PROVIDER_ROLE_ARN }} + E2E_AZURE_SUBSCRIPTION_ID: ${{ secrets.E2E_AZURE_SUBSCRIPTION_ID }} + E2E_AZURE_CLIENT_ID: ${{ secrets.E2E_AZURE_CLIENT_ID }} + E2E_AZURE_SECRET_ID: ${{ secrets.E2E_AZURE_SECRET_ID }} + E2E_AZURE_TENANT_ID: ${{ secrets.E2E_AZURE_TENANT_ID }} + E2E_M365_DOMAIN_ID: ${{ secrets.E2E_M365_DOMAIN_ID }} + E2E_M365_CLIENT_ID: ${{ secrets.E2E_M365_CLIENT_ID }} + E2E_M365_SECRET_ID: ${{ secrets.E2E_M365_SECRET_ID }} + E2E_M365_TENANT_ID: ${{ secrets.E2E_M365_TENANT_ID }} + E2E_M365_CERTIFICATE_CONTENT: ${{ secrets.E2E_M365_CERTIFICATE_CONTENT }} + E2E_NEW_PASSWORD: ${{ secrets.E2E_NEW_PASSWORD }} steps: - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - name: Fix API data directory permissions + run: docker run --rm -v $(pwd)/_data/api:/data alpine chown -R 1000:1000 /data - name: Start API services run: | # Override docker-compose image tag to use latest instead of stable @@ -57,7 +75,7 @@ jobs: echo "All database fixtures loaded successfully!" ' - name: Setup Node.js environment - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 with: node-version: '20.x' cache: 'npm' @@ -69,7 +87,7 @@ jobs: working-directory: ./ui run: npm run build - name: Cache Playwright browsers - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 id: playwright-cache with: path: ~/.cache/ms-playwright diff --git a/.github/workflows/ui-pull-request.yml b/.github/workflows/ui-pull-request.yml deleted file mode 100644 index 1925f6c230..0000000000 --- a/.github/workflows/ui-pull-request.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: UI - Pull Request - -on: - push: - branches: - - "master" - - "v5.*" - paths: - - ".github/workflows/ui-pull-request.yml" - - "ui/**" - pull_request: - branches: - - master - - "v5.*" - paths: - - 'ui/**' -env: - UI_WORKING_DIR: ./ui - IMAGE_NAME: prowler-ui - -jobs: - test-and-coverage: - runs-on: ubuntu-latest - strategy: - matrix: - os: [ubuntu-latest] - node-version: [20.x] - steps: - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: false - - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - cache-dependency-path: './ui/package-lock.json' - - name: Install dependencies - working-directory: ./ui - run: npm ci - - name: Run Healthcheck - working-directory: ./ui - run: npm run healthcheck - - name: Build the application - working-directory: ./ui - run: npm run build - - test-container-build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - name: Build Container - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: ${{ env.UI_WORKING_DIR }} - # Always build using `prod` target - target: prod - push: false - tags: ${{ env.IMAGE_NAME }}:latest - outputs: type=docker - build-args: | - NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_51LwpXXXX diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml new file mode 100644 index 0000000000..a5a5b5fa17 --- /dev/null +++ b/.github/workflows/ui-tests.yml @@ -0,0 +1,64 @@ +name: 'UI: Tests' + +on: + push: + branches: + - 'master' + - 'v5.*' + pull_request: + branches: + - 'master' + - 'v5.*' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + UI_WORKING_DIR: ./ui + NODE_VERSION: '20.x' + +jobs: + ui-tests: + runs-on: ubuntu-latest + timeout-minutes: 20 + permissions: + contents: read + defaults: + run: + working-directory: ./ui + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Check for UI changes + id: check-changes + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: | + ui/** + .github/workflows/ui-tests.yml + files_ignore: | + ui/CHANGELOG.md + ui/README.md + + - name: Setup Node.js ${{ env.NODE_VERSION }} + if: steps.check-changes.outputs.any_changed == 'true' + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'npm' + cache-dependency-path: './ui/package-lock.json' + + - name: Install dependencies + if: steps.check-changes.outputs.any_changed == 'true' + run: npm ci + + - name: Run healthcheck + if: steps.check-changes.outputs.any_changed == 'true' + run: npm run healthcheck + + - name: Build application + if: steps.check-changes.outputs.any_changed == 'true' + run: npm run build diff --git a/.gitignore b/.gitignore index 6e7e284566..7792a031b4 100644 --- a/.gitignore +++ b/.gitignore @@ -39,21 +39,92 @@ secrets-*/ # JUnit Reports junit-reports/ -# VSCode files -.vscode/ +# Test and coverage artifacts +*_coverage.xml +pytest_*.xml +.coverage +htmlcov/ -# Cursor files +# VSCode files and settings +.vscode/ +*.code-workspace +.vscode-test/ + +# VSCode extension settings and workspaces +.history/ +.ionide/ + +# MCP Server Settings (various locations) +**/cline_mcp_settings.json +**/mcp_settings.json +**/mcp-config.json +**/mcpServers.json +.mcp/ + +# AI Coding Assistants - Cursor .cursorignore .cursor/ +.cursorrules -# RooCode files +# AI Coding Assistants - RooCode .roo/ .rooignore .roomodes -# Cline files +# AI Coding Assistants - Cline (formerly Claude Dev) .cline/ .clineignore +.clinerules + +# AI Coding Assistants - Continue +.continue/ +continue.json +.continuerc +.continuerc.json + +# AI Coding Assistants - GitHub Copilot +.copilot/ +.github/copilot/ + +# AI Coding Assistants - Amazon Q Developer (formerly CodeWhisperer) +.aws/ +.codewhisperer/ +.amazonq/ +.aws-toolkit/ + +# AI Coding Assistants - Tabnine +.tabnine/ +tabnine_config.json + +# AI Coding Assistants - Kiro +.kiro/ +.kiroignore +kiro.config.json + +# AI Coding Assistants - Aider +.aider/ +.aider.chat.history.md +.aider.input.history +.aider.tags.cache.v3/ + +# AI Coding Assistants - Windsurf +.windsurf/ +.windsurfignore + +# AI Coding Assistants - Replit Agent +.replit +.replitignore + +# AI Coding Assistants - Supermaven +.supermaven/ + +# AI Coding Assistants - Sourcegraph Cody +.cody/ + +# AI Coding Assistants - General +.ai/ +.aiconfig +ai-config.json # Terraform .terraform* @@ -63,7 +134,7 @@ junit-reports/ # .env ui/.env* api/.env* -.env.local +mcp_server/.env* # Coverage .coverage* @@ -78,3 +149,10 @@ _data/ # Claude CLAUDE.md + +# MCP Server +mcp_server/prowler_mcp_server/prowler_app/server.py +mcp_server/prowler_mcp_server/prowler_app/utils/schema.yaml + +# Compliance report +*.pdf diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 80c9ac250f..d4bb2435f1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,6 +6,7 @@ repos: - id: check-merge-conflict - id: check-yaml args: ["--unsafe"] + exclude: prowler/config/llm_config.yaml - id: check-json - id: end-of-file-fixer - id: trailing-whitespace diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..c6a6027c18 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,110 @@ +# Repository Guidelines + +## How to Use This Guide + +- Start here for cross-project norms, Prowler is a monorepo with several components. Every component should have an `AGENTS.md` file that contains the guidelines for the agents in that component. The file is located beside the code you are touching (e.g. `api/AGENTS.md`, `ui/AGENTS.md`, `prowler/AGENTS.md`). +- Follow the stricter rule when guidance conflicts; component docs override this file for their scope. +- Keep instructions synchronized. When you add new workflows or scripts, update both, the relevant component `AGENTS.md` and this file if they apply broadly. + +## Project Overview + +Prowler is an open-source cloud security assessment tool that supports multiple cloud providers (AWS, Azure, GCP, Kubernetes, GitHub, M365, etc.). The project consists in a monorepo with the following main components: + +- **Prowler SDK**: Python SDK, includes the Prowler CLI, providers, services, checks, compliances, config, etc. (`prowler/`) +- **Prowler API**: Django-based REST API backend (`api/`) +- **Prowler UI**: Next.js frontend application (`ui/`) +- **Prowler MCP Server**: Model Context Protocol server that gives access to the entire Prowler ecosystem for LLMs (`mcp_server/`) +- **Prowler Dashboard**: Prowler CLI feature that allows to visualize the results of the scans in a simple dashboard (`dashboard/`) + +### Project Structure (Key Folders & Files) + +- `prowler/`: Main source code for Prowler SDK (CLI, providers, services, checks, compliances, config, etc.) +- `api/`: Django-based REST API backend components +- `ui/`: Next.js frontend application +- `mcp_server/`: Model Context Protocol server that gives access to the entire Prowler ecosystem for LLMs +- `dashboard/`: Prowler CLI feature that allows to visualize the results of the scans in a simple dashboard +- `docs/`: Documentation +- `examples/`: Example output formats for providers and scripts +- `permissions/`: Permission-related files and policies +- `contrib/`: Community-contributed scripts or modules +- `tests/`: Prowler SDK test suite +- `docker-compose.yml`: Docker compose file to run the Prowler App (API + UI) production environment +- `docker-compose-dev.yml`: Docker compose file to run the Prowler App (API + UI) development environment +- `pyproject.toml`: Poetry Prowler SDK project file +- `.pre-commit-config.yaml`: Pre-commit hooks configuration +- `Makefile`: Makefile to run the project +- `LICENSE`: License file +- `README.md`: README file +- `CONTRIBUTING.md`: Contributing guide + +## Python Development + +Most of the code is written in Python, so the main files in the root are focused on Python code. + +### Poetry Dev Environment + +For developing in Python we recommend using `poetry` to manage the dependencies. The minimal version is `2.1.1`. So it is recommended to run all commands using `poetry run ...`. + +To install the core dependencies to develop it is needed to run `poetry install --with dev`. + +### Pre-commit hooks + +The project has pre-commit hooks to lint and format the code. They are installed by running `poetry run pre-commit install`. + +When commiting a change, the hooks will be run automatically. Some of them are: + +- Code formatting (black, isort) +- Linting (flake8, pylint) +- Security checks (bandit, safety, trufflehog) +- YAML/JSON validation +- Poetry lock file validation + + +### Linting and Formatting + +We use the following tools to lint and format the code: + +- `flake8`: for linting the code +- `black`: for formatting the code +- `pylint`: for linting the code + +You can run all using the `make` command: +```bash +poetry run make lint +poetry run make format +``` + +Or they will be run automatically when you commit your changes using pre-commit hooks. + +## Commit & Pull Request Guidelines + +For the commit messages and pull requests name follow the conventional-commit style. + +Befire creating a pull request, complete the checklist in `.github/pull_request_template.md`. Summaries should explain deployment impact, highlight review steps, and note changelog or permission updates. Run all relevant tests and linters before requesting review and link screenshots for UI or dashboard changes. + +### Conventional Commit Style + +The Conventional Commits specification is a lightweight convention on top of commit messages. It provides an easy set of rules for creating an explicit commit history; which makes it easier to write automated tools on top of. + +The commit message should be structured as follows: + +``` +[optional scope]: + +[optional body] + +[optional footer(s)] +``` + +Any line of the commit message cannot be longer 100 characters! This allows the message to be easier to read on GitHub as well as in various git tools + +#### Commit Types + +- **feat**: code change introuce new functionality to the application +- **fix**: code change that solve a bug in the codebase +- **docs**: documentation only changes +- **chore**: changes related to the build process or auxiliary tools and libraries, that do not affect the application's functionality +- **perf**: code change that improves performance +- **refactor**: code change that neither fixes a bug nor adds a feature +- **style**: changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) +- **test**: adding missing tests or correcting existing tests diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2dc954e9d9..f530feb99a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,4 +10,4 @@ Want some swag as appreciation for your contribution? # Prowler Developer Guide -https://docs.prowler.com/projects/prowler-open-source/en/latest/developer-guide/introduction/ +https://goto.prowler.com/devguide diff --git a/Dockerfile b/Dockerfile index 5884bda9f3..f71c53e008 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,10 @@ LABEL maintainer="https://github.com/prowler-cloud/prowler" LABEL org.opencontainers.image.source="https://github.com/prowler-cloud/prowler" ARG POWERSHELL_VERSION=7.5.0 +ENV POWERSHELL_VERSION=${POWERSHELL_VERSION} + +ARG TRIVY_VERSION=0.66.0 +ENV TRIVY_VERSION=${TRIVY_VERSION} # hadolint ignore=DL3008 RUN apt-get update && apt-get install -y --no-install-recommends \ @@ -25,6 +29,24 @@ RUN ARCH=$(uname -m) && \ ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh && \ rm /tmp/powershell.tar.gz +# Install Trivy for IaC scanning +RUN ARCH=$(uname -m) && \ + if [ "$ARCH" = "x86_64" ]; then \ + TRIVY_ARCH="Linux-64bit" ; \ + elif [ "$ARCH" = "aarch64" ]; then \ + TRIVY_ARCH="Linux-ARM64" ; \ + else \ + echo "Unsupported architecture for Trivy: $ARCH" && exit 1 ; \ + fi && \ + wget --progress=dot:giga "https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_${TRIVY_ARCH}.tar.gz" -O /tmp/trivy.tar.gz && \ + tar zxf /tmp/trivy.tar.gz -C /tmp && \ + mv /tmp/trivy /usr/local/bin/trivy && \ + chmod +x /usr/local/bin/trivy && \ + rm /tmp/trivy.tar.gz && \ + # Create trivy cache directory with proper permissions + mkdir -p /tmp/.cache/trivy && \ + chmod 777 /tmp/.cache/trivy + # Add prowler user RUN addgroup --gid 1000 prowler && \ adduser --uid 1000 --gid 1000 --disabled-password --gecos "" prowler diff --git a/Makefile b/Makefile index ccd67c5a45..861c9cf7fe 100644 --- a/Makefile +++ b/Makefile @@ -45,3 +45,15 @@ pypi-upload: ## Upload package help: ## Show this help. @echo "Prowler Makefile" @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +##@ Build no cache +build-no-cache-dev: + docker compose -f docker-compose-dev.yml build --no-cache api-dev worker-dev worker-beat + +##@ Development Environment +run-api-dev: ## Start development environment with API, PostgreSQL, Valkey, and workers + docker compose -f docker-compose-dev.yml up api-dev postgres valkey worker-dev worker-beat + +##@ Development Environment +build-and-run-api-dev: build-no-cache-dev run-api-dev + diff --git a/README.md b/README.md index fce0fbdc48..25cc8f6abe 100644 --- a/README.md +++ b/README.md @@ -19,19 +19,16 @@ Slack Shield Python Version Python Version - PyPI Prowler Downloads + PyPI Downloads Docker Pulls - Docker - Docker AWS ECR Gallery

- Repo size - Issues - Version + Version Version Contributors + Issues License Twitter Twitter @@ -55,15 +52,11 @@ Prowler includes hundreds of built-in controls to ensure compliance with standar - **National Security Standards:** ENS (Spanish National Security Scheme) - **Custom Security Frameworks:** Tailored to your needs -## Prowler CLI and Prowler Cloud - -Prowler offers a Command Line Interface (CLI), known as Prowler Open Source, and an additional service built on top of it, called Prowler Cloud. - ## Prowler App Prowler App is a web-based application that simplifies running Prowler across your cloud provider accounts. It provides a user-friendly interface to visualize the results and streamline your security assessments. -![Prowler App](docs/img/overview.png) +![Prowler App](docs/images/products/overview.png) >For more details, refer to the [Prowler App Documentation](https://docs.prowler.com/projects/prowler-open-source/en/latest/#prowler-app-installation) @@ -80,28 +73,38 @@ prowler ```console prowler dashboard ``` -![Prowler Dashboard](docs/img/dashboard.png) +![Prowler Dashboard](docs/images/products/dashboard.png) # Prowler at a Glance +> [!Tip] +> For the most accurate and up-to-date information about checks, services, frameworks, and categories, visit [**Prowler Hub**](https://hub.prowler.com). -| Provider | Checks | Services | [Compliance Frameworks](https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/compliance/) | [Categories](https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/misc/#categories) | -|---|---|---|---|---| -| AWS | 571 | 82 | 36 | 10 | -| GCP | 79 | 13 | 10 | 3 | -| Azure | 162 | 19 | 11 | 4 | -| Kubernetes | 83 | 7 | 5 | 7 | -| GitHub | 17 | 2 | 1 | 0 | -| M365 | 70 | 7 | 3 | 2 | -| NHN (Unofficial) | 6 | 2 | 1 | 0 | + +| Provider | Checks | Services | [Compliance Frameworks](https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/compliance/) | [Categories](https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/misc/#categories) | Support | Interface | +|---|---|---|---|---|---|---| +| AWS | 576 | 82 | 39 | 10 | Official | UI, API, CLI | +| GCP | 79 | 13 | 13 | 3 | Official | UI, API, CLI | +| Azure | 162 | 19 | 13 | 4 | Official | UI, API, CLI | +| Kubernetes | 83 | 7 | 5 | 7 | Official | UI, API, CLI | +| GitHub | 17 | 2 | 1 | 0 | Official | Stable | UI, API, CLI | +| M365 | 70 | 7 | 3 | 2 | Official | UI, API, CLI | +| OCI | 51 | 13 | 1 | 10 | Official | UI, API, CLI | +| IaC | [See `trivy` docs.](https://trivy.dev/latest/docs/coverage/iac/) | N/A | N/A | N/A | Official | UI, API, CLI | +| MongoDB Atlas | 10 | 3 | 0 | 0 | Official | CLI, API | +| LLM | [See `promptfoo` docs.](https://www.promptfoo.dev/docs/red-team/plugins/) | N/A | N/A | N/A | Official | CLI | +| NHN | 6 | 2 | 1 | 0 | Unofficial | CLI | > [!Note] > The numbers in the table are updated periodically. -> [!Tip] -> For the most accurate and up-to-date information about checks, services, frameworks, and categories, visit [**Prowler Hub**](https://hub.prowler.com). + > [!Note] -> Use the following commands to list Prowler's available checks, services, compliance frameworks, and categories: `prowler --list-checks`, `prowler --list-services`, `prowler --list-compliance` and `prowler --list-categories`. +> Use the following commands to list Prowler's available checks, services, compliance frameworks, and categories: +> - `prowler --list-checks` +> - `prowler --list-services` +> - `prowler --list-compliance` +> - `prowler --list-categories` # šŸ’» Installation @@ -239,7 +242,7 @@ The following versions of Prowler CLI are available, depending on your requireme The container images are available here: - Prowler CLI: - - [DockerHub](https://hub.docker.com/r/toniblyx/prowler/tags) + - [DockerHub](https://hub.docker.com/r/prowlercloud/prowler/tags) - [AWS Public ECR](https://gallery.ecr.aws/prowler-cloud/prowler) - Prowler App: - [DockerHub - Prowler UI](https://hub.docker.com/r/prowlercloud/prowler-ui/tags) @@ -274,7 +277,7 @@ python prowler-cli.py -v - **Prowler API**: A backend service, developed with Django REST Framework, responsible for running Prowler scans and storing the generated results. - **Prowler SDK**: A Python SDK designed to extend the functionality of the Prowler CLI for advanced capabilities. -![Prowler App Architecture](docs/img/prowler-app-architecture.png) +![Prowler App Architecture](docs/products/img/prowler-app-architecture.png) ## Prowler CLI @@ -300,40 +303,12 @@ And many more environments. ![Architecture](docs/img/architecture.png) -# Deprecations from v3 - -## General -- `Allowlist` now is called `Mutelist`. -- The `--quiet` option has been deprecated. Use the `--status` flag to filter findings based on their status: PASS, FAIL, or MANUAL. -- All findings with an `INFO` status have been reclassified as `MANUAL`. -- The CSV output format is standardized across all providers. - -**Deprecated Output Formats** - -The following formats are now deprecated: -- Native JSON has been replaced with JSON in [OCSF] v1.1.0 format, which is standardized across all providers (https://schema.ocsf.io/). - -## AWS - -**AWS Flag Deprecation** - -The flag --sts-endpoint-region has been deprecated due to the adoption of AWS STS regional tokens. - -**Sending FAIL Results to AWS Security Hub** - -- To send only FAILS to AWS Security Hub, use one of the following options: `--send-sh-only-fails` or `--security-hub --status FAIL`. - - # šŸ“– Documentation -**Documentation Resources** - For installation instructions, usage details, tutorials, and the Developer Guide, visit https://docs.prowler.com/ # šŸ“ƒ License -**Prowler License Information** - -Prowler is licensed under the Apache License 2.0, as indicated in each file within the repository. Obtaining a Copy of the License +Prowler is licensed under the Apache License 2.0. A copy of the License is available at diff --git a/api/.env.example b/api/.env.example index 76ea6de3d2..0be5388790 100644 --- a/api/.env.example +++ b/api/.env.example @@ -19,6 +19,8 @@ DJANGO_REFRESH_TOKEN_LIFETIME=1440 DJANGO_CACHE_MAX_AGE=3600 DJANGO_STALE_WHILE_REVALIDATE=60 DJANGO_SECRETS_ENCRYPTION_KEY="" +# Throttle, two options: Empty means no throttle; or if desired use one in DRF format: https://www.django-rest-framework.org/api-guide/throttling/#setting-the-throttling-policy +DJANGO_THROTTLE_TOKEN_OBTAIN=50/minute # Decide whether to allow Django manage database table partitions DJANGO_MANAGE_DB_PARTITIONS=[True|False] DJANGO_CELERY_DEADLOCK_ATTEMPTS=5 diff --git a/api/CHANGELOG.md b/api/CHANGELOG.md index adc80ed8cf..ce5d8eed74 100644 --- a/api/CHANGELOG.md +++ b/api/CHANGELOG.md @@ -2,13 +2,112 @@ All notable changes to the **Prowler API** are documented in this file. -## [1.12.0] (Prowler 5.11.0 - UNRELEASED) +## [1.15.0] (Prowler UNRELEASED) + +### Added +- IaC (Infrastructure as Code) provider support for remote repositories [(#8751)](https://github.com/prowler-cloud/prowler/pull/8751) +- Extend `GET /api/v1/providers` with provider-type filters and optional pagination disable to support the new Overview filters [(#8975)](https://github.com/prowler-cloud/prowler/pull/8975) +- New endpoint to retrieve the number of providers grouped by provider type [(#8975)](https://github.com/prowler-cloud/prowler/pull/8975) +- Support for configuring multiple LLM providers [(#8772)](https://github.com/prowler-cloud/prowler/pull/8772) +- Support C5 compliance framework for Azure provider [(#9081)](https://github.com/prowler-cloud/prowler/pull/9081) +- Support for Oracle Cloud Infrastructure (OCI) provider [(#8927)](https://github.com/prowler-cloud/prowler/pull/8927) +- Support muting findings based on simple rules with custom reason [(#9051)](https://github.com/prowler-cloud/prowler/pull/9051) +- Support C5 compliance framework for the GCP provider [(#9097)](https://github.com/prowler-cloud/prowler/pull/9097) +- Support for Amazon Bedrock and OpenAI compatible providers in Lighthouse AI [(#8957)](https://github.com/prowler-cloud/prowler/pull/8957) +- Tenant-wide ThreatScore overview aggregation and snapshot persistence with backfill support [(#9148)](https://github.com/prowler-cloud/prowler/pull/9148) +- Added `metadata`, `details`, and `partition` attributes to `/resources` endpoint & `details`, and `partition` to `/findings` endpoint [(#9098)](https://github.com/prowler-cloud/prowler/pull/9098) +- Support for MongoDB Atlas provider [(#9167)](https://github.com/prowler-cloud/prowler/pull/9167) +- Enhanced compliance overview endpoint with provider filtering and latest scan aggregation [(#9244)](https://github.com/prowler-cloud/prowler/pull/9244) + +### Changed +- Optimized database write queries for scan related tasks [(#9190)](https://github.com/prowler-cloud/prowler/pull/9190) +- Date filters are now optional for `GET /api/v1/overviews/services` endpoint; returns latest scan data by default [(#9248)](https://github.com/prowler-cloud/prowler/pull/9248) + +### Fixed +- Scans no longer fail when findings have UIDs exceeding 300 characters; such findings are now skipped with detailed logging [(#9246)](https://github.com/prowler-cloud/prowler/pull/9246) + +### Security +- Django updated to the latest 5.1 security release, 5.1.14, due to problems with potential [SQL injection](https://github.com/prowler-cloud/prowler/security/dependabot/113) and [denial-of-service vulnerability](https://github.com/prowler-cloud/prowler/security/dependabot/114) [(#9176)](https://github.com/prowler-cloud/prowler/pull/9176) + +--- + +## [1.14.2] (Prowler 5.13.2) + +### Fixed +- Update unique constraint for `Provider` model to exclude soft-deleted entries, resolving duplicate errors when re-deleting providers [(#9054)](https://github.com/prowler-cloud/prowler/pull/9054) +- Remove compliance generation for providers without compliance frameworks [(#9208)](https://github.com/prowler-cloud/prowler/pull/9208) + +## [1.14.1] (Prowler 5.13.1) + +### Fixed +- `/api/v1/overviews/providers` collapses data by provider type so the UI receives a single aggregated record per cloud family even when multiple accounts exist [(#9053)](https://github.com/prowler-cloud/prowler/pull/9053) +- Added retry logic to database transactions to handle Aurora read replica connection failures during scale-down events [(#9064)](https://github.com/prowler-cloud/prowler/pull/9064) +- Security Hub integrations stop failing when they read relationships via the replica by allowing replica relations and saving updates through the primary [(#9080)](https://github.com/prowler-cloud/prowler/pull/9080) + +--- + +## [1.14.0] (Prowler 5.13.0) + +### Added +- Default JWT keys are generated and stored if they are missing from configuration [(#8655)](https://github.com/prowler-cloud/prowler/pull/8655) +- `compliance_name` for each compliance [(#7920)](https://github.com/prowler-cloud/prowler/pull/7920) +- Support C5 compliance framework for the AWS provider [(#8830)](https://github.com/prowler-cloud/prowler/pull/8830) +- Support for M365 Certificate authentication [(#8538)](https://github.com/prowler-cloud/prowler/pull/8538) +- API Key support [(#8805)](https://github.com/prowler-cloud/prowler/pull/8805) +- SAML role mapping protection for single-admin tenants to prevent accidental lockout [(#8882)](https://github.com/prowler-cloud/prowler/pull/8882) +- 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) +- PDF reporting for Prowler ThreatScore [(#8867)](https://github.com/prowler-cloud/prowler/pull/8867) +- 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) +- Now at least one user with MANAGE_ACCOUNT permission is required in the tenant [(#8729)](https://github.com/prowler-cloud/prowler/pull/8729) + +### Security +- Django updated to the latest 5.1 security release, 5.1.13, due to problems with potential [SQL injection](https://github.com/prowler-cloud/prowler/security/dependabot/104) and [directory traversals](https://github.com/prowler-cloud/prowler/security/dependabot/103) [(#8842)](https://github.com/prowler-cloud/prowler/pull/8842) + +--- + +## [1.13.2] (Prowler 5.12.3) + +### Fixed +- 500 error when deleting user [(#8731)](https://github.com/prowler-cloud/prowler/pull/8731) + +--- + +## [1.13.1] (Prowler 5.12.2) + +### Changed +- Renamed compliance overview task queue to `compliance` [(#8755)](https://github.com/prowler-cloud/prowler/pull/8755) + +### Security +- Django updated to the latest 5.1 security release, 5.1.12, due to [problems](https://www.djangoproject.com/weblog/2025/sep/03/security-releases/) with potential SQL injection in FilteredRelation column aliases [(#8693)](https://github.com/prowler-cloud/prowler/pull/8693) + +--- + +## [1.13.0] (Prowler 5.12.0) + +### Added +- Integration with JIRA, enabling sending findings to a JIRA project [(#8622)](https://github.com/prowler-cloud/prowler/pull/8622), [(#8637)](https://github.com/prowler-cloud/prowler/pull/8637) +- `GET /overviews/findings_severity` now supports `filter[status]` and `filter[status__in]` to aggregate by specific statuses (`FAIL`, `PASS`)[(#8186)](https://github.com/prowler-cloud/prowler/pull/8186) +- Throttling options for `/api/v1/tokens` using the `DJANGO_THROTTLE_TOKEN_OBTAIN` environment variable [(#8647)](https://github.com/prowler-cloud/prowler/pull/8647) + +--- + +## [1.12.0] (Prowler 5.11.0) ### Added - Lighthouse support for OpenAI GPT-5 [(#8527)](https://github.com/prowler-cloud/prowler/pull/8527) - Integration with Amazon Security Hub, enabling sending findings to Security Hub [(#8365)](https://github.com/prowler-cloud/prowler/pull/8365) - Generate ASFF output for AWS providers with SecurityHub integration enabled [(#8569)](https://github.com/prowler-cloud/prowler/pull/8569) +### Fixed +- GitHub provider always scans user instead of organization when using provider UID [(#8587)](https://github.com/prowler-cloud/prowler/pull/8587) + +--- + ## [1.11.0] (Prowler 5.10.0) ### Added diff --git a/api/Dockerfile b/api/Dockerfile index a3cfb21782..2d7883a957 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -5,6 +5,9 @@ LABEL maintainer="https://github.com/prowler-cloud/api" ARG POWERSHELL_VERSION=7.5.0 ENV POWERSHELL_VERSION=${POWERSHELL_VERSION} +ARG TRIVY_VERSION=0.66.0 +ENV TRIVY_VERSION=${TRIVY_VERSION} + # hadolint ignore=DL3008 RUN apt-get update && apt-get install -y --no-install-recommends \ wget \ @@ -36,6 +39,24 @@ RUN ARCH=$(uname -m) && \ ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh && \ rm /tmp/powershell.tar.gz +# Install Trivy for IaC scanning +RUN ARCH=$(uname -m) && \ + if [ "$ARCH" = "x86_64" ]; then \ + TRIVY_ARCH="Linux-64bit" ; \ + elif [ "$ARCH" = "aarch64" ]; then \ + TRIVY_ARCH="Linux-ARM64" ; \ + else \ + echo "Unsupported architecture for Trivy: $ARCH" && exit 1 ; \ + fi && \ + wget --progress=dot:giga "https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_${TRIVY_ARCH}.tar.gz" -O /tmp/trivy.tar.gz && \ + tar zxf /tmp/trivy.tar.gz -C /tmp && \ + mv /tmp/trivy /usr/local/bin/trivy && \ + chmod +x /usr/local/bin/trivy && \ + rm /tmp/trivy.tar.gz && \ + # Create trivy cache directory with proper permissions + mkdir -p /tmp/.cache/trivy && \ + chmod 777 /tmp/.cache/trivy + # Add prowler user RUN addgroup --gid 1000 prowler && \ adduser --uid 1000 --gid 1000 --disabled-password --gecos "" prowler diff --git a/api/README.md b/api/README.md index ba8896ff35..60a2669718 100644 --- a/api/README.md +++ b/api/README.md @@ -18,7 +18,11 @@ Valkey exposes a Redis 7.2 compliant API. Any service that exposes the Redis API # Modify environment variables -Under the root path of the project, you can find a file called `.env.example`. This file shows all the environment variables that the project uses. You *must* create a new file called `.env` and set the values for the variables. +Under the root path of the project, you can find a file called `.env`. This file shows all the environment variables that the project uses. You should review it and set the values for the variables you want to change. + +If you don’t set `DJANGO_TOKEN_SIGNING_KEY` or `DJANGO_TOKEN_VERIFYING_KEY`, the API will generate them at `~/.config/prowler-api/` with `0600` and `0644` permissions; back up these files to persist identity across redeploys. + +**Important note**: Every Prowler version (or repository branches and tags) could have different variables set in its `.env` file. Please use the `.env` file that corresponds with each version. ## Local deployment Keep in mind if you export the `.env` file to use it with local deployment that you will have to do it within the context of the Poetry interpreter, not before. Otherwise, variables will not be loaded properly. diff --git a/api/docker-entrypoint.sh b/api/docker-entrypoint.sh index 5669de6788..f9b19e04d0 100755 --- a/api/docker-entrypoint.sh +++ b/api/docker-entrypoint.sh @@ -32,7 +32,7 @@ start_prod_server() { start_worker() { echo "Starting the worker..." - poetry run python -m celery -A config.celery worker -l "${DJANGO_LOGGING_LEVEL:-info}" -Q celery,scans,scan-reports,deletion,backfill,overview,integrations -E --max-tasks-per-child 1 + poetry run python -m celery -A config.celery worker -l "${DJANGO_LOGGING_LEVEL:-info}" -Q celery,scans,scan-reports,deletion,backfill,overview,integrations,compliance -E --max-tasks-per-child 1 } start_worker_beat() { diff --git a/api/poetry.lock b/api/poetry.lock index 5171644ab1..332d4d9f73 100644 --- a/api/poetry.lock +++ b/api/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. [[package]] name = "about-time" @@ -273,14 +273,14 @@ tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" a [[package]] name = "authlib" -version = "1.6.1" +version = "1.6.5" description = "The ultimate Python library in building OAuth and OpenID Connect servers and clients." optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "authlib-1.6.1-py2.py3-none-any.whl", hash = "sha256:e9d2031c34c6309373ab845afc24168fe9e93dc52d252631f52642f21f5ed06e"}, - {file = "authlib-1.6.1.tar.gz", hash = "sha256:4dffdbb1460ba6ec8c17981a4c67af7d8af131231b5a36a88a1e8c80c111cdfd"}, + {file = "authlib-1.6.5-py2.py3-none-any.whl", hash = "sha256:3e0e0507807f842b02175507bdee8957a1d5707fd4afb17c32fb43fee90b6e3a"}, + {file = "authlib-1.6.5.tar.gz", hash = "sha256:6aaf9c79b7cc96c900f0b284061691c5d4e61221640a948fe690b556a6d6d10b"}, ] [package.dependencies] @@ -383,6 +383,24 @@ cryptography = ">=2.1.4" isodate = ">=0.6.1" typing-extensions = ">=4.0.1" +[[package]] +name = "azure-mgmt-apimanagement" +version = "5.0.0" +description = "Microsoft Azure API Management Client Library for Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "azure_mgmt_apimanagement-5.0.0-py3-none-any.whl", hash = "sha256:b88c42a392333b60722fb86f15d092dfc19a8d67510dccd15c217381dff4e6ec"}, + {file = "azure_mgmt_apimanagement-5.0.0.tar.gz", hash = "sha256:0ab7fe17e70fe3154cd840ff47d19d7a4610217003eaa7c21acf3511a6e57999"}, +] + +[package.dependencies] +azure-common = ">=1.1" +azure-mgmt-core = ">=1.3.2" +isodate = ">=0.6.1" +typing-extensions = ">=4.6.0" + [[package]] name = "azure-mgmt-applicationinsights" version = "4.1.0" @@ -540,6 +558,23 @@ azure-mgmt-core = ">=1.3.2" isodate = ">=0.6.1" typing-extensions = ">=4.6.0" +[[package]] +name = "azure-mgmt-loganalytics" +version = "12.0.0" +description = "Microsoft Azure Log Analytics Management Client Library for Python" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "azure-mgmt-loganalytics-12.0.0.zip", hash = "sha256:da128a7e0291be7fa2063848df92a9180cf5c16d42adc09d2bc2efd711536bfb"}, + {file = "azure_mgmt_loganalytics-12.0.0-py2.py3-none-any.whl", hash = "sha256:75ac1d47dd81179905c40765be8834643d8994acff31056ddc1863017f3faa02"}, +] + +[package.dependencies] +azure-common = ">=1.1,<2.0" +azure-mgmt-core = ">=1.2.0,<2.0.0" +msrest = ">=0.6.21" + [[package]] name = "azure-mgmt-monitor" version = "6.0.2" @@ -750,6 +785,23 @@ azure-mgmt-core = ">=1.3.2" isodate = ">=0.6.1" typing-extensions = ">=4.6.0" +[[package]] +name = "azure-monitor-query" +version = "2.0.0" +description = "Microsoft Corporation Azure Monitor Query Client Library for Python" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "azure_monitor_query-2.0.0-py3-none-any.whl", hash = "sha256:8f52d581271d785e12f49cd5aaa144b8910fb843db2373855a7ef94c7fc462ea"}, + {file = "azure_monitor_query-2.0.0.tar.gz", hash = "sha256:7b05f2fcac4fb67fc9f77a7d4c5d98a0f3099fb73b57c69ec1b080773994671b"}, +] + +[package.dependencies] +azure-core = ">=1.30.0" +isodate = ">=0.6.1" +typing-extensions = ">=4.6.0" + [[package]] name = "azure-storage-blob" version = "12.24.1" @@ -1204,6 +1256,98 @@ files = [ {file = "contextlib2-21.6.0.tar.gz", hash = "sha256:ab1e2bfe1d01d968e1b7e8d9023bc51ef3509bba217bb730cee3827e1ee82869"}, ] +[[package]] +name = "contourpy" +version = "1.3.3" +description = "Python library for calculating contours of 2D quadrilateral grids" +optional = false +python-versions = ">=3.11" +groups = ["main"] +files = [ + {file = "contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1"}, + {file = "contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db"}, + {file = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620"}, + {file = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f"}, + {file = "contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff"}, + {file = "contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42"}, + {file = "contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470"}, + {file = "contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb"}, + {file = "contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1"}, + {file = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7"}, + {file = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411"}, + {file = "contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69"}, + {file = "contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b"}, + {file = "contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc"}, + {file = "contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5"}, + {file = "contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9"}, + {file = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659"}, + {file = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7"}, + {file = "contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d"}, + {file = "contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263"}, + {file = "contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9"}, + {file = "contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d"}, + {file = "contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b"}, + {file = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a"}, + {file = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e"}, + {file = "contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3"}, + {file = "contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8"}, + {file = "contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301"}, + {file = "contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a"}, + {file = "contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3"}, + {file = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b"}, + {file = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36"}, + {file = "contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d"}, + {file = "contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd"}, + {file = "contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339"}, + {file = "contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772"}, + {file = "contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0"}, + {file = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4"}, + {file = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f"}, + {file = "contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae"}, + {file = "contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc"}, + {file = "contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77"}, + {file = "contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880"}, +] + +[package.dependencies] +numpy = ">=1.25" + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["bokeh", "contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.17.0)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] + [[package]] name = "coverage" version = "7.5.4" @@ -1338,6 +1482,22 @@ ssh = ["bcrypt (>=3.1.5)"] test = ["certifi (>=2024)", "cryptography-vectors (==44.0.1)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] test-randomorder = ["pytest-randomly"] +[[package]] +name = "cycler" +version = "0.12.1" +description = "Composable style cycles" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, + {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, +] + +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] + [[package]] name = "dash" version = "3.1.1" @@ -1511,14 +1671,14 @@ with-social = ["django-allauth[socialaccount] (>=64.0.0)"] [[package]] name = "django" -version = "5.1.10" +version = "5.1.14" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." optional = false python-versions = ">=3.10" groups = ["main", "dev"] files = [ - {file = "django-5.1.10-py3-none-any.whl", hash = "sha256:19c9b771e9cf4de91101861aadd2daaa159bcf10698ca909c5755c88e70ccb84"}, - {file = "django-5.1.10.tar.gz", hash = "sha256:73e5d191421d177803dbd5495d94bc7d06d156df9561f4eea9e11b4994c07137"}, + {file = "django-5.1.14-py3-none-any.whl", hash = "sha256:2a4b9c20404fd1bf50aaaa5542a19d860594cba1354f688f642feb271b91df27"}, + {file = "django-5.1.14.tar.gz", hash = "sha256:b98409fb31fdd6e8c3a6ba2eef3415cc5c0020057b43b21ba7af6eff5f014831"}, ] [package.dependencies] @@ -1872,6 +2032,27 @@ files = [ Django = ">=4.2" djangorestframework = ">=3.15.0" +[[package]] +name = "drf-simple-apikey" +version = "2.2.1" +description = "API Key authentication and permissions for Django REST." +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "drf_simple_apikey-2.2.1-py2.py3-none-any.whl", hash = "sha256:2a60b35676d14f907c47dee179dd0fa7425a84c34d6ff5b48d08d3b87ff32809"}, + {file = "drf_simple_apikey-2.2.1.tar.gz", hash = "sha256:e5a52804bbac12c8db80c10a3d51a8514fc59fc8385b5e751099a2bc944ad25d"}, +] + +[package.dependencies] +cryptography = ">=38.0.4" +django = ">=4.2" +djangorestframework = ">=3.14.0" + +[package.extras] +test = ["coverage", "pytest", "pytest-django"] +tooling = ["black (==22.3.0)", "bump2version", "pylint"] + [[package]] name = "drf-spectacular" version = "0.27.2" @@ -2047,6 +2228,87 @@ werkzeug = ">=3.1.0" async = ["asgiref (>=3.2)"] dotenv = ["python-dotenv"] +[[package]] +name = "fonttools" +version = "4.60.1" +description = "Tools to manipulate font files" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "fonttools-4.60.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9a52f254ce051e196b8fe2af4634c2d2f02c981756c6464dc192f1b6050b4e28"}, + {file = "fonttools-4.60.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7420a2696a44650120cdd269a5d2e56a477e2bfa9d95e86229059beb1c19e15"}, + {file = "fonttools-4.60.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee0c0b3b35b34f782afc673d503167157094a16f442ace7c6c5e0ca80b08f50c"}, + {file = "fonttools-4.60.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:282dafa55f9659e8999110bd8ed422ebe1c8aecd0dc396550b038e6c9a08b8ea"}, + {file = "fonttools-4.60.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4ba4bd646e86de16160f0fb72e31c3b9b7d0721c3e5b26b9fa2fc931dfdb2652"}, + {file = "fonttools-4.60.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0b0835ed15dd5b40d726bb61c846a688f5b4ce2208ec68779bc81860adb5851a"}, + {file = "fonttools-4.60.1-cp310-cp310-win32.whl", hash = "sha256:1525796c3ffe27bb6268ed2a1bb0dcf214d561dfaf04728abf01489eb5339dce"}, + {file = "fonttools-4.60.1-cp310-cp310-win_amd64.whl", hash = "sha256:268ecda8ca6cb5c4f044b1fb9b3b376e8cd1b361cef275082429dc4174907038"}, + {file = "fonttools-4.60.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7b4c32e232a71f63a5d00259ca3d88345ce2a43295bb049d21061f338124246f"}, + {file = "fonttools-4.60.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3630e86c484263eaac71d117085d509cbcf7b18f677906824e4bace598fb70d2"}, + {file = "fonttools-4.60.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5c1015318e4fec75dd4943ad5f6a206d9727adf97410d58b7e32ab644a807914"}, + {file = "fonttools-4.60.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e6c58beb17380f7c2ea181ea11e7db8c0ceb474c9dd45f48e71e2cb577d146a1"}, + {file = "fonttools-4.60.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec3681a0cb34c255d76dd9d865a55f260164adb9fa02628415cdc2d43ee2c05d"}, + {file = "fonttools-4.60.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f4b5c37a5f40e4d733d3bbaaef082149bee5a5ea3156a785ff64d949bd1353fa"}, + {file = "fonttools-4.60.1-cp311-cp311-win32.whl", hash = "sha256:398447f3d8c0c786cbf1209711e79080a40761eb44b27cdafffb48f52bcec258"}, + {file = "fonttools-4.60.1-cp311-cp311-win_amd64.whl", hash = "sha256:d066ea419f719ed87bc2c99a4a4bfd77c2e5949cb724588b9dd58f3fd90b92bf"}, + {file = "fonttools-4.60.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:7b0c6d57ab00dae9529f3faf187f2254ea0aa1e04215cf2f1a8ec277c96661bc"}, + {file = "fonttools-4.60.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:839565cbf14645952d933853e8ade66a463684ed6ed6c9345d0faf1f0e868877"}, + {file = "fonttools-4.60.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8177ec9676ea6e1793c8a084a90b65a9f778771998eb919d05db6d4b1c0b114c"}, + {file = "fonttools-4.60.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:996a4d1834524adbb423385d5a629b868ef9d774670856c63c9a0408a3063401"}, + {file = "fonttools-4.60.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a46b2f450bc79e06ef3b6394f0c68660529ed51692606ad7f953fc2e448bc903"}, + {file = "fonttools-4.60.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6ec722ee589e89a89f5b7574f5c45604030aa6ae24cb2c751e2707193b466fed"}, + {file = "fonttools-4.60.1-cp312-cp312-win32.whl", hash = "sha256:b2cf105cee600d2de04ca3cfa1f74f1127f8455b71dbad02b9da6ec266e116d6"}, + {file = "fonttools-4.60.1-cp312-cp312-win_amd64.whl", hash = "sha256:992775c9fbe2cf794786fa0ffca7f09f564ba3499b8fe9f2f80bd7197db60383"}, + {file = "fonttools-4.60.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6f68576bb4bbf6060c7ab047b1574a1ebe5c50a17de62830079967b211059ebb"}, + {file = "fonttools-4.60.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:eedacb5c5d22b7097482fa834bda0dafa3d914a4e829ec83cdea2a01f8c813c4"}, + {file = "fonttools-4.60.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b33a7884fabd72bdf5f910d0cf46be50dce86a0362a65cfc746a4168c67eb96c"}, + {file = "fonttools-4.60.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2409d5fb7b55fd70f715e6d34e7a6e4f7511b8ad29a49d6df225ee76da76dd77"}, + {file = "fonttools-4.60.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c8651e0d4b3bdeda6602b85fdc2abbefc1b41e573ecb37b6779c4ca50753a199"}, + {file = "fonttools-4.60.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:145daa14bf24824b677b9357c5e44fd8895c2a8f53596e1b9ea3496081dc692c"}, + {file = "fonttools-4.60.1-cp313-cp313-win32.whl", hash = "sha256:2299df884c11162617a66b7c316957d74a18e3758c0274762d2cc87df7bc0272"}, + {file = "fonttools-4.60.1-cp313-cp313-win_amd64.whl", hash = "sha256:a3db56f153bd4c5c2b619ab02c5db5192e222150ce5a1bc10f16164714bc39ac"}, + {file = "fonttools-4.60.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:a884aef09d45ba1206712c7dbda5829562d3fea7726935d3289d343232ecb0d3"}, + {file = "fonttools-4.60.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8a44788d9d91df72d1a5eac49b31aeb887a5f4aab761b4cffc4196c74907ea85"}, + {file = "fonttools-4.60.1-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e852d9dda9f93ad3651ae1e3bb770eac544ec93c3807888798eccddf84596537"}, + {file = "fonttools-4.60.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:154cb6ee417e417bf5f7c42fe25858c9140c26f647c7347c06f0cc2d47eff003"}, + {file = "fonttools-4.60.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5664fd1a9ea7f244487ac8f10340c4e37664675e8667d6fee420766e0fb3cf08"}, + {file = "fonttools-4.60.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:583b7f8e3c49486e4d489ad1deacfb8d5be54a8ef34d6df824f6a171f8511d99"}, + {file = "fonttools-4.60.1-cp314-cp314-win32.whl", hash = "sha256:66929e2ea2810c6533a5184f938502cfdaea4bc3efb7130d8cc02e1c1b4108d6"}, + {file = "fonttools-4.60.1-cp314-cp314-win_amd64.whl", hash = "sha256:f3d5be054c461d6a2268831f04091dc82753176f6ea06dc6047a5e168265a987"}, + {file = "fonttools-4.60.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:b6379e7546ba4ae4b18f8ae2b9bc5960936007a1c0e30b342f662577e8bc3299"}, + {file = "fonttools-4.60.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9d0ced62b59e0430b3690dbc5373df1c2aa7585e9a8ce38eff87f0fd993c5b01"}, + {file = "fonttools-4.60.1-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:875cb7764708b3132637f6c5fb385b16eeba0f7ac9fa45a69d35e09b47045801"}, + {file = "fonttools-4.60.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a184b2ea57b13680ab6d5fbde99ccef152c95c06746cb7718c583abd8f945ccc"}, + {file = "fonttools-4.60.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:026290e4ec76583881763fac284aca67365e0be9f13a7fb137257096114cb3bc"}, + {file = "fonttools-4.60.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f0e8817c7d1a0c2eedebf57ef9a9896f3ea23324769a9a2061a80fe8852705ed"}, + {file = "fonttools-4.60.1-cp314-cp314t-win32.whl", hash = "sha256:1410155d0e764a4615774e5c2c6fc516259fe3eca5882f034eb9bfdbee056259"}, + {file = "fonttools-4.60.1-cp314-cp314t-win_amd64.whl", hash = "sha256:022beaea4b73a70295b688f817ddc24ed3e3418b5036ffcd5658141184ef0d0c"}, + {file = "fonttools-4.60.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:122e1a8ada290423c493491d002f622b1992b1ab0b488c68e31c413390dc7eb2"}, + {file = "fonttools-4.60.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a140761c4ff63d0cb9256ac752f230460ee225ccef4ad8f68affc723c88e2036"}, + {file = "fonttools-4.60.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0eae96373e4b7c9e45d099d7a523444e3554360927225c1cdae221a58a45b856"}, + {file = "fonttools-4.60.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:596ecaca36367027d525b3b426d8a8208169d09edcf8c7506aceb3a38bfb55c7"}, + {file = "fonttools-4.60.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2ee06fc57512144d8b0445194c2da9f190f61ad51e230f14836286470c99f854"}, + {file = "fonttools-4.60.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b42d86938e8dda1cd9a1a87a6d82f1818eaf933348429653559a458d027446da"}, + {file = "fonttools-4.60.1-cp39-cp39-win32.whl", hash = "sha256:8b4eb332f9501cb1cd3d4d099374a1e1306783ff95489a1026bde9eb02ccc34a"}, + {file = "fonttools-4.60.1-cp39-cp39-win_amd64.whl", hash = "sha256:7473a8ed9ed09aeaa191301244a5a9dbe46fe0bf54f9d6cd21d83044c3321217"}, + {file = "fonttools-4.60.1-py3-none-any.whl", hash = "sha256:906306ac7afe2156fcf0042173d6ebbb05416af70f6b370967b47f8f00103bbb"}, + {file = "fonttools-4.60.1.tar.gz", hash = "sha256:ef00af0439ebfee806b25f24c8f92109157ff3fac5731dc7867957812e87b8d9"}, +] + +[package.extras] +all = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\"", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0) ; python_version <= \"3.12\"", "xattr ; sys_platform == \"darwin\"", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\""] +lxml = ["lxml (>=4.0)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.23.0)"] +symfont = ["sympy"] +type1 = ["xattr ; sys_platform == \"darwin\""] +unicode = ["unicodedata2 (>=15.1.0) ; python_version <= \"3.12\""] +woff = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "zopfli (>=0.1.4)"] + [[package]] name = "freezegun" version = "1.5.1" @@ -2714,6 +2976,117 @@ files = [ [package.dependencies] referencing = ">=0.31.0" +[[package]] +name = "kiwisolver" +version = "1.4.9" +description = "A fast implementation of the Cassowary constraint solver" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "kiwisolver-1.4.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b4b4d74bda2b8ebf4da5bd42af11d02d04428b2c32846e4c2c93219df8a7987b"}, + {file = "kiwisolver-1.4.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fb3b8132019ea572f4611d770991000d7f58127560c4889729248eb5852a102f"}, + {file = "kiwisolver-1.4.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84fd60810829c27ae375114cd379da1fa65e6918e1da405f356a775d49a62bcf"}, + {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b78efa4c6e804ecdf727e580dbb9cba85624d2e1c6b5cb059c66290063bd99a9"}, + {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4efec7bcf21671db6a3294ff301d2fc861c31faa3c8740d1a94689234d1b415"}, + {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:90f47e70293fc3688b71271100a1a5453aa9944a81d27ff779c108372cf5567b"}, + {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8fdca1def57a2e88ef339de1737a1449d6dbf5fab184c54a1fca01d541317154"}, + {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9cf554f21be770f5111a1690d42313e140355e687e05cf82cb23d0a721a64a48"}, + {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fc1795ac5cd0510207482c3d1d3ed781143383b8cfd36f5c645f3897ce066220"}, + {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ccd09f20ccdbbd341b21a67ab50a119b64a403b09288c27481575105283c1586"}, + {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:540c7c72324d864406a009d72f5d6856f49693db95d1fbb46cf86febef873634"}, + {file = "kiwisolver-1.4.9-cp310-cp310-win_amd64.whl", hash = "sha256:ede8c6d533bc6601a47ad4046080d36b8fc99f81e6f1c17b0ac3c2dc91ac7611"}, + {file = "kiwisolver-1.4.9-cp310-cp310-win_arm64.whl", hash = "sha256:7b4da0d01ac866a57dd61ac258c5607b4cd677f63abaec7b148354d2b2cdd536"}, + {file = "kiwisolver-1.4.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb14a5da6dc7642b0f3a18f13654847cd8b7a2550e2645a5bda677862b03ba16"}, + {file = "kiwisolver-1.4.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:39a219e1c81ae3b103643d2aedb90f1ef22650deb266ff12a19e7773f3e5f089"}, + {file = "kiwisolver-1.4.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2405a7d98604b87f3fc28b1716783534b1b4b8510d8142adca34ee0bc3c87543"}, + {file = "kiwisolver-1.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dc1ae486f9abcef254b5618dfb4113dd49f94c68e3e027d03cf0143f3f772b61"}, + {file = "kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a1f570ce4d62d718dce3f179ee78dac3b545ac16c0c04bb363b7607a949c0d1"}, + {file = "kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb27e7b78d716c591e88e0a09a2139c6577865d7f2e152488c2cc6257f460872"}, + {file = "kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:15163165efc2f627eb9687ea5f3a28137217d217ac4024893d753f46bce9de26"}, + {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bdee92c56a71d2b24c33a7d4c2856bd6419d017e08caa7802d2963870e315028"}, + {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:412f287c55a6f54b0650bd9b6dce5aceddb95864a1a90c87af16979d37c89771"}, + {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2c93f00dcba2eea70af2be5f11a830a742fe6b579a1d4e00f47760ef13be247a"}, + {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f117e1a089d9411663a3207ba874f31be9ac8eaa5b533787024dc07aeb74f464"}, + {file = "kiwisolver-1.4.9-cp311-cp311-win_amd64.whl", hash = "sha256:be6a04e6c79819c9a8c2373317d19a96048e5a3f90bec587787e86a1153883c2"}, + {file = "kiwisolver-1.4.9-cp311-cp311-win_arm64.whl", hash = "sha256:0ae37737256ba2de764ddc12aed4956460277f00c4996d51a197e72f62f5eec7"}, + {file = "kiwisolver-1.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ac5a486ac389dddcc5bef4f365b6ae3ffff2c433324fb38dd35e3fab7c957999"}, + {file = "kiwisolver-1.4.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2ba92255faa7309d06fe44c3a4a97efe1c8d640c2a79a5ef728b685762a6fd2"}, + {file = "kiwisolver-1.4.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a2899935e724dd1074cb568ce7ac0dce28b2cd6ab539c8e001a8578eb106d14"}, + {file = "kiwisolver-1.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f6008a4919fdbc0b0097089f67a1eb55d950ed7e90ce2cc3e640abadd2757a04"}, + {file = "kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67bb8b474b4181770f926f7b7d2f8c0248cbcb78b660fdd41a47054b28d2a752"}, + {file = "kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2327a4a30d3ee07d2fbe2e7933e8a37c591663b96ce42a00bc67461a87d7df77"}, + {file = "kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a08b491ec91b1d5053ac177afe5290adacf1f0f6307d771ccac5de30592d198"}, + {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8fc5c867c22b828001b6a38d2eaeb88160bf5783c6cb4a5e440efc981ce286d"}, + {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3b3115b2581ea35bb6d1f24a4c90af37e5d9b49dcff267eeed14c3893c5b86ab"}, + {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858e4c22fb075920b96a291928cb7dea5644e94c0ee4fcd5af7e865655e4ccf2"}, + {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ed0fecd28cc62c54b262e3736f8bb2512d8dcfdc2bcf08be5f47f96bf405b145"}, + {file = "kiwisolver-1.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:f68208a520c3d86ea51acf688a3e3002615a7f0238002cccc17affecc86a8a54"}, + {file = "kiwisolver-1.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:2c1a4f57df73965f3f14df20b80ee29e6a7930a57d2d9e8491a25f676e197c60"}, + {file = "kiwisolver-1.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a5d0432ccf1c7ab14f9949eec60c5d1f924f17c037e9f8b33352fa05799359b8"}, + {file = "kiwisolver-1.4.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efb3a45b35622bb6c16dbfab491a8f5a391fe0e9d45ef32f4df85658232ca0e2"}, + {file = "kiwisolver-1.4.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1a12cf6398e8a0a001a059747a1cbf24705e18fe413bc22de7b3d15c67cffe3f"}, + {file = "kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098"}, + {file = "kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5656aa670507437af0207645273ccdfee4f14bacd7f7c67a4306d0dcaeaf6eed"}, + {file = "kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bfc08add558155345129c7803b3671cf195e6a56e7a12f3dde7c57d9b417f525"}, + {file = "kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:40092754720b174e6ccf9e845d0d8c7d8e12c3d71e7fc35f55f3813e96376f78"}, + {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:497d05f29a1300d14e02e6441cf0f5ee81c1ff5a304b0d9fb77423974684e08b"}, + {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdd1a81a1860476eb41ac4bc1e07b3f07259e6d55bbf739b79c8aaedcf512799"}, + {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e6b93f13371d341afee3be9f7c5964e3fe61d5fa30f6a30eb49856935dfe4fc3"}, + {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d75aa530ccfaa593da12834b86a0724f58bff12706659baa9227c2ccaa06264c"}, + {file = "kiwisolver-1.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:dd0a578400839256df88c16abddf9ba14813ec5f21362e1fe65022e00c883d4d"}, + {file = "kiwisolver-1.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:d4188e73af84ca82468f09cadc5ac4db578109e52acb4518d8154698d3a87ca2"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:5a0f2724dfd4e3b3ac5a82436a8e6fd16baa7d507117e4279b660fe8ca38a3a1"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1b11d6a633e4ed84fc0ddafd4ebfd8ea49b3f25082c04ad12b8315c11d504dc1"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61874cdb0a36016354853593cffc38e56fc9ca5aa97d2c05d3dcf6922cd55a11"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:60c439763a969a6af93b4881db0eed8fadf93ee98e18cbc35bc8da868d0c4f0c"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92a2f997387a1b79a75e7803aa7ded2cfbe2823852ccf1ba3bcf613b62ae3197"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31d512c812daea6d8b3be3b2bfcbeb091dbb09177706569bcfc6240dcf8b41c"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:52a15b0f35dad39862d376df10c5230155243a2c1a436e39eb55623ccbd68185"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a30fd6fdef1430fd9e1ba7b3398b5ee4e2887783917a687d86ba69985fb08748"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cc9617b46837c6468197b5945e196ee9ca43057bb7d9d1ae688101e4e1dddf64"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:0ab74e19f6a2b027ea4f845a78827969af45ce790e6cb3e1ebab71bdf9f215ff"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dba5ee5d3981160c28d5490f0d1b7ed730c22470ff7f6cc26cfcfaacb9896a07"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-win_arm64.whl", hash = "sha256:0749fd8f4218ad2e851e11cc4dc05c7cbc0cbc4267bdfdb31782e65aace4ee9c"}, + {file = "kiwisolver-1.4.9-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:9928fe1eb816d11ae170885a74d074f57af3a0d65777ca47e9aeb854a1fba386"}, + {file = "kiwisolver-1.4.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d0005b053977e7b43388ddec89fa567f43d4f6d5c2c0affe57de5ebf290dc552"}, + {file = "kiwisolver-1.4.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2635d352d67458b66fd0667c14cb1d4145e9560d503219034a18a87e971ce4f3"}, + {file = "kiwisolver-1.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:767c23ad1c58c9e827b649a9ab7809fd5fd9db266a9cf02b0e926ddc2c680d58"}, + {file = "kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72d0eb9fba308b8311685c2268cf7d0a0639a6cd027d8128659f72bdd8a024b4"}, + {file = "kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f68e4f3eeca8fb22cc3d731f9715a13b652795ef657a13df1ad0c7dc0e9731df"}, + {file = "kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d84cd4061ae292d8ac367b2c3fa3aad11cb8625a95d135fe93f286f914f3f5a6"}, + {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a60ea74330b91bd22a29638940d115df9dc00af5035a9a2a6ad9399ffb4ceca5"}, + {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ce6a3a4e106cf35c2d9c4fa17c05ce0b180db622736845d4315519397a77beaf"}, + {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:77937e5e2a38a7b48eef0585114fe7930346993a88060d0bf886086d2aa49ef5"}, + {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:24c175051354f4a28c5d6a31c93906dc653e2bf234e8a4bbfb964892078898ce"}, + {file = "kiwisolver-1.4.9-cp314-cp314-win_amd64.whl", hash = "sha256:0763515d4df10edf6d06a3c19734e2566368980d21ebec439f33f9eb936c07b7"}, + {file = "kiwisolver-1.4.9-cp314-cp314-win_arm64.whl", hash = "sha256:0e4e2bf29574a6a7b7f6cb5fa69293b9f96c928949ac4a53ba3f525dffb87f9c"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d976bbb382b202f71c67f77b0ac11244021cfa3f7dfd9e562eefcea2df711548"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2489e4e5d7ef9a1c300a5e0196e43d9c739f066ef23270607d45aba368b91f2d"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e2ea9f7ab7fbf18fffb1b5434ce7c69a07582f7acc7717720f1d69f3e806f90c"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b34e51affded8faee0dfdb705416153819d8ea9250bbbf7ea1b249bdeb5f1122"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8aacd3d4b33b772542b2e01beb50187536967b514b00003bdda7589722d2a64"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7cf974dd4e35fa315563ac99d6287a1024e4dc2077b8a7d7cd3d2fb65d283134"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:85bd218b5ecfbee8c8a82e121802dcb519a86044c9c3b2e4aef02fa05c6da370"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0856e241c2d3df4efef7c04a1e46b1936b6120c9bcf36dd216e3acd84bc4fb21"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9af39d6551f97d31a4deebeac6f45b156f9755ddc59c07b402c148f5dbb6482a"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:bb4ae2b57fc1d8cbd1cf7b1d9913803681ffa903e7488012be5b76dedf49297f"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:aedff62918805fb62d43a4aa2ecd4482c380dc76cd31bd7c8878588a61bd0369"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:1fa333e8b2ce4d9660f2cda9c0e1b6bafcfb2457a9d259faa82289e73ec24891"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:4a48a2ce79d65d363597ef7b567ce3d14d68783d2b2263d98db3d9477805ba32"}, + {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4d1d9e582ad4d63062d34077a9a1e9f3c34088a2ec5135b1f7190c07cf366527"}, + {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:deed0c7258ceb4c44ad5ec7d9918f9f14fd05b2be86378d86cf50e63d1e7b771"}, + {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0a590506f303f512dff6b7f75fd2fd18e16943efee932008fe7140e5fa91d80e"}, + {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e09c2279a4d01f099f52d5c4b3d9e208e91edcbd1a175c9662a8b16e000fece9"}, + {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c9e7cdf45d594ee04d5be1b24dd9d49f3d1590959b2271fb30b5ca2b262c00fb"}, + {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:720e05574713db64c356e86732c0f3c5252818d05f9df320f0ad8380641acea5"}, + {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:17680d737d5335b552994a2008fab4c851bcd7de33094a82067ef3a576ff02fa"}, + {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:85b5352f94e490c028926ea567fc569c52ec79ce131dadb968d3853e809518c2"}, + {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:464415881e4801295659462c49461a24fb107c140de781d55518c4b80cb6790f"}, + {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:fb940820c63a9590d31d88b815e7a3aa5915cad3ce735ab45f0c730b39547de1"}, + {file = "kiwisolver-1.4.9.tar.gz", hash = "sha256:c3b22c26c6fd6811b0ae8363b95ca8ce4ea3c202d3d0975b2914310ceb1bcc4d"}, +] + [[package]] name = "kombu" version = "5.5.4" @@ -2933,6 +3306,22 @@ html5 = ["html5lib"] htmlsoup = ["BeautifulSoup4"] source = ["Cython (>=3.0.11,<3.1.0)"] +[[package]] +name = "markdown" +version = "3.9" +description = "Python implementation of John Gruber's Markdown." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "markdown-3.9-py3-none-any.whl", hash = "sha256:9f4d91ed810864ea88a6f32c07ba8bee1346c0cc1f6b1f9f6c822f2a9667d280"}, + {file = "markdown-3.9.tar.gz", hash = "sha256:d2900fe1782bd33bdbbd56859defef70c2e78fc46668f8eb9df3128138f2cb6a"}, +] + +[package.extras] +docs = ["mdx_gh_links (>=0.2)", "mkdocs (>=1.6)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] +testing = ["coverage", "pyyaml"] + [[package]] name = "markdown-it-py" version = "4.0.0" @@ -3048,6 +3437,85 @@ dev = ["marshmallow[tests]", "pre-commit (>=3.5,<5.0)", "tox"] docs = ["autodocsumm (==0.2.14)", "furo (==2024.8.6)", "sphinx (==8.1.3)", "sphinx-copybutton (==0.5.2)", "sphinx-issues (==5.0.0)", "sphinxext-opengraph (==0.9.1)"] tests = ["pytest", "simplejson"] +[[package]] +name = "matplotlib" +version = "3.10.6" +description = "Python plotting package" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "matplotlib-3.10.6-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:bc7316c306d97463a9866b89d5cc217824e799fa0de346c8f68f4f3d27c8693d"}, + {file = "matplotlib-3.10.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d00932b0d160ef03f59f9c0e16d1e3ac89646f7785165ce6ad40c842db16cc2e"}, + {file = "matplotlib-3.10.6-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8fa4c43d6bfdbfec09c733bca8667de11bfa4970e8324c471f3a3632a0301c15"}, + {file = "matplotlib-3.10.6-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ea117a9c1627acaa04dbf36265691921b999cbf515a015298e54e1a12c3af837"}, + {file = "matplotlib-3.10.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:08fc803293b4e1694ee325896030de97f74c141ccff0be886bb5915269247676"}, + {file = "matplotlib-3.10.6-cp310-cp310-win_amd64.whl", hash = "sha256:2adf92d9b7527fbfb8818e050260f0ebaa460f79d61546374ce73506c9421d09"}, + {file = "matplotlib-3.10.6-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:905b60d1cb0ee604ce65b297b61cf8be9f4e6cfecf95a3fe1c388b5266bc8f4f"}, + {file = "matplotlib-3.10.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7bac38d816637343e53d7185d0c66677ff30ffb131044a81898b5792c956ba76"}, + {file = "matplotlib-3.10.6-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:942a8de2b5bfff1de31d95722f702e2966b8a7e31f4e68f7cd963c7cd8861cf6"}, + {file = "matplotlib-3.10.6-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3276c85370bc0dfca051ec65c5817d1e0f8f5ce1b7787528ec8ed2d524bbc2f"}, + {file = "matplotlib-3.10.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9df5851b219225731f564e4b9e7f2ac1e13c9e6481f941b5631a0f8e2d9387ce"}, + {file = "matplotlib-3.10.6-cp311-cp311-win_amd64.whl", hash = "sha256:abb5d9478625dd9c9eb51a06d39aae71eda749ae9b3138afb23eb38824026c7e"}, + {file = "matplotlib-3.10.6-cp311-cp311-win_arm64.whl", hash = "sha256:886f989ccfae63659183173bb3fced7fd65e9eb793c3cc21c273add368536951"}, + {file = "matplotlib-3.10.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:31ca662df6a80bd426f871105fdd69db7543e28e73a9f2afe80de7e531eb2347"}, + {file = "matplotlib-3.10.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1678bb61d897bb4ac4757b5ecfb02bfb3fddf7f808000fb81e09c510712fda75"}, + {file = "matplotlib-3.10.6-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:56cd2d20842f58c03d2d6e6c1f1cf5548ad6f66b91e1e48f814e4fb5abd1cb95"}, + {file = "matplotlib-3.10.6-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:662df55604a2f9a45435566d6e2660e41efe83cd94f4288dfbf1e6d1eae4b0bb"}, + {file = "matplotlib-3.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:08f141d55148cd1fc870c3387d70ca4df16dee10e909b3b038782bd4bda6ea07"}, + {file = "matplotlib-3.10.6-cp312-cp312-win_amd64.whl", hash = "sha256:590f5925c2d650b5c9d813c5b3b5fc53f2929c3f8ef463e4ecfa7e052044fb2b"}, + {file = "matplotlib-3.10.6-cp312-cp312-win_arm64.whl", hash = "sha256:f44c8d264a71609c79a78d50349e724f5d5fc3684ead7c2a473665ee63d868aa"}, + {file = "matplotlib-3.10.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:819e409653c1106c8deaf62e6de6b8611449c2cd9939acb0d7d4e57a3d95cc7a"}, + {file = "matplotlib-3.10.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:59c8ac8382fefb9cb71308dde16a7c487432f5255d8f1fd32473523abecfecdf"}, + {file = "matplotlib-3.10.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:84e82d9e0fd70c70bc55739defbd8055c54300750cbacf4740c9673a24d6933a"}, + {file = "matplotlib-3.10.6-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25f7a3eb42d6c1c56e89eacd495661fc815ffc08d9da750bca766771c0fd9110"}, + {file = "matplotlib-3.10.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f9c862d91ec0b7842920a4cfdaaec29662195301914ea54c33e01f1a28d014b2"}, + {file = "matplotlib-3.10.6-cp313-cp313-win_amd64.whl", hash = "sha256:1b53bd6337eba483e2e7d29c5ab10eee644bc3a2491ec67cc55f7b44583ffb18"}, + {file = "matplotlib-3.10.6-cp313-cp313-win_arm64.whl", hash = "sha256:cbd5eb50b7058b2892ce45c2f4e92557f395c9991f5c886d1bb74a1582e70fd6"}, + {file = "matplotlib-3.10.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:acc86dd6e0e695c095001a7fccff158c49e45e0758fdf5dcdbb0103318b59c9f"}, + {file = "matplotlib-3.10.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e228cd2ffb8f88b7d0b29e37f68ca9aaf83e33821f24a5ccc4f082dd8396bc27"}, + {file = "matplotlib-3.10.6-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:658bc91894adeab669cf4bb4a186d049948262987e80f0857216387d7435d833"}, + {file = "matplotlib-3.10.6-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8913b7474f6dd83ac444c9459c91f7f0f2859e839f41d642691b104e0af056aa"}, + {file = "matplotlib-3.10.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:091cea22e059b89f6d7d1a18e2c33a7376c26eee60e401d92a4d6726c4e12706"}, + {file = "matplotlib-3.10.6-cp313-cp313t-win_amd64.whl", hash = "sha256:491e25e02a23d7207629d942c666924a6b61e007a48177fdd231a0097b7f507e"}, + {file = "matplotlib-3.10.6-cp313-cp313t-win_arm64.whl", hash = "sha256:3d80d60d4e54cda462e2cd9a086d85cd9f20943ead92f575ce86885a43a565d5"}, + {file = "matplotlib-3.10.6-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:70aaf890ce1d0efd482df969b28a5b30ea0b891224bb315810a3940f67182899"}, + {file = "matplotlib-3.10.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1565aae810ab79cb72e402b22facfa6501365e73ebab70a0fdfb98488d2c3c0c"}, + {file = "matplotlib-3.10.6-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3b23315a01981689aa4e1a179dbf6ef9fbd17143c3eea77548c2ecfb0499438"}, + {file = "matplotlib-3.10.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:30fdd37edf41a4e6785f9b37969de57aea770696cb637d9946eb37470c94a453"}, + {file = "matplotlib-3.10.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bc31e693da1c08012c764b053e702c1855378e04102238e6a5ee6a7117c53a47"}, + {file = "matplotlib-3.10.6-cp314-cp314-win_amd64.whl", hash = "sha256:05be9bdaa8b242bc6ff96330d18c52f1fc59c6fb3a4dd411d953d67e7e1baf98"}, + {file = "matplotlib-3.10.6-cp314-cp314-win_arm64.whl", hash = "sha256:f56a0d1ab05d34c628592435781d185cd99630bdfd76822cd686fb5a0aecd43a"}, + {file = "matplotlib-3.10.6-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:94f0b4cacb23763b64b5dace50d5b7bfe98710fed5f0cef5c08135a03399d98b"}, + {file = "matplotlib-3.10.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:cc332891306b9fb39462673d8225d1b824c89783fee82840a709f96714f17a5c"}, + {file = "matplotlib-3.10.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee1d607b3fb1590deb04b69f02ea1d53ed0b0bf75b2b1a5745f269afcbd3cdd3"}, + {file = "matplotlib-3.10.6-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:376a624a218116461696b27b2bbf7a8945053e6d799f6502fc03226d077807bf"}, + {file = "matplotlib-3.10.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:83847b47f6524c34b4f2d3ce726bb0541c48c8e7692729865c3df75bfa0f495a"}, + {file = "matplotlib-3.10.6-cp314-cp314t-win_amd64.whl", hash = "sha256:c7e0518e0d223683532a07f4b512e2e0729b62674f1b3a1a69869f98e6b1c7e3"}, + {file = "matplotlib-3.10.6-cp314-cp314t-win_arm64.whl", hash = "sha256:4dd83e029f5b4801eeb87c64efd80e732452781c16a9cf7415b7b63ec8f374d7"}, + {file = "matplotlib-3.10.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:13fcd07ccf17e354398358e0307a1f53f5325dca22982556ddb9c52837b5af41"}, + {file = "matplotlib-3.10.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:470fc846d59d1406e34fa4c32ba371039cd12c2fe86801159a965956f2575bd1"}, + {file = "matplotlib-3.10.6-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f7173f8551b88f4ef810a94adae3128c2530e0d07529f7141be7f8d8c365f051"}, + {file = "matplotlib-3.10.6-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f2d684c3204fa62421bbf770ddfebc6b50130f9cad65531eeba19236d73bb488"}, + {file = "matplotlib-3.10.6-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:6f4a69196e663a41d12a728fab8751177215357906436804217d6d9cf0d4d6cf"}, + {file = "matplotlib-3.10.6-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d6ca6ef03dfd269f4ead566ec6f3fb9becf8dab146fb999022ed85ee9f6b3eb"}, + {file = "matplotlib-3.10.6.tar.gz", hash = "sha256:ec01b645840dd1996df21ee37f208cd8ba57644779fa20464010638013d3203c"}, +] + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +kiwisolver = ">=1.3.1" +numpy = ">=1.23" +packaging = ">=20.0" +pillow = ">=8" +pyparsing = ">=2.3.1" +python-dateutil = ">=2.7" + +[package.extras] +dev = ["meson-python (>=0.13.1,<0.17.0)", "pybind11 (>=2.13.2,!=2.13.3)", "setuptools (>=64)", "setuptools_scm (>=7)"] + [[package]] name = "mccabe" version = "0.7.0" @@ -3768,6 +4236,131 @@ files = [ [package.dependencies] setuptools = "*" +[[package]] +name = "pillow" +version = "11.3.0" +description = "Python Imaging Library (Fork)" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "pillow-11.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860"}, + {file = "pillow-11.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad"}, + {file = "pillow-11.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0"}, + {file = "pillow-11.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b"}, + {file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50"}, + {file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae"}, + {file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9"}, + {file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e"}, + {file = "pillow-11.3.0-cp310-cp310-win32.whl", hash = "sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6"}, + {file = "pillow-11.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f"}, + {file = "pillow-11.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f"}, + {file = "pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722"}, + {file = "pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288"}, + {file = "pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d"}, + {file = "pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494"}, + {file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58"}, + {file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f"}, + {file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e"}, + {file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94"}, + {file = "pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0"}, + {file = "pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac"}, + {file = "pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd"}, + {file = "pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4"}, + {file = "pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69"}, + {file = "pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d"}, + {file = "pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6"}, + {file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7"}, + {file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024"}, + {file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809"}, + {file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d"}, + {file = "pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149"}, + {file = "pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d"}, + {file = "pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542"}, + {file = "pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd"}, + {file = "pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8"}, + {file = "pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f"}, + {file = "pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c"}, + {file = "pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd"}, + {file = "pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e"}, + {file = "pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1"}, + {file = "pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805"}, + {file = "pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8"}, + {file = "pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2"}, + {file = "pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b"}, + {file = "pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3"}, + {file = "pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51"}, + {file = "pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580"}, + {file = "pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e"}, + {file = "pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d"}, + {file = "pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced"}, + {file = "pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c"}, + {file = "pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8"}, + {file = "pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59"}, + {file = "pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe"}, + {file = "pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c"}, + {file = "pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788"}, + {file = "pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31"}, + {file = "pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e"}, + {file = "pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12"}, + {file = "pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a"}, + {file = "pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632"}, + {file = "pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673"}, + {file = "pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027"}, + {file = "pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77"}, + {file = "pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874"}, + {file = "pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a"}, + {file = "pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214"}, + {file = "pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635"}, + {file = "pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6"}, + {file = "pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae"}, + {file = "pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653"}, + {file = "pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6"}, + {file = "pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36"}, + {file = "pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b"}, + {file = "pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477"}, + {file = "pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50"}, + {file = "pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b"}, + {file = "pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12"}, + {file = "pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db"}, + {file = "pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa"}, + {file = "pillow-11.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:48d254f8a4c776de343051023eb61ffe818299eeac478da55227d96e241de53f"}, + {file = "pillow-11.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7aee118e30a4cf54fdd873bd3a29de51e29105ab11f9aad8c32123f58c8f8081"}, + {file = "pillow-11.3.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:23cff760a9049c502721bdb743a7cb3e03365fafcdfc2ef9784610714166e5a4"}, + {file = "pillow-11.3.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6359a3bc43f57d5b375d1ad54a0074318a0844d11b76abccf478c37c986d3cfc"}, + {file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:092c80c76635f5ecb10f3f83d76716165c96f5229addbd1ec2bdbbda7d496e06"}, + {file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cadc9e0ea0a2431124cde7e1697106471fc4c1da01530e679b2391c37d3fbb3a"}, + {file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6a418691000f2a418c9135a7cf0d797c1bb7d9a485e61fe8e7722845b95ef978"}, + {file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:97afb3a00b65cc0804d1c7abddbf090a81eaac02768af58cbdcaaa0a931e0b6d"}, + {file = "pillow-11.3.0-cp39-cp39-win32.whl", hash = "sha256:ea944117a7974ae78059fcc1800e5d3295172bb97035c0c1d9345fca1419da71"}, + {file = "pillow-11.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:e5c5858ad8ec655450a7c7df532e9842cf8df7cc349df7225c60d5d348c8aada"}, + {file = "pillow-11.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:6abdbfd3aea42be05702a8dd98832329c167ee84400a1d1f61ab11437f1717eb"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8"}, + {file = "pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] +test-arrow = ["pyarrow"] +tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "trove-classifiers (>=2024.10.12)"] +typing = ["typing-extensions ; python_version < \"3.10\""] +xmp = ["defusedxml"] + [[package]] name = "platformdirs" version = "4.3.8" @@ -3987,7 +4580,7 @@ files = [ [[package]] name = "prowler" -version = "5.11.0" +version = "5.13.0" description = "Prowler is an Open Source security tool to perform AWS, GCP and Azure security best practices assessments, audits, incident response, continuous monitoring, hardening and forensics readiness. It contains hundreds of controls covering CIS, NIST 800, NIST CSF, CISA, RBI, FedRAMP, PCI-DSS, GDPR, HIPAA, FFIEC, SOC2, GXP, AWS Well-Architected Framework Security Pillar, AWS Foundational Technical Review (FTR), ENS (Spanish National Security Scheme) and your custom security frameworks." optional = false python-versions = ">3.9.1,<3.13" @@ -4000,6 +4593,7 @@ alive-progress = "3.3.0" awsipranges = "0.3.3" azure-identity = "1.21.0" azure-keyvault-keys = "4.10.0" +azure-mgmt-apimanagement = "5.0.0" azure-mgmt-applicationinsights = "4.1.0" azure-mgmt-authorization = "4.0.0" azure-mgmt-compute = "34.0.0" @@ -4008,6 +4602,7 @@ azure-mgmt-containerservice = "34.1.0" azure-mgmt-cosmosdb = "9.7.0" azure-mgmt-databricks = "2.0.0" azure-mgmt-keyvault = "10.3.1" +azure-mgmt-loganalytics = "12.0.0" azure-mgmt-monitor = "6.0.2" azure-mgmt-network = "28.1.0" azure-mgmt-rdbms = "10.1.0" @@ -4020,6 +4615,7 @@ azure-mgmt-sql = "3.0.1" azure-mgmt-storage = "22.1.1" azure-mgmt-subscription = "3.1.1" azure-mgmt-web = "8.0.0" +azure-monitor-query = "2.0.0" azure-storage-blob = "12.24.1" boto3 = "1.39.15" botocore = "1.39.15" @@ -4031,8 +4627,10 @@ detect-secrets = "1.5.0" dulwich = "0.23.0" google-api-python-client = "2.163.0" google-auth-httplib2 = ">=0.1,<0.3" +h2 = "4.3.0" jsonschema = "4.23.0" kubernetes = "32.0.1" +markdown = "3.9.0" microsoft-kiota-abstractions = "1.9.2" msgraph-sdk = "1.23.0" numpy = "2.0.2" @@ -4053,7 +4651,7 @@ tzlocal = "5.3.1" type = "git" url = "https://github.com/prowler-cloud/prowler.git" reference = "master" -resolved_reference = "525f152e51f82de2110ed158c8dc489e42c289cf" +resolved_reference = "a52697bfdfee83d14a49c11dcbe96888b5cd767e" [[package]] name = "psutil" @@ -4922,6 +5520,29 @@ attrs = ">=22.2.0" rpds-py = ">=0.7.0" typing-extensions = {version = ">=4.4.0", markers = "python_version < \"3.13\""} +[[package]] +name = "reportlab" +version = "4.4.4" +description = "The Reportlab Toolkit" +optional = false +python-versions = "<4,>=3.9" +groups = ["main"] +files = [ + {file = "reportlab-4.4.4-py3-none-any.whl", hash = "sha256:299b3b0534e7202bb94ed2ddcd7179b818dcda7de9d8518a57c85a58a1ebaadb"}, + {file = "reportlab-4.4.4.tar.gz", hash = "sha256:cb2f658b7f4a15be2cc68f7203aa67faef67213edd4f2d4bdd3eb20dab75a80d"}, +] + +[package.dependencies] +charset-normalizer = "*" +pillow = ">=9.0.0" + +[package.extras] +accel = ["rl_accel (>=0.9.0,<1.1)"] +bidi = ["rlbidi"] +pycairo = ["freetype-py (>=2.3.0,<2.4)", "rlPyCairo (>=0.2.0,<1)"] +renderpm = ["rl_renderPM (>=4.0.3,<4.1)"] +shaping = ["uharfbuzz"] + [[package]] name = "requests" version = "2.32.5" @@ -5223,6 +5844,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"}, @@ -5231,6 +5853,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"}, @@ -5239,6 +5862,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"}, @@ -5247,6 +5871,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"}, @@ -5255,6 +5880,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"}, @@ -6160,4 +6786,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.11,<3.13" -content-hash = "b954196aba7e108cacb94fd15732be7130b27379add09140fabbb55f7335bb7b" +content-hash = "943e2cd6b87229704550d4e140b36509fb9f58896ebb5834b9fbabe28a9ee92f" diff --git a/api/pyproject.toml b/api/pyproject.toml index 3a597281cc..ffc8413489 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -7,7 +7,7 @@ authors = [{name = "Prowler Engineering", email = "engineering@prowler.com"}] dependencies = [ "celery[pytest] (>=5.4.0,<6.0.0)", "dj-rest-auth[with_social,jwt] (==7.0.1)", - "django==5.1.10", + "django (==5.1.14)", "django-allauth[saml] (>=65.8.0,<66.0.0)", "django-celery-beat (>=2.7.0,<3.0.0)", "django-celery-results (>=2.5.1,<3.0.0)", @@ -31,7 +31,11 @@ dependencies = [ "uuid6==2024.7.10", "openai (>=1.82.0,<2.0.0)", "xmlsec==1.3.14", - "h2 (==4.3.0)" + "h2 (==4.3.0)", + "markdown (>=3.9,<4.0)", + "drf-simple-apikey (==2.2.1)", + "matplotlib (>=3.10.6,<4.0.0)", + "reportlab (>=4.4.4,<5.0.0)" ] description = "Prowler's API (Django/DRF)" license = "Apache-2.0" @@ -39,7 +43,7 @@ name = "prowler-api" package-mode = false # Needed for the SDK compatibility requires-python = ">=3.11,<3.13" -version = "1.12.0" +version = "1.15.0" [project.scripts] celery = "src.backend.config.settings.celery" diff --git a/api/src/backend/api/admin.py b/api/src/backend/api/admin.py deleted file mode 100644 index 4185d360e9..0000000000 --- a/api/src/backend/api/admin.py +++ /dev/null @@ -1,3 +0,0 @@ -# from django.contrib import admin - -# Register your models here. diff --git a/api/src/backend/api/apps.py b/api/src/backend/api/apps.py index bfd78e30c7..add97cf376 100644 --- a/api/src/backend/api/apps.py +++ b/api/src/backend/api/apps.py @@ -1,4 +1,26 @@ +import logging +import os +import sys +from pathlib import Path + +from config.custom_logging import BackendLogger +from config.env import env from django.apps import AppConfig +from django.conf import settings + +logger = logging.getLogger(BackendLogger.API) + +SIGNING_KEY_ENV = "DJANGO_TOKEN_SIGNING_KEY" +VERIFYING_KEY_ENV = "DJANGO_TOKEN_VERIFYING_KEY" + +PRIVATE_KEY_FILE = "jwt_private.pem" +PUBLIC_KEY_FILE = "jwt_public.pem" + +KEYS_DIRECTORY = ( + Path.home() / ".config" / "prowler-api" +) # `/home/prowler/.config/prowler-api` inside the container + +_keys_initialized = False # Flag to prevent multiple executions within the same process class ApiConfig(AppConfig): @@ -6,7 +28,142 @@ class ApiConfig(AppConfig): name = "api" def ready(self): + from api import schema_extensions # noqa: F401 from api import signals # noqa: F401 from api.compliance import load_prowler_compliance + # Generate required cryptographic keys if not present, but only if: + # `"manage.py" not in sys.argv`: If an external server (e.g., Gunicorn) is running the app + # `os.environ.get("RUN_MAIN")`: If it's not a Django command or using `runserver`, + # only the main process will do it + if "manage.py" not in sys.argv or os.environ.get("RUN_MAIN"): + self._ensure_crypto_keys() + load_prowler_compliance() + + def _ensure_crypto_keys(self): + """ + Orchestrator method that ensures all required cryptographic keys are present. + This method coordinates the generation of: + - RSA key pairs for JWT token signing and verification + Note: During development, Django spawns multiple processes (migrations, fixtures, etc.) + which will each generate their own keys. This is expected behavior and each process + will have consistent keys for its lifetime. In production, set the keys as environment + variables to avoid regeneration. + """ + global _keys_initialized + + # Skip key generation if running tests + if hasattr(settings, "TESTING") and settings.TESTING: + return + + # Skip if already initialized in this process + if _keys_initialized: + return + + # Check if both JWT keys are set; if not, generate them + signing_key = env.str(SIGNING_KEY_ENV, default="").strip() + verifying_key = env.str(VERIFYING_KEY_ENV, default="").strip() + + if not signing_key or not verifying_key: + logger.info( + f"Generating JWT RSA key pair. In production, set '{SIGNING_KEY_ENV}' and '{VERIFYING_KEY_ENV}' " + "environment variables." + ) + self._ensure_jwt_keys() + + # Mark as initialized to prevent future executions in this process + _keys_initialized = True + + def _read_key_file(self, file_name): + """ + Utility method to read the contents of a file. + """ + file_path = KEYS_DIRECTORY / file_name + return file_path.read_text().strip() if file_path.is_file() else None + + def _write_key_file(self, file_name, content, private=True): + """ + Utility method to write content to a file. + """ + try: + file_path = KEYS_DIRECTORY / file_name + file_path.parent.mkdir(parents=True, exist_ok=True) + file_path.write_text(content) + file_path.chmod(0o600 if private else 0o644) + + except Exception as e: + logger.error( + f"Error writing key file '{file_name}': {e}. " + f"Please set '{SIGNING_KEY_ENV}' and '{VERIFYING_KEY_ENV}' manually." + ) + raise e + + def _ensure_jwt_keys(self): + """ + Generate RSA key pairs for JWT token signing and verification + if they are not already set in environment variables. + """ + # Read existing keys from files if they exist + signing_key = self._read_key_file(PRIVATE_KEY_FILE) + verifying_key = self._read_key_file(PUBLIC_KEY_FILE) + + if not signing_key or not verifying_key: + # Generate and store the RSA key pair + signing_key, verifying_key = self._generate_jwt_keys() + self._write_key_file(PRIVATE_KEY_FILE, signing_key, private=True) + self._write_key_file(PUBLIC_KEY_FILE, verifying_key, private=False) + logger.info("JWT keys generated and stored successfully") + + else: + logger.info("JWT keys already generated") + + # Set environment variables and Django settings + os.environ[SIGNING_KEY_ENV] = signing_key + settings.SIMPLE_JWT["SIGNING_KEY"] = signing_key + + os.environ[VERIFYING_KEY_ENV] = verifying_key + settings.SIMPLE_JWT["VERIFYING_KEY"] = verifying_key + + def _generate_jwt_keys(self): + """ + Generate and set RSA key pairs for JWT token operations. + """ + try: + from cryptography.hazmat.primitives import serialization + from cryptography.hazmat.primitives.asymmetric import rsa + + # Generate RSA key pair + private_key = rsa.generate_private_key( # Future improvement: we could read the next values from env vars + public_exponent=65537, + key_size=2048, + ) + + # Serialize private key (for signing) + private_pem = private_key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption(), + ).decode("utf-8") + + # Serialize public key (for verification) + public_key = private_key.public_key() + public_pem = public_key.public_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PublicFormat.SubjectPublicKeyInfo, + ).decode("utf-8") + + logger.debug("JWT RSA key pair generated successfully.") + return private_pem, public_pem + + except ImportError as e: + logger.warning( + "The 'cryptography' package is required for automatic JWT key generation." + ) + raise e + + except Exception as e: + logger.error( + f"Error generating JWT keys: {e}. Please set '{SIGNING_KEY_ENV}' and '{VERIFYING_KEY_ENV}' manually." + ) + raise e diff --git a/api/src/backend/api/authentication.py b/api/src/backend/api/authentication.py new file mode 100644 index 0000000000..499e290bb7 --- /dev/null +++ b/api/src/backend/api/authentication.py @@ -0,0 +1,95 @@ +from typing import Optional, Tuple +from uuid import UUID + +from cryptography.fernet import InvalidToken +from django.utils import timezone +from drf_simple_apikey.backends import APIKeyAuthentication as BaseAPIKeyAuth +from drf_simple_apikey.crypto import get_crypto +from rest_framework.authentication import BaseAuthentication +from rest_framework.exceptions import AuthenticationFailed +from rest_framework.request import Request +from rest_framework_simplejwt.authentication import JWTAuthentication + +from api.db_router import MainRouter +from api.models import TenantAPIKey, TenantAPIKeyManager + + +class TenantAPIKeyAuthentication(BaseAPIKeyAuth): + model = TenantAPIKey + + def __init__(self): + self.key_crypto = get_crypto() + + def _authenticate_credentials(self, request, key): + """ + Override to use admin connection, bypassing RLS during authentication. + Delegates to parent after temporarily routing model queries to admin DB. + """ + # Temporarily point the model's manager to admin database + original_objects = self.model.objects + self.model.objects = self.model.objects.using(MainRouter.admin_db) + + try: + # Call parent method which will now use admin database + return super()._authenticate_credentials(request, key) + finally: + # Restore original manager + self.model.objects = original_objects + + def authenticate(self, request: Request): + prefixed_key = self.get_key(request) + + # Split prefix from key (format: pk_xxxxxxxx.encrypted_key) + try: + prefix, key = prefixed_key.split(TenantAPIKeyManager.separator, 1) + except ValueError: + raise AuthenticationFailed("Invalid API Key.") + + try: + entity, _ = self._authenticate_credentials(request, key) + except InvalidToken: + raise AuthenticationFailed("Invalid API Key.") + + # Get the API key instance to update last_used_at and retrieve tenant info + # We need to decrypt again to get the pk (already validated by _authenticate_credentials) + payload = self.key_crypto.decrypt(key) + api_key_pk = payload["_pk"] + + # Convert string UUID back to UUID object for lookup + if isinstance(api_key_pk, str): + api_key_pk = UUID(api_key_pk) + + try: + api_key_instance = TenantAPIKey.objects.using(MainRouter.admin_db).get( + id=api_key_pk, prefix=prefix + ) + except TenantAPIKey.DoesNotExist: + raise AuthenticationFailed("Invalid API Key.") + + # Update last_used_at + api_key_instance.last_used_at = timezone.now() + api_key_instance.save(update_fields=["last_used_at"], using=MainRouter.admin_db) + + return entity, { + "tenant_id": str(api_key_instance.tenant_id), + "sub": str(api_key_instance.entity.id), + "api_key_prefix": prefix, + } + + +class CombinedJWTOrAPIKeyAuthentication(BaseAuthentication): + jwt_auth = JWTAuthentication() + api_key_auth = TenantAPIKeyAuthentication() + + def authenticate(self, request: Request) -> Optional[Tuple[object, dict]]: + auth_header = request.headers.get("Authorization", "") + + # Prioritize JWT authentication if both are present + if auth_header.startswith("Bearer "): + return self.jwt_auth.authenticate(request) + + if auth_header.startswith("Api-Key "): + return self.api_key_auth.authenticate(request) + + # Default fallback + return self.jwt_auth.authenticate(request) diff --git a/api/src/backend/api/base_views.py b/api/src/backend/api/base_views.py index 605afe332d..7cdf8fdd7f 100644 --- a/api/src/backend/api/base_views.py +++ b/api/src/backend/api/base_views.py @@ -1,13 +1,15 @@ +from django.conf import settings from django.core.exceptions import ObjectDoesNotExist from django.db import transaction from rest_framework import permissions from rest_framework.exceptions import NotAuthenticated from rest_framework.filters import SearchFilter +from rest_framework.permissions import SAFE_METHODS from rest_framework_json_api import filters from rest_framework_json_api.views import ModelViewSet -from rest_framework_simplejwt.authentication import JWTAuthentication -from api.db_router import MainRouter +from api.authentication import CombinedJWTOrAPIKeyAuthentication +from api.db_router import MainRouter, reset_read_db_alias, set_read_db_alias from api.db_utils import POSTGRES_USER_VAR, rls_transaction from api.filters import CustomDjangoFilterBackend from api.models import Role, Tenant @@ -15,7 +17,7 @@ from api.rbac.permissions import HasPermissions class BaseViewSet(ModelViewSet): - authentication_classes = [JWTAuthentication] + authentication_classes = [CombinedJWTOrAPIKeyAuthentication] required_permissions = [] permission_classes = [permissions.IsAuthenticated, HasPermissions] filter_backends = [ @@ -31,6 +33,20 @@ class BaseViewSet(ModelViewSet): ordering_fields = "__all__" ordering = ["id"] + def _get_request_db_alias(self, request): + if request is None: + return MainRouter.default_db + + read_alias = ( + MainRouter.replica_db + if request.method in SAFE_METHODS + and MainRouter.replica_db in settings.DATABASES + else None + ) + if read_alias: + return read_alias + return MainRouter.default_db + def initial(self, request, *args, **kwargs): """ Sets required_permissions before permissions are checked. @@ -48,8 +64,21 @@ class BaseViewSet(ModelViewSet): class BaseRLSViewSet(BaseViewSet): def dispatch(self, request, *args, **kwargs): - with transaction.atomic(): - return super().dispatch(request, *args, **kwargs) + self.db_alias = self._get_request_db_alias(request) + alias_token = None + try: + if self.db_alias != MainRouter.default_db: + alias_token = set_read_db_alias(self.db_alias) + + if request is not None: + request.db_alias = self.db_alias + + with transaction.atomic(using=self.db_alias): + return super().dispatch(request, *args, **kwargs) + finally: + if alias_token is not None: + reset_read_db_alias(alias_token) + self.db_alias = MainRouter.default_db def initial(self, request, *args, **kwargs): # Ideally, this logic would be in the `.setup()` method but DRF view sets don't call it @@ -61,7 +90,9 @@ class BaseRLSViewSet(BaseViewSet): if tenant_id is None: raise NotAuthenticated("Tenant ID is not present in token") - with rls_transaction(tenant_id): + with rls_transaction( + tenant_id, using=getattr(self, "db_alias", MainRouter.default_db) + ): self.request.tenant_id = tenant_id return super().initial(request, *args, **kwargs) @@ -73,18 +104,33 @@ class BaseRLSViewSet(BaseViewSet): class BaseTenantViewset(BaseViewSet): def dispatch(self, request, *args, **kwargs): - with transaction.atomic(): - tenant = super().dispatch(request, *args, **kwargs) - + self.db_alias = self._get_request_db_alias(request) + alias_token = None try: - # If the request is a POST, create the admin role - if request.method == "POST": - isinstance(tenant, dict) and self._create_admin_role(tenant.data["id"]) - except Exception as e: - self._handle_creation_error(e, tenant) - raise + if self.db_alias != MainRouter.default_db: + alias_token = set_read_db_alias(self.db_alias) - return tenant + if request is not None: + request.db_alias = self.db_alias + + with transaction.atomic(using=self.db_alias): + tenant = super().dispatch(request, *args, **kwargs) + + try: + # If the request is a POST, create the admin role + if request.method == "POST": + isinstance(tenant, dict) and self._create_admin_role( + tenant.data["id"] + ) + except Exception as e: + self._handle_creation_error(e, tenant) + raise + + return tenant + finally: + if alias_token is not None: + reset_read_db_alias(alias_token) + self.db_alias = MainRouter.default_db def _create_admin_role(self, tenant_id): Role.objects.using(MainRouter.admin_db).create( @@ -117,14 +163,31 @@ class BaseTenantViewset(BaseViewSet): raise NotAuthenticated("Tenant ID is not present in token") user_id = str(request.user.id) - with rls_transaction(value=user_id, parameter=POSTGRES_USER_VAR): + with rls_transaction( + value=user_id, + parameter=POSTGRES_USER_VAR, + using=getattr(self, "db_alias", MainRouter.default_db), + ): return super().initial(request, *args, **kwargs) class BaseUserViewset(BaseViewSet): def dispatch(self, request, *args, **kwargs): - with transaction.atomic(): - return super().dispatch(request, *args, **kwargs) + self.db_alias = self._get_request_db_alias(request) + alias_token = None + try: + if self.db_alias != MainRouter.default_db: + alias_token = set_read_db_alias(self.db_alias) + + if request is not None: + request.db_alias = self.db_alias + + with transaction.atomic(using=self.db_alias): + return super().dispatch(request, *args, **kwargs) + finally: + if alias_token is not None: + reset_read_db_alias(alias_token) + self.db_alias = MainRouter.default_db def initial(self, request, *args, **kwargs): # TODO refactor after improving RLS on users @@ -137,6 +200,8 @@ class BaseUserViewset(BaseViewSet): if tenant_id is None: raise NotAuthenticated("Tenant ID is not present in token") - with rls_transaction(tenant_id): + with rls_transaction( + tenant_id, using=getattr(self, "db_alias", MainRouter.default_db) + ): self.request.tenant_id = tenant_id return super().initial(request, *args, **kwargs) diff --git a/api/src/backend/api/compliance.py b/api/src/backend/api/compliance.py index 1773a9a820..da39fc23bb 100644 --- a/api/src/backend/api/compliance.py +++ b/api/src/backend/api/compliance.py @@ -144,18 +144,23 @@ def generate_scan_compliance( Returns: None: This function modifies the compliance_overview in place. """ + for compliance_id in PROWLER_CHECKS[provider_type][check_id]: for requirement in compliance_overview[compliance_id]["requirements"].values(): if check_id in requirement["checks"]: requirement["checks"][check_id] = status requirement["checks_status"][status.lower()] += 1 - if requirement["status"] != "FAIL" and any( - value == "FAIL" for value in requirement["checks"].values() - ): - requirement["status"] = "FAIL" - compliance_overview[compliance_id]["requirements_status"]["passed"] -= 1 - compliance_overview[compliance_id]["requirements_status"]["failed"] += 1 + if requirement["status"] != "FAIL" and any( + value == "FAIL" for value in requirement["checks"].values() + ): + requirement["status"] = "FAIL" + compliance_overview[compliance_id]["requirements_status"][ + "passed" + ] -= 1 + compliance_overview[compliance_id]["requirements_status"][ + "failed" + ] += 1 def generate_compliance_overview_template(prowler_compliance: dict): @@ -225,6 +230,7 @@ def generate_compliance_overview_template(prowler_compliance: dict): # Build compliance dictionary compliance_dict = { "framework": compliance_data.Framework, + "name": compliance_data.Name, "version": compliance_data.Version, "provider": provider_type, "description": compliance_data.Description, diff --git a/api/src/backend/api/db_router.py b/api/src/backend/api/db_router.py index dc34c1191a..2a9085746e 100644 --- a/api/src/backend/api/db_router.py +++ b/api/src/backend/api/db_router.py @@ -1,9 +1,31 @@ +from contextvars import ContextVar + +from django.conf import settings + ALLOWED_APPS = ("django", "socialaccount", "account", "authtoken", "silk") +_read_db_alias = ContextVar("read_db_alias", default=None) + + +def set_read_db_alias(alias: str | None): + if not alias: + return None + return _read_db_alias.set(alias) + + +def get_read_db_alias() -> str | None: + return _read_db_alias.get() + + +def reset_read_db_alias(token) -> None: + if token is not None: + _read_db_alias.reset(token) + class MainRouter: default_db = "default" admin_db = "admin" + replica_db = "replica" def db_for_read(self, model, **hints): # noqa: F841 model_table_name = model._meta.db_table @@ -11,6 +33,9 @@ class MainRouter: model_table_name.startswith(f"{app}_") for app in ALLOWED_APPS ): return self.admin_db + read_alias = get_read_db_alias() + if read_alias: + return read_alias return None def db_for_write(self, model, **hints): # noqa: F841 @@ -23,7 +48,13 @@ class MainRouter: return db == self.admin_db def allow_relation(self, obj1, obj2, **hints): # noqa: F841 - # Allow relations if both objects are in either "default" or "admin" db connectors - if {obj1._state.db, obj2._state.db} <= {self.default_db, self.admin_db}: + # Allow relations when both objects originate from allowed connectors + allowed_dbs = {self.default_db, self.admin_db, self.replica_db} + if {obj1._state.db, obj2._state.db} <= allowed_dbs: return True return None + + +READ_REPLICA_ALIAS = ( + MainRouter.replica_db if MainRouter.replica_db in settings.DATABASES else None +) diff --git a/api/src/backend/api/db_utils.py b/api/src/backend/api/db_utils.py index d7ec718f11..c6fcaeb43a 100644 --- a/api/src/backend/api/db_utils.py +++ b/api/src/backend/api/db_utils.py @@ -1,17 +1,36 @@ import re import secrets +import time import uuid from contextlib import contextmanager from datetime import datetime, timedelta, timezone +from celery.utils.log import get_task_logger +from config.env import env from django.conf import settings from django.contrib.auth.models import BaseUserManager -from django.db import connection, models, transaction +from django.db import ( + DEFAULT_DB_ALIAS, + OperationalError, + connection, + connections, + models, + transaction, +) from django_celery_beat.models import PeriodicTask from psycopg2 import connect as psycopg2_connect from psycopg2.extensions import AsIs, new_type, register_adapter, register_type from rest_framework_json_api.serializers import ValidationError +from api.db_router import ( + READ_REPLICA_ALIAS, + get_read_db_alias, + reset_read_db_alias, + set_read_db_alias, +) + +logger = get_task_logger(__name__) + DB_USER = settings.DATABASES["default"]["USER"] if not settings.TESTING else "test" DB_PASSWORD = ( settings.DATABASES["default"]["PASSWORD"] if not settings.TESTING else "test" @@ -26,6 +45,9 @@ TASK_RUNNER_DB_TABLE = "django_celery_results_taskresult" POSTGRES_TENANT_VAR = "api.tenant_id" POSTGRES_USER_VAR = "api.user_id" +REPLICA_MAX_ATTEMPTS = env.int("POSTGRES_REPLICA_MAX_ATTEMPTS", default=3) +REPLICA_RETRY_BASE_DELAY = env.float("POSTGRES_REPLICA_RETRY_BASE_DELAY", default=0.5) + SET_CONFIG_QUERY = "SELECT set_config(%s, %s::text, TRUE);" @@ -49,7 +71,11 @@ def psycopg_connection(database_alias: str): @contextmanager -def rls_transaction(value: str, parameter: str = POSTGRES_TENANT_VAR): +def rls_transaction( + value: str, + parameter: str = POSTGRES_TENANT_VAR, + using: str | None = None, +): """ Creates a new database transaction setting the given configuration value for Postgres RLS. It validates the if the value is a valid UUID. @@ -57,16 +83,59 @@ def rls_transaction(value: str, parameter: str = POSTGRES_TENANT_VAR): Args: value (str): Database configuration parameter value. parameter (str): Database configuration parameter name, by default is 'api.tenant_id'. + using (str | None): Optional database alias to run the transaction against. Defaults to the + active read alias (if any) or Django's default connection. """ - with transaction.atomic(): - with connection.cursor() as cursor: - try: - # just in case the value is an UUID object - uuid.UUID(str(value)) - except ValueError: - raise ValidationError("Must be a valid UUID") - cursor.execute(SET_CONFIG_QUERY, [parameter, value]) - yield cursor + requested_alias = using or get_read_db_alias() + db_alias = requested_alias or DEFAULT_DB_ALIAS + if db_alias not in connections: + db_alias = DEFAULT_DB_ALIAS + + alias = db_alias + is_replica = READ_REPLICA_ALIAS and alias == READ_REPLICA_ALIAS + max_attempts = REPLICA_MAX_ATTEMPTS if is_replica else 1 + + for attempt in range(1, max_attempts + 1): + router_token = None + + # On final attempt, fallback to primary + if attempt == max_attempts and is_replica: + logger.warning( + f"RLS transaction failed after {attempt - 1} attempts on replica, " + f"falling back to primary DB" + ) + alias = DEFAULT_DB_ALIAS + + conn = connections[alias] + try: + if alias != DEFAULT_DB_ALIAS: + router_token = set_read_db_alias(alias) + + with transaction.atomic(using=alias): + with conn.cursor() as cursor: + try: + # just in case the value is a UUID object + uuid.UUID(str(value)) + except ValueError: + raise ValidationError("Must be a valid UUID") + cursor.execute(SET_CONFIG_QUERY, [parameter, value]) + yield cursor + return + except OperationalError as e: + # If on primary or max attempts reached, raise + if not is_replica or attempt == max_attempts: + raise + + # Retry with exponential backoff + delay = REPLICA_RETRY_BASE_DELAY * (2 ** (attempt - 1)) + logger.info( + f"RLS transaction failed on replica (attempt {attempt}/{max_attempts}), " + f"retrying in {delay}s. Error: {e}" + ) + time.sleep(delay) + finally: + if router_token is not None: + reset_read_db_alias(router_token) class CustomUserManager(BaseUserManager): @@ -434,6 +503,12 @@ def drop_index_on_partitions( schema_editor.execute(sql) +def generate_api_key_prefix(): + """Generate a random 8-character prefix for API keys (e.g., 'pk_abc123de').""" + random_chars = generate_random_token(length=8) + return f"pk_{random_chars}" + + # Postgres enum definition for member role diff --git a/api/src/backend/api/exceptions.py b/api/src/backend/api/exceptions.py index b622118674..d1cf7d78ce 100644 --- a/api/src/backend/api/exceptions.py +++ b/api/src/backend/api/exceptions.py @@ -1,6 +1,10 @@ from django.core.exceptions import ValidationError as django_validation_error from rest_framework import status -from rest_framework.exceptions import APIException +from rest_framework.exceptions import ( + APIException, + AuthenticationFailed, + NotAuthenticated, +) from rest_framework_json_api.exceptions import exception_handler from rest_framework_json_api.serializers import ValidationError from rest_framework_simplejwt.exceptions import InvalidToken, TokenError @@ -68,15 +72,18 @@ def custom_exception_handler(exc, context): exc = ValidationError(exc.message_dict) else: exc = ValidationError(detail=exc.messages[0], code=exc.code) - elif isinstance(exc, (TokenError, InvalidToken)): - if ( - hasattr(exc, "detail") - and isinstance(exc.detail, dict) - and "messages" in exc.detail - ): - exc.detail["messages"] = [ - message_item["message"] for message_item in exc.detail["messages"] - ] + # Force 401 status for AuthenticationFailed exceptions regardless of the authentication backend + elif isinstance(exc, (AuthenticationFailed, NotAuthenticated, TokenError)): + exc.status_code = status.HTTP_401_UNAUTHORIZED + if isinstance(exc, (TokenError, InvalidToken)): + if ( + hasattr(exc, "detail") + and isinstance(exc.detail, dict) + and "messages" in exc.detail + ): + exc.detail["messages"] = [ + message_item["message"] for message_item in exc.detail["messages"] + ] return exception_handler(exc, context) diff --git a/api/src/backend/api/filters.py b/api/src/backend/api/filters.py index 7418d2daf9..de1397b117 100644 --- a/api/src/backend/api/filters.py +++ b/api/src/backend/api/filters.py @@ -2,7 +2,7 @@ from datetime import date, datetime, timedelta, timezone from dateutil.parser import parse from django.conf import settings -from django.db.models import Q +from django.db.models import F, Q from django_filters.rest_framework import ( BaseInFilter, BooleanFilter, @@ -27,7 +27,11 @@ from api.models import ( Finding, Integration, Invitation, + LighthouseProviderConfiguration, + LighthouseProviderModels, Membership, + MuteRule, + OverviewStatusChoices, PermissionChoices, Processor, Provider, @@ -42,6 +46,8 @@ from api.models import ( StateChoices, StatusChoices, Task, + TenantAPIKey, + ThreatScoreSnapshot, User, ) from api.rls import Tenant @@ -218,10 +224,39 @@ class MembershipFilter(FilterSet): class ProviderFilter(FilterSet): - inserted_at = DateFilter(field_name="inserted_at", lookup_expr="date") - updated_at = DateFilter(field_name="updated_at", lookup_expr="date") - connected = BooleanFilter() + inserted_at = DateFilter( + field_name="inserted_at", + lookup_expr="date", + help_text="""Filter by date when the provider was added + (format: YYYY-MM-DD)""", + ) + updated_at = DateFilter( + field_name="updated_at", + lookup_expr="date", + help_text="""Filter by date when the provider was updated + (format: YYYY-MM-DD)""", + ) + connected = BooleanFilter( + help_text="""Filter by connection status. Set to True to return only + connected providers, or False to return only providers with failed + connections. If not specified, both connected and failed providers are + included. Providers with no connection attempt (status is null) are + excluded from this filter.""" + ) provider = ChoiceFilter(choices=Provider.ProviderChoices.choices) + provider__in = ChoiceInFilter( + field_name="provider", + choices=Provider.ProviderChoices.choices, + lookup_expr="in", + ) + provider_type = ChoiceFilter( + choices=Provider.ProviderChoices.choices, field_name="provider" + ) + provider_type__in = ChoiceInFilter( + field_name="provider", + choices=Provider.ProviderChoices.choices, + lookup_expr="in", + ) class Meta: model = Provider @@ -647,8 +682,16 @@ class LatestFindingFilter(CommonFindingFilters): class ProviderSecretFilter(FilterSet): - inserted_at = DateFilter(field_name="inserted_at", lookup_expr="date") - updated_at = DateFilter(field_name="updated_at", lookup_expr="date") + inserted_at = DateFilter( + field_name="inserted_at", + lookup_expr="date", + help_text="Filter by date when the secret was added (format: YYYY-MM-DD)", + ) + updated_at = DateFilter( + field_name="updated_at", + lookup_expr="date", + help_text="Filter by date when the secret was updated (format: YYYY-MM-DD)", + ) provider = UUIDFilter(field_name="provider__id", lookup_expr="exact") class Meta: @@ -718,6 +761,14 @@ class RoleFilter(FilterSet): class ComplianceOverviewFilter(FilterSet): inserted_at = DateFilter(field_name="inserted_at", lookup_expr="date") scan_id = UUIDFilter(field_name="scan_id") + 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 + ) + provider_type__in = ChoiceInFilter( + field_name="scan__provider__provider", choices=Provider.ProviderChoices.choices + ) region = CharFilter(field_name="region") class Meta: @@ -734,6 +785,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 ) @@ -750,24 +802,70 @@ class ScanSummaryFilter(FilterSet): } -class ServiceOverviewFilter(ScanSummaryFilter): - def is_valid(self): - # Check if at least one of the inserted_at filters is present - inserted_at_filters = [ - self.data.get("inserted_at"), - self.data.get("inserted_at__gte"), - self.data.get("inserted_at__lte"), - ] - if not any(inserted_at_filters): - raise ValidationError( - { - "inserted_at": [ - "At least one of filter[inserted_at], filter[inserted_at__gte], or " - "filter[inserted_at__lte] is required." - ] - } - ) - return super().is_valid() +class ScanSummarySeverityFilter(ScanSummaryFilter): + """Filter for findings_severity ScanSummary endpoint - includes status filters""" + + # Custom status filters - only for severity grouping endpoint + status = ChoiceFilter(method="filter_status", choices=OverviewStatusChoices.choices) + status__in = CharInFilter(method="filter_status_in", lookup_expr="in") + + def filter_status(self, queryset, name, value): + # Validate the status value + if value not in [choice[0] for choice in OverviewStatusChoices.choices]: + raise ValidationError(f"Invalid status value: {value}") + + # Apply the filter by annotating the queryset with the status field + if value == OverviewStatusChoices.FAIL: + return queryset.annotate(status_count=F("fail")) + elif value == OverviewStatusChoices.PASS: + return queryset.annotate(status_count=F("_pass")) + else: + return queryset.annotate(status_count=F("total")) + + def filter_status_in(self, queryset, name, value): + # Validate the status values + valid_statuses = [choice[0] for choice in OverviewStatusChoices.choices] + for status_val in value: + if status_val not in valid_statuses: + raise ValidationError(f"Invalid status value: {status_val}") + + # If all statuses or no valid statuses, use total + if ( + set(value) + >= { + OverviewStatusChoices.FAIL, + OverviewStatusChoices.PASS, + } + or not value + ): + return queryset.annotate(status_count=F("total")) + + # Build the sum expression based on status values + sum_expression = None + for status in value: + if status == OverviewStatusChoices.FAIL: + field_expr = F("fail") + elif status == OverviewStatusChoices.PASS: + field_expr = F("_pass") + else: + continue + + if sum_expression is None: + sum_expression = field_expr + else: + sum_expression = sum_expression + field_expr + + if sum_expression is None: + return queryset.annotate(status_count=F("total")) + + return queryset.annotate(status_count=sum_expression) + + class Meta: + model = ScanSummary + fields = { + "inserted_at": ["date", "gte", "lte"], + "region": ["exact", "icontains", "in"], + } class IntegrationFilter(FilterSet): @@ -793,3 +891,132 @@ class ProcessorFilter(FilterSet): field_name="processor_type", lookup_expr="in", ) + + +class IntegrationJiraFindingsFilter(FilterSet): + # To be expanded as needed + finding_id = UUIDFilter(field_name="id", lookup_expr="exact") + finding_id__in = UUIDInFilter(field_name="id", lookup_expr="in") + + class Meta: + model = Finding + fields = {} + + def filter_queryset(self, queryset): + # Validate that there is at least one filter provided + if not self.data: + raise ValidationError( + { + "findings": "No finding filters provided. At least one filter is required." + } + ) + return super().filter_queryset(queryset) + + +class TenantApiKeyFilter(FilterSet): + inserted_at = DateFilter(field_name="created", lookup_expr="date") + inserted_at__gte = DateFilter(field_name="created", lookup_expr="gte") + inserted_at__lte = DateFilter(field_name="created", lookup_expr="lte") + expires_at = DateFilter(field_name="expiry_date", lookup_expr="date") + expires_at__gte = DateFilter(field_name="expiry_date", lookup_expr="gte") + expires_at__lte = DateFilter(field_name="expiry_date", lookup_expr="lte") + + class Meta: + model = TenantAPIKey + fields = { + "prefix": ["exact", "icontains"], + "revoked": ["exact"], + "name": ["exact", "icontains"], + } + + +class LighthouseProviderConfigFilter(FilterSet): + provider_type = ChoiceFilter( + choices=LighthouseProviderConfiguration.LLMProviderChoices.choices + ) + provider_type__in = ChoiceInFilter( + choices=LighthouseProviderConfiguration.LLMProviderChoices.choices, + field_name="provider_type", + lookup_expr="in", + ) + is_active = BooleanFilter() + + class Meta: + model = LighthouseProviderConfiguration + fields = { + "provider_type": ["exact", "in"], + "is_active": ["exact"], + } + + +class LighthouseProviderModelsFilter(FilterSet): + provider_type = ChoiceFilter( + choices=LighthouseProviderConfiguration.LLMProviderChoices.choices, + field_name="provider_configuration__provider_type", + ) + provider_type__in = ChoiceInFilter( + choices=LighthouseProviderConfiguration.LLMProviderChoices.choices, + field_name="provider_configuration__provider_type", + lookup_expr="in", + ) + + # Allow filtering by model id + model_id = CharFilter(field_name="model_id", lookup_expr="exact") + model_id__icontains = CharFilter(field_name="model_id", lookup_expr="icontains") + model_id__in = CharInFilter(field_name="model_id", lookup_expr="in") + + class Meta: + model = LighthouseProviderModels + fields = { + "model_id": ["exact", "icontains", "in"], + } + + +class MuteRuleFilter(FilterSet): + inserted_at = DateFilter(field_name="inserted_at", lookup_expr="date") + updated_at = DateFilter(field_name="updated_at", lookup_expr="date") + created_by = UUIDFilter(field_name="created_by__id", lookup_expr="exact") + + class Meta: + model = MuteRule + fields = { + "id": ["exact", "in"], + "name": ["exact", "icontains"], + "reason": ["icontains"], + "enabled": ["exact"], + "inserted_at": ["gte", "lte"], + "updated_at": ["gte", "lte"], + } + + +class ThreatScoreSnapshotFilter(FilterSet): + """ + Filter for ThreatScore snapshots. + Allows filtering by scan, provider, compliance_id, and date ranges. + """ + + inserted_at = DateFilter(field_name="inserted_at", lookup_expr="date") + scan_id = UUIDFilter(field_name="scan__id", lookup_expr="exact") + scan_id__in = UUIDInFilter(field_name="scan__id", lookup_expr="in") + provider_id = UUIDFilter(field_name="provider__id", lookup_expr="exact") + provider_id__in = UUIDInFilter(field_name="provider__id", lookup_expr="in") + provider_type = ChoiceFilter( + field_name="provider__provider", choices=Provider.ProviderChoices.choices + ) + provider_type__in = ChoiceInFilter( + field_name="provider__provider", + choices=Provider.ProviderChoices.choices, + lookup_expr="in", + ) + compliance_id = CharFilter(field_name="compliance_id", lookup_expr="exact") + compliance_id__in = CharInFilter(field_name="compliance_id", lookup_expr="in") + + class Meta: + model = ThreatScoreSnapshot + fields = { + "scan": ["exact", "in"], + "provider": ["exact", "in"], + "compliance_id": ["exact", "in"], + "inserted_at": ["date", "gte", "lte"], + "overall_score": ["exact", "gte", "lte"], + } diff --git a/api/src/backend/api/fixtures/dev/7_dev_compliance.json b/api/src/backend/api/fixtures/dev/7_dev_compliance.json index 90a4bcd6be..b90ead642b 100644 --- a/api/src/backend/api/fixtures/dev/7_dev_compliance.json +++ b/api/src/backend/api/fixtures/dev/7_dev_compliance.json @@ -1 +1 @@ -[{"model": "api.complianceoverview","pk": "07d0c342-abcb-4d91-b865-88f9c96adbfc","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "cisa_aws","framework": "CISA","version": "","description": "Cybersecurity & Infrastructure Security Agency's (CISA) Cyber Essentials is a guide for leaders of small businesses as well as leaders of small and local government agencies to develop an actionable understanding of where to start implementing organizational cybersecurity practices.","region": "eu-west-1","requirements": {"your-data-1": {"name": "Your Data-1","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"sagemaker_training_jobs_volume_and_output_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-data-1","Section": "your data","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Learn how your data is protected.","checks_status": {"fail": 4,"pass": 3,"total": 13,"manual": 0}},"your-data-2": {"name": "Your Data-2","checks": {"elb_ssl_listeners": "FAIL","elb_logging_enabled": "FAIL","elbv2_ssl_listeners": "FAIL","vpc_flow_logs_enabled": "FAIL","ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","efs_have_backup_enabled": "FAIL","s3_bucket_public_access": null,"s3_bucket_acl_prohibited": "FAIL","ec2_ebs_volume_encryption": "PASS","rds_snapshots_public_access": "PASS","s3_bucket_default_encryption": "PASS","rds_instance_no_public_access": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"redshift_cluster_public_access": null,"cloudtrail_multi_region_enabled": "PASS","acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_logging_enabled": "PASS","s3_bucket_policy_public_write_access": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","awslambda_function_not_publicly_accessible": "PASS","dynamodb_tables_kms_cmk_encryption_enabled": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_cloudwatch_logging_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_training_jobs_volume_and_output_encryption_enabled": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-data-2","Section": "your data","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Learn what is happening on your network, manage network and perimeter components, host and device components, data-at-rest and in-transit, and user behavior activities.","checks_status": {"fail": 18,"pass": 11,"total": 49,"manual": 0}},"your-data-3": {"name": "Your Data-3","checks": {"elbv2_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-data-3","Section": "your data","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Domain name system protection.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"your-data-4": {"name": "Your Data-4","checks": {"efs_have_backup_enabled": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL","redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-data-4","Section": "your data","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establish regular automated backups and redundancies of key systems.","checks_status": {"fail": 4,"pass": 1,"total": 8,"manual": 0}},"your-data-5": {"name": "Your Data-5","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "your-data-5","Section": "your data","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Leverage protections for backups, including physical security, encryption and offline copies.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"your-systems-1": {"name": "Your Systems-1","checks": {"ec2_elastic_ip_unassigned": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-systems-1","Section": "your systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Learn what is on your network. Maintain inventories of hardware and software assets to know what is in play and at-risk from attack.","checks_status": {"fail": 4,"pass": 0,"total": 4,"manual": 0}},"your-systems-2": {"name": "Your Systems-2","checks": {"ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-systems-2","Section": "your systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Leverage automatic updates for all operating systems and third-party software.","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"your-systems-3": {"name": "Your Systems-3","checks": {"elb_ssl_listeners": "FAIL","elb_logging_enabled": "FAIL","elbv2_ssl_listeners": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_root_mfa_enabled": null,"rds_instance_multi_az": "FAIL","ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","efs_have_backup_enabled": "FAIL","s3_bucket_public_access": null,"kms_cmk_rotation_enabled": null,"ec2_ebs_volume_encryption": "PASS","elbv2_deletion_protection": "FAIL","iam_user_accesskey_unused": null,"ec2_ebs_default_encryption": "PASS","iam_password_policy_number": null,"iam_password_policy_symbol": null,"rds_instance_backup_enabled": "PASS","rds_snapshots_public_access": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"s3_bucket_default_encryption": "PASS","iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"rds_instance_no_public_access": "PASS","efs_encryption_at_rest_enabled": "FAIL","iam_user_console_access_unused": null,"rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"redshift_cluster_public_access": null,"cloudtrail_multi_region_enabled": "PASS","rds_instance_deletion_protection": "FAIL","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_logging_enabled": "PASS","apigateway_restapi_waf_acl_attached": "FAIL","iam_user_mfa_enabled_console_access": null,"redshift_cluster_automated_snapshot": null,"s3_bucket_policy_public_write_access": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"emr_cluster_master_nodes_no_public_ip": null,"iam_password_policy_minimum_length_14": null,"s3_account_level_public_access_blocks": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","secretsmanager_automatic_rotation_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","vpc_endpoint_connections_trust_boundaries": "FAIL","awslambda_function_not_publicly_accessible": "PASS","dynamodb_tables_kms_cmk_encryption_enabled": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL","codebuild_project_user_controlled_buildspec": "PASS","apigateway_restapi_client_certificate_enabled": "FAIL","iam_inline_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_aws_attached_policy_no_administrative_privileges": null,"opensearch_service_domains_cloudwatch_logging_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"iam_customer_attached_policy_no_administrative_privileges": null,"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_training_jobs_volume_and_output_encryption_enabled": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-systems-3","Section": "your systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement security configurations for all hardware and software assets.","checks_status": {"fail": 25,"pass": 16,"total": 84,"manual": 0}},"your-surroundings-1": {"name": "Your Surroundings-1","checks": {"vpc_flow_logs_enabled": "FAIL","ec2_elastic_ip_unassigned": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-surroundings-1","Section": "your surroundings","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Learn who is on your network. Maintain inventories of network connections (user accounts, vendors, business partners, etc.).","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"your-surroundings-2": {"name": "Your Surroundings-2","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "your-surroundings-2","Section": "your surroundings","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Leverage multi-factor authentication for all users, starting with privileged, administrative and remote access users.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"your-surroundings-3": {"name": "Your Surroundings-3","checks": {"elbv2_ssl_listeners": "FAIL","iam_no_root_access_key": null,"iam_inline_policy_no_administrative_privileges": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-surroundings-3","Section": "your surroundings","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Grant access and admin permissions based on need-to-know and least privilege.","checks_status": {"fail": 1,"pass": 0,"total": 6,"manual": 0}},"your-surroundings-4": {"name": "Your Surroundings-4","checks": {"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "your-surroundings-4","Section": "your surroundings","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Leverage unique passwords for all user accounts.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"your-crisis-response-2": {"name": "Your Crisis Response-2","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "your-crisis-response-2","Section": "your crisis response","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Lead development of an internal reporting structure to detect, communicate and contain attacks.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"booting-up-thing-to-do-first-1": {"name": "YBooting Up: Things to Do First-1","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "booting-up-thing-to-do-first-1","Section": "booting up thing to do first","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Lead development of an internal reporting structure to detect, communicate and contain attacks.","checks_status": {"fail": 2,"pass": 1,"total": 7,"manual": 0}},"booting-up-thing-to-do-first-2": {"name": "YBooting Up: Things to Do First-2","checks": {"iam_root_mfa_enabled": null,"iam_user_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "booting-up-thing-to-do-first-2","Section": "booting up thing to do first","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Require multi-factor authentication (MFA) for accessing your systems whenever possible. MFA should be required of all users, but start with privileged, administrative, and remote access users.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"booting-up-thing-to-do-first-3": {"name": "YBooting Up: Things to Do First-3","checks": {"ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "booting-up-thing-to-do-first-1","Section": "booting up thing to do first","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Enable automatic updates whenever possible. Replace unsupported operating systems, applications and hardware. Test and deploy patches quickly.","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}}},"requirements_passed": 4,"requirements_failed": 11,"requirements_manual": 1,"total_requirements": 16,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "089cf697-547a-4a34-a811-e7a19b78b9fd","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "aws_foundational_technical_review_aws","framework": "AWS-Foundational-Technical-Review","version": "","description": "The AWS Foundational Technical Review (FTR) assesses an AWS Partner's solution against a specific set of Amazon Web Services (AWS) best practices around security, performance, and operational processes that are most critical for customer success. Passing the FTR is required to qualify AWS Software Partners for AWS Partner Network (APN) programs such as AWS Competency and AWS Service Ready but any AWS Partner who offers a technology solution may request a FTR review through AWS Partner Central.","region": "eu-west-1","requirements": {"S3-001": {"name": "Review all Amazon S3 buckets to determine appropriate access levels","checks": {"s3_bucket_object_lock": "FAIL","s3_bucket_public_access": null,"s3_bucket_acl_prohibited": "FAIL","s3_bucket_kms_encryption": "FAIL","s3_bucket_public_list_acl": null,"s3_bucket_public_write_acl": null,"s3_bucket_default_encryption": "PASS","s3_bucket_secure_transport_policy": "FAIL","s3_bucket_level_public_access_block": "PASS","s3_bucket_policy_public_write_access": "PASS","s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "You must ensure that buckets that require public access have been reviewed to determine if public read or write access is needed and if appropriate controls are in place to control public access. When assigning access permissions, follow the principle of least privilege, an AWS best practice. For more information, refer to overview of managing access.","checks_status": {"fail": 5,"pass": 3,"total": 11,"manual": 0}},"ARC-001": {"name": "Use root user only by exception","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "The root user has unlimited access to your account and its resources, and using it only by exception helps protect your AWS resources. The AWS root user must not be used for everyday tasks, even administrative ones. Instead, adhere to the best practice of using the root user only to create your first AWS Identity and Access Management (IAM) user. Then securely lock away the root user credentials and use them to perform only a few accounts and service management tasks. To view the tasks that require you to sign in as the root user, see AWS Tasks That Require Root User. FTR does not require you to actively monitor root usage.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ARC-003": {"name": "Enable multi-factor authentication (MFA) on the root user for all AWS accounts","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Enabling MFA provides an additional layer of protection against unauthorized access to your account. To configure MFA for the root user, follow the instructions for enabling either a virtual MFA or hardware MFA device. If you are using AWS Organizations to create new accounts, the initial password for the root user is set to a random value that is never exposed to you. If you do not recover the password for the root user of these accounts, you do not need to enable MFA on them. For any accounts where you do have access to the root user’s password, you must enable MFA","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"ARC-004": {"name": "Remove access keys for the root user","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Programmatic access to AWS APIs should never use the root user. It is best not to generate static an access key for the root user. If one already exists, you should transition any processes using that key to use temporary access keys from an AWS Identity and Access Management (IAM) role, or, if necessary, static access keys from an IAM user.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ARC-005": {"name": "Develop incident management plans","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "An incident management plan is critical to respond, mitigate, and recover from the potential impact of security incidents. An incident management plan is a structured process for identifying, remediating, and responding in a timely matter to security incidents. An effective incident management plan must be continually iterated upon, remaining current with your cloud operations goal. For more information on developing incident management plan please see Develop incident management plans.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"BAR-001": {"name": "Configure automatic data backups","checks": {"backup_plans_exist": "PASS","backup_vaults_exist": null,"backup_vaults_encrypted": "PASS","efs_have_backup_enabled": "FAIL","backup_reportplans_exist": null,"rds_instance_backup_enabled": "PASS"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "You must perform regular backups to a durable storage service. Backups ensure that you have the ability to recover from administrative, logical, or physical error scenarios. Configure backups to be taken automatically based on a periodic schedule, or by changes in the dataset. RDS instances, EBS volumes, DynamoDB tables, and S3 objects can all be configured for automatic backup. AWS Backup, AWS Marketplace solutions or third-party solutions can also be used. If objects in S3 bucket are write-once-read-many (WORM), compensating controls such as object lock can be used meet this requirement. If it is customers’ responsibility to backup their data, it must be clearly stated in the documentation and the Partner must provide clear instructions on how to backup the data.","checks_status": {"fail": 1,"pass": 3,"total": 6,"manual": 0}},"BAR-002": {"name": "Periodically recover data to verify the integrity of your backup process","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "To confirm that your backup process meets your recovery time objectives (RTO) and recovery point objectives (RPO), run a recovery test on a regular schedule and after making significant changes to your cloud environment. For more information, refer to Getting Started - Backup and Restore with AWS.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"CAA-001": {"name": "Use cross-account roles to access customer AWS accounts","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Cross-account roles reduce the amount of sensitive information AWS Partners need to store for their customers.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"CAA-002": {"name": "Use an external ID with cross-account roles to access customer accounts","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "An external ID allows the user that is assuming the role to assert the circumstances in which they are operating. It also provides a way for the account owner to permit the role to be assumed only under specific circumstances. The primary function of the external ID is to address and prevent the confused deputy problem.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"CAA-003": {"name": "Deprecate any historical use of customer-provided IAM credentials","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "If your application provides legacy support for the use of static IAM credentials for cross-account access, the application's user interface and customer documentation must make it clear that this method is deprecated. Existing customers should be encouraged to switch to cross-account role based-access, and collection of credentials should be disabled for new customers.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"CAA-004": {"name": "Use a value you generate (not something provided by the customer) for the external ID","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "When configuring cross-account access using IAM roles, you must use a value you generate for the external ID, instead of one provided by the customer, to ensure the integrity of the cross-account role configuration. A partner-generated external ID ensures that malicious parties cannot impersonate a customer's configuration and enforces uniqueness and format consistency across all customers. If you are not generating an external ID today we recommend implementing a process that generates a random unique value (such as a Universally Unique Identifier) for the external ID that a customer uses to set up a cross-account role.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"CAA-005": {"name": "Ensure that all external IDs are unique.","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "The external IDs used must be unique across all customers. Re-using external IDs for different customers does not solve the confused deputy problem and runs the risk of customer A being able to view data of customer B by using the role ARN and the external ID of customer B. To resolve this, we recommend implementing a process that ensures a random unique value, such as a Universally Unique Identifier, is generated for the external ID that a customer would use to setup a cross account role.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"CAA-006": {"name": "Provide read-only access to external ID to customers","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Customers must not be able to set or influence external IDs. When the external ID is editable, it is possible for one customer to impersonate the configuration of another. For example, when the external ID is editable, customer A can create a cross account role setup using customer B’s role ARN and external ID, granting customer A access to customer B’s data. Remediation of this item involves making the external ID a view-only field, ensuring that the external ID cannot be changed to impersonate the setup of another customer.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"CAA-007": {"name": "Provide guidance or an automated setup mechanism (for example, an AWS CloudFormation template) for creating cross-account roles with the minimum required privileges","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "The policy created for cross-account access in customer accounts must follow the principle of least privilege. The AWS Partner must provide a role-policy document or an automated setup mechanism (for example, an AWS CloudFormation template) for the customers to use to ensure that the roles are created with minimum required privileges. For more information, refer to the AWS Partner Network (APN) blog posts.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"IAM-001": {"name": "Enable multi-factor authentication (MFA) for all Human Identities with AWS access","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_hardware_mfa_enabled": null,"iam_administrator_access_with_mfa": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "You must require any human identities to authenticate using MFA before accessing your AWS accounts. Typically, this means enabling MFA within your corporate identity provider. If you have existing legacy IAM users you must enable MFA for console access for those principals as well. Enabling MFA for IAM users provides an additional layer of security. With MFA, users have a device that generates a unique authentication code (a one-time password, or OTP). Users must provide both their normal credentials (user name and password) and the OTP. The MFA device can either be a special piece of hardware, or it can be a virtual device (for example, it can run in an app on a smartphone). Please note that machine identities do not require MFA.","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"IAM-002": {"name": "Monitor and secure static AWS Identity and Access Management (IAM) credentials","checks": {"guardduty_is_enabled": "PASS","iam_user_accesskey_unused": null,"iam_rotate_access_key_90_days": null,"guardduty_no_high_severity_findings": "FAIL","iam_user_with_temporary_credentials": null},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Use temporary IAM credentials retrieved by assuming a role whenever possible. In cases where it is infeasible to use IAM roles, implement the following controls to reduce the risk these credentials are misused: Rotate IAM access keys regularly (recommended at least every 90 days). Maintain an inventory of all static keys and where they are used and remove unused access keys. Implement monitoring of AWS CloudTrail logs to detect anomalous activity or other potential misuse (e.g. using AWS GuardDuty.) Define a runbook or SOP for revoking credentials in the event you detect misuse.","checks_status": {"fail": 1,"pass": 1,"total": 5,"manual": 0}},"IAM-003": {"name": "Use strong password policy","checks": {"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_password_policy_minimum_length_14": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Enforce a strong password policy, and educate users to avoid common or re-used passwords. For IAM users, you can create a password policy for your account on the Account Settings page of the IAM console. You can use the password policy to define password requirements, such as minimum length and whether it requires non-alphabetic characters, and so on. For more information, see Setting an Account Password Policy for IAM users.","checks_status": {"fail": 0,"pass": 0,"total": 7,"manual": 0}},"IAM-004": {"name": "Create individual identities (no shared credentials) for anyone who needs AWS access","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Create individual entities and give unique security credentials and permissions to each user accessing your account. With individual entities and no shared credentials, you can audit the activity of each user.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"IAM-005": {"name": "Use IAM roles and its temporary security credentials to provide access to third parties.","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Do not provision IAM users and share those credentials with people outside of your organization. Any external services that need to make AWS API calls against your account (for example, a monitoring solution that accesses your account's AWS CloudWatch metrics) must use a cross-account role. For more information, refer to Providing access to AWS accounts owned by third parties.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"IAM-006": {"name": "Grant least privilege access","checks": {"iam_policy_attached_only_to_group_or_roles": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "You must follow the standard security advice of granting least privilege. Grant only the access that identities require by allowing access to specific actions on specific AWS resources under specific conditions. Rely on groups and identity attributes to dynamically set permissions at scale, rather than defining permissions for individual users. For example, you can allow a group of developers access to manage only resources for their project. This way, when a developer is removed from the group, access for the developer is revoked everywhere that group was used for access control, without requiring any changes to the access policies.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"IAM-007": {"name": "Manage access based on life cycle","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Integrate access controls with operator and application lifecycle and your centralized federation provider and IAM. For example, remove a user’s access when they leave the organization or change roles.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"IAM-008": {"name": "Audit identities quarterly","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Auditing the identities that are configured in your identity provider and IAM helps ensure that only authorized identities have access to your workload. For example, remove people that leave the organization, and remove cross-account roles that are no longer required. Have a process in place to periodically audit permissions to the services accessed by an IAM entity. This helps you identify the policies you needto modify to remove any unused permissions. For more information, see Refining permissions in AWS using last accessed information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"IAM-009": {"name": "Do not embed credentials in application code","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Ensure that all credentials used by your applications (for example, IAM access keys and database passwords) are never included in your application's source code or committed to source control in any way.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"RES-001": {"name": "Define a Recovery Point Objective (RPO)","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "To confirm that your backup process meets your recovery time objectives (RTO) and recovery point objectives (RPO), run a recovery test on a regular schedule and after making significant changes to your cloud environment. For more information, refer to Getting Started - Backup and Restore with AWS.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"RES-002": {"name": "Establish a Recovery Time Objective (RTO)","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Define an RTO that meets your organization’s needs and expectations. RTO is the maximum acceptable delay your organization will accept between the interruption and restoration of service.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"RES-004": {"name": "Resiliency Testing","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Test resiliency to ensure that RTO and RPO are met, both periodically (minimum every 12 months) and after major updates. The resiliency test must include accidental data loss, instance failures, and Availability Zone (AZ) failures. At least one resilience test that meets RTO and RPO requirements must be completed prior to FTR approval. You can use AWS Resilience Hub to test and verify your workloads to see if it meets its resilience target. AWS Resilience Hub works with AWS Fault Injection Service (AWS FIS) , a chaos engineering service, to provide fault-injection simulations of real-world failures to validate the application recovers within the resilience targets you defined. AWS Resilience Hub also provides API operations for you to integrate its resilience assessment and testing into your CI/CD pipelines for ongoing resilience validation. Including resilience validation in CI/CD pipelines helps make sure that changes to the workload’s underlying infrastructure don't compromise resilience.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"RES-005": {"name": "Communicate customer responsibilities for resilience","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Clearly define your customers’ responsibility for backup, recovery, and availability. At a minimum, your product documentation or customer agreements should cover the following: Responsibility the customer has for backing up the data stored in your solution. Instructions for backing up data or configuring optional features in your product for data protection, if applicable. Options customers have for configuring the availability of your product.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"RES-006": {"name": "Architect your product to meet availability targets and uptime service level agreements (SLAs)","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "If you publish or privately agree to availability targets or uptime SLAs, ensure that your architecture and operational processes are designed to support them. Additionally, provide clear guidance to customers on any configuration required to achieve the targets or SLAs.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"RES-007": {"name": "Define a customer communication plan for outages","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Establish a plan for communicating information about system outages to your customers both during and after incidents. Your communication should not include any data that was provided by AWS under a non-disclosure agreement (NDA).","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SUP-001": {"name": "Subscribe to the AWS Business Support tier (or higher) for all production AWS accounts or have an action plan to handle issues which require help from AWS Support","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Partner-hosted FTR requirements","Service": null,"SubGroup": null,"SubSection": null}],"description": "It is recommended that you subscribe to the AWS Business Support tier or higher (including AWS Partner-Led Support) for all of your AWS production accounts. For more information, refer to Compare AWS Support Plans. If you don't have premium support, you must have an action plan to handle issues which require help from AWS Support. AWS Support provides a mix of tools and technology, people, and programs designed to proactively help you optimize performance, lower costs, and innovate faster. AWS Business Support provides additional benefits including access to AWS Trusted Advisor and AWS Personal Health Dashboard and faster response times.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ACOM-001": {"name": "Configure AWS account contacts","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "If an account is not managed by AWS Organizations, alternate account contacts help AWS get in contact with the appropriate personnel if needed. Configure the account’s alternate contacts to point to a group rather than an individual. For example, create separate email distribution lists for billing, operations, and security and configure these as Billing, Security, and Operations contacts in each active AWS account. This ensures that multiple people will receive AWS notifications and be able to respond, even if someone is on vacation, changes roles, or leaves the company.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ACOM-002": {"name": "Set account contact information including the root user email address to email addresses and phone numbers owned by your company","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Using company owned email addresses and phone numbers for contact information enables you to access them even if the individuals whom they belong to are no longer with your organization","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"HOST-001": {"name": "Confirm your hosting model","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Partner-hosted FTR requirements","Service": null,"SubGroup": null,"SubSection": null}],"description": "To use this FTR checklist you must host all critical application components on AWS. You may use external providers for edge services such as content delivery networks (CDNs) or domain name system (DNS), or corporate identity providers. If you are using any edge services outside AWS, please specify them in the self-assessment.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"IAM-0010": {"name": "Store secrets securely.","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Encrypt all secrets in transit and at rest, define fine-grained access controls that only allow access to specific identities, and log access to secrets in an audit log. We recommend you use a purpose-built secret management service such as AWS Secrets Manager, AWS Systems Manager Parameter Store, or an AWS Partner solution, but internally developed solutions that meet these requirements are also acceptable.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"IAM-0011": {"name": "Encrypt all end user/customer credentials and hash passwords at rest.","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "If you are storing end user/customer credentials in a database that you manage, encrypt credentials at rest and hash passwords. As an alternative, AWS recommends using a user-identity synchronization service, such as Amazon Cognito or an equivalent AWS Partner solution.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"IAM-0012": {"name": "Use temporary credentials","checks": {"iam_root_mfa_enabled": null,"iam_user_accesskey_unused": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_hardware_mfa_enabled": null,"iam_administrator_access_with_mfa": null,"iam_role_administratoraccess_policy": null,"iam_user_mfa_enabled_console_access": null,"iam_user_with_temporary_credentials": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_role_cross_account_readonlyaccess_policy": null,"iam_role_cross_service_confused_deputy_prevention": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Use temporary security credentials to access AWS resources. For machine identities within AWS (for example, Amazon Elastic Compute Cloud (Amazon EC2) instances or AWS Lambda functions), always use IAM roles to acquire temporary security credentials. For machine identities running outside of AWS, use IAM Roles Anywhere or securely store static AWS access keys that are only used to assume an IAM role.For human identities, use AWS IAM Identity Center or other identity federation solutions where possible. If you must use static AWS access keys for human users, require MFA for all access, including the AWS Management Console, and AWS Command Line Interface (AWS CLI).","checks_status": {"fail": 0,"pass": 0,"total": 13,"manual": 0}},"RCVP-001": {"name": "Establish a process to ensure that all required compliance standards are met","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "If you advertise that your product meets specific compliance standards, you must have an internal process for ensuring compliance. Examples of compliance standards include Payment Card Industry Data Security Standard (PCI DSS) PCI DSS, Federal Risk and Authorization Management Program (FedRAMP)FedRAMP, and U.S. Health Insurance Portability and Accountability Act (HIPAA)HIPAA. Applicable compliance standards are determined by various factors, such as what types of data the solution stores or transmits and which geographic regions the solution supports.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SDAT-001": {"name": "Identify sensitive data (for example, Personally Identifiable Information (PII) and Protected Health Information (PHI))","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Data classification enables you to determine which data needs to be protected and how. Based on the workload and the data it processes, identify the data that is not common public knowledge.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SDAT-002": {"name": "Encrypt all sensitive data at rest","checks": {"athena_workgroup_encryption": null,"efs_encryption_at_rest_enabled": "FAIL","cloudtrail_kms_encryption_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Encryption maintains the confidentiality of sensitive data even when it gets stolen or the network through which it is transmitted becomes compromised.","checks_status": {"fail": 3,"pass": 0,"total": 7,"manual": 0}},"SDAT-003": {"name": "Only use protocols with encryption when transmitting sensitive data outside of your VPC","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Encryption maintains data confidentiality even when the network through which it is transmitted becomes compromised.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"WAFR-001": {"name": "Conduct periodic architecture reviews (minimum once every year)","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Partner-hosted FTR requirements","Service": null,"SubGroup": null,"SubSection": null}],"description": "Conduct periodic architecture reviews of your production workload (at least once per year) using a documented architectural standard that includes AWS-specific best practices. If you have an internally defined standard for your AWS workloads, we recommend you use it for these reviews. If you do not have an internal standard, we recommend you use the AWS Well-Architected Framework.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"WAFR-002": {"name": "Review the AWS Shared Responsibility Models for Security and Resiliency","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Partner-hosted FTR requirements","Service": null,"SubGroup": null,"SubSection": null}],"description": "Review the AWS Shared Responsibility Model for Security and the AWS Shared Responsibility Model for Resiliency. Ensure that your product’s architecture and operational processes address the customer responsibilities defined in these models. We recommend you to use AWS Resilience Hub to ensure your workload resiliency posture meets your targets and to provide you with operational procedures you may use to address the customer responsibilities.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"NETSEC-001": {"name": "Implement the least permissive rules for all Amazon EC2 security groups","checks": {"ec2_ami_public": null,"ec2_instance_public_ip": "FAIL","ec2_securitygroup_not_used": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "All Amazon EC2 security groups should restrict access to the greatest degree possible. At a minimum, do the following: Ensure that no security groups allow ingress from 0.0.0.0/0 to port 22 or 3389 (CIS 5.2) Ensure that the default security group of every VPC restricts all traffic (CIS 5.3/Security Control EC2.2)","checks_status": {"fail": 3,"pass": 16,"total": 20,"manual": 0}},"NETSEC-002": {"name": "Restrict resources in public subnets","checks": {"vpc_subnet_no_public_ip_by_default": "FAIL","vpc_subnet_separate_private_public": "FAIL","vpc_endpoint_connections_trust_boundaries": "FAIL","workspaces_vpc_2private_1public_subnets_nat": null,"vpc_endpoint_services_allowed_principals_trust_boundaries": null},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Do not place resources in public subnets of your VPC unless they must receive network traffic from public sources. Public subnets are subnets associated with a route table that has a route to an internet gateway.","checks_status": {"fail": 3,"pass": 0,"total": 5,"manual": 0}},"SECOPS-001": {"name": "Perform vulnerability management","checks": {"inspector2_is_enabled": "FAIL","inspector2_active_findings_exist": "FAIL","guardduty_no_high_severity_findings": "FAIL","accessanalyzer_enabled_without_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Define a mechanism and frequency to scan and patch for vulnerabilities in your dependencies, and in your operating systems to help protect against new threats. Scan and patch your dependencies, and your operating systems on a defined schedule. Software vulnerability management is essential to keeping your system secure from threat actors. Embedding vulnerability assessments early into your continuous integration/continuous delivery (CI/CD) pipeline allows you to prioritize remediation of any security vulnerabilities detected. The solution you need to achieve this varies according to the AWS services that you are consuming. To check for vulnerabilities in software running in Amazon EC2 instances, you can add Amazon Inspector to your pipeline to cause your build to fail if Inspector detects vulnerabilities. You can also use open source products such as OWASP Dependency-Check, Snyk, OpenVAS, package managers and AWS Partner tools for vulnerability management.","checks_status": {"fail": 4,"pass": 0,"total": 4,"manual": 0}}},"requirements_passed": 6,"requirements_failed": 7,"requirements_manual": 32,"total_requirements": 45,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "1491ce35-3d2b-4cf6-a56d-b18b391d5623","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "nist_800_171_revision_2_aws","framework": "NIST-800-171-Revision-2","version": "","description": "The cybersecurity controls within NIST 800-171 safeguard CUI in the IT networks of government contractors and subcontractors. It defines the practices and procedures that government contractors must adhere to when their networks process or store CUI. NIST 800-171 only applies to those parts of a contractor’s network where CUI is present.","region": "eu-west-1","requirements": {"3_1_1": {"name": "3.1.1 Limit system access to authorized users, processes acting on behalf of authorized users, and devices (including other systems)","checks": {"iam_root_mfa_enabled": null,"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"ec2_instance_profile_attached": "PASS","iam_root_hardware_mfa_enabled": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"eks_cluster_not_publicly_accessible": null,"iam_user_mfa_enabled_console_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_1_1","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Access control policies (e.g., identity or role-based policies, control matrices, and cryptography) control access between active entities or subjects (i.e., users or processes acting on behalf of users) and passive entities or objects (e.g., devices, files, records, and domains) in systems. Access enforcement mechanisms can be employed at the application and service level to provide increased information security. Other systems include systems internal and external to the organization. This requirement focuses on account management for systems and applications. The definition of and enforcement of access authorizations, other than those determined by account type (e.g., privileged verses non-privileged) are addressed in requirement 3.1.2.","checks_status": {"fail": 3,"pass": 7,"total": 28,"manual": 0}},"3_1_2": {"name": "3.1.2 Limit system access to the types of transactions and functions that authorized users are permitted to execute","checks": {"iam_root_mfa_enabled": null,"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"ec2_instance_profile_attached": "PASS","iam_root_hardware_mfa_enabled": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"eks_cluster_not_publicly_accessible": null,"iam_user_mfa_enabled_console_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_1_2","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Organizations may choose to define access privileges or other attributes by account, by type of account, or a combination of both. System account types include individual, shared, group, system, anonymous, guest, emergency, developer, manufacturer, vendor, and temporary. Other attributes required for authorizing access include restrictions on time-of-day, day-of-week, and point-oforigin. In defining other account attributes, organizations consider system-related requirements (e.g., system upgrades scheduled maintenance,) and mission or business requirements, (e.g., time zone differences, customer requirements, remote access to support travel requirements).","checks_status": {"fail": 3,"pass": 7,"total": 28,"manual": 0}},"3_1_3": {"name": "3.1.3 Control the flow of CUI in accordance with approved authorizations","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"eks_cluster_not_publicly_accessible": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_1_3","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Information flow control regulates where information can travel within a system and between systems (versus who can access the information) and without explicit regard to subsequent accesses to that information. Flow control restrictions include the following: keeping exportcontrolled information from being transmitted in the clear to the Internet; blocking outside traffic that claims to be from within the organization; restricting requests to the Internet that are not from the internal web proxy server; and limiting information transfers between organizations based on data structures and content. Organizations commonly use information flow control policies and enforcement mechanisms to control the flow of information between designated sources and destinations (e.g., networks, individuals, and devices) within systems and between interconnected systems. Flow control is based on characteristics of the information or the information path. Enforcement occurs in boundary protection devices (e.g., gateways, routers, guards, encrypted tunnels, firewalls) that employ rule sets or establish configuration settings that restrict system services, provide a packetfiltering capability based on header information, or message-filtering capability based on message content (e.g., implementing key word searches or using document characteristics). Organizations also consider the trustworthiness of filtering and inspection mechanisms (i.e., hardware, firmware, and software components) that are critical to information flow enforcement. Transferring information between systems representing different security domains with different security policies introduces risk that such transfers violate one or more domain security policies. In such situations, information owners or stewards provide guidance at designated policy enforcement points between interconnected systems. Organizations consider mandating specific architectural solutions when required to enforce specific security policies. Enforcement includes: prohibiting information transfers between interconnected systems (i.e., allowing access only); employing hardware mechanisms to enforce one-way information flows; and implementing trustworthy regrading mechanisms to reassign security attributes and security labels.","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"3_1_4": {"name": "3.1.4 Separate the duties of individuals to reduce the risk of malevolent activity without collusion","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_1_4","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Separation of duties addresses the potential for abuse of authorized privileges and helps to reduce the risk of malevolent activity without collusion. Separation of duties includes dividing mission functions and system support functions among different individuals or roles; conducting system support functions with different individuals (e.g., configuration management, quality assurance and testing, system management, programming, and network security); and ensuring that security personnel administering access control functions do not also administer audit functions. Because separation of duty violations can span systems and application domains, organizations consider the entirety of organizational systems and system components when developing policy on separation of duties.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"3_1_5": {"name": "3.1.5 Employ the principle of least privilege, including for specific security functions and privileged accounts","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_1_5","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Organizations employ the principle of least privilege for specific duties and authorized accesses for users and processes. The principle of least privilege is applied with the goal of authorized privileges no higher than necessary to accomplish required organizational missions or business functions. Organizations consider the creation of additional processes, roles, and system accounts as necessary, to achieve least privilege. Organizations also apply least privilege to the development, implementation, and operation of organizational systems. Security functions include establishing system accounts, setting events to be logged, setting intrusion detection parameters, and configuring access authorizations (i.e., permissions, privileges). Privileged accounts, including super user accounts, are typically described as system administrator for various types of commercial off-the-shelf operating systems. Restricting privileged accounts to specific personnel or roles prevents day-to-day users from having access to privileged information or functions. Organizations may differentiate in the application of this requirement between allowed privileges for local accounts and for domain accounts provided organizations retain the ability to control system configurations for key security parameters and as otherwise necessary to sufficiently mitigate risk.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"3_1_6": {"name": "3.1.6 Use non-privileged accounts or roles when accessing nonsecurity functions","checks": {"iam_no_root_access_key": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_1_6","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "This requirement limits exposure when operating from within privileged accounts or roles. The inclusion of roles addresses situations where organizations implement access control policies such as role-based access control and where a change of role provides the same degree of assurance in the change of access authorizations for the user and all processes acting on behalf of the user as would be provided by a change between a privileged and non-privileged account.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"3_1_7": {"name": "3.1.7 Prevent non-privileged users from executing privileged functions and capture the execution of such functions in audit logs","checks": {"iam_no_root_access_key": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_1_7","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Privileged functions include establishing system accounts, performing system integrity checks, conducting patching operations, or administering cryptographic key management activities. Nonprivileged users are individuals that do not possess appropriate authorizations. Circumventing intrusion detection and prevention mechanisms or malicious code protection mechanisms are examples of privileged functions that require protection from non-privileged users. Note that this requirement represents a condition to be achieved by the definition of authorized privileges in 3.1.2. Misuse of privileged functions, either intentionally or unintentionally by authorized users, or by unauthorized external entities that have compromised system accounts, is a serious and ongoing concern and can have significant adverse impacts on organizations. Logging the use of privileged functions is one way to detect such misuse, and in doing so, help mitigate the risk from insider threats and the advanced persistent threat.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"3_3_1": {"name": "3.3.1 Create and retain system audit logs and records to the extent needed to enable the monitoring, analysis, investigation, and reporting of unlawful or unauthorized system activity","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_3_1","Section": "3.3 Audit and Accountability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "An event is any observable occurrence in a system, which includes unlawful or unauthorized system activity. Organizations identify event types for which a logging functionality is needed as those events which are significant and relevant to the security of systems and the environments in which those systems operate to meet specific and ongoing auditing needs. Event types can include password changes, failed logons or failed accesses related to systems, administrative privilege usage, or third-party credential usage. In determining event types that require logging, organizations consider the monitoring and auditing appropriate for each of the CUI security requirements. Monitoring and auditing requirements can be balanced with other system needs. For example, organizations may determine that systems must have the capability to log every file access both successful and unsuccessful, but not activate that capability except for specific circumstances due to the potential burden on system performance. Audit records can be generated at various levels of abstraction, including at the packet level as information traverses the network. Selecting the appropriate level of abstraction is a critical aspect of an audit logging capability and can facilitate the identification of root causes to problems. Organizations consider in the definition of event types, the logging necessary to cover related events such as the steps in distributed, transaction-based processes (e.g., processes that are distributed across multiple organizations) and actions that occur in service-oriented or cloudbased architectures. Audit record content that may be necessary to satisfy this requirement includes time stamps, source and destination addresses, user or process identifiers, event descriptions, success or fail indications, filenames involved, and access control or flow control rules invoked. Event outcomes can include indicators of event success or failure and event-specific results (e.g., the security state of the system after the event occurred). Detailed information that organizations may consider in audit records includes full text recording of privileged commands or the individual identities of group account users. Organizations consider limiting the additional audit log information to only that information explicitly needed for specific audit requirements. This facilitates the use of audit trails and audit logs by not including information that could potentially be misleading or could make it more difficult to locate information of interest. Audit logs are reviewed and analyzed as often as needed to provide important information to organizations to facilitate risk-based decision making.","checks_status": {"fail": 7,"pass": 4,"total": 14,"manual": 0}},"3_3_2": {"name": "3.3.2 Ensure that the actions of individual system users can be uniquely traced to those users, so they can be held accountable for their actions","checks": {"guardduty_is_enabled": "PASS","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_3_2","Section": "3.3 Audit and Accountability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "This requirement ensures that the contents of the audit record include the information needed to link the audit event to the actions of an individual to the extent feasible. Organizations consider logging for traceability including results from monitoring of account usage, remote access, wireless connectivity, mobile device connection, communications at system boundaries, configuration settings, physical access, nonlocal maintenance, use of maintenance tools, temperature and humidity, equipment delivery and removal, system component inventory, use of mobile code, and use of Voice over Internet Protocol (VoIP).","checks_status": {"fail": 3,"pass": 3,"total": 9,"manual": 0}},"3_3_3": {"name": "3.3.3 Review and update logged events","checks": {"vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_3_3","Section": "3.3 Audit and Accountability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The intent of this requirement is to periodically re-evaluate which logged events will continue to be included in the list of events to be logged. The event types that are logged by organizations may change over time. Reviewing and updating the set of logged event types periodically is necessary to ensure that the current set remains necessary and sufficient.","checks_status": {"fail": 4,"pass": 2,"total": 9,"manual": 0}},"3_3_4": {"name": "3.3.4 Alert in the event of an audit logging process failure","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_3_4","Section": "3.3 Audit and Accountability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Audit logging process failures include software and hardware errors, failures in the audit record capturing mechanisms, and audit record storage capacity being reached or exceeded. This requirement applies to each audit record data storage repository (i.e., distinct system component where audit records are stored), the total audit record storage capacity of organizations (i.e., all audit record data storage repositories combined), or both.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"3_3_5": {"name": "3.3.5 Correlate audit record review, analysis, and reporting processes for investigation and response to indications of unlawful, unauthorized, suspicious, or unusual activity","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_3_5","Section": "3.3 Audit and Accountability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Correlating audit record review, analysis, and reporting processes helps to ensure that they do not operate independently, but rather collectively. Regarding the assessment of a given organizational system, the requirement is agnostic as to whether this correlation is applied at the system level or at the organization level across all systems.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"3_3_8": {"name": "3.3.8 Protect audit information and audit logging tools from unauthorized access, modification, and deletion","checks": {"s3_bucket_public_access": null,"s3_bucket_object_versioning": "FAIL","s3_bucket_default_encryption": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_policy_public_write_access": "PASS","s3_account_level_public_access_blocks": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_3_8","Section": "3.3 Audit and Accountability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Audit information includes all information (e.g., audit records, audit log settings, and audit reports) needed to successfully audit system activity. Audit logging tools are those programs and devices used to conduct audit and logging activities. This requirement focuses on the technical protection of audit information and limits the ability to access and execute audit logging tools to authorized individuals. Physical protection of audit information is addressed by media protection and physical and environmental protection requirements.","checks_status": {"fail": 4,"pass": 2,"total": 8,"manual": 0}},"3_4_1": {"name": "3.4.1 Establish and maintain baseline configurations and inventories of organizational systems (including hardware, software, firmware, and documentation) throughout the respective system development life cycles","checks": {"ec2_elastic_ip_unassigned": "FAIL","elbv2_deletion_protection": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","cloudtrail_multi_region_enabled": "PASS","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_4_1","Section": "3.4 Configuration Management","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Baseline configurations are documented, formally reviewed, and agreed-upon specifications for systems or configuration items within those systems. Baseline configurations serve as a basis for future builds, releases, and changes to systems. Baseline configurations include information about system components (e.g., standard software packages installed on workstations, notebook computers, servers, network components, or mobile devices; current version numbers and update and patch information on operating systems and applications; and configuration settings and parameters), network topology, and the logical placement of those components within the system architecture. Baseline configurations of systems also reflect the current enterprise architecture. Maintaining effective baseline configurations requires creating new baselines as organizational systems change over time. Baseline configuration maintenance includes reviewing and updating the baseline configuration when changes are made based on security risks and deviations from the established baseline configuration Organizations can implement centralized system component inventories that include components from multiple organizational systems. In such situations, organizations ensure that the resulting inventories include system-specific information required for proper component accountability (e.g., system association, system owner). Information deemed necessary for effective accountability of system components includes hardware inventory specifications, software license information, software version numbers, component owners, and for networked components or devices, machine names and network addresses. Inventory specifications include manufacturer, device type, model, serial number, and physical location.","checks_status": {"fail": 6,"pass": 1,"total": 7,"manual": 0}},"3_4_2": {"name": "3.4.2 Establish and enforce security configuration settings for information technology products employed in organizational systems","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_4_2","Section": "3.4 Configuration Management","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Configuration settings are the set of parameters that can be changed in hardware, software, or firmware components of the system that affect the security posture or functionality of the system. Information technology products for which security-related configuration settings can be defined include mainframe computers, servers, workstations, input and output devices (e.g., scanners, copiers, and printers), network components (e.g., firewalls, routers, gateways, voice and data switches, wireless access points, network appliances, sensors), operating systems, middleware, and applications. Security parameters are those parameters impacting the security state of systems including the parameters required to satisfy other security requirements. Security parameters include: registry settings; account, file, directory permission settings; and settings for functions, ports, protocols, and remote connections. Organizations establish organization-wide configuration settings and subsequently derive specific configuration settings for systems. The established settings become part of the systems configuration baseline. Common secure configurations (also referred to as security configuration checklists, lockdown and hardening guides, security reference guides, security technical implementation guides) provide recognized, standardized, and established benchmarks that stipulate secure configuration settings for specific information technology platforms/products and instructions for configuring those system components to meet operational requirements. Common secure configurations can be developed by a variety of organizations including information technology product developers, manufacturers, vendors, consortia, academia, industry, federal agencies, and other organizations in the public and private sectors.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"3_4_6": {"name": "3.4.6 Employ the principle of least functionality by configuring organizational systems to provide only essential capabilities","checks": {"iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"ec2_instance_managed_by_ssm": "FAIL","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"redshift_cluster_public_access": null,"ssm_managed_compliant_patching": "FAIL","s3_bucket_policy_public_write_access": "PASS","s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_4_6","Section": "3.4 Configuration Management","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Systems can provide a wide variety of functions and services. Some of the functions and services routinely provided by default, may not be necessary to support essential organizational missions, functions, or operations. It is sometimes convenient to provide multiple services from single system components. However, doing so increases risk over limiting the services provided by any one component. Where feasible, organizations limit component functionality to a single function per component. Organizations review functions and services provided by systems or components of systems, to determine which functions and services are candidates for elimination. Organizations disable unused or unnecessary physical and logical ports and protocols to prevent unauthorized connection of devices, transfer of information, and tunneling. Organizations can utilize network scanning tools, intrusion detection and prevention systems, and end-point protections such as firewalls and host-based intrusion detection systems to identify and prevent the use of prohibited functions, ports, protocols, and services.","checks_status": {"fail": 3,"pass": 3,"total": 15,"manual": 0}},"3_4_7": {"name": "3.4.7 Restrict, disable, or prevent the use of nonessential programs, functions, ports, protocols, and services","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_4_7","Section": "3.4 Configuration Management","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Restricting the use of nonessential software (programs) includes restricting the roles allowed to approve program execution; prohibiting auto-execute; program blacklisting and whitelisting; or restricting the number of program instances executed at the same time. The organization makes a security-based determination which functions, ports, protocols, and/or services are restricted. Bluetooth, File Transfer Protocol (FTP), and peer-to-peer networking are examples of protocols organizations consider preventing the use of, restricting, or disabling.","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"3_4_9": {"name": "3.4.9 Control and monitor user-installed software","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_4_9","Section": "3.4 Configuration Management","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Users can install software in organizational systems if provided the necessary privileges. To maintain control over the software installed, organizations identify permitted and prohibited actions regarding software installation through policies. Permitted software installations include updates and security patches to existing software and applications from organization-approved 'app stores.' Prohibited software installations may include software with unknown or suspect pedigrees or software that organizations consider potentially malicious. The policies organizations select governing user-installed software may be organization-developed or provided by some external entity. Policy enforcement methods include procedural methods, automated methods, or both.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"3_5_2": {"name": "3.5.2 Authenticate (or verify) the identities of users, processes, or devices, as a prerequisite to allowing access to organizational systems","checks": {"iam_root_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_5_2","Section": "3.5 Identification and Authentication","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Individual authenticators include the following: passwords, key cards, cryptographic devices, and one-time password devices. Initial authenticator content is the actual content of the authenticator, for example, the initial password. In contrast, the requirements about authenticator content include the minimum password length. Developers ship system components with factory default authentication credentials to allow for initial installation and configuration. Default authentication credentials are often well known, easily discoverable, and present a significant security risk. Systems support authenticator management by organization-defined settings and restrictions for various authenticator characteristics including minimum password length, validation time window for time synchronous one-time tokens, and number of allowed rejections during the verification stage of biometric authentication. Authenticator management includes issuing and revoking, when no longer needed, authenticators for temporary access such as that required for remote maintenance. Device authenticators include certificates and passwords.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"3_5_3": {"name": "3.5.3 Use multifactor authentication for local and network access to privileged accounts and for network access to non-privileged accounts","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_5_3","Section": "3.5 Identification and Authentication","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Multifactor authentication requires the use of two or more different factors to authenticate. The factors are defined as something you know (e.g., password, personal identification number [PIN]); something you have (e.g., cryptographic identification device, token); or something you are (e.g., biometric). Multifactor authentication solutions that feature physical authenticators include hardware authenticators providing time-based or challenge-response authenticators and smart cards. In addition to authenticating users at the system level (i.e., at logon), organizations may also employ authentication mechanisms at the application level, when necessary, to provide increased information security. Access to organizational systems is defined as local access or network access. Local access is any access to organizational systems by users (or processes acting on behalf of users) where such access is obtained by direct connections without the use of networks. Network access is access to systems by users (or processes acting on behalf of users) where such access is obtained through network connections (i.e., nonlocal accesses). Remote access is a type of network access that involves communication through external networks. The use of encrypted virtual private networks for connections between organization-controlled and non-organization controlled endpoints may be treated as internal networks with regard to protecting the confidentiality of information.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"3_5_5": {"name": "3.5.5 Prevent reuse of identifiers for a defined period","checks": {"iam_password_policy_reuse_24": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_5_5","Section": "3.5 Identification and Authentication","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Identifiers are provided for users, processes acting on behalf of users, or devices (3.5.1). Preventing reuse of identifiers implies preventing the assignment of previously used individual, group, role, or device identifiers to different individuals, groups, roles, or devices.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"3_5_6": {"name": "3.5.6 Disable identifiers after a defined period of inactivity","checks": {"iam_user_accesskey_unused": null,"iam_password_policy_reuse_24": null,"iam_user_console_access_unused": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_5_6","Section": "3.5 Identification and Authentication","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Inactive identifiers pose a risk to organizational information because attackers may exploit an inactive identifier to gain undetected access to organizational devices. The owners of the inactive accounts may not notice if unauthorized access to the account has been obtained.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"3_5_7": {"name": "3.5.7 Enforce a minimum password complexity and change of characters when new passwords are created","checks": {"iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_5_7","Section": "3.5 Identification and Authentication","Service": "aws","SubGroup": null,"SubSection": null}],"description": "This requirement applies to single-factor authentication of individuals using passwords as individual or group authenticators, and in a similar manner, when passwords are used as part of multifactor authenticators. The number of changed characters refers to the number of changes required with respect to the total number of positions in the current password. To mitigate certain brute force attacks against passwords, organizations may also consider salting passwords.","checks_status": {"fail": 0,"pass": 0,"total": 9,"manual": 0}},"3_5_8": {"name": "3.5.8 Prohibit password reuse for a specified number of generations","checks": {"iam_user_accesskey_unused": null,"iam_password_policy_reuse_24": null,"iam_user_console_access_unused": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_5_8","Section": "3.5 Identification and Authentication","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Password lifetime restrictions do not apply to temporary passwords.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"3_6_1": {"name": "3.6.1 Establish an operational incident-handling capability for organizational systems that includes preparation, detection, analysis, containment, recovery, and user response activities","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_6_1","Section": "3.6 Incident Response","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Organizations recognize that incident handling capability is dependent on the capabilities of organizational systems and the mission/business processes being supported by those systems. Organizations consider incident handling as part of the definition, design, and development of mission/business processes and systems. Incident-related information can be obtained from a variety of sources including audit monitoring, network monitoring, physical access monitoring, user and administrator reports, and reported supply chain events. Effective incident handling capability includes coordination among many organizational entities including mission/business owners, system owners, authorizing officials, human resources offices, physical and personnel security offices, legal departments, operations personnel, procurement offices, and the risk executive. As part of user response activities, incident response training is provided by organizations and is linked directly to the assigned roles and responsibilities of organizational personnel to ensure that the appropriate content and level of detail is included in such training. For example, regular users may only need to know who to call or how to recognize an incident on the system; system administrators may require additional training on how to handle or remediate incidents; and incident responders may receive more specific training on forensics, reporting, system recovery, and restoration. Incident response training includes user training in the identification/reporting of suspicious activities from external and internal sources. User response activities also includes incident response assistance which may consist of help desk support, assistance groups, and access to forensics services or consumer redress services, when required.","checks_status": {"fail": 6,"pass": 4,"total": 14,"manual": 0}},"3_6_2": {"name": "3.6.2 Track, document, and report incidents to designated officials and/or authorities both internal and external to the organization","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_6_2","Section": "3.6 Incident Response","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Tracking and documenting system security incidents includes maintaining records about each incident, the status of the incident, and other pertinent information necessary for forensics, evaluating incident details, trends, and handling. Incident information can be obtained from a variety of sources including incident reports, incident response teams, audit monitoring, network monitoring, physical access monitoring, and user/administrator reports. Reporting incidents addresses specific incident reporting requirements within an organization and the formal incident reporting requirements for the organization. Suspected security incidents may also be reported and include the receipt of suspicious email communications that can potentially contain malicious code. The types of security incidents reported, the content and timeliness of the reports, and the designated reporting authorities reflect applicable laws, Executive Orders, directives, regulations, and policies.","checks_status": {"fail": 6,"pass": 4,"total": 14,"manual": 0}},"3_11_2": {"name": "3.11.2 Scan for vulnerabilities in organizational systems and applications periodically and when new vulnerabilities affecting those systems and applications are identified","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_11_2","Section": "3.11 Risk Assessment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Organizations determine the required vulnerability scanning for all system components, ensuring that potential sources of vulnerabilities such as networked printers, scanners, and copiers are not overlooked. The vulnerabilities to be scanned are readily updated as new vulnerabilities are discovered, announced, and scanning methods developed. This process ensures that potential vulnerabilities in the system are identified and addressed as quickly as possible. Vulnerability analyses for custom software applications may require additional approaches such as static analysis, dynamic analysis, binary analysis, or a hybrid of the three approaches. Organizations can employ these analysis approaches in source code reviews and in a variety of tools (e.g., static analysis tools, web-based application scanners, binary analyzers) and in source code reviews. Vulnerability scanning includes: scanning for patch levels; scanning for functions, ports, protocols, and services that should not be accessible to users or devices; and scanning for improperly configured or incorrectly operating information flow control mechanisms. To facilitate interoperability, organizations consider using products that are Security Content Automated Protocol (SCAP)-validated, scanning tools that express vulnerabilities in the Common Vulnerabilities and Exposures (CVE) naming convention, and that employ the Open Vulnerability Assessment Language (OVAL) to determine the presence of system vulnerabilities. Sources for vulnerability information include the Common Weakness Enumeration (CWE) listing and the National Vulnerability Database (NVD). Security assessments, such as red team exercises, provide additional sources of potential vulnerabilities for which to scan. Organizations also consider using scanning tools that express vulnerability impact by the Common Vulnerability Scoring System (CVSS). In certain situations, the nature of the vulnerability scanning may be more intrusive or the system component that is the subject of the scanning may contain highly sensitive information. Privileged access authorization to selected system components facilitates thorough vulnerability scanning and protects the sensitive nature of such scanning.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"3_11_3": {"name": "3.11.3 Remediate vulnerabilities in accordance with risk assessments","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_11_3","Section": "3.11 Risk Assessment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Vulnerabilities discovered, for example, via the scanning conducted in response to 3.11.2, are remediated with consideration of the related assessment of risk. The consideration of risk influences the prioritization of remediation efforts and the level of effort to be expended in the remediation for specific vulnerabilities.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"3_12_4": {"name": "3.12.4 Develop, document, and periodically update system security plans that describe system boundaries, system environments of operation, how security requirements are implemented, and the relationships with or connections to other systems","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_12_4","Section": "3.12 Assessment, Authorization, and Monitoring","Service": "aws","SubGroup": null,"SubSection": null}],"description": "System security plans relate security requirements to a set of security controls. System security plans also describe, at a high level, how the security controls meet those security requirements, but do not provide detailed, technical descriptions of the design or implementation of the controls. System security plans contain sufficient information to enable a design and implementation that is unambiguously compliant with the intent of the plans and subsequent determinations of risk if the plan is implemented as intended. Security plans need not be single documents; the plans can be a collection of various documents including documents that already exist. Effective security plans make extensive use of references to policies, procedures, and additional documents (e.g., design and implementation specifications) where more detailed information can be obtained. This reduces the documentation requirements associated with security programs and maintains security-related information in other established management/operational areas related to enterprise architecture, system development life cycle, systems engineering, and acquisition. Federal agencies may consider the submitted system security plans and plans of action as critical inputs to an overall risk management decision to process, store, or transmit CUI on a system hosted by a nonfederal organization and whether it is advisable to pursue an agreement or contract with the nonfederal organization.","checks_status": {"fail": 2,"pass": 3,"total": 9,"manual": 0}},"3_13_1": {"name": "3.13.1 Monitor, control, and protect communications (i.e., information transmitted or received by organizational systems) at the external boundaries and key internal boundaries of organizational systems","checks": {"elb_ssl_listeners": "FAIL","elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","elbv2_waf_acl_attached": "FAIL","rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"cloudtrail_multi_region_enabled": "PASS","acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_logging_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_13_1","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Communications can be monitored, controlled, and protected at boundary components and by restricting or prohibiting interfaces in organizational systems. Boundary components include gateways, routers, firewalls, guards, network-based malicious code analysis and virtualization systems, or encrypted tunnels implemented within a system security architecture (e.g., routers protecting firewalls or application gateways residing on protected subnetworks). Restricting or prohibiting interfaces in organizational systems includes restricting external web communications traffic to designated web servers within managed interfaces and prohibiting external traffic that appears to be spoofing internal addresses. Organizations consider the shared nature of commercial telecommunications services in the implementation of security requirements associated with the use of such services. Commercial telecommunications services are commonly based on network components and consolidated management systems shared by all attached commercial customers and may also include third party-provided access lines and other service elements. Such transmission services may represent sources of increased risk despite contract security provisions.","checks_status": {"fail": 10,"pass": 8,"total": 23,"manual": 0}},"3_13_2": {"name": "3.13.2 Employ architectural designs, software development techniques, and systems engineering principles that promote effective information security within organizational systems","checks": {"rds_instance_multi_az": "FAIL","ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","efs_have_backup_enabled": "FAIL","s3_bucket_public_access": null,"elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","dynamodb_tables_pitr_enabled": null,"awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"cloudtrail_multi_region_enabled": "PASS","acm_certificates_expiration_check": "PASS","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"rds_instance_integration_cloudwatch_logs": "FAIL","awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_13_2","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Organizations apply systems security engineering principles to new development systems or systems undergoing major upgrades. For legacy systems, organizations apply systems security engineering principles to system upgrades and modifications to the extent feasible, given the current state of hardware, software, and firmware components within those systems. The application of systems security engineering concepts and principles helps to develop trustworthy, secure, and resilient systems and system components and reduce the susceptibility of organizations to disruptions, hazards, and threats. Examples of these concepts and principles include developing layered protections; establishing security policies, architecture, and controls as the foundation for design; incorporating security requirements into the system development life cycle; delineating physical and logical security boundaries; ensuring that developers are trained on how to build secure software; and performing threat modeling to identify use cases, threat agents, attack vectors and patterns, design patterns, and compensating controls needed to mitigate risk. Organizations that apply security engineering concepts and principles can facilitate the development of trustworthy, secure systems, system components, and system services; reduce risk to acceptable levels; and make informed risk-management decisions.","checks_status": {"fail": 7,"pass": 8,"total": 23,"manual": 0}},"3_13_3": {"name": "3.13.3 Separate user functionality from system management functionality","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_13_3","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "System management functionality includes functions necessary to administer databases, network components, workstations, or servers, and typically requires privileged user access. The separation of user functionality from system management functionality is physical or logical. Organizations can implement separation of system management functionality from user functionality by using different computers, different central processing units, different instances of operating systems, or different network addresses; virtualization techniques; or combinations of these or other methods, as appropriate. This type of separation includes web administrative interfaces that use separate authentication methods for users of any other system resources. Separation of system and user functionality may include isolating administrative interfaces on different domains and with additional access controls.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"3_13_4": {"name": "3.13.4 Prevent unauthorized and unintended information transfer via shared system resources","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_13_4","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The control of information in shared system resources (e.g., registers, cache memory, main memory, hard disks) is also commonly referred to as object reuse and residual information protection. This requirement prevents information produced by the actions of prior users or roles (or the actions of processes acting on behalf of prior users or roles) from being available to any current users or roles (or current processes acting on behalf of current users or roles) that obtain access to shared system resources after those resources have been released back to the system. This requirement also applies to encrypted representations of information. This requirement does not address information remanence, which refers to residual representation of data that has been nominally deleted; covert channels (including storage or timing channels) where shared resources are manipulated to violate information flow restrictions; or components within systems for which there are only single users or roles.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3_13_5": {"name": "3.13.5 Implement subnetworks for publicly accessible system components that are physically or logically separated from internal networks","checks": {"elb_ssl_listeners": "FAIL","ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_13_5","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Subnetworks that are physically or logically separated from internal networks are referred to as demilitarized zones (DMZs). DMZs are typically implemented with boundary control devices and techniques that include routers, gateways, firewalls, virtualization, or cloud-based technologies.","checks_status": {"fail": 6,"pass": 6,"total": 20,"manual": 0}},"3_13_6": {"name": "3.13.6 Deny network communications traffic by default and allow network communications traffic by exception (i.e., deny all, permit by exception)","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_13_6","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "This requirement applies to inbound and outbound network communications traffic at the system boundary and at identified points within the system. A deny-all, permit-by-exception network communications traffic policy ensures that only those connections which are essential and approved are allowed.","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"3_13_8": {"name": "3.13.8 Implement cryptographic mechanisms to prevent unauthorized disclosure of CUI during transmission unless otherwise protected by alternative physical safeguards","checks": {"elb_ssl_listeners": "FAIL","acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_13_8","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "This requirement applies to internal and external networks and any system components that can transmit information including servers, notebook computers, desktop computers, mobile devices, printers, copiers, scanners, and facsimile machines. Communication paths outside the physical protection of controlled boundaries are susceptible to both interception and modification. Organizations relying on commercial providers offering transmission services as commodity services rather than as fully dedicated services (i.e., services which can be highly specialized to individual customer needs), may find it difficult to obtain the necessary assurances regarding the implementation of the controls for transmission confidentiality. In such situations, organizations determine what types of confidentiality services are available in commercial telecommunication service packages. If it is infeasible or impractical to obtain the necessary safeguards and assurances of the effectiveness of the safeguards through appropriate contracting vehicles, organizations implement compensating safeguards or explicitly accept the additional risk. An example of an alternative physical safeguard is a protected distribution system (PDS) where the distribution medium is protected against electronic or physical intercept, thereby ensuring the confidentiality of the information being transmitted.","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"3_14_1": {"name": "3.14.1 Identify, report, and correct system flaws in a timely manner","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_14_1","Section": "3.14 System and Information integrity","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Organizations identify systems that are affected by announced software and firmware flaws including potential vulnerabilities resulting from those flaws and report this information to designated personnel with information security responsibilities. Security-relevant updates include patches, service packs, hot fixes, and anti-virus signatures. Organizations address flaws discovered during security assessments, continuous monitoring, incident response activities, and system error handling. Organizations can take advantage of available resources such as the Common Weakness Enumeration (CWE) database or Common Vulnerabilities and Exposures (CVE) database in remediating flaws discovered in organizational systems. Organization-defined time periods for updating security-relevant software and firmware may vary based on a variety of factors including the criticality of the update (i.e., severity of the vulnerability related to the discovered flaw). Some types of flaw remediation may require more testing than other types of remediation.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"3_14_2": {"name": "3.14.2 Provide protection from malicious code at designated locations within organizational systems","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_14_2","Section": "3.14 System and Information integrity","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Designated locations include system entry and exit points which may include firewalls, remoteaccess servers, workstations, electronic mail servers, web servers, proxy servers, notebook computers, and mobile devices. Malicious code includes viruses, worms, Trojan horses, and spyware. Malicious code can be encoded in various formats (e.g., UUENCODE, Unicode), contained within compressed or hidden files, or hidden in files using techniques such as steganography. Malicious code can be inserted into systems in a variety of ways including web accesses, electronic mail, electronic mail attachments, and portable storage devices. Malicious code insertions occur through the exploitation of system vulnerabilities. Malicious code protection mechanisms include anti-virus signature definitions and reputationbased technologies. A variety of technologies and methods exist to limit or eliminate the effects of malicious code. Pervasive configuration management and comprehensive software integrity controls may be effective in preventing execution of unauthorized code. In addition to commercial off-the-shelf software, malicious code may also be present in custom-built software. This could include logic bombs, back doors, and other types of cyber-attacks that could affect organizational missions/business functions. Traditional malicious code protection mechanisms cannot always detect such code. In these situations, organizations rely instead on other safeguards including secure coding practices, configuration management and control, trusted procurement processes, and monitoring practices to help ensure that software does not perform functions other than the functions intended.","checks_status": {"fail": 2,"pass": 2,"total": 5,"manual": 0}},"3_14_3": {"name": "3.14.3 Monitor system security alerts and advisories and take action in response","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_14_3","Section": "3.14 System and Information integrity","Service": "aws","SubGroup": null,"SubSection": null}],"description": "There are many publicly available sources of system security alerts and advisories. For example, the Department of Homeland Security’s Cybersecurity and Infrastructure Security Agency (CISA) generates security alerts and advisories to maintain situational awareness across the federal government and in nonfederal organizations. Software vendors, subscription services, and industry information sharing and analysis centers (ISACs) may also provide security alerts and advisories. Examples of response actions include notifying relevant external organizations, for example, external mission/business partners, supply chain partners, external service providers, and peer or supporting organizations.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"3_14_4": {"name": "3.14.4 Update malicious code protection mechanisms when new releases are available","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_14_4","Section": "3.14 System and Information integrity","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Malicious code protection mechanisms include anti-virus signature definitions and reputationbased technologies. A variety of technologies and methods exist to limit or eliminate the effects of malicious code. Pervasive configuration management and comprehensive software integrity controls may be effective in preventing execution of unauthorized code. In addition to commercial off-the-shelf software, malicious code may also be present in custom-built software. This could include logic bombs, back doors, and other types of cyber-attacks that could affect organizational missions/business functions. Traditional malicious code protection mechanisms cannot always detect such code. In these situations, organizations rely instead on other safeguards including secure coding practices, configuration management and control, trusted procurement processes, and monitoring practices to help ensure that software does not perform functions other than the functions intended.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3_14_6": {"name": "3.14.6 Monitor organizational systems, including inbound and outbound communications traffic, to detect attacks and indicators of potential attacks","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_14_6","Section": "3.14 System and Information integrity","Service": "aws","SubGroup": null,"SubSection": null}],"description": "System monitoring includes external and internal monitoring. External monitoring includes the observation of events occurring at the system boundary (i.e., part of perimeter defense and boundary protection). Internal monitoring includes the observation of events occurring within the system. Organizations can monitor systems, for example, by observing audit record activities in real time or by observing other system aspects such as access patterns, characteristics of access, and other actions. The monitoring objectives may guide determination of the events. System monitoring capability is achieved through a variety of tools and techniques (e.g., intrusion detection systems, intrusion prevention systems, malicious code protection software, scanning tools, audit record monitoring software, network monitoring software). Strategic locations for monitoring devices include selected perimeter locations and near server farms supporting critical applications, with such devices being employed at managed system interfaces. The granularity of monitoring information collected is based on organizational monitoring objectives and the capability of systems to support such objectives. System monitoring is an integral part of continuous monitoring and incident response programs. Output from system monitoring serves as input to continuous monitoring and incident response programs. A network connection is any connection with a device that communicates through a network (e.g., local area network, Internet). A remote connection is any connection with a device communicating through an external network (e.g., the Internet). Local, network, and remote connections can be either wired or wireless. Unusual or unauthorized activities or conditions related to inbound/outbound communications traffic include internal traffic that indicates the presence of malicious code in systems or propagating among system components, the unauthorized exporting of information, or signaling to external systems. Evidence of malicious code is used to identify potentially compromised systems or system components. System monitoring requirements, including the need for specific types of system monitoring, may be referenced in other requirements.","checks_status": {"fail": 5,"pass": 4,"total": 12,"manual": 0}},"3_14_7": {"name": "3.14.7 Identify unauthorized use of organizational systems","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_14_7","Section": "3.14 System and Information integrity","Service": "aws","SubGroup": null,"SubSection": null}],"description": "System monitoring includes external and internal monitoring. System monitoring can detect unauthorized use of organizational systems. System monitoring is an integral part of continuous monitoring and incident response programs. Monitoring is achieved through a variety of tools and techniques (e.g., intrusion detection systems, intrusion prevention systems, malicious code protection software, scanning tools, audit record monitoring software, network monitoring software). Output from system monitoring serves as input to continuous monitoring and incident response programs. Unusual/unauthorized activities or conditions related to inbound and outbound communications traffic include internal traffic that indicates the presence of malicious code in systems or propagating among system components, the unauthorized exporting of information, or signaling to external systems. Evidence of malicious code is used to identify potentially compromised systems or system components. System monitoring requirements, including the need for specific types of system monitoring, may be referenced in other requirements.","checks_status": {"fail": 5,"pass": 4,"total": 12,"manual": 0}},"3_1_12": {"name": "3.1.12 Monitor and control remote access sessions","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_1_12","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Remote access is access to organizational systems by users (or processes acting on behalf of users) communicating through external networks (e.g., the Internet). Remote access methods include dial-up, broadband, and wireless. Organizations often employ encrypted virtual private networks (VPNs) to enhance confidentiality over remote connections. The use of encrypted VPNs does not make the access non-remote; however, the use of VPNs, when adequately provisioned with appropriate control (e.g., employing encryption techniques for confidentiality protection), may provide sufficient assurance to the organization that it can effectively treat such connections as internal networks. VPNs with encrypted tunnels can affect the capability to adequately monitor network communications traffic for malicious code. Automated monitoring and control of remote access sessions allows organizations to detect cyberattacks and help to ensure ongoing compliance with remote access policies by auditing connection activities of remote users on a variety of system components (e.g., servers, workstations, notebook computers, smart phones, and tablets).","checks_status": {"fail": 4,"pass": 4,"total": 11,"manual": 0}},"3_1_13": {"name": "3.1.13 Employ cryptographic mechanisms to protect the confidentiality of remote access sessions","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_1_13","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Cryptographic standards include FIPS-validated cryptography and NSA-approved cryptography.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"3_1_14": {"name": "3.1.14 Route remote access via managed access control points","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"iam_user_mfa_enabled_console_access": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_1_14","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Routing remote access through managed access control points enhances explicit, organizational control over such connections, reducing the susceptibility to unauthorized access to organizational systems resulting in the unauthorized disclosure of CUI.","checks_status": {"fail": 3,"pass": 5,"total": 14,"manual": 0}},"3_1_20": {"name": "3.1.20 Verify and control/limit connections to and use of external systems","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_1_20","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "External systems are systems or components of systems for which organizations typically have no direct supervision and authority over the application of security requirements and controls or the determination of the effectiveness of implemented controls on those systems. External systems include personally owned systems, components, or devices and privately-owned computing and communications devices resident in commercial or public facilities. This requirement also addresses the use of external systems for the processing, storage, or transmission of CUI, including accessing cloud services (e.g., infrastructure as a service, platform as a service, or software as a service) from organizational systems. Organizations establish terms and conditions for the use of external systems in accordance with organizational security policies and procedures. Terms and conditions address as a minimum, the types of applications that can be accessed on organizational systems from external systems. If terms and conditions with the owners of external systems cannot be established, organizations may impose restrictions on organizational personnel using those external systems. This requirement recognizes that there are circumstances where individuals using external systems (e.g., contractors, coalition partners) need to access organizational systems. In those situations, organizations need confidence that the external systems contain the necessary controls so as not to compromise, damage, or otherwise harm organizational systems. Verification that the required controls have been effectively implemented can be achieved by third-party, independent assessments, attestations, or other means, depending on the assurance or confidence level required by organizations. Note that while ā€œexternalā€ typically refers to outside of the organization's direct supervision and authority, that is not always the case. Regarding the protection of CUI across an organization, the organization may have systems that process CUI and others that do not. And among the systems that process CUI there are likely access restrictions for CUI that apply between systems. Therefore, from the perspective of a given system, other systems within the organization may be considered 'external' to that system.","checks_status": {"fail": 2,"pass": 1,"total": 5,"manual": 0}},"3_5_10": {"name": "3.5.10 Store and transmit only cryptographically-protected passwords","checks": {"ec2_ebs_volume_encryption": "PASS","elbv2_insecure_ssl_ciphers": "PASS","s3_bucket_default_encryption": "PASS","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_5_10","Section": "3.5 Identification and Authentication","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Cryptographically-protected passwords use salted one-way cryptographic hashes of passwords.","checks_status": {"fail": 2,"pass": 3,"total": 6,"manual": 0}},"3_13_11": {"name": "3.13.11 Employ FIPS-validated cryptography when used to protect the confidentiality of CUI","checks": {"ec2_ebs_volume_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","acm_certificates_expiration_check": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_13_11","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Cryptography can be employed to support many security solutions including the protection of controlled unclassified information, the provision of digital signatures, and the enforcement of information separation when authorized individuals have the necessary clearances for such information but lack the necessary formal access approvals. Cryptography can also be used to support random number generation and hash generation. Cryptographic standards include FIPSvalidated cryptography and/or NSA-approved cryptography.","checks_status": {"fail": 6,"pass": 3,"total": 12,"manual": 0}},"3_13_15": {"name": "3.13.15 Protect the authenticity of communications sessions","checks": {"elb_ssl_listeners": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_13_15","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Authenticity protection includes protecting against man-in-the-middle attacks, session hijacking, and the insertion of false information into communications sessions. This requirement addresses communications protection at the session versus packet level (e.g., sessions in service-oriented architectures providing web-based services) and establishes grounds for confidence at both ends of communications sessions in ongoing identities of other parties and in the validity of information transmitted.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3_13_16": {"name": "3.13.16 Protect the confidentiality of CUI at rest","checks": {"ec2_ebs_volume_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_13_16","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Information at rest refers to the state of information when it is not in process or in transit and is located on storage devices as specific components of systems. The focus of protection at rest is not on the type of storage device or the frequency of access but rather the state of the information. Organizations can use different mechanisms to achieve confidentiality protections, including the use of cryptographic mechanisms and file share scanning. Organizations may also use other controls including secure off-line storage in lieu of online storage when adequate protection of information at rest cannot otherwise be achieved or continuous monitoring to identify malicious code at rest.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}}},"requirements_passed": 14,"requirements_failed": 35,"requirements_manual": 1,"total_requirements": 50,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "168b9e98-d0d8-47a8-b53a-32097ec095ac","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "nist_800_53_revision_4_aws","framework": "NIST-800-53-Revision-4","version": "","description": "NIST 800-53 is a regulatory standard that defines the minimum baseline of security controls for all U.S. federal information systems except those related to national security. The controls defined in this standard are customizable and address a diverse set of security and privacy requirements.","region": "eu-west-1","requirements": {"ac_2": {"name": "Account Management (AC-2)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_password_policy_reuse_24": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_2","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Manage system accounts, group memberships, privileges, workflow, notifications, deactivations, and authorizations.","checks_status": {"fail": 3,"pass": 3,"total": 18,"manual": 0}},"ac_3": {"name": "Access Enforcement (AC-3)","checks": {"iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_3","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system enforces approved authorizations for logical access to information and system resources in accordance with applicable access control policies.","checks_status": {"fail": 0,"pass": 3,"total": 14,"manual": 0}},"ac_4": {"name": "Information Flow Enforcement (AC-4)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"acm_certificates_expiration_check": "PASS","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_4","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system enforces approved authorizations for controlling the flow of information within the system and between interconnected systems based on organization-defined information flow control policies.","checks_status": {"fail": 3,"pass": 7,"total": 17,"manual": 0}},"ac_5": {"name": "Separation Of Duties (AC-5)","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_5","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Separate duties of individuals to prevent malevolent activity. automate separation of duties and access authorizations.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"ac_6": {"name": "Least Privilege (AC-6)","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_6","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks in accordance with organizational missions and business functions.","checks_status": {"fail": 1,"pass": 5,"total": 18,"manual": 0}},"au_2": {"name": "Event Logging (AU-2)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_2","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Automate security audit function with other organizational entities. Enable mutual support of audit of auditable events.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_3": {"name": "Content of Audit Records (AU-3)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_3","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system generates audit records containing information that establishes what type of event occurred, when the event occurred, where the event occurred, the source of the event, the outcome of the event, and the identity of any individuals or subjects associated with the event.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_9": {"name": "Protection of Audit Information (AU-9)","checks": {"cloudtrail_kms_encryption_enabled": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_9","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects audit information and audit tools from unauthorized access, modification, and deletion.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"ca_7": {"name": "Continuous Monitoring (CA-7)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ca_7","Section": "Security Assessment And Authorization (CA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Continuously monitor configuration management processes. Determine security impact, environment and operational risks.","checks_status": {"fail": 2,"pass": 3,"total": 9,"manual": 0}},"cm_2": {"name": "Baseline Configuration (CM-2)","checks": {"elbv2_deletion_protection": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","cloudtrail_multi_region_enabled": "PASS","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_2","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization develops, documents, and maintains under configuration control, a current baseline configuration of the information system.","checks_status": {"fail": 5,"pass": 1,"total": 6,"manual": 0}},"cm_7": {"name": "Least Functionality (CM-7)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_7","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization configures the information system to provide only essential capabilities and prohibits or restricts the use of the functions, ports, protocols, and/or services.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cp_9": {"name": "Information System Backup (CP-9)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","dynamodb_tables_pitr_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_9","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization conducts backups of user-level information, system-level information and information system documentation including security-related documentation contained in the information system and protects the confidentiality, integrity, and availability of backup information at storage locations.","checks_status": {"fail": 1,"pass": 1,"total": 4,"manual": 0}},"ia_2": {"name": "Identification and Authentication (Organizational users) (IA-2)","checks": {"iam_password_policy_reuse_24": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2","Section": "Identification and Authentication (IA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ra_5": {"name": "Vulnerability Scanning (RA-5)","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ra_5","Section": "Risk Assessment (RA)","Service": "guardduty","SubGroup": null,"SubSection": null}],"description": "Scan for system vulnerabilities. Share vulnerability information and security controls that eliminate vulnerabilities.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"sa_3": {"name": "System Development Life Cycle (SA-3)","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sa_3","Section": "System and Services Acquisition (SA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization manages the information system using organization-defined system development life cycle, defines and documents information security roles and responsibilities throughout the system development life cycle, identifies individuals having information security roles and responsibilities and integrates the organizational information security risk management process into system development life cycle activities.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sc_2": {"name": "Application Partitioning (SC-2)","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_2","Section": "System and Communications Protection (SC)","Service": "iam","SubGroup": null,"SubSection": null}],"description": "The information system separates user functionality (including user interface services) from information system management functionality.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"sc_4": {"name": "Information In Shared Resources (SC-4)","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_4","Section": "System and Communications Protection (SC)","Service": "ebs","SubGroup": null,"SubSection": null}],"description": "The information system prevents unauthorized and unintended information transfer via shared system resources.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"sc_5": {"name": "Denial Of Service Protection (SC-5)","checks": {"rds_instance_multi_az": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_5","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects against or limits the effects of the following types of denial of service attacks: [Assignment: organization-defined types of denial of service attacks or references to sources for such information] by employing [Assignment: organization-defined security safeguards].","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"sc_7": {"name": "Boundary Protection (SC-7)","checks": {"elb_ssl_listeners": "FAIL","ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system: a. Monitors and controls communications at the external boundary of the system and at key internal boundaries within the system; b. Implements subnetworks for publicly accessible system components that are [Selection: physically; logically] separated from internal organizational networks; and c. Connects to external networks or information systems only through managed interfaces consisting of boundary protection devices arranged in accordance with an organizational security architecture.","checks_status": {"fail": 6,"pass": 6,"total": 20,"manual": 0}},"sc_8": {"name": "Transmission Confidentiality And Integrity (SC-8)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_8","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects the [Selection (one or more): confidentiality; integrity] of transmitted information.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"si_4": {"name": "Information System Monitoring (SI-4)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_waf_acl_attached": "FAIL","ec2_instance_imdsv2_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_4","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization: a.Monitors the information system to detect: 1. Attacks and indicators of potential attacks in accordance with [Assignment: organization-defined monitoring objectives]; and 2.Unauthorized local, network, and remote connections; b. Identifies unauthorized use of the information system through [Assignment: organization-defined techniques and methods]; c. Deploys monitoring devices: 1. Strategically within the information system to collect organization-determined essential information; and 2. At ad hoc locations within the system to track specific types of transactions of interest to the organization; d. Protects information obtained from intrusion-monitoring tools from unauthorized access, modification, and deletion; e. Heightens the level of information system monitoring activity whenever there is an indication of increased risk to organizational operations and assets, individuals, other organizations, or the Nation based on law enforcement information, intelligence information, or other credible sources of information; f. Obtains legal opinion with regard to information system monitoring activities in accordance with applicable federal laws, Executive Orders, directives, policies, or regulations; and g. Provides [Assignment: organization-defined information system monitoring information] to [Assignment: organization-defined personnel or roles] [Selection (one or more): as needed; [Assignment: organization-defined frequency]].","checks_status": {"fail": 3,"pass": 3,"total": 10,"manual": 0}},"si_7": {"name": "Software, Firmware, and Information Integrity (SI-7)","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_7","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization employs integrity verification tools to detect unauthorized changes to [Assignment: organization-defined software, firmware, and information].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ac_21": {"name": "Information Sharing (AC-21)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_21","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Facilitate information sharing. Enable authorized users to grant access to partners.","checks_status": {"fail": 1,"pass": 4,"total": 11,"manual": 0}},"au_11": {"name": "Audit Record Retention (AU-11)","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_11","Section": "Audit and Accountability (AU)","Service": "cloudwatch","SubGroup": null,"SubSection": null}],"description": "The organization retains audit records for [Assignment: organization-defined time period consistent with records retention policy] to provide support for after-the-fact investigations of security incidents and to meet regulatory and organizational information retention requirements.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"au_12": {"name": "Audit Generation (AU-12)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_12","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Audit events defined in AU-2. Allow trusted personnel to select which events to audit. Generate audit records for events.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"cp_10": {"name": "Information System Recovery And Reconstitution (CP-10)","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_10","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization provides for the recovery and reconstitution of the information system to a known state after a disruption, compromise, or failure.","checks_status": {"fail": 4,"pass": 1,"total": 7,"manual": 0}},"sa_10": {"name": "Developer Configuration Management (SA-10)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sa_10","Section": "System and Services Acquisition (SA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization requires the developer of the information system, system component, or information system service to: a. Perform configuration management during system, component, or service [Selection (one or more): design; development; implementation; operation]; b. Document, manage, and control the integrity of changes to [Assignment: organization-defined configuration items under configuration management]; c. Implement only organization-approved changes to the system, component, or service; d. Document approved changes to the system, component, or service and the potential security impacts of such changes; and e. Track security flaws and flaw resolution within the system, component, or service and report findings to [Assignment: organization-defined personnel].","checks_status": {"fail": 2,"pass": 2,"total": 4,"manual": 0}},"sc_12": {"name": "Cryptographic Key Establishment And Management (SC-12)","checks": {"kms_cmk_rotation_enabled": null,"acm_certificates_expiration_check": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_12","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization establishes and manages cryptographic keys for required cryptography employed within the information system in accordance with [Assignment: organization-defined requirements for key generation, distribution, storage, access, and destruction].","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"sc_13": {"name": "Cryptographic Protection (SC-13)","checks": {"dynamodb_tables_kms_cmk_encryption_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_13","Section": "System and Communications Protection (SC)","Service": "dynamodb","SubGroup": null,"SubSection": null}],"description": "The information system implements [Assignment: organization-defined cryptographic uses and type of cryptography required for each use] in accordance with applicable federal laws, Executive Orders, directives, policies, regulations, and standards.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"sc_23": {"name": "Session Authenticity (SC-23)","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_23","Section": "System and Communications Protection (SC)","Service": "elb","SubGroup": null,"SubSection": null}],"description": "The information system protects the authenticity of communications sessions.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"sc_28": {"name": "Protection Of Information At Rest (SC-28)","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_28","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects the [Selection (one or more): confidentiality; integrity] of [Assignment: organization-defined information at rest].","checks_status": {"fail": 5,"pass": 3,"total": 12,"manual": 0}},"si_12": {"name": "Information Handling and Retention (SI-12)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_12","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization handles and retains information within the information system and information output from the system in accordance with applicable federal laws, Executive Orders, directives, policies, regulations, standards, and operational requirements.","checks_status": {"fail": 3,"pass": 1,"total": 6,"manual": 0}},"ac_2_1": {"name": "AC-2(1) Automated System Account Management","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_user_accesskey_unused": null,"iam_password_policy_reuse_24": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_1","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "Access control policies (e.g., identity or role-based policies, control matrices, and cryptography) control access between active entities or subjects (i.e., users or processes acting on behalf of users) and passive entities or objects (e.g., devices, files, records, and domains) in systems. Access enforcement mechanisms can be employed at the application and service level to provide increased information security. Other systems include systems internal and external to the organization. This requirement focuses on account management for systems and applications. The definition of and enforcement of access authorizations, other than those determined by account type (e.g., privileged verses non-privileged) are addressed in requirement 3.1.2.","checks_status": {"fail": 0,"pass": 2,"total": 6,"manual": 0}},"ac_2_3": {"name": "AC-2(3) Disable Inactive Accounts","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_3","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The information system automatically disables inactive accounts after 90 days for user accounts.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"ac_2_4": {"name": "AC-2(4) Automated Audit Actions","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_2_4","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The information system automatically audits account creation, modification, enabling, disabling, and removal actions, and notifies [Assignment: organization-defined personnel or roles].","checks_status": {"fail": 2,"pass": 3,"total": 11,"manual": 0}},"au_6_1": {"name": "AU-6(1) Process Integration","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_6_1","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Review, Analysis And Reporting (AU-6)"}],"description": "The organization employs automated mechanisms to integrate audit review, analysis,and reporting processes to support organizational processes for investigation and response to suspicious activities.","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"au_6_3": {"name": "AU-6(3) Correlate Audit Repositories","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_6_3","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Review, Analysis And Reporting (AU-6)"}],"description": "The organization analyzes and correlates audit records across different repositories to gain organization-wide situational awareness.","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"au_7_1": {"name": "AU-7(1) Automatic Processing","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_7_1","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system provides the capability to process audit records for events of interest based on [Assignment: organization-defined audit fields within audit records].","checks_status": {"fail": 1,"pass": 0,"total": 5,"manual": 0}},"au_9_2": {"name": "AU-9(2) Audit Backup On Separate Physical Systems / Components","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "au_9_2","Section": "Audit and Accountability (AU)","Service": "s3","SubGroup": null,"SubSection": "Protection of Audit Information (AU-9)"}],"description": "The information system backs up audit records [Assignment: organization-defined frequency] onto a physically different system or system component than the system or component being audited.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cm_8_1": {"name": "CM-8(1) Updates During Installation / Removals","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_1","Section": "Configuration Management (CM)","Service": "ec2","SubGroup": null,"SubSection": "Information System Component Inventory (CM-8)"}],"description": "The organization develops and documents an inventory of information system components that accurately reflects the current information system, includes all components within the authorization boundary of the information system, is at the level of granularity deemed necessary for tracking and reporting and reviews and updates the information system component inventory.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cm_8_3": {"name": "CM-8(3) Automated Unauthorized Component Detection","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_3","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Information System Component Inventory (CM-8)"}],"description": "The organization employs automated mechanisms to detect the presence of unauthorized hardware, software, and firmware components within the information system and takes actions (disables network access by such components, isolates the components etc) when unauthorized components are detected.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"ia_2_1": {"name": "IA-2(1) Network Access To Privileged Accounts","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2_1","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "The information system implements multi-factor authentication for network access to privileged accounts.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ia_2_2": {"name": "IA-2(2) Network Access To Non-Privileged Accounts","checks": {"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2_2","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "The information system implements multifactor authentication for network access to non-privileged accounts.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"ia_5_1": {"name": "IA-5(1) Password-Based Authentication","checks": {"iam_password_policy_reuse_24": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_1","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "The information system, for password-based authentication that enforces minimum password complexity, stores and transmits only cryptographically-protected passwords, enforces password minimum and maximum lifetime restrictions, prohibits password reuse, allows the use of a temporary password for system logons with an immediate change to a permanent password etc.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_4": {"name": "IA-5(4) Automated Support For Password Strength Determination","checks": {"iam_password_policy_reuse_24": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_4","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "The organization employs automated tools to determine if password authenticators are sufficiently strong to satisfy [Assignment: organization-defined requirements].","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_7": {"name": "IA-5(7) No Embedded Unencrypted Static Authenticators","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_7","Section": "Identification and Authentication (IA)","Service": "codebuild","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "The organization ensures that unencrypted static authenticators are not embedded in applications or access scripts or stored on function keys.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ir_4_1": {"name": "IR-4(1) Automated Incident Handling Processes","checks": {"guardduty_no_high_severity_findings": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ir_4_1","Section": "Incident Response (IR)","Service": "aws","SubGroup": null,"SubSection": "Incident Handling (IR-4)"}],"description": "The organization employs automated mechanisms to support the incident handling process.","checks_status": {"fail": 1,"pass": 0,"total": 5,"manual": 0}},"ir_6_1": {"name": "IR-6(1) Automated Reporting","checks": {"guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ir_6_1","Section": "Incident Response (IR)","Service": "guardduty","SubGroup": null,"SubSection": "Incident Reporting (IR-6)"}],"description": "The organization employs automated mechanisms to assist in the reporting of security incidents.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ir_7_1": {"name": "IR-7(1) Automation Support For Availability Of Information / Support","checks": {"guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ir_7_1","Section": "Incident Response (IR)","Service": "guardduty","SubGroup": null,"SubSection": "Incident Response Assistance (IR-7)"}],"description": "The organization employs automated mechanisms to increase the availability of incident response-related information and support.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sc_7_3": {"name": "SC-7(3) Access Points","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_3","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "The organization limits the number of external network connections to the information system.","checks_status": {"fail": 3,"pass": 6,"total": 16,"manual": 0}},"sc_8_1": {"name": "SC-8(1) Cryptographic Or Alternate Physical Protection","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_8_1","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Transmission Confidentiality And Integrity (SC-8)"}],"description": "The information system implements cryptographic mechanisms to [Selection (one or more): prevent unauthorized disclosure of information; detect changes to information] during transmission unless otherwise protected by [Assignment: organization-defined alternative physical safeguards].","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"si_2_2": {"name": "SI-2(2) Automates Flaw Remediation Status","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_2_2","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Flaw Remediation (SI-2)"}],"description": "The organization employs automated mechanisms to determine the state of information system components with regard to flaw remediation.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"si_4_1": {"name": "SI-4(1) System-Wide Intrusion Detection System","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_1","Section": "System and Information Integrity (SI)","Service": "guardduty","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The organization connects and configures individual intrusion detection tools into an information system-wide intrusion detection system.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_2": {"name": "SI-4(2) Automated Tools For Real-Time Analysis","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_4_2","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The organization employs automated tools to support near real-time analysis of events.","checks_status": {"fail": 1,"pass": 3,"total": 8,"manual": 0}},"si_4_4": {"name": "SI-4(4) Inbound and Outbound Communications Traffic","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_4_4","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The information system monitors inbound and outbound communications traffic continuously for unusual or unauthorized activities or conditions.","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"si_4_5": {"name": "SI-4(5) System-Generated Alerts","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_4_5","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The information system alerts organization-defined personnel or roles when the following indications of compromise or potential compromise occur: [Assignment: organization-defined compromise indicators].","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"si_7_1": {"name": "SI-7(1) Integrity Checks","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_7_1","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Software, Firmware, and Information Integrity (SI-7)"}],"description": "The information system performs an integrity check of security relevant events at least monthly.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"ac_17_1": {"name": "AC-17(1) Automated Monitoring/Control","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_17_1","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system monitors and controls remote access methods.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"ac_17_2": {"name": "AC-17(2) Protection Of Confidentiality/Integrity Using Encryption","checks": {"elb_ssl_listeners": "FAIL","acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_17_2","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system implements cryptographic mechanisms to protect the confidentiality and integrity of remote access sessions.","checks_status": {"fail": 2,"pass": 1,"total": 3,"manual": 0}},"ac_17_3": {"name": "AC-17(3) Managed Access Control Points","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_17_3","Section": "Access Control (AC)","Service": "vpc","SubGroup": null,"SubSection": null}],"description": "The information system routes all remote accesses through organization-defined managed network access control points.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ac_2_12": {"name": "AC-2(12) Account Monitoring","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_12","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "Monitors and reports atypical usage of information system accounts to organization-defined personnel or roles.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"ac_6_10": {"name": "AC-6(10) Prohibit Non-Privileged Users From Executing Privileged Functions","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_6_10","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Least Privilege (AC-6)"}],"description": "The information system prevents non-privileged users from executing privileged functions to include disabling, circumventing, or altering implemented security safeguards/countermeasures.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_2_11": {"name": "IA-2(11) Remote Access - Separate Device","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2_11","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "The information system implements multifactor authentication for remote access to privileged and non-privileged accounts such that one of the factors is provided by a device separate from the system gaining access and the device meets [Assignment: organization-defined strength of mechanism requirements].","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"si_4_16": {"name": "SI-4(16) Correlate Monitoring Information","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_16","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The organization correlates information from monitoring tools employed throughout the information system.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}}},"requirements_passed": 18,"requirements_failed": 41,"requirements_manual": 5,"total_requirements": 64,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "1c8c75df-34ec-48f2-b6e2-5dba27d9b734","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "kisa_isms_p_2023_aws","framework": "KISA-ISMS-P","version": "2023","description": "The ISMS-P certification, established by KISA (Korea Internet & Security Agency), is a system where an independent certification body evaluates whether a company or organization's information security and privacy protection measures comply with certification standards, and grants certification. This helps organizations improve public trust in their services and respond effectively to increasingly complex cyber threats. The ISMS-P framework also provides comprehensive guidelines for systematically establishing, implementing, and managing information security and privacy protection.","region": "eu-west-1","requirements": {"1.1.1": {"name": "Executive Participation","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.1.1 Executive Participation","Subdomain": "1.1. Management System","AuditEvidence": ["Information protection and personal information protection reporting system (e.g., communication plan)","Minutes of the Information Protection and Personal Information Protection Committee","Information protection and personal information protection policies/guidelines (including executive approval records)","Information protection plans and internal management plans (including executive approval records)","Information protection and personal information protection organization chart"],"AuditChecklist": ["Is there documentation outlining the responsibilities and roles of executives to ensure their participation in the establishment and operation of the information protection and personal information protection management system?","Is there a reporting, review, and approval process in place to ensure that executives actively participate in decision-making regarding information protection and personal information protection activities?"],"NonComplianceCases": ["Case 1: Although it is stated in the information protection and personal information protection policy to report the status of information protection and personal information protection to the executives on a quarterly basis, no such reports have been made for an extended period.","Case 2: In performing major information protection activities (e.g., risk assessment, determining risk acceptance levels, reviewing information protection measures and implementation plans, reviewing the results of information protection measures, security audits, etc.), executives or those authorized by the executives did not participate in decision-making or there was no evidence of their involvement."],"RelatedRegulations": []}],"description": "The CEO must establish and operate a reporting and decision-making system to ensure executive participation in the establishment and operation of the information protection and personal information protection management system.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.2": {"name": "Designation of Chief Officers","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.1.2 Designation of Chief Officers","Subdomain": "1.1. Management System","AuditEvidence": ["Documents related to the appointment of the CISO and CPO (e.g., personnel orders, personnel records)","Information protection and personal information protection organization chart","Information protection and personal information protection policies/guidelines","Job descriptions (roles and responsibilities of the CISO and CPO)","Records of CISO reports","Internal management plans (regarding the appointment of the CPO)"],"AuditChecklist": ["Has the CEO officially designated a chief officer responsible for overseeing information protection and personal information protection?","Are the CISO and CPO appointed at an executive level with authority to allocate resources such as budget and personnel, and do they meet the qualifications required by relevant laws?"],"NonComplianceCases": ["Case 1: Failure to appoint and report a CISO as required under the Information and Communications Network Act, even though the organization is obligated to do so.","Case 2: Appointing a person without substantial authority and status as the CPO, making it difficult to believe that they are responsible for overseeing personal information processing.","Case 3: Although the organization chart specifies the CISO and CPO, the formal appointment process, such as issuing personnel orders, was not followed.","Case 4: Although the entity is subject to ISMS certification and had over 5 trillion won in assets at the end of the previous year, the CISO also holds the position of CIO, in violation of the ISMS requirements."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures), Article 31 (Designation of a Personal Information Protection Officer)","Information and Communications Network Act, Article 45-3 (Designation of a Chief Information Security Officer, etc.)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "The CEO must appoint a Chief Information Security Officer (CISO) responsible for information protection and a Chief Privacy Officer (CPO) responsible for personal information protection, both at an executive level with authority to allocate resources such as budget and personnel.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.3": {"name": "Organization Structure","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.1.3 Organization Structure","Subdomain": "1.1. Management System","AuditEvidence": ["Information protection and personal information protection committee regulations/minutes","Information protection and personal information protection working group regulations/minutes","Information protection and personal information protection organization chart","Internal management plan","Job descriptions"],"AuditChecklist": ["Has the organization established and operated a working group with expertise to support the work of the CISO and CPO and systematically implement the organization's information protection and personal information protection activities?","Has the organization established and operated a committee that can review, approve, and make decisions on important information protection and personal information protection matters across the organization?","Has the organization established and operated a working group composed of information protection and personal information protection officers and department-level personnel for enterprise-wide information protection and personal information protection activities?"],"NonComplianceCases": ["Case 1: The Information Protection and Personal Information Protection Committee was established, but it consists only of department heads without the inclusion of executives, making it difficult to make decisions on the organization's key information and personal information protection matters.","Case 2: Although a working group for information protection and personal information protection was established, including heads of departments that handle important information and personal data, it has not been active for an extended period.","Case 3: Although the Information Protection and Personal Information Protection Committee was convened, major matters such as the annual information protection and personal information protection plan, training plan, budget, and personnel were not reviewed or decided upon.","Case 4: Although an Information Protection Committee was established for deliberation and decision-making on information protection and personal information protection matters, only the operations and IT security departments participated, without the involvement of departments responsible for personal information protection, leaving personal information protection matters undecided."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "The CEO must establish and operate a working group to effectively implement information protection and personal information protection, a committee that can review and approve key matters related to information protection and personal information protection across the organization, and a consultative body consisting of department-level information protection and personal information protection officers for enterprise-wide protection activities.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.4": {"name": "Scope Setting","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.1.4 Scope Setting","Subdomain": "1.1. Management System","AuditEvidence": ["Scope definition document for information protection and personal information protection management system","List of information assets and personal information","Document list","Service flowchart","Personal information flowchart","Organization-wide organizational chart","System and network configuration diagram"],"AuditChecklist": ["Has the organization set the scope of the management system to include key assets that may affect core services and personal information processing?","If there are exceptions within the defined scope, are clear reasons documented, and are consultations with relevant stakeholders and approvals from responsible parties recorded and managed?","Is the organization maintaining documentation that includes the major services, operational status, and systems, allowing for clear verification of the scope of the information protection and personal information protection management system?"],"NonComplianceCases": ["Case 1: The development and test systems, external staff, PCs, and test devices related to the development work for information systems and personal information processing systems were omitted from the management system's scope.","Case 2: Key organizations (personnel) in departments and business units that play critical roles in decision-making for services or businesses within the scope of the information protection and personal information protection management system were not included in the certification scope.","Case 3: The development and test systems, developer PCs, test devices, and development organizations related to the development work for information systems and personal information processing systems were omitted from the management system's scope."],"RelatedRegulations": []}],"description": "The organization must set the scope of the management system by considering its core services and the current state of personal information processing, and document the related services, personal information processing tasks, organizations, assets, and physical locations.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.5": {"name": "Policy Establishment","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.1.5 Policy Establishment","Subdomain": "1.1. Management System","AuditEvidence": ["Information protection and personal information protection policies/guidelines/procedures (including records of new/revised versions)","Meeting minutes of stakeholder reviews of newly established/revised information protection and personal information protection policies/guidelines/procedures","Internal management plans for personal information","Notifications of new/revised information protection and personal information protection policies/guidelines (via groupware, intranet, etc.)","Minutes of the Information Protection and Personal Information Protection Committee"],"AuditChecklist": ["Has the organization established a top-level information protection and personal information protection policy that serves as the foundation for all information protection and personal information protection activities?","Has the organization established detailed guidelines, procedures, and manuals specifying the methods, processes, and frequencies required to implement the information protection and personal information protection policies?","Are the information protection and personal information protection policies and implementation documents approved by the CEO or by someone delegated by the CEO when newly established or revised?","Are the latest versions of the information protection and personal information protection policies and implementation documents provided to relevant employees in an easily understandable format?"],"NonComplianceCases": ["Case 1: Although internal regulations stipulate that revisions to the information protection and personal information protection policies must be approved by the Information Protection and Personal Information Protection Committee, recent revisions were made solely based on the approval of the CISO and CPO without presenting the revisions to the committee.","Case 2: The information protection and personal information protection policies and guidelines were recently revised, but these changes were not communicated to relevant departments and employees, leading some departments to continue operating based on outdated guidelines.","Case 3: The information protection and personal information protection policies and guidelines are managed solely by the security department and are not made available for employees to access through bulletin boards or documents."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "The organization must establish and document information protection and personal information protection policies and implementation documents, clearly stating the organization's information protection and personal information protection guidelines and direction. These policies and implementation documents must be approved by the executive management and communicated in an understandable form to employees and relevant parties.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.6": {"name": "Resource Allocation","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.1.6 Resource Allocation","Subdomain": "1.1. Management System","AuditEvidence": ["Annual action plan for information protection and personal information protection activities (including budget and personnel plans)","Reports on the results of information protection and personal information protection activities","Records of investments in information protection and personal information protection","Information protection and personal information protection organization chart"],"AuditChecklist": ["Has the organization secured personnel with expertise in the fields of information protection and personal information protection?","Has the organization evaluated and allocated the necessary resources, including budget and personnel, for the effective implementation and continuous operation of the information protection and personal information protection management system?","Has the organization established and implemented an annual detailed action plan for information protection and personal information protection, and conducted audits, analyses, and evaluations of the results?"],"NonComplianceCases": ["Case 1: The organization assembled an information protection and personal information protection team, but the team consisted only of personnel without expertise in information protection or IT, resulting in inadequate security staffing.","Case 2: The CEO failed to allocate sufficient resources, such as budget and security solutions, for implementing the technical and managerial safeguards required for personal information processing systems.","Case 3: After obtaining certification, the organization significantly reduced personnel and budget support, reassigned existing staff to other departments, and repurposed part of the budget for other uses."],"RelatedRegulations": []}],"description": "The CEO must allocate the necessary resources, including budget and personnel with expertise in the fields of information protection and personal information protection, for the effective implementation and continuous operation of the management system.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.2.1": {"name": "Identification of Information Assets","checks": {"macie_is_enabled": "PASS","resourceexplorer2_indexes_found": "PASS","config_recorder_all_regions_enabled": null,"organizations_account_part_of_organizations": null,"organizations_tags_policies_enabled_and_attached": null},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.2.1 Identification of Information Assets","Subdomain": "1.2. Risk Management","AuditEvidence": ["Information asset and personal information asset classification criteria","Information asset and personal information asset list (from asset management system screen)","Information asset and personal information security levels","Asset audit details","Risk analysis report (including asset identification)"],"AuditChecklist": ["Has the organization established classification criteria for information assets and identified all assets within the scope of the information protection and personal information protection management system, maintaining them in a list?","For the identified information assets, does the organization determine their importance by considering legal requirements and their impact on operations, and assign security levels?","Does the organization regularly review the status of information assets to keep the list up-to-date?"],"NonComplianceCases": ["Case 1: The list of assets within the scope of the information protection and personal information protection management system omits internal information leakage control systems, such as print security, document encryption, and USB media control, which are used to manage PCs handling important information and personal information.","Case 2: Personal information provided by third parties within the scope of the information protection and personal information protection management system has not been identified as an asset.","Case 3: The asset classification criteria in the internal guidelines and the classification criteria in the asset management register are inconsistent.","Case 4: Although on-premises assets have been identified, assets related to externally entrusted IT services (web hosting, server hosting, cloud, etc.) have been omitted (only for assets within the certification scope).","Case 5: The backup server storing unique identification information and other personal data has been classified with a low confidentiality rating, raising concerns about the reasonableness and reliability of the importance assessment."],"RelatedRegulations": []}],"description": "Organizations must establish classification criteria for information assets according to the characteristics of their operations, identify and classify all information assets within the scope of the management system, assess their importance, and maintain an up-to-date list.","checks_status": {"fail": 0,"pass": 2,"total": 5,"manual": 0}},"1.2.2": {"name": "Status and Flow Analysis","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.2.2 Status and Flow Analysis","Subdomain": "1.2. Risk Management","AuditEvidence": ["Information service status table","Information service workflow charts and process maps","Personal information processing status table (for ISMS-P certification)","Personal information flowcharts (for ISMS-P certification)"],"AuditChecklist": ["Has the organization identified and documented the status and workflows of information services across all areas of the management system?","Has the organization identified and documented the status of personal information processing within the scope of the management system, and mapped out personal information flows in flowcharts?","Does the organization regularly review procedures and workflows in response to changes in services, operations, and information assets, and keep the flowcharts and related documents up-to-date?"],"NonComplianceCases": ["Case 1: There are no documents outlining the workflows and procedures for major services within the scope of the management system.","Case 2: The personal information flowchart contains significant discrepancies from the actual personal information flow, or important personal information flows are missing.","Case 3: After the initial creation of the personal information flowchart, it has not been updated to reflect changes in the personal information flow."],"RelatedRegulations": []}],"description": "Organizations must analyze the status of information services and personal information processing across all areas of the management system, document the procedures and workflows, and review them regularly to maintain their accuracy.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.2.3": {"name": "Risk Assessment","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.2.3 Risk Assessment","Subdomain": "1.2. Risk Management","AuditEvidence": ["Risk management guidelines","Risk management manuals/guides","Risk management plan","Risk assessment report","Minutes of the Information Protection and Personal Information Protection Committee","Minutes of the Information Protection and Personal Information Protection Working Group","Information asset and personal information asset list","Information service and personal information flowcharts"],"AuditChecklist": ["Has the organization defined methods for identifying and assessing risks that could arise from various aspects, depending on the characteristics of the organization or service?","Does the organization annually develop a risk management plan that specifies the personnel, timeline, targets, methods, and budget for risk management activities?","Does the organization conduct regular or ad-hoc risk assessments at least once a year according to the risk management plan?","Has the organization established an acceptable target risk level and identified risks that exceed that level?","Are the results of risk identification and assessment reported to the executives?"],"NonComplianceCases": ["Case 1: The risk management plan specifies the risk assessment period and the targets and methods for risk management, but lacks details on the personnel and budget required for execution.","Case 2: While a risk assessment was conducted in the previous year, no risk assessment was conducted this year due to a lack of changes in assets.","Case 3: The organization conducted risk identification and assessment according to the risk management plan, but failed to assess the risks of important information assets within the scope, or failed to assess compliance with legal requirements related to information protection.","Case 4: The organization identified and assessed risks and set an acceptable target risk level according to the risk management plan, but did not report and seek approval from the executives (e.g., the Chief Information Security Officer).","Case 5: The method defined in the internal guidelines for risk assessment differs from the method actually used.","Case 6: The organization failed to identify and assess risks in the administrative and physical areas related to the information protection management system, and used only the results of technical vulnerability assessments as the risk assessment outcome.","Case 7: The organization set the acceptable target risk level (DoA) unreasonably high, designating risks that required action as acceptable risks, even though these risks were significant and required immediate or short-term action."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "Organizations must collect threat information by analyzing internal and external environments, select a risk assessment method suitable for the organization, conduct a risk assessment at least once a year across all areas of the management system, and manage acceptable risks with the approval of the executives.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.2.4": {"name": "Selection of Protective Measures","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.2.4 Selection of Protective Measures","Subdomain": "1.2. Risk Management","AuditEvidence": ["Information protection and personal information protection implementation plans/risk management plans","Information protection and personal information protection measures","Information protection and personal information protection master plan","Records of management reports and approvals for the information protection and personal information protection implementation plan"],"AuditChecklist": ["Has the organization developed risk treatment strategies (e.g., risk reduction, avoidance, transfer, acceptance) and selected protective measures to address the identified risks?","Has the organization established and reported to management an implementation plan that includes priority, schedule, responsible department/personnel, and budget for the protective measures?"],"NonComplianceCases": ["Case 1: Although an implementation plan for the information protection and personal information protection measures was established, it was not reported to the CISO and CPO.","Case 2: Some risk mitigation actions that were required were missing from the implementation plan.","Case 3: Mandatory legal requirements and risks with high security vulnerabilities were accepted without additional protective measures, instead of being addressed by a risk treatment plan.","Case 4: The rationale and validity for risk acceptance were insufficient, and some risks that could have been addressed immediately or in the short term due to urgency or ease of implementation were classified under long-term plans without specific justification."],"RelatedRegulations": []}],"description": "Based on the results of the risk assessment, appropriate protective measures must be selected to address the identified risks, and an implementation plan including the priority, schedule, responsible department/personnel, and budget for the protective measures must be established and approved by management.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.3.1": {"name": "Implementation of Protective Measures","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.3.1 Implementation of Protective Measures","Subdomain": "1.3. Operation of the Management System","AuditEvidence": ["Information protection and personal information protection implementation plans/risk management plans","Information protection and personal information protection measures","Information protection and personal information protection implementation progress reports (including reports to management)","Information protection and personal information protection implementation completion reports (including reports to management)","Information protection and personal information protection operating statements"],"AuditChecklist": ["Are the protective measures effectively implemented according to the implementation plan, and are the implementation results reported to management to verify their accuracy and effectiveness?","Has the organization created and documented detailed operating statements recording the implementation and operation status of protective measures according to the certification standards of the management system?"],"NonComplianceCases": ["Case 1: The results of the completion of the information protection and personal information protection measures were not reported to the CISO and CPO.","Case 2: The risk action implementation result report indicated 'completed,' but related risks still existed, or the accuracy and effectiveness of the implementation results were not verified.","Case 3: Risks classified as medium- to long-term in the previous year's information protection measures implementation plan were not implemented in the current year, or the results were not reviewed and verified by management.","Case 4: The actual operating status described in the operating statements did not match reality, and related documents, approvals, and meeting minutes mentioned in the operating statements did not exist.","Case 5: Although the implementation results were reported to the CISO and CPO, some incomplete items were not followed up with reasons and corrective actions."],"RelatedRegulations": []}],"description": "The selected protective measures must be effectively implemented according to the implementation plan, and management must verify the accuracy and effectiveness of the implementation results.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.3.2": {"name": "Sharing of Protective Measures","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.3.2 Sharing of Protective Measures","Subdomain": "1.3. Operation of the Management System","AuditEvidence": ["List of operating or implementing departments for each protective measure","Evidence of internal sharing of information protection and personal information protection plans (e.g., notices, training materials, shared documents)"],"AuditChecklist": ["Has the organization clearly identified the departments and personnel responsible for the operation or implementation of the protective measures?","Has the organization shared or provided training to the departments and personnel responsible for the operation or implementation of the protective measures?"],"NonComplianceCases": ["Case 1: Although protective measures were developed and implemented, the relevant information was not sufficiently shared or provided through training, so the departments or personnel responsible for the actual operation or implementation were unaware of the details."],"RelatedRegulations": []}],"description": "The departments and personnel responsible for the actual operation or implementation of the protective measures must be identified, and the related information must be shared and provided through training to ensure continuous operation.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.3.3": {"name": "Operation Status Management","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.3.3 Operation Status Management","Subdomain": "1.3. Operation of the Management System","AuditEvidence": ["Annual plan for information protection and personal information protection","Operation status report for information protection and personal information protection","Results of inspections on the implementation of information protection and personal information protection activities"],"AuditChecklist": ["Are information protection and personal information protection activities that need to be performed periodically or continuously for the operation of the management system documented and managed?","Does management periodically review the effectiveness of the operation of the management system and manage it accordingly?"],"NonComplianceCases": ["Case 1: Failure to document activities that are required to be performed periodically or continuously as part of the operation of the information protection and personal information protection management system.","Case 2: Although documentation of the operational status of the information protection and personal information protection management system has been completed, periodic reviews have not been conducted, resulting in the omission of some required monthly and quarterly activities, and some activities have not been verified for implementation."],"RelatedRegulations": ["Personal Information Protection Act, Article 31 (Designation of a Personal Information Protection Officer)","Information and Communications Network Act, Article 45-3 (Designation of a Chief Information Security Officer, etc.)"]}],"description": "According to the management system established by the organization, operational activities that must be performed continuously or periodically must be recorded and managed in a way that allows identification and tracking, and management must regularly review the effectiveness of operational activities and manage them accordingly.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.4.1": {"name": "Review of Legal Requirements Compliance","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.4.1 Review of Legal Requirements Compliance","Subdomain": "1.4. Inspection and Improvement of the Management System","AuditEvidence": ["Records of legal compliance reviews","Records of reviews and revisions of information protection and personal information protection policies and guidelines","Comparison tables of revised policies and guidelines","Internal sharing documents of legal revisions","Proof of personal information liability insurance or equivalent guarantees (e.g., cyber insurance contracts)","Information protection disclosure records"],"AuditChecklist": ["Is the organization regularly identifying and maintaining up-to-date legal requirements related to information protection and personal information protection?","Is the organization conducting regular reviews of compliance with legal requirements at least once a year?"],"NonComplianceCases": ["Case 1: Although the Information and Communications Network Act and Personal Information Protection Act were recently revised, the organization did not review the impact of the changes on the organization, and as a result, the policy documents, implementation documents, and legal compliance checklists were not updated, leading to inconsistencies between the documents and the law.","Case 2: Although legal requirements that the organization must comply with were amended, the organization failed to conduct legal compliance reviews for an extended period.","Case 3: Inadequate legal compliance reviews resulted in numerous violations of the Personal Information Protection Act and other regulations.","Case 4: The organization was subject to the Personal Information Liability Compensation Guarantee system under the Personal Information Protection Act but failed to recognize this, resulting in non-compliance with insurance or reserve requirements. In cases where insurance was obtained, the organization failed to meet the minimum coverage requirements based on the number of users and revenue.","Case 5: Although the organization was required by law to disclose information protection status, it failed to do so within the legally mandated timeframe.","Case 6: The organization used a mobile app to receive personal location information from a location-based service provider, but failed to report its location-based service business.","Case 7: A foreign personal information controller without a domestic address or business office, whose personal information of domestic subjects stored and managed in the previous three months averaged over one million persons per day, failed to appoint a domestic representative in writing as required."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "The organization must regularly identify and reflect legal requirements related to information protection and personal information protection and continuously review whether compliance is being maintained.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.4.2": {"name": "Management System Audit","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.4.2 Management System Audit","Subdomain": "1.4. Inspection and Improvement of the Management System","AuditEvidence": ["Management system audit plan (internal audit plan, internal inspection plan)","Management system audit report","Minutes of the Information Protection and Personal Information Protection Committee"],"AuditChecklist": ["Has the organization established a management system audit plan that includes the criteria, scope, frequency, and qualifications for audit personnel to audit the management system's effectiveness in accordance with legal requirements and established policies?","Has the organization conducted audits at least once a year with personnel who have independence, objectivity, and expertise, and reported any identified issues to management?"],"NonComplianceCases": ["Case 1: The audit team included personnel from the IT department, which was also the subject of the audit, compromising the independence of the audit.","Case 2: Although a management system audit was conducted this year, the audit scope was limited to certain areas, failing to cover the full scope of the information protection and personal information protection management system.","Case 3: The management system audit team was composed solely of internal staff and external consultants who participated in the development of the management system, compromising the independence of the audit."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "The organization must audit its management system at least once a year with a team of personnel who possess independence and expertise, to ensure the system is operating effectively in accordance with internal policies and legal requirements, and report any identified issues to management.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.4.3": {"name": "Management System Improvement","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.4.3 Management System Improvement","Subdomain": "1.4. Management System Inspection and Improvement","AuditEvidence": ["Management system inspection result reports","Management system inspection action plans and implementation result reports","Preventive measures","Effectiveness measurement indicators and results (including reports to management)"],"AuditChecklist": ["Are the root causes of the issues identified during legal compliance reviews and management system inspections analyzed, and are preventive and improvement measures established and implemented?","Are there criteria and procedures in place to verify the accuracy and effectiveness of preventive and improvement results?"],"NonComplianceCases": ["Case 1: The same issues in the operation of the information protection and personal information protection management system, identified during internal inspections, are repeated each time.","Case 2: Although internal regulations require the analysis of root causes and the establishment of preventive measures for issues identified during internal inspections, recent internal inspections failed to include root cause analysis and preventive measures.","Case 3: Preventive measures for the issues in the management system were established, and key performance indicators (KPIs) were developed for periodic measurement, but the results were not reported to management for a long period.","Case 4: Action plans were not established or the completion of actions was not confirmed for issues identified during management system inspections."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "The root causes of the issues identified during legal compliance reviews and management system inspections must be analyzed, and preventive measures must be established and implemented. The management must confirm the accuracy and effectiveness of the improvement results.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.1.1": {"name": "Policy Maintenance","checks": {},"status": "PASS","attributes": [{"Domain": "2. Control Measures Requirements","Section": "2.1.1 Policy Maintenance","Subdomain": "2.1. Policies, Organization, and Asset Management","AuditEvidence": ["Information protection and personal information protection policies and implementation documents (e.g., guidelines, procedures, manuals)","Results of regular and ad hoc validity reviews of policies and guidelines","Meeting minutes and circulation records with relevant departments regarding policies and guidelines","Revision history of policies and guidelines"],"AuditChecklist": ["Has the organization established and implemented a procedure for regularly reviewing the validity of information protection and personal information protection policies and implementation documents?","When there are significant changes in the internal and external environment, are the impacts on information protection and personal information protection policies and implementation documents reviewed and revised as necessary?","Are stakeholders consulted when revising information protection and personal information protection policies and implementation documents?","Is there a system in place to track the revision history of information protection and personal information protection policies and implementation documents?"],"NonComplianceCases": ["Case 1: There is inconsistency between password setting rules in guidelines and procedures.","Case 2: Information protection activities (e.g., training, encryption, backup) have different targets, frequencies, levels, and methods described in internal regulations, guidelines, and procedures, leading to inconsistency.","Case 3: A new database access control solution was introduced to effectively record and manage access and operation logs for the database, but internal security guidelines such as those for security systems and database security management have not been updated to reflect these new controls.","Case 4: Although the personal information protection policy was revised, the policy implementation date was not specified, and information such as the author, creation date, and approval date were missing from the relevant policy.","Case 5: Although significant changes occurred in laws and regulations related to personal information protection, these changes were not reviewed or reflected in the personal information protection policy and implementation documents."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "Information protection and personal information protection policies and implementation documents must be periodically reviewed and, if necessary, revised in response to changes in laws and regulations, policies of higher organizations and related agencies, and changes in the internal and external environment. These changes must be documented and tracked.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.1.2": {"name": "Organization Maintenance","checks": {},"status": "PASS","attributes": [{"Domain": "2. Control Measures Requirements","Section": "2.1.2 Organization Maintenance","Subdomain": "2.1. Policies, Organization, and Asset Management","AuditEvidence": ["Information protection and personal information protection organization chart","Job descriptions for the information protection and personal information protection organization","Assignment tables for information protection and personal information protection roles","Information protection and personal information protection policies/guidelines and internal management plans","Information protection and personal information protection communication management plans","Records of communication activities (e.g., monthly/weekly reports, internal notices)","Communication channels (e.g., information protection portal, bulletin boards)"],"AuditChecklist": ["Are the roles and responsibilities of those responsible for and involved in information protection and personal information protection clearly defined?","Has the organization established a system for evaluating the activities of those responsible for and involved in information protection and personal information protection?","Has the organization established and implemented systems and procedures for communication between the information protection and personal information protection organization and its members?"],"NonComplianceCases": ["Case 1: Although the roles and responsibilities of the CISO, CPO, and related personnel are defined in internal guidelines and job descriptions, they do not align with the actual operating status.","Case 2: There are no goals, criteria, or performance indicators in place for the periodic evaluation of the activities of the CISO and related personnel.","Case 3: Although internal guidelines require departments to set KPIs related to information protection for the information protection officers in each department to be reflected in performance evaluations, no information protection-related KPIs were set for any of the departmental information protection officers.","Case 4: Although the CISO and CPO are designated, the roles and responsibilities required by law are not specifically defined in internal guidelines or job descriptions."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures), Article 31 (Designation of a Personal Information Protection Officer)","Information and Communications Network Act, Article 45-3 (Designation of a Chief Information Security Officer, etc.)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "Roles and responsibilities related to information protection and personal information protection must be assigned to all members of the organization, and systems must be established for evaluating these activities and for communication between members and departments.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.1.3": {"name": "Management of Information Assets","checks": {"macie_is_enabled": "PASS","resourceexplorer2_indexes_found": "PASS","config_recorder_all_regions_enabled": null,"account_maintain_current_contact_details": null,"organizations_account_part_of_organizations": null,"organizations_tags_policies_enabled_and_attached": null,"account_security_contact_information_is_registered": null,"account_security_questions_are_registered_in_the_aws_account": null,"account_maintain_different_contact_details_to_security_billing_and_operations": null},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.1.3 Management of Information Assets","Subdomain": "2.1. Policy, Organization, Asset Management","AuditEvidence": ["List of information assets (designation of responsible persons and managers)","Handling procedures for information assets (documents, information systems, etc.)","Information asset management system screen","Security classification indicators for information assets"],"AuditChecklist": ["Are handling procedures (creation, introduction, storage, use, disposal) and protection measures defined and implemented according to the security classification of information assets?","Have responsible persons and managers been designated for identified information assets?"],"NonComplianceCases": ["Case 1: Although internal guidelines require security classification to be indicated on documents, this has not been followed.","Case 2: Responsible persons and managers for information assets have not been identified, or the asset list has not been updated, leading to changes in responsible personnel due to resignations, transfers, etc., not being reflected.","Case 3: Although security classifications were assigned to identified information assets after evaluating their importance, handling procedures based on the security classification were not defined."],"RelatedRegulations": []}],"description": "The procedures and protection measures for handling information assets according to their purpose and importance must be established and implemented, and the responsibilities for each asset must be clearly defined and managed.","checks_status": {"fail": 0,"pass": 2,"total": 9,"manual": 0}},"2.2.1": {"name": "Designation and Management of Key Personnel","checks": {"iam_support_role_created": null,"organizations_delegated_administrators": null,"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.2.1 Designation and Management of Key Personnel","Subdomain": "2.2. Personnel Security","AuditEvidence": ["Criteria for key duties","List of key personnel","List of personal information handlers","Account and authority management ledger for key information systems and personal information processing systems","Management status of key personnel (e.g., training results, security pledges)"],"AuditChecklist": ["Are the criteria for key duties, such as handling personal information and important information or accessing key systems, clearly defined?","Are employees and external personnel performing key duties designated as key personnel, and is the list kept up-to-date?","Are personnel handling personal information designated as personal information handlers, and is the list kept up-to-date?","Is the designation of key personnel and personal information handlers minimized based on business needs, and are management plans established and implemented?"],"NonComplianceCases": ["Case 1: Although a list of key personnel (e.g., personal information handlers, secret information managers) has been created, some employees who handle large volumes of personal information (e.g., DBAs, DLP managers) were omitted.","Case 2: Although the list of key personnel and personal information handlers is being managed, it has not been updated, including resigned employees and newly hired personnel.","Case 3: Personal information handler privileges were granted collectively to entire departments, leading to personnel without the need to handle personal information being excessively designated as personal information handlers.","Case 4: Although internal guidelines require approval from the security team and the signing of security pledges when granting key personnel privileges, many key personnel were registered without following this process."],"RelatedRegulations": ["Personal Information Protection Act, Article 28 (Supervision of Personal Information Handlers), Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "Criteria and management plans for key duties, such as handling personal information and important information or accessing key systems, must be established, and the number of key personnel must be minimized and their list kept up-to-date.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"2.2.2": {"name": "Separation of Duties","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.2.2 Separation of Duties","Subdomain": "2.2. Personnel Security","AuditEvidence": ["Guidelines on the separation of duties (e.g., personnel security guidelines)","Job descriptions (e.g., system operation/management, development/operation)","Status of supplementary controls when duties are not separated"],"AuditChecklist": ["Are criteria for the separation of duties established and applied to prevent potential harm from the misuse or abuse of authority?","If separation of duties is difficult, have supplementary controls such as mutual review between personnel, regular monitoring and approval of changes by senior management, and ensuring accountability been established?"],"NonComplianceCases": ["Case 1: Although the organization has sufficient size and personnel to enable separation of duties, the established internal separation of duties criteria were not followed due to operational convenience.","Case 2: Although the organization received approval from senior management to combine development and operation duties due to the organization's characteristics, supplementary control measures such as mutual review between personnel, regular monitoring and review of changes by senior management, and ensuring accountability were not established."],"RelatedRegulations": []}],"description": "Criteria for the separation of duties must be established and applied to prevent potential harm from the misuse or abuse of authority. If separation of duties is unavoidable, supplementary measures must be established and implemented.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.2.3": {"name": "Security Pledge","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.2.3 Security Pledge","Subdomain": "2.2. Human Security","AuditEvidence": ["Security and personal information protection pledge (for employees and external personnel)","Confidentiality agreement (for resigned employees)"],"AuditChecklist": ["When hiring new personnel, is there a signed security and personal information protection agreement that specifies their responsibilities?","If temporary or external personnel are granted access to information assets, is there a signed agreement outlining their responsibilities for information protection and confidentiality?","Upon the resignation of an employee, is a separate confidentiality agreement obtained?","Are security, personal information protection, and confidentiality agreements stored safely and managed in a way that they can be easily retrieved when necessary?"],"NonComplianceCases": ["Case 1: While it is stipulated that new hires must sign a security pledge, some recently hired employees have not completed the pledge.","Case 2: Although employees sign a security pledge, external personnel with direct access to information systems have not signed such an agreement.","Case 3: Submitted security and personal information protection pledges are poorly managed, with documents left accessible on desks where unauthorized personnel can access them.","Case 4: Although personal information handlers have signed security pledges, the content only covers confidentiality and does not include specific responsibilities related to personal information protection."],"RelatedRegulations": []}],"description": "Employees, temporary staff, or external personnel handling information assets or granted access must sign a security and confidentiality agreement in accordance with internal policies.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.2.4": {"name": "Awareness and Training","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.2.4 Awareness and Training","Subdomain": "2.2. Human Security","AuditEvidence": ["Information protection and personal information protection training plan","Training result report","General and job-specific training materials","List of training attendees"],"AuditChecklist": ["Is an annual training plan approved by management, detailing the timing, duration, target audience, content, and method of information protection and personal information protection training?","Are all employees and external personnel within the scope of the management system provided with regular training at least once per year, and are additional training sessions provided when there are significant changes in relevant laws and regulations?","Is information protection and personal information protection training provided to new hires and external personnel before they begin their duties?","Are IT, information protection, and personal information protection staff receiving specialized training to enhance their job-specific expertise?","Are training records maintained, and is the effectiveness of the training evaluated and reflected in future training plans?"],"NonComplianceCases": ["Case 1: Although an annual information protection and personal information protection training plan was established and implemented last year, no such plan was established for the current year without a valid reason.","Case 2: The annual information protection and personal information protection training plan includes the frequency and target audience but lacks details such as schedule, content, and method.","Case 3: Although the annual training plan includes general personal information awareness training for all employees, it does not include job-specific training for those responsible for personal information protection, such as the personal information protection officer.","Case 4: Upon reviewing the training plan and result reports, it was found that certain external contractors (e.g., cleaning staff and security guards who have access to critical facilities within the certification scope) were not included in the training.","Case 5: Although information protection and personal information protection training was conducted, some records (e.g., training materials, attendance lists, evaluation surveys, result reports) were not retained.","Case 6: There is no system in place to identify employees who did not complete the required training or to provide make-up sessions for them (e.g., additional training, online courses)."],"RelatedRegulations": ["Personal Information Protection Act, Article 26 (Limitation on the Processing of Personal Information by Outsourcing), Article 28 (Supervision of Personal Information Handlers), Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "Organizations must establish and operate an annual awareness and training plan to ensure that employees and related external personnel understand the organization's management system and policies and acquire the necessary job-specific expertise. The effectiveness of this plan must be evaluated and reflected in future plans.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.2.5": {"name": "Management of Resignation and Job Changes","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.2.5 Management of Resignation and Job Changes","Subdomain": "2.2. Human Security","AuditEvidence": ["Procedures for resignation and job changes","Asset (account) return management ledger upon resignation","Security checklists and inspection records for resigned employees"],"AuditChecklist": ["Are personnel changes (e.g., resignation, job changes, department transfers, leave of absence) shared among HR, information protection, personal information protection, and IT system operations departments?","Are procedures in place and implemented to promptly return information assets, revoke or adjust access rights, and confirm results when an employee (including temporary staff and external contractors) resigns or changes roles?"],"NonComplianceCases": ["Case 1: Accounts and access rights for personnel no longer handling personal information due to job changes remain active in the personal information processing system.","Case 2: No records of asset returns or access rights revocation procedures were found for recently resigned key personnel and personal information handlers.","Case 3: While asset returns are properly managed for resigned employees, the security check and resignation confirmation forms required by HR regulations are not being completed.","Case 4: Although access rights to personal information processing systems were revoked promptly upon the resignation of personal information handlers, access rights to systems like physical access control and VPN were not revoked in a timely manner."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights)"]}],"description": "Procedures must be established and managed for the return of assets, the revocation or adjustment of accounts and access rights, and confirmation of results when there is a resignation, job change, or leave of absence, involving departments such as HR, information protection, personal information protection, and IT.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.2.6": {"name": "Actions in Case of Security Violations","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.2.6 Actions in Case of Security Violations","Subdomain": "2.2. Human Security","AuditEvidence": ["HR regulations (disciplinary measures for violations of information protection and personal information protection regulations)","Records of disciplinary actions for violations of information protection and personal information protection guidelines","Incident case studies (company-wide notices, training materials)"],"AuditChecklist": ["Has the organization established disciplinary measures for employees and relevant external parties in case of violations of information protection and personal information protection responsibilities and obligations under laws, regulations, and internal policies?","When violations of information protection and personal information protection are detected, are actions taken in accordance with internal procedures?"],"NonComplianceCases": ["Case 1: No disciplinary measures or procedures are included in internal regulations for handling violations of information protection and personal information protection regulations.","Case 2: Although warning messages are sent to those who violate policies detected by security systems (e.g., DLP, database access control system, internal information leakage control system), follow-up actions such as explanations, additional investigations, or disciplinary actions are not carried out in accordance with internal regulations."],"RelatedRegulations": []}],"description": "In the event that employees or relevant external parties violate laws, regulations, or internal policies, the organization must establish and implement procedures to take appropriate actions.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.3.1": {"name": "Management of External Parties","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.3.1 Management of External Parties","Subdomain": "2.3. External Security","AuditEvidence": ["List of outsourced services and external facilities/services","Outsourcing contracts","Risk analysis reports and protective measures","Outsourcing security management guidelines, checklists, etc."],"AuditChecklist": ["Has the organization identified the status of outsourcing and the use of external facilities and services within the scope of the management system?","Has the organization identified the legal requirements and risks associated with outsourcing and the use of external facilities and services, and established appropriate protective measures?"],"NonComplianceCases": ["Case 1: Although the organization manages a list of outsourced services and external facilities/services as required by internal regulations, the list is outdated and does not reflect changes made to vendors several months ago.","Case 2: The organization has migrated some personal information processing systems to external cloud services within the scope of the management system, but no identification or risk assessment has been performed."],"RelatedRegulations": ["Personal Information Protection Act, Article 26 (Restrictions on the Processing of Personal Information by Outsourcing)","Information and Communications Network Act, Article 50-3 (Entrustment of the Transmission of Commercial Information for Profit)"]}],"description": "When outsourcing part of the work (e.g., handling personal information, information protection, operating or developing information systems) or using external facilities or services (e.g., data centers, cloud services, application services), the organization must identify the current status, understand the legal requirements and risks arising from external organizations or services, and establish appropriate protective measures.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.3.2": {"name": "Security in Contracts with External Parties","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.3.2 Security in Contracts with External Parties","Subdomain": "2.3. External Security","AuditEvidence": ["Outsourcing contracts","Information protection and personal information protection agreements (agreements, annexes)","Internal guidelines on outsourcing","RFPs (Requests for Proposals), evaluation forms related to the selection of outsourcing vendors"],"AuditChecklist": ["When selecting external services or outsourcing vendors related to the handling of important information and personal information, does the organization follow procedures to consider the vendors' capabilities in information protection and personal information protection?","Has the organization identified the information protection and personal information protection requirements associated with the use of external services and outsourcing, and specified them in contracts or agreements?","When outsourcing the development of information systems and personal information processing systems, has the organization specified the information protection and personal information protection requirements that must be followed during development in the contract?"],"NonComplianceCases": ["Case 1: No outsourcing contract exists for external vendors performing IT operations, development, or personal information processing tasks.","Case 2: The outsourcing contract with an external vendor handling personal information does not include some items required by the Personal Information Protection Act (e.g., management and supervision provisions).","Case 3: Although infrastructure operation and part of personal information processing tasks are outsourced to external vendors, the contract does not specify security requirements related to the nature of the outsourced work, but only includes general provisions on confidentiality and liability for damages."],"RelatedRegulations": ["Personal Information Protection Act, Article 26 (Restrictions on the Processing of Personal Information by Outsourcing)"]}],"description": "When using external services or outsourcing work to external parties, the organization must identify the information protection and personal information protection requirements and specify them in contracts or agreements.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.3.3": {"name": "External Party Security Implementation Management","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.3.3 External Party Security Implementation Management","Subdomain": "2.3. External Party Security","AuditEvidence": ["Security inspection results for external parties and contractors","Training details for external parties and contractors (training outcomes, attendee list, training materials, etc.)","Personal information outsourcing contract","Evidence of consent for re-outsourcing of personal information processing tasks"],"AuditChecklist": ["Are periodic inspections or audits conducted to ensure external parties comply with information protection and personal information protection requirements specified in contracts, agreements, and internal policies?","When issues are identified during inspections or audits of external parties, are improvement plans established and implemented?","If a contractor entrusted with personal information processing re-outsources related tasks to a third party, does the contractor obtain the principal's consent?"],"NonComplianceCases": ["Case 1: Failure to regularly conduct security inspections of external contractors who perform IT development and operations tasks on-site.","Case 2: Sending a notification to contractors entrusted with personal information processing to conduct security training, but failing to verify whether the training has been conducted.","Case 3: Allowing contractors to perform their own security inspections and report the results, without a verification process to ensure the inspections were properly conducted, thus undermining the reliability of the inspection results.","Case 4: Allowing contractors to re-outsource personal information processing tasks to a third party without the principal's consent.","Case 5: Failure to supervise contractors entrusted with transmitting commercial information for profit."],"RelatedRegulations": ["Personal Information Protection Act, Article 26 (Restrictions on the Outsourcing of Personal Information Processing)","Information and Communications Network Act, Article 50-3 (Outsourcing of the Transmission of Commercial Information for Profit)"]}],"description": "Security measures specified in contracts, agreements, and internal policies must be regularly inspected or audited to ensure external parties comply with information protection and personal information protection requirements.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.3.4": {"name": "Security for External Party Contract Changes and Expiry","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.3.4 Security for External Party Contract Changes and Expiry","Subdomain": "2.3. External Party Security","AuditEvidence": ["Information protection and personal information protection agreements","Confidentiality agreements","Information and personal information destruction agreements","Internal policies and guidelines related to the termination of external party contracts"],"AuditChecklist": ["Has the organization established and implemented security measures to ensure the return of information assets, deletion of information system access accounts, and the acquisition of confidentiality agreements in accordance with official procedures when an external party contract expires, a task is completed, or there is a personnel change?","When an external party contract expires, has the organization established and implemented procedures to confirm whether the external party holds any sensitive or personal information related to the outsourced task, and to retrieve or destroy such information?"],"NonComplianceCases": ["Case 1: Failure to delete accounts and permissions for external parties after their contract has expired, allowing access to certain information systems.","Case 2: During an outsourcing project, failure to take appropriate measures for some contractors who were replaced or whose contracts expired, including failing to obtain security agreements as required by internal regulations.","Case 3: After terminating a contract with a contractor entrusted with personal information processing, failure to verify whether the contractor destroyed any personal information they held."],"RelatedRegulations": ["Personal Information Protection Act, Article 26 (Restrictions on the Outsourcing of Personal Information Processing)","Information and Communications Network Act, Article 50-3 (Outsourcing of the Transmission of Commercial Information for Profit)"]}],"description": "When an external party contract expires, the task is completed, or there is a personnel change, security measures such as returning provided information assets, deleting information system access accounts, destroying sensitive information, and obtaining confidentiality agreements for acquired information must be implemented.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.1": {"name": "Designation of Protected Zones","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.4.1 Designation of Protected Zones","Subdomain": "2.4. Physical Security","AuditEvidence": ["Physical security guidelines (criteria for designating protected zones)","List of designated protected zones","Protected zone signage","List of protection measures for each zone"],"AuditChecklist": ["Has the organization established criteria for designating physical protection zones such as controlled areas, restricted areas, and reception areas to protect personal and sensitive information, documents, storage media, key facilities, and systems from physical and environmental threats?","Has the organization designated physical protection zones in accordance with the criteria and established and implemented protection measures for each zone?"],"NonComplianceCases": ["Case 1: Although internal physical security guidelines state that areas where personal information is stored and processed must be designated as controlled zones, certain document storage rooms containing membership application forms were omitted from the list of controlled zones.","Case 2: Internal physical security guidelines require that controlled zones be marked with specific signs, but some controlled zones do not have the required signage."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 10 (Physical Safety Measures)"]}],"description": "To protect personal and sensitive information, documents, storage media, key facilities, and systems from physical and environmental threats, physical protection zones such as controlled areas, restricted areas, and reception areas must be designated, and protection measures for each zone must be established and implemented.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.2": {"name": "Access Control","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protective Measures Requirements","Section": "2.4.2 Access Control","Subdomain": "2.4. Physical Security","AuditEvidence": ["Access logbook and entry logs","Access registration application form and approval records","Entry record review report","Access control system management screen (status of registered personnel, etc.)"],"AuditChecklist": ["Is access to protected areas controlled so that only authorized personnel are allowed to enter according to access procedures?","Are entry records for internal and external personnel for each protected area retained for a certain period, and are entry records and access permissions reviewed periodically?"],"NonComplianceCases": ["Case 1: Although control areas are defined, protective measures are established, and employees with access are managed, the entry records are not reviewed periodically, resulting in many inactive personnel (due to retirement, transfer, etc.) having long periods of no entry.","Case 2: Although access control devices are installed in controlled areas such as data centers and document storage rooms, they are left open for extended periods without valid reasons or approval.","Case 3: Some external partner employees are excessively granted all-area access cards for unrestricted entry."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 10 (Physical Safety Measures)"]}],"description": "Access to protected areas must be restricted to authorized personnel only, and entry and access logs should be reviewed periodically to ensure accountability.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.3": {"name": "Information System Protection","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protective Measures Requirements","Section": "2.4.3 Information System Protection","Subdomain": "2.4. Physical Security","AuditEvidence": ["Data processing facility diagram","Information system layout","Asset list"],"AuditChecklist": ["Are information systems placed in separated locations based on their importance, usage, and characteristics?","Are there measures in place to easily verify the actual physical location of the information systems?","Are power and communication cables protected from physical damage and electrical interference from external sources?"],"NonComplianceCases": ["Case 1: The system layout is not updated to reflect the latest changes, making it difficult to quickly identify the information system that has experienced a failure.","Case 2: Many cables are tangled and not properly organized on the server room floor or in racks, increasing the risk of failure due to electrical interference, damage, leakage, or negligence."],"RelatedRegulations": []}],"description": "Information systems should be arranged considering their importance and characteristics to reduce environmental threats, harmful factors, and unauthorized access, and communication and power cables should be protected from damage.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.4": {"name": "Operation of Protective Facilities","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protective Measures Requirements","Section": "2.4.4 Operation of Protective Facilities","Subdomain": "2.4. Physical Security","AuditEvidence": ["Physical security guidelines (related to protective facilities)","Data center facility status and inspection checklist","IDC outsourcing contract, SLA, etc."],"AuditChecklist": ["Are necessary facilities established and operational procedures set up based on the importance and characteristics of each protected area to prevent disasters such as fire, flood, and power failure caused by human error or natural disasters?","If operating outsourced integrated data centers (IDC), are physical security requirements included in the contract, and is the operational status periodically reviewed?"],"NonComplianceCases": ["Case 1: In some protected areas, such as the main office data center, the required protective facilities specified in internal guidelines are not installed.","Case 2: Although protective facilities such as UPS and fire suppression systems are in place in the data center, operational and inspection standards for the related facilities are not established.","Case 3: Although temperature and humidity control devices were installed in the data center according to operational guidelines, insufficient capacity means that the standard temperature and humidity levels are not maintained, increasing the risk of failure."],"RelatedRegulations": ["Information and Communications Network Act, Article 46 (Protection of Integrated Data Centers)","Guidelines for the Protection of Integrated Data Centers","Fire Facility Installation and Management Act, Article 12 (Management of Fire Protection Facilities in Specific Fire Protection Objects), Article 16 (Management of Evacuation Facilities, Fire Zones, and Fire Protection Facilities)"]}],"description": "Based on the importance and characteristics of the information systems located in protected areas, protective facilities such as temperature and humidity control, fire detection, firefighting equipment, leak detection, UPS, emergency generators, and dual power lines should be established and operated according to operational procedures.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.5": {"name": "Operations in Secure Zones","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.4.5 Operations in Secure Zones","Subdomain": "2.4. Physical Security","AuditEvidence": ["Operation request forms, operation logs","Entry logs for controlled areas","Records of review of entry and operation logs for controlled areas"],"AuditChecklist": ["When operations within secure zones, such as the introduction and maintenance of information systems, are required, are formal procedures for application and execution of such operations established and implemented?","Are the records of operations within secure zones periodically reviewed to confirm that the operations were carried out in accordance with the control procedures?"],"NonComplianceCases": ["Case 1: The entry log of the data center shows the presence of external maintenance personnel, but there is no record of an operation request or approval for work within the secure zone (i.e., entry and work in the secure zone were carried out without an operation request as required by internal regulations).","Case 2: Although internal regulations state that the records of operations within secure zones must be reviewed at least once per quarter, the review of such records has not been conducted for a long period without a valid reason."],"RelatedRegulations": []}],"description": "Procedures to prevent unauthorized actions and abuse of privileges within secure zones must be established and implemented, and the records of operations should be periodically reviewed.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.6": {"name": "Device Control for Inbound and Outbound","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.4.6 Device Control for Inbound and Outbound","Subdomain": "2.4. Physical Security","AuditEvidence": ["Inbound and outbound application forms for secure zones","Inbound and outbound management logs","Results of the review of inbound and outbound records"],"AuditChecklist": ["Are control procedures established and implemented to prevent security incidents such as information leakage and malware infection when information systems, mobile devices, storage media, etc., are brought into or taken out of secure zones?","Are records maintained and managed in accordance with the inbound and outbound control procedures, and is the compliance with the procedures periodically checked by reviewing the history of inbound and outbound activities?"],"NonComplianceCases": ["Case 1: Although control procedures for the inbound and outbound of mobile computing devices are established, there is no control over the movement of such devices within the controlled area, allowing both internal and external personnel with access to the controlled area to use mobile computing devices without restriction.","Case 2: Although internal guidelines state that inbound and outbound details of IT equipment must be recorded in the operation plan and signed by the person responsible for management, many signatures of responsible managers are missing from the records."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 10 (Physical Safety Measures)"]}],"description": "Procedures to control the inbound and outbound movement of information systems, mobile devices, storage media, etc., within secure zones must be established, implemented, and periodically reviewed.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.7": {"name": "Work Environment Security","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.4.7 Work Environment Security","Subdomain": "2.4. Physical Security","AuditEvidence": ["Security inspection reports for offices and shared spaces","Security inspection checklists for offices and shared spaces","Actions taken for non-compliance (e.g., training, rewards and penalties)","Current status of protection measures for printed and copied materials"],"AuditChecklist": ["Are protection measures established and implemented for shared facilities and office equipment such as document storage, shared PCs, multifunction printers, file servers, etc.?","Are protection measures established and implemented to prevent the exposure or leakage of personal and sensitive information through individual work environments such as work PCs, desks, drawers, etc.?","Are appropriate protection measures in place to ensure the safe handling of printed or copied materials containing personal information, such as paper documents?","Is compliance with information protection requirements in both individual and shared work environments periodically reviewed?"],"NonComplianceCases": ["Case 1: Although the internal management plan for personal information specifies that regular security inspections (e.g., clean desk policies) must be conducted, no such inspections have been carried out.","Case 2: Documents containing personal information, such as membership application forms, are stored in an office cabinet without a lock.","Case 3: Employee computers do not have screen savers or passwords set, and important documents have been left on vacationing employees' desks for an extended period.","Case 4: No protection measures are in place for shared PCs installed in shared office spaces such as meeting rooms, resulting in personal information files being stored unencrypted, or security updates not applied, or antivirus software not installed, leaving the systems vulnerable."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 10 (Physical Safety Measures), Article 12 (Safety Measures for Printing and Copying)"]}],"description": "Protection measures such as clean desk policies and regular inspections must be established and implemented to prevent unauthorized exposure or leakage of personal and sensitive information through shared office equipment (e.g., document storage, shared PCs, multifunction printers, file servers) and individual work environments (e.g., work PCs, desks).","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.5.1": {"name": "User Account Management","checks": {"iam_user_accesskey_unused": null,"iam_securityaudit_role_created": null,"iam_user_console_access_unused": null,"iam_policy_no_full_access_to_kms": null,"iam_role_administratoraccess_policy": null,"iam_user_administrator_access_policy": null,"organizations_scp_check_deny_regions": null,"iam_group_administrator_access_policy": null,"iam_policy_allows_privilege_escalation": null,"iam_inline_policy_no_full_access_to_kms": null,"iam_policy_no_full_access_to_cloudtrail": null,"iam_policy_attached_only_to_group_or_roles": null,"cognito_user_pool_self_registration_disabled": null,"iam_role_cross_account_readonlyaccess_policy": null,"iam_inline_policy_allows_privilege_escalation": null,"iam_inline_policy_no_administrative_privileges": null,"iam_inline_policy_no_full_access_to_cloudtrail": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_role_cross_service_confused_deputy_prevention": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"iam_customer_unattached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.5.1 User Account Management","Subdomain": "2.5. Authentication and Access Management","AuditEvidence": ["User account and access request forms","User account and access management log or screen","Access classification table for information systems and personal information processing systems","Lists of users, administrators, and personal information handlers for each information system and personal information processing system"],"AuditChecklist": ["Has the organization established and implemented formal procedures for registering, changing, and deleting user accounts and access rights to information systems, personal information, and critical information?","When creating and registering user accounts and access rights to information systems, personal information, and critical information, is access limited to the minimum necessary for each job based on the job-specific access classification system?","When granting users accounts and access rights, are they made fully aware that they are responsible for the security of those accounts?"],"NonComplianceCases": ["Case 1: User registration, termination, and approval procedures for accounts and permissions for users and personal information handlers were processed through verbal requests, email, etc., without proper approval and handling records.","Case 2: A personal information handler shared their account with an unauthorized individual for backup purposes during vacations, business trips, or other absences without going through official procedures.","Case 3: Users of information systems or personal information processing systems were granted excessive permissions, allowing access to unnecessary information or personal data."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights)"]}],"description": "To control unauthorized access to information systems, personal information, and critical information, organizations must establish and implement procedures for user registration, termination, and granting, changing, or revoking access rights, ensuring that access rights are granted only to the minimum necessary for work purposes. Additionally, when registering or granting user rights, it must be made clear to users that they are responsible for the security of their accounts.","checks_status": {"fail": 0,"pass": 0,"total": 22,"manual": 0}},"2.5.2": {"name": "User Identification","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.5.2 User Identification","Subdomain": "2.5. Authentication and Access Management","AuditEvidence": ["Login screen for information systems and personal information processing systems","Lists of administrators, users, and personal information handlers for information systems and personal information processing systems","Records of approvals for exceptions"],"AuditChecklist": ["Are unique identifiers assigned to users and personal information handlers in information systems and personal information processing systems, and is the use of easily guessable identifiers restricted?","If the same identifier is shared by multiple users for unavoidable reasons, has the justification been reviewed and have supplementary measures such as approval from the responsible party been established?"],"NonComplianceCases": ["Case 1: The account status of information systems (servers, networks, firewalls, DBMS, etc.) shows that default administrator accounts provided by the manufacturer are still in use, despite being technically modifiable.","Case 2: Developers are sharing personal information processing system accounts for common use without any justification or approval from responsible parties.","Case 3: External personnel maintaining information systems are using operational accounts like personal accounts without going through the required approval procedures."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights)"]}],"description": "User accounts must be assigned unique identifiers that distinguish each user individually, and the use of easily guessable identifiers must be restricted. If the same identifier is shared by multiple users, the reason and justification must be reviewed, supplementary measures such as approval from a responsible party must be established, and accountability must be ensured.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.5.3": {"name": "User Authentication","checks": {"iam_root_mfa_enabled": null,"iam_user_accesskey_unused": null,"iam_check_saml_providers_sts": null,"cognito_user_pool_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_hardware_mfa_enabled": null,"iam_user_two_active_access_key": null,"iam_administrator_access_with_mfa": null,"iam_user_mfa_enabled_console_access": null,"iam_user_with_temporary_credentials": null,"apigatewayv2_api_authorizers_enabled": "FAIL","iam_user_no_setup_initial_access_key": null,"apigateway_restapi_authorizers_enabled": "PASS","rds_cluster_iam_authentication_enabled": "FAIL","rds_instance_iam_authentication_enabled": "FAIL","kafka_cluster_unrestricted_access_disabled": null,"cognito_identity_pool_guest_access_disabled": "FAIL","cognito_user_pool_advanced_security_enabled": null,"cognito_user_pool_self_registration_disabled": null,"directoryservice_supported_mfa_radius_enabled": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cognito_user_pool_client_token_revocation_enabled": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cognito_user_pool_client_prevent_user_existence_errors": null,"opensearch_service_domains_internal_user_database_enabled": null,"cognito_user_pool_blocks_potential_malicious_sign_in_attempts": null,"opensearch_service_domains_use_cognito_authentication_for_kibana": null,"cognito_user_pool_blocks_compromised_credentials_sign_in_attempts": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.5.3 User Authentication","Subdomain": "2.5. Authentication and Authorization Management","AuditEvidence": ["Login screen for information systems and personal information processing systems","Login attempt limitation setting screen","Login failure message screen","Procedures for external access (e.g., external access request forms, list of external accessors)"],"AuditChecklist": ["Is access to information systems and personal information processing systems controlled through secure user authentication procedures, login attempt limitations, and warnings for illegal login attempts?","When accessing personal information processing systems from outside via a communication network, are secure authentication methods or secure access measures applied in accordance with legal requirements?"],"NonComplianceCases": ["Case 1: When a personal information handler accesses a personal information processing system through the public external internet, secure authentication methods are not applied, and authentication is done only through ID and password.","Case 2: In the login process for information systems and personal information processing systems, detailed messages are displayed about whether the ID exists or the password is incorrect, and there is no limit on login failure attempts."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights), Article 6 (Access Control)"]}],"description": "User access to information systems, personal information, and critical information must be secured through safe authentication procedures and, if necessary, enhanced authentication methods. In addition, access control measures such as limiting login attempts and issuing warnings for illegal login attempts must be established and implemented.","checks_status": {"fail": 4,"pass": 1,"total": 29,"manual": 0}},"2.5.4": {"name": "Password Management","checks": {"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_password_policy_minimum_length_14": null,"cognito_user_pool_password_policy_number": null,"cognito_user_pool_password_policy_symbol": null,"cognito_user_pool_password_policy_lowercase": null,"cognito_user_pool_password_policy_uppercase": null,"cognito_user_pool_temporary_password_expiration": null,"cognito_user_pool_password_policy_minimum_length_14": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.5.4 Password Management","Subdomain": "2.5. Authentication and Authorization Management","AuditEvidence": ["Password setting screens for web pages, information systems, and personal information processing systems","Password management policies and procedures"],"AuditChecklist": ["Are procedures for managing and creating secure user passwords for information systems established and implemented?","Are password creation rules established and enforced to ensure that users can use secure passwords?","Are authentication methods for personal information handlers and users securely applied and managed?"],"NonComplianceCases": ["Case 1: Although password creation rules are set in policies and guidelines related to information protection and personal information protection, some information systems and personal information processing systems use passwords that differ from internal guidelines.","Case 2: Internal regulations state that when passwords are reset, temporary passwords must be assigned and forced to be changed, but in practice, temporary passwords are being used without change.","Case 3: Although internal regulations require users and personal information handlers to change their passwords periodically, passwords are being used without change."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights)"]}],"description": "Procedures for managing passwords used by users of information systems, as well as customers and members, must be established and implemented, taking into account legal requirements and external threats.","checks_status": {"fail": 0,"pass": 0,"total": 13,"manual": 0}},"2.5.5": {"name": "Management of Special Accounts and Privileges","checks": {"iam_avoid_root_usage": null,"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_support_role_created": null,"rds_cluster_default_admin": "FAIL","rds_instance_default_admin": "FAIL","ec2_instance_profile_attached": "PASS","iam_root_hardware_mfa_enabled": null,"organizations_delegated_administrators": null,"cloudwatch_log_metric_filter_root_usage": null,"sagemaker_notebook_instance_root_access_disabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measures Requirements","Section": "2.5.5 Management of Special Accounts and Privileges","Subdomain": "2.5. Authentication and Privilege Management","AuditEvidence": ["Guidelines related to special privileges","Records of special privilege requests and approvals","List of special privilege holders","Records of special privilege reviews"],"AuditChecklist": ["Is there a formal privilege request and approval process established and implemented to ensure that special privileges, such as administrative privileges, are only granted to a minimal number of people?","Is there a control procedure established and implemented to identify and manage accounts and privileges granted for special purposes in a separate list?"],"NonComplianceCases": ["Case 1: The approval history for granting administrator and special privileges in the information system and personal information processing system is not documented or does not match the special privileges list.","Case 2: Internal regulations require that personal information administrators and special privilege holders be documented and managed in a list, but the list is not maintained or some special privileges, such as security system administrators, are not identified or managed.","Case 3: A maintenance special account for visiting maintenance once a quarter remains active at all times without a time limit on usage.","Case 4: Regular reviews of administrator and special privilege usage are not conducted, and some individuals retain special privileges even after their roles have changed."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights)"]}],"description": "Accounts and privileges used for special purposes, such as managing information systems, personal information, and important information, should be granted minimally, separately identified, and controlled.","checks_status": {"fail": 2,"pass": 1,"total": 11,"manual": 0}},"2.5.6": {"name": "Review of Access Rights","checks": {"accessanalyzer_enabled": "PASS","cloudtrail_insights_exist": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","accessanalyzer_enabled_without_findings": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_cross_account_sharing_disabled": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cloudtrail_multi_region_enabled_logging_management_events": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measures Requirements","Section": "2.5.6 Review of Access Rights","Subdomain": "2.5. Authentication and Privilege Management","AuditEvidence": ["Access rights review standards and procedures","History of access rights reviews","Access rights review reports and follow-up action records"],"AuditChecklist": ["Are the histories of account and access right creation, registration, granting, use, modification, and deletion for information systems, personal information, and important information being recorded?","Are standards, review subjects, review methods, and periodic review schedules established to regularly review the appropriateness of user accounts and access rights to information systems, personal information, and important information?","When issues such as excessive access rights, failure to follow access right granting procedures, or misuse of access rights are identified in the review results, are appropriate response procedures established and implemented?"],"NonComplianceCases": ["Case 1: The methods, review periods, reporting structure, and misuse criteria related to access rights reviews are not clearly defined in the relevant guidelines, leading to irregular performance of access rights reviews.","Case 2: Although internal policies and guidelines require locking (deactivating) or deleting long-unused accounts, some accounts that have not been accessed for more than six months remain active (indicating that the access rights review was not thoroughly conducted, failing to identify these accounts).","Case 3: During the access rights review, cases of excessive privileges or suspected misuse were identified, but no detailed investigation, internal reporting, or follow-up actions were taken."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights)"]}],"description": "The registration, use, and deletion of user accounts accessing information systems, personal information, and important information, as well as the history of granting, changing, and deleting access rights, should be recorded and periodically reviewed to ensure their appropriateness.","checks_status": {"fail": 2,"pass": 1,"total": 14,"manual": 0}},"2.6.1": {"name": "Network Access","checks": {"ec2_ami_public": null,"elb_internet_facing": "FAIL","ec2_elastic_ip_shodan": null,"elbv2_internet_facing": "PASS","ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","kafka_cluster_is_public": null,"s3_bucket_acl_prohibited": "FAIL","apigateway_restapi_public": "FAIL","lightsail_database_public": null,"lightsail_instance_public": null,"ec2_securitygroup_not_used": "FAIL","elbv2_listeners_underneath": "PASS","networkfirewall_in_all_vpc": "FAIL","s3_bucket_public_write_acl": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","ssm_documents_set_as_public": "PASS","awslambda_function_url_public": null,"dms_instance_no_public_access": null,"rds_instance_no_public_access": "PASS","emr_cluster_publicly_accesible": null,"redshift_cluster_public_access": null,"neptune_cluster_public_snapshot": null,"eks_cluster_private_nodes_enabled": null,"awslambda_function_url_cors_policy": null,"documentdb_cluster_public_snapshot": null,"eks_cluster_network_policy_enabled": null,"neptune_cluster_uses_public_subnet": null,"sns_topics_not_publicly_accessible": "PASS","sqs_queues_not_publicly_accessible": "PASS","vpc_subnet_no_public_ip_by_default": "FAIL","vpc_subnet_separate_private_public": "FAIL","eks_cluster_not_publicly_accessible": null,"glacier_vaults_policy_public_access": null,"iam_user_mfa_enabled_console_access": null,"s3_access_point_public_access_block": "PASS","s3_bucket_level_public_access_block": "PASS","iam_user_administrator_access_policy": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"iam_group_administrator_access_policy": null,"s3_account_level_public_access_blocks": null,"apigateway_restapi_authorizers_enabled": "PASS","elasticache_cluster_uses_public_subnet": "PASS","rds_instance_iam_authentication_enabled": "FAIL","appstream_fleet_maximum_session_duration": null,"ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ecr_repositories_not_publicly_accessible": "PASS","emr_cluster_account_public_block_enabled": "PASS","sagemaker_models_vpc_settings_configured": null,"apigateway_restapi_public_with_authorizer": "FAIL","ec2_instance_port_ftp_exposed_to_internet": "PASS","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","vpc_endpoint_connections_trust_boundaries": "FAIL","appstream_fleet_session_disconnect_timeout": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_instance_port_cifs_exposed_to_internet": "PASS","ec2_instance_port_ldap_exposed_to_internet": "PASS","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","kafka_cluster_unrestricted_access_disabled": null,"sagemaker_models_network_isolation_enabled": null,"cognito_identity_pool_guest_access_disabled": "FAIL","ec2_instance_port_kafka_exposed_to_internet": "PASS","ec2_instance_port_mysql_exposed_to_internet": "PASS","ec2_instance_port_redis_exposed_to_internet": "PASS","workspaces_vpc_2private_1public_subnets_nat": null,"ec2_instance_port_oracle_exposed_to_internet": "PASS","ec2_instance_port_telnet_exposed_to_internet": "PASS","ec2_instance_port_mongodb_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_instance_port_kerberos_exposed_to_internet": "PASS","ec2_transitgateway_auto_accept_vpc_attachments": null,"appstream_fleet_session_idle_disconnect_timeout": null,"ec2_instance_port_cassandra_exposed_to_internet": "PASS","ec2_instance_port_memcached_exposed_to_internet": "PASS","ec2_instance_port_sqlserver_exposed_to_internet": "PASS","rds_instance_event_subscription_security_groups": "FAIL","sagemaker_training_jobs_vpc_settings_configured": null,"vpc_peering_routing_tables_with_least_privilege": "PASS","appstream_fleet_default_internet_access_disabled": null,"ec2_instance_port_postgresql_exposed_to_internet": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","cloudfront_distributions_geo_restrictions_enabled": null,"sagemaker_training_jobs_network_isolation_enabled": null,"opensearch_service_domains_not_publicly_accessible": null,"sagemaker_notebook_instance_vpc_settings_configured": null,"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","vpc_endpoint_services_allowed_principals_trust_boundaries": null,"ec2_instance_port_elasticsearch_kibana_exposed_to_internet": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","cognito_user_pool_blocks_potential_malicious_sign_in_attempts": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Control Measures","Section": "2.6.1 Network Access","Subdomain": "2.6. Access Control","AuditEvidence": ["Network diagram","IP management ledger","Information asset list","Firewall rules"],"AuditChecklist": ["Has the organization identified all access paths to its network and ensured that internal networks are controlled so that only authorized users can access them according to the access control policy?","Has the organization physically or logically segmented the network based on services, user groups, information asset importance, and legal requirements, and applied access control between different network segments?","Has the organization established IP address allocation standards for each network segment, and applied measures such as assigning private IPs to systems like database servers that do not require external connections?","Has the organization implemented protective measures for communication paths when connecting networks between physically separated locations, such as IDCs, branches, and agents?"],"NonComplianceCases": ["Case 1: The network configuration and interviews revealed that data transmission and reception between external sites and the servers located in the IDC are being processed through the general internet line, rather than using VPN or dedicated lines as specified in internal regulations.","Case 2: The IP addresses of some important servers, such as database servers located in the internal network, were set to public IPs instead of private IPs as per internal regulations, and network access blocking was not applied.","Case 3: Although a server farm was established, access from the internal network to the server farm was excessively allowed due to insufficient network access control settings.","Case 4: The network provided to external parties (e.g., external developers, visitors) was not separated from the internal business network without appropriate controls.","Case 5: Contrary to internal regulations, the organization's network could be accessed and used simply by connecting a network cable without applying protective measures such as MAC address authentication and mandatory security software installation."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 6 (Access Control)"]}],"description": "In order to control unauthorized access to the network, management procedures such as IP management and device authentication must be established and implemented. Network segmentation (DMZ, server farm, DB zone, development zone, etc.) and access controls must be applied according to the business purpose and importance.","checks_status": {"fail": 17,"pass": 54,"total": 112,"manual": 0}},"2.6.2": {"name": "Access to Information Systems","checks": {"ec2_elastic_ip_shodan": null,"ec2_instance_public_ip": "FAIL","ec2_elastic_ip_unassigned": "FAIL","lightsail_instance_public": null,"lightsail_static_ip_unused": null,"ec2_instance_managed_by_ssm": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_instance_port_ftp_exposed_to_internet": "PASS","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_instance_port_telnet_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","ec2_instance_internet_facing_with_instance_profile": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Protection Requirements","Section": "2.6.2 Access to Information Systems","Subdomain": "2.6. Access Control","AuditEvidence": ["List of operating system accounts of information systems","Server security settings","Server access control policy (e.g., SecureOS management screen)","Server and network configuration diagram","Information asset list"],"AuditChecklist": ["Have users, access locations, and access means allowed to access operating systems (OS) of information systems such as servers, network systems, and security systems been defined and controlled?","Is the system automatically disconnected when there is no work processed after accessing the information system for a certain period?","Are services unrelated to the purpose of using the information system removed?","Are information systems that provide key services operated on independent servers?"],"NonComplianceCases": ["Case 1: When a server administrator accesses a Windows server located in the IDC from the office using terminal services, session timeout settings are not configured, allowing the session to remain open for a long period without any activity.","Case 2: Due to improper restrictions on server-to-server access, a user authorized to access a particular server can access other unauthorized servers via that server.","Case 3: Unsafe access protocols (e.g., telnet, ftp) are being used without valid reasons or compensatory measures, and unnecessary services and ports are open.","Case 4: Although the access control policy requires all access to servers to go through a server access control system, bypass routes exist that allow access to servers without going through the system."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 6 (Access Control)"]}],"description": "The users, access restriction methods, and secure access means for accessing information systems such as servers and network systems must be defined and controlled.","checks_status": {"fail": 8,"pass": 13,"total": 24,"manual": 0}},"2.6.3": {"name": "Access to Applications","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.6.3 Access to Applications","Subdomain": "2.6. Access Control","AuditEvidence": ["Application access rights classification system","Application account and rights management screen","Application user and administrator screens (e.g., personal information viewing, etc.)","Application session time and concurrent session restriction settings","Application administrator access log monitoring details","Information asset list","Personal information processing system's personal information viewing and search screens","Personal information masking standards","Personal information masking application screen"],"AuditChecklist": ["Are access rights to applications granted differentially based on the user's tasks to control access to sensitive information?","Are sessions automatically disconnected after a certain period of inactivity, and is the number of simultaneous sessions per user restricted?","Is access to administrator-exclusive applications (e.g., admin web pages, admin consoles) restricted to unauthorized users?","Are criteria established and applied to ensure consistency in protection measures for limiting the display of personal and sensitive information?","Are applications implemented and operated to minimize unnecessary exposure (e.g., viewing, screen display, printing, downloading) of personal and sensitive information?"],"NonComplianceCases": ["Case 1: There is a flaw in the authorization control function of certain personal information processing screens in the application, allowing users without permission to view personal information.","Case 2: The administrator page of the application is open to the public internet without secure authentication methods applied.","Case 3: Session timeouts or concurrent logins for the same user account are not restricted without valid reasons.","Case 4: When personal information is downloaded through the application, the file contains excessive unnecessary information such as resident registration numbers.","Case 5: The application excessively allows 'like' searches, allowing all users to retrieve all customer information by searching only for a surname, even beyond their work scope.","Case 6: Due to the lack of criteria for limiting the display of personal information or failure to adhere to them, different masking standards are applied to the same personal information items on different screens of the personal information processing system.","Case 7: Although personal information is masked on the screen of the personal information processing system, unmasked personal information is exposed by viewing the web browser source."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights), Article 6 (Access Control), Article 12 (Safety Measures for Printing and Copying)"]}],"description": "Access rights to applications must be restricted according to the user's tasks and the importance of the accessed information, and criteria should be established to minimize exposure of unnecessary or sensitive information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.6.4": {"name": "Database Access","checks": {"accessanalyzer_enabled": "PASS","lightsail_database_public": null,"rds_snapshots_public_access": "PASS","dms_instance_no_public_access": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"neptune_cluster_public_snapshot": null,"rds_instance_transport_encrypted": "FAIL","documentdb_cluster_public_snapshot": null,"neptune_cluster_uses_public_subnet": null,"vpc_subnet_separate_private_public": "FAIL","dynamodb_table_cross_account_access": null,"rds_cluster_iam_authentication_enabled": "FAIL","accessanalyzer_enabled_without_findings": "FAIL","rds_instance_iam_authentication_enabled": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","neptune_cluster_iam_authentication_enabled": null,"ec2_instance_port_mysql_exposed_to_internet": "PASS","ec2_instance_port_redis_exposed_to_internet": "PASS","ec2_instance_port_oracle_exposed_to_internet": "PASS","ec2_instance_port_mongodb_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_instance_port_cassandra_exposed_to_internet": "PASS","ec2_instance_port_sqlserver_exposed_to_internet": "PASS","opensearch_service_domains_not_publicly_accessible": null,"opensearch_service_domains_https_communications_enforced": null,"opensearch_service_domains_internal_user_database_enabled": null,"ec2_instance_port_elasticsearch_kibana_exposed_to_internet": "PASS","opensearch_service_domains_use_cognito_authentication_for_kibana": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Protection Measures Requirements","Section": "2.6.4 Database Access","Subdomain": "2.6. Access Control","AuditEvidence": ["Database status (e.g., tables, columns)","List of database user accounts and permissions","Database access control policy (e.g., database access control system management screen)","Network diagram (e.g., database zone)","Information asset list"],"AuditChecklist": ["Are you identifying the information stored and managed in the database, such as the table list?","Are you clearly identifying the applications, information systems (servers), and users that need access to information in the database and controlling access according to the access control policy?"],"NonComplianceCases": ["Case 1: A database that stores and processes a large amount of personal information is operated on the same physical server as a web application accessible via the Internet, without separating them.","Case 2: Developers and operators share accounts used by the application to access the production database.","Case 3: Although internal regulations require database access rights to be restricted by object, access rights to the database are granted uniformly to administrators, even those who do not need access to personal information tables.","Case 4: A database access control solution has been implemented, but access to the database is not properly restricted by IP address, allowing users to bypass the access control solution.","Case 5: The table status of a database storing personal information has not been identified, resulting in the unnecessary retention of personal information in temporary tables that have not been deleted."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights), Article 6 (Access Control)"]}],"description": "Identify the information stored and managed in the database, such as the table list, and establish and implement access control policies according to the importance of the information and the type of applications and users.","checks_status": {"fail": 6,"pass": 19,"total": 37,"manual": 0}},"2.6.5": {"name": "Wireless Network Access","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measures Requirements","Section": "2.6.5 Wireless Network Access","Subdomain": "2.6. Access Control","AuditEvidence": ["Network diagram","AP security settings history","Inspection records of unauthorized wireless networks","Wireless network usage application and approval records"],"AuditChecklist": ["When using a wireless network for business purposes, are you establishing and implementing protection measures such as authentication and encryption of transmitted and received data to ensure the security of the wireless AP and network segment?","Have you established and implemented procedures for applying for and terminating access to ensure that only authorized employees can use the wireless network?","Have you established and implemented protection measures against unauthorized wireless networks, such as detecting and blocking AD Hoc connections and unauthorized wireless APs within the organization?"],"NonComplianceCases": ["Case 1: The wireless network segments for external users and internal users are the same, allowing external users to access the internal network without separate control via the wireless network.","Case 2: Although the encryption function for information transmission and reception was enabled when configuring the wireless AP, it was set in an insecure manner.","Case 3: A wireless AP connected to the internal network for business purposes has security settings that are insufficient, such as exposure of the administrator password (using the default password) and lack of access control."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 6 (Access Control)"]}],"description": "When using a wireless network, wireless network protection measures such as user authentication, encryption of transmitted and received data, and AP control must be applied. In addition, protection measures must be established and implemented to prevent unauthorized wireless network access, such as AD Hoc connections and the use of unauthorized APs.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.6.6": {"name": "Remote Access Control","checks": {"vpc_flow_logs_enabled": "FAIL","networkfirewall_in_all_vpc": "FAIL","cognito_user_pool_mfa_enabled": null,"iam_user_console_access_unused": null,"vpc_subnet_no_public_ip_by_default": "FAIL","vpc_subnet_separate_private_public": "FAIL","iam_user_mfa_enabled_console_access": null,"workspaces_volume_encryption_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","appstream_fleet_maximum_session_duration": null,"ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","appstream_fleet_session_disconnect_timeout": null,"ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","cognito_identity_pool_guest_access_disabled": "FAIL","workspaces_vpc_2private_1public_subnets_nat": null,"cognito_user_pool_self_registration_disabled": null,"appstream_fleet_session_idle_disconnect_timeout": null,"appstream_fleet_default_internet_access_disabled": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"ec2_client_vpn_endpoint_connection_logging_enabled": null,"cloudwatch_log_metric_filter_authentication_failures": null,"ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Protective Measures Requirements","Section": "2.6.6 Remote Access Control","Subdomain": "2.6. Access Control","AuditEvidence": ["Remote access application form (e.g., VPN)","VPN account list","VPN access control policy settings","IP management log","Remote access control settings (server settings, security system settings, etc.)","Designation and management of management terminals","Network diagram"],"AuditChecklist": ["Is remote operation of information systems through external networks such as the internet prohibited in principle, and are compensatory measures in place if allowed for unavoidable reasons such as incident response?","Is access through remote operation of information systems allowed only for specific devices when done through internal networks?","Are protective measures established and implemented to prevent security incidents such as data breaches and hacking during remote work, such as telecommuting, remote collaboration, and smart work?","Are the devices used for remote access to personal information processing systems for management, operation, development, and security purposes designated as management terminals, and are safety measures such as prohibiting unauthorized operations and use for purposes other than those intended being applied?"],"NonComplianceCases": ["Case 1: Although internal regulations state that remote access to the system is prohibited in principle and, when allowed, access is restricted through IP-based access control, remote desktop connections and SSH access to the system are not limited by IP addresses, allowing access from any PC.","Case 2: A VPN has been established for remote management, but it is always available without usage approval or access period restrictions.","Case 3: Work-related mobile apps have been installed on personal smart devices for external workers, but appropriate protective measures (e.g., antivirus, encryption, wiping in case of loss or theft) to prevent personal information leaks are not being applied.","Case 4: VPN access for external users is not limited by network segments and information systems, allowing excessive access to the entire internal network and information systems for authenticated remote users."],"RelatedRegulations": ["Personal Information Protection Act Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information Article 6 (Access Control)"]}],"description": "Managing information systems and handling personal information outside of protected areas is, in principle, prohibited. However, if remote access is allowed for unavoidable reasons such as telecommuting, incident response, or remote collaboration, protective measures must be established and implemented, including approval from responsible personnel, designation of access devices, setting access scope and duration, enhanced authentication, encrypted communication, and securing access devices (e.g., antivirus, patches).","checks_status": {"fail": 8,"pass": 5,"total": 26,"manual": 0}},"2.6.7": {"name": "Internet Access Control","checks": {"ec2_elastic_ip_shodan": null,"vpc_flow_logs_enabled": "FAIL","ec2_instance_public_ip": "FAIL","ec2_elastic_ip_unassigned": "FAIL","networkfirewall_in_all_vpc": "FAIL","vpc_subnet_no_public_ip_by_default": "FAIL","vpc_subnet_separate_private_public": "FAIL","workspaces_volume_encryption_enabled": null,"route53_dangling_ip_subdomain_takeover": null,"appstream_fleet_maximum_session_duration": null,"appstream_fleet_session_disconnect_timeout": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"workspaces_vpc_2private_1public_subnets_nat": null,"ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","appstream_fleet_session_idle_disconnect_timeout": null,"appstream_fleet_default_internet_access_disabled": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Domain": "2. Protective Measures Requirements","Section": "2.6.7 Internet Access Control","Subdomain": "2.6. Access Control","AuditEvidence": ["Policy for blocking non-work-related sites (e.g., P2P) (management screen of non-work-related site blocking system)","Internet access monitoring history","List of individuals subject to internet access restriction measures","Procedures and records for data transfer between networks (e.g., application and approval records)","Network diagram"],"AuditChecklist": ["Is there an established and implemented policy to control internet access for work PCs used for key duties and personal information handling terminals?","Is unnecessary external internet access from key information systems (e.g., database servers) being controlled?","Are internet access restrictions being applied in a secure manner for individuals who are required by law to have their internet access restricted?"],"NonComplianceCases": ["Case 1: Internet access restriction measures were applied according to the Personal Information Protection Act, but the restriction was not applied to some individuals with the authority to set access rights for personal information processing systems.","Case 2: Although internet access restriction measures were applied as required under the Personal Information Protection Act, it was possible to bypass the restriction by accessing the system through another server, allowing the download and deletion of personal information.","Case 3: Some servers located in the DMZ and internal network were unnecessarily able to access the internet directly.","Case 4: Although a physical network separation system was applied between internet PCs and internal work PCs, and a data transfer system was established, there was no approval process for data transfers, and there was no periodic review of the data transfer records.","Case 5: Internal regulations require that individuals handling personal information obtain approval from a responsible person before accessing P2P or web hard drive sites, and access is only permitted for a specific period, but there are numerous cases of exceptions being made without going through the approval process."],"RelatedRegulations": ["Personal Information Protection Act Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information Article 6 (Access Control)"]}],"description": "To prevent information leaks, malware infections, and intrusions into the internal network through the internet, policies must be established and implemented to restrict internet access or services (e.g., P2P, web hard drives, messengers) on key information systems, devices handling sensitive duties, and terminals processing personal information.","checks_status": {"fail": 6,"pass": 1,"total": 19,"manual": 0}},"2.7.1": {"name": "Application of Encryption Policy","checks": {"elb_ssl_listeners": "FAIL","backup_vaults_exist": null,"elbv2_ssl_listeners": "FAIL","ssm_document_secrets": "PASS","backup_vaults_encrypted": "PASS","rds_snapshots_encrypted": "FAIL","elb_insecure_ssl_ciphers": "PASS","s3_bucket_kms_encryption": "FAIL","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","elbv2_insecure_ssl_ciphers": "PASS","athena_workgroup_encryption": null,"ec2_ebs_snapshots_encrypted": "FAIL","s3_bucket_default_encryption": "PASS","ec2_instance_secrets_user_data": "PASS","ec2_launch_template_no_secrets": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","rds_instance_transport_encrypted": "FAIL","cloudtrail_kms_encryption_enabled": "FAIL","neptune_cluster_storage_encrypted": null,"s3_bucket_secure_transport_policy": "FAIL","documentdb_cluster_storage_encrypted": null,"workspaces_volume_encryption_enabled": null,"awslambda_function_no_secrets_in_code": "PASS","glue_database_connections_ssl_enabled": null,"athena_workgroup_enforce_configuration": null,"cloudfront_distributions_https_enabled": null,"cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudformation_stack_outputs_find_secrets": "PASS","codebuild_project_no_secrets_in_variables": "PASS","kafka_cluster_encryption_at_rest_uses_cmk": null,"sns_subscription_not_using_http_endpoints": "PASS","sns_topics_kms_encryption_at_rest_enabled": "FAIL","sqs_queues_server_side_encryption_enabled": "PASS","awslambda_function_no_secrets_in_variables": "PASS","dynamodb_tables_kms_cmk_encryption_enabled": null,"glue_etl_jobs_amazon_s3_encryption_enabled": "PASS","acm_certificates_with_secure_key_algorithms": "PASS","cloudwatch_log_group_kms_encryption_enabled": "FAIL","ecs_task_definitions_no_environment_secrets": "PASS","kafka_cluster_in_transit_encryption_enabled": null,"storagegateway_fileshare_encryption_enabled": null,"apigateway_restapi_client_certificate_enabled": "FAIL","glue_etl_jobs_job_bookmark_encryption_enabled": "FAIL","glue_data_catalogs_metadata_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"kafka_cluster_mutual_tls_authentication_enabled": null,"directoryservice_radius_server_security_protocol": null,"glue_development_endpoints_s3_encryption_enabled": null,"glue_etl_jobs_cloudwatch_logs_encryption_enabled": "FAIL","autoscaling_find_secrets_ec2_launch_configuration": "PASS","eks_cluster_kms_cmk_encryption_in_secrets_enabled": null,"elasticache_redis_cluster_rest_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"cloudfront_distributions_field_level_encryption_enabled": null,"cloudfront_distributions_using_deprecated_ssl_protocols": null,"elasticache_redis_cluster_in_transit_encryption_enabled": null,"opensearch_service_domains_https_communications_enforced": null,"sagemaker_training_jobs_intercontainer_encryption_enabled": null,"glue_data_catalogs_connection_passwords_encryption_enabled": "FAIL","glue_development_endpoints_job_bookmark_encryption_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null,"sagemaker_training_jobs_volume_and_output_encryption_enabled": null,"glue_development_endpoints_cloudwatch_logs_encryption_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measures Requirements","Section": "2.7.1 Application of Encryption Policy","Subdomain": "2.7. Application of Encryption","AuditEvidence": ["Encryption control policy (targets, methods, algorithms, etc.)","Encryption application status (during storage and transmission)","Risk analysis results (if encryption is not applied to unique identifiers other than resident registration numbers in the internal network)","Encryption solution management screen"],"AuditChecklist": ["Has an encryption policy been established that includes encryption targets, encryption strength, and encryption usage in consideration of legal requirements for the protection of personal and important information?","Is encryption applied to personal and important information during storage, transmission, and transfer according to the encryption policy?"],"NonComplianceCases": ["Case 1: Internal policies and guidelines do not properly specify encryption targets, encryption strength, encryption methods during storage and transmission, or the roles and responsibilities of those responsible for encryption, considering legal requirements.","Case 2: The company applied incorrect regulations during the creation of its encryption policy, leading to non-compliance with legal encryption requirements (e.g., storing user account numbers without encryption).","Case 3: Although one-way encryption was applied to the passwords of both personal information handlers and data subjects, an insecure MD5 algorithm was used.","Case 4: Although a security server was applied to an internet shopping mall in accordance with relevant laws and internal regulations, encryption was missing in some sections where users' personal information is transmitted (e.g., viewing or modifying member information, password retrieval, password changes).","Case 5: Passwords for accessing information systems, authentication keys, and other values were stored in plaintext in system configuration files and source code."],"RelatedRegulations": ["Personal Information Protection Act, Article 24-2 (Restrictions on Processing of Resident Registration Numbers), Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 7 (Encryption of Personal Information)"]}],"description": "To protect personal and important information, encryption policies that reflect legal requirements, such as encryption targets, encryption strength, and encryption usage policies, must be established. Encryption must be applied during the storage, transmission, and transfer of personal and important information.","checks_status": {"fail": 18,"pass": 19,"total": 66,"manual": 0}},"2.7.2": {"name": "Cryptographic Key Management","checks": {"kms_cmk_are_used": null,"kms_cmk_rotation_enabled": null,"kms_key_not_publicly_accessible": null,"kms_cmk_not_deleted_unintentionally": null,"rds_instance_certificate_expiration": "PASS","secretsmanager_automatic_rotation_enabled": "FAIL","acm_certificates_transparency_logs_enabled": "PASS","directoryservice_ldap_certificate_expiration": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "FAIL","attributes": [{"Domain": "2. Security Control Requirements","Section": "2.7.2 Cryptographic Key Management","Subdomain": "2.7. Application of Encryption","AuditEvidence": ["Cryptographic Key Management Policy","Cryptographic Key Management Log and System Screens"],"AuditChecklist": ["Are procedures for the generation, use, storage, distribution, modification, recovery, and destruction of cryptographic keys established and implemented?","Are cryptographic keys securely stored in a separate location to ensure they can be recovered if necessary, and is access to the use of cryptographic keys minimized?"],"NonComplianceCases": ["Case 1: If encryption policies do not specify procedures and methods for managing cryptographic keys, leading to varying levels and methods of cryptographic key management among personnel, resulting in vulnerabilities.","Case 2: Internal regulations require the generation of encryption keys under the approval of a responsible person when encrypting important information, and to maintain a key management log, but some keys are either missing or outdated in the log.","Case 3: The encryption key applied in the development system is the same as the one applied in the production system, making it easy to decrypt actual data through the development system."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 7 (Encryption of Personal Information)"]}],"description": "Establish and implement management procedures for the secure generation, use, storage, distribution, and destruction of cryptographic keys, and prepare recovery methods if necessary.","checks_status": {"fail": 1,"pass": 2,"total": 9,"manual": 0}},"2.8.1": {"name": "Definition of Security Requirements","checks": {"macie_is_enabled": "PASS","securityhub_enabled": "PASS","fms_policy_compliant": null,"guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","accessanalyzer_enabled": "PASS","networkfirewall_in_all_vpc": "FAIL","guardduty_centrally_managed": "FAIL","wafv2_webacl_logging_enabled": "FAIL","config_recorder_all_regions_enabled": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","codebuild_project_no_secrets_in_variables": "PASS","codebuild_project_user_controlled_buildspec": "PASS","wellarchitected_workload_no_high_or_medium_risks": "FAIL","codebuild_project_source_repo_url_no_sensitive_credentials": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Security Control Requirements","Section": "2.8.1 Definition of Security Requirements","Subdomain": "2.8. Security for Information System Introduction and Development","AuditEvidence": ["Information System Acquisition Standards and Procedures","RFP (Request for Proposal) and Purchase Contracts for Information System Introduction","Development Outputs (Project Execution Plans, Requirements Definition, Screen Design, Security Architecture Design, Test Plans, etc.)","Secure Coding Standards"],"AuditChecklist": ["When introducing, developing, or modifying an information system, are procedures for reviewing the validity of information protection and personal information protection aspects and for acquisition established and implemented?","When introducing, developing, or modifying an information system, are security requirements, including legal requirements and the latest vulnerabilities, clearly defined and reflected from the design stage?","Are coding standards for secure implementation of the information system established and applied?"],"NonComplianceCases": ["Case 1: Lack of established security verification standards and procedures prior to acquiring an information system.","Case 2: Internal regulations require the review of the security impact and the operating environment when introducing a new system, but recent acquisitions of some information systems lacked detailed standards and plans, and therefore, no security review was conducted during the acquisition.","Case 3: Internal development guidelines do not define key security requirements related to development (authentication and encryption, security logging, etc.).","Case 4: In the 'Development Standards Definition Document', user passwords are to be encrypted using insecure algorithms (MD5, SHA1), resulting in failure to comply with relevant legal requirements."],"RelatedRegulations": []}],"description": "When introducing, developing, or modifying information systems, security requirements such as legal requirements related to information protection and personal information protection, the latest security vulnerabilities, and secure coding methods must be defined and applied.","checks_status": {"fail": 7,"pass": 7,"total": 16,"manual": 0}},"2.8.2": {"name": "Review and Testing of Security Requirements","checks": {"macie_is_enabled": "PASS","securityhub_enabled": "PASS","fms_policy_compliant": null,"guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","accessanalyzer_enabled": "PASS","networkfirewall_in_all_vpc": "FAIL","guardduty_centrally_managed": "FAIL","wafv2_webacl_logging_enabled": "FAIL","inspector2_active_findings_exist": "FAIL","config_recorder_all_regions_enabled": null,"guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","accessanalyzer_enabled_without_findings": "FAIL","codebuild_project_no_secrets_in_variables": "PASS","codebuild_project_user_controlled_buildspec": "PASS","wellarchitected_workload_no_high_or_medium_risks": "FAIL","codebuild_project_source_repo_url_no_sensitive_credentials": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Security Control Requirements","Section": "2.8.2 Review and Testing of Security Requirements","Subdomain": "2.8. Security for Information System Introduction and Development","AuditEvidence": ["Information System Acceptance Test Results","Requirements Traceability Matrix","Test Plans, Test Results","Vulnerability Assessment Results","Personal Information Impact Assessment Report","Confirmation of Implementation of Corrective Actions for Personal Information Impact Assessment"],"AuditChecklist": ["When introducing, developing, or modifying an information system, are tests conducted to verify whether the security requirements defined during the analysis and design stages have been effectively applied?","Are vulnerability assessments conducted to confirm that the information system has been securely developed according to secure coding standards?","Are procedures established and implemented to ensure that issues identified during testing and vulnerability assessments are promptly addressed through corrective action plans and follow-up checks?","For public institutions, are impact assessments conducted during the analysis and design stages when developing or modifying personal information processing systems, as required by relevant laws, and are the results reflected during development and modification?"],"NonComplianceCases": ["Case 1: Failure to test security requirements defined in internal guidelines and documents after implementing an information system.","Case 2: In the application program test scenario and technical vulnerability checklist, important validation items such as input validation checks were omitted.","Case 3: Failure to assess whether known technical vulnerabilities exist during implementation or testing, or failure to address identified vulnerabilities without valid reasons or approval.","Case 4: A public institution failed to conduct an impact assessment when developing a personal information file or personal information processing system subject to an impact assessment requirement, such as processing unique identifiers of more than 50,000 data subjects.","Case 5: A public institution failed to submit the impact assessment report to the Personal Information Protection Commission within two months after receiving the report from the impact assessment agency.","Case 6: Internal guidelines require reviewing the security and impact on the operating environment when introducing a new system (e.g., vulnerability assessments), but recent acquisitions of some information systems lacked security reviews during the acceptance process."],"RelatedRegulations": ["Personal Information Protection Act, Article 33 (Personal Information Impact Assessment)","Notification on Personal Information Impact Assessment"]}],"description": "To verify that an information system has been introduced or implemented according to predefined security requirements, review standards and procedures must be established and implemented to check compliance with legal requirements, the latest security vulnerabilities, secure coding implementation, and personal information impact assessment, and corrective measures must be taken for any identified issues.","checks_status": {"fail": 10,"pass": 7,"total": 19,"manual": 0}},"2.8.3": {"name": "Separation of Test and Production Environments","checks": {"codebuild_project_user_controlled_buildspec": "PASS"},"status": "PASS","attributes": [{"Domain": "2. Security Requirements for Protection Measures","Section": "2.8.3 Separation of Test and Production Environments","Subdomain": "2.8. Security for Information System Introduction and Development","AuditEvidence": ["Network diagrams (including test environment configuration)","Current application of access control between the production environment and the development/test environment"],"AuditChecklist": ["Are development and test systems separated from the production system?","If separation of development and production environments is difficult due to unavoidable reasons, have security measures such as mutual review, monitoring by supervisors, approval for changes, and ensuring accountability been implemented?"],"NonComplianceCases": ["Case 1: Source code changes are being made directly in the production environment without a separate development environment or proper approval.","Case 2: Although it is unavoidable to operate the development and production systems without separation, records of mutual review or monitoring are missing.","Case 3: Although a separate development system is in place, access from the development environment to the production environment is not controlled, allowing developers unnecessary access to the production system through the development system."],"RelatedRegulations": []}],"description": "Development and test systems must, in principle, be separated from production systems to reduce the risk of unauthorized access and changes to the production system.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.8.4": {"name": "Test Data Security","checks": {"codebuild_project_no_secrets_in_variables": "PASS"},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.8.4 Test Data Security","Subdomain": "2.8. Security in Information System Introduction and Development","AuditEvidence": ["Test data status","Test data generation rules","If operational data was used in a test environment, the approval history"],"AuditChecklist": ["Is the use of actual operational data restricted during the development and testing of information systems?","If it is inevitable to use operational data in a test environment, are control procedures such as approval by the responsible person, monitoring of access and leakage, and deletion of data after testing established and implemented?"],"NonComplianceCases": ["Case 1: There are no specific standards and procedures established for generating test data for use on the development server.","Case 2: Operational data is being used as test data without proper processing and without approval from the responsible person for a valid reason.","Case 3: Although operational data was approved in advance for use as test data for unavoidable reasons, the same level of access control as the operational database is not applied to the test database.","Case 4: After using operational data for testing purposes, the data was not deleted from the test database even though the testing was completed."],"RelatedRegulations": []}],"description": "In order to prevent the leakage of operational data during system testing, procedures for the creation, use, management, disposal, and technical protection measures of test data must be established and implemented.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.8.5": {"name": "Source Program Management","checks": {"ecr_repositories_not_publicly_accessible": "PASS","codeartifact_packages_external_public_publishing_disabled": null},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.8.5 Source Program Management","Subdomain": "2.8. Security in Information System Introduction and Development","AuditEvidence": ["Status of configuration management systems such as SVN (e.g., list of authorized personnel)","History of changes to the source program"],"AuditChecklist": ["Have procedures been established and implemented to control access to source programs by unauthorized persons?","Is the source program stored safely in a non-operational environment for emergencies such as system failures?","Is the history of changes to the source program being managed?"],"NonComplianceCases": ["Case 1: There is no separate backup or configuration management system for source programs, and previous versions of the source code are stored on the operational server or developer's PC without approval or history management.","Case 2: A configuration management system has been established, but access control, access and change history for the system or the source code stored in the system are not properly managed.","Case 3: The internal regulations require version control of source programs through a configuration management system, but the latest version of the source program is only stored on the developer's PC, and no separate backup is performed."],"RelatedRegulations": []}],"description": "Source programs must be managed so that only authorized users can access them, and it is a principle that they should not be stored in the operational environment.","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"2.8.6": {"name": "Transition to Operational Environment","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.8.6 Transition to Operational Environment","Subdomain": "2.8. Security in Information System Introduction and Development","AuditEvidence": ["Transition procedures","Transition records (requests, approvals, tests, transitions, etc.)"],"AuditChecklist": ["Have control procedures been established and implemented to safely transition newly introduced, developed, or modified systems to the operational environment?","Are contingency plans in place to address issues that may arise during the transition to the operational environment?","Are only the files necessary for service execution installed in the operational environment?"],"NonComplianceCases": ["Case 1: There are no procedures in place to review and approve the transition of developed or modified source programs to the operational environment.","Case 2: Unnecessary files (source code, distribution modules, backups, development-related documents, manuals, etc.) exist in the operational server.","Case 3: The internal guidelines require the preparation of change request and result documents for safe transition and recovery during transitions to the operational environment, but such documents are not available.","Case 4: The internal guidelines require internal review and approval before distributing mobile apps to the app market, but developers are bypassing these procedures and distributing the apps directly."],"RelatedRegulations": []}],"description": "When transitioning newly introduced, developed, or modified systems to the operational environment, the process must be controlled, and the executable code must be run according to test and user acceptance procedures.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.9.1": {"name": "Change Management","checks": {"codebuild_project_older_90_days": "FAIL","config_recorder_all_regions_enabled": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.9.1 Change Management","Subdomain": "2.9. System and Service Operations Management","AuditEvidence": ["Change management procedures","Change management records (requests, approvals, change details, etc.)","Impact analysis results of changes"],"AuditChecklist": ["Have procedures been established and implemented for changes to assets related to information systems (hardware, operating systems, commercial software packages, etc.)?","Are the performance and security impacts analyzed before making changes to information system-related assets?"],"NonComplianceCases": ["Case 1: A recent change to the DMZ section for redundancy was made, but there is no evidence of performing and approving the security risk and performance evaluation that may occur after the change.","Case 2: A recent network change was made, but the review and notification were not sufficiently carried out, so the changes were not properly reflected in the network diagram or some access control systems (e.g., firewalls, database access control systems) ACLs.","Case 3: Although a change management system was established to analyze and discuss the impact on performance and security when information systems are introduced or changed, changes can still be made outside the system, and related changes are not properly reviewed."],"RelatedRegulations": []}],"description": "Procedures must be established and implemented to manage all changes to assets related to information systems, and the impact on system performance and security must be analyzed before changes are made.","checks_status": {"fail": 2,"pass": 0,"total": 14,"manual": 0}},"2.9.2": {"name": "Performance and Fault Management","checks": {"rds_cluster_multi_az": "FAIL","elb_is_in_multiple_az": "FAIL","rds_instance_multi_az": "FAIL","elbv2_is_in_multiple_az": "PASS","s3_bucket_no_mfa_delete": "FAIL","vpc_subnet_different_az": "PASS","neptune_cluster_multi_az": null,"elbv2_deletion_protection": "FAIL","autoscaling_group_multiple_az": null,"dms_instance_multi_az_enabled": null,"rds_cluster_backtrack_enabled": null,"cloudtrail_multi_region_enabled": "PASS","rds_cluster_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL","acm_certificates_expiration_check": "PASS","s3_bucket_cross_region_replication": "FAIL","trustedadvisor_errors_and_warnings": null,"config_recorder_all_regions_enabled": null,"kms_cmk_not_deleted_unintentionally": null,"neptune_cluster_deletion_protection": null,"networkfirewall_deletion_protection": null,"rds_instance_certificate_expiration": "PASS","route53_domains_transferlock_enabled": null,"cloudtrail_bucket_requires_mfa_delete": null,"elb_cross_zone_load_balancing_enabled": "PASS","documentdb_cluster_deletion_protection": null,"documentdb_cluster_cloudwatch_log_export": null,"ec2_instance_detailed_monitoring_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","iam_no_expired_server_certificates_stored": null,"kafka_cluster_enhanced_monitoring_enabled": null,"elasticache_redis_cluster_multi_az_enabled": null,"directoryservice_ldap_certificate_expiration": null,"cognito_user_pool_deletion_protection_enabled": null,"trustedadvisor_premium_support_plan_subscribed": null,"directoryservice_directory_monitor_notifications": null,"cloudformation_stacks_termination_protection_enabled": "FAIL","cloudtrail_multi_region_enabled_logging_management_events": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.9.2 Performance and Fault Management","Subdomain": "2.9. System and Service Operations Management","AuditEvidence": ["Procedures for performance and capacity monitoring","Evidence of performance and capacity monitoring (e.g., internal reporting results)","Fault response procedures","Fault response report"],"AuditChecklist": ["Have procedures been established and implemented to continuously monitor performance and capacity to ensure the availability of information systems?","Are response procedures in place and implemented to address cases where the performance and capacity requirements (thresholds) of the information system are exceeded?","Have procedures been established and implemented to immediately recognize and respond to information system faults?","Are procedures in place to record and manage actions taken in response to faults through fault response reports?","For serious faults, are measures being taken to prevent recurrence through cause analysis?"],"NonComplianceCases": ["Case 1: Failure to define requirements (e.g., thresholds) for managing performance and capacity for each target, or the absence of records in regular inspection reports, making it difficult to assess the current status.","Case 2: Performance or capacity standards were exceeded, but no related reviews or follow-up measures were taken or implemented.","Case 3: Fault response procedures for IT equipment have been established, but internal and external environmental changes such as network configuration or vendor changes are not adequately reflected.","Case 4: Inconsistencies exist between fault handling procedures and fault type-specific response methods, or there is a lack of rationale for estimating response times, making swift, accurate, and systematic responses difficult."],"RelatedRegulations": []}],"description": "To ensure the availability of information systems, performance and capacity requirements must be defined, and the status must be continuously monitored. Procedures for detecting, recording, analyzing, recovering, and reporting in response to faults must be established and managed effectively.","checks_status": {"fail": 11,"pass": 6,"total": 39,"manual": 0}},"2.9.3": {"name": "Backup and Recovery Management","checks": {"ec2_ami_public": null,"backup_plans_exist": "PASS","backup_vaults_exist": null,"backup_vaults_encrypted": "PASS","ec2_ebs_public_snapshot": "PASS","efs_have_backup_enabled": "FAIL","s3_bucket_public_access": null,"backup_reportplans_exist": null,"s3_bucket_kms_encryption": "FAIL","s3_bucket_public_list_acl": null,"s3_bucket_public_write_acl": null,"ec2_ebs_snapshots_encrypted": "FAIL","rds_instance_backup_enabled": "PASS","rds_snapshots_public_access": "PASS","s3_bucket_lifecycle_enabled": "FAIL","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"s3_bucket_default_encryption": "PASS","rds_cluster_backtrack_enabled": null,"neptune_cluster_backup_enabled": null,"ec2_ebs_volume_snapshots_exists": "FAIL","neptune_cluster_public_snapshot": null,"documentdb_cluster_backup_enabled": null,"documentdb_cluster_public_snapshot": null,"rds_cluster_copy_tags_to_snapshots": "FAIL","s3_bucket_cross_region_replication": "FAIL","rds_instance_copy_tags_to_snapshots": null,"redshift_cluster_automated_snapshot": null,"s3_access_point_public_access_block": "PASS","s3_bucket_policy_public_write_access": "PASS","lightsail_instance_automated_snapshots": null,"dlm_ebs_snapshot_lifecycle_policy_exists": "FAIL","elasticache_redis_cluster_backup_enabled": null,"ecr_repositories_lifecycle_policy_enabled": "FAIL","directoryservice_directory_snapshots_limit": null,"ec2_ebs_snapshot_account_block_public_access": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.9.3 Backup and Recovery Management","Subdomain": "2.9. System and Service Operation Management","AuditEvidence": ["Backup and recovery procedures","Recovery test results","Disaster recovery backup status"],"AuditChecklist": ["Have backup and recovery procedures been established and implemented, including targets, frequency, methods, and procedures?","Is regular recovery testing conducted to verify the completeness and accuracy of the backed-up information and the adequacy of the recovery procedures?","For backup media containing critical information, is the media stored in physically separate locations to address disaster recovery?"],"NonComplianceCases": ["Case 1: Backup and recovery procedures, including targets, frequency, methods, and procedures, have not been established.","Case 2: Although a backup policy is in place, information required to be stored for a long period (6 months, 3 years, 5 years, etc.) according to legal requirements is not being stored according to the backup policy.","Case 3: Some systems (e.g., security system policies and logs) that are required to be separately backed up according to higher-level or internal guidelines are not being backed up.","Case 4: Although higher-level or internal guidelines stipulate that recovery tests for backup media should be conducted periodically, recovery tests have not been performed for an extended period."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 11 (Safety Measures for Disaster Recovery)"]}],"description": "To maintain the availability and data integrity of the information system, procedures must be established and implemented regarding the backup targets, frequency, methods, storage locations, retention periods, and disaster recovery. Additionally, management must ensure timely recovery in case of incidents.","checks_status": {"fail": 11,"pass": 8,"total": 37,"manual": 0}},"2.9.4": {"name": "Log and Access Record Management","checks": {"macie_is_enabled": "PASS","elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","inspector2_is_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","ec2_ebs_public_snapshot": "PASS","eventbridge_bus_exposed": "PASS","rds_snapshots_encrypted": "FAIL","s3_bucket_public_access": null,"s3_bucket_kms_encryption": "FAIL","cloudtrail_insights_exist": null,"s3_bucket_public_list_acl": null,"s3_bucket_public_write_acl": null,"ec2_ebs_snapshots_encrypted": "FAIL","ec2_instance_managed_by_ssm": "FAIL","efs_not_publicly_accessible": "FAIL","guardduty_centrally_managed": "FAIL","rds_snapshots_public_access": "PASS","s3_bucket_default_encryption": "PASS","wafv2_webacl_logging_enabled": "FAIL","iam_securityaudit_role_created": null,"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","config_recorder_all_regions_enabled": null,"s3_access_point_public_access_block": "PASS","s3_bucket_level_public_access_block": "PASS","eventbridge_bus_cross_account_access": "FAIL","s3_bucket_policy_public_write_access": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"s3_account_level_public_access_blocks": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"apigatewayv2_api_access_logging_enabled": "FAIL","cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"s3_bucket_server_access_logging_enabled": "FAIL","cloudfront_distributions_logging_enabled": null,"documentdb_cluster_cloudwatch_log_export": null,"ec2_instance_detailed_monitoring_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_cross_account_sharing_disabled": null,"kafka_cluster_enhanced_monitoring_enabled": null,"acm_certificates_transparency_logs_enabled": "PASS","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","cloudwatch_log_metric_filter_policy_changes": null,"eks_control_plane_logging_all_types_enabled": null,"ec2_ebs_snapshot_account_block_public_access": null,"iam_inline_policy_no_full_access_to_cloudtrail": null,"trustedadvisor_premium_support_plan_subscribed": null,"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL","cloudwatch_log_metric_filter_sign_in_without_mfa": null,"directoryservice_directory_monitor_notifications": null,"eventbridge_schema_registry_cross_account_access": "FAIL","glue_etl_jobs_cloudwatch_logs_encryption_enabled": "FAIL","opensearch_service_domains_audit_logging_enabled": null,"directoryservice_directory_log_forwarding_enabled": null,"ec2_client_vpn_endpoint_connection_logging_enabled": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS","cloudwatch_log_metric_filter_authentication_failures": null,"opensearch_service_domains_cloudwatch_logging_enabled": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"route53_public_hosted_zones_cloudwatch_logging_enabled": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudtrail_multi_region_enabled_logging_management_events": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","glue_development_endpoints_cloudwatch_logs_encryption_enabled": null,"awslambda_function_invoke_api_operations_cloudtrail_logging_enabled": "PASS","cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.9.4 Log and Access Record Management","Subdomain": "2.9. System and Service Operation Management","AuditEvidence": ["Log management procedures","Log record details","Access control records for log storage devices","Access records of personal information"],"AuditChecklist": ["Has the organization established log management procedures for information systems such as servers, applications, security systems, and network systems, and is it generating and storing the necessary logs accordingly?","Are log records of information systems securely stored to prevent tampering, theft, or loss, and is access to the log records minimized?","Are access records for personal information processing systems securely stored for a specified period in accordance with legal requirements, including all necessary items?"],"NonComplianceCases": ["Case 1: The detailed criteria and procedures for log recording, retention periods, review frequency, and responsible personnel have not been established.","Case 2: The maximum size for critical logs such as security event logs, application, and service logs (for Windows Server 2008 or later) is not sufficiently configured, resulting in logs not being recorded and retained for the period specified by internal standards.","Case 3: The log records of important Linux/UNIX servers are not separately backed up or adequately protected, allowing users to arbitrarily delete command execution histories and access logs.","Case 4: Upon reviewing access records for the personal information processing system, while the account, access time, and IP address of the user were logged, details about the data subject information handled and the tasks performed (e.g., view, modify, delete, download) were not recorded.","Case 5: The capacity of the log server is insufficient, leaving only two months of access records for the personal information processing system.","Case 6: A personal information processing system handling personal information of 100,000 data subjects is only retaining access logs for one year."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 8 (Retention and Inspection of Access Records)"]}],"description": "The organization must define the types of logs, retention periods, and retention methods for user access records, system logs, and privilege grant records for information systems such as servers, applications, security systems, and network systems, and must securely retain and manage them to prevent tampering, theft, or loss.","checks_status": {"fail": 25,"pass": 15,"total": 81,"manual": 0}},"2.9.5": {"name": "Log and Access Record Inspection","checks": {"cloudtrail_insights_exist": null,"inspector2_active_findings_exist": "FAIL","trustedadvisor_errors_and_warnings": null,"guardduty_no_high_severity_findings": "FAIL","accessanalyzer_enabled_without_findings": "FAIL","cloudtrail_threat_detection_enumeration": null,"cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_cross_account_sharing_disabled": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cognito_user_pool_client_prevent_user_existence_errors": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Control Requirements","Section": "2.9.5 Log and Access Record Inspection","Subdomain": "2.9. System and Service Operation Management","AuditEvidence": ["Log review and monitoring procedures","Log review and monitoring results (review details, reports, etc.)","Access record inspection details for personal information","Criteria and results for verifying reasons for personal information downloads","Evidence of responses to detected anomalies"],"AuditChecklist": ["Are there established log review and monitoring procedures, including the frequency, targets, and methods for detecting errors, misuse (unauthorized access, excessive queries, etc.), fraud, and other anomalies in the information system?","Are the results of log reviews and monitoring reported to the responsible person, and are responses taken following procedures when anomalies are detected?","Are access records of the personal information processing system regularly inspected according to the periods specified in relevant laws?"],"NonComplianceCases": ["Case 1: Monitoring and alert policies (criteria) for abnormal access (e.g., early morning access on holidays, access via bypass routes) or abnormal behaviors (e.g., large-scale data queries or continuous small data queries) on information systems processing important information have not been established.","Case 2: Although periodic inspection/monitoring criteria for access and usage are established in internal guidelines or systems, there is no record of actual review of abnormal access or behavior.","Case 3: The personal information processor sets the inspection frequency of access records for personal information processing systems to once per quarter.","Case 4: The internal management plan for the personal information processor sets criteria for verifying reasons when more than 1,000 items of personal information are downloaded, but the reasons are not verified when such downloads occur."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 8 (Retention and Inspection of Access Records)"]}],"description": "To ensure normal use of the information system and prevent misuse (unauthorized access, excessive queries, etc.) by users, log review criteria for access and usage must be established and inspected periodically, and post-event actions must be taken promptly if issues arise.","checks_status": {"fail": 6,"pass": 0,"total": 26,"manual": 0}},"2.9.6": {"name": "Time Synchronization","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Control Requirements","Section": "2.9.6 Time Synchronization","Subdomain": "2.9. System and Service Operation Management","AuditEvidence": ["Time synchronization settings","Evidence of time synchronization for key systems"],"AuditChecklist": ["Is the system time synchronized with the standard time?","Is regular inspection conducted to ensure that time synchronization is functioning properly?"],"NonComplianceCases": ["Case 1: The time of some critical systems (e.g., security systems, CCTV, etc.) is not synchronized with the standard time, and regular inspections for synchronization are not being conducted.","Case 2: Although internal NTP servers are configured for time synchronization, some systems are not synchronized, and there has been no cause analysis or response."],"RelatedRegulations": []}],"description": "To ensure the accuracy of logs and access records and provide reliable log analysis, the system time must be synchronized with a standard time and regularly maintained.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.9.7": {"name": "Reuse and Disposal of Information Assets","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Control Requirements","Section": "2.9.7 Reuse and Disposal of Information Assets","Subdomain": "2.9. System and Service Operation Management","AuditEvidence": ["Procedures for the disposal and reuse of information assets","Storage media management ledger","Evidence of the disposal of information assets and storage media","Disposal-related outsourcing contracts for information assets and storage media"],"AuditChecklist": ["Are secure reuse and disposal procedures for information assets established and implemented?","When reusing or disposing of information assets and storage media, are personal and critical information processed to be irrecoverable?","If information assets and storage media are disposed of internally, are the disposal records maintained in a management ledger along with evidence of disposal?","If disposal is outsourced to an external company, are disposal procedures specified in the contract and is the complete disposal confirmed?","Are measures in place to protect data on storage media during maintenance, repairs, or replacements of systems and PCs?"],"NonComplianceCases": ["Case 1: Although the policy and procedure require the complete deletion of data using a data deletion program when reusing PCs used by personal information handlers, in practice, PCs are reused without complete deletion or are only formatted before reuse, indicating that procedures are not being followed.","Case 2: Although storage media are disposed of through an external company, the contract lacks details on secure disposal procedures and protective measures, and there is no verification or supervision of the disposal process or evidence of compliance.","Case 3: Instead of recording the serial numbers of disposed HDDs, the system names are recorded, or the disposal ledger is not maintained, making it impossible to verify the disposal history and traceability.","Case 4: Discarded hard disks are left unsecured in an area without locks, and the data has not been fully deleted."],"RelatedRegulations": ["Personal Information Protection Act, Article 21 (Destruction of Personal Information)","Standards for Ensuring the Safety of Personal Information, Article 13 (Destruction of Personal Information)"]}],"description": "To prevent the recovery or regeneration of personal and critical information during the reuse and disposal process, secure reuse and disposal procedures for information assets must be established and implemented.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.1": {"name": "Collection and Use of Personal Information","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.1.1 Collection and Use of Personal Information","Subdomain": "3.1. Protection Measures during Personal Information Collection","AuditEvidence": ["Online personal information collection forms (e.g., website sign-up screens, mobile app registration screens, event participation forms)","Offline personal information collection forms (e.g., membership application forms)","Records of personal information collection consent (e.g., member databases)","Records of legal guardian consent","Privacy policy"],"AuditChecklist": ["When collecting personal information, is it collected in accordance with lawful requirements such as obtaining the data subject’s consent, complying with legal obligations, or concluding and fulfilling contracts?","When obtaining consent from the data subject for the collection of personal information, are the method and timing of obtaining consent appropriate?","When obtaining consent from the data subject for the collection of personal information, are the relevant details clearly communicated, and are significant points required by law highlighted in a way that is easy to understand?","When collecting, using, or providing personal information from children under the age of 14, are necessary details notified to their legal representatives, and is consent obtained?","When obtaining the consent of a legal representative, is only the minimum necessary personal information collected, and are procedures and methods in place to verify the qualifications of the legal representative?","When notifying children under the age of 14 about matters related to the processing of their personal information, are the notifications presented in a format and language that is clear and easy to understand?","Are records of consent obtained from data subjects and legal representatives being retained?","For personal information that can be processed without the consent of the data subject, are the relevant items and legal basis for processing disclosed in the privacy policy or communicated to the data subject separately from the personal information processed with consent?","When personal information is used for additional purposes without the consent of the data subject, are criteria established and implemented to assess the relevance to the original purpose, predictability, impact on the data subject, and safety measures? If additional usage continues to occur, are these criteria disclosed in the privacy policy and regularly reviewed?"],"NonComplianceCases": ["Case 1: A personal information processor subject to the Personal Information Protection Act failed to include the 'right to refuse consent and the consequences of refusal' in the notifications when obtaining consent to collect personal information.","Case 2: During the process of obtaining consent for the collection of personal information, the items of personal information to be collected were not specified in detail, and were instead described in general terms like 'etc.'","Case 3: On a shopping mall website, personal information necessary for membership registration was collected alongside payment and delivery information required for future purchases, even though such information was not necessary at the time of registration.","Case 4: Personal information (e.g., name, email, phone number) was collected through Q&A boards without obtaining the data subject's consent.","Case 5: Personal information of children under the age of 14 was collected without obtaining the consent of their legal guardians.","Case 6: Although the service was not intended for children under 14, some members were under 14 because the website did not check birthdates during registration, allowing them to register without legal guardian consent.","Case 7: The procedure for verifying the authenticity of the legal representative was insufficient, allowing individuals who were not legal guardians to provide consent.","Case 8: Personal information (e.g., name, phone number) of legal guardians was collected for the purpose of obtaining their consent to collect personal information from children under the age of 14, but the consent of the legal guardian was not confirmed for an extended period, and the information was retained without being destroyed.","Case 9: Personal information of children under 14 was collected based on the consent of their legal guardians, but records of this consent were not maintained, making it impossible to verify the details related to legal guardian consent (e.g., legal guardian’s name, time of consent)."],"RelatedRegulations": ["Personal Information Protection Act, Article 15 (Collection and Use of Personal Information), Article 22 (Methods for Obtaining Consent), Article 22-2 (Protection of Personal Information of Children)","Notice on the Processing of Personal Information"]}],"description": "Personal information must be collected and used lawfully and fairly. When collecting personal information based on the consent of the data subject, such consent must be obtained through legal means. Additionally, when collecting personal information from children under the age of 14, consent must be obtained from their legal representative, and it must be verified that such consent was given by the legal representative.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.2": {"name": "Restrictions on the Collection of Personal Information","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.1.2 Restrictions on the Collection of Personal Information","Subdomain": "3.1. Protection Measures during Personal Information Collection","AuditEvidence": ["Online personal information collection forms (e.g., website sign-up screens, event participation forms)","Offline personal information collection forms (e.g., membership application forms)","Privacy policy"],"AuditChecklist": ["When collecting personal information, is only the minimum amount of information necessary for the intended purpose being collected?","When collecting personal information based on the data subject’s consent, is the data subject clearly informed that they can refuse to consent to the collection of additional personal information beyond the minimum required?","Is the data subject not denied goods or services for refusing to consent to the collection of additional personal information beyond the minimum necessary for the intended purpose?"],"NonComplianceCases": ["Case 1: Although personal information was being collected based on the fulfillment of a contract, excessive personal information not essential to the fulfillment of the contract was being collected.","Case 2: During the process of obtaining consent from the data subject for optional information, the data subject was not explicitly informed that they could refuse to provide such information.","Case 3: Although the sign-up form distinguished between required and optional information, the data subject was not clearly informed that they could complete registration without providing optional information (e.g., there was no indication on the personal information entry form of which fields were required and which were optional).","Case 4: On the website registration page, the data subject was unable to proceed or complete registration if they refused to provide optional information or consent to optional matters.","Case 5: During the hiring process, excessive personal information unrelated to the job position (e.g., family details) was collected."],"RelatedRegulations": ["Personal Information Protection Act, Article 16 (Restrictions on the Collection of Personal Information), Article 22 (Methods for Obtaining Consent)"]}],"description": "When collecting personal information, only the minimum amount of personal information necessary for the intended purpose may be collected, and the data subject must not be denied the provision of goods or services for refusing to consent to optional matters.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.3": {"name": "Restrictions on the Processing of Resident Registration Numbers","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.1.3 Restrictions on the Processing of Resident Registration Numbers","Subdomain": "3.1. Protection Measures during Personal Information Collection","AuditEvidence": ["Personal information collection forms (e.g., website sign-up screens, event participation forms, membership application forms)","Online personal information collection forms (alternative registration methods for identity verification)","Evidence of legal grounds for processing resident registration numbers","Privacy policy"],"AuditChecklist": ["Are resident registration numbers only processed when there is a clear legal basis?","Is the legal provision that forms the basis for the collection of resident registration numbers clearly identified?","When processing resident registration numbers under a legal basis, does the organization provide a method for data subjects to register without using their resident registration number during the membership registration process on an internet website?"],"NonComplianceCases": ["Case 1: Resident registration numbers were collected for simple membership management purposes, such as identity verification, during website sign-up based on the data subject's consent.","Case 2: Resident registration numbers were collected based on provisions in enforcement rules or local ordinances.","Case 3: The last 6 digits of the resident registration number were collected for identity verification, such as during password recovery, without any legal basis.","Case 4: Resident registration numbers were collected from job applicants during the hiring process without a legal basis.","Case 5: Resident registration numbers were collected during customer service inquiries at a call center for identity verification purposes.","Case 6: Even when there was a legal basis for the collection of resident registration numbers, alternative registration methods were not provided during the membership registration process on the website, and resident registration numbers were required for identity verification and membership registration."],"RelatedRegulations": ["Personal Information Protection Act, Article 24-2 (Restrictions on the Processing of Resident Registration Numbers)","Information and Communications Network Act, Article 23-2 (Restrictions on the Use of Resident Registration Numbers)"]}],"description": "Resident registration numbers may not be collected, used, or processed unless there is a legal basis for doing so. Even when the processing of resident registration numbers is permitted, alternative methods must be provided, such as through an internet website.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.4": {"name": "Restriction on Processing of Sensitive and Unique Identifying Information","checks": {},"status": "PASS","attributes": [{"Domain": "3. Personal Information Processing Requirements","Section": "3.1.4 Restriction on Processing of Sensitive and Unique Identifying Information","Subdomain": "3.1. Protection Measures for Personal Information Collection","AuditEvidence": ["Online personal information collection forms (e.g., membership sign-up pages, event participation forms)","Offline personal information collection forms (e.g., membership application forms)","Privacy policy"],"AuditChecklist": ["Is sensitive information processed only with the separate consent of the data subject or when legally required?","Is unique identifying information (excluding resident registration numbers) processed only with the separate consent of the data subject or when there is a specific legal basis?","If there is a risk of invasion of privacy due to the disclosure of sensitive information during the provision of goods or services, is the data subject clearly informed of the possibility of such disclosure and how to opt for non-disclosure before the provision of goods or services?"],"NonComplianceCases": ["Case 1: Collecting sensitive information such as disability status for discounts or benefits for disabled individuals, and obtaining blanket consent for all personal information items.","Case 2: Collecting foreign registration numbers only from foreigners during membership registration, and obtaining blanket consent for all personal information items.","Case 3: When obtaining separate consent for the collection of sensitive or unique identifying information, failing to inform or incorrectly informing the data subject about the four key points that must be disclosed (e.g., the right to refuse consent and the consequences of refusal)."],"RelatedRegulations": ["Personal Information Protection Act, Article 23 (Restrictions on Processing of Sensitive Information), Article 24 (Restrictions on Processing of Unique Identifying Information)"]}],"description": "In order to process sensitive information and unique identifying information (excluding resident registration numbers), separate consent from the data subject must be obtained unless the processing is specifically required or permitted by law.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.5": {"name": "Indirect Collection of Personal Information","checks": {},"status": "PASS","attributes": [{"Domain": "3. Personal Information Processing Requirements","Section": "3.1.5 Indirect Collection of Personal Information","Subdomain": "3.1. Protection Measures for Personal Information Collection","AuditEvidence": ["Contracts related to the provision of personal information (agreements with providers)","Records of notifications to data subjects about the source of personal information","Privacy policy"],"AuditChecklist": ["When receiving personal information from a third party, is it clearly stated in the contract that the responsibility for obtaining consent for the collection of personal information lies with the party providing the information?","When collecting personal information from public media or places, is the collection limited to the scope recognized as having the data subject's consent, based on common societal standards?","Even for personal information collected or generated through automated collection devices during the process of providing services, is the principle of minimum collection applied?","When personal information is collected from a source other than the data subject and the data subject requests it, is the required information immediately provided to the data subject?","When personal information collected from a source other than the data subject meets legal requirements in terms of type or scale, is the required information provided to the data subject?","Is there a record of informing the data subject about the source of personal information, and is this record maintained until the personal information is destroyed?"],"NonComplianceCases": ["Case 1: In the case of collecting personal information published on websites or social media, there is no procedure for handling requests from data subjects about the source of the information.","Case 2: Personal information provided by another business entity was received based on consent for the provision of personal information under Article 17(1)(1) of the Personal Information Protection Act, but the data subjects were not notified within three months (note: this applies to cases where the recipient handles the personal information of more than 50,000 data subjects, sensitive information, or unique identifying information, or processes personal information of over 1 million data subjects).","Case 3: The data subject was informed about the source of the personal information as required by law, but some mandatory notification items were omitted, such as the purpose of processing or the right to withdraw consent.","Case 4: The data subject was informed about the source of the personal information, but the record of this notification was not maintained until the personal information was destroyed, in violation of legal obligations."],"RelatedRegulations": ["Personal Information Protection Act, Article 16 (Restrictions on the Collection of Personal Information), Article 19 (Restrictions on Use and Provision of Personal Information Provided by a Third Party), Article 20 (Notification of the Source, Purpose, etc. of Indirectly Collected Personal Information)"]}],"description": "When collecting personal information from sources other than the data subject or when receiving personal information from a third party, only the minimum amount of personal information necessary for the task should be collected or received. If there is a legal basis or at the request of the data subject, the source of the personal information, the purpose of processing, and the right to request a suspension of processing must be disclosed.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.6": {"name": "Installation and Operation of Video Information Processing Devices","checks": {},"status": "PASS","attributes": [{"Domain": "3. Personal Information Processing Requirements","Section": "3.1.6 Installation and Operation of Video Information Processing Devices","Subdomain": "3.1. Protection Measures for Personal Information Collection","AuditEvidence": ["Status of video information processing device operation","Signs for video information processing devices","Video information processing device operation and management policies","Management screens for video information processing devices (e.g., account/permission details, video retention periods)","Contracts with operators of video information processing devices and inspection records"],"AuditChecklist": ["When installing and operating fixed video information processing devices in public places, is it reviewed whether the installation meets legal requirements?","If public institutions install and operate fixed video information processing devices in public places, are public hearings or explanation sessions held to gather opinions from relevant experts and stakeholders, as required by law?","When installing and operating fixed video information processing devices, are necessary measures taken, such as installing signs to ensure the data subject can easily recognize the presence of the devices?","When operating mobile video information processing devices in public places for business purposes, is it reviewed whether the operation meets legal requirements?","When operating mobile video information processing devices in public places for business purposes, is the fact that the video is being recorded indicated and informed to the public through lights, sounds, or signs?","Is there an operation and management policy in place for the safe management of video information processing devices and the video information they record, and is it being implemented?","Is the retention period for video information set, and is the information destroyed without delay after the retention period expires?","When outsourcing the operation of video information processing devices, are the related procedures and requirements reflected in the contract?"],"NonComplianceCases": ["Case 1: The wording on the signs for video information processing devices is incomplete, or there is no established and implemented policy for the operation and management of video information processing devices.","Case 2: Although there is a policy for the operation and management of video information processing devices, the policy is not followed, such as failing to comply with the retention period or failing to implement access control and logging as described in the policy.","Case 3: The operation of video information processing devices is outsourced, but the legal requirements, such as inspection of the video information management status and provisions regarding liability for damages, are not reflected in the contract.","Case 4: The operation of video information processing devices is outsourced, but the signs for the devices do not include the name and contact information of the contractor."],"RelatedRegulations": ["Personal Information Protection Act, Article 25 (Restrictions on the Installation and Operation of Fixed Video Information Processing Devices), Article 25-2 (Restrictions on the Operation of Mobile Video Information Processing Devices)"]}],"description": "When installing and operating fixed video information processing devices in public places or operating mobile video information processing devices in public places for business purposes, legal requirements must be followed according to the purpose and location of the installation, and appropriate protection measures must be established and implemented.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.7": {"name": "Collection and Use of Personal Information for Marketing Purposes","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.1.7 Collection and Use of Personal Information for Marketing Purposes","Subdomain": "3.1. Protection Measures When Collecting Personal Information","AuditEvidence": ["Online personal information collection forms (e.g., website membership sign-up, mobile app sign-up, event participation)","Offline personal information collection forms (e.g., membership application forms)","Marketing consent records","Records of consent for receiving advertising information and confirmation of consent","Administrator screen for advertising information transmission systems (e.g., email, SMS, app push notifications)","Advertising information transmission content","Personal information processing policy"],"AuditChecklist": ["When obtaining consent from data subjects to process personal information for the purpose of promoting or recommending goods or services, is the data subject clearly informed, and is separate consent obtained?","When sending advertising information for profit using electronic transmission media, is the recipient's explicit prior consent obtained, and is the consent reconfirmed every two years?","When a recipient indicates refusal or withdraws prior consent for receiving advertising information for profit, is the transmission of such advertising information stopped?","When sending advertising information for profit, is the sender's name, method for opting out, etc., clearly stated, and are such messages not sent during nighttime hours?"],"NonComplianceCases": ["Case 1: When collecting personal information for 'promotion and marketing' purposes, the purpose is vaguely explained (e.g., 'providing additional services', 'providing partner services') or blanket consent is obtained without distinguishing between different purposes.","Case 2: Even after a user has expressed refusal to receive advertising push notifications via a mobile app, such notifications are sent due to a program error.","Case 3: The option to receive advertising information via text messages or email is pre-selected by default on the online sign-up page.","Case 4: The recipient's consent for receiving advertising information is not reconfirmed every two years.","Case 5: When sending advertising information for profit via email, the subject line does not begin with '(Advertisement)'."],"RelatedRegulations": ["Personal Information Protection Act, Article 22 (Method of Obtaining Consent)","Information and Communications Network Act, Article 50 (Restrictions on Transmission of Advertising Information)"]}],"description": "When collecting and using personal information for marketing purposes, such as promoting goods or services, sales recommendations, or sending advertising information, the purpose must be clearly communicated to the data subject, and their consent must be obtained.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.2.1": {"name": "Management of Personal Information Status","checks": {"macie_is_enabled": "PASS","s3_bucket_lifecycle_enabled": "FAIL"},"status": "FAIL","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.2.1 Management of Personal Information Status","Subdomain": "3.2. Protection Measures When Retaining and Using Personal Information","AuditEvidence": ["Personal information status table","Personal information flowchart","Registration status of personal information files","Personal information file management ledger","Personal information processing policy-related personal information files","Personal information files related to investigations under the Punishment of Tax Offenses Act and the Customs Act","Personal information files for one-time operations deemed to have a low need for continuous management as determined by Presidential Decree","Personal information files for simple tasks such as attending meetings, sending documents or materials, and financial settlements, which have a low need for continuous management","Personal information files processed temporarily for public health or public safety emergencies","Other personal information files collected for one-time tasks that are not stored or recorded","Personal information files classified as confidential under other laws","Personal information files collected or requested for analysis related to national security","Personal video information files processed via video information processing devices","Personal information files retained by financial institutions for handling financial transactions under the Real Name Financial Transactions and Guarantee of Secrecy Act"],"AuditChecklist": ["Is the status of collected and retained personal information, including the items, volume, purpose and method of processing, and retention period, regularly managed?","When a public institution operates or modifies personal information files, are the relevant matters registered with the head of the relevant agency as required by law?","Does the public institution disclose the status of personal information files in the personal information processing policy?"],"NonComplianceCases": ["Case 1: Although personal information files are managed through the website's personal information file registration menu, some personal information files related to website services are missing from the personal information processing policy.","Case 2: Although two months have passed since a new personal information file was created, it has not been registered with the Personal Information Protection Commission.","Case 3: The content of personal information files registered and disclosed with the Personal Information Protection Commission (e.g., items of personal information collected) does not match the actual status of personal information files being processed.","Case 4: A public institution has not registered personal information files with the Personal Information Protection Commission, even though the files do not qualify for exceptions such as employee personal information files or personal information files collected under the Statistics Act."],"RelatedRegulations": ["Personal Information Protection Act, Article 32 (Registration and Disclosure of Personal Information Files)"]}],"description": "The items, volume, purpose and method of processing, and retention period of collected and retained personal information must be regularly managed. In the case of public institutions, such information must be registered with the head of the relevant agency as stipulated by law.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"3.2.2": {"name": "Personal Information Quality Assurance","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.2.2 Personal Information Quality Assurance","Subdomain": "3.2. Protection Measures for Retention and Use of Personal Information","AuditEvidence": ["Form for data subjects to modify/update their personal information (online, offline)","Procedures to maintain the up-to-date status of personal information"],"AuditChecklist": ["Are procedures and methods in place to maintain personal information in an accurate and up-to-date state?","Is there a method provided for data subjects to ensure the accuracy, completeness, and up-to-dateness of their personal information?"],"NonComplianceCases": ["Case 1: Although an identity verification process is implemented when changing member information through the website, the identity verification process is insufficient when changing member information via customer service, making unauthorized changes possible.","Case 2: While an online method is provided for online members to change their personal information, no such method is provided for offline members."],"RelatedRegulations": ["Personal Information Protection Act, Article 3 (Principles of Personal Information Protection)"]}],"description": "Collected personal information must be managed to ensure its accuracy, completeness, and up-to-dateness within the scope necessary for the processing purpose, and procedures must be provided to data subjects to manage their information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.2.3": {"name": "Protection of User Device Access","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.2.3 Protection of User Device Access","Subdomain": "3.2. Protection Measures for Retention and Use of Personal Information","AuditEvidence": ["App access rights consent screen","App access rights settings"],"AuditChecklist": ["When accessing information stored on the user's mobile device or functions installed on the device, are users clearly informed and their consent obtained?","Is it ensured that services are not denied if users do not consent to access rights that are not essential for the service?","Are methods provided for users to consent to or withdraw access rights on their mobile devices?"],"NonComplianceCases": ["Case 1: A smartphone app requests excessive access to personal information areas such as contacts, photos, and messages, even though such access is unnecessary for the service.","Case 2: A service provider's smartphone app accesses information stored on the smartphone and installed functions without notifying the user and obtaining their consent.","Case 3: Consent is obtained for app access rights by informing users that optional permissions are required as essential permissions.","Case 4: A smartphone app supports Android versions below 6.0, where individual consent for access rights is not possible, making it impossible for users to reject optional access rights."],"RelatedRegulations": ["Information and Communications Network Act, Article 22-2 (Consent for Access Rights)"]}],"description": "When accessing information stored on the user's mobile device or functions installed on the mobile device, it is necessary to notify the user clearly and obtain their consent.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.2.4": {"name": "Use and Provision of Personal Information Beyond Purpose","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.2.4 Use and Provision of Personal Information Beyond Purpose","Subdomain": "3.2. Protection Measures for Retention and Use of Personal Information","AuditEvidence": ["Records of personal information use and provision beyond the original purpose (including related evidence such as requests)","Log of personal information use and provision beyond the original purpose (for public institutions)","Records of publication in the official gazette or on the website (for public institutions)","Guidelines for handling information provision requests","Official documents requesting information provision and records of personal information provision"],"AuditChecklist": ["Is personal information used or provided only within the scope of the purpose consented to by the data subject at the time of collection or as permitted by law?","When receiving personal information from a personal information processor, is the information used or provided only within the scope of the purpose for which it was provided?","If personal information is used or provided beyond the scope of the purpose of collection or the purpose for which it was received from a personal information processor, is additional consent obtained from the data subject or limited to cases with a legal basis?","When providing personal information to a third party for purposes beyond the original purpose, is the recipient required to take necessary actions to restrict the use of personal information and ensure safety?","When public institutions use or provide personal information beyond the original purpose, are the legal basis, purpose, and scope published in the official gazette or on the internet?","When public institutions use or provide personal information beyond the original purpose, is there a record of such use or provision and are procedures in place for managing it?"],"NonComplianceCases": ["Case 1: Personal information collected for product delivery is used for telemarketing of other company products without prior consent.","Case 2: Personal information collected for customer satisfaction surveys or sweepstakes entries is used for advertising other promotional events without consent.","Case 3: A public institution provides personal information to another institution for purposes outside the scope of the original purpose based on legal grounds but does not publish the information in the official gazette or on the internet.","Case 4: A public institution provides personal information to a police department for criminal investigation purposes but fails to record the details in the log of personal information use and provision beyond the original purpose."],"RelatedRegulations": ["Personal Information Protection Act, Article 18 (Restriction on the Use and Provision of Personal Information Beyond the Original Purpose), Article 19 (Restriction on Use and Provision by Recipients of Personal Information)"]}],"description": "Personal information must only be used or provided within the scope notified and consented to by the data subject at the time of collection or as permitted by law. If personal information is to be used or provided beyond this scope, additional consent must be obtained from the data subject or the legality must be verified, and appropriate protective measures must be established and implemented.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.2.5": {"name": "Processing of Pseudonymized Information","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.2.5 Processing of Pseudonymized Information","Subdomain": "3.2. Protection Measures for Retention and Use of Personal Information","AuditEvidence": ["Procedures and results of the adequacy review of pseudonymization/anonymization","Records of pseudonymized information processing","Privacy policy (regarding the use and provision of pseudonymized information)"],"AuditChecklist": ["When processing pseudonymized information, are procedures established for purpose limitation, pseudonymization methods and standards, adequacy review, prohibition of re-identification, and actions in case of re-identification?","When using or providing pseudonymized personal information, is the information pseudonymized to a level where individuals cannot be identified without using or combining additional information?","When combining pseudonymized information with that of other personal information processors, is the combination conducted through a specialized agency or data professional organization?","When processing pseudonymized information, are technical, administrative, and physical measures taken to ensure safety, such as deleting or separately storing additional information and keeping records?","Is the processing period for pseudonymized information set to an appropriate period considering the processing purpose, and is the information destroyed without delay when that period expires?","When anonymizing personal information, is the information anonymized to a level where individuals cannot be identified even with the use of additional information, considering the time, cost, and technology available?"],"NonComplianceCases": ["Case 1: When processing pseudonymized information for statistical purposes or scientific research without obtaining consent from data subjects, records of the pseudonymization process were not kept, or the privacy policy was not updated to include relevant information.","Case 2: Additional information was not stored separately from pseudonymized information in the same database, or access rights to both sets of information were not appropriately segregated.","Case 3: Although pseudonymized personal information was used, the pseudonymization process was not sufficient, making it possible to identify individuals by combining the information with other data without using additional information.","Case 4: Personal information was anonymized for generating test data or for public release, but due to outliers or other factors, it was still possible to identify individuals, indicating that the anonymization process was not sufficient."],"RelatedRegulations": ["Personal Information Protection Act, Article 2 (Definitions), Article 28-2 (Processing of Pseudonymized Information), Article 28-3 (Restrictions on Combining Pseudonymized Information), Article 28-4 (Obligations for the Safe Processing of Pseudonymized Information), Article 28-5 (Prohibition of Re-identification in Processing Pseudonymized Information), Article 28-7 (Scope of Application), Article 58-2 (Exemptions)"]}],"description": "When processing pseudonymized information, legal requirements such as purpose limitation, combination restrictions, safety measures, and prohibition obligations must be met, and procedures must be established and implemented to ensure an appropriate level of pseudonymization.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.3.1": {"name": "Provision of Personal Information to Third Parties","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.3.1 Provision of Personal Information to Third Parties","Subdomain": "3.3. Protective Measures When Providing Personal Information","AuditEvidence": ["Forms related to the provision of personal information to third parties online (e.g., membership registration page, consent for third-party provision on websites)","Forms related to the provision of personal information to third parties offline (e.g., membership application forms, consent forms for third-party provision)","Records of third-party provisions","Privacy policy"],"AuditChecklist": ["When providing personal information to third parties, are legal requirements such as consent from the data subject or compliance with legal obligations clearly identified and followed?","When obtaining consent from the data subject for the provision of personal information to third parties, are the related matters clearly communicated, and is consent legally obtained by distinguishing it from other consents?","When obtaining consent from the data subject for the provision of personal information to third parties, are important matters clearly indicated and made easily understandable as required by law?","When providing personal information to third parties, is the information limited to the minimum necessary for the intended purpose?","When providing personal information to third parties, is it done through secure procedures and methods, and is the provision recorded and stored?","When allowing third parties to access personal information, is control implemented in accordance with protection procedures to securely protect the personal information?","When providing additional personal information without the data subject's consent, are criteria for determining the relevance to the original purpose of collection, predictability, potential harm, and safety measures established and followed? If such provisions continue, are these criteria disclosed in the privacy policy and periodically reviewed?"],"NonComplianceCases": ["Case 1: When obtaining consent from the data subject for the provision of personal information to third parties, some necessary information (e.g., the right to refuse consent, the items provided) was omitted.","Case 2: In the process of providing personal information to third parties, personal information from data subjects who did not consent was provided due to improper verification of consent.","Case 3: When obtaining consent for the provision of personal information, the recipient was not specifically identified and was vaguely referred to as Ź»~ etc.ʼ in the consent.","Case 4: Although third-party provision consent was optional during the membership registration process, if the data subject did not agree to third-party provision, the registration process could not be completed.","Case 5: An excessive amount of personal information was provided beyond what was necessary for the recipient's purpose of use."],"RelatedRegulations": ["Personal Information Protection Act, Article 17 (Provision of Personal Information), Article 22 (Methods of Obtaining Consent)","Notification on the Methods of Processing Personal Information"]}],"description": "When providing personal information to third parties, there must be a legal basis or consent from the data subject, and protection measures must be established and implemented to securely protect personal information during the process of providing access to third parties.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.3.2": {"name": "Outsourcing of Personal Information Processing","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.3.2 Outsourcing of Personal Information Processing","Subdomain": "3.3. Protective Measures When Providing Personal Information","AuditEvidence": ["Privacy policy (disclosing details related to the outsourcing of personal information processing)","Personal information collection forms","Contracts for outsourcing personal information processing","Records of notifications to data subjects regarding outsourced tasks related to promoting or selling goods or services"],"AuditChecklist": ["When outsourcing personal information processing tasks (including sub-outsourcing) to third parties, are the details of the outsourced tasks and the trustees regularly updated and disclosed on the website?","When outsourcing tasks related to promoting or selling goods or services, is the data subject notified of the details of the outsourced tasks and the trustees through methods such as written notice, email, or text messages?"],"NonComplianceCases": ["Case 1: Although the details of the outsourcing of personal information processing tasks were disclosed on the website's privacy policy, some trustees and the details of the outsourced tasks were missing.","Case 2: When outsourcing tasks related to promoting or selling goods or services, the details of the outsourced tasks and trustees were not notified to the data subject through written methods, and instead, the information was disclosed only in the privacy policy.","Case 3: After terminating a contract with an existing trustee for personal information processing, the new trustee was not promptly reflected in the privacy policy.","Case 4: Although the trustee sub-outsourced the personal information processing tasks to a third party, the sub-outsourcing details were not disclosed on the website."],"RelatedRegulations": ["Personal Information Protection Act, Article 26 (Restrictions on the Processing of Personal Information by Outsourcing)"]}],"description": "When outsourcing personal information processing tasks to third parties, the details of the outsourced tasks and the trustee must be disclosed. Additionally, if the task involves promoting or selling goods or services, the details of the outsourced task and the trustee must be notified to the data subject.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.3.3": {"name": "Transfer of Personal Information Due to Business Transfers","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.3.3 Transfer of Personal Information Due to Business Transfers","Subdomain": "3.3. Protective Measures When Providing Personal Information","AuditEvidence": ["Records of notifications to data subjects regarding the transfer of personal information (during business transfers)","Privacy policy"],"AuditChecklist": ["When transferring personal information to another party due to the transfer or merger of all or part of the business, are the necessary matters communicated to the data subjects in advance?","When receiving personal information, does the recipient notify the data subjects without delay regarding the fact that personal information has been received and other necessary matters, if legally required?","Does the recipient of the personal information use the information only for its original purpose at the time of transfer, or provide it to third parties in compliance with the original purpose?"],"NonComplianceCases": ["Case 1: When receiving personal information through business acquisition, the data subjects were not notified of the transfer of personal information, even though the data provider failed to notify them of the transfer.","Case 2: When receiving personal information through business acquisition or merger, no procedures or methods were provided to allow data subjects to opt-out of the transfer, nor were such options communicated to the data subjects."],"RelatedRegulations": ["Personal Information Protection Act, Article 27 (Restrictions on the Transfer of Personal Information Due to Business Transfers)"]}],"description": "When transferring or receiving personal information due to business transfers or mergers, appropriate protection measures such as notifying the data subjects must be established and implemented.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.3.4": {"name": "Transfer of Personal Information Abroad","checks": {"s3_bucket_cross_region_replication": "FAIL"},"status": "FAIL","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.3.4 Transfer of Personal Information Abroad","Subdomain": "3.3. Protection Measures When Providing Personal Information","AuditEvidence": ["Consent form for personal information transfer abroad","Contract related to personal information transfer abroad","Privacy policy","Notification or disclosure records regarding outsourcing or storage of personal information abroad"],"AuditChecklist": ["When transferring personal information abroad, has the data subject been fully informed of all notification requirements and obtained separate consent, or complied with certification or recognition, as required by law?","When informing the data subject about the outsourcing or storage of personal information abroad for the purpose of contract execution, are all necessary details included and communicated appropriately?","Has a contract for the transfer of personal information abroad been established, including compliance with personal information protection laws?","Are necessary measures being taken to protect personal information when transferring it abroad?"],"NonComplianceCases": ["Case 1: Personal information was provided to a foreign company during processing, but separate consent for the transfer of personal information abroad was not obtained, even though the conditions for consent exemption (such as certification or recognition by the recipient country) were not met.","Case 2: While using foreign cloud services (foreign regions) for outsourcing and storing personal information, the relevant details, such as the destination country and transfer method, were not disclosed in the privacy policy or communicated to the data subject.","Case 3: While obtaining consent for the transfer of personal information abroad, only the name of the recipient (company name) was disclosed, and the destination country was not properly notified."],"RelatedRegulations": ["Personal Information Protection Act, Articles 28-8 (Transfer of Personal Information Abroad), 28-9 (Order to Suspend Transfer of Personal Information Abroad), 28-10 (Reciprocity), 28-11 (Applicable Provisions)","Regulations on the Operation of Personal Information Transfer Abroad"]}],"description": "When transferring personal information abroad, appropriate protective measures such as obtaining consent and disclosing relevant details about the transfer must be established and implemented.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.4.1": {"name": "Destruction of Personal Information","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.4.1 Destruction of Personal Information","Subdomain": "3.4. Protection Measures When Destroying Personal Information","AuditEvidence": ["Regulations regarding the retention period and destruction of personal information","Destruction results (e.g., from member databases)","Personal information destruction management records"],"AuditChecklist": ["Has an internal policy been established regarding the retention period and destruction of personal information?","Is personal information being destroyed without delay when the processing purpose is achieved or the retention period has expired?","Is personal information destroyed using safe methods that prevent recovery or reconstruction?","Are records kept of the destruction of personal information and managed properly?"],"NonComplianceCases": ["Case 1: When a member withdraws or the purpose of retention is achieved, personal information was destroyed from the member database, but not from associated systems (CRM, DW) where duplicate personal information was stored.","Case 2: Personal information collected during a specific event was not destroyed or no destruction policy was established, even after the event ended.","Case 3: Personal information collected through a call center (such as call logs, recordings) is retained for three years under the Electronic Commerce Act, but the information was not destroyed even after three years had passed.","Case 4: Due to technical limitations, such as using blockchain, it was not possible to completely destroy personal information, so it was anonymized instead. However, the anonymization process was not done properly, allowing partial re-identification of personal information."],"RelatedRegulations": ["Personal Information Protection Act, Article 21 (Destruction of Personal Information)","Standards for Ensuring the Safety of Personal Information, Article 13 (Destruction of Personal Information)"]}],"description": "The organization must establish an internal policy regarding retention periods and destruction of personal information. When the retention period has expired or the purpose of processing has been achieved, personal information must be destroyed without delay using methods that ensure safety and completeness.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.4.2": {"name": "Measures When Retaining Personal Information After Purpose Is Achieved","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.4.2 Measures When Retaining Personal Information After Purpose Is Achieved","Subdomain": "3.4. Protection Measures When Destroying Personal Information","AuditEvidence": ["Regulations regarding the retention period and destruction of personal information","Current status of separated databases (table structure, etc.)","Access permissions for separated databases"],"AuditChecklist": ["When personal information is retained beyond the retention period or after the processing purpose has been achieved, in accordance with relevant laws, is it limited to the minimum necessary period and only the minimum necessary information?","When personal information is retained beyond the retention period or after the processing purpose has been achieved, is it stored separately from other personal information?","Is personal information that is stored separately processed only within the scope allowed by law?","Is access to separately stored personal information limited to the minimum number of personnel?"],"NonComplianceCases": ["Case 1: Information from withdrawn members was not destroyed but kept for a certain period under the Electronic Commerce Act, with only the flag value changed, and stored in the same table as other member information.","Case 2: Records related to consumer complaints and disputes were kept for five years instead of the required three years, due to misinterpretation of legal requirements.","Case 3: Although a separate database was set up, access permissions were not appropriately configured, allowing personnel who did not require access to view the separated database.","Case 4: Information from withdrawn members was stored separately in accordance with the Electronic Commerce Act, but excessive optional information was also stored, even though there was no legal obligation to do so."],"RelatedRegulations": ["Personal Information Protection Act, Article 21 (Destruction of Personal Information)"]}],"description": "If personal information is retained beyond the retention period or after the purpose of processing has been achieved, as permitted by relevant laws, it must be limited to the minimum necessary items and stored separately from other personal information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.5.1": {"name": "Disclosure of Privacy Policy","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.5.1 Disclosure of Privacy Policy","Subdomain": "3.5. Protection of Data Subject's Rights","AuditEvidence": ["Privacy policy","Records of privacy policy amendments (e.g., board notices)"],"AuditChecklist": ["Is the privacy policy written in clear and easy-to-understand language, covering all the contents required by law?","Is the privacy policy continuously updated and made easily accessible to data subjects via the internet or other means?","When the privacy policy is updated, are the reasons for the changes and the contents of the changes promptly notified, and can the data subjects easily recognize the changes at any time?"],"NonComplianceCases": ["Case 1: The privacy policy discloses information about the collection and provision of personal information, but the actual details differ from what is being collected and provided.","Case 2: Changes such as the replacement of the privacy officer or changes in subcontractors have occurred, but these changes have not been reflected in the privacy policy.","Case 3: The privacy policy is disclosed, but it is labeled 'Privacy Protection Policy' instead of 'Privacy Policy,' and its visibility is not enhanced with larger font sizes or color to make it easy for data subjects to find.","Case 4: Several amendments have been made to the privacy policy, but older versions of the policy are not made available for review.","Case 5: Although personal information is retained in compliance with laws such as the Electronic Commerce Act and the Commercial Act, the legal grounds for retention and the retained personal information items are not disclosed in the privacy policy."],"RelatedRegulations": ["Personal Information Protection Act, Article 30 (Establishment and Disclosure of Privacy Policy), Article 30-2 (Evaluation and Improvement Recommendations for Privacy Policy)"]}],"description": "A privacy policy must be established to include all necessary information, such as the purpose of personal information processing, in a way that is easy for data subjects to understand. The policy must be disclosed through appropriate methods so that data subjects can easily access it at any time, and it must be continuously updated.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.5.2": {"name": "Guaranteeing Data Subject's Rights","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.5.2 Guaranteeing Data Subject's Rights","Subdomain": "3.5. Protection of Data Subject's Rights","AuditEvidence": ["Privacy policy","Procedures and forms for handling Requests for Access, etc.","Records of actions taken in response to Requests for Access, etc.","Procedures for member withdrawal and consent withdrawal"],"AuditChecklist": ["Are procedures in place to ensure that data subjects or their representatives can exercise their rights (hereinafter referred to as 'Requests for Access, etc.') to access, rectify, delete, or suspend the processing of their personal information in a way that is not more difficult than the process used for collecting it?","When data subjects or their representatives submit Requests for Access, etc., are the necessary measures taken within the required time frame?","When data subjects withdraw their consent to the collection, use, or provision of their personal information, are the collected personal information and associated data promptly deleted or otherwise handled appropriately?","Are appropriate procedures in place to allow data subjects to object to the actions taken regarding their Requests for Access, etc., and are they informed of these procedures?","Are records kept of data subjects' Requests for Access, etc., and the resulting actions?","When the rights of others, such as privacy or honor, are violated on information networks, does the organization have procedures for the affected individuals to request the deletion of the information from service providers, and are these procedures being implemented?"],"NonComplianceCases": ["Case 1: The method for requesting access, rectification, deletion, or suspension of personal information is not disclosed in a way that data subjects can easily find.","Case 2: There has been no response to access requests for personal information within 10 days, without any valid reason.","Case 3: Records of actions taken in response to personal information access requests are not maintained.","Case 4: Access notifications are being sent without verifying whether the requester is the data subject or their legitimate representative.","Case 5: There has been a failure to respond to rectification or deletion requests within 10 days.","Case 6: It was easy to sign up online as a member, but to withdraw membership, additional documents such as ID must be submitted, or in-person visits are required."],"RelatedRegulations": ["Personal Information Protection Act, Article 34-2 (Deletion or Blocking of Exposed Personal Information), Article 35 (Access to Personal Information), Article 35-2 (Right to Data Portability), Article 36 (Rectification or Deletion of Personal Information), Article 37 (Suspension of Processing, etc.), Article 37-2 (Right of Data Subjects to Contest Automated Decisions), Article 38 (Methods and Procedures for Exercising Rights)","Information and Communications Network Act, Article 44 (Protection of Rights in Information Networks), Article 44-2 (Request for Deletion of Information, etc.), Article 44-3 (Temporary Measures)"]}],"description": "Procedures must be established and implemented to ensure that data subjects can easily exercise their rights, such as requesting access, rectification, deletion, suspension of processing, objection, or withdrawal of consent, through simpler processes than those used for collecting their information. When a request is received, it must be processed without delay, and records must be kept. Measures such as deletion requests and temporary actions must be taken to prevent the distribution of information that infringes on the rights of others, such as invasion of privacy or defamation.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.5.3": {"name": "Notification to Data Subjects","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.5.3 Notification to Data Subjects","Subdomain": "3.5. Protection of Data Subject's Rights","AuditEvidence": ["Records of notifications regarding the use and provision of personal information","Forms and wording used for notifications regarding the use and provision of personal information"],"AuditChecklist": ["If the organization is legally obligated to do so, does it periodically notify data subjects of the use and provision of their personal information, or provide them with access to an information system where they can review such details?","Do the notification items regarding the use and provision of personal information include all legally required elements?"],"NonComplianceCases": ["Case 1: Although the organization is required to notify data subjects of the use and provision of their personal information, no notifications have been sent during the year despite being obligated due to handling personal information of more than 1 million people on a daily average for the past three months at the end of the previous year.","Case 2: Instead of directly notifying individual data subjects, notifications about the use and provision of personal information were made through simple pop-ups or general announcements on the website."],"RelatedRegulations": ["Personal Information Protection Act, Article 20-2 (Notification of Use and Provision of Personal Information)"]}],"description": "The organization must identify matters that must be notified to data subjects, such as the use and provision of personal information, and periodically inform the data subjects of these matters.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.10.1": {"name": "Security System Operation","checks": {"kms_cmk_are_used": null,"macie_is_enabled": "PASS","securityhub_enabled": "PASS","fms_policy_compliant": null,"guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","elbv2_waf_acl_attached": "FAIL","kms_cmk_rotation_enabled": null,"ec2_securitygroup_not_used": "FAIL","guardduty_centrally_managed": "FAIL","wafv2_webacl_logging_enabled": "FAIL","ssm_managed_compliant_patching": "FAIL","kms_key_not_publicly_accessible": null,"ssmincidents_enabled_with_plans": null,"inspector2_active_findings_exist": "FAIL","cloudfront_distributions_using_waf": null,"cognito_user_pool_waf_acl_attached": null,"trustedadvisor_errors_and_warnings": null,"apigateway_restapi_waf_acl_attached": "FAIL","config_recorder_all_regions_enabled": null,"guardduty_no_high_severity_findings": "FAIL","ec2_securitygroup_from_launch_wizard": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","organizations_delegated_administrators": null,"ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_instance_port_ftp_exposed_to_internet": "PASS","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","secretsmanager_automatic_rotation_enabled": "FAIL","ec2_instance_port_cifs_exposed_to_internet": "PASS","ec2_instance_port_ldap_exposed_to_internet": "PASS","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_instance_port_kafka_exposed_to_internet": "PASS","ec2_instance_port_mysql_exposed_to_internet": "PASS","ec2_instance_port_redis_exposed_to_internet": "PASS","ec2_instance_port_oracle_exposed_to_internet": "PASS","ec2_instance_port_telnet_exposed_to_internet": "PASS","ec2_instance_port_mongodb_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_instance_port_kerberos_exposed_to_internet": "PASS","ec2_instance_port_cassandra_exposed_to_internet": "PASS","ec2_instance_port_memcached_exposed_to_internet": "PASS","ec2_instance_port_sqlserver_exposed_to_internet": "PASS","cloudwatch_log_metric_filter_sign_in_without_mfa": null,"ec2_instance_port_postgresql_exposed_to_internet": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","shield_advanced_protection_in_global_accelerators": null,"ec2_instance_internet_facing_with_instance_profile": "FAIL","shield_advanced_protection_in_route53_hosted_zones": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_authentication_failures": null,"shield_advanced_protection_in_associated_elastic_ips": null,"shield_advanced_protection_in_classic_load_balancers": null,"shield_advanced_protection_in_cloudfront_distributions": null,"ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","ec2_instance_port_elasticsearch_kibana_exposed_to_internet": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","shield_advanced_protection_in_internet_facing_load_balancers": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Security Control Requirements","Section": "2.10.1 Security System Operation","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Security system configuration","Network configuration","Security system operational procedures","Firewall policies","Firewall policy setup/modification request forms","Exception list for the security system","Management screens for each security system (firewall, IPS, server access control, DLP, DRM, etc.)","Security system policy review history"],"AuditChecklist": ["Has the organization established and implemented operational procedures for the security systems in use?","Is access to the security system administrators limited to a minimum, and is unauthorized access strictly controlled?","Has the organization established and implemented formal procedures for registering, modifying, and deleting policies for each security system?","Are exception policies for the security system managed according to procedures, and are users of exception policies managed with the minimum privileges?","Is the validity of the policies set on the security system periodically reviewed?","Has the organization installed and operated security systems that perform functions specified by law to prevent illegal access and data leakage in personal information processing systems?"],"NonComplianceCases": ["Case 1: Regular reviews of the security policies for the intrusion prevention system were not conducted, resulting in unnecessary or excessively permissive policies.","Case 2: There are no procedures or criteria for applying, modifying, or deleting security policies, or such procedures exist but are not followed.","Case 3: The assignment and supervision of administrators for the security system were not properly implemented.","Case 4: Although internal guidelines stipulate that the information security officer must record and maintain the history of security policy changes for the security system, the policy management ledger was not periodically maintained, or the policies recorded in the ledger did not match those actually applied in the operating system."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 6 (Access Control)"]}],"description": "For each type of security system, an administrator must be designated, and operational procedures such as updating to the latest policies, modifying rule sets, and monitoring events must be established and implemented. The status of policy application for each security system must be managed.","checks_status": {"fail": 16,"pass": 39,"total": 75,"manual": 0}},"2.10.2": {"name": "Cloud Security","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protective Measure Requirements","Section": "2.10.2 Cloud Security","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Cloud service-related contracts and SLA","Cloud service risk analysis results","Cloud service security control policies","Cloud service administrator privilege assignment status","Cloud service architecture diagram","Cloud service security setting status","Cloud service security setting appropriateness review history"],"AuditChecklist": ["Is the responsibility and role for information protection and personal information protection clearly defined with the cloud service provider, and is it reflected in contracts (such as SLA)?","Are security risks based on the service type evaluated when using cloud services, and are security control policies established and implemented, including security configurations and setting standards, security setting changes and approval procedures, secure connection methods, and authority systems to prevent unauthorized access and configuration errors?","Are administrator privileges for cloud services granted minimally according to roles, and are enhanced protection measures such as strengthened authentication, encryption, access control, and audit logs applied to prevent unauthorized access and abuse of privileges?","Is the monitoring of cloud service security setting changes and operation status conducted, and is the appropriateness of these settings reviewed regularly?"],"NonComplianceCases": ["Case 1: The cloud service contract does not include responsibilities and roles related to security.","Case 2: Employees without a business need have been excessively granted permissions to change the security settings of the cloud service.","Case 3: Internal guidelines require security officer approval when changing access control rules in the private network of the cloud, but many access control rules were registered or changed without following the approval procedure.","Case 4: Due to security setting errors in the cloud service, internal log files were exposed to the internet."],"RelatedRegulations": []}],"description": "When using cloud services, protection measures must be established and implemented for administrator access and security settings to prevent unauthorized access and configuration errors that could lead to the leakage or exposure of critical information and personal data, depending on the service type (SaaS, PaaS, IaaS, etc.).","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.10.3": {"name": "Public Server Security","checks": {"elb_ssl_listeners": "FAIL","elbv2_ssl_listeners": "FAIL","ssm_document_secrets": "PASS","elbv2_waf_acl_attached": "FAIL","elb_insecure_ssl_ciphers": "PASS","apigateway_restapi_public": "FAIL","lightsail_database_public": null,"lightsail_instance_public": null,"elbv2_insecure_ssl_ciphers": "PASS","lightsail_static_ip_unused": null,"networkfirewall_in_all_vpc": "FAIL","ec2_instance_imdsv2_enabled": "PASS","elbv2_desync_mitigation_mode": "FAIL","awslambda_function_inside_vpc": "FAIL","awslambda_function_url_public": null,"ec2_instance_secrets_user_data": "PASS","ec2_launch_template_no_secrets": "PASS","ssm_managed_compliant_patching": "FAIL","inspector2_active_findings_exist": "FAIL","acm_certificates_expiration_check": "PASS","awslambda_function_url_cors_policy": null,"cloudfront_distributions_using_waf": null,"vpc_subnet_separate_private_public": "FAIL","apigateway_restapi_waf_acl_attached": "FAIL","apigatewayv2_api_authorizers_enabled": "FAIL","awslambda_function_no_secrets_in_code": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","apigateway_restapi_authorizers_enabled": "PASS","cloudfront_distributions_https_enabled": null,"ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","apigateway_restapi_public_with_authorizer": "FAIL","ec2_instance_port_ftp_exposed_to_internet": "PASS","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","awslambda_function_no_secrets_in_variables": "PASS","awslambda_function_not_publicly_accessible": "PASS","ec2_instance_port_cifs_exposed_to_internet": "PASS","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","route53_domains_privacy_protection_enabled": null,"ec2_instance_port_kafka_exposed_to_internet": "PASS","ec2_instance_port_mysql_exposed_to_internet": "PASS","ec2_instance_port_redis_exposed_to_internet": "PASS","ec2_instance_port_oracle_exposed_to_internet": "PASS","ec2_instance_port_telnet_exposed_to_internet": "PASS","apigateway_restapi_client_certificate_enabled": "FAIL","ec2_instance_port_mongodb_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_instance_port_kerberos_exposed_to_internet": "PASS","ec2_instance_port_cassandra_exposed_to_internet": "PASS","ec2_instance_port_memcached_exposed_to_internet": "PASS","ec2_instance_port_sqlserver_exposed_to_internet": "PASS","kafka_cluster_mutual_tls_authentication_enabled": null,"ec2_instance_port_postgresql_exposed_to_internet": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","autoscaling_find_secrets_ec2_launch_configuration": "PASS","ec2_instance_internet_facing_with_instance_profile": "FAIL","cloudfront_distributions_using_deprecated_ssl_protocols": null,"ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","ec2_instance_port_elasticsearch_kibana_exposed_to_internet": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Protective Measure Requirements","Section": "2.10.3 Public Server Security","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Network diagram","Website information disclosure procedures and history (e.g., requests, approvals, posting history)","Inspection history of personal and sensitive information exposure"],"AuditChecklist": ["Are protective measures established and implemented for the operation of public servers?","Are public servers installed in a DMZ separated from internal networks and protected by security systems such as firewalls?","When posting or storing personal or sensitive information on public servers, are approval and posting procedures, including obtaining approval from the responsible person, established and followed?","Does the organization regularly check whether sensitive information is being exposed through websites and web servers, and if exposure is detected, are measures taken immediately to block it?"],"NonComplianceCases": ["Case 1: Due to vulnerabilities in publicly exposed websites, unauthorized individuals were able to access others' personal information through Google search.","Case 2: Although internal regulations require approval procedures before posting personal information on websites, there were multiple cases where personal information was posted without following these procedures.","Case 3: In web applications such as bulletin boards, it was possible to arbitrarily modify or delete posts made by others, or view password-protected posts."],"RelatedRegulations": []}],"description": "For servers exposed to external networks, protective measures must be established and implemented, including separating them from internal networks, conducting vulnerability assessments, access control, authentication, and establishing procedures for information collection, storage, and disclosure.","checks_status": {"fail": 19,"pass": 47,"total": 76,"manual": 0}},"2.10.4": {"name": "Security for Electronic Transactions and FinTech","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.10.4 Security for Electronic Transactions and FinTech","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Protection measures for electronic transaction and FinTech services","Security review results for payment system integration"],"AuditChecklist": ["Are protection measures established and implemented to ensure the safety and reliability of transactions when providing electronic transaction and FinTech services?","Are protection measures established and implemented to protect transmitted information when integrating with external systems, such as payment systems, and is the security of the integration checked?"],"NonComplianceCases": ["Case 1: While a contract was made with a payment service provider and integration was established, all payment-related information was transmitted in plain text through a specific URL without appropriate authentication or access restrictions.","Case 2: Although the external payment system was connected via a dedicated network, internal business systems were not properly controlled by firewalls or other security measures.","Case 3: Although internal guidelines required a security review by the information protection team before integrating external FinTech services, the review was skipped due to scheduling reasons when integrating a new FinTech service."],"RelatedRegulations": []}],"description": "When providing electronic transaction and FinTech services, protection measures such as authentication and encryption must be established to prevent data leakage, data tampering, or fraud. The security of external systems, such as payment systems, must be checked when integrated.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.10.5": {"name": "Secure Information Transmission","checks": {"elb_ssl_listeners": "FAIL","elbv2_ssl_listeners": "FAIL","elb_insecure_ssl_ciphers": "PASS","elbv2_insecure_ssl_ciphers": "PASS","rds_instance_transport_encrypted": "FAIL","s3_bucket_secure_transport_policy": "FAIL","glue_database_connections_ssl_enabled": null,"cloudfront_distributions_https_enabled": null,"sns_subscription_not_using_http_endpoints": "PASS","kafka_cluster_in_transit_encryption_enabled": null,"apigateway_restapi_client_certificate_enabled": "FAIL","kafka_cluster_mutual_tls_authentication_enabled": null,"directoryservice_radius_server_security_protocol": null,"cloudfront_distributions_using_deprecated_ssl_protocols": null,"elasticache_redis_cluster_in_transit_encryption_enabled": null,"opensearch_service_domains_https_communications_enforced": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.10.5 Secure Information Transmission","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Information transmission agreement or contract","Technical standards for information transmission","System diagrams and interface definitions related to information transmission"],"AuditChecklist": ["Has a secure transmission policy been established when transmitting personal and critical information to external organizations?","When exchanging personal and critical information between organizations for business purposes, are agreements and protection measures for secure transmission established and implemented?"],"NonComplianceCases": ["Case 1: Although a dedicated network or VPN is applied when integrating with external organizations, there is inadequate management of the timing, method, responsible person, transmitted information, and legal basis for each integration.","Case 2: There is a lack of implementation of security reviews, security standards, and action plans for using weak encryption algorithms (e.g., DES, 3DES) or decrypting during intermediate transmission stages."],"RelatedRegulations": []}],"description": "When transmitting personal or critical information to other organizations, a secure transmission policy must be established, and agreements must be made between organizations regarding management responsibilities, transmission methods, and technical protection measures for personal and critical information.","checks_status": {"fail": 5,"pass": 3,"total": 17,"manual": 0}},"2.10.6": {"name": "Security for Business Devices","checks": {"workspaces_volume_encryption_enabled": null,"appstream_fleet_maximum_session_duration": null,"appstream_fleet_session_disconnect_timeout": null,"workspaces_vpc_2private_1public_subnets_nat": null,"appstream_fleet_session_idle_disconnect_timeout": null,"appstream_fleet_default_internet_access_disabled": null},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.10.6 Security for Business Devices","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Security control guidelines and procedures for business devices","Registration status of business devices","Security settings for business devices","Authentication and approval history for business devices","Security check status for business devices"],"AuditChecklist": ["Are security control policies, such as device authentication, approval, access scope, and security settings, established and implemented for devices used for business purposes, such as PCs, laptops, virtual PCs, and tablets?","Are policies established and implemented to prevent the leakage of personal and critical information through business devices by prohibiting the use of file-sharing programs, limiting shared settings, and controlling wireless network usage?","Are security measures applied to prevent the leakage of personal and critical information in case of loss or theft of business mobile devices?","Is the appropriateness of access control measures for business devices periodically reviewed?"],"NonComplianceCases": ["Case 1: Although laptops and tablet PCs are used for business purposes, there are no policies established for device approval, usage scope, approval procedures, or authentication methods.","Case 2: The security management guidelines for mobile devices prohibit the use of mobile devices for business purposes unless specifically approved, but unapproved mobile devices are still being used to access internal information systems.","Case 3: Personal and critical information is handled on mobile devices, but security measures such as password protection are not applied to prevent leaks due to loss or theft.","Case 4: Although internal regulations prohibit the use of shared folders on business devices, periodic checks are not conducted, resulting in excessive use of shared folders on many business devices."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 6 (Access Control)"]}],"description": "When connecting devices such as PCs and mobile devices to the network for business purposes, access control measures such as device authentication, approval, access scope, and security settings must be established and periodically checked.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"2.10.7": {"name": "Management of Removable Media","checks": {},"status": "PASS","attributes": [{"Domain": "2. Security Control Requirements","Section": "2.10.7 Management of Removable Media","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Policy on blocking removable media (USB, CD, etc.)","Removable media management log","Inspection records of removable media status"],"AuditChecklist": ["Are policies and procedures established and implemented for handling (use), storage, disposal, and reuse of removable media such as external hard drives, USB memory, and CDs?","Is the status of ownership, use, and management of removable media periodically checked?","Is the use of removable media restricted in controlled areas, such as key information systems or important restricted areas?","Are measures in place to prevent the infection of malware and the leakage of important information through removable media?","Are removable media containing personal or important information stored in a secure location with locking mechanisms?"],"NonComplianceCases": ["Case 1: Although there is a policy restricting the use of removable media in controlled areas like server rooms, several cases were found where removable media was used without following the exception approval process, and periodic inspections of the removable media management status were not conducted, resulting in inadequate updates to the management log.","Case 2: Removable media containing personal information was not stored in a secure location with locking mechanisms and was left unattended in office drawers.","Case 3: Although a solution to control removable media was implemented, some users were granted write access without appropriate approval procedures.","Case 4: Some common PCs and IT equipment in the server room allowed writing to standard USB memory devices, but controls such as media import and usage restrictions, usage history records, and reviews were not applied."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 10 (Physical Safety Measures)"]}],"description": "Procedures must be established and implemented to prevent the leakage of personal or important information or infection by malware through removable media. Removable media containing personal or important information must be stored in a secure location.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.10.8": {"name": "Patch Management","checks": {"ssm_managed_compliant_patching": "FAIL","kafka_cluster_uses_latest_version": null,"ec2_instance_account_imdsv2_enabled": null,"redshift_cluster_automatic_upgrades": null,"eks_cluster_uses_a_supported_version": null,"ec2_instance_older_than_specific_days": "FAIL","rds_instance_deprecated_engine_version": "PASS","rds_cluster_minor_version_upgrade_enabled": "PASS","dms_instance_minor_version_upgrade_enabled": null,"rds_instance_minor_version_upgrade_enabled": "PASS","awslambda_function_using_supported_runtimes": "FAIL","elasticache_redis_cluster_auto_minor_version_upgrades": null,"cloudfront_distributions_using_deprecated_ssl_protocols": null,"opensearch_service_domains_updated_to_the_latest_service_software_version": null},"status": "FAIL","attributes": [{"Domain": "2. Security Control Requirements","Section": "2.10.8 Patch Management","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Patch management policies and procedures","Patch status of each system","Impact analysis results related to patch application"],"AuditChecklist": ["Are patch management policies and procedures for operating systems (OS) and software established and implemented according to the characteristics and importance of each asset, such as servers, network systems, security systems, and PCs?","Are the patch status of installed OS and software on key servers, network systems, and security systems periodically managed?","If applying the latest patches to address vulnerabilities is difficult due to service impact, are alternative measures implemented?","Is the application of patches via public internet access restricted for key servers, network systems, and security systems?","When using a patch management system, are sufficient protection measures, such as access control, established?"],"NonComplianceCases": ["Case 1: In some systems, OS patches were not applied for a long period without valid reasons or approval from the responsible personnel.","Case 2: Some systems were using OS versions that were no longer supported (EOS), but no response plans or alternative measures were in place.","Case 3: Although the latest patches were applied to commercial software and OS, there were no procedures or personnel assigned to confirm and apply the latest patches for open-source programs (e.g., OpenSSL, OpenSSH, Apache), resulting in the lack of application of the latest security patches."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 9 (Prevention of Malware, etc.)"]}],"description": "To prevent security incidents due to vulnerabilities in software, operating systems, or security systems, the latest patches must be applied. However, if the application of the latest patches is difficult due to service impact considerations, alternative measures must be implemented.","checks_status": {"fail": 3,"pass": 3,"total": 14,"manual": 0}},"2.10.9": {"name": "Malware Control","checks": {},"status": "PASS","attributes": [{"Domain": "2. Security Control Requirements","Section": "2.10.9 Malware Control","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Guidelines, procedures, and manuals for malware response","Antivirus program installation status","Antivirus program configuration screens","Malware response history (e.g., response reports)"],"AuditChecklist": ["Are protection measures established and implemented to protect information systems and business terminals from malware such as viruses, worms, Trojans, and ransomware?","Are prevention and detection activities for the latest malware continuously performed using security programs such as antivirus software?","Are security programs such as antivirus software kept up to date, and are emergency security updates performed when necessary?","Are procedures for response, such as minimizing the spread of malware and mitigating damage, established and implemented when malware infections are discovered?"],"NonComplianceCases": ["Case 1: Some PCs and servers do not have antivirus software installed, or the antivirus engine has not been updated to the latest version for a long time.","Case 2: Although users can change the antivirus program settings (e.g., real-time scanning, scheduled scanning, update settings) at their discretion, no additional protection measures were established to address this.","Case 3: Insufficient protection measures, such as access control, were in place for the central antivirus management system, leading to the possibility of security incidents through the central management system, or no integrity verification of the antivirus pattern was performed, making it possible for malware to spread through malicious users.","Case 4: Although multiple malware infections were confirmed on some internal network PCs and servers, there was no confirmation of the infection status, infection routes, cause analysis, or resulting actions."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 9 (Prevention of Malware, etc.)"]}],"description": "To protect personal and important information, information systems, and business terminals from malware such as viruses, worms, Trojans, and ransomware, prevention, detection, and response measures must be established and implemented.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.11.1": {"name": "Establishment of Incident Prevention and Response System","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protective Measures Requirements","Section": "2.11.1 Establishment of Incident Prevention and Response System","Subdomain": "2.11. Incident Prevention and Response","AuditEvidence": ["Incident response guidelines/procedures/manual","Incident response organization chart and emergency contact list","Security monitoring service contract (SLA, etc.)"],"AuditChecklist": ["Has the organization established procedures and systems to prevent security breaches and personal information leaks and to respond quickly and effectively when incidents occur?","If the organization is operating an incident response system through an external institution, such as a security monitoring service, are the details of the incident response procedures reflected in the contract?","Has the organization established a cooperative system with external experts, specialized companies, or institutions for monitoring, responding to, and handling security incidents?"],"NonComplianceCases": ["Case 1: Failure to clearly define the incident response organization and procedures for responding to security breaches.","Case 2: Although internal guidelines and procedures specify incident response steps for different phases (before, during, after detection, recovery, reporting, etc.), some or all of the response and recovery procedures for specific incident types and severity levels are not established.","Case 3: Failure to keep the incident response organization chart and emergency contact list up to date, or the roles and responsibilities of each team member are not clearly defined.","Case 4: Errors or outdated information in the contact details for external agencies responsible for incident reporting, notification, and cooperation, or failure to keep some agency details current.","Case 5: When outsourcing incident detection and response to an external security monitoring company or related institution, failure to clearly define the roles and responsibilities for both parties in the contract or SLA.","Case 6: Although incident response procedures are in place, they do not meet the legal requirements for reporting and notifying personal data breaches, such as criteria and timing."],"RelatedRegulations": ["Personal Information Protection Act, Article 34 (Notification and Reporting of Personal Information Leaks, etc.)","Information and Communications Network Act, Article 48-3 (Reporting of Security Incidents), Article 48-4 (Analysis of Causes of Security Incidents, etc.)"]}],"description": "To prevent incidents such as security breaches and personal information leaks, and to respond quickly and effectively in the event of an incident, the organization must establish procedures for detecting, responding to, analyzing, and sharing internal and external intrusion attempts. In addition, the organization must establish a cooperative system with relevant external institutions and experts.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.11.2": {"name": "Vulnerability Inspection and Remediation","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ssm_document_secrets": "PASS","inspector2_is_enabled": "FAIL","ec2_instance_imdsv2_enabled": "PASS","guardduty_centrally_managed": "FAIL","ec2_instance_secrets_user_data": "PASS","ec2_launch_template_no_secrets": "PASS","inspector2_active_findings_exist": "FAIL","trustedadvisor_errors_and_warnings": null,"guardduty_no_high_severity_findings": "FAIL","awslambda_function_no_secrets_in_code": "PASS","cloudwatch_log_group_no_secrets_in_logs": "FAIL","ecr_registry_scan_images_on_push_enabled": "PASS","cloudformation_stack_outputs_find_secrets": "PASS","codebuild_project_no_secrets_in_variables": "PASS","awslambda_function_no_secrets_in_variables": "PASS","ecs_task_definitions_no_environment_secrets": "PASS","ecr_repositories_scan_images_on_push_enabled": "FAIL","trustedadvisor_premium_support_plan_subscribed": null,"autoscaling_find_secrets_ec2_launch_configuration": "PASS","ecr_repositories_scan_vulnerabilities_in_latest_image": null,"codebuild_project_source_repo_url_no_sensitive_credentials": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Protective Measures Requirements","Section": "2.11.2 Vulnerability Inspection and Remediation","Subdomain": "2.11. Incident Prevention and Response","AuditEvidence": ["Vulnerability inspection plan","Vulnerability inspection report (for web, mobile apps, servers, network systems, security systems, DBMS, etc.)","Vulnerability inspection records","Vulnerability remediation plan","Vulnerability remediation completion report","Penetration testing plan/results report"],"AuditChecklist": ["Has the organization established and implemented procedures for conducting regular vulnerability inspections of information systems?","Are actions taken to address identified vulnerabilities, and are the results reported to the responsible authorities?","Does the organization continuously monitor for new security vulnerabilities and assess their impact on the information systems, taking appropriate actions?","Is a record of vulnerability inspections maintained, and are protective measures implemented to address recurring vulnerabilities identified in previous years?"],"NonComplianceCases": ["Case 1: Although internal regulations require annual technical vulnerability inspections for major systems, some major systems were excluded from the inspection.","Case 2: Failure to implement corrective actions for identified vulnerabilities, or failure to provide justification and approval records for vulnerabilities that cannot be addressed promptly."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans), Article 6 (Access Control)"]}],"description": "Regular vulnerability inspections must be conducted to verify whether information systems have exposed vulnerabilities, and any identified vulnerabilities must be promptly addressed. In addition, the organization must continuously monitor for new security vulnerabilities, assess their impact on the information systems, and take necessary actions.","checks_status": {"fail": 6,"pass": 14,"total": 23,"manual": 0}},"2.11.3": {"name": "Abnormal Behavior Analysis and Monitoring","checks": {"securityhub_enabled": "PASS","fms_policy_compliant": null,"vpc_flow_logs_enabled": "FAIL","cloudtrail_insights_exist": null,"networkfirewall_in_all_vpc": "FAIL","trustedadvisor_errors_and_warnings": null,"guardduty_no_high_severity_findings": "FAIL","cloudtrail_threat_detection_enumeration": null,"cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_cross_account_sharing_disabled": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cognito_user_pool_client_prevent_user_existence_errors": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measures Requirements","Section": "2.11.3 Abnormal Behavior Analysis and Monitoring","Subdomain": "2.11. Incident Prevention and Response","AuditEvidence": ["Status of abnormal behavior analysis and monitoring","Evidence of responses taken when abnormal behaviors were detected"],"AuditChecklist": ["Is the organization collecting, analyzing, and monitoring network traffic, data flows, and event logs from major information systems, applications, networks, and security systems to detect abnormal behaviors such as intrusion attempts, personal information leakage attempts, or fraudulent activities?","Has the organization defined criteria and thresholds to determine abnormal behaviors, and is follow-up action, such as the determination and investigation of abnormal activities, taken in a timely manner?"],"NonComplianceCases": ["Case 1: Failure to establish a real-time or regular monitoring system and procedures to detect intrusion attempts on servers, networks, databases, and security systems from external sources.","Case 2: Although the organization has outsourced monitoring tasks to an external security monitoring agency, there is no record of reviewing the reports provided by the agency, and the organization does not have its own monitoring system for systems excluded from the outsourced service.","Case 3: Although abnormal traffic exceeding internally defined thresholds has been continuously detected, no response measures have been taken."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 6 (Access Control)"]}],"description": "To quickly detect and respond to intrusion attempts, personal information leakage attempts, and fraudulent activities from internal or external sources, the organization must collect and analyze network and data flows. Post-monitoring and inspection actions must be timely.","checks_status": {"fail": 6,"pass": 1,"total": 28,"manual": 0}},"2.11.4": {"name": "Incident Response Training and Improvement","checks": {"ssmincidents_enabled_with_plans": null},"status": "PASS","attributes": [{"Domain": "2. Protection Measures Requirements","Section": "2.11.4 Incident Response Training and Improvement","Subdomain": "2.11. Incident Prevention and Response","AuditEvidence": ["Simulation training plan for responding to security and personal information leakage incidents","Simulation training result reports for responding to security and personal information leakage incidents","Incident response procedures"],"AuditChecklist": ["Has the organization established a simulation training plan for responding to security incidents and personal information leakage incidents, and are such training exercises conducted at least once a year?","Is the organization reflecting the results of security incident and personal information leakage incident training to improve its response system?"],"NonComplianceCases": ["Case 1: Failure to conduct simulation training or provide related training plans and result reports.","Case 2: Although an annual simulation training plan for security incidents was established, it was not conducted within the planned period without valid reason or approval.","Case 3: Simulation training was conducted, but it was not performed according to the procedures and forms defined in the internal guidelines."],"RelatedRegulations": []}],"description": "The organization must conduct at least one simulation training per year based on scenarios to ensure that employees and stakeholders are familiar with the procedures for responding to security incidents and personal information leakage incidents. The response system must be improved based on the training results.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"2.11.5": {"name": "Incident Response and Recovery","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measures Requirements","Section": "2.11.5 Incident Response and Recovery","Subdomain": "2.11. Incident Prevention and Response","AuditEvidence": ["Incident response procedures","Incident response reports","Incident management logs","Personal information leakage reports","Emergency contact list"],"AuditChecklist": ["When signs of or actual incidents of security breaches or personal information leakage are detected, is the organization responding and reporting promptly according to the defined incident response procedures?","Is the organization notifying data subjects and reporting to relevant authorities as required by law in case of a personal information breach?","After the incident is resolved, is the organization analyzing the cause, reporting the results, and sharing them with relevant departments and personnel?","Is the organization utilizing the information obtained from incident analysis to establish preventive measures to prevent similar incidents from recurring, and if necessary, modifying its incident response procedures?"],"NonComplianceCases": ["Case 1: Although internal incident response guidelines require that security incidents be reported to the internal information protection committee and relevant departments, the department in charge responded to the incident independently without reporting to the information protection committee or relevant departments.","Case 2: Although a service outage suspected to be caused by a DDoS attack occurred recently, the organization did not analyze the cause or establish preventive measures.","Case 3: Although a personal information leakage incident occurred due to external hacking, notification and reporting were not made within 72 hours, citing the small number of affected personal information records as the reason.","Case 4: Although personal information of more than 1,000 individuals was leaked due to an employee's mistake on the company website, the affected data subjects were not notified."],"RelatedRegulations": ["Personal Information Protection Act, Article 34 (Notification and Reporting of Personal Information Leakage)","Information and Communications Network Act, Article 48-3 (Reporting of Security Incidents), Article 48-4 (Analysis of Causes of Security Incidents)"]}],"description": "When signs of or actual incidents of security breaches or personal information leakage are detected, the organization must comply with legal notification and reporting obligations, respond and recover promptly according to established procedures, and analyze the incident to establish preventive measures to reflect in the response system.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.12.1": {"name": "Safety Measures for Disaster Preparedness","checks": {"drs_job_exist": "FAIL","backup_plans_exist": "PASS","rds_cluster_multi_az": "FAIL","elb_is_in_multiple_az": "FAIL","rds_instance_multi_az": "FAIL","s3_bucket_object_lock": "FAIL","vpc_different_regions": null,"efs_have_backup_enabled": "FAIL","elbv2_is_in_multiple_az": "PASS","vpc_subnet_different_az": "PASS","backup_reportplans_exist": null,"neptune_cluster_multi_az": null,"elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_lifecycle_enabled": "FAIL","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"autoscaling_group_multiple_az": null,"dms_instance_multi_az_enabled": null,"ec2_ebs_volume_snapshots_exists": "FAIL","rds_cluster_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL","documentdb_cluster_backup_enabled": null,"s3_bucket_cross_region_replication": "FAIL","kms_cmk_not_deleted_unintentionally": null,"neptune_cluster_deletion_protection": null,"redshift_cluster_automated_snapshot": null,"elb_cross_zone_load_balancing_enabled": "PASS","lightsail_instance_automated_snapshots": null,"dlm_ebs_snapshot_lifecycle_policy_exists": "FAIL","documentdb_cluster_cloudwatch_log_export": null,"elasticache_redis_cluster_backup_enabled": null,"elasticache_redis_cluster_multi_az_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protective Measure Requirements","Section": "2.12.1 Safety Measures for Disaster Preparedness","Subdomain": "2.12. Disaster Recovery","AuditEvidence": ["IT disaster recovery guidelines/procedures","IT disaster recovery plans (including RTO and RPO definitions)","Emergency contact list","Crisis response manual for personal information processing systems"],"AuditChecklist": ["Has the organization identified IT disaster types that could threaten the continuity of core services (businesses) and analyzed the expected scale of damage and impact on operations to identify core IT services (businesses) and systems?","Has the organization defined recovery time objectives (RTO) and recovery point objectives (RPO) based on the importance and characteristics of core IT services and systems?","Has the organization established and implemented disaster recovery plans, including recovery strategies, emergency recovery teams, emergency contact networks, and recovery procedures, to ensure the continuity of core services and systems during disasters?"],"NonComplianceCases": ["Case 1: The IT disaster recovery procedures lack critical details such as the definition of IT disaster recovery teams and roles, emergency contact systems, and recovery procedures and methods.","Case 2: Although a backup center has been established to ensure the continuity of information systems and minimize damage during emergencies, the relevant policies do not include disaster recovery procedures using the backup center, making disaster recovery tests and actual recovery efforts ineffective.","Case 3: Recovery time objectives for some critical systems related to service operations have not been defined, and appropriate recovery strategies are not in place.","Case 4: The disaster recovery guidelines do not define the recovery priorities, RTO, or RPO for IT services or systems.","Case 5: Unrealistic recovery objectives have been set, either too high or too low, and the RPO and backup policies (e.g., targets, frequency) are not appropriately linked, making it difficult to ensure the effectiveness of recovery."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 11 (Safety Measures for Disaster Preparedness)"]}],"description": "Identify types of disasters that could threaten the operational continuity of the organization's core services and systems, such as natural disasters, communication or power failures, and hacking. Analyze the expected scale of damage and impact for each type, define the recovery time objective (RTO) and recovery point objective (RPO), and establish a disaster recovery system including recovery strategies, emergency recovery teams, emergency contact networks, and recovery procedures.","checks_status": {"fail": 14,"pass": 5,"total": 33,"manual": 0}},"2.12.2": {"name": "Disaster Recovery Testing and Improvement","checks": {"drs_job_exist": "FAIL","backup_plans_exist": "PASS","rds_cluster_multi_az": "FAIL","elb_is_in_multiple_az": "FAIL","rds_instance_multi_az": "FAIL","s3_bucket_object_lock": "FAIL","vpc_different_regions": null,"efs_have_backup_enabled": "FAIL","elbv2_is_in_multiple_az": "PASS","vpc_subnet_different_az": "PASS","backup_reportplans_exist": null,"neptune_cluster_multi_az": null,"elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_lifecycle_enabled": "FAIL","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"autoscaling_group_multiple_az": null,"dms_instance_multi_az_enabled": null,"ec2_ebs_volume_snapshots_exists": "FAIL","rds_cluster_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL","documentdb_cluster_backup_enabled": null,"s3_bucket_cross_region_replication": "FAIL","kms_cmk_not_deleted_unintentionally": null,"neptune_cluster_deletion_protection": null,"redshift_cluster_automated_snapshot": null,"elb_cross_zone_load_balancing_enabled": "PASS","lightsail_instance_automated_snapshots": null,"dlm_ebs_snapshot_lifecycle_policy_exists": "FAIL","documentdb_cluster_cloudwatch_log_export": null,"elasticache_redis_cluster_backup_enabled": null,"elasticache_redis_cluster_multi_az_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protective Measure Requirements","Section": "2.12.2 Disaster Recovery Testing and Improvement","Subdomain": "2.12. Disaster Recovery","AuditEvidence": ["IT disaster recovery procedures","IT disaster recovery test plans","IT disaster recovery test results"],"AuditChecklist": ["Has the organization established and implemented disaster recovery test plans to evaluate the effectiveness of the established IT disaster recovery system?","Are the disaster recovery strategies and plans regularly reviewed and supplemented to reflect test results, changes in the information system environment, and legal requirements?"],"NonComplianceCases": ["Case 1: Disaster recovery drills were not planned or conducted, and the related plans and result reports are not available.","Case 2: Although a disaster recovery drill plan was established, it was not conducted as planned or approved, and the related result reports are missing.","Case 3: Disaster recovery drills were conducted, but they did not follow the procedures and forms outlined in the internal guidelines, making it difficult to evaluate the adequacy and effectiveness of the disaster recovery procedures."],"RelatedRegulations": []}],"description": "Regularly test the adequacy of the disaster recovery strategies and plans, and supplement the recovery strategies and plans based on test results, changes in the information system environment, and legal requirements.","checks_status": {"fail": 14,"pass": 5,"total": 33,"manual": 0}}},"requirements_passed": 10,"requirements_failed": 27,"requirements_manual": 64,"total_requirements": 101,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "23a633ec-caa6-4021-809a-a247c6f177e6","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "nist_csf_1.1_aws","framework": "NIST-CSF","version": "1.1","description": "The NIST Cybersecurity Framework (CSF) is supported by governments and industries worldwide as a recommended baseline for use by any organization, regardless of sector or size. The NIST Cybersecurity Framework consists of three primary components: the framework core, the profiles, and the implementation tiers. The framework core contains desired cybersecurity activities and outcomes organized into 23 categories that cover the breadth of cybersecurity objectives for an organization. The profiles contain an organization's unique alignment of their organizational requirements and objectives, risk appetite, and resources using the desired outcomes of the framework core. The implementation tiers describe the degree to which an organization’s cybersecurity risk management practices exhibit the characteristics defined in the framework core.","region": "eu-west-1","requirements": {"ac_1": {"name": "PR.AC-1","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_password_policy_reuse_24": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_1","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Identity Management and Access Control (PR.AC)"}],"description": "Identities and credentials are issued, managed, verified, revoked, and audited for authorized devices, users and processes.","checks_status": {"fail": 1,"pass": 0,"total": 9,"manual": 0}},"ac_3": {"name": "PR.AC-3","checks": {"iam_root_mfa_enabled": null,"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"iam_root_hardware_mfa_enabled": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"iam_user_mfa_enabled_console_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Identity Management and Access Control (PR.AC)"}],"description": "Remote access is managed.","checks_status": {"fail": 3,"pass": 6,"total": 20,"manual": 0}},"ac_4": {"name": "PR.AC-4","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_4","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Identity Management and Access Control (PR.AC)"}],"description": "Access permissions and authorizations are managed, incorporating the principles of least privilege and separation of duties.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"ac_5": {"name": "PR.AC-5","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"acm_certificates_expiration_check": "PASS","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_5","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Identity Management and Access Control (PR.AC)"}],"description": "Network integrity is protected (e.g., network segregation, network segmentation).","checks_status": {"fail": 3,"pass": 7,"total": 17,"manual": 0}},"ac_6": {"name": "PR.AC-6","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_6","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Identity Management and Access Control (PR.AC)"}],"description": "Identities are proofed and bound to credentials and asserted in interactions.","checks_status": {"fail": 1,"pass": 1,"total": 4,"manual": 0}},"ac_7": {"name": "PR.AC-7","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_7","Section": "Protect (PR)","Service": "iam","SubGroup": null,"SubSection": "Identity Management and Access Control (PR.AC)"}],"description": "Users, devices, and other assets are authenticated (e.g., single-factor, multi-factor) commensurate with the risk of the transaction (e.g., individuals’ security and privacy risks and other organizational risks).","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ae_1": {"name": "DE.AE-1","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","s3_bucket_server_access_logging_enabled": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ae_1","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Anomalies and Events (DE.AE)"}],"description": "A baseline of network operations and expected data flows for users and systems is established and managed.","checks_status": {"fail": 7,"pass": 3,"total": 13,"manual": 0}},"ae_2": {"name": "DE.AE-2","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ae_2","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Anomalies and Events (DE.AE)"}],"description": "Detected events are analyzed to understand attack targets and methods.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"ae_3": {"name": "DE.AE-3","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ae_3","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Anomalies and Events (DE.AE)"}],"description": "Event data are collected and correlated from multiple sources and sensors.","checks_status": {"fail": 5,"pass": 2,"total": 11,"manual": 0}},"ae_4": {"name": "DE.AE-4","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ae_4","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Anomalies and Events (DE.AE)"}],"description": "Impact of events is determined.","checks_status": {"fail": 4,"pass": 3,"total": 10,"manual": 0}},"ae_5": {"name": "DE.AE-5","checks": {"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ae_5","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Anomalies and Events (DE.AE)"}],"description": "Incident alert thresholds are established.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"am_1": {"name": "ID.AM-1","checks": {"ec2_instance_managed_by_ssm": "FAIL","config_recorder_all_regions_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "am_1","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Asset Management (ID.AM)"}],"description": "Physical devices and systems within the organization are inventoried.","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"am_2": {"name": "ID.AM-2","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "am_2","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Asset Management (ID.AM)"}],"description": "Software platforms and applications within the organization are inventoried.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"am_3": {"name": "ID.AM-3","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "am_3","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Asset Management (ID.AM)"}],"description": "Organizational communication and data flows are mapped.","checks_status": {"fail": 4,"pass": 2,"total": 8,"manual": 0}},"am_5": {"name": "ID.AM-5","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "am_5","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Asset Management (ID.AM)"}],"description": "Resources (e.g., hardware, devices, data, time, personnel, and software) are prioritized based on their classification, criticality, and business value.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"am_6": {"name": "ID.AM-6","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "am_6","Section": "Identify (ID)","Service": "iam","SubGroup": null,"SubSection": "Asset Management (ID.AM)"}],"description": "Cybersecurity roles and responsibilities for the entire workforce and third-party stakeholders (e.g., suppliers, customers, partners) are established.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"an_2": {"name": "RS.AN-2","checks": {"guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "an_2","Section": "Respond (RS)","Service": "guardduty","SubGroup": null,"SubSection": "Analysis (RS.AN)"}],"description": "The impact of the incident is understood.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"be_5": {"name": "ID.BE-5","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "be_5","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Business Environment (ID.BE)"}],"description": "Resilience requirements to support delivery of critical services are established for all operating states (e.g. under duress/attack, during recovery, normal operations)","checks_status": {"fail": 3,"pass": 1,"total": 4,"manual": 0}},"cm_1": {"name": "DE.CM-1","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_1","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Security Continuous Monitoring (DE.CM)"}],"description": "The network is monitored to detect potential cybersecurity events.","checks_status": {"fail": 4,"pass": 4,"total": 11,"manual": 0}},"cm_2": {"name": "DE.CM-2","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","config_recorder_all_regions_enabled": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_2","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Security Continuous Monitoring (DE.CM)"}],"description": "The physical environment is monitored to detect potential cybersecurity events.","checks_status": {"fail": 2,"pass": 3,"total": 20,"manual": 0}},"cm_3": {"name": "DE.CM-3","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_multi_region_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_3","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Security Continuous Monitoring (DE.CM)"}],"description": "Personnel activity is monitored to detect potential cybersecurity events.","checks_status": {"fail": 1,"pass": 3,"total": 7,"manual": 0}},"cm_4": {"name": "DE.CM-4","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "cm_4","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Security Continuous Monitoring (DE.CM)"}],"description": "Malicious code is detected.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"cm_5": {"name": "DE.CM-5","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_waf_acl_attached": "FAIL","ec2_instance_imdsv2_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_5","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Security Continuous Monitoring (DE.CM)"}],"description": "Unauthorized mobile code is detected.","checks_status": {"fail": 3,"pass": 3,"total": 10,"manual": 0}},"cm_6": {"name": "DE.CM-6","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_multi_region_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_6","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Security Continuous Monitoring (DE.CM)"}],"description": "External service provider activity is monitored to detect potential cybersecurity events.","checks_status": {"fail": 1,"pass": 3,"total": 7,"manual": 0}},"cm_7": {"name": "DE.CM-7","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_7","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Security Continuous Monitoring (DE.CM)"}],"description": "Monitoring for unauthorized personnel, connections, devices, and software is performed.","checks_status": {"fail": 4,"pass": 4,"total": 11,"manual": 0}},"cp_4": {"name": "DE.DP-4","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_waf_acl_attached": "FAIL","ec2_instance_imdsv2_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_4","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Detection Processes (DE.DP)"}],"description": "Event detection information is communicated.","checks_status": {"fail": 3,"pass": 3,"total": 10,"manual": 0}},"cp_5": {"name": "DE.DP-5","checks": {"ec2_instance_imdsv2_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "cp_5","Section": "Detect (DE)","Service": "ec2","SubGroup": null,"SubSection": "Detection Processes (DE.DP)"}],"description": "Detection processes are continuously improved.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ds_1": {"name": "PR.DS-1","checks": {"ec2_ebs_volume_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","cloudtrail_kms_encryption_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ds_1","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Data Security (PR.DS)"}],"description": "Data-at-rest is protected.","checks_status": {"fail": 5,"pass": 2,"total": 9,"manual": 0}},"ds_2": {"name": "PR.DS-2","checks": {"elb_ssl_listeners": "FAIL","acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ds_2","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Data Security (PR.DS)"}],"description": "Data-in-transit is protected.","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"ds_3": {"name": "PR.DS-3","checks": {"ec2_elastic_ip_unassigned": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ds_3","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Data Security (PR.DS)"}],"description": "Assets are formally managed throughout removal, transfers, and disposition.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"ds_4": {"name": "PR.DS-4","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ds_4","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Data Security (PR.DS)"}],"description": "Adequate capacity to ensure availability is maintained.","checks_status": {"fail": 4,"pass": 1,"total": 5,"manual": 0}},"ds_5": {"name": "PR.DS-5","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"cloudtrail_multi_region_enabled": "PASS","s3_bucket_policy_public_write_access": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"s3_account_level_public_access_blocks": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ds_5","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Data Security (PR.DS)"}],"description": "Protections against data leaks are implemented.","checks_status": {"fail": 4,"pass": 7,"total": 19,"manual": 0}},"ds_6": {"name": "PR.DS-6","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ds_6","Section": "Protect (PR)","Service": "cloudtrail","SubGroup": null,"SubSection": "Data Security (PR.DS)"}],"description": "Integrity checking mechanisms are used to verify software, firmware, and information integrity.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ds_7": {"name": "PR.DS-7","checks": {"elbv2_deletion_protection": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","ec2_instance_older_than_specific_days": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ds_7","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Data Security (PR.DS)"}],"description": "The development and testing environment(s) are separate from the production environment.","checks_status": {"fail": 5,"pass": 1,"total": 6,"manual": 0}},"ds_8": {"name": "PR.DS-8","checks": {"securityhub_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ds_8","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Data Security (PR.DS)"}],"description": "Integrity checking mechanisms are used to verify hardware integrity.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"ip_1": {"name": "PR.IP-1","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ip_1","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Information Protection Processes and Procedures (PR.IP)"}],"description": "A baseline configuration of information technology/industrial control systems is created and maintained incorporating security principles (e.g. concept of least functionality).","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"ip_2": {"name": "PR.IP-2","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ip_2","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Information Protection Processes and Procedures (PR.IP)"}],"description": "A System Development Life Cycle to manage systems is implemented.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ip_3": {"name": "PR.IP-3","checks": {"elbv2_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ip_3","Section": "Protect (PR)","Service": "elb","SubGroup": null,"SubSection": "Information Protection Processes and Procedures (PR.IP)"}],"description": "Configuration change control processes are in place.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ip_4": {"name": "PR.IP-4","checks": {"rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ip_4","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Information Protection Processes and Procedures (PR.IP)"}],"description": "Backups of information are conducted, maintained, and tested periodically.","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"ip_7": {"name": "PR.IP-7","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "ip_7","Section": "Protect (PR)","Service": "ec2","SubGroup": null,"SubSection": "Information Protection Processes and Procedures (PR.IP)"}],"description": "Protection processes are improved.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ip_8": {"name": "PR.IP-8","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"eks_cluster_not_publicly_accessible": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ip_8","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Information Protection Processes and Procedures (PR.IP)"}],"description": "Effectiveness of protection technologies is shared.","checks_status": {"fail": 1,"pass": 4,"total": 13,"manual": 0}},"ip_9": {"name": "PR.IP-9","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ip_9","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Information Protection Processes and Procedures (PR.IP)"}],"description": "Response plans (Incident Response and Business Continuity) and recovery plans (Incident Recovery and Disaster Recovery) are in place and managed.","checks_status": {"fail": 4,"pass": 1,"total": 10,"manual": 0}},"ma_2": {"name": "PR.MA-2","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ma_2","Section": "Protect (PR)","Service": "cloudtrail","SubGroup": null,"SubSection": "Maintenance (PR.MA)"}],"description": "Remote maintenance of organizational assets is approved, logged, and performed in a manner that prevents unauthorized access.","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"mi_3": {"name": "RS.MI-3","checks": {"guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "mi_3","Section": "Respond (RS)","Service": "guardduty","SubGroup": null,"SubSection": "Mitigation (RS.MI)"}],"description": "Newly identified vulnerabilities are mitigated or documented as accepted risks.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"pt_1": {"name": "PR.PT-1","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pt_1","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Protective Technology (PR.PT)"}],"description": "Audit/log records are determined, documented, implemented, and reviewed in accordance with policy.","checks_status": {"fail": 5,"pass": 2,"total": 8,"manual": 0}},"pt_3": {"name": "PR.PT-3","checks": {"iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","s3_account_level_public_access_blocks": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "pt_3","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Protective Technology (PR.PT)"}],"description": "The principle of least functionality is incorporated by configuring systems to provide only essential capabilities.","checks_status": {"fail": 0,"pass": 3,"total": 11,"manual": 0}},"pt_4": {"name": "PR.PT-4","checks": {"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pt_4","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Protective Technology (PR.PT)"}],"description": "Communications and control networks are protected.","checks_status": {"fail": 1,"pass": 3,"total": 6,"manual": 0}},"pt_5": {"name": "PR.PT-5","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pt_5","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Protective Technology (PR.PT)"}],"description": "Mechanisms (e.g., failsafe, load balancing, hot swap) are implemented to achieve resilience requirements in normal and adverse situations.","checks_status": {"fail": 3,"pass": 1,"total": 4,"manual": 0}},"ra_1": {"name": "ID.RA-1","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ra_1","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Risk Assessment (ID.RA)"}],"description": "Asset vulnerabilities are identified and documented.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"ra_2": {"name": "ID.RA-2","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_2","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Risk Assessment (ID.RA)"}],"description": "Cyber threat intelligence is received from information sharing forums and sources.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"ra_3": {"name": "ID.RA-3","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_3","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Risk Assessment (ID.RA)"}],"description": "Threats, both internal and external, are identified and documented.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"ra_5": {"name": "ID.RA-5","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","config_recorder_all_regions_enabled": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ra_5","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Risk Assessment (ID.RA)"}],"description": "Threats, vulnerabilities, likelihoods, and impacts are used to determine risk.","checks_status": {"fail": 2,"pass": 3,"total": 20,"manual": 0}},"rp_1": {"name": "RS.RP-1","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "rp_1","Section": "Respond (RS)","Service": "aws","SubGroup": null,"SubSection": "Response Planning (RS.RP)"}],"description": "Response plan is executed during or after an incident.","checks_status": {"fail": 4,"pass": 1,"total": 11,"manual": 0}},"sc_4": {"name": "ID.SC-4","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","config_recorder_all_regions_enabled": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_4","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Supply Chain Risk Management (ID.SC)"}],"description": "Suppliers and third-party partners are routinely assessed using audits, test results, or other forms of evaluations to confirm they are meeting their contractual obligations.","checks_status": {"fail": 2,"pass": 3,"total": 16,"manual": 0}},"ip_12": {"name": "PR.IP-12","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","config_recorder_all_regions_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ip_12","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Information Protection Processes and Procedures (PR.IP)"}],"description": "A vulnerability management plan is developed and implemented.","checks_status": {"fail": 2,"pass": 0,"total": 4,"manual": 0}}},"requirements_passed": 11,"requirements_failed": 42,"requirements_manual": 3,"total_requirements": 56,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "23ef3629-e1cd-4f16-af98-ab0daaff257e","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "fedramp_low_revision_4_aws","framework": "FedRAMP-Low-Revision-4","version": "","description": "The Federal Risk and Authorization Management Program (FedRAMP) was established in 2011. It provides a cost-effective, risk-based approach for the adoption and use of cloud services by the U.S. federal government. FedRAMP empowers federal agencies to use modern cloud technologies, with an emphasis on the security and protection of federal information.","region": "eu-west-1","requirements": {"ac-2": {"name": "Account Management (AC-2)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_hardware_mfa_enabled": null,"iam_user_console_access_unused": null,"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","iam_user_mfa_enabled_console_access": null,"cloudtrail_s3_dataevents_read_enabled": null,"iam_password_policy_minimum_length_14": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"iam_aws_attached_policy_no_administrative_privileges": null,"opensearch_service_domains_cloudwatch_logging_enabled": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-2","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Manage system accounts, group memberships, privileges, workflow, notifications, deactivations, and authorizations.","checks_status": {"fail": 3,"pass": 4,"total": 26,"manual": 0}},"ac-3": {"name": "Account Management (AC-3)","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-3","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system enforces approved authorizations for logical access to information and system resources in accordance with applicable access control policies.","checks_status": {"fail": 1,"pass": 6,"total": 20,"manual": 0}},"au-2": {"name": "Audit Events (AU-2)","checks": {"elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-2","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization: a. Determines that the information system is capable of auditing the following events: [Assignment: organization-defined auditable events]; b. Coordinates the security audit function with other organizational entities requiring audit- related information to enhance mutual support and to help guide the selection of auditable events; c. Provides a rationale for why the auditable events are deemed to be adequate support after- the-fact investigations of security incidents","checks_status": {"fail": 5,"pass": 2,"total": 11,"manual": 0}},"au-9": {"name": "Protection of Audit Information (AU-9)","checks": {"s3_bucket_object_versioning": "FAIL","cloudtrail_kms_encryption_enabled": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-9","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects audit information and audit tools from unauthorized access, modification, and deletion.","checks_status": {"fail": 4,"pass": 0,"total": 4,"manual": 0}},"ca-7": {"name": "Continuous Monitoring (CA-7)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_waf_acl_attached": "FAIL","ec2_instance_imdsv2_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_network_acls_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ca-7","Section": "Security Assessment And Authorization (CA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Continuously monitor configuration management processes. Determine security impact, environment and operational risks.","checks_status": {"fail": 2,"pass": 4,"total": 11,"manual": 0}},"cm-2": {"name": "Baseline Configuration (CM-2)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"elbv2_deletion_protection": "FAIL","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"ssm_managed_compliant_patching": "FAIL","apigateway_restapi_waf_acl_attached": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm-2","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization develops, documents, and maintains under configuration control, a current baseline configuration of the information system.","checks_status": {"fail": 7,"pass": 6,"total": 21,"manual": 0}},"cm-8": {"name": "Information System Component Inventory (CM-8)","checks": {"guardduty_is_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm-8","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization develops and documents an inventory of information system components that accurately reflects the current information system, includes all components within the authorization boundary of the information system, is at the level of granularity deemed necessary for tracking and reporting and reviews and updates the information system component inventory.","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"cp-9": {"name": "Information System Backup (CP-9)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp-9","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization conducts backups of user-level information, system-level information and information system documentation including security-related documentation contained in the information system and protects the confidentiality, integrity, and availability of backup information at storage locations.","checks_status": {"fail": 2,"pass": 1,"total": 7,"manual": 0}},"ia-2": {"name": "Identification and Authentication (Organizational users) (IA-2)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia-2","Section": "Identification and Authentication (IA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"ir-4": {"name": "Incident Handling (IR-4)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ir-4","Section": "Incident Response (IR)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization implements an incident handling capability for security incidents that includes preparation, detection and analysis, containment, eradication, and recovery, coordinates incident handling activities with contingency planning activities and incorporates lessons learned from ongoing incident handling activities into incident response procedures, training, and testing, and implements the resulting changes accordingly.","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"sa-3": {"name": "System Development Life Cycle (SA-3)","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sa-3","Section": "System and Services Acquisition (SA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization manages the information system using organization-defined system development life cycle, defines and documents information security roles and responsibilities throughout the system development life cycle, identifies individuals having information security roles and responsibilities and integrates the organizational information security risk management process into system development life cycle activities.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sc-5": {"name": "Denial Of Service Protection (SC-5)","checks": {"guardduty_is_enabled": "PASS","rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL","redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-5","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects against or limits the effects of the following types of denial of service attacks: [Assignment: organization-defined types of denial of service attacks or references to sources for such information] by employing [Assignment: organization-defined security safeguards].","checks_status": {"fail": 4,"pass": 2,"total": 8,"manual": 0}},"sc-7": {"name": "Boundary Protection (SC-7)","checks": {"elb_ssl_listeners": "FAIL","ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-7","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system: a. Monitors and controls communications at the external boundary of the system and at key internal boundaries within the system; b. Implements subnetworks for publicly accessible system components that are [Selection: physically; logically] separated from internal organizational networks; and c. Connects to external networks or information systems only through managed interfaces consisting of boundary protection devices arranged in accordance with an organizational security architecture.","checks_status": {"fail": 6,"pass": 6,"total": 21,"manual": 0}},"ac-17": {"name": "Remote Access (AC-17)","checks": {"elb_ssl_listeners": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-17","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Authorize remote access systems prior to connection. Enforce remote connection requirements to information systems.","checks_status": {"fail": 5,"pass": 9,"total": 21,"manual": 0}},"au-11": {"name": "Audit Record Retention (AU-11)","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-11","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization retains audit records for at least 90 days to provide support for after-the-fact investigations of security incidents and to meet regulatory and organizational information retention requirements.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cp-10": {"name": "Information System Recovery And Reconstitution (CP-10)","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp-10","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization provides for the recovery and reconstitution of the information system to a known state after a disruption, compromise, or failure.","checks_status": {"fail": 4,"pass": 1,"total": 9,"manual": 0}},"sc-12": {"name": "Cryptographic Key Establishment And Management (SC-12)","checks": {"kms_cmk_rotation_enabled": null,"acm_certificates_expiration_check": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc-12","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization establishes and manages cryptographic keys for required cryptography employed within the information system in accordance with [Assignment: organization-defined requirements for key generation, distribution, storage, access, and destruction].","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"sc-13": {"name": "Use of Cryptography (SC-13)","checks": {"s3_bucket_default_encryption": "PASS","sns_topics_kms_encryption_at_rest_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"sagemaker_training_jobs_volume_and_output_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-13","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system implements FIPS-validated or NSA-approved cryptography in accordance with applicable federal laws, Executive Orders, directives, policies, regulations, and standards.","checks_status": {"fail": 1,"pass": 1,"total": 4,"manual": 0}}},"requirements_passed": 2,"requirements_failed": 16,"requirements_manual": 0,"total_requirements": 18,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "2d3bdafb-2503-4e04-a107-bdda7c4163ba","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "aws_audit_manager_control_tower_guardrails_aws","framework": "AWS-Audit-Manager-Control-Tower-Guardrails","version": "","description": "AWS Control Tower is a management and governance service that you can use to navigate through the setup process and governance requirements that are involved in creating a multi-account AWS environment.","region": "eu-west-1","requirements": {"1.0.1": {"name": "Disallow launch of EC2 instance types that are not EBS-optimized","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "1.0.1","Section": "EBS checks","Service": "ebs","SubGroup": null,"SubSection": null}],"description": "Checks whether EBS optimization is enabled for your EC2 instances that can be EBS-optimized","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.0.2": {"name": "Disallow EBS volumes that are unattached to an EC2 instance","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "1.0.2","Section": "EBS checks","Service": "ebs","SubGroup": null,"SubSection": null}],"description": "Checks whether EBS volumes are attached to EC2 instances","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.0.3": {"name": "Enable encryption for EBS volumes attached to EC2 instances","checks": {"ec2_ebs_default_encryption": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "1.0.3","Section": "EBS checks","Service": "ebs","SubGroup": null,"SubSection": null}],"description": "Checks whether EBS volumes that are in an attached state are encrypted","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.0.1": {"name": "Disallow internet connection through RDP","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "2.0.1","Section": "Disallow Internet Connection","Service": "vpc","SubGroup": null,"SubSection": null}],"description": "Checks whether security groups that are in use disallow unrestricted incoming TCP traffic to the specified","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.0.2": {"name": "Disallow internet connection through SSH","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "2.0.2","Section": "Disallow Internet Connection","Service": "vpc","SubGroup": null,"SubSection": null}],"description": "Checks whether security groups that are in use disallow unrestricted incoming SSH traffic.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3.0.1": {"name": "Disallow access to IAM users without MFA","checks": {"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3.0.1","Section": "Multi-Factor Authentication","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Checks whether the AWS Identity and Access Management users have multi-factor authentication (MFA) enabled.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.0.2": {"name": "Disallow console access to IAM users without MFA","checks": {"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3.0.2","Section": "Multi-Factor Authentication","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Checks whether AWS Multi-Factor Authentication (MFA) is enabled for all AWS Identity and Access Management (IAM) users that use a console password.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.0.3": {"name": "Enable MFA for the root user","checks": {"iam_root_mfa_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3.0.3","Section": "Multi-Factor Authentication","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Checks whether the root user of your AWS account requires multi-factor authentication for console sign-in.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.0.1": {"name": "Disallow public access to RDS database instances","checks": {"rds_instance_no_public_access": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "4.0.1","Section": "Disallow Public Access","Service": "rds","SubGroup": null,"SubSection": null}],"description": "Checks whether the Amazon Relational Database Service (RDS) instances are not publicly accessible. The rule is non-compliant if the publiclyAccessible field is true in the instance configuration item.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"4.0.2": {"name": "Disallow public access to RDS database snapshots","checks": {"rds_snapshots_public_access": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "4.0.2","Section": "Disallow Public Access","Service": "rds","SubGroup": null,"SubSection": null}],"description": "Checks if Amazon Relational Database Service (Amazon RDS) snapshots are public. The rule is non-compliant if any existing and new Amazon RDS snapshots are public.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"4.1.1": {"name": "Disallow public read access to S3 buckets","checks": {"rds_instance_no_public_access": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "4.1.1","Section": "Disallow Public Access","Service": "s3","SubGroup": null,"SubSection": null}],"description": "Checks that your S3 buckets do not allow public read access.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"4.1.2": {"name": "Disallow public write access to S3 buckets","checks": {"s3_bucket_policy_public_write_access": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "4.1.2","Section": "Disallow Public Access","Service": "s3","SubGroup": null,"SubSection": null}],"description": "Checks that your S3 buckets do not allow public write access.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"5.0.1": {"name": "Disallow RDS database instances that are not storage encrypted ","checks": {"rds_instance_storage_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "5.0.1","Section": "Disallow Instances","Service": "rds","SubGroup": null,"SubSection": null}],"description": "Checks whether storage encryption is enabled for your RDS DB instances.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"5.1.1": {"name": "Disallow S3 buckets that are not versioning enabled","checks": {"s3_bucket_object_versioning": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "5.1.1","Section": "Disallow Instances","Service": "s3","SubGroup": null,"SubSection": null}],"description": "Checks whether versioning is enabled for your S3 buckets.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 10,"requirements_failed": 2,"requirements_manual": 2,"total_requirements": 14,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "3477e5c1-467e-4fb1-9b4b-1c2bc8fcd03e","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "pci_3.2.1_aws","framework": "PCI","version": "3.2.1","description": "The Payment Card Industry Data Security Standard (PCI DSS) is a proprietary information security standard. It's administered by the PCI Security Standards Council, which was founded by American Express, Discover Financial Services, JCB International, MasterCard Worldwide, and Visa Inc. PCI DSS applies to entities that store, process, or transmit cardholder data (CHD) or sensitive authentication data (SAD). This includes, but isn't limited to, merchants, processors, acquirers, issuers, and service providers. The PCI DSS is mandated by the card brands and administered by the Payment Card Industry Security Standards Council.","region": "eu-west-1","requirements": {"cw": {"name": "CloudWatch","checks": {"cloudwatch_log_metric_filter_root_usage": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "cw","Section": null,"Service": "cloudwatch","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring CloudWatch resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"s3": {"name": "S3","checks": {"s3_bucket_public_access": null,"s3_bucket_default_encryption": "PASS","s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "s3","Section": null,"Service": "s3","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS S3 resources and options.","checks_status": {"fail": 1,"pass": 2,"total": 5,"manual": 0}},"dms": {"name": "DMS","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "dms","Section": null,"Service": "dms","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS DMS resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ec2": {"name": "EC2","checks": {"vpc_flow_logs_enabled": "FAIL","ec2_ebs_public_snapshot": "PASS","ec2_elastic_ip_unassigned": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ec2","Section": null,"Service": "ec2","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring EC2 resources and options.","checks_status": {"fail": 3,"pass": 3,"total": 6,"manual": 0}},"iam": {"name": "IAM","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "iam","Section": null,"Service": "iam","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS IAM resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 15,"manual": 0}},"kms": {"name": "KMS","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "kms","Section": null,"Service": "kms","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS KMS resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"rds": {"name": "RDS","checks": {"rds_snapshots_public_access": "PASS","rds_instance_no_public_access": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "rds","Section": null,"Service": "rds","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS RDS resources and options.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"ssm": {"name": "SSM","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ssm","Section": null,"Service": "ssm","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS SSM resources and options.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"elbv2": {"name": "ELBV2","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "elbv2","Section": null,"Service": "elbv2","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Elastic Load Balancer resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"config": {"name": "Config","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "config","Section": null,"Service": "config","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Config.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"lambda": {"name": "Lambda","checks": {"awslambda_function_url_public": null,"awslambda_function_not_publicly_accessible": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "lambda","Section": null,"Service": "lambda","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Lambda resources and options.","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"redshift": {"name": "Redshift","checks": {"redshift_cluster_public_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "redshift","Section": null,"Service": "redshift","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Redshift resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"codebuild": {"name": "CodeBuild","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "codebuild","Section": null,"Service": "codebuild","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring CodeBuild resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"guardduty": {"name": "GuardDuty","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "guardduty","Section": null,"Service": "guardduty","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS GuardDuty resources and options.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sagemaker": {"name": "SageMaker","checks": {"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sagemaker","Section": null,"Service": "sagemaker","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Sagemaker resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"cloudtrail": {"name": "CloudTrail","checks": {"cloudtrail_multi_region_enabled": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cloudtrail","Section": null,"Service": "cloudtrail","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring CloudTrail resources and options.","checks_status": {"fail": 3,"pass": 1,"total": 4,"manual": 0}},"opensearch": {"name": "OpenSearch","checks": {"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "opensearch","Section": null,"Service": "opensearch","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring OpenSearch resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"autoscaling": {"name": "Auto Scaling","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "autoscaling","Section": null,"Service": "autoscaling","SubGroup": null,"SubSection": null}],"description": "This control checks whether your Auto Scaling groups that are associated with a load balancer are using Elastic Load Balancing health checks. PCI DSS does not require load balancing or highly available configurations. However, this check aligns with AWS best practices.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"elasticsearch": {"name": "Elasticsearch","checks": {"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "elasticsearch","Section": null,"Service": "elasticsearch","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Elasticsearch resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 11,"requirements_failed": 4,"requirements_manual": 4,"total_requirements": 19,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "34f5d2fe-fe37-4143-81ce-fdf21d9a9826","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "gxp_eu_annex_11_aws","framework": "GxP-EU-Annex-11","version": "","description": "The GxP EU Annex 11 framework is the European equivalent to the FDA 21 CFR part 11 framework in the United States. This annex applies to all forms of computerized systems that are used as part of Good Manufacturing Practices (GMP) regulated activities. A computerized system is a set of software and hardware components that together fulfill certain functionalities. The application should be validated and IT infrastructure should be qualified. Where a computerized system replaces a manual operation, there should be no resultant decrease in product quality, process control, or quality assurance. There should be no increase in the overall risk of the process.","region": "eu-west-1","requirements": {"5-data": {"name": "5 Data","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "5-data","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Computerised systems exchanging data electronically with other systems should include appropriate built-in checks for the correct and secure entry and processing of data, in order to minimize the risks.","checks_status": {"fail": 2,"pass": 1,"total": 8,"manual": 0}},"17-archiving": {"name": "17 Archiving","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "17-archiving","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Data may be archived. This data should be checked for accessibility, readability and integrity. If relevant changes are to be made to the system (e.g. computer equipment or programs), then the ability to retrieve the data should be ensured and tested.","checks_status": {"fail": 2,"pass": 1,"total": 9,"manual": 0}},"9-audit-trails": {"name": "9 Audit Trails","checks": {"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "9-audit-trails","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Consideration should be given, based on a risk assessment, to building into the system the creation of a record of all GMP-relevant changes and deletions (a system generated 'audit trail'). For change or deletion of GMP-relevant data the reason should be documented. Audit trails need to be available and convertible to a generally intelligible form and regularly reviewed.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1-risk-management": {"name": "1 Risk Management","checks": {"securityhub_enabled": "PASS","cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "1-risk-management","Section": "General","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Risk management should be applied throughout the lifecycle of the computerised system taking into account patient safety, data integrity and product quality. As part of a risk management system, decisions on the extent of validation and data integrity controls should be based on a justified and documented risk assessment of the computerised system.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"16-business-continuity": {"name": "16 Business Continuity","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "16-business-continuity","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "For the availability of computerised systems supporting critical processes, provisions should be made to ensure continuity of support for those processes in the event of a system breakdown (e.g. a manual or alternative system). The time required to bring the alternative arrangements into use should be based on risk and appropriate for a particular system and the business process it supports. These arrangements should be adequately documented and tested.","checks_status": {"fail": 2,"pass": 1,"total": 9,"manual": 0}},"7.2-data-storage-backups": {"name": "7.2 Data Storage - Backups","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "7.2-data-storage-backups","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Regular back-ups of all relevant data should be done. Integrity and accuracy of backup data and the ability to restore the data should be checked during validation and monitored periodically.","checks_status": {"fail": 2,"pass": 1,"total": 8,"manual": 0}},"12.4-security-audit-trail": {"name": "12.4 Security - Audit Trail","checks": {"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "12.4-security-audit-trail","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Management systems for data and for documents should be designed to record the identity of operators entering, changing, confirming or deleting data including date and time.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"8.2-printouts-data-changes": {"name": "8.2 Printouts - Data Changes","checks": {"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "8.2-printouts-data-changes","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "For records supporting batch release it should be possible to generate printouts indicating if any of the data has been changed since the original entry.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"4.8-validation-data-transfer": {"name": "4.8 Validation - Data Transfer","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "4.8-validation-data-transfer","Section": "Project Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "If data are transferred to another data format or system, validation should include checks that data are not altered in value and/or meaning during this migration process.","checks_status": {"fail": 2,"pass": 1,"total": 9,"manual": 0}},"4.5-validation-development-quality": {"name": "4.5 Validation - Development Quality","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "4.5-validation-development-quality","Section": "Project Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The regulated user should take all reasonable steps, to ensure that the system has been developed in accordance with an appropriate quality management system. The supplier should be assessed appropriately.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.6-validation-quality-performance": {"name": "4.6 Validation - Quality and Performance","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "4.6-validation-quality-performance","Section": "Project Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "For the validation of bespoke or customised computerised systems there should be a process in place that ensures the formal assessment and reporting of quality and performance measures for all the life-cycle stages of the system.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"7.1-data-storage-damage-protection": {"name": "7.1 Data Storage - Damage Protection","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","redshift_cluster_automated_snapshot": null,"sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"eks_cluster_kms_cmk_encryption_in_secrets_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "7.1-data-storage-damage-protection","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Data should be secured by both physical and electronic means against damage. Stored data should be checked for accessibility, readability and accuracy. Access to data should be ensured throughout the retention period.","checks_status": {"fail": 6,"pass": 4,"total": 22,"manual": 0}},"10-change-and-configuration-management": {"name": "10 Change and Configuration Management","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "10-change-and-configuration-management","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Any changes to a computerised system including system configurations should only be made in a controlled manner in accordance with a defined procedure.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.2-validation-documentation-change-control": {"name": "4.2 Validation - Documentation Change Control","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "4.2-validation-documentation-change-control","Section": "Project Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Validation documentation should include change control records (if applicable) and reports on any deviations observed during the validation process.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}}},"requirements_passed": 8,"requirements_failed": 6,"requirements_manual": 0,"total_requirements": 14,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "376854be-93cd-44ab-a070-1e996b24184d","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "cis_1.5_aws","framework": "CIS","version": "1.5","description": "The CIS Amazon Web Services Foundations Benchmark provides prescriptive guidance for configuring security options for a subset of Amazon Web Services with an emphasis on foundational, testable, and architecture agnostic settings.","region": "eu-west-1","requirements": {"1.1": {"name": "1.1","checks": {"account_maintain_current_contact_details": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/manage-account-payment.html#contact-info","Description": "Ensure contact email and telephone details for AWS accounts are current and map to more than one individual in your organization.An AWS account supports a number of contact details, and AWS will use these to contact the account owner if activity judged to be in breach of Acceptable Use Policy or indicative of likely security compromise is observed by the AWS Abuse team. Contact details should not be for a single individual, as circumstances may arise where that individual is unavailable. Email contact details should point to a mail alias which forwards email to multiple individuals within the organization; where feasible, phone contact details should point to a PABX hunt group or other call-forwarding system.","DefaultValue": null,"AuditProcedure": "This activity can only be performed via the AWS Console, with a user who has permission to read and write Billing information (aws-portal:\\*Billing )1. Sign in to the AWS Management Console and open the `Billing and Cost Management` console at https://console.aws.amazon.com/billing/home#/. 2. On the navigation bar, choose your account name, and then choose `My Account`. 3. On the `Account Settings` page, review and verify the current details. 4. Under `Contact Information`, review and verify the current details.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "If an AWS account is observed to be behaving in a prohibited or suspicious manner, AWS will attempt to contact the account owner by email and phone using the contact details listed. If this is unsuccessful and the account behavior needs urgent mitigation, proactive measures may be taken, including throttling of traffic between the account exhibiting suspicious behavior and the AWS API endpoints and the Internet. This will result in impaired service to and from the account in question, so it is in both the customers' and AWS' best interests that prompt contact can be established. This is best achieved by setting AWS account contact details to point to resources which have multiple individuals as recipients, such as email aliases and PABX hunt groups.","RemediationProcedure": "This activity can only be performed via the AWS Console, with a user who has permission to read and write Billing information (aws-portal:\\*Billing ).1. Sign in to the AWS Management Console and open the `Billing and Cost Management` console at https://console.aws.amazon.com/billing/home#/. 2. On the navigation bar, choose your account name, and then choose `My Account`. 3. On the `Account Settings` page, next to `Account Settings`, choose `Edit`. 4. Next to the field that you need to update, choose `Edit`. 5. After you have entered your changes, choose `Save changes`. 6. After you have made your changes, choose `Done`. 7. To edit your contact information, under `Contact Information`, choose `Edit`. 8. For the fields that you want to change, type your updated information, and then choose `Update`.","AdditionalInformation": ""}],"description": "Maintain current contact details","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.2": {"name": "1.2","checks": {"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "","Description": "AWS provides customers with the option of specifying the contact information for account's security team. It is recommended that this information be provided.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if security contact information is present:**From Console:**1. Click on your account name at the top right corner of the console 2. From the drop-down menu Click `My Account`3. Scroll down to the `Alternate Contacts` section 4. Ensure contact information is specified in the `Security` section","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Specifying security-specific contact information will help ensure that security advisories sent by AWS reach the team in your organization that is best equipped to respond to them.","RemediationProcedure": "Perform the following to establish security contact information:**From Console:**1. Click on your account name at the top right corner of the console. 2. From the drop-down menu Click `My Account`3. Scroll down to the `Alternate Contacts` section 4. Enter contact information in the `Security` section**Note:** Consider specifying an internal email distribution list to ensure emails are regularly monitored by more than one individual.","AdditionalInformation": ""}],"description": "Ensure security contact information is registered","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.3": {"name": "1.3","checks": {"account_security_questions_are_registered_in_the_aws_account": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "","Description": "The AWS support portal allows account owners to establish security questions that can be used to authenticate individuals calling AWS customer service for support. It is recommended that security questions be established.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS account as the 'root' user 2. On the top right you will see the __ 3. Click on the __ 4. From the drop-down menu Click `My Account`5. In the `Configure Security Challenge Questions` section on the `Personal Information` page, configure three security challenge questions. 6. Click `Save questions` .","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "When creating a new AWS account, a default super user is automatically created. This account is referred to as the 'root user' or 'root' account. It is recommended that the use of this account be limited and highly controlled. During events in which the 'root' password is no longer accessible or the MFA token associated with 'root' is lost/destroyed it is possible, through authentication using secret questions and associated answers, to recover 'root' user login access.","RemediationProcedure": "**From Console:**1. Login to the AWS Account as the 'root' user 2. Click on the __ from the top right of the console 3. From the drop-down menu Click _My Account_ 4. Scroll down to the `Configure Security Questions` section 5. Click on `Edit`6. Click on each `Question` - From the drop-down select an appropriate question- Click on the `Answer` section- Enter an appropriate answer - Follow process for all 3 questions 7. Click `Update` when complete 8. Save Questions and Answers and place in a secure physical location","AdditionalInformation": ""}],"description": "Ensure security questions are registered in the AWS account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.4": {"name": "1.4","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "http://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html:http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html:http://docs.aws.amazon.com/IAM/latest/APIReference/API_GetAccountSummary.html:https://aws.amazon.com/blogs/security/an-easier-way-to-determine-the-presence-of-aws-account-access-keys/","Description": "The 'root' user account is the most privileged user in an AWS account. AWS Access Keys provide programmatic access to a given AWS account. It is recommended that all access keys associated with the 'root' user account be removed.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has access keys:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on `Credential Report`5. This will download a `.csv` file which contains credential usage for all IAM users within an AWS Account - open this file 6. For the `` user, ensure the `access_key_1_active` and `access_key_2_active` fields are set to `FALSE` .**From Command Line:**Run the following command: ```aws iam get-account-summary | grep \"AccountAccessKeysPresent\"``` If no 'root' access keys exist the output will show \"AccountAccessKeysPresent\": 0,. If the output shows a \"1\" than 'root' keys exist, refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Removing access keys associated with the 'root' user account limits vectors by which the account can be compromised. Additionally, removing the 'root' access keys encourages the creation and use of role based accounts that are least privileged.","RemediationProcedure": "Perform the following to delete or disable active 'root' user access keys**From Console:**1. Sign in to the AWS Management Console as 'root' and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. Click on __ at the top right and select `My Security Credentials` from the drop down list 3. On the pop out screen Click on `Continue to Security Credentials`4. Click on `Access Keys` _(Access Key ID and Secret Access Key)_ 5. Under the `Status` column if there are any Keys which are Active- Click on `Make Inactive` - (Temporarily disable Key - may be needed again)- Click `Delete` - (Deleted keys cannot be recovered)","AdditionalInformation": "IAM User account \"root\" for us-gov cloud regions is not enabled by default. However, on request to AWS support enables 'root' access only through access-keys (CLI, API methods) for us-gov cloud region."}],"description": "Ensure no 'root' user account access key exists","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.5": {"name": "1.5","checks": {"iam_root_mfa_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#id_root-user_manage_mfa:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html#enable-virt-mfa-for-root","Description": "The 'root' user account is the most privileged user in an AWS account. Multi-factor Authentication (MFA) adds an extra layer of protection on top of a username and password. With MFA enabled, when a user signs in to an AWS website, they will be prompted for their username and password as well as for an authentication code from their AWS MFA device.**Note:** When virtual MFA is used for 'root' accounts, it is recommended that the device used is NOT a personal device, but rather a dedicated mobile device (tablet or phone) that is managed to be kept charged and secured independent of any individual personal devices. (\"non-personal virtual MFA\") This lessens the risks of losing access to the MFA due to device loss, device trade-in or if the individual owning the device is no longer employed at the company.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has MFA setup:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on `Credential Report`5. This will download a `.csv` file which contains credential usage for all IAM users within an AWS Account - open this file 6. For the `` user, ensure the `mfa_active` field is set to `TRUE` .**From Command Line:**1. Run the following command: ```aws iam get-account-summary | grep \"AccountMFAEnabled\" ``` 2. Ensure the AccountMFAEnabled property is set to 1","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling MFA provides increased security for console access as it requires the authenticating principal to possess a device that emits a time-sensitive key and have knowledge of a credential.","RemediationProcedure": "Perform the following to establish MFA for the 'root' user account:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). Note: to manage MFA devices for the 'root' AWS account, you must use your 'root' account credentials to sign in to AWS. You cannot manage MFA devices for the 'root' account using other credentials.2. Choose `Dashboard` , and under `Security Status` , expand `Activate MFA` on your root account. 3. Choose `Activate MFA`4. In the wizard, choose `A virtual MFA` device and then choose `Next Step` . 5. IAM generates and displays configuration information for the virtual MFA device, including a QR code graphic. The graphic is a representation of the 'secret configuration key' that is available for manual entry on devices that do not support QR codes. 6. Open your virtual MFA application. (For a list of apps that you can use for hosting virtual MFA devices, see [Virtual MFA Applications](http://aws.amazon.com/iam/details/mfa/#Virtual_MFA_Applications).) If the virtual MFA application supports multiple accounts (multiple virtual MFA devices), choose the option to create a new account (a new virtual MFA device). 7. Determine whether the MFA app supports QR codes, and then do one of the following: - Use the app to scan the QR code. For example, you might choose the camera icon or choose an option similar to Scan code, and then use the device's camera to scan the code.- In the Manage MFA Device wizard, choose Show secret key for manual configuration, and then type the secret configuration key into your MFA application.When you are finished, the virtual MFA device starts generating one-time passwords.In the Manage MFA Device wizard, in the Authentication Code 1 box, type the one-time password that currently appears in the virtual MFA device. Wait up to 30 seconds for the device to generate a new one-time password. Then type the second one-time password into the Authentication Code 2 box. Choose Assign Virtual MFA.","AdditionalInformation": "IAM User account \"root\" for us-gov cloud regions does not have console access. This recommendation is not applicable for us-gov cloud regions."}],"description": "Ensure MFA is enabled for the 'root' user account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.6": {"name": "1.6","checks": {"iam_root_hardware_mfa_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_physical.html#enable-hw-mfa-for-root","Description": "The 'root' user account is the most privileged user in an AWS account. MFA adds an extra layer of protection on top of a user name and password. With MFA enabled, when a user signs in to an AWS website, they will be prompted for their user name and password as well as for an authentication code from their AWS MFA device. For Level 2, it is recommended that the 'root' user account be protected with a hardware MFA.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has a hardware MFA setup:1. Run the following command to determine if the 'root' account has MFA setup: ```aws iam get-account-summary | grep \"AccountMFAEnabled\" ```The `AccountMFAEnabled` property is set to `1` will ensure that the 'root' user account has MFA (Virtual or Hardware) Enabled. If `AccountMFAEnabled` property is set to `0` the account is not compliant with this recommendation.2. If `AccountMFAEnabled` property is set to `1`, determine 'root' account has Hardware MFA enabled. Run the following command to list all virtual MFA devices: ```aws iam list-virtual-mfa-devices``` If the output contains one MFA with the following Serial Number, it means the MFA is virtual, not hardware and the account is not compliant with this recommendation: `\"SerialNumber\": \"arn:aws:iam::__:mfa/root-account-mfa-device\"`","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "A hardware MFA has a smaller attack surface than a virtual MFA. For example, a hardware MFA does not suffer the attack surface introduced by the mobile smartphone on which a virtual MFA resides.**Note**: Using hardware MFA for many, many AWS accounts may create a logistical device management issue. If this is the case, consider implementing this Level 2 recommendation selectively to the highest security AWS accounts and the Level 1 recommendation applied to the remaining accounts.","RemediationProcedure": "Perform the following to establish a hardware MFA for the 'root' user account:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). Note: to manage MFA devices for the AWS 'root' user account, you must use your 'root' account credentials to sign in to AWS. You cannot manage MFA devices for the 'root' account using other credentials. 2. Choose `Dashboard` , and under `Security Status` , expand `Activate MFA` on your root account. 3. Choose `Activate MFA`4. In the wizard, choose `A hardware MFA` device and then choose `Next Step` . 5. In the `Serial Number` box, enter the serial number that is found on the back of the MFA device. 6. In the `Authentication Code 1` box, enter the six-digit number displayed by the MFA device. You might need to press the button on the front of the device to display the number. 7. Wait 30 seconds while the device refreshes the code, and then enter the next six-digit number into the `Authentication Code 2` box. You might need to press the button on the front of the device again to display the second number. 8. Choose `Next Step` . The MFA device is now associated with the AWS account. The next time you use your AWS account credentials to sign in, you must type a code from the hardware MFA device.Remediation for this recommendation is not available through AWS CLI.","AdditionalInformation": "IAM User account 'root' for us-gov cloud regions does not have console access. This control is not applicable for us-gov cloud regions."}],"description": "Ensure hardware MFA is enabled for the 'root' user account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.7": {"name": "1.7","checks": {"iam_avoid_root_usage": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html:https://docs.aws.amazon.com/general/latest/gr/aws_tasks-that-require-root.html","Description": "With the creation of an AWS account, a 'root user' is created that cannot be disabled or deleted. That user has unrestricted access to and control over all resources in the AWS account. It is highly recommended that the use of this account be avoided for everyday tasks.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console at `https://console.aws.amazon.com/iam/` 2. In the left pane, click `Credential Report` 3. Click on `Download Report` 4. Open of Save the file locally 5. Locate the `` under the user column 6. Review `password_last_used, access_key_1_last_used_date, access_key_2_last_used_date` to determine when the 'root user' was last used.**From Command Line:**Run the following CLI commands to provide a credential report for determining the last time the 'root user' was used: ``` aws iam generate-credential-report ``` ``` aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,5,11,16 | grep -B1 '' ```Review `password_last_used`, `access_key_1_last_used_date`, `access_key_2_last_used_date` to determine when the _root user_ was last used.**Note:** There are a few conditions under which the use of the 'root' user account is required. Please see the reference links for all of the tasks that require use of the 'root' user.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "The 'root user' has unrestricted access to and control over all account resources. Use of it is inconsistent with the principles of least privilege and separation of duties, and can lead to unnecessary harm due to error or account compromise.","RemediationProcedure": "If you find that the 'root' user account is being used for daily activity to include administrative tasks that do not require the 'root' user:1. Change the 'root' user password. 2. Deactivate or delete any access keys associate with the 'root' user.**Remember, anyone who has 'root' user credentials for your AWS account has unrestricted access to and control of all the resources in your account, including billing information.","AdditionalInformation": "The 'root' user for us-gov cloud regions is not enabled by default. However, on request to AWS support, they can enable the 'root' user and grant access only through access-keys (CLI, API methods) for us-gov cloud region. If the 'root' user for us-gov cloud regions is enabled, this recommendation is applicable.Monitoring usage of the 'root' user can be accomplished by implementing recommendation 3.3 Ensure a log metric filter and alarm exist for usage of the 'root' user."}],"description": "Eliminate use of the 'root' user for administrative and daily tasks","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.8": {"name": "1.8","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy","Description": "Password policies are, in part, used to enforce password complexity requirements. IAM password policies can be used to ensure password are at least a given length. It is recommended that the password policy require a minimum password length 14.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure the password policy is configured as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Ensure \"Minimum password length\" is set to 14 or greater.**From Command Line:** ``` aws iam get-account-password-policy ``` Ensure the output of the above command includes \"MinimumPasswordLength\": 14 (or higher)","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Setting a password complexity policy increases account resiliency against brute force login attempts.","RemediationProcedure": "Perform the following to set the password policy as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Set \"Minimum password length\" to `14` or greater. 5. Click \"Apply password policy\"**From Command Line:** ```aws iam update-account-password-policy --minimum-password-length 14 ``` Note: All commands starting with \"aws iam update-account-password-policy\" can be combined into a single command.","AdditionalInformation": ""}],"description": "Ensure IAM password policy requires minimum length of 14 or greater","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.9": {"name": "1.9","checks": {"iam_password_policy_reuse_24": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy","Description": "IAM password policies can prevent the reuse of a given password by the same user. It is recommended that the password policy prevent the reuse of passwords.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure the password policy is configured as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Ensure \"Prevent password reuse\" is checked 5. Ensure \"Number of passwords to remember\" is set to 24**From Command Line:** ``` aws iam get-account-password-policy``` Ensure the output of the above command includes \"PasswordReusePrevention\": 24","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Preventing password reuse increases account resiliency against brute force login attempts.","RemediationProcedure": "Perform the following to set the password policy as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Check \"Prevent password reuse\" 5. Set \"Number of passwords to remember\" is set to `24` **From Command Line:** ```aws iam update-account-password-policy --password-reuse-prevention 24 ``` Note: All commands starting with \"aws iam update-account-password-policy\" can be combined into a single command.","AdditionalInformation": ""}],"description": "Ensure IAM password policy prevents password reuse","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.1": {"name": "3.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-management-events:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-management-and-data-events-with-cloudtrail.html?icmpid=docs_cloudtrail_console#logging-management-events:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-supported-services.html#cloud-trail-supported-services-data-events","Description": "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. CloudTrail provides a history of AWS API calls for an account, including API calls made via the Management Console, SDKs, command line tools, and higher-level AWS services (such as CloudFormation).","DefaultValue": null,"AuditProcedure": "Perform the following to determine if CloudTrail is enabled for all regions:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane- You will be presented with a list of trails across all regions 3. Ensure at least one Trail has `All` specified in the `Region` column 4. Click on a trail via the link in the _Name_ column 5. Ensure `Logging` is set to `ON`6. Ensure `Apply trail to all regions` is set to `Yes` 7. In section `Management Events` ensure `Read/Write Events` set to `ALL`**From Command Line:** ```aws cloudtrail describe-trails ``` Ensure `IsMultiRegionTrail` is set to `true```` aws cloudtrail get-trail-status --name ``` Ensure `IsLogging` is set to `true` ``` aws cloudtrail get-event-selectors --trail-name ``` Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`","ImpactStatement": "S3 lifecycle features can be used to manage the accumulation and management of logs over time. See the following AWS resource for more information on these features:1. https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html","AssessmentStatus": "Automated","RationaleStatement": "The AWS API call history produced by CloudTrail enables security analysis, resource change tracking, and compliance auditing. Additionally, - ensuring that a multi-regions trail exists will ensure that unexpected activity occurring in otherwise unused regions is detected- ensuring that a multi-regions trail exists will ensure that `Global Service Logging` is enabled for a trail by default to capture recording of events generated onAWS global services- for a multi-regions trail, ensuring that management events configured for all type of Read/Writes ensures recording of management operations that are performed on all resources in an AWS account","RemediationProcedure": "Perform the following to enable global (Multi-region) CloudTrail logging:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on _Trails_ on the left navigation pane 3. Click `Get Started Now` , if presented- Click `Add new trail` - Enter a trail name in the `Trail name` box- Set the `Apply trail to all regions` option to `Yes` - Specify an S3 bucket name in the `S3 bucket` box- Click `Create`4. If 1 or more trails already exist, select the target trail to enable for global logging 5. Click the edit icon (pencil) next to `Apply trail to all regions` , Click `Yes` and Click `Save`. 6. Click the edit icon (pencil) next to `Management Events` click `All` for setting `Read/Write Events` and Click `Save`.**From Command Line:** ``` aws cloudtrail create-trail --name --bucket-name --is-multi-region-trailaws cloudtrail update-trail --name --is-multi-region-trail ```Note: Creating CloudTrail via CLI without providing any overriding options configures `Management Events` to set `All` type of `Read/Writes` by default.","AdditionalInformation": ""}],"description": "Ensure CloudTrail is enabled in all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3.2": {"name": "3.2","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-file-validation-enabling.html","Description": "CloudTrail log file validation creates a digitally signed digest file containing a hash of each log that CloudTrail writes to S3. These digest files can be used to determine whether a log file was changed, deleted, or unchanged after CloudTrail delivered the log. It is recommended that file validation be enabled on all CloudTrails.","DefaultValue": null,"AuditProcedure": "Perform the following on each trail to determine if log file validation is enabled:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane 3. For Every Trail: - Click on a trail via the link in the _Name_ column - Under the `General details` section, ensure `Log file validation` is set to `Enabled` **From Command Line:** ``` aws cloudtrail describe-trails ``` Ensure `LogFileValidationEnabled` is set to `true` for each trail","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling log file validation will provide additional integrity checking of CloudTrail logs.","RemediationProcedure": "Perform the following to enable log file validation on a given trail:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane 3. Click on target trail 4. Within the `General details` section click `edit` 5. Under the `Advanced settings` section 6. Check the enable box under `Log file validation`7. Click `Save changes` **From Command Line:** ``` aws cloudtrail update-trail --name --enable-log-file-validation ``` Note that periodic validation of logs using these digests can be performed by running the following command: ``` aws cloudtrail validate-logs --trail-arn --start-time --end-time ```","AdditionalInformation": ""}],"description": "Ensure CloudTrail log file validation is enabled","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.3": {"name": "3.3","checks": {"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html","Description": "CloudTrail logs a record of every API call made in your AWS account. These logs file are stored in an S3 bucket. It is recommended that the bucket policy or access control list (ACL) applied to the S3 bucket that CloudTrail logs to prevent public access to the CloudTrail logs.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if any public access is granted to an S3 bucket via an ACL or S3 bucket policy:**From Console:**1. Go to the Amazon CloudTrail console at [https://console.aws.amazon.com/cloudtrail/home](https://console.aws.amazon.com/cloudtrail/home) 2. In the `API activity history` pane on the left, click `Trails`3. In the `Trails` pane, note the bucket names in the `S3 bucket` column 4. Go to Amazon S3 console at [https://console.aws.amazon.com/s3/home](https://console.aws.amazon.com/s3/home) 5. For each bucket noted in step 3, right-click on the bucket and click `Properties`6. In the `Properties` pane, click the `Permissions` tab. 7. The tab shows a list of grants, one row per grant, in the bucket ACL. Each row identifies the grantee and the permissions granted. 8. Ensure no rows exists that have the `Grantee` set to `Everyone` or the `Grantee` set to `Any Authenticated User.`9. If the `Edit bucket policy` button is present, click it to review the bucket policy. 10. Ensure the policy does not contain a `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ```aws cloudtrail describe-trails --query 'trailList[*].S3BucketName' ``` 2. Ensure the `AllUsers` principal is not granted privileges to that `` : ```aws s3api get-bucket-acl --bucket --query 'Grants[?Grantee.URI== `https://acs.amazonaws.com/groups/global/AllUsers` ]' ``` 3. Ensure the `AuthenticatedUsers` principal is not granted privileges to that ``: ```aws s3api get-bucket-acl --bucket --query 'Grants[?Grantee.URI== `https://acs.amazonaws.com/groups/global/Authenticated Users` ]' ``` 4. Get the S3 Bucket Policy ```aws s3api get-bucket-policy --bucket ``` 5. Ensure the policy does not contain a `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}**Note:** Principal set to \"\\*\" or {\"AWS\" : \"\\*\"} allows anonymous access.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Allowing public access to CloudTrail log content may aid an adversary in identifying weaknesses in the affected account's use or configuration.","RemediationProcedure": "Perform the following to remove any public access that has been granted to the bucket via an ACL or S3 bucket policy:1. Go to Amazon S3 console at [https://console.aws.amazon.com/s3/home](https://console.aws.amazon.com/s3/home) 2. Right-click on the bucket and click Properties 3. In the `Properties` pane, click the `Permissions` tab. 4. The tab shows a list of grants, one row per grant, in the bucket ACL. Each row identifies the grantee and the permissions granted. 5. Select the row that grants permission to `Everyone` or `Any Authenticated User`6. Uncheck all the permissions granted to `Everyone` or `Any Authenticated User` (click `x` to delete the row). 7. Click `Save` to save the ACL. 8. If the `Edit bucket policy` button is present, click it. 9. Remove any `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}.","AdditionalInformation": ""}],"description": "Ensure the S3 bucket used to store CloudTrail logs is not publicly accessible","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3.4": {"name": "3.4","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-user-guide.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/how-cloudtrail-works.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-aws-service-specific-topics.html","Description": "AWS CloudTrail is a web service that records AWS API calls made in a given AWS account. 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. CloudTrail uses Amazon S3 for log file storage and delivery, so log files are stored durably. In addition to capturing CloudTrail logs within a specified S3 bucket for long term analysis, realtime analysis can be performed by configuring CloudTrail to send logs to CloudWatch Logs. For a trail that is enabled in all regions in an account, CloudTrail sends log files from all those regions to a CloudWatch Logs log group. It is recommended that CloudTrail logs be sent to CloudWatch Logs.Note: The intent of this recommendation is to ensure AWS account activity is being captured, monitored, and appropriately alarmed on. CloudWatch Logs is a native way to accomplish this using AWS services but does not preclude the use of an alternate solution.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure CloudTrail is configured as prescribed:**From Console:**1. Login to the CloudTrail console at `https://console.aws.amazon.com/cloudtrail/` 2. Under `Trails` , click on the CloudTrail you wish to evaluate 3. Under the `CloudWatch Logs` section. 4. Ensure a `CloudWatch Logs` log group is configured and listed. 5. Under `General details` confirm `Last log file delivered` has a recent (~one day old) timestamp.**From Command Line:**1. Run the following command to get a listing of existing trails: ```aws cloudtrail describe-trails ``` 2. Ensure `CloudWatchLogsLogGroupArn` is not empty and note the value of the `Name` property. 3. Using the noted value of the `Name` property, run the following command: ```aws cloudtrail get-trail-status --name ``` 4. Ensure the `LatestcloudwatchLogdDeliveryTime` property is set to a recent (~one day old) timestamp.If the `CloudWatch Logs` log group is not setup and the delivery time is not recent refer to the remediation below.","ImpactStatement": "Note: By default, CloudWatch Logs will store Logs indefinitely unless a specific retention period is defined for the log group. When choosing the number of days to retain, keep in mind the average days it takes an organization to realize they have been breached is 210 days (at the time of this writing). Since additional time is required to research a breach, a minimum 365 day retention policy allows time for detection and research. You may also wish to archive the logs to a cheaper storage service rather than simply deleting them. See the following AWS resource to manage CloudWatch Logs retention periods:1. https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/SettingLogRetention.html","AssessmentStatus": "Automated","RationaleStatement": "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.","RemediationProcedure": "Perform the following to establish the prescribed state:**From Console:**1. Login to the CloudTrail console at `https://console.aws.amazon.com/cloudtrail/` 2. Select the `Trail` the needs to be updated. 3. Scroll down to `CloudWatch Logs` 4. Click `Edit` 5. Under `CloudWatch Logs` click the box `Enabled` 6. Under `Log Group` pick new or select an existing log group 7. Edit the `Log group name` to match the CloudTrail or pick the existing CloudWatch Group. 8. Under `IAM Role` pick new or select an existing. 9. Edit the `Role name` to match the CloudTrail or pick the existing IAM Role. 10. Click `Save changes.**From Command Line:** ``` aws cloudtrail update-trail --name --cloudwatch-logs-log-group-arn --cloudwatch-logs-role-arn ```","AdditionalInformation": ""}],"description": "Ensure CloudTrail trails are integrated with CloudWatch Logs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.5": {"name": "3.5","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/cli/latest/reference/configservice/describe-configuration-recorder-status.html","Description": "AWS Config is a web service that performs configuration management of supported AWS resources within your account and delivers log files to you. The recorded information includes the configuration item (AWS resource), relationships between configuration items (AWS resources), any configuration changes between resources. It is recommended AWS Config be enabled in all regions.","DefaultValue": null,"AuditProcedure": "Process to evaluate AWS Config configuration per region**From Console:**1. Sign in to the AWS Management Console and open the AWS Config console at [https://console.aws.amazon.com/config/](https://console.aws.amazon.com/config/). 2. On the top right of the console select target Region. 3. If presented with Setup AWS Config - follow remediation procedure: 4. On the Resource inventory page, Click on edit (the gear icon). The Set Up AWS Config page appears. 5. Ensure 1 or both check-boxes under \"All Resources\" is checked.- Include global resources related to IAM resources - which needs to be enabled in 1 region only 6. Ensure the correct S3 bucket has been defined. 7. Ensure the correct SNS topic has been defined. 8. Repeat steps 2 to 7 for each region.**From Command Line:**1. Run this command to show all AWS Config recorders and their properties: ``` aws configservice describe-configuration-recorders ``` 2. Evaluate the output to ensure that there's at least one recorder for which `recordingGroup` object includes `\"allSupported\": true` AND `\"includeGlobalResourceTypes\": true`Note: There is one more parameter \"ResourceTypes\" in recordingGroup object. We don't need to check the same as whenever we set \"allSupported\": true, AWS enforces resource types to be empty (\"ResourceTypes\":[])Sample Output:``` {\"ConfigurationRecorders\": [{\"recordingGroup\": {\"allSupported\": true,\"resourceTypes\": [],\"includeGlobalResourceTypes\": true},\"roleARN\": \"arn:aws:iam:::role/service-role/\",\"name\": \"default\"}] } ```3. Run this command to show the status for all AWS Config recorders: ``` aws configservice describe-configuration-recorder-status ``` 4. In the output, find recorders with `name` key matching the recorders that met criteria in step 2. Ensure that at least one of them includes `\"recording\": true` and `\"lastStatus\": \"SUCCESS\"`","ImpactStatement": "It is recommended AWS Config be enabled in all regions.","AssessmentStatus": "Automated","RationaleStatement": "The AWS configuration item history captured by AWS Config enables security analysis, resource change tracking, and compliance auditing.","RemediationProcedure": "To implement AWS Config configuration:**From Console:**1. Select the region you want to focus on in the top right of the console 2. Click `Services`3. Click `Config`4. Define which resources you want to record in the selected region 5. Choose to include global resources (IAM resources) 6. Specify an S3 bucket in the same account or in another managed AWS account 7. Create an SNS Topic from the same AWS account or another managed AWS account**From Command Line:**1. Ensure there is an appropriate S3 bucket, SNS topic, and IAM role per the [AWS Config Service prerequisites](http://docs.aws.amazon.com/config/latest/developerguide/gs-cli-prereq.html). 2. Run this command to set up the configuration recorder ``` aws configservice subscribe --s3-bucket my-config-bucket --sns-topic arn:aws:sns:us-east-1:012345678912:my-config-notice --iam-role arn:aws:iam::012345678912:role/myConfigRole ``` 3. Run this command to start the configuration recorder: ``` start-configuration-recorder --configuration-recorder-name ```","AdditionalInformation": ""}],"description": "Ensure AWS Config is enabled in all regions","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.6": {"name": "3.6","checks": {"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerLogs.html","Description": "S3 Bucket Access Logging generates a log that contains access records for each request made to your S3 bucket. An access log record contains details about the request, such as the request type, the resources specified in the request worked, and the time and date the request was processed. It is recommended that bucket access logging be enabled on the CloudTrail S3 bucket.","DefaultValue": null,"AuditProcedure": "Perform the following ensure the CloudTrail S3 bucket has access logging is enabled:**From Console:**1. Go to the Amazon CloudTrail console at [https://console.aws.amazon.com/cloudtrail/home](https://console.aws.amazon.com/cloudtrail/home) 2. In the API activity history pane on the left, click Trails 3. In the Trails pane, note the bucket names in the S3 bucket column 4. Sign in to the AWS Management Console and open the S3 console at [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3). 5. Under `All Buckets` click on a target S3 bucket 6. Click on `Properties` in the top right of the console 7. Under `Bucket:` _ `` _ click on `Logging`8. Ensure `Enabled` is checked.**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ```aws cloudtrail describe-trails --query 'trailList[*].S3BucketName'``` 2. Ensure Bucket Logging is enabled: ``` aws s3api get-bucket-logging --bucket ``` Ensure command does not returns empty output.Sample Output for a bucket with logging enabled:``` {\"LoggingEnabled\": {\"TargetPrefix\": \"\",\"TargetBucket\": \"\"} } ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "By enabling S3 bucket logging on target S3 buckets, it is possible to capture all events which may affect objects within any target buckets. Configuring logs to be placed in a separate bucket allows access to log information which can be useful in security and incident response workflows.","RemediationProcedure": "Perform the following to enable S3 bucket logging:**From Console:**1. Sign in to the AWS Management Console and open the S3 console at [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3). 2. Under `All Buckets` click on the target S3 bucket 3. Click on `Properties` in the top right of the console 4. Under `Bucket:` click on `Logging`5. Configure bucket logging- Click on the `Enabled` checkbox- Select Target Bucket from list- Enter a Target Prefix 6. Click `Save`.**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ``` aws cloudtrail describe-trails --region --query trailList[*].S3BucketName ``` 2. Copy and add target bucket name at ``, Prefix for logfile at `` and optionally add an email address in the following template and save it as ``: ``` {\"LoggingEnabled\": {\"TargetBucket\": \"\",\"TargetPrefix\": \"\",\"TargetGrants\": [{\"Grantee\": {\"Type\": \"AmazonCustomerByEmail\",\"EmailAddress\": \"\"},\"Permission\": \"FULL_CONTROL\"}]}} ``` 3. Run the `put-bucket-logging` command with bucket name and `` as input, for more information refer at [put-bucket-logging](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-logging.html): ``` aws s3api put-bucket-logging --bucket --bucket-logging-status file:// ```","AdditionalInformation": ""}],"description": "Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.7": {"name": "3.7","checks": {"cloudtrail_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/encrypting-cloudtrail-log-files-with-aws-kms.html:https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html","Description": "AWS CloudTrail is a web service that records AWS API calls for an account and makes those logs available to users and resources in accordance with IAM policies. AWS Key Management Service (KMS) is a managed service that helps create and control the encryption keys used to encrypt account data, and uses Hardware Security Modules (HSMs) to protect the security of encryption keys. CloudTrail logs can be configured to leverage server side encryption (SSE) and KMS customer created master keys (CMK) to further protect CloudTrail logs. It is recommended that CloudTrail be configured to use SSE-KMS.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if CloudTrail is configured to use SSE-KMS:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. In the left navigation pane, choose `Trails` . 3. Select a Trail 4. Under the `S3` section, ensure `Encrypt log files` is set to `Yes` and a KMS key ID is specified in the `KSM Key Id` field.**From Command Line:**1. Run the following command: ```aws cloudtrail describe-trails``` 2. For each trail listed, SSE-KMS is enabled if the trail has a `KmsKeyId` property defined.","ImpactStatement": "Customer created keys incur an additional cost. See https://aws.amazon.com/kms/pricing/ for more information.","AssessmentStatus": "Automated","RationaleStatement": "Configuring CloudTrail to use SSE-KMS provides additional confidentiality controls on log data as a given user must have S3 read permission on the corresponding log bucket and must be granted decrypt permission by the CMK policy.","RemediationProcedure": "Perform the following to configure CloudTrail to use SSE-KMS:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. In the left navigation pane, choose `Trails` . 3. Click on a Trail 4. Under the `S3` section click on the edit button (pencil icon) 5. Click `Advanced`6. Select an existing CMK from the `KMS key Id` drop-down menu- Note: Ensure the CMK is located in the same region as the S3 bucket- Note: You will need to apply a KMS Key policy on the selected CMK in order for CloudTrail as a service to encrypt and decrypt log files using the CMK provided. Steps are provided [here](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/create-kms-key-policy-for-cloudtrail.html) for editing the selected CMK Key policy 7. Click `Save`8. You will see a notification message stating that you need to have decrypt permissions on the specified KMS key to decrypt log files. 9. Click `Yes` **From Command Line:** ``` aws cloudtrail update-trail --name --kms-id aws kms put-key-policy --key-id --policy ```","AdditionalInformation": "3 statements which need to be added to the CMK policy:1\\. Enable Cloudtrail to describe CMK properties ```

{\"Sid\": \"Allow CloudTrail access\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\"Action\": \"kms:DescribeKey\",\"Resource\": \"*\" } ``` 2\\. Granting encrypt permissions ``` 
{\"Sid\": \"Allow CloudTrail to encrypt logs\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\"Action\": \"kms:GenerateDataKey*\",\"Resource\": \"*\",\"Condition\": {\"StringLike\": {\"kms:EncryptionContext:aws:cloudtrail:arn\": [\"arn:aws:cloudtrail:*:aws-account-id:trail/*\"]}} } ``` 3\\. Granting decrypt permissions ``` 
{\"Sid\": \"Enable CloudTrail log decrypt permissions\",\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"arn:aws:iam::aws-account-id:user/username\"},\"Action\": \"kms:Decrypt\",\"Resource\": \"*\",\"Condition\": {\"Null\": {\"kms:EncryptionContext:aws:cloudtrail:arn\": \"false\"}} } ```"}],"description": "Ensure CloudTrail logs are encrypted at rest using KMS CMKs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.8": {"name": "3.8","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://aws.amazon.com/kms/pricing/:https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final","Description": "AWS Key Management Service (KMS) allows customers to rotate the backing key which is key material stored within the KMS which is tied to the key ID of the Customer Created customer master key (CMK). It is the backing key that is used to perform cryptographic operations such as encryption and decryption. Automated key rotation currently retains all prior backing keys so that decryption of encrypted data can take place transparently. It is recommended that CMK key rotation be enabled for symmetric keys. Key rotation can not be enabled for any asymmetric CMK.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam](https://console.aws.amazon.com/iam). 2. In the left navigation pane, choose `Customer managed keys` 3. Select a customer managed CMK where `Key spec = SYMMETRIC_DEFAULT` 4. Underneath the `General configuration` panel open the tab `Key rotation` 5. Ensure that the checkbox `Automatically rotate this KMS key every year.` is activated 6. Repeat steps 3 - 5 for all customer managed CMKs where \"Key spec = SYMMETRIC_DEFAULT\"**From Command Line:**1. Run the following command to get a list of all keys and their associated `KeyIds````aws kms list-keys ``` 2. For each key, note the KeyId and run the following command ``` describe-key --key-id  ``` 3. If the response contains \"KeySpec = SYMMETRIC_DEFAULT\" run the following command ```aws kms get-key-rotation-status --key-id  ``` 4. Ensure `KeyRotationEnabled` is set to `true` 5. Repeat steps 2 - 4 for all remaining CMKs","ImpactStatement": "Creation, management, and storage of CMKs may require additional time from and administrator.","AssessmentStatus": "Automated","RationaleStatement": "Rotating encryption keys helps reduce the potential impact of a compromised key as data encrypted with a new key cannot be accessed with a previous key that may have been exposed. Keys should be rotated every year, or upon event that would result in the compromise of that key.","RemediationProcedure": "**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam](https://console.aws.amazon.com/iam). 2. In the left navigation pane, choose `Customer managed keys` . 3. Select a customer managed CMK where `Key spec = SYMMETRIC_DEFAULT` 4. Underneath the \"General configuration\" panel open the tab \"Key rotation\" 5. Check the \"Automatically rotate this KMS key every year.\" checkbox**From Command Line:**1. Run the following command to enable key rotation: ```aws kms enable-key-rotation --key-id  ```","AdditionalInformation": ""}],"description": "Ensure rotation for customer created symmetric CMKs is enabled","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.9": {"name": "3.9","checks": {"vpc_flow_logs_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/flow-logs.html","Description": "VPC Flow Logs is a feature that enables you to capture information about the IP traffic going to and from network interfaces in your VPC. After you've created a flow log, you can view and retrieve its data in Amazon CloudWatch Logs. It is recommended that VPC Flow Logs be enabled for packet \"Rejects\" for VPCs.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if VPC Flow logs are enabled:**From Console:**1. Sign into the management console 2. Select `Services` then `VPC`3. In the left navigation pane, select `Your VPCs`4. Select a VPC 5. In the right pane, select the `Flow Logs` tab. 6. Ensure a Log Flow exists that has `Active` in the `Status` column.**From Command Line:**1. Run `describe-vpcs` command (OSX/Linux/UNIX) to list the VPC networks available in the current AWS region: ``` aws ec2 describe-vpcs --region  --query Vpcs[].VpcId ``` 2. The command output returns the `VpcId` available in the selected region. 3. Run `describe-flow-logs` command (OSX/Linux/UNIX) using the VPC ID to determine if the selected virtual network has the Flow Logs feature enabled: ``` aws ec2 describe-flow-logs --filter \"Name=resource-id,Values=\" ``` 4. If there are no Flow Logs created for the selected VPC, the command output will return an `empty list []`. 5. Repeat step 3 for other VPCs available in the same region. 6. Change the region by updating `--region` and repeat steps 1 - 5 for all the VPCs.","ImpactStatement": "By default, CloudWatch Logs will store Logs indefinitely unless a specific retention period is defined for the log group. When choosing the number of days to retain, keep in mind the average days it takes an organization to realize they have been breached is 210 days (at the time of this writing). Since additional time is required to research a breach, a minimum 365 day retention policy allows time for detection and research. You may also wish to archive the logs to a cheaper storage service rather than simply deleting them. See the following AWS resource to manage CloudWatch Logs retention periods:1. https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/SettingLogRetention.html","AssessmentStatus": "Automated","RationaleStatement": "VPC Flow Logs provide visibility into network traffic that traverses the VPC and can be used to detect anomalous traffic or insight during security workflows.","RemediationProcedure": "Perform the following to determine if VPC Flow logs is enabled:**From Console:**1. Sign into the management console 2. Select `Services` then `VPC`3. In the left navigation pane, select `Your VPCs`4. Select a VPC 5. In the right pane, select the `Flow Logs` tab. 6. If no Flow Log exists, click `Create Flow Log`7. For Filter, select `Reject` 8. Enter in a `Role` and `Destination Log Group`9. Click `Create Log Flow`10. Click on `CloudWatch Logs Group` **Note:** Setting the filter to \"Reject\" will dramatically reduce the logging data accumulation for this recommendation and provide sufficient information for the purposes of breach detection, research and remediation. However, during periods of least privilege security group engineering, setting this the filter to \"All\" can be very helpful in discovering existing traffic flows required for proper operation of an already running environment.**From Command Line:**1. Create a policy document and name it as `role_policy_document.json` and paste the following content: ``` {\"Version\": \"2012-10-17\",\"Statement\": [{\"Sid\": \"test\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"ec2.amazonaws.com\"},\"Action\": \"sts:AssumeRole\"}] } ``` 2. Create another policy document and name it as `iam_policy.json` and paste the following content: ``` {\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Action\":[\"logs:CreateLogGroup\",\"logs:CreateLogStream\",\"logs:DescribeLogGroups\",\"logs:DescribeLogStreams\",\"logs:PutLogEvents\",\"logs:GetLogEvents\",\"logs:FilterLogEvents\"],\"Resource\": \"*\"}] } ``` 3. Run the below command to create an IAM role: ``` aws iam create-role --role-name  --assume-role-policy-document file://role_policy_document.json``` 4. Run the below command to create an IAM policy: ``` aws iam create-policy --policy-name  --policy-document file://iam-policy.json ``` 5. Run `attach-group-policy` command using the IAM policy ARN returned at the previous step to attach the policy to the IAM role (if the command succeeds, no output is returned): ``` aws iam attach-group-policy --policy-arn arn:aws:iam:::policy/ --group-name  ``` 6. Run `describe-vpcs` to get the VpcId available in the selected region: ``` aws ec2 describe-vpcs --region  ``` 7. The command output should return the VPC Id available in the selected region. 8. Run `create-flow-logs` to create a flow log for the vpc: ``` aws ec2 create-flow-logs --resource-type VPC --resource-ids  --traffic-type REJECT --log-group-name  --deliver-logs-permission-arn  ``` 9. Repeat step 8 for other vpcs available in the selected region. 10. Change the region by updating --region and repeat remediation procedure for other vpcs.","AdditionalInformation": ""}],"description": "Ensure VPC flow logging is enabled in all VPCs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"4.1": {"name": "4.1","checks": {"cloudwatch_log_metric_filter_unauthorized_api_calls": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://aws.amazon.com/sns/:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for unauthorized API calls.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with \"Name\":` note ``- From value associated with \"CloudWatchLogsLogGroupArn\" note Example: for CloudWatchLogsLogGroupArn that looks like arn:aws:logs:::log-group:NewGroup:*,  would be NewGroup- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name <\"Name\" as shown in describe-trails>`Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this `` that you captured in step 1:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.errorCode = *UnauthorizedOperation) || ($.errorCode = AccessDenied*) || ($.sourceIPAddress!=delivery.logs.amazonaws.com) || ($.eventName!=HeadBucket) }\", ```4. Note the \"filterName\" `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query \"MetricAlarms[?MetricName == `unauthorized_api_calls_metric`]\" ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "This alert may be triggered by normal read-only console activities that attempt to opportunistically gather optional information, but gracefully fail if they don't have permissions.If an excessive number of alerts are being generated then an organization may wish to consider adding read access to the limited IAM user permissions simply to quiet the alerts.In some cases doing this may allow the users to actually view some areas of the system - any additional access given should be reviewed for alignment with the original limited IAM user intent.","AssessmentStatus": "Automated","RationaleStatement": "Monitoring unauthorized API calls will help reveal application errors and may reduce time to detect malicious activity.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for unauthorized API calls and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name \"cloudtrail_log_group_name\" --filter-name \"\" --metric-transformations metricName=unauthorized_api_calls_metric,metricNamespace=CISBenchmark,metricValue=1 --filter-pattern \"{ ($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\") || ($.sourceIPAddress!=\"delivery.logs.amazonaws.com\") || ($.eventName!=\"HeadBucket\") }\" ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms. **Note**: Capture the TopicArn displayed when creating the SNS Topic in Step 2.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name \"unauthorized_api_calls_alarm\" --metric-name \"unauthorized_api_calls_metric\" --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace \"CISBenchmark\" --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for unauthorized API calls","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.2": {"name": "4.2","checks": {"cloudwatch_log_metric_filter_sign_in_without_mfa": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/viewing_metrics_with_cloudwatch.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for console logins that are not protected by multi-factor authentication (MFA).","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all `CloudTrails`:``` aws cloudtrail describe-trails ```- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region `CloudTrail` is active``` aws cloudtrail get-trail-status --name  ```Ensure in the output that `IsLogging` is set to `TRUE`- Ensure identified Multi-region 'Cloudtrail' captures all Management Events``` aws cloudtrail get-event-selectors --trail-name  ```Ensure in the output there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }\" ```Or (To reduce false positives incase Single Sign-On (SSO) is used in organization):``` \"filterPattern\": \"{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\") }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring for single-factor console logins will increase visibility into accounts that are not protected by MFA.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Management Console sign-in without MFA and the `` taken from audit step 1.Use Command: ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }' ```Or (To reduce false positives incase Single Sign-On (SSO) is used in organization):``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\") }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored -Filter pattern set to `{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\"}` reduces false alarms raised when user logs in via SSO account."}],"description": "Ensure a log metric filter and alarm exist for Management Console sign-in without MFA","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.3": {"name": "4.3","checks": {"cloudwatch_log_metric_filter_root_usage": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for 'root' login attempts.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails:`aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring for 'root' account logins will provide visibility into the use of a fully privileged account and an opportunity to reduce the use of it.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for 'Root' account usage and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name `` --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "**Configuring log metric filter and alarm on Multi-region (global) CloudTrail**- ensures that activities from all regions (used as well as unused) are monitored- ensures that activities on all supported global services are monitored- ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for usage of 'root' account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.4": {"name": "4.4","checks": {"cloudwatch_log_metric_filter_policy_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established changes made to Identity and Access Management (IAM) policies.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails:`aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to IAM policies will help ensure authentication and authorization controls remain intact.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for IAM policy changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name `` --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for IAM policy changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.5": {"name": "4.5","checks": {"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for detecting changes to CloudTrail's configurations.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to CloudTrail's configuration will help ensure sustained visibility to activities performed in the AWS account.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for cloudtrail configuration changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for CloudTrail configuration changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.6": {"name": "4.6","checks": {"cloudwatch_log_metric_filter_authentication_failures": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for failed console authentication attempts.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring failed console logins may decrease lead time to detect an attempt to brute force a credential, which may provide an indicator, such as source IP, that can be used in other event correlation.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS management Console Login Failures and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }' ``` **Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for AWS Management Console authentication failures","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.7": {"name": "4.7","checks": {"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for customer created CMKs which have changed state to disabled or scheduled deletion.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Data encrypted with disabled or deleted keys will no longer be accessible.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for disabled or scheduled for deletion CMK's and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }' ``` **Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.8": {"name": "4.8","checks": {"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for changes to S3 bucket policies.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to S3 bucket policies may reduce time to detect and correct permissive policies on sensitive S3 buckets.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for S3 bucket policy changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for S3 bucket policy changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.9": {"name": "4.9","checks": {"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for detecting changes to CloudTrail's configurations.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to AWS Config configuration will help ensure sustained visibility of configuration items within the AWS account.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Configuration changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for AWS Config configuration changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"5.1": {"name": "5.1","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html:https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Security.html#VPC_Security_Comparison","Description": "The Network Access Control List (NACL) function provide stateless filtering of ingress and egress network traffic to AWS resources. It is recommended that no NACL allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "**From Console:**Perform the following to determine if the account is configured as prescribed: 1. Login to the AWS Management Console at https://console.aws.amazon.com/vpc/home 2. In the left pane, click `Network ACLs` 3. For each network ACL, perform the following:- Select the network ACL- Click the `Inbound Rules` tab- Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `0.0.0.0/0` and shows `ALLOW`**Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "**From Console:**Perform the following: 1. Login to the AWS Management Console at https://console.aws.amazon.com/vpc/home 2. In the left pane, click `Network ACLs` 3. For each network ACL to remediate, perform the following:- Select the network ACL- Click the `Inbound Rules` tab- Click `Edit inbound rules`- Either A) update the Source field to a range other than 0.0.0.0/0, or, B) Click `Delete` to remove the offending inbound rule- Click `Save`","AdditionalInformation": ""}],"description": "Ensure no Network ACLs allow ingress from 0.0.0.0/0 to remote server administration ports","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"5.2": {"name": "5.2","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#deleting-security-group-rule","Description": "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `0.0.0.0/0` **Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports.","ImpactStatement": "When updating an existing environment, ensure that administrators have access to remote server administration ports through another mechanism before removing access by deleting the 0.0.0.0/0 inbound rule.","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "Perform the following to implement the prescribed state:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Click the `Edit inbound rules` button 4. Identify the rules to be edited or removed 5. Either A) update the Source field to a range other than 0.0.0.0/0, or, B) Click `Delete` to remove the offending inbound rule 6. Click `Save rules`","AdditionalInformation": ""}],"description": "Ensure no security groups allow ingress from 0.0.0.0/0 to remote server administration ports","checks_status": {"fail": 0,"pass": 3,"total": 3,"manual": 0}},"5.3": {"name": "5.3","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#deleting-security-group-rule","Description": "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `::/0` **Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports.","ImpactStatement": "When updating an existing environment, ensure that administrators have access to remote server administration ports through another mechanism before removing access by deleting the ::/0 inbound rule.","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "Perform the following to implement the prescribed state:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Click the `Edit inbound rules` button 4. Identify the rules to be edited or removed 5. Either A) update the Source field to a range other than ::/0, or, B) Click `Delete` to remove the offending inbound rule 6. Click `Save rules`","AdditionalInformation": ""}],"description": "Ensure no security groups allow ingress from ::/0 to remote server administration ports","checks_status": {"fail": 0,"pass": 3,"total": 3,"manual": 0}},"5.4": {"name": "5.4","checks": {"ec2_securitygroup_default_restrict_traffic": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#default-security-group","Description": "A VPC comes with a default security group whose initial settings deny all inbound traffic, allow all outbound traffic, and allow all traffic between instances assigned to the security group. If you don't specify a security group when you launch an instance, the instance is automatically assigned to this default security group. Security groups provide stateful filtering of ingress/egress network traffic to AWS resources. It is recommended that the default security group restrict all traffic.The default VPC in every region should have its default security group updated to comply. Any newly created VPCs will automatically contain a default security group that will need remediation to comply with this recommendation.**NOTE:** When implementing this recommendation, VPC flow logging is invaluable in determining the least privilege port access required by systems to work properly because it can log all packet acceptances and rejections occurring under the current security groups. This dramatically reduces the primary barrier to least privilege engineering - discovering the minimum ports required by systems in the environment. Even if the VPC flow logging recommendation in this benchmark is not adopted as a permanent security measure, it should be used during any period of discovery and engineering for least privileged security groups.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:Security Group State1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. For each default security group, perform the following: 1. Select the `default` security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exist 4. Click the `Outbound Rules` tab 5. Ensure no rules existSecurity Group Members1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all default groups in all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. Copy the id of the default security group. 5. Change to the EC2 Management Console at https://console.aws.amazon.com/ec2/v2/home 6. In the filter column type 'Security Group ID : < security group id from #4 >'","ImpactStatement": "Implementing this recommendation in an existing VPC containing operating resources requires extremely careful migration planning as the default security groups are likely to be enabling many ports that are unknown. Enabling VPC flow logging (of accepts) in an existing environment that is known to be breach free will reveal the current pattern of ports being used for each instance to communicate successfully.","AssessmentStatus": "Automated","RationaleStatement": "Configuring all VPC default security groups to restrict all traffic will encourage least privilege security group development and mindful placement of AWS resources into security groups which will in-turn reduce the exposure of those resources.","RemediationProcedure": "Security Group MembersPerform the following to implement the prescribed state:1. Identify AWS resources that exist within the default security group 2. Create a set of least privilege security groups for those resources 3. Place the resources in those security groups 4. Remove the resources noted in #1 from the default security groupSecurity Group State1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. For each default security group, perform the following: 1. Select the `default` security group 2. Click the `Inbound Rules` tab 3. Remove any inbound rules 4. Click the `Outbound Rules` tab 5. Remove any Outbound rulesRecommended:IAM groups allow you to edit the \"name\" field. After remediating default groups rules for all VPCs in all regions, edit this field to add text similar to \"DO NOT USE. DO NOT ADD RULES\"","AdditionalInformation": ""}],"description": "Ensure the default security group of every VPC restricts all traffic","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"5.5": {"name": "5.5","checks": {"vpc_peering_routing_tables_with_least_privilege": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "5. Networking","References": "https://docs.aws.amazon.com/AmazonVPC/latest/PeeringGuide/peering-configurations-partial-access.html:https://docs.aws.amazon.com/cli/latest/reference/ec2/create-vpc-peering-connection.html","Description": "Once a VPC peering connection is established, routing tables must be updated to establish any connections between the peered VPCs. These routes can be as specific as desired - even peering a VPC to only a single host on the other side of the connection.","DefaultValue": null,"AuditProcedure": "Review routing tables of peered VPCs for whether they route all subnets of each VPC and whether that is necessary to accomplish the intended purposes for peering the VPCs.**From Command Line:**1. List all the route tables from a VPC and check if \"GatewayId\" is pointing to a __ (e.g. pcx-1a2b3c4d) and if \"DestinationCidrBlock\" is as specific as desired. ``` aws ec2 describe-route-tables --filter \"Name=vpc-id,Values=\" --query \"RouteTables[*].{RouteTableId:RouteTableId, VpcId:VpcId, Routes:Routes, AssociatedSubnets:Associations[*].SubnetId}\" ```","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Being highly selective in peering routing tables is a very effective way of minimizing the impact of breach as resources outside of these routes are inaccessible to the peered VPC.","RemediationProcedure": "Remove and add route table entries to ensure that the least number of subnets or hosts as is required to accomplish the purpose for peering are routable.**From Command Line:**1. For each __ containing routes non compliant with your routing policy (which grants more than desired \"least access\"), delete the non compliant route: ``` aws ec2 delete-route --route-table-id  --destination-cidr-block  ```2. Create a new compliant route: ``` aws ec2 create-route --route-table-id  --destination-cidr-block  --vpc-peering-connection-id  ```","AdditionalInformation": "If an organization has AWS transit gateway implemented in their VPC architecture they should look to apply the recommendation above for \"least access\" routing architecture at the AWS transit gateway level in combination with what must be implemented at the standard VPC route table. More specifically, to route traffic between two or more VPCs via a transit gateway VPCs must have an attachment to a transit gateway route table as well as a route, therefore to avoid routing traffic between VPCs an attachment to the transit gateway route table should only be added where there is an intention to route traffic between the VPCs. As transit gateways are able to host multiple route tables it is possible to group VPCs by attaching them to a common route table."}],"description": "Ensure routing tables for VPC peering are \"least access\"","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.10": {"name": "1.10","checks": {"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://tools.ietf.org/html/rfc6238:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#enable-mfa-for-privileged-users:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html:https://blogs.aws.amazon.com/security/post/Tx2SJJYE082KBUK/How-to-Delegate-Management-of-Multi-Factor-Authentication-to-AWS-IAM-Users","Description": "Multi-Factor Authentication (MFA) adds an extra layer of authentication assurance beyond traditional credentials. With MFA enabled, when a user signs in to the AWS Console, they will be prompted for their user name and password as well as for an authentication code from their physical or virtual MFA token. It is recommended that MFA be enabled for all accounts that have a console password.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if a MFA device is enabled for all IAM users having a console password:**From Console:**1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the left pane, select `Users`3. If the `MFA` or `Password age` columns are not visible in the table, click the gear icon at the upper right corner of the table and ensure a checkmark is next to both, then click `Close`. 4. Ensure that for each user where the `Password age` column shows a password age, the `MFA` column shows `Virtual`, `U2F Security Key`, or `Hardware`.**From Command Line:**1. Run the following command (OSX/Linux/UNIX) to generate a list of all IAM users along with their password and MFA status: ```aws iam generate-credential-report ``` ```aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,8``` 2. The output of this command will produce a table similar to the following: ```user,password_enabled,mfa_activeelise,false,falsebrandon,true,truerakesh,false,falsehelene,false,falseparas,true,trueanitha,false,false``` 3. For any column having `password_enabled` set to `true` , ensure `mfa_active` is also set to `true.`","ImpactStatement": "AWS will soon end support for SMS multi-factor authentication (MFA). New customers are not allowed to use this feature. We recommend that existing customers switch to one of the following alternative methods of MFA.","AssessmentStatus": "Automated","RationaleStatement": "Enabling MFA provides increased security for console access as it requires the authenticating principal to possess a device that displays a time-sensitive key and have knowledge of a credential.","RemediationProcedure": "Perform the following to enable MFA:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at 'https://console.aws.amazon.com/iam/' 2. In the left pane, select `Users`. 3. In the `User Name` list, choose the name of the intended MFA user. 4. Choose the `Security Credentials` tab, and then choose `Manage MFA Device`. 5. In the `Manage MFA Device wizard`, choose `Virtual MFA` device, and then choose `Continue`. IAM generates and displays configuration information for the virtual MFA device, including a QR code graphic. The graphic is a representation of the 'secret configuration key' that is available for manual entry on devices that do not support QR codes.6. Open your virtual MFA application. (For a list of apps that you can use for hosting virtual MFA devices, see Virtual MFA Applications at https://aws.amazon.com/iam/details/mfa/#Virtual_MFA_Applications). If the virtual MFA application supports multiple accounts (multiple virtual MFA devices), choose the option to create a new account (a new virtual MFA device). 7. Determine whether the MFA app supports QR codes, and then do one of the following: - Use the app to scan the QR code. For example, you might choose the camera icon or choose an option similar to Scan code, and then use the device's camera to scan the code.- In the Manage MFA Device wizard, choose Show secret key for manual configuration, and then type the secret configuration key into your MFA application. When you are finished, the virtual MFA device starts generating one-time passwords.8. In the `Manage MFA Device wizard`, in the `MFA Code 1 box`, type the `one-time password` that currently appears in the virtual MFA device. Wait up to 30 seconds for the device to generate a new one-time password. Then type the second `one-time password` into the `MFA Code 2 box`.9. Click `Assign MFA`.","AdditionalInformation": "**Forced IAM User Self-Service Remediation**Amazon has published a pattern that forces users to self-service setup MFA before they have access to their complete permissions set. Until they complete this step, they cannot access their full permissions. This pattern can be used on new AWS accounts. It can also be used on existing accounts - it is recommended users are given instructions and a grace period to accomplish MFA enrollment before active enforcement on existing AWS accounts."}],"description": "Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.11": {"name": "1.11","checks": {"iam_user_no_setup_initial_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/cli/latest/reference/iam/delete-access-key.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html","Description": "AWS console defaults to no check boxes selected when creating a new IAM user. When cerating the IAM User credentials you have to determine what type of access they require. Programmatic access: The IAM user might need to make API calls, use the AWS CLI, or use the Tools for Windows PowerShell. In that case, create an access key (access key ID and a secret access key) for that user. AWS Management Console access: If the user needs to access the AWS Management Console, create a password for the user.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if access keys were created upon user creation and are being used and rotated as prescribed:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on a User where column `Password age` and `Access key age` is not set to `None` 5. Click on `Security credentials` Tab 6. Compare the user 'Creation time` to the Access Key `Created` date. 6. For any that match, the key was created during initial user setup.- Keys that were created at the same time as the user profile and do not have a last used date should be deleted. Refer to the remediation below.**From Command Line:**1. Run the following command (OSX/Linux/UNIX) to generate a list of all IAM users along with their access keys utilization: ```aws iam generate-credential-report ``` ```aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,9,11,14,16 ``` 2. The output of this command will produce a table similar to the following: ``` user,password_enabled,access_key_1_active,access_key_1_last_used_date,access_key_2_active,access_key_2_last_used_dateelise,false,true,2015-04-16T15:14:00+00:00,false,N/Abrandon,true,true,N/A,false,N/Arakesh,false,false,N/A,false,N/Ahelene,false,true,2015-11-18T17:47:00+00:00,false,N/Aparas,true,true,2016-08-28T12:04:00+00:00,true,2016-03-04T10:11:00+00:00anitha,true,true,2016-06-08T11:43:00+00:00,true,N/A``` 3. For any user having `password_enabled` set to `true` AND `access_key_last_used_date` set to `N/A` refer to the remediation below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Requiring the additional steps be taken by the user for programmatic access after their profile has been created will give a stronger indication of intent that access keys are [a] necessary for their work and [b] once the access key is established on an account that the keys may be in use somewhere in the organization.**Note**: Even if it is known the user will need access keys, require them to create the keys themselves or put in a support ticket to have them created as a separate step from user creation.","RemediationProcedure": "Perform the following to delete access keys that do not pass the audit:**From Console:**1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. As an Administrator - Click on the X `(Delete)` for keys that were created at the same time as the user profile but have not been used. 7. As an IAM User- Click on the X `(Delete)` for keys that were created at the same time as the user profile but have not been used.**From Command Line:** ``` aws iam delete-access-key --access-key-id  --user-name  ```","AdditionalInformation": "Credential report does not appear to contain \"Key Creation Date\""}],"description": "Do not setup access keys during initial user setup for all IAM users that have a console password","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.12": {"name": "1.12","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#remove-credentials:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_admin-change-user.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "AWS IAM users can access AWS resources using different types of credentials, such as passwords or access keys. It is recommended that all credentials that have been unused in 45 or greater days be deactivated or removed.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if unused credentials exist:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM` 4. Click on `Users` 5. Click the `Settings` (gear) icon. 6. Select `Console last sign-in`, `Access key last used`, and `Access Key Id` 7. Click on `Close`8. Check and ensure that `Console last sign-in` is less than 45 days ago.**Note** - `Never` means the user has never logged in.9. Check and ensure that `Access key age` is less than 45 days and that `Access key last used` does not say `None`If the user hasn't signed into the Console in the last 45 days or Access keys are over 45 days old refer to the remediation.**From Command Line:****Download Credential Report:**1. Run the following commands: ```aws iam generate-credential-report aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,5,6,9,10,11,14,15,16 | grep -v '^' ```**Ensure unused credentials do not exist:**2. For each user having `password_enabled` set to `TRUE` , ensure `password_last_used_date` is less than `45` days ago.- When `password_enabled` is set to `TRUE` and `password_last_used` is set to `No_Information` , ensure `password_last_changed` is less than 45 days ago.3. For each user having an `access_key_1_active` or `access_key_2_active` to `TRUE` , ensure the corresponding `access_key_n_last_used_date` is less than `45` days ago.- When a user having an `access_key_x_active` (where x is 1 or 2) to `TRUE` and corresponding access_key_x_last_used_date is set to `N/A', ensure `access_key_x_last_rotated` is less than 45 days ago.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Disabling or removing unnecessary credentials will reduce the window of opportunity for credentials associated with a compromised or abandoned account to be used.","RemediationProcedure": "**From Console:**Perform the following to manage Unused Password (IAM user console access)1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. Select user whose `Console last sign-in` is greater than 45 days 7. Click `Security credentials` 8. In section `Sign-in credentials`, `Console password` click `Manage`9. Under Console Access select `Disable` 10.Click `Apply`Perform the following to deactivate Access Keys:1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. Select any access keys that are over 45 days old and that have been used and - Click on `Make Inactive` 7. Select any access keys that are over 45 days old and that have not been used and - Click the X to `Delete`","AdditionalInformation": " is excluded in the audit since the root account should not be used for day to day business and would likely be unused for more than 45 days."}],"description": "Ensure credentials unused for 45 days or greater are disabled","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1.13": {"name": "1.13","checks": {"iam_user_two_active_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "Access keys are long-term credentials for an IAM user or the AWS account 'root' user. You can use access keys to sign programmatic requests to the AWS CLI or AWS API (directly or using the AWS SDK)","DefaultValue": null,"AuditProcedure": "**From Console:**1. Sign in to the AWS Management Console and navigate to IAM dashboard at `https://console.aws.amazon.com/iam/`. 2. In the left navigation panel, choose `Users`. 3. Click on the IAM user name that you want to examine. 4. On the IAM user configuration page, select `Security Credentials` tab. 5. Under `Access Keys` section, in the Status column, check the current status for each access key associated with the IAM user. If the selected IAM user has more than one access key activated then the users access configuration does not adhere to security best practices and the risk of accidental exposures increases. - Repeat steps no. 3 – 5 for each IAM user in your AWS account.**From Command Line:**1. Run `list-users` command to list all IAM users within your account: ``` aws iam list-users --query \"Users[*].UserName\" ``` The command output should return an array that contains all your IAM user names.2. Run `list-access-keys` command using the IAM user name list to return the current status of each access key associated with the selected IAM user: ``` aws iam list-access-keys --user-name  ``` The command output should expose the metadata `(\"Username\", \"AccessKeyId\", \"Status\", \"CreateDate\")` for each access key on that user account.3. Check the `Status` property value for each key returned to determine each keys current state. If the `Status` property value for more than one IAM access key is set to `Active`, the user access configuration does not adhere to this recommendation, refer to the remediation below.- Repeat steps no. 2 and 3 for each IAM user in your AWS account.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Access keys are long-term credentials for an IAM user or the AWS account 'root' user. You can use access keys to sign programmatic requests to the AWS CLI or AWS API. One of the best ways to protect your account is to not allow users to have multiple access keys.","RemediationProcedure": "**From Console:**1. Sign in to the AWS Management Console and navigate to IAM dashboard at `https://console.aws.amazon.com/iam/`. 2. In the left navigation panel, choose `Users`. 3. Click on the IAM user name that you want to examine. 4. On the IAM user configuration page, select `Security Credentials` tab. 5. In `Access Keys` section, choose one access key that is less than 90 days old. This should be the only active key used by this IAM user to access AWS resources programmatically. Test your application(s) to make sure that the chosen access key is working. 6. In the same `Access Keys` section, identify your non-operational access keys (other than the chosen one) and deactivate it by clicking the `Make Inactive` link. 7. If you receive the `Change Key Status` confirmation box, click `Deactivate` to switch off the selected key. 8. Repeat steps no. 3 – 7 for each IAM user in your AWS account.**From Command Line:**1. Using the IAM user and access key information provided in the `Audit CLI`, choose one access key that is less than 90 days old. This should be the only active key used by this IAM user to access AWS resources programmatically. Test your application(s) to make sure that the chosen access key is working.2. Run the `update-access-key` command below using the IAM user name and the non-operational access key IDs to deactivate the unnecessary key(s). Refer to the Audit section to identify the unnecessary access key ID for the selected IAM user**Note** - the command does not return any output: ``` aws iam update-access-key --access-key-id  --status Inactive --user-name  ``` 3. To confirm that the selected access key pair has been successfully `deactivated` run the `list-access-keys` audit command again for that IAM User: ``` aws iam list-access-keys --user-name  ``` - The command output should expose the metadata for each access key associated with the IAM user. If the non-operational key pair(s) `Status` is set to `Inactive`, the key has been successfully deactivated and the IAM user access configuration adheres now to this recommendation.4. Repeat steps no. 1 – 3 for each IAM user in your AWS account.","AdditionalInformation": ""}],"description": "Ensure there is only one active access key available for any single IAM user","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.14": {"name": "1.14","checks": {"iam_rotate_access_key_90_days": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#rotate-credentials:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html:https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "Access keys consist of an access key ID and secret access key, which are used to sign programmatic requests that you make to AWS. AWS users need their own access keys to make programmatic calls to AWS from the AWS Command Line Interface (AWS CLI), Tools for Windows PowerShell, the AWS SDKs, or direct HTTP calls using the APIs for individual AWS services. It is recommended that all access keys be regularly rotated.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if access keys are rotated as prescribed:**From Console:**1. Go to Management Console (https://console.aws.amazon.com/iam) 2. Click on `Users` 3. Click `setting` icon 4. Select `Console last sign-in` 5. Click `Close` 6. Ensure that `Access key age` is less than 90 days ago. note) `None` in the `Access key age` means the user has not used the access key.**From Command Line:**``` aws iam generate-credential-report aws iam get-credential-report --query 'Content' --output text | base64 -d ``` The `access_key_1_last_rotated` field in this file notes The date and time, in ISO 8601 date-time format, when the user's access key was created or last changed. If the user does not have an active access key, the value in this field is N/A (not applicable).","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Rotating access keys will reduce the window of opportunity for an access key that is associated with a compromised or terminated account to be used.Access keys should be rotated to ensure that data cannot be accessed with an old key which might have been lost, cracked, or stolen.","RemediationProcedure": "Perform the following to rotate access keys:**From Console:**1. Go to Management Console (https://console.aws.amazon.com/iam) 2. Click on `Users` 3. Click on `Security Credentials`4. As an Administrator - Click on `Make Inactive` for keys that have not been rotated in `90` Days 5. As an IAM User- Click on `Make Inactive` or `Delete` for keys which have not been rotated or used in `90` Days 6. Click on `Create Access Key`7. Update programmatic call with new Access Key credentials**From Command Line:**1. While the first access key is still active, create a second access key, which is active by default. Run the following command: ``` aws iam create-access-key ```At this point, the user has two active access keys.2. Update all applications and tools to use the new access key. 3. Determine whether the first access key is still in use by using this command: ``` aws iam get-access-key-last-used ``` 4. One approach is to wait several days and then check the old access key for any use before proceeding.Even if step Step 3 indicates no use of the old key, it is recommended that you do not immediately delete the first access key. Instead, change the state of the first access key to Inactive using this command: ``` aws iam update-access-key ``` 5. Use only the new access key to confirm that your applications are working. Any applications and tools that still use the original access key will stop working at this point because they no longer have access to AWS resources. If you find such an application or tool, you can switch its state back to Active to reenable the first access key. Then return to step Step 2 and update this application to use the new key.6. After you wait some period of time to ensure that all applications and tools have been updated, you can delete the first access key with this command: ``` aws iam delete-access-key ```","AdditionalInformation": ""}],"description": "Ensure access keys are rotated every 90 days or less","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.15": {"name": "1.15","checks": {"iam_policy_attached_only_to_group_or_roles": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html","Description": "IAM users are granted access to services, functions, and data through IAM policies. There are three ways to define policies for a user: 1) Edit the user policy directly, aka an inline, or user, policy; 2) attach a policy directly to a user; 3) add the user to an IAM group that has an attached policy. Only the third implementation is recommended.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if an inline policy is set or a policy is directly attached to users:1. Run the following to get a list of IAM users: ```aws iam list-users --query 'Users[*].UserName' --output text``` 2. For each user returned, run the following command to determine if any policies are attached to them: ```aws iam list-attached-user-policies --user-name aws iam list-user-policies --user-name ``` 3. If any policies are returned, the user has an inline policy or direct policy attachment.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Assigning IAM policy only through groups unifies permissions management to a single, flexible layer consistent with organizational functional roles. By unifying permissions management, the likelihood of excessive permissions is reduced.","RemediationProcedure": "Perform the following to create an IAM group and assign a policy to it:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click `Groups` and then click `Create New Group` . 3. In the `Group Name` box, type the name of the group and then click `Next Step` . 4. In the list of policies, select the check box for each policy that you want to apply to all members of the group. Then click `Next Step` . 5. Click `Create Group` Perform the following to add a user to a given group:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click `Groups`3. Select the group to add a user to 4. Click `Add Users To Group`5. Select the users to be added to the group 6. Click `Add Users` Perform the following to remove a direct association between a user and policy:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the left navigation pane, click on Users 3. For each user:- Select the user- Click on the `Permissions` tab- Expand `Permissions policies` - Click `X` for each policy; then click Detach or Remove (depending on policy type)","AdditionalInformation": ""}],"description": "Ensure IAM Users Receive Permissions Only Through Groups","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.16": {"name": "1.16","checks": {"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html:https://docs.aws.amazon.com/cli/latest/reference/iam/index.html#cli-aws-iam","Description": "IAM policies are the means by which privileges are granted to users, groups, or roles. It is recommended and considered a standard security advice to grant _least privilege_ -that is, granting only the permissions required to perform a task. Determine what users need to do and then craft policies for them that let the users perform _only_ those tasks, instead of allowing full administrative privileges.","DefaultValue": null,"AuditProcedure": "Perform the following to determine what policies are created:**From Command Line:**1. Run the following to get a list of IAM policies: ```aws iam list-policies --only-attached --output text ``` 2. For each policy returned, run the following command to determine if any policies is allowing full administrative privileges on the account: ```aws iam get-policy-version --policy-arn  --version-id  ``` 3. In output ensure policy should not have any Statement block with `\"Effect\": \"Allow\"` and `Action` set to `\"*\"` and `Resource` set to `\"*\"`","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "It's more secure to start with a minimum set of permissions and grant additional permissions as necessary, rather than starting with permissions that are too lenient and then trying to tighten them later.Providing full administrative privileges instead of restricting to the minimum set of permissions that the user is required to do exposes the resources to potentially unwanted actions.IAM policies that have a statement with \"Effect\": \"Allow\" with \"Action\": \"\\*\" over \"Resource\": \"\\*\" should be removed.","RemediationProcedure": "**From Console:**Perform the following to detach the policy that has full administrative privileges:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click Policies and then search for the policy name found in the audit step. 3. Select the policy that needs to be deleted. 4. In the policy action menu, select first `Detach`5. Select all Users, Groups, Roles that have this policy attached 6. Click `Detach Policy`7. In the policy action menu, select `Detach` **From Command Line:**Perform the following to detach the policy that has full administrative privileges as found in the audit step:1. Lists all IAM users, groups, and roles that the specified managed policy is attached to.```aws iam list-entities-for-policy --policy-arn  ``` 2. Detach the policy from all IAM Users: ```aws iam detach-user-policy --user-name  --policy-arn  ``` 3. Detach the policy from all IAM Groups: ```aws iam detach-group-policy --group-name  --policy-arn  ``` 4. Detach the policy from all IAM Roles: ```aws iam detach-role-policy --role-name  --policy-arn  ```","AdditionalInformation": ""}],"description": "Ensure IAM policies that allow full \"*:*\" administrative privileges are not attached","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1.17": {"name": "1.17","checks": {"iam_support_role_created": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html:https://aws.amazon.com/premiumsupport/pricing/:https://docs.aws.amazon.com/cli/latest/reference/iam/list-policies.html:https://docs.aws.amazon.com/cli/latest/reference/iam/attach-role-policy.html:https://docs.aws.amazon.com/cli/latest/reference/iam/list-entities-for-policy.html","Description": "AWS provides a support center that can be used for incident notification and response, as well as technical support and customer services. Create an IAM Role to allow authorized users to manage incidents with AWS Support.","DefaultValue": null,"AuditProcedure": "**From Command Line:**1. List IAM policies, filter for the 'AWSSupportAccess' managed policy, and note the \"Arn\" element value: ``` aws iam list-policies --query \"Policies[?PolicyName == 'AWSSupportAccess']\" ``` 2. Check if the 'AWSSupportAccess' policy is attached to any role:``` aws iam list-entities-for-policy --policy-arn arn:aws:iam::aws:policy/AWSSupportAccess ```3. In Output, Ensure `PolicyRoles` does not return empty. 'Example: Example: PolicyRoles: [ ]'If it returns empty refer to the remediation below.","ImpactStatement": "All AWS Support plans include an unlimited number of account and billing support cases, with no long-term contracts. Support billing calculations are performed on a per-account basis for all plans. Enterprise Support plan customers have the option to include multiple enabled accounts in an aggregated monthly billing calculation. Monthly charges for the Business and Enterprise support plans are based on each month's AWS usage charges, subject to a monthly minimum, billed in advance.","AssessmentStatus": "Automated","RationaleStatement": "By implementing least privilege for access control, an IAM Role will require an appropriate IAM Policy to allow Support Center Access in order to manage Incidents with AWS Support.","RemediationProcedure": "**From Command Line:**1. Create an IAM role for managing incidents with AWS:- Create a trust relationship policy document that allows  to manage AWS incidents, and save it locally as /tmp/TrustPolicy.json: ```{\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"\"},\"Action\": \"sts:AssumeRole\"}]} ``` 2. Create the IAM role using the above trust policy: ``` aws iam create-role --role-name  --assume-role-policy-document file:///tmp/TrustPolicy.json ``` 3. Attach 'AWSSupportAccess' managed policy to the created IAM role: ``` aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AWSSupportAccess --role-name  ```","AdditionalInformation": "AWSSupportAccess policy is a global AWS resource. It has same ARN as `arn:aws:iam::aws:policy/AWSSupportAccess` for every account."}],"description": "Ensure a support role has been created to manage incidents with AWS Support","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.18": {"name": "1.18","checks": {"ec2_instance_profile_attached": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html","Description": "AWS access from within AWS instances can be done by either encoding AWS keys into AWS API calls or by assigning the instance to a role which has an appropriate permissions policy for the required access. \"AWS Access\" means accessing the APIs of AWS in order to access AWS resources or manage AWS account resources.","DefaultValue": null,"AuditProcedure": "Where an instance is associated with a Role:For instances that are known to perform AWS actions, ensure that they belong to an instance role that has the necessary permissions:1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Open the EC2 Dashboard and choose \"Instances\" 3. Click the EC2 instance that performs AWS actions, in the lower pane details find \"IAM Role\" 4. If the Role is blank, the instance is not assigned to one. 5. If the Role is filled in, it does not mean the instance might not \\*also\\* have credentials encoded on it for some activities.Where an Instance Contains Embedded Credentials:- On the instance that is known to perform AWS actions, audit all scripts and environment variables to ensure that none of them contain AWS credentials.Where an Instance Application Contains Embedded Credentials:- Applications that run on an instance may also have credentials embedded. This is a bad practice, but even worse if the source code is stored in a public code repository such as github. When an application contains credentials can be determined by eliminating all other sources of credentials and if the application can still access AWS resources - it likely contains embedded credentials. Another method is to examine all source code and configuration files of the application.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "AWS IAM roles reduce the risks associated with sharing and rotating credentials that can be used outside of AWS itself. If credentials are compromised, they can be used from outside of the AWS account they give access to. In contrast, in order to leverage role permissions an attacker would need to gain and maintain access to a specific instance to use the privileges associated with it.Additionally, if credentials are encoded into compiled applications or other hard to change mechanisms, then they are even more unlikely to be properly rotated due to service disruption risks. As time goes on, credentials that cannot be rotated are more likely to be known by an increasing number of individuals who no longer work for the organization owning the credentials.","RemediationProcedure": "IAM roles can only be associated at the launch of an instance. To remediate an instance to add it to a role you must create a new instance.If the instance has no external dependencies on its current private ip or public addresses are elastic IPs:1. In AWS IAM create a new role. Assign a permissions policy if needed permissions are already known. 2. In the AWS console launch a new instance with identical settings to the existing instance, and ensure that the newly created role is selected. 3. Shutdown both the existing instance and the new instance. 4. Detach disks from both instances. 5. Attach the existing instance disks to the new instance. 6. Boot the new instance and you should have the same machine, but with the associated role.**Note:** if your environment has dependencies on a dynamically assigned PRIVATE IP address you can create an AMI from the existing instance, destroy the old one and then when launching from the AMI, manually assign the previous private IP address.**Note: **if your environment has dependencies on a dynamically assigned PUBLIC IP address there is not a way ensure the address is retained and assign an instance role. Dependencies on dynamically assigned public IP addresses are a bad practice and, if possible, you may wish to rebuild the instance with a new elastic IP address and make the investment to remediate affected systems while assigning the system to a role.","AdditionalInformation": ""}],"description": "Ensure IAM instance roles are used for AWS resource access from instances","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.19": {"name": "1.19","checks": {"iam_no_expired_server_certificates_stored": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_server-certs.html:https://docs.aws.amazon.com/cli/latest/reference/iam/delete-server-certificate.html","Description": "To enable HTTPS connections to your website or application in AWS, you need an SSL/TLS server certificate. You can use ACM or IAM to store and deploy server certificates.Use IAM as a certificate manager only when you must support HTTPS connections in a region that is not supported by ACM. IAM securely encrypts your private keys and stores the encrypted version in IAM SSL certificate storage. IAM supports deploying server certificates in all regions, but you must obtain your certificate from an external provider for use with AWS. You cannot upload an ACM certificate to IAM. Additionally, you cannot manage your certificates from the IAM Console.","DefaultValue": null,"AuditProcedure": "**From Console:**Getting the certificates expiration information via AWS Management Console is not currently supported.To request information about the SSL/TLS certificates stored in IAM via the AWS API use the Command Line Interface (CLI).**From Command Line:**Run list-server-certificates command to list all the IAM-stored server certificates:``` aws iam list-server-certificates ```The command output should return an array that contains all the SSL/TLS certificates currently stored in IAM and their metadata (name, ID, expiration date, etc):``` {\"ServerCertificateMetadataList\": [{\"ServerCertificateId\": \"EHDGFRW7EJFYTE88D\",\"ServerCertificateName\": \"MyServerCertificate\",\"Expiration\": \"2018-07-10T23:59:59Z\",\"Path\": \"/\",\"Arn\": \"arn:aws:iam::012345678910:server-certificate/MySSLCertificate\",\"UploadDate\": \"2018-06-10T11:56:08Z\"}] } ```Verify the `ServerCertificateName` and `Expiration` parameter value (expiration date) for each SSL/TLS certificate returned by the list-server-certificates command and determine if there are any expired server certificates currently stored in AWS IAM. If so, use the AWS API to remove them.If this command returns: ``` { { \"ServerCertificateMetadataList\": [] } ``` This means that there are no expired certificates, It DOES NOT mean that no certificates exist.","ImpactStatement": "Deleting the certificate could have implications for your application if you are using an expired server certificate with Elastic Load Balancing, CloudFront, etc. One has to make configurations at respective services to ensure there is no interruption in application functionality.","AssessmentStatus": "Automated","RationaleStatement": "Removing expired SSL/TLS certificates eliminates the risk that an invalid certificate will be deployed accidentally to a resource such as AWS Elastic Load Balancer (ELB), which can damage the credibility of the application/website behind the ELB. As a best practice, it is recommended to delete expired certificates.","RemediationProcedure": "**From Console:**Removing expired certificates via AWS Management Console is not currently supported. To delete SSL/TLS certificates stored in IAM via the AWS API use the Command Line Interface (CLI).**From Command Line:**To delete Expired Certificate run following command by replacing  with the name of the certificate to delete:``` aws iam delete-server-certificate --server-certificate-name  ```When the preceding command is successful, it does not return any output.","AdditionalInformation": ""}],"description": "Ensure that all the expired SSL/TLS certificates stored in AWS IAM are removed","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.20": {"name": "1.20","checks": {"accessanalyzer_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-getting-started.html:https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/get-analyzer.html:https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/create-analyzer.html","Description": "Enable IAM Access analyzer for IAM policies about all resources in each region.IAM Access Analyzer is a technology introduced at AWS reinvent 2019. After the Analyzer is enabled in IAM, scan results are displayed on the console showing the accessible resources. Scans show resources that other accounts and federated users can access, such as KMS keys and IAM roles. So the results allow you to determine if an unintended user is allowed, making it easier for administrators to monitor least privileges access. Access Analyzer analyzes only policies that are applied to resources in the same AWS Region.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Open the IAM console at `https://console.aws.amazon.com/iam/` 2. Choose `Access analyzer` 3. Click 'Analyzers' 4. Ensure that at least one analyzer is present 5. Ensure that the `STATUS` is set to `Active` 6. Repeat these step for each active region**From Command Line:**1. Run the following command: ``` aws accessanalyzer list-analyzers | grep status ``` 2. Ensure that at least one Analyzer the `status` is set to `ACTIVE`3. Repeat the steps above for each active region.If an Access analyzer is not listed for each region or the status is not set to active refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "AWS IAM Access Analyzer helps you identify the resources in your organization and accounts, such as Amazon S3 buckets or IAM roles, that are shared with an external entity. This lets you identify unintended access to your resources and data. Access Analyzer identifies resources that are shared with external principals by using logic-based reasoning to analyze the resource-based policies in your AWS environment. IAM Access Analyzer continuously monitors all policies for S3 bucket, IAM roles, KMS(Key Management Service) keys, AWS Lambda functions, and Amazon SQS(Simple Queue Service) queues.","RemediationProcedure": "**From Console:**Perform the following to enable IAM Access analyzer for IAM policies:1. Open the IAM console at `https://console.aws.amazon.com/iam/.` 2. Choose `Access analyzer`. 3. Choose `Create analyzer`. 4. On the `Create analyzer` page, confirm that the `Region` displayed is the Region where you want to enable Access Analyzer. 5. Enter a name for the analyzer. `Optional as it will generate a name for you automatically`. 6. Add any tags that you want to apply to the analyzer. `Optional`.7. Choose `Create Analyzer`. 8. Repeat these step for each active region**From Command Line:**Run the following command: ``` aws accessanalyzer create-analyzer --analyzer-name  --type  ``` Repeat this command above for each active region.**Note:** The IAM Access Analyzer is successfully configured only when the account you use has the necessary permissions.","AdditionalInformation": ""}],"description": "Ensure that IAM Access analyzer is enabled for all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.21": {"name": "1.21","checks": {"iam_check_saml_providers_sts": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "","Description": "In multi-account environments, IAM user centralization facilitates greater user control. User access beyond the initial account is then provided via role assumption. Centralization of users can be accomplished through federation with an external identity provider or through the use of AWS Organizations.","DefaultValue": null,"AuditProcedure": "For multi-account AWS environments with an external identity provider... 1. Determine the master account for identity federation or IAM user management 2. Login to that account through the AWS Management Console 3. Click `Services`4. Click `IAM`5. Click `Identity providers` 6. Verify the configurationThen..., determine all accounts that should not have local users present. For each account...1. Determine all accounts that should not have local users present 2. Log into the AWS Management Console 3. Switch role into each identified account 4. Click `Services`5. Click `IAM`6. Click `Users` 7. Confirm that no IAM users representing individuals are presentFor multi-account AWS environments implementing AWS Organizations without an external identity provider... 1. Determine all accounts that should not have local users present 2. Log into the AWS Management Console 3. Switch role into each identified account 4. Click `Services`5. Click `IAM`6. Click `Users` 7. Confirm that no IAM users representing individuals are present","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Centralizing IAM user management to a single identity store reduces complexity and thus the likelihood of access management errors.","RemediationProcedure": "The remediation procedure will vary based on the individual organization's implementation of identity federation and/or AWS Organizations with the acceptance criteria that no non-service IAM users, and non-root accounts, are present outside the account providing centralized IAM user management.","AdditionalInformation": ""}],"description": "Ensure IAM users are managed centrally via identity federation or AWS Organizations for multi-account environments","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.10": {"name": "3.10","checks": {"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-cloudtrail-events.html","Description": "S3 object-level API operations such as GetObject, DeleteObject, and PutObject are called data events. By default, CloudTrail trails don't log data events and so it is recommended to enable Object-level logging for S3 buckets.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to CloudTrail dashboard at `https://console.aws.amazon.com/cloudtrail/` 2. In the left panel, click `Trails` and then click on the CloudTrail Name that you want to examine. 3. Review `General details` 4. Confirm that `Multi-region trail` is set to `Yes` 5. Scroll down to `Data events` 6. Confirm that it reads: Data events: S3 Bucket Name: All current and future S3 buckets Read: Enabled Write: Enabled 7. Repeat steps 2 to 6 to verify that Multi-region trail and Data events logging of S3 buckets in CloudTrail. If the CloudTrails do not have multi-region and data events configured for S3 refer to the remediation below.**From Command Line:**1. Run `list-trails` command to list the names of all Amazon CloudTrail trails currently available in all AWS regions: ``` aws cloudtrail list-trails ``` 2. The command output will be a list of all the trail names to include. \"TrailARN\": \"arn:aws:cloudtrail:::trail/\", \"Name\": \"\", \"HomeRegion\": \"\" 3. Next run 'get-trail- command to determine Multi-region. ``` aws cloudtrail get-trail --name  --region  ``` 4. The command output should include: \"IsMultiRegionTrail\": true, 5. Next run `get-event-selectors` command using the `Name` of the trail and the `region` returned in step 2 to determine if Data events logging feature is enabled within the selected CloudTrail trail for all S3 buckets: ``` aws cloudtrail get-event-selectors --region  --trail-name  --query EventSelectors[*].DataResources[] ``` 6. The command output should be an array that contains the configuration of the AWS resource(S3 bucket) defined for the Data events selector. \"Type\": \"AWS::S3::Object\",\"Values\": [\"arn:aws:s3\" 7. If the `get-event-selectors` command returns an empty array '[]', the Data events are not included in the selected AWS Cloudtrail trail logging configuration, therefore the S3 object-level API operations performed within your AWS account are not recorded. 8. Repeat steps 1 to 5 for auditing each CloudTrail to determine if Data events for S3 are covered. If Multi-region is not set to true and the Data events does not show S3 defined as shown refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling object-level logging will help you meet data compliance requirements within your organization, perform comprehensive security analysis, monitor specific patterns of user behavior in your AWS account or take immediate actions on any object-level API activity within your S3 Buckets using Amazon CloudWatch Events.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. Click on the `Object-level` logging setting, enter the CloudTrail name for the recording activity. You can choose an existing Cloudtrail or create a new one by navigating to the Cloudtrail console link `https://console.aws.amazon.com/cloudtrail/` 5. Once the Cloudtrail is selected, check the `Write` event checkbox, so that `object-level` logging for Write events is enabled. 6. Repeat steps 2 to 5 to enable object-level logging of write events for other S3 buckets.**From Command Line:**1. To enable `object-level` data events logging for S3 buckets within your AWS account, run `put-event-selectors` command using the name of the trail that you want to reconfigure as identifier: ``` aws cloudtrail put-event-selectors --region  --trail-name  --event-selectors '[{ \"ReadWriteType\": \"WriteOnly\", \"IncludeManagementEvents\":true, \"DataResources\": [{ \"Type\": \"AWS::S3::Object\", \"Values\": [\"arn:aws:s3:::/\"] }] }]' ``` 2. The command output will be `object-level` event trail configuration. 3. If you want to enable it for all buckets at once then change Values parameter to `[\"arn:aws:s3\"]` in command given above. 4. Repeat step 1 for each s3 bucket to update `object-level` logging of write events. 5. Change the AWS region by updating the `--region` command parameter and perform the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that Object-level logging for write events is enabled for S3 bucket","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.11": {"name": "3.11","checks": {"cloudtrail_s3_dataevents_read_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-cloudtrail-events.html","Description": "S3 object-level API operations such as GetObject, DeleteObject, and PutObject are called data events. By default, CloudTrail trails don't log data events and so it is recommended to enable Object-level logging for S3 buckets.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. If the current status for `Object-level` logging is set to `Disabled`, then object-level logging of read events for the selected s3 bucket is not set. 5. If the current status for `Object-level` logging is set to `Enabled`, but the Read event check-box is unchecked, then object-level logging of read events for the selected s3 bucket is not set. 6. Repeat steps 2 to 5 to verify `object-level` logging for `read` events of your other S3 buckets.**From Command Line:** 1. Run `describe-trails` command to list the names of all Amazon CloudTrail trails currently available in the selected AWS region: ``` aws cloudtrail describe-trails --region  --output table --query trailList[*].Name ``` 2. The command output will be table of the requested trail names. 3. Run `get-event-selectors` command using the name of the trail returned at the previous step and custom query filters to determine if Data events logging feature is enabled within the selected CloudTrail trail configuration for s3 bucket resources: ``` aws cloudtrail get-event-selectors --region  --trail-name  --query EventSelectors[*].DataResources[] ``` 4. The command output should be an array that contains the configuration of the AWS resource(S3 bucket) defined for the Data events selector. 5. If the `get-event-selectors` command returns an empty array, the Data events are not included into the selected AWS Cloudtrail trail logging configuration, therefore the S3 object-level API operations performed within your AWS account are not recorded. 6. Repeat steps 1 to 5 for auditing each s3 bucket to identify other trails that are missing the capability to log Data events. 7. Change the AWS region by updating the `--region` command parameter and perform the audit process for other regions.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling object-level logging will help you meet data compliance requirements within your organization, perform comprehensive security analysis, monitor specific patterns of user behavior in your AWS account or take immediate actions on any object-level API activity using Amazon CloudWatch Events.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. Click on the `Object-level` logging setting, enter the CloudTrail name for the recording activity. You can choose an existing Cloudtrail or create a new one by navigating to the Cloudtrail console link `https://console.aws.amazon.com/cloudtrail/` 5. Once the Cloudtrail is selected, check the Read event checkbox, so that `object-level` logging for `Read` events is enabled. 6. Repeat steps 2 to 5 to enable `object-level` logging of read events for other S3 buckets.**From Command Line:** 1. To enable `object-level` data events logging for S3 buckets within your AWS account, run `put-event-selectors` command using the name of the trail that you want to reconfigure as identifier: ``` aws cloudtrail put-event-selectors --region  --trail-name  --event-selectors '[{ \"ReadWriteType\": \"ReadOnly\", \"IncludeManagementEvents\":true, \"DataResources\": [{ \"Type\": \"AWS::S3::Object\", \"Values\": [\"arn:aws:s3:::/\"] }] }]' ``` 2. The command output will be `object-level` event trail configuration. 3. If you want to enable it for all buckets at ones then change Values parameter to `[\"arn:aws:s3\"]` in command given above. 4. Repeat step 1 for each s3 bucket to update `object-level` logging of read events. 5. Change the AWS region by updating the `--region` command parameter and perform the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that Object-level logging for read events is enabled for S3 bucket","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.10": {"name": "4.10","checks": {"cloudwatch_log_metric_filter_security_group_changes": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Security Groups are a stateful packet filter that controls ingress and egress traffic within a VPC. It is recommended that a metric filter and alarm be established for detecting changes to Security Groups.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query \"MetricAlarms[?MetricName== '']\" ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to security group will help ensure that resources and services are not unintentionally exposed.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for security groups changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name \"\" --filter-name \"\" --metric-transformations metricName= \"\" ,metricNamespace=\"CISBenchmark\",metricValue=1 --filter-pattern \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\" ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name \"\" ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn \"\" --protocol  --notification-endpoint \"\" ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name \"\" --metric-name \"\" --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace \"CISBenchmark\" --alarm-actions \"\" ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for security group changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.11": {"name": "4.11","checks": {"cloudwatch_changes_to_network_acls_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. NACLs are used as a stateless packet filter to control ingress and egress traffic for subnets within a VPC. It is recommended that a metric filter and alarm be established for changes made to NACLs.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to NACLs will help ensure that AWS resources and services are not unintentionally exposed.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for NACL changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL)","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.12": {"name": "4.12","checks": {"cloudwatch_changes_to_network_gateways_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Network gateways are required to send/receive traffic to a destination outside of a VPC. It is recommended that a metric filter and alarm be established for changes to network gateways.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to network gateways will help ensure that all ingress/egress traffic traverses the VPC border via a controlled path.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for network gateways changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for changes to network gateways","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.13": {"name": "4.13","checks": {"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Routing tables are used to route network traffic between subnets and to network gateways. It is recommended that a metric filter and alarm be established for changes to route tables.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to route tables will help ensure that all VPC traffic flows through an expected path.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for route table changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for route table changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.14": {"name": "4.14","checks": {"cloudwatch_changes_to_vpcs_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is possible to have more than 1 VPC within an account, in addition it is also possible to create a peer connection between 2 VPCs enabling network traffic to route between VPCs. It is recommended that a metric filter and alarm be established for changes made to VPCs.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to VPC will help ensure VPC traffic flow is not getting impacted.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for VPC changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for VPC changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.15": {"name": "4.15","checks": {"cloudwatch_log_metric_filter_aws_organizations_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/organizations/latest/userguide/orgs_security_incident-response.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for AWS Organizations changes made in the master AWS Account.","DefaultValue": null,"AuditProcedure": "1. Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured: - Identify the log group name configured for use with active multi-region CloudTrail: - List all CloudTrails:``` aws cloudtrail describe-trails ``` - Identify Multi region Cloudtrails, Trails with `\"IsMultiRegionTrail\"` set to true - From value associated with CloudWatchLogsLogGroupArn note **Example:** for CloudWatchLogsLogGroupArn that looks like arn:aws:logs:::log-group:NewGroup:*,  would be NewGroup- Ensure Identified Multi region CloudTrail is active: ``` aws cloudtrail get-trail-status --name  ``` Ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events: ``` aws cloudtrail get-event-selectors --trail-name  ``` - Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to true and `ReadWriteType` set to `All`.2. Get a list of all associated metric filters for this : ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdatePolicy\") || ($.eventName = \"UpdateOrganizationalUnit\")) }\" ``` 4. Note the `` value associated with the filterPattern found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4: ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the AlarmActions value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic: ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. Example of valid \"SubscriptionArn\":``` \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring AWS Organizations changes can help you prevent any unwanted, accidental or intentional modifications that may lead to unauthorized access or other security breaches. This monitoring technique helps you to ensure that any unexpected changes performed within your AWS Organizations can be investigated and any unwanted changes can be rolled back.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Organizations changes and the `` taken from audit step 1: ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdatePolicy\") || ($.eventName = \"UpdateOrganizationalUnit\")) }' ``` **Note:** You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify: ``` aws sns create-topic --name  ``` **Note:** you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2: ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note:** you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2: ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": ""}],"description": "Ensure a log metric filter and alarm exists for AWS Organizations changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.16": {"name": "4.16","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-get-started.html:https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-enable.html#securityhub-enable-api:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/securityhub/enable-security-hub.html","Description": "Security Hub collects security data from across AWS accounts, services, and supported third-party partner products and helps you analyze your security trends and identify the highest priority security issues. When you enable Security Hub, it begins to consume, aggregate, organize, and prioritize findings from AWS services that you have enabled, such as Amazon GuardDuty, Amazon Inspector, and Amazon Macie. You can also enable integrations with AWS partner security products.","DefaultValue": null,"AuditProcedure": "The process to evaluate AWS Security Hub configuration per region **From Console:**1. Sign in to the AWS Management Console and open the AWS Security Hub console at https://console.aws.amazon.com/securityhub/. 2. On the top right of the console, select the target Region. 3. If presented with the Security Hub > Summary page then Security Hub is set-up for the selected region. 4. If presented with Setup Security Hub or Get Started With Security Hub - follow the online instructions. 5. Repeat steps 2 to 4 for each region.","ImpactStatement": "It is recommended AWS Security Hub be enabled in all regions. AWS Security Hub requires AWS Config to be enabled.","AssessmentStatus": "Automated","RationaleStatement": "AWS Security Hub provides you with a comprehensive view of your security state in AWS and helps you check your environment against security industry standards and best practices - enabling you to quickly assess the security posture across your AWS accounts.","RemediationProcedure": "To grant the permissions required to enable Security Hub, attach the Security Hub managed policy AWSSecurityHubFullAccess to an IAM user, group, or role.Enabling Security Hub**From Console:**1. Use the credentials of the IAM identity to sign in to the Security Hub console. 2. When you open the Security Hub console for the first time, choose Enable AWS Security Hub. 3. On the welcome page, Security standards list the security standards that Security Hub supports. 4. Choose Enable Security Hub.**From Command Line:**1. Run the enable-security-hub command. To enable the default standards, include `--enable-default-standards`. ``` aws securityhub enable-security-hub --enable-default-standards ```2. To enable the security hub without the default standards, include `--no-enable-default-standards`. ``` aws securityhub enable-security-hub --no-enable-default-standards ```","AdditionalInformation": ""}],"description": "Ensure AWS Security Hub is enabled","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.1": {"name": "2.1.1","checks": {"s3_bucket_default_encryption": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/default-bucket-encryption.html:https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html#bucket-encryption-related-resources","Description": "Amazon S3 provides a variety of no, or low, cost encryption options to protect data at rest.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select a Bucket. 3. Click on 'Properties'. 4. Verify that `Default Encryption` is enabled, and displays either `AES-256`, `AWS-KMS`, `SSE-KMS` or `SSE-S3`. 5. Repeat for all the buckets in your AWS account.**From Command Line:**1. Run command to list buckets ``` aws s3 ls ``` 2. For each bucket, run``` aws s3api get-bucket-encryption --bucket  ``` 3. Verify that either``` \"SSEAlgorithm\": \"AES256\" ```or``` \"SSEAlgorithm\": \"aws:kms\"```is displayed.","ImpactStatement": "Amazon S3 buckets with default bucket encryption using SSE-KMS cannot be used as destination buckets for Amazon S3 server access logging. Only SSE-S3 default encryption is supported for server access log destination buckets.","AssessmentStatus": "Automated","RationaleStatement": "Encrypting data at rest reduces the likelihood that it is unintentionally exposed and can nullify the impact of disclosure if the encryption remains unbroken.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select a Bucket. 3. Click on 'Properties'. 4. Click edit on `Default Encryption`. 5. Select either `AES-256`, `AWS-KMS`, `SSE-KMS` or `SSE-S3`. 6. Click `Save` 7. Repeat for all the buckets in your AWS account lacking encryption.**From Command Line:**Run either``` aws s3api put-bucket-encryption --bucket  --server-side-encryption-configuration '{\"Rules\": [{\"ApplyServerSideEncryptionByDefault\": {\"SSEAlgorithm\": \"AES256\"}}]}' ```or``` aws s3api put-bucket-encryption --bucket  --server-side-encryption-configuration '{\"Rules\": [{\"ApplyServerSideEncryptionByDefault\": {\"SSEAlgorithm\": \"aws:kms\",\"KMSMasterKeyID\": \"aws/s3\"}}]}' ```**Note:** the KMSMasterKeyID can be set to the master key of your choosing; aws/s3 is an AWS preconfigured default.","AdditionalInformation": "S3 bucket encryption only applies to objects as they are placed in the bucket. Enabling S3 bucket encryption does **not** encrypt objects previously stored within the bucket."}],"description": "Ensure all S3 buckets employ encryption-at-rest","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.2": {"name": "2.1.2","checks": {"s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-policy-for-config-rule/:https://aws.amazon.com/blogs/security/how-to-use-bucket-policies-and-apply-defense-in-depth-to-help-secure-your-amazon-s3-data/:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-bucket-policy.html","Description": "At the Amazon S3 bucket level, you can configure permissions through a bucket policy making the objects accessible only through HTTPS.","DefaultValue": null,"AuditProcedure": "To allow access to HTTPS you can use a condition that checks for the key `\"aws:SecureTransport: true\"`. This means that the request is sent through HTTPS but that HTTP can still be used. So to make sure you do not allow HTTP access confirm that there is a bucket policy that explicitly denies access for HTTP requests and that it contains the key \"aws:SecureTransport\": \"false\".**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/ 2. Select the Check box next to the Bucket. 3. Click on 'Permissions', then Click on `Bucket Policy`. 4. Ensure that a policy is listed that matches: ``` '{\"Sid\": ,\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}' ``` `` and `` will be specific to your account5. Repeat for all the buckets in your AWS account.**From Command Line:**1. List all of the S3 Buckets``` aws s3 ls ``` 2. Using the list of buckets run this command on each of them: ``` aws s3api get-bucket-policy --bucket  | grep aws:SecureTransport ``` 3. Confirm that `aws:SecureTransport` is set to false `aws:SecureTransport:false` 4. Confirm that the policy line has Effect set to Deny 'Effect:Deny'","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "By default, Amazon S3 allows both HTTP and HTTPS requests. To achieve only allowing access to Amazon S3 objects through HTTPS you also have to explicitly deny access to HTTP requests. Bucket policies that allow HTTPS requests without explicitly denying HTTP requests will not comply with this recommendation.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/ 2. Select the Check box next to the Bucket. 3. Click on 'Permissions'. 4. Click 'Bucket Policy' 5. Add this to the existing policy filling in the required information ``` {\"Sid\": \",\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}}} ``` 6. Save 7. Repeat for all the buckets in your AWS account that contain sensitive data.**From Console** using AWS Policy Generator:1. Repeat steps 1-4 above. 2. Click on `Policy Generator` at the bottom of the Bucket Policy Editor 3. Select Policy Type `S3 Bucket Policy` 4. Add Statements - `Effect` = Deny - `Principal` = * - `AWS Service` = Amazon S3 - `Actions` = * - `Amazon Resource Name` =  5. Generate Policy 6. Copy the text and add it to the Bucket Policy.**From Command Line:**1. Export the bucket policy to a json file. ``` aws s3api get-bucket-policy --bucket  --query Policy --output text > policy.json ```2. Modify the policy.json file by adding in this statement: ``` {\"Sid\": \",\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}}} ``` 3. Apply this modified policy back to the S3 bucket: ``` aws s3api put-bucket-policy --bucket  --policy file://policy.json ```","AdditionalInformation": ""}],"description": "Ensure S3 Bucket Policy is set to deny HTTP requests","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.1.3": {"name": "2.1.3","checks": {"s3_bucket_no_mfa_delete": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html#MultiFactorAuthenticationDelete:https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMFADelete.html:https://aws.amazon.com/blogs/security/securing-access-to-aws-using-mfa-part-3/:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_lost-or-broken.html","Description": "Once MFA Delete is enabled on your sensitive and classified S3 bucket it requires the user to have two forms of authentication.","DefaultValue": null,"AuditProcedure": "Perform the steps below to confirm MFA delete is configured on an S3 Bucket**From Console:**1. Login to the S3 console at `https://console.aws.amazon.com/s3/`2. Click the `Check` box next to the Bucket name you want to confirm3. In the window under `Properties`4. Confirm that Versioning is `Enabled`5. Confirm that MFA Delete is `Enabled`**From Command Line:**1. Run the `get-bucket-versioning` ``` aws s3api get-bucket-versioning --bucket my-bucket ```Output example: ```  EnabledEnabled ```If the Console or the CLI output does not show Versioning and MFA Delete `enabled` refer to the remediation below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Adding MFA delete to an S3 bucket, requires additional authentication when you change the version state of your bucket or you delete and object version adding another layer of security in the event your security credentials are compromised or unauthorized access is granted.","RemediationProcedure": "Perform the steps below to enable MFA delete on an S3 bucket.Note: -You cannot enable MFA Delete using the AWS Management Console. You must use the AWS CLI or API. -You must use your 'root' account to enable MFA Delete on S3 buckets.**From Command line:**1. Run the s3api put-bucket-versioning command``` aws s3api put-bucket-versioning --profile my-root-profile --bucket Bucket_Name --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa ā€œarn:aws:iam::aws_account_id:mfa/root-account-mfa-device passcodeā€ ```","AdditionalInformation": ""}],"description": "Ensure MFA Delete is enabled on S3 buckets","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.1.4": {"name": "2.1.4","checks": {"macie_is_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://aws.amazon.com/macie/getting-started/:https://docs.aws.amazon.com/workspaces/latest/adminguide/data-protection.html:https://docs.aws.amazon.com/macie/latest/user/data-classification.html","Description": "Amazon S3 buckets can contain sensitive data, that for security purposes should be discovered, monitored, classified and protected. Macie along with other 3rd party tools can automatically provide an inventory of Amazon S3 buckets.","DefaultValue": null,"AuditProcedure": "Perform the following steps to determine if Macie is running:**From Console:** 1. Login to the Macie console at https://console.aws.amazon.com/macie/ 2. In the left hand pane click on By job under findings. 3. Confirm that you have a Job setup for your S3 BucketsWhen you log into the Macie console if you aren't taken to the summary page and you don't have a job setup and running then refer to the remediation procedure below.If you are using a 3rd Party tool to manage and protect your s3 data you meet this recommendation.","ImpactStatement": "There is a cost associated with using Amazon Macie. There is also typically a cost associated with 3rd Party tools that perform similar processes and protection.","AssessmentStatus": "Manual","RationaleStatement": "Using a Cloud service or 3rd Party software to continuously monitor and automate the process of data discovery and classification for S3 buckets using machine learning and pattern matching is a strong defense in protecting that information.Amazon Macie is a fully managed data security and data privacy service that uses machine learning and pattern matching to discover and protect your sensitive data in AWS.","RemediationProcedure": "Perform the steps below to enable and configure Amazon Macie**From Console:**1. Log on to the Macie console at `https://console.aws.amazon.com/macie/`2. Click `Get started`.3. Click `Enable Macie`.Setup a repository for sensitive data discovery results1. In the Left pane, under Settings, click `Discovery results`.2. Make sure `Create bucket` is selected.3. Create a bucket, enter a name for the bucket. The name must be unique across all S3 buckets. In addition, the name must start with a lowercase letter or a number.4. Click on `Advanced`.5. Block all public access, make sure `Yes` is selected.6. KMS encryption, specify the AWS KMS key that you want to use to encrypt the results. The key must be a symmetric, customer master key (CMK) that's in the same Region as the S3 bucket.7. Click on `Save`Create a job to discover sensitive data1. In the left pane, click `S3 buckets`. Macie displays a list of all the S3 buckets for your account.2. Select the `check box` for each bucket that you want Macie to analyze as part of the job3. Click `Create job`.3. Click `Quick create`.4. For the Name and description step, enter a name and, optionally, a description of the job.5. Then click `Next`.6. For the Review and create step, click `Submit`.Review your findings1. In the left pane, click `Findings`.2. To view the details of a specific finding, choose any field other than the check box for the finding.If you are using a 3rd Party tool to manage and protect your s3 data, follow the Vendor documentation for implementing and configuring that tool.","AdditionalInformation": ""}],"description": "Ensure all data in Amazon S3 has been discovered, classified and secured when required.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.5": {"name": "2.1.5","checks": {"s3_bucket_level_public_access_block": "PASS","s3_account_level_public_access_blocks": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/block-public-access-account.html","Description": "Amazon S3 provides `Block public access (bucket settings)` and `Block public access (account settings)` to help you manage public access to Amazon S3 resources. By default, S3 buckets and objects are created with public access disabled. However, an IAM principal with sufficient S3 permissions can enable public access at the bucket and/or object level. While enabled, `Block public access (bucket settings)` prevents an individual bucket, and its contained objects, from becoming publicly accessible. Similarly, `Block public access (account settings)` prevents all buckets, and contained objects, from becoming publicly accessible across the entire account.","DefaultValue": null,"AuditProcedure": "**If utilizing Block Public Access (bucket settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select the Check box next to the Bucket. 3. Click on 'Edit public access settings'. 4. Ensure that block public access settings are set appropriately for this bucket 5. Repeat for all the buckets in your AWS account.**From Command Line:**1. List all of the S3 Buckets ``` aws s3 ls ``` 2. Find the public access setting on that bucket ``` aws s3api get-public-access-block --bucket  ``` Output if Block Public access is enabled:``` {\"PublicAccessBlockConfiguration\": {\"BlockPublicAcls\": true,\"IgnorePublicAcls\": true,\"BlockPublicPolicy\": true,\"RestrictPublicBuckets\": true} } ```If the output reads `false` for the separate configuration settings then proceed to the remediation.**If utilizing Block Public Access (account settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Choose `Block public access (account settings)` 3. Ensure that block public access settings are set appropriately for your AWS account.**From Command Line:**To check Public access settings for this account status, run the following command, `aws s3control get-public-access-block --account-id  --region `Output if Block Public access is enabled:``` {\"PublicAccessBlockConfiguration\": {\"IgnorePublicAcls\": true, \"BlockPublicPolicy\": true, \"BlockPublicAcls\": true, \"RestrictPublicBuckets\": true} } ```If the output reads `false` for the separate configuration settings then proceed to the remediation.","ImpactStatement": "When you apply Block Public Access settings to an account, the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously, but they eventually propagate to all Regions.","AssessmentStatus": "Automated","RationaleStatement": "Amazon S3 `Block public access (bucket settings)` prevents the accidental or malicious public exposure of data contained within the respective bucket(s). Amazon S3 `Block public access (account settings)` prevents the accidental or malicious public exposure of data contained within all buckets of the respective AWS account.Whether blocking public access to all or some buckets is an organizational decision that should be based on data sensitivity, least privilege, and use case.","RemediationProcedure": "**If utilizing Block Public Access (bucket settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select the Check box next to the Bucket. 3. Click on 'Edit public access settings'. 4. Click 'Block all public access' 5. Repeat for all the buckets in your AWS account that contain sensitive data.**From Command Line:**1. List all of the S3 Buckets ``` aws s3 ls ``` 2. Set the Block Public Access to true on that bucket ``` aws s3api put-public-access-block --bucket  --public-access-block-configuration \"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true\" ```**If utilizing Block Public Access (account settings)****From Console:**If the output reads `true` for the separate configuration settings then it is set on the account.1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Choose `Block Public Access (account settings)` 3. Choose `Edit` to change the block public access settings for all the buckets in your AWS account 4. Choose the settings you want to change, and then choose `Save`. For details about each setting, pause on the `i` icons. 5. When you're asked for confirmation, enter `confirm`. Then Click `Confirm` to save your changes.**From Command Line:**To set Block Public access settings for this account, run the following command: ``` aws s3control put-public-access-block --public-access-block-configuration BlockPublicAcls=true, IgnorePublicAcls=true, BlockPublicPolicy=true, RestrictPublicBuckets=true --account-id  ```","AdditionalInformation": ""}],"description": "Ensure that S3 Buckets are configured with 'Block public access (bucket settings)'","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"2.2.1": {"name": "2.2.1","checks": {"ec2_ebs_volume_encryption": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.2. Elastic Compute Cloud (EC2)","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html:https://aws.amazon.com/blogs/aws/new-opt-in-to-default-encryption-for-new-ebs-volumes/","Description": "Elastic Compute Cloud (EC2) supports encryption at rest when using the Elastic Block Store (EBS) service. While disabled by default, forcing encryption at EBS volume creation is supported.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under `Account attributes`, click `EBS encryption`. 3. Verify `Always encrypt new EBS volumes` displays `Enabled`. 4. Review every region in-use.**Note:** EBS volume encryption is configured per region.**From Command Line:**1. Run``` aws --region  ec2 get-ebs-encryption-by-default ``` 2. Verify that `\"EbsEncryptionByDefault\": true` is displayed. 3. Review every region in-use.**Note:** EBS volume encryption is configured per region.","ImpactStatement": "Losing access or removing the KMS key in use by the EBS volumes will result in no longer being able to access the volumes.","AssessmentStatus": "Automated","RationaleStatement": "Encrypting data at rest reduces the likelihood that it is unintentionally exposed and can nullify the impact of disclosure if the encryption remains unbroken.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under `Account attributes`, click `EBS encryption`. 3. Click `Manage`. 4. Click the `Enable` checkbox. 5. Click `Update EBS encryption` 6. Repeat for every region requiring the change.**Note:** EBS volume encryption is configured per region.**From Command Line:**1. Run``` aws --region  ec2 enable-ebs-encryption-by-default ``` 2. Verify that `\"EbsEncryptionByDefault\": true` is displayed. 3. Repeat every region requiring the change.**Note:** EBS volume encryption is configured per region.","AdditionalInformation": "Default EBS volume encryption only applies to newly created EBS volumes. Existing EBS volumes are **not** converted automatically."}],"description": "Ensure EBS Volume Encryption is Enabled in all Regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.3.1": {"name": "2.3.1","checks": {"rds_instance_storage_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Encryption.html:https://aws.amazon.com/blogs/database/selecting-the-right-encryption-options-for-amazon-rds-and-amazon-aurora-database-engines/#:~:text=With%20RDS%2Dencrypted%20resources%2C%20data,transparent%20to%20your%20database%20engine.:https://aws.amazon.com/rds/features/security/","Description": "Amazon RDS encrypted DB instances use the industry standard AES-256 encryption algorithm to encrypt your data on the server that hosts your Amazon RDS DB instances. After your data is encrypted, Amazon RDS handles authentication of access and decryption of your data transparently with a minimal impact on performance.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and open the RDS dashboard at https://console.aws.amazon.com/rds/ 2. In the navigation pane, under RDS dashboard, click `Databases`. 3. Select the RDS Instance that you want to examine 4. Click `Instance Name` to see details, then click on `Configuration` tab. 5. Under Configuration Details section, In Storage pane search for the `Encryption Enabled` Status. 6. If the current status is set to `Disabled`, Encryption is not enabled for the selected RDS Instance database instance. 7. Repeat steps 3 to 7 to verify encryption status of other RDS Instance in same region. 8. Change region from the top of the navigation bar and repeat audit for other regions.**From Command Line:**1. Run `describe-db-instances` command to list all RDS Instance database names, available in the selected AWS region, Output will return each Instance database identifier-name.``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. Run again `describe-db-instances` command using the RDS Instance identifier returned earlier, to determine if the selected database instance is encrypted, The command output should return the encryption status `True` Or `False`. ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].StorageEncrypted' ``` 3. If the StorageEncrypted parameter value is `False`, Encryption is not enabled for the selected RDS database instance. 4. Repeat steps 1 to 3 for auditing each RDS Instance and change Region to verify for other regions","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Databases are likely to hold sensitive and critical data, it is highly recommended to implement encryption in order to protect your data from unauthorized access or disclosure. With RDS encryption enabled, the data stored on the instance's underlying storage, the automated backups, read replicas, and snapshots, are all encrypted.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and open the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases` 3. Select the Database instance that needs to be encrypted. 4. Click on `Actions` button placed at the top right and select `Take Snapshot`. 5. On the Take Snapshot page, enter a database name of which you want to take a snapshot in the `Snapshot Name` field and click on `Take Snapshot`. 6. Select the newly created snapshot and click on the `Action` button placed at the top right and select `Copy snapshot` from the Action menu. 7. On the Make Copy of DB Snapshot page, perform the following:- In the New DB Snapshot Identifier field, Enter a name for the `new snapshot`. - Check `Copy Tags`, New snapshot must have the same tags as the source snapshot. - Select `Yes` from the `Enable Encryption` dropdown list to enable encryption, You can choose to use the AWS default encryption key or custom key from Master Key dropdown list.8. Click `Copy Snapshot` to create an encrypted copy of the selected instance snapshot. 9. Select the new Snapshot Encrypted Copy and click on the `Action` button placed at the top right and select `Restore Snapshot` button from the Action menu, This will restore the encrypted snapshot to a new database instance. 10. On the Restore DB Instance page, enter a unique name for the new database instance in the DB Instance Identifier field. 11. Review the instance configuration details and click `Restore DB Instance`. 12. As the new instance provisioning process is completed can update application configuration to refer to the endpoint of the new Encrypted database instance Once the database endpoint is changed at the application level, can remove the unencrypted instance.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names available in the selected AWS region, The command output should return the database instance identifier. ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. Run `create-db-snapshot` command to create a snapshot for the selected database instance, The command output will return the `new snapshot` with name DB Snapshot Name. ``` aws rds create-db-snapshot --region  --db-snapshot-identifier  --db-instance-identifier  ``` 3. Now run `list-aliases` command to list the KMS keys aliases available in a specified region, The command output should return each `key alias currently available`. For our RDS encryption activation process, locate the ID of the AWS default KMS key. ``` aws kms list-aliases --region  ``` 4. Run `copy-db-snapshot` command using the default KMS key ID for RDS instances returned earlier to create an encrypted copy of the database instance snapshot, The command output will return the `encrypted instance snapshot configuration`. ``` aws rds copy-db-snapshot --region  --source-db-snapshot-identifier  --target-db-snapshot-identifier  --copy-tags --kms-key-id  ``` 5. Run `restore-db-instance-from-db-snapshot` command to restore the encrypted snapshot created at the previous step to a new database instance, If successful, the command output should return the new encrypted database instance configuration. ``` aws rds restore-db-instance-from-db-snapshot --region  --db-instance-identifier  --db-snapshot-identifier  ``` 6. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region, Output will return database instance identifier name Select encrypted database name that we just created DB-Name-Encrypted. ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 7. Run again `describe-db-instances` command using the RDS instance identifier returned earlier, to determine if the selected database instance is encrypted, The command output should return the encryption status `True`. ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].StorageEncrypted' ```","AdditionalInformation": ""}],"description": "Ensure that encryption is enabled for RDS Instances","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.3.2": {"name": "2.3.2","checks": {"rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_RDS_Managing.html:https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.Upgrading.html:https://aws.amazon.com/rds/faqs/","Description": "Ensure that RDS database instances have the Auto Minor Version Upgrade flag enabled in order to receive automatically minor engine upgrades during the specified maintenance window. So, RDS instances can get the new features, bug fixes, and security patches for their database engines.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases`. 3. Select the RDS instance that wants to examine. 4. Click on the `Maintenance and backups` panel. 5. Under the `Maintenance` section, search for the Auto Minor Version Upgrade status. - If the current status is set to `Disabled`, means the feature is not set and the minor engine upgrades released will not be applied to the selected RDS instance**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance identifier. 3. Run again `describe-db-instances` command using the RDS instance identifier returned earlier to determine the Auto Minor Version Upgrade status for the selected instance: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].AutoMinorVersionUpgrade' ``` 4. The command output should return the feature current status. If the current status is set to `true`, the feature is enabled and the minor engine upgrades will be applied to the selected RDS instance.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "AWS RDS will occasionally deprecate minor engine versions and provide new ones for an upgrade. When the last version number within the release is replaced, the version changed is considered minor. With Auto Minor Version Upgrade feature enabled, the version upgrades will occur automatically during the specified maintenance window so your RDS instances can get the new features, bug fixes, and security patches for their database engines.","RemediationProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases`. 3. Select the RDS instance that wants to update. 4. Click on the `Modify` button placed on the top right side. 5. On the `Modify DB Instance: ` page, In the `Maintenance` section, select `Auto minor version upgrade` click on the `Yes` radio button. 6. At the bottom of the page click on `Continue`, check to Apply Immediately to apply the changes immediately, or select `Apply during the next scheduled maintenance window` to avoid any downtime. 7. Review the changes and click on `Modify DB Instance`. The instance status should change from available to modifying and back to available. Once the feature is enabled, the `Auto Minor Version Upgrade` status should change to `Yes`.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database instance names, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance identifier. 3. Run the `modify-db-instance` command to modify the selected RDS instance configuration this command will apply the changes immediately, Remove `--apply-immediately` to apply changes during the next scheduled maintenance window and avoid any downtime: ``` aws rds modify-db-instance --region  --db-instance-identifier  --auto-minor-version-upgrade --apply-immediately ``` 4. The command output should reveal the new configuration metadata for the RDS instance and check `AutoMinorVersionUpgrade` parameter value. 5. Run `describe-db-instances` command to check if the Auto Minor Version Upgrade feature has been successfully enable: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].AutoMinorVersionUpgrade' ``` 6. The command output should return the feature current status set to `true`, the feature is `enabled` and the minor engine upgrades will be applied to the selected RDS instance.","AdditionalInformation": ""}],"description": "Ensure Auto Minor Version Upgrade feature is Enabled for RDS Instances","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.3.3": {"name": "2.3.3","checks": {"rds_instance_no_public_access": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.html:https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario2.html:https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html:https://aws.amazon.com/rds/faqs/","Description": "Ensure and verify that RDS database instances provisioned in your AWS account do restrict unauthorized access in order to minimize security risks. To restrict access to any publicly accessible RDS database instance, you must disable the database Publicly Accessible flag and update the VPC security group associated with the instance.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. Under the navigation panel, On RDS Dashboard, click `Databases`. 3. Select the RDS instance that you want to examine. 4. Click `Instance Name` from the dashboard, Under `Connectivity and Security. 5. On the `Security`, check if the Publicly Accessible flag status is set to `Yes`, follow the below-mentioned steps to check database subnet access. - In the `networking` section, click the subnet link available under `Subnets` - The link will redirect you to the VPC Subnets page. - Select the subnet listed on the page and click the `Route Table` tab from the dashboard bottom panel. If the route table contains any entries with the destination `CIDR block set to 0.0.0.0/0` and with an `Internet Gateway` attached. - The selected RDS database instance was provisioned inside a public subnet, therefore is not running within a logically isolated environment and can be accessible from the Internet. 6. Repeat steps no. 4 and 5 to determine the type (public or private) and subnet for other RDS database instances provisioned in the current region. 8. Change the AWS region from the navigation bar and repeat the audit process for other regions.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance `identifier`. 3. Run again `describe-db-instances` command using the `PubliclyAccessible` parameter as query filter to reveal the database instance Publicly Accessible flag status: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].PubliclyAccessible' ``` 4. Check for the Publicly Accessible parameter status, If the Publicly Accessible flag is set to `Yes`. Then selected RDS database instance is publicly accessible and insecure, follow the below-mentioned steps to check database subnet access 5. Run again `describe-db-instances` command using the RDS database instance identifier that you want to check and appropriate filtering to describe the VPC subnet(s) associated with the selected instance: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].DBSubnetGroup.Subnets[]' ``` - The command output should list the subnets available in the selected database subnet group. 6. Run `describe-route-tables` command using the ID of the subnet returned at the previous step to describe the routes of the VPC route table associated with the selected subnet: ``` aws ec2 describe-route-tables --region  --filters \"Name=association.subnet-id,Values=\" --query 'RouteTables[*].Routes[]' ``` - If the command returns the route table associated with database instance subnet ID. Check the `GatewayId` and `DestinationCidrBlock` attributes values returned in the output. If the route table contains any entries with the `GatewayId` value set to `igw-xxxxxxxx` and the `DestinationCidrBlock` value set to `0.0.0.0/0`, the selected RDS database instance was provisioned inside a public subnet. - Or - If the command returns empty results, the route table is implicitly associated with subnet, therefore the audit process continues with the next step 7. Run again `describe-db-instances` command using the RDS database instance identifier that you want to check and appropriate filtering to describe the VPC ID associated with the selected instance: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].DBSubnetGroup.VpcId' ``` - The command output should show the VPC ID in the selected database subnet group 8. Now run `describe-route-tables` command using the ID of the VPC returned at the previous step to describe the routes of the VPC main route table implicitly associated with the selected subnet: ``` aws ec2 describe-route-tables --region  --filters \"Name=vpc-id,Values=\" \"Name=association.main,Values=true\" --query 'RouteTables[*].Routes[]' ``` - The command output returns the VPC main route table implicitly associated with database instance subnet ID. Check the `GatewayId` and `DestinationCidrBlock` attributes values returned in the output. If the route table contains any entries with the `GatewayId` value set to `igw-xxxxxxxx` and the `DestinationCidrBlock` value set to `0.0.0.0/0`, the selected RDS database instance was provisioned inside a public subnet, therefore is not running within a logically isolated environment and does not adhere to AWS security best practices.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Ensure that no public-facing RDS database instances are provisioned in your AWS account and restrict unauthorized access in order to minimize security risks. When the RDS instance allows unrestricted access (0.0.0.0/0), everyone and everything on the Internet can establish a connection to your database and this can increase the opportunity for malicious activities such as brute force attacks, PostgreSQL injections, or DoS/DDoS attacks.","RemediationProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. Under the navigation panel, On RDS Dashboard, click `Databases`. 3. Select the RDS instance that you want to update. 4. Click `Modify` from the dashboard top menu. 5. On the Modify DB Instance panel, under the `Connectivity` section, click on `Additional connectivity configuration` and update the value for `Publicly Accessible` to Not publicly accessible to restrict public access. Follow the below steps to update subnet configurations: - Select the `Connectivity and security` tab, and click on the VPC attribute value inside the `Networking` section. - Select the `Details` tab from the VPC dashboard bottom panel and click on Route table configuration attribute value. - On the Route table details page, select the Routes tab from the dashboard bottom panel and click on `Edit routes`. - On the Edit routes page, update the Destination of Target which is set to `igw-xxxxx` and click on `Save` routes. 6. On the Modify DB Instance panel Click on `Continue` and In the Scheduling of modifications section, perform one of the following actions based on your requirements: - Select Apply during the next scheduled maintenance window to apply the changes automatically during the next scheduled maintenance window. - Select Apply immediately to apply the changes right away. With this option, any pending modifications will be asynchronously applied as soon as possible, regardless of the maintenance window setting for this RDS database instance. Note that any changes available in the pending modifications queue are also applied. If any of the pending modifications require downtime, choosing this option can cause unexpected downtime for the application. 7. Repeat steps 3 to 6 for each RDS instance available in the current region. 8. Change the AWS region from the navigation bar to repeat the process for other regions.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names identifiers, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance identifier. 3. Run `modify-db-instance` command to modify the selected RDS instance configuration. Then use the following command to disable the `Publicly Accessible` flag for the selected RDS instances. This command use the apply-immediately flag. If you want `to avoid any downtime --no-apply-immediately flag can be used`: ``` aws rds modify-db-instance --region  --db-instance-identifier  --no-publicly-accessible --apply-immediately ``` 4. The command output should reveal the `PubliclyAccessible` configuration under pending values and should get applied at the specified time. 5. Updating the Internet Gateway Destination via AWS CLI is not currently supported To update information about Internet Gateway use the AWS Console Procedure. 6. Repeat steps 1 to 5 for each RDS instance provisioned in the current region. 7. Change the AWS region by using the --region filter to repeat the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that public access is not given to RDS Instance","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.4.1": {"name": "2.4.1","checks": {"efs_encryption_at_rest_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.4 Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/efs/index.html#efs","Description": "EFS data should be encrypted at rest using AWS KMS (Key Management Service).","DefaultValue": null,"AuditProcedure": "**From Console:** 1. Login to the AWS Management Console and Navigate to `Elastic File System (EFS) dashboard. 2. Select `File Systems` from the left navigation panel. 3. Each item on the list has a visible Encrypted field that displays data at rest encryption status. 4. Validate that this field reads `Encrypted` for all EFS file systems in all AWS regions.**From CLI:** 1. Run describe-file-systems command using custom query filters to list the identifiers of all AWS EFS file systems currently available within the selected region: ``` aws efs describe-file-systems --region  --output table --query 'FileSystems[*].FileSystemId' ``` 2. The command output should return a table with the requested file system IDs. 3. Run describe-file-systems command using the ID of the file system that you want to examine as identifier and the necessary query filters: ``` aws efs describe-file-systems --region  --file-system-id  --query 'FileSystems[*].Encrypted' ``` 4. The command output should return the file system encryption status true or false. If the returned value is `false`, the selected AWS EFS file system is not encrypted and if the returned value is `true`, the selected AWS EFS file system is encrypted.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Data should be encrypted at rest to reduce the risk of a data breach via direct access to the storage device.","RemediationProcedure": "**It is important to note that EFS file system data at rest encryption must be turned on when creating the file system.**If an EFS file system has been created without data at rest encryption enabled then you must create another EFS file system with the correct configuration and transfer the data.**Steps to create an EFS file system with data encrypted at rest:****From Console:** 1. Login to the AWS Management Console and Navigate to `Elastic File System (EFS)` dashboard. 2. Select `File Systems` from the left navigation panel. 3. Click `Create File System` button from the dashboard top menu to start the file system setup process. 4. On the `Configure file system access` configuration page, perform the following actions. - Choose the right VPC from the VPC dropdown list. - Within Create mount targets section, select the checkboxes for all of the Availability Zones (AZs) within the selected VPC. These will be your mount targets. - Click `Next step` to continue.5. Perform the following on the `Configure optional settings` page. - Create `tags` to describe your new file system. - Choose `performance mode` based on your requirements. - Check `Enable encryption` checkbox and choose `aws/elasticfilesystem` from Select KMS master key dropdown list to enable encryption for the new file system using the default master key provided and managed by AWS KMS. - Click `Next step` to continue.6. Review the file system configuration details on the `review and create` page and then click `Create File System` to create your new AWS EFS file system. 7. Copy the data from the old unencrypted EFS file system onto the newly create encrypted file system. 8. Remove the unencrypted file system as soon as your data migration to the newly create encrypted file system is completed. 9. Change the AWS region from the navigation bar and repeat the entire process for other aws regions.**From CLI:** 1. Run describe-file-systems command to describe the configuration information available for the selected (unencrypted) file system (see Audit section to identify the right resource): ``` aws efs describe-file-systems --region  --file-system-id  ``` 2. The command output should return the requested configuration information. 3. To provision a new AWS EFS file system, you need to generate a universally unique identifier (UUID) in order to create the token required by the create-file-system command. To create the required token, you can use a randomly generated UUID from \"https://www.uuidgenerator.net\". 4. Run create-file-system command using the unique token created at the previous step. ``` aws efs create-file-system --region  --creation-token  --performance-mode generalPurpose --encrypted ``` 5. The command output should return the new file system configuration metadata. 6. Run create-mount-target command using the newly created EFS file system ID returned at the previous step as identifier and the ID of the Availability Zone (AZ) that will represent the mount target: ``` aws efs create-mount-target --region  --file-system-id  --subnet-id  ``` 7. The command output should return the new mount target metadata. 8. Now you can mount your file system from an EC2 instance. 9. Copy the data from the old unencrypted EFS file system onto the newly create encrypted file system. 10. Remove the unencrypted file system as soon as your data migration to the newly create encrypted file system is completed. ``` aws efs delete-file-system --region  --file-system-id  ``` 11. Change the AWS region by updating the --region and repeat the entire process for other aws regions.","AdditionalInformation": ""}],"description": "Ensure that encryption is enabled for EFS file systems","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 52,"requirements_failed": 11,"requirements_manual": 0,"total_requirements": 63,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "407c3a08-81aa-4d24-9aca-46a0904f4b1d","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "aws_account_security_onboarding_aws","framework": "AWS-Account-Security-Onboarding","version": "","description": "Checklist when onboarding new AWS Accounts to existing AWS Organization.","region": "eu-west-1","requirements": {"S3 protection": {"name": "S3 protection","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "S3","SubGroup": null,"SubSection": null}],"description": "Protection using S3","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"RDS protection": {"name": "RDS protection","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "GuardDuty","SubGroup": null,"SubSection": null}],"description": "Protection for RDS instances","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Block root user": {"name": "Block root user","checks": {"iam_avoid_root_usage": null,"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "SCPs","Service": "IAM","SubGroup": null,"SubSection": "Apply existing SCPs based on OU placement"}],"description": "Block root user","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"Malware Scanning": {"name": "Malware Scanning","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "GuardDuty","SubGroup": null,"SubSection": null}],"description": "Conducting a Comprehensive Scan for Malicious Software","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Threat Detection": {"name": "Threat Detection","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "GuardDuty","SubGroup": null,"SubSection": null}],"description": "Detection of Threats in your AWS environment","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Lambda protection": {"name": "Lambda protection","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "Lambda","SubGroup": null,"SubSection": null}],"description": "Protection using Lambda","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Runtime protection": {"name": "Runtime protection","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Optional","ItemId": null,"Section": "Enable GuardDuty","Service": "GuardDuty","SubGroup": null,"SubSection": null}],"description": "Brand new and in need of thorough testing.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Predefine IAM Roles": {"name": "Predefine IAM Roles","checks": {"iam_support_role_created": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_role_cross_service_confused_deputy_prevention": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Deploy account from predefined IaC template","Service": "IAM","SubGroup": null,"SubSection": null}],"description": "Check if exists predefine IAM Roles","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"Block unused regions": {"name": "Block unused regions","checks": {"organizations_scp_check_deny_regions": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "SCPs","Service": "IAM","SubGroup": null,"SubSection": "Apply existing SCPs based on OU placement"}],"description": "Block unsued regions","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"S3 Block Public Access": {"name": "S3 Block Public Access","checks": {"s3_bucket_public_access": null,"s3_bucket_level_public_access_block": "PASS","s3_account_level_public_access_blocks": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Deploy account from predefined IaC template","Service": "S3","SubGroup": null,"SubSection": null}],"description": "Block public access to S3 buckets","checks_status": {"fail": 0,"pass": 1,"total": 3,"manual": 0}},"Organization invitation": {"name": "Organization invitation","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Deploy account from predefined IaC template","Service": "Organizations","SubGroup": null,"SubSection": null}],"description": "Check if organization invitation is enabled","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Additional managed rules": {"name": "Additional managed rules","checks": {},"status": "PASS","attributes": [{"Type": "Discuss","ItemId": null,"Section": "WAFv2","Service": "WAFv2","SubGroup": null,"SubSection": "Deploy WAF setup for each public web service"}],"description": "Supplementary managed rules","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Blanket rate-based rules": {"name": "Blanket rate-based rules","checks": {},"status": "PASS","attributes": [{"Type": "Must","ItemId": null,"Section": "WAFv2","Service": "WAFv2","SubGroup": null,"SubSection": "Deploy WAF setup for each public web service"}],"description": "Establishing rules based on a standardized, all-encompassing rate.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Restrict instances types": {"name": "Restrict instances types","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "SCPs","Service": "IAM","SubGroup": null,"SubSection": "Apply existing SCPs based on OU placement"}],"description": "Restrict instances types","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Alert on IAM user changes": {"name": "Alert on IAM user changes","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "CloudTrail","SubGroup": null,"SubSection": "CloudTrail"}],"description": "Alert on IAM user changes","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Enabled security services": {"name": "Enabled security services","checks": {"macie_is_enabled": "PASS","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","accessanalyzer_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Deploy account from predefined IaC template","Service": "SecurityServices","SubGroup": null,"SubSection": null}],"description": "Check if security services are enabled","checks_status": {"fail": 0,"pass": 4,"total": 4,"manual": 0}},"Alert on blocked DNS query": {"name": "Alert on blocked DNS query","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "Route53","SubGroup": null,"SubSection": "R53 DNS Resolver"}],"description": "Notify when a DNS query is obstructed.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Alert on each High finding": {"name": "Alert on each High finding","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Alerting","Service": "GuardDuty","SubGroup": null,"SubSection": "GuardDuty"}],"description": "Checks that GuardDuty is enabled and configured to send High findings to CloudWatch Events","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"Disable AMI public sharing": {"name": "Disable AMI public sharing","checks": {"ec2_ami_public": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Deploy account from predefined IaC template","Service": "EC2","SubGroup": null,"SubSection": null}],"description": "Disable AMI public sharing","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"Add custom SCPs if required": {"name": "Add custom SCPs if required","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "SCPs","Service": "IAM","SubGroup": null,"SubSection": null}],"description": "Add custom SCPs if required","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Scoped-down rate-based rules": {"name": "Scoped-down rate-based rules","checks": {"elbv2_waf_acl_attached": "FAIL","cloudfront_distributions_using_waf": null,"apigateway_restapi_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Type": "Discuss","ItemId": null,"Section": "WAFv2","Service": "WAFv2","SubGroup": null,"SubSection": "Deploy WAF setup for each public web service"}],"description": "Rate-based rules with a narrowed scope","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"Global allow - and block-lists": {"name": "Global allow - and block-lists","checks": {"elbv2_waf_acl_attached": "FAIL","cloudfront_distributions_using_waf": null,"apigateway_restapi_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "WAFv2","Service": "WAFv2","SubGroup": null,"SubSection": "Deploy WAF setup for each public web service"}],"description": "Establishing International Lists for Permissions and Restrictions","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"Service-unique exclusion rules": {"name": "Service-unique exclusion rules","checks": {"elbv2_waf_acl_attached": "FAIL","cloudfront_distributions_using_waf": null,"apigateway_restapi_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "WAFv2","Service": "WAFv2","SubGroup": null,"SubSection": "Deploy WAF setup for each public web service"}],"description": "Exclusion rules specific to the service provided.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"Alert on snapshot manipulations": {"name": "Alert on snapshot manipulations","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "CloudTrail","SubGroup": null,"SubSection": "CloudTrail"}],"description": "Alert when a snapshot is manipulated","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"EKS protection (if EKS is used)": {"name": "EKS protection (if EKS is used)","checks": {},"status": "PASS","attributes": [{"Type": "Optional","ItemId": null,"Section": "Enable GuardDuty","Service": "EKS","SubGroup": null,"SubSection": null}],"description": "Enhanced Kubernetes Security (EKS) protection, if the Kubernetes service is employed.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Predefined set of managed rules": {"name": "Predefined set of managed rules","checks": {"elbv2_waf_acl_attached": "FAIL","cloudfront_distributions_using_waf": null,"apigateway_restapi_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "WAFv2","Service": "WAFv2","SubGroup": null,"SubSection": "Deploy WAF setup for each public web service"}],"description": "A pre-established collection of rules under management control.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"Alerts based on rate-based rules": {"name": "Alerts based on rate-based rules","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "WAF","SubGroup": null,"SubSection": "WAF"}],"description": "Notifications triggered by rate-based regulations","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Use strictly AWS VPC DNS resolver": {"name": "Use strictly AWS VPC DNS resolver","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "R53 DNS Resolver Firewall","Service": "Route53","SubGroup": null,"SubSection": null}],"description": "Exclusively Employ Amazon Web Services (AWS) Virtual Private Cloud (VPC) DNS Resolver","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Alert based on DDoSDetected metric": {"name": "Alert based on DDoSDetected metric","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "Shield","SubGroup": null,"SubSection": "Shield"}],"description": "Generate an alert triggered by the detection of a DDoS attack based on the DDoSDetected metric.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Enable and configure AWS Inspector": {"name": "Enable and configure AWS Inspector","checks": {"inspector2_is_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Vulnerability Scanning","Service": "EC2","SubGroup": null,"SubSection": "EC2 used as servers"}],"description": "Enable and set up AWS Inspector.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"IDC integration, SSO configuration": {"name": "IDC integration, SSO configuration","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Deploy account from predefined IaC template","Service": "IAM Identity Center","SubGroup": null,"SubSection": null}],"description": "Check if IDC integration and SSO configuration is enabled","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Send DNS Resolvers queries to SIEM": {"name": "Send DNS Resolvers queries to SIEM","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Logging","Service": "Logging","SubGroup": null,"SubSection": null}],"description": "Send DNS Resolvers queries to SIEM","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Alerts on raised cost anomaly events": {"name": "Alerts on raised cost anomaly events","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "Billing","SubGroup": null,"SubSection": "Cost Anomaly"}],"description": "Alert when cost anomaly events are raised","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Enable as part of Organization trail": {"name": "Enable as part of Organization trail","checks": {"cloudtrail_multi_region_enabled": "PASS","cloudtrail_multi_region_enabled_logging_management_events": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "AWS Cloudtrail","Service": "CloudTrail","SubGroup": null,"SubSection": null}],"description": "Activate as a component of the Organization trail.","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"Root user - distribution email + MFA": {"name": "Root user - distribution email + MFA","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Deploy account from predefined IaC template","Service": "IAM","SubGroup": null,"SubSection": null}],"description": "Check if root user has distribution email and MFA enabled","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"Billing, emergency, security contacts": {"name": "Billing, emergency, security contacts","checks": {"account_maintain_current_contact_details": null,"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Deploy account from predefined IaC template","Service": "Billing","SubGroup": null,"SubSection": null}],"description": "Check if billing, emergency, security contacts are configured","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"Realert on inactivity in a set period": {"name": "Realert on inactivity in a set period","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "SecurityHub","SubGroup": null,"SubSection": "SecurityHub"}],"description": "Activate a re-alert system for detecting inactivity within a specified time frame.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Confirm that events are present in SIEM": {"name": "Confirm that events are present in SIEM","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "GuardDuty","SubGroup": null,"SubSection": null}],"description": "Confirm that events are present in SIEM","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Create analyzers in each active regions": {"name": "Create analyzers in each active regions","checks": {"accessanalyzer_enabled": "PASS","accessanalyzer_enabled_without_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "IAM Access Analyzer","Service": "IAM Access Analyzer","SubGroup": null,"SubSection": null}],"description": "Establish analyzers within every active region.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Export metrics in centralized collector": {"name": "Export metrics in centralized collector","checks": {"wafv2_webacl_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "WAFv2","Service": "CloudWatch","SubGroup": null,"SubSection": null}],"description": "Exporting metrics to a centralized collector for comprehensive data aggregation.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"CFD + ALB + secret rotation architecture": {"name": "CFD + ALB + secret rotation architecture","checks": {"elbv2_waf_acl_attached": "FAIL","cloudfront_distributions_using_waf": null,"apigateway_restapi_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "WAFv2","Service": "WAFv2","SubGroup": null,"SubSection": "Deploy WAF setup for each public web service"}],"description": "Designing an Architecture for Computational Fluid Dynamics (CFD), Application Load Balancing (ALB), and Secret Rotation Integration","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"Critical alert on every root user activity": {"name": "Critical alert on every root user activity","checks": {"cloudwatch_log_metric_filter_root_usage": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Alerting","Service": "CloudTrail","SubGroup": null,"SubSection": "CloudTrail"}],"description": "Send critical alert on every root user activity","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"Consider enabling for critical buckets only": {"name": "Consider enabling for critical buckets only","checks": {"macie_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Macie","Service": "Macie","SubGroup": null,"SubSection": null}],"description": "Please contemplate activating this feature exclusively for essential or crucial buckets.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"Alert on rise of ConsoleLoginFailures events": {"name": "Alert on rise of ConsoleLoginFailures events","checks": {"cloudwatch_log_metric_filter_authentication_failures": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Alerting","Service": "CloudTrail","SubGroup": null,"SubSection": "CloudTrail"}],"description": "Alert on rise ConsoleLoginFailures events","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"Send VPC Flow Logs (only DENYs) to S3 bucket": {"name": "Send VPC Flow Logs (only DENYs) to S3 bucket","checks": {"vpc_flow_logs_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Logging","Service": "Logging","SubGroup": null,"SubSection": null}],"description": "Send VPC Flow Logs (only DENYs) to S3 bucket","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"Critical alert on cloudtrail settings changes": {"name": "Critical alert on cloudtrail settings changes","checks": {"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Alerting","Service": "CloudTrail","SubGroup": null,"SubSection": "CloudTrail"}],"description": "Send critical alert on cloudtrail settings changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"Scan images for vulnerability on upload to ECR": {"name": "Scan images for vulnerability on upload to ECR","checks": {"inspector2_is_enabled": "FAIL","inspector2_active_findings_exist": "FAIL","ecr_registry_scan_images_on_push_enabled": "PASS","ecr_repositories_scan_images_on_push_enabled": "FAIL","ecr_repositories_scan_vulnerabilities_in_latest_image": null},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Vulnerability Scanning","Service": "ECR","SubGroup": null,"SubSection": "ECR used as docker images hub"}],"description": "Check uploaded images for vulnerabilities when adding them to the ECR (Elastic Container Registry).","checks_status": {"fail": 3,"pass": 1,"total": 5,"manual": 0}},"Alert on critical vulnerabilities in AMIs/Images": {"name": "Alert on critical vulnerabilities in AMIs/Images","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "Inspector","SubGroup": null,"SubSection": "Vulnerability Scanning"}],"description": "Notification regarding severe vulnerabilities detected in AMIs/Images.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Ban outbound DNS calls from all VPCs to ports 53": {"name": "Ban outbound DNS calls from all VPCs to ports 53","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "R53 DNS Resolver Firewall","Service": "Route53","SubGroup": null,"SubSection": null}],"description": "Prohibit all Virtual Private Clouds (VPCs) from initiating outbound DNS calls on port 53.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Enable/disable additional standards and controls": {"name": "Enable/disable additional standards and controls","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Enable AWS SecurityHub","Service": "SecurityHub","SubGroup": null,"SubSection": null}],"description": "Implement SecurityHub Central Configuration across the organization.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"Confirm that logs are present in S3 bucket and SIEM": {"name": "Confirm that logs are present in S3 bucket and SIEM","checks": {"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "AWS Cloudtrail","Service": "CloudTrail","SubGroup": null,"SubSection": null}],"description": "Verify the existence of logs within both the S3 bucket and the SIEM system.","checks_status": {"fail": 1,"pass": 0,"total": 3,"manual": 0}},"Alerts based on (at least) each new CRITICAL finding": {"name": "Alerts based on (at least) each new CRITICAL finding","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "SecurityHub","SubGroup": null,"SubSection": "SecurityHub"}],"description": "Alerts triggered by every new CRITICAL finding, at a minimum.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Apply suppression filters to disable useless findings": {"name": "Apply suppression filters to disable useless findings","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "GuardDuty","SubGroup": null,"SubSection": null}],"description": "Implementing suppression filters to deactivate non-essential detections.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Enable continuous recording for most of the resources": {"name": "Enable continuous recording for most of the resources","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Enable AWS Config","Service": "Config","SubGroup": null,"SubSection": null}],"description": "Activate continuous recording for the majority of resources.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"Adopt incident response guide and prepared battle card": {"name": "Adopt incident response guide and prepared battle card","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "Shield","SubGroup": null,"SubSection": "Shield"}],"description": "Utilize the incident response manual and have the battle card ready for use.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Confirm that records are present in central aggregator": {"name": "Confirm that records are present in central aggregator","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Enable AWS Config","Service": "Config","SubGroup": null,"SubSection": null}],"description": "Confirm that records are present in central aggregator","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"Configure R53 health checks for all protected resources": {"name": "Configure R53 health checks for all protected resources","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "WAFv2","Service": "Route53","SubGroup": null,"SubSection": null}],"description": "Establishing Amazon Route 53 (R53) health checks to monitor the well-being of all safeguarded resources.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Export scan results as metrics in centralized collector": {"name": "Export scan results as metrics in centralized collector","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Vulnerability Scanning","Service": "ECR","SubGroup": null,"SubSection": "ECR used as docker images hub"}],"description": "Generate metric data from scan results and store it in a centralized collector.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Include in process of incident response based on events": {"name": "Include in process of incident response based on events","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "GuardDuty","SubGroup": null,"SubSection": null}],"description": "Incorporate within the procedural framework of incident response, taking into account the triggering events.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Apply SecurityHub Central Configuration for Organization": {"name": "Apply SecurityHub Central Configuration for Organization","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Enable AWS SecurityHub","Service": "SecurityHub","SubGroup": null,"SubSection": null}],"description": "Apply SecurityHub Central Configuration for Organization","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"Enable as part of central configuration for Organization": {"name": "Enable as part of central configuration for Organization","checks": {"guardduty_is_enabled": "PASS","guardduty_centrally_managed": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "GuardDuty","SubGroup": null,"SubSection": null}],"description": "Please verify the existence of records within the central aggregator.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Deploy solution to alert on at least critical new findings": {"name": "Deploy solution to alert on at least critical new findings","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Enable AWS SecurityHub","Service": "SecurityHub","SubGroup": null,"SubSection": null}],"description": "Implement a solution to trigger alerts for newly identified critical issues at minimum.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"Apply managed domain name lists for Resolver in block mode)": {"name": "Apply managed domain name lists for Resolver in block mode)","checks": {"route53_domains_transferlock_enabled": null,"route53_domains_privacy_protection_enabled": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "R53 DNS Resolver Firewall","Service": "Route53","SubGroup": null,"SubSection": null}],"description": "Utilize managed domain name lists within Resolver to implement block mode.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"Block tampering with security-related settings and services": {"name": "Block tampering with security-related settings and services","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "SCPs","Service": "IAM","SubGroup": null,"SubSection": "Apply existing SCPs based on OU placement"}],"description": "Block tampering with security-related settings and services","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Enable Shield Advanced subscription for public facing account": {"name": "Enable Shield Advanced subscription for public facing account","checks": {"shield_advanced_protection_in_global_accelerators": null,"shield_advanced_protection_in_route53_hosted_zones": null,"shield_advanced_protection_in_associated_elastic_ips": null,"shield_advanced_protection_in_classic_load_balancers": null,"shield_advanced_protection_in_cloudfront_distributions": null,"shield_advanced_protection_in_internet_facing_load_balancers": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Shield Advanced","Service": "Shield Advanced","SubGroup": null,"SubSection": null}],"description": "Activate the Shield Advanced subscription for the publicly accessible account.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"Verify that events are present in SecurityHub aggregated view": {"name": "Verify that events are present in SecurityHub aggregated view","checks": {"securityhub_enabled": "PASS","accessanalyzer_enabled": "PASS","accessanalyzer_enabled_without_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "IAM Access Analyzer","Service": "SecurityHub","SubGroup": null,"SubSection": null}],"description": "Confirm the presence of events within the aggregated view of SecurityHub.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"Configure sensitive fields redaction and send WAF logs to SIEM": {"name": "Configure sensitive fields redaction and send WAF logs to SIEM","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "WAFv2","Service": "WAFv2","SubGroup": null,"SubSection": null}],"description": "Configure the redaction of sensitive fields and transmit Web Application Firewall (WAF) logs to the Security Information and Event Management (SIEM) system.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Confirm that findings are being visible in the aggregated view": {"name": "Confirm that findings are being visible in the aggregated view","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Enable AWS SecurityHub","Service": "SecurityHub","SubGroup": null,"SubSection": null}],"description": "Please verify that the findings are visible when viewed in the aggregated perspective.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"Send S3 access logs for critical buckets to separate S3 bucket": {"name": "Send S3 access logs for critical buckets to separate S3 bucket","checks": {"cloudtrail_s3_dataevents_write_enabled": null,"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Logging","Service": "Logging","SubGroup": null,"SubSection": null}],"description": "Send S3 access logs for critical buckets to separate S3 bucket","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"Consider periodic recording for some resources to optimize bill": {"name": "Consider periodic recording for some resources to optimize bill","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Enable AWS Config","Service": "Config","SubGroup": null,"SubSection": null}],"description": "Think about implementing scheduled monitoring for specific resources in order to maximize cost efficiency.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Create DDoS battle card with main info about protected services": {"name": "Create DDoS battle card with main info about protected services","checks": {"shield_advanced_protection_in_global_accelerators": null,"shield_advanced_protection_in_route53_hosted_zones": null,"shield_advanced_protection_in_associated_elastic_ips": null,"shield_advanced_protection_in_classic_load_balancers": null,"shield_advanced_protection_in_cloudfront_distributions": null,"shield_advanced_protection_in_internet_facing_load_balancers": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Shield Advanced","Service": "Shield Advanced","SubGroup": null,"SubSection": null}],"description": "Prepare a Detailed Distributed Denial of Service (DDoS) Battle Card Encompassing Key Information Regarding Safeguarded Services.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"Alerts based on high amount of blocked requests by managed rules": {"name": "Alerts based on high amount of blocked requests by managed rules","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "WAF","SubGroup": null,"SubSection": "WAF"}],"description": "Notifications triggered by a significant number of blocked requests as a result of managed rules.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Alerts based on aggregated findings with severity Medium and below": {"name": "Alerts based on aggregated findings with severity Medium and below","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "GuardDuty","SubGroup": null,"SubSection": "GuardDuty"}],"description": "Alert based on aggregated findings with severity Medium and below","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Create Cost Anomaly Detection monitors to alert spending anomalies": {"name": "Create Cost Anomaly Detection monitors to alert spending anomalies","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Budget Alarms","Service": "CloudWatch","SubGroup": null,"SubSection": "QA"}],"description": "Establish monitoring systems for cost anomaly detection to promptly notify about unusual spending patterns.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Enable Shield Advanced automatic application layer DDoS mitigation": {"name": "Enable Shield Advanced automatic application layer DDoS mitigation","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "WAFv2","Service": "Shield Advanced","SubGroup": null,"SubSection": null}],"description": "Activate automatic application layer Distributed Denial of Service (DDoS) mitigation within Shield Advanced.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Apply custom threat list for GuardDuty to alert on access to DoH servers": {"name": "Apply custom threat list for GuardDuty to alert on access to DoH servers","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "R53 DNS Resolver Firewall","Service": "Route53","SubGroup": null,"SubSection": null}],"description": "Implement a customized threat list within GuardDuty to generate alerts when there is access to Domain Name System over HTTPS (DoH) servers.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Configure Budgets Actions to stop services in cases of big unexpected spendings": {"name": "Configure Budgets Actions to stop services in cases of big unexpected spendings","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Budget Alarms","Service": "SNS","SubGroup": null,"SubSection": "QA"}],"description": "Set up Budgets Actions to halt services when significant unexpected expenses occur.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Ensure that there are no critical (and considered critical) findings present in account": {"name": "Ensure that there are no critical (and considered critical) findings present in account","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Enable AWS SecurityHub","Service": "SecurityHub","SubGroup": null,"SubSection": null}],"description": "Make certain that there are no critical findings, whether deemed critical or not, within the account.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"Deploy solution to periodically rescan currently used images and report found vulnerabilities": {"name": "Deploy solution to periodically rescan currently used images and report found vulnerabilities","checks": {"ecr_repositories_scan_vulnerabilities_in_latest_image": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Vulnerability Scanning","Service": "ECR","SubGroup": null,"SubSection": "ECR used as docker images hub"}],"description": "Implement a solution to conduct regular scans on currently employed images and notify about any identified vulnerabilities.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"Establish ready-to-be-enabled pipelines to deliver ALB and CFD to SIEM to toggle in case of emergency and investigations": {"name": "Establish ready-to-be-enabled pipelines to deliver ALB and CFD to SIEM to toggle in case of emergency and investigations","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Logging","Service": "Logging","SubGroup": null,"SubSection": null}],"description": "Establish ready-to-be-enabled pipelines to deliver ALB and CFD to SIEM to toggle in case of emergency and investigations","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}}},"requirements_passed": 26,"requirements_failed": 23,"requirements_manual": 34,"total_requirements": 83,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "623480b7-012a-4aab-b553-16d3b8898136","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "hipaa_aws","framework": "HIPAA","version": "","description": "The Health Insurance Portability and Accountability Act of 1996 (HIPAA) is legislation that helps US workers to retain health insurance coverage when they change or lose jobs. The legislation also seeks to encourage electronic health records to improve the efficiency and quality of the US healthcare system through improved information sharing.","region": "eu-west-1","requirements": {"164_312_b": {"name": "164.312(b) Audit controls","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_b","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement hardware, software, and/or procedural mechanisms that record and examine activity in information systems that contain or use electronic protected health information.","checks_status": {"fail": 8,"pass": 4,"total": 16,"manual": 0}},"164_312_d": {"name": "164.312(d) Person or entity authentication","checks": {"iam_root_mfa_enabled": null,"iam_password_policy_reuse_24": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_312_d","Section": "164.312 Technical Safeguards","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Implement procedures to verify that a person or entity seeking access to electronic protected health information is the one claimed.","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"164_308_a_8": {"name": "164.308(a)(8) Evaluation","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_8","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Perform a periodic technical and nontechnical evaluation, based initially upon the standards implemented under this rule and subsequently, in response to environmental or operational changes affecting the security of electronic protected health information, that establishes the extent to which an entity's security policies and procedures meet the requirements of this subpart.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"164_312_a_1": {"name": "164.312(a)(1) Access control","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"iam_user_mfa_enabled_console_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"awslambda_function_not_publicly_accessible": "PASS","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_a_1","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement technical policies and procedures for electronic information systems that maintain electronic protected health information to allow access only to those persons or software programs that have been granted access rights as specified in 164.308(a)(4).","checks_status": {"fail": 1,"pass": 5,"total": 16,"manual": 0}},"164_312_c_1": {"name": "164.312(c)(1) Integrity","checks": {"ec2_ebs_volume_encryption": "PASS","s3_bucket_object_versioning": "FAIL","s3_bucket_default_encryption": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_c_1","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement policies and procedures to protect electronic protected health information from improper alteration or destruction.","checks_status": {"fail": 4,"pass": 2,"total": 6,"manual": 0}},"164_312_c_2": {"name": "164.312(c)(2) Mechanism to authenticate electronic protected health information","checks": {"vpc_flow_logs_enabled": "FAIL","ec2_ebs_volume_encryption": "PASS","s3_bucket_object_versioning": "FAIL","s3_bucket_default_encryption": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_c_2","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement electronic mechanisms to corroborate that electronic protected health information has not been altered or destroyed in an unauthorized manner.","checks_status": {"fail": 5,"pass": 2,"total": 7,"manual": 0}},"164_312_e_1": {"name": "164.312(e)(1) Transmission security","checks": {"elb_ssl_listeners": "FAIL","acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","cloudfront_distributions_https_enabled": null,"awslambda_function_not_publicly_accessible": "PASS","opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_e_1","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement technical security measures to guard against unauthorized access to electronic protected health information that is being transmitted over an electronic communications network.","checks_status": {"fail": 3,"pass": 3,"total": 9,"manual": 0}},"164_308_a_3_i": {"name": "164.308(a)(3)(i) Workforce security","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_3_i","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement policies and procedures to ensure that all members of its workforce have appropriate access to electronic protected health information, as provided under paragraph (a)(4) of this section, and to prevent those workforce members who do not have access under paragraph (a)(4) of this section from obtaining access to electronic protected health information.","checks_status": {"fail": 1,"pass": 5,"total": 15,"manual": 0}},"164_308_a_4_i": {"name": "164.308(a)(4)(i) Information access management","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_4_i","Section": "164.308 Administrative Safeguards","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Implement policies and procedures for authorizing access to electronic protected health information that are consistent with the applicable requirements of subpart E of this part.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"164_308_a_6_i": {"name": "164.308(a)(6)(i) Security incident procedures","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_6_i","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement policies and procedures to address security incidents.","checks_status": {"fail": 0,"pass": 2,"total": 8,"manual": 0}},"164_308_a_7_i": {"name": "164.308(a)(7)(i) Contingency plan","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_7_i","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establish (and implement as needed) policies and procedures for responding to an emergency or other occurrence (for example, fire, vandalism, system failure, and natural disaster) that damages systems that contain electronic protected health information.","checks_status": {"fail": 3,"pass": 1,"total": 10,"manual": 0}},"164_312_a_2_i": {"name": "164.312(a)(2)(i) Unique user identification","checks": {"iam_no_root_access_key": null,"s3_bucket_public_access": null,"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_312_a_2_i","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Assign a unique name and/or number for identifying and tracking user identity.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"164_312_e_2_i": {"name": "164.312(e)(2)(i) Integrity controls","checks": {"elb_ssl_listeners": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_multi_region_enabled": "PASS","s3_bucket_secure_transport_policy": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_e_2_i","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement security measures to ensure that electronically transmitted electronic protected health information is not improperly modified without detection until disposed of.","checks_status": {"fail": 4,"pass": 3,"total": 10,"manual": 0}},"164_308_a_6_ii": {"name": "164.308(a)(6)(ii) Response and reporting","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"cloudwatch_log_metric_filter_root_usage": null,"s3_bucket_server_access_logging_enabled": "FAIL","cloudwatch_log_metric_filter_authentication_failures": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_6_ii","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Identify and respond to suspected or known security incidents; mitigate, to the extent practicable, harmful effects of security incidents that are known to the covered entity or business associate; and document security incidents and their outcomes.","checks_status": {"fail": 6,"pass": 4,"total": 15,"manual": 0}},"164_312_a_2_ii": {"name": "164.312(a)(2)(ii) Emergency access procedure","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_a_2_ii","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establish (and implement as needed) procedures for obtaining necessary electronic protected health information during an emergency.","checks_status": {"fail": 2,"pass": 1,"total": 9,"manual": 0}},"164_312_a_2_iv": {"name": "164.312(a)(2)(iv) Encryption and decryption","checks": {"kms_cmk_rotation_enabled": null,"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"eks_cluster_kms_cmk_encryption_in_secrets_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_a_2_iv","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement a mechanism to encrypt and decrypt electronic protected health information.","checks_status": {"fail": 6,"pass": 3,"total": 19,"manual": 0}},"164_312_e_2_ii": {"name": "164.312(e)(2)(ii) Encryption","checks": {"elb_ssl_listeners": "FAIL","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"eks_cluster_kms_cmk_encryption_in_secrets_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_e_2_ii","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement a mechanism to encrypt electronic protected health information whenever deemed appropriate.","checks_status": {"fail": 7,"pass": 3,"total": 19,"manual": 0}},"164_308_a_1_ii_a": {"name": "164.308(a)(1)(ii)(A) Risk analysis","checks": {"guardduty_is_enabled": "PASS","config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_1_ii_a","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Conduct an accurate and thorough assessment of the potential risks and vulnerabilities to the confidentiality, integrity, and availability of electronic protected health information held by the covered entity or business associate.","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"164_308_a_1_ii_b": {"name": "164.308(a)(1)(ii)(B) Risk Management","checks": {"elb_ssl_listeners": "FAIL","rds_instance_multi_az": "FAIL","ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"ec2_ebs_volume_encryption": "PASS","elbv2_deletion_protection": "FAIL","ec2_ebs_default_encryption": "PASS","rds_instance_backup_enabled": "PASS","rds_snapshots_public_access": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"s3_bucket_default_encryption": "PASS","awslambda_function_url_public": null,"efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"redshift_cluster_public_access": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"cloudtrail_log_file_validation_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","awslambda_function_not_publicly_accessible": "PASS","cloudwatch_log_group_kms_encryption_enabled": "FAIL","iam_inline_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_encryption_enabled": null,"iam_aws_attached_policy_no_administrative_privileges": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"iam_customer_attached_policy_no_administrative_privileges": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_1_ii_b","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement security measures sufficient to reduce risks and vulnerabilities to a reasonable and appropriate level to comply with 164.306(a): Ensure the confidentiality, integrity, and availability of all electronic protected health information the covered entity or business associate creates, receives, maintains, or transmits.","checks_status": {"fail": 14,"pass": 9,"total": 39,"manual": 0}},"164_308_a_1_ii_d": {"name": "164.308(a)(1)(ii)(D) Information system activity review","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_1_ii_d","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement procedures to regularly review records of information system activity, such as audit logs, access reports, and security incident tracking reports.","checks_status": {"fail": 7,"pass": 4,"total": 15,"manual": 0}},"164_308_a_3_ii_a": {"name": "164.308(a)(3)(ii)(A) Authorization and/or supervision","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_root_mfa_enabled": null,"elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","iam_root_hardware_mfa_enabled": null,"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","iam_user_mfa_enabled_console_access": null,"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_3_ii_a","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement procedures for the authorization and/or supervision of workforce members who work with electronic protected health information or in locations where it might be accessed.","checks_status": {"fail": 4,"pass": 4,"total": 16,"manual": 0}},"164_308_a_3_ii_b": {"name": "164.308(a)(3)(ii)(B) Workforce clearance procedure","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_3_ii_b","Section": "164.308 Administrative Safeguards","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Implement procedures to determine that the access of a workforce member to electronic protected health information is appropriate.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"164_308_a_3_ii_c": {"name": "164.308(a)(3)(ii)(C) Termination procedures","checks": {"iam_rotate_access_key_90_days": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_3_ii_c","Section": "164.308 Administrative Safeguards","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Implement procedures for terminating access to electronic protected health information when the employment of, or other arrangement with, a workforce member ends or as required by determinations made as specified in paragraph (a)(3)(ii)(b).","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"164_308_a_4_ii_a": {"name": "164.308(a)(4)(ii)(A) Isolating health care clearinghouse functions","checks": {"elb_ssl_listeners": "FAIL","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","rds_instance_backup_enabled": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"acm_certificates_expiration_check": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","redshift_cluster_automated_snapshot": null,"cloudfront_distributions_https_enabled": null,"rds_instance_integration_cloudwatch_logs": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"eks_cluster_kms_cmk_encryption_in_secrets_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_4_ii_a","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "If a health care clearinghouse is part of a larger organization, the clearinghouse must implement policies and procedures that protect the electronic protected health information of the clearinghouse from unauthorized access by the larger organization.","checks_status": {"fail": 7,"pass": 5,"total": 25,"manual": 0}},"164_308_a_4_ii_b": {"name": "164.308(a)(4)(ii)(B) Access authorization","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_4_ii_b","Section": "164.308 Administrative Safeguards","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Implement policies and procedures for granting access to electronic protected health information, As one illustrative example, through access to a workstation, transaction, program, process, or other mechanism.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"164_308_a_4_ii_c": {"name": "164.308(a)(4)(ii)(B) Access authorization","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_password_policy_reuse_24": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_4_ii_c","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement policies and procedures that, based upon the covered entity's or the business associate's access authorization policies, establish, document, review, and modify a user's right of access to a workstation, transaction, program, or process.","checks_status": {"fail": 1,"pass": 0,"total": 9,"manual": 0}},"164_308_a_5_ii_b": {"name": "164.308(a)(5)(ii)(B) Protection from malicious software","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_5_ii_b","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Procedures for guarding against, detecting, and reporting malicious software.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"164_308_a_5_ii_c": {"name": "164.308(a)(5)(ii)(C) Log-in monitoring","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudwatch_log_metric_filter_authentication_failures": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_5_ii_c","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Procedures for monitoring log-in attempts and reporting discrepancies.","checks_status": {"fail": 0,"pass": 2,"total": 3,"manual": 0}},"164_308_a_5_ii_d": {"name": "164.308(a)(5)(ii)(D) Password management","checks": {"iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_5_ii_d","Section": "164.308 Administrative Safeguards","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Procedures for creating, changing, and safeguarding passwords.","checks_status": {"fail": 0,"pass": 0,"total": 9,"manual": 0}},"164_308_a_7_ii_a": {"name": "164.308(a)(7)(ii)(A) Data backup plan","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_7_ii_a","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establish and implement procedures to create and maintain retrievable exact copies of electronic protected health information.","checks_status": {"fail": 3,"pass": 1,"total": 10,"manual": 0}},"164_308_a_7_ii_b": {"name": "164.308(a)(7)(ii)(B) Disaster recovery plan","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_7_ii_b","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establish (and implement as needed) procedures to restore any loss of data.","checks_status": {"fail": 3,"pass": 1,"total": 10,"manual": 0}},"164_308_a_7_ii_c": {"name": "164.308(a)(7)(ii)(C) Emergency mode operation plan","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_7_ii_c","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establish (and implement as needed) procedures to enable continuation of critical business processes for protection of the security of electronic protected health information while operating in emergency mode.","checks_status": {"fail": 3,"pass": 1,"total": 10,"manual": 0}}},"requirements_passed": 11,"requirements_failed": 21,"requirements_manual": 0,"total_requirements": 32,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "6a808cc7-3501-4085-98f9-e4a9fa251f4c","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "mitre_attack_aws","framework": "MITRE-ATTACK","version": "","description": "MITRE ATT&CKĀ® is a globally-accessible knowledge base of adversary tactics and techniques based on real-world observations. The ATT&CK knowledge base is used as a foundation for the development of specific threat models and methodologies in the private sector, in government, and in the cybersecurity product and service community.","region": "eu-west-1","requirements": {"T1040": {"name": "Network Sniffing","checks": {"elb_ssl_listeners": "FAIL","elbv2_ssl_listeners": "FAIL","iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_hardware_mfa_enabled": null,"rds_instance_transport_encrypted": "FAIL","acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL","config_recorder_all_regions_enabled": null,"iam_user_mfa_enabled_console_access": null,"cloudfront_distributions_https_enabled": null,"iam_policy_allows_privilege_escalation": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","iam_inline_policy_no_administrative_privileges": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "AWS CloudWatch uses TLS/SSL connections to communicate with other AWS resources which protects against network sniffing attacks. As a result, this mapping is given a score of Significant.","Category": "Protect","AWSService": "AWS CloudWatch"},{"Value": "Significant","Comment": "AWS RDS and AWS RDS Proxy support TLS/SSL connections to database instances which protects against network sniffing attacks. As a result, this mapping is given a score of Significant.","Category": "Protect","AWSService": "AWS RDS"},{"Value": "Significant","Comment": "The VPC service's support for the AWS Virtual Private Network (VPN) can be used to encrypt traffic traversing over untrusted networks which can prevent information from being gathered via network sniffing.","Category": "Protect","AWSService": "Amazon Virtual Private Cloud"},{"Value": "Partial","Comment": "The following AWS IoT Device Defender audit checks and corresponding mitigation actions can identify and resolve configuration problems that should be fixed in order to ensure SSL/TLS encryption is enabled and secure to protect network traffic to/from IoT devices: 'CA certificate expiring' ('CA_CERTIFICATE_EXPIRING_CHECK' in the CLI and API), 'CA certificate key quality' ('CA_CERTIFICATE_KEY_QUALITY_CHECK' in the CLI and API), and 'CA certificate revoked but device certificates still active' ('REVOKED_CA_CERTIFICATE_STILL_ACTIVE_CHECK' in the CLI and API) can identify problems with certificate authority (CA) certificates being used for signing and support the 'UPDATE_CA_CERTIFICATE' mitigation action which can resolve them. 'Device certificate expiring' ('DEVICE_CERTIFICATE_EXPIRING_CHECK' in the CLI and API), 'Device certificate key quality' ('DEVICE_CERTIFICATE_KEY_QUALITY_CHECK' in the CLI and API), 'Device certificate shared' ('DEVICE_CERTIFICATE_SHARED_CHECK' in the CLI and API), and 'Revoked device certificate still active' ('REVOKED_DEVICE_CERTIFICATE_STILL_ACTIVE_CHECK' in the CLI and API) can identify problems with IoT devices' certificates and support the 'UPDATE_DEVICE_CERTIFICATE' and 'ADD_THINGS_TO_THING_GROUP' mitigation actions which can resolve them. Coverage factor is partial for these checks and mitigations, since they are specific to IoT device communication and can only mitigate behavior for adversaries who are unable to decrypt the relevant traffic, resulting in an overall score of Partial.","Category": "Protect","AWSService": "AWS IoT Device Defender"},{"Value": "Partial","Comment": "The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure SSL/TLS encryption is enabled to protect network traffic: 'acm-certificate-expiration-check' for nearly expired certificates in AWS Certificate Manager (ACM); 'alb-http-to-https-redirection-check' for Application Load Balancer (ALB) HTTP listeners; 'api-gw-ssl-enabled' for API Gateway REST API stages; 'cloudfront-custom-ssl-certificate', 'cloudfront-sni-enabled', and 'cloudfront-viewer-policy-https', for Amazon CloudFront distributions; 'elb-acm-certificate-required', 'elb-custom-security-policy-ssl-check', 'elb-predefined-security-policy-ssl-check', and 'elb-tls-https-listeners-only' for Elastic Load Balancing (ELB) Classic Load Balancer listeners; 'redshift-require-tls-ssl' for Amazon Redshift cluster connections to SQL clients; 's3-bucket-ssl-requests-only' for requests for S3 bucket contents; and 'elasticsearch-node-to-node-encryption-check' for Amazon ElasticSearch Service node-to-node communications. The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure that private traffic is routed securely and only within VPCs rather than on the public Internet: 'api-gw-endpoint-type-check' for Amazon API Gateway APIs, 'elasticsearch-in-vpc-only' for Amazon ElasticSearch Service domains, and 'redshift-enhanced-vpc-routing-enabled' for Amazon Redshift cluster traffic. All of these are run on configuration changes except 'alb-http-to-https-redirection-check' and 'elasticsearch-in-vpc-only', which are run periodically. Coverage factor is partial for these rules, since they are specific to a subset of the available AWS services and can only mitigate behavior for adversaries who are unable to decrypt the relevant traffic and/or do not have access to traffic within the relevant VPCs, resulting in an overall score of Partial.","Category": "Protect","AWSService": "AWS Config"}],"description": "Adversaries may sniff network traffic to capture information about an environment, including authentication material passed over the network. Network sniffing refers to using the network interface on a system to monitor or capture information sent over a wired or wireless connection. An adversary may place a network interface into promiscuous mode to passively access data in transit over the network, or use span ports to capture a larger amount of data.","checks_status": {"fail": 5,"pass": 1,"total": 17,"manual": 0}},"T1046": {"name": "Network Service Discovery","checks": {"guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","elbv2_waf_acl_attached": "FAIL","networkfirewall_in_all_vpc": "FAIL","inspector2_active_findings_exist": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Value": "Partial","Comment": "The following AWS IoT Device Defender device-side detection metrics can detect indicators that an adversary may be leveraging compromised AWS IoT devices to search their networks for other hosts and their running services, possibly to subsequently carry out lateral movement techniques: 'Destination IPs' ('aws:destination-ip-addresses') outside of expected IP address ranges may suggest that a device is communicating with unexpected devices. 'Bytes in' ('aws:all-bytes-in'), 'Bytes out' ('aws:all-bytes-out'), 'Packets in' ('aws:all-packets-in'), and 'Packets out' ('aws:all-packets-out') values outside of expected norms may indicate that the device is sending and/or receiving non-standard traffic, which may traffic used to discover other hosts/services. 'Listening TCP ports' ('aws:listening-tcp-ports'), 'Listening TCP port count' ('aws:num-listening-tcp-ports'), 'Established TCP connections count' ('aws:num-established-tcp-connections'), 'Listening UDP ports' ('aws:listening-udp-ports'), and 'Listening UDP port count' ('aws:num-listening-udp-ports') values outside of expected norms may indicate that devices are communicating via unexpected ports/protocols that may suggest scanning is taking place. Coverage factor is partial, since these metrics are limited to IoT device communication and detection is only based on network traffic, resulting in an overall score of Partial.","Category": "Detect","AWSService": "AWS IoT Device Defender"},{"Value": "Partial","Comment": "AWS Network Firewall has the ability to pass, drop, or alert on traffic based on the network protocol as well as perform deep packet inspection on the payload. This functionality can be used to restrict access to the endpoints within the virtual private cloud and protect against network service scanning. This mapping is given a score of Partial because it only protects against network service scanning attacks that originate from outside the firewall and not from within network protected by the firewall.","Category": "Protect","AWSService": "AWS Network Firewall"},{"Value": "Partial","Comment": "AWS WAF protects against bots that run scans against web applications such as Nessus (vulnerability assessments) and Nmap (IP address and port scans) among others. AWS WAF does this by blocking malicious traffic that indicate bad bots such as those listed above (e.g., via User-Agent values). AWS WAF uses the following rule sets to provide this protection. AWSManagedRulesCommonRuleSet AWSManagedRulesBotControlRuleSet. This is scored as Partial because the rule sets, while they block malicious traffic in near real-time, only protect web applications against scans performed by bots.","Category": "Protect","AWSService": "AWS Web Application Firewall"},{"Value": "Partial","Comment": "The following GuardDuty finding types reflect flagged events where there is an attempt to get a list of services running on a remote host. Recon:EC2/PortProbeEMRUnprotectedPort Recon:EC2/PortProbeUnprotectedPort Recon:EC2/Portscan Impact:EC2/PortSweep","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Partial","Comment": "The Amazon Inspector Network Reachability assessment package can assess whether or not cloud/network components are vulnerable (e.g., publicly accessible from the Internet). Amazon Inspector does not directly protect cloud/network components rather reports on vulnerabilities that it identifies which can then be used to securely configure the cloud/network components. Due to this, the score is capped at Partial.","Category": "Protect","AWSService": "Amazon Inspector"},{"Value": "Significant","Comment": "VPC security groups and network access control lists (NACLs) can filter both internal and external network traffic and therefore, can mitigate unauthorized network service scanning.","Category": "Protect","AWSService": "Amazon Virtual Private Cloud"}],"description": "Adversaries may attempt to get a listing of services running on remote hosts and local network infrastructure devices, including those that may be vulnerable to remote software exploitation. Common methods to acquire this information include port and/or vulnerability scans using tools that are brought onto a system.","checks_status": {"fail": 7,"pass": 16,"total": 23,"manual": 0}},"T1048": {"name": "Exfiltration Over Alternative Protocol","checks": {"guardduty_is_enabled": "PASS","networkfirewall_in_all_vpc": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Value": "Partial","Comment": "AWS Network Firewall has the ability to pass, drop, or alert on traffic based on the network protocol as well as perform deep packet inspection on the payload. This functionality can be used to block adversaries from accessing resources from which to exfiltrate data as well as prevent resources from communicating with known-bad IP addresses and domains that might be used to receive exfiltrated data. This mapping is given a score of Partial because the known-bad IP addresses and domains would need to be known in advance and AWS Network Firewall wouldn't have deep packet inspection visibility into encrypted non-C2 protocols.","Category": "Protect","AWSService": "AWS Network Firewall"},{"Value": "Partial","Comment": "The following GuardDuty finding type flags events where adversaries may steal data by exfiltrating it over a different protocol than that of the existing command-and-control channel. Trojan:EC2/DNSDataExfiltration Behavior:EC2/TrafficVolumeUnusual.","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Partial","Comment": "This control provides partial coverage for this technique and all of its sub-techniques, resulting in an overall score of Partial.","Category": "Detect","AWSService": "AWS IoT Device Defender"},{"Value": "Partial","Comment": "VPC security groups and network access control lists (NACLs) can limit access to external hosts and can therefore provide mitigation of this technique. For environments where Internet access is required, these controls can be used to block known malicious addresses. Because this latter protection is limited to known malicious endpoints, it provides Partial coverage resulting in an overall Partial score.","Category": "Protect","AWSService": "Amazon Virtual Private Cloud"}],"description": "Adversaries may steal data by exfiltrating it over a different protocol than that of the existing command and control channel. The data may also be sent to an alternate network location from the main command and control server.","checks_status": {"fail": 4,"pass": 16,"total": 20,"manual": 0}},"T1049": {"name": "System Network Connections Discovery","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may attempt to get a listing of network connections to or from the compromised system they are currently accessing or from remote systems by querying for information over the network.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1059": {"name": "Command and Scripting Interpreter","checks": {"elbv2_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Value": "Partial","Comment": "The AWS WAF protects web applications from injection attacks that leverage command and scripting interpreters. AWS WAF provides this protection via the following rule sets that block malicious traffic across a variety of operating systems and applications. AWSManagedRulesCommonRuleSet AWSManagedRulesSQLiRuleSet AWSManagedRulesUnixRuleSet AWSManagedRulesWindowsRuleSet AWSManagedRulesPHPRuleSet AWSManagedRulesWordPressRuleSet. This is given a score of Partial (instead of Minimal) because while it only protects against a subset of SubTechniques (3 out of 8), it does provide protections for command and scripting interpreters that do not have SubTechniques (SQL, PHP, etc.). Furthermore, it blocks the malicious content in near real-time.","Category": "Protect","AWSService": "AWS Web Application Firewall"}],"description": "Adversaries may abuse command and script interpreters to execute commands, scripts, or binaries. These interfaces and languages provide ways of interacting with computer systems and are a common feature across many different platforms. Most systems come with some built-in command-line interface and scripting capabilities, for example, macOS and Linux distributions include some flavor of Unix Shell while Windows installations include the Windows Command Shell and PowerShell.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"T1069": {"name": "Permission Groups Discovery","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may attempt to discover group and permission settings. This information can help adversaries determine which user accounts and groups are available, the membership of users in particular groups, and which users and groups have elevated permissions.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1074": {"name": "Data from Cloud Storage","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may stage collected data in a central location or directory prior to Exfiltration. Data may be kept in separate files or combined into one file through techniques such as Archive Collected Data. Interactive command shells may be used, and common functionality within cmd and bash may be used to copy data into a staging location.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1078": {"name": "Valid Accounts","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_avoid_root_usage": null,"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_hardware_mfa_enabled": null,"iam_user_console_access_unused": null,"iam_user_two_active_access_key": null,"iam_policy_no_full_access_to_kms": null,"iam_administrator_access_with_mfa": null,"config_recorder_all_regions_enabled": null,"iam_user_mfa_enabled_console_access": null,"iam_user_no_setup_initial_access_key": null,"organizations_scp_check_deny_regions": null,"iam_password_policy_minimum_length_14": null,"iam_policy_allows_privilege_escalation": null,"organizations_delegated_administrators": null,"iam_policy_no_full_access_to_cloudtrail": null,"iam_no_expired_server_certificates_stored": null,"organizations_account_part_of_organizations": null,"iam_role_cross_account_readonlyaccess_policy": null,"iam_inline_policy_no_administrative_privileges": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_role_cross_service_confused_deputy_prevention": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"iam_customer_unattached_policy_no_administrative_privileges": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Value": "Partial","Comment": "GuardDuty implements a finding that flags occurrences unattended behavior from an IAM User in the Account. PenTest:IAMUser/KaliLinux, PenTest:IAMUser/ParrotLinux, PenTest:IAMUser/PentooLinux, Policy:IAMUser/RootCredentialUsage, PrivilegeEscalation:IAMUser/AdministrativePermissions, UnauthorizedAccess:IAMUser/ConsoleLogin, UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B, UnauthorizedAccess:IAMUser/MaliciousIPCaller, UnauthorizedAccess:IAMUser/MaliciousIPCaller.Custom, UnauthorizedAccess:IAMUser/TorIPCaller, Policy:S3/AccountBlockPublicAccessDisabled, Policy:S3/BucketAnonymousAccessGranted, Policy:S3/BucketBlockPublicAccessDisabled, Policy:S3/BucketPublicAccessGranted, CredentialAccess:IAMUser/AnomalousBehavior, DefenseEvasion:IAMUser/AnomalousBehavior, Discovery:IAMUser/AnomalousBehavior, Exfiltration:IAMUser/AnomalousBehavior, Impact:IAMUser/AnomalousBehavior, Persistence:IAMUser/AnomalousBehavior, Recon:IAMUser/MaliciousIPCaller, Recon:IAMUser/MaliciousIPCaller.Custom, UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Minimal","Comment": "This control provides significant coverage for one of this technique's SubTechniques, resulting in an overall score of Minimal.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Partial","Comment": "This control provides detection capability for one of this technique's SubTechniques and some of its procedure examples resulting in an overall Partial protection score.","Category": "Detect","AWSService": "AWS IAM"},{"Value": "Partial","Comment": "This control provides protection capability for one of this technique's SubTechniques and some of its procedure examples resulting in an overall Partial protection score.","Category": "Protect","AWSService": "AWS IAM"},{"Value": "Partial","Comment": "This control provides protection capability for one of this technique's SubTechniques and some of its procedure examples resulting in an overall Partial protection score.","Category": "Protect","AWSService": "AWS Single Sign-On"},{"Value": "Minimal","Comment": "This control provides partial detection capability for one of this technique's SubTechniques and a few of its procedure examples resulting in an overall Minimal protection score.","Category": "Detect","AWSService": "AWS IoT Device Defender"},{"Value": "Minimal","Comment": "This control provides partial protection for one of this technique's SubTechniques and a few of its procedure examples resulting in an overall Minimal protection score.","Category": "Protect","AWSService": "AWS IoT Device Defender"},{"Value": "Partial","Comment": "This control may protect against malicious use of cloud accounts but may not mitigate exploitation of local, domain, or default accounts present within deployed resources.","Category": "Protect","AWSService": "AWS Organizations"},{"Value": "Minimal","Comment": "AWS Security Hub detects suspicious activity by AWS accounts which could indicate valid accounts being leveraged by an adversary. AWS Security Hub provides these detections with the following managed insights. AWS principals with suspicious access key activity Credentials that may have leaked AWS resources with unauthorized access attempts IAM users with suspicious activity. AWS Security Hub also performs checks from the AWS Foundations CIS Benchmark and PCI-DSS security standard that, if implemented, would help towards detecting the misuse of valid accounts. AWS Security Hub provides these detections with the following checks. 3.1 Ensure a log metric filter and alarm exist for unauthorized API calls 3.2 Ensure a log metric filter and alarm exist for Management Console sign-in without MFA 3.3 Ensure a log metric filter and alarm exist for usage of root account 3.4 Ensure a log metric filter and alarm exist for IAM policy changes 3.6 Ensure a log metric filter and alarm exist for AWS Management Console authentication failures [PCI.CW.1] A log metric filter and alarm should exist for usage of the root user. By monitoring the root account, activity where accounts make unauthorized API calls, and changes to IAM permissions among other things, it may be possible to detect valid accounts that are being misused and are potentially compromised. This is scored as Minimal because it only supports a subset of the SubTechniques (1 of 4).","Category": "Detect","AWSService": "AWS Security Hub"},{"Value": "Minimal","Comment": "This control provides partial protection for one of this technique's SubTechniques and a few of its procedure examples resulting in an overall Minimal protection score.","Category": "Protect","AWSService": "Amazon Cognito"}],"description": "Adversaries may obtain and abuse credentials of existing accounts as a means of gaining Initial Access, Persistence, Privilege Escalation, or Defense Evasion. Compromised credentials may be used to bypass access controls placed on various resources on systems within the network and may even be used for persistent access to remote systems and externally available services, such as VPNs, Outlook Web Access, network devices, and remote desktop.[1] Compromised credentials may also grant an adversary increased privilege to specific systems or access to restricted areas of the network. Adversaries may choose not to use malware or tools in conjunction with the legitimate access those credentials provide to make it harder to detect their presence.","checks_status": {"fail": 0,"pass": 2,"total": 36,"manual": 0}},"T1082": {"name": "System Information Discovery","checks": {},"status": "PASS","attributes": [],"description": "An adversary may attempt to get detailed information about the operating system and hardware, including version, patches, hotfixes, service packs, and architecture. Adversaries may use the information from System Information Discovery during automated discovery to shape follow-on behaviors, including whether or not the adversary fully infects the target and/or attempts specific actions.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1087": {"name": "Account Discovery","checks": {"organizations_account_part_of_organizations": null},"status": "PASS","attributes": [{"Value": "Minimal","Comment": "This control may protect against cloud account discovery but does not mitigate against other forms of account discovery.","Category": "Protect","AWSService": "AWS Organizations"}],"description": "Adversaries may attempt to get a listing of valid accounts, usernames, or email addresses on a system or within a compromised environment. This information can help adversaries determine which accounts exist, which can aid in follow-on behavior such as brute-forcing, spear-phishing attacks, or account takeovers (e.g., Valid Accounts).","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"T1098": {"name": "Account Manipulation","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_avoid_root_usage": null,"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_hardware_mfa_enabled": null,"iam_policy_no_full_access_to_kms": null,"iam_administrator_access_with_mfa": null,"config_recorder_all_regions_enabled": null,"iam_user_mfa_enabled_console_access": null,"iam_policy_allows_privilege_escalation": null,"iam_policy_no_full_access_to_cloudtrail": null,"iam_inline_policy_no_administrative_privileges": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Value": "Minimal","Comment": "This control provides significant coverage for one of this technique's SubTechniques, resulting in an overall score of Minimal.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Minimal","Comment": "This control may generate logs for creation and manipulation of accounts but the relevant security information would be handled by another security control.","Category": "Detect","AWSService": "AWS IAM"},{"Value": "Minimal","Comment": "AWS Security Hub performs a check from the AWS Foundations CIS Benchmark that, if implemented, would help towards detecting the manipulation of accounts. AWS Security Hub provides this detection with the following check. 3.4 Ensure a log metric filter and alarm exist for IAM policy changes. This is scored as Minimal because it only supports a subset of the SubTechniques (1 of 4).","Category": "Detect","AWSService": "AWS Security Hub"},{"Value": "Partial","Comment": "GuardDuty has a finding types that flag events where an adversary may have compromised an AWS IAM User. Finding Type: Persistence:IAMUser/AnomalousBehavior.","Category": "Detect","AWSService": "Amazon GuardDuty"}],"description": "Adversaries may manipulate accounts to maintain access to victim systems. Account manipulation may consist of any action that preserves adversary access to a compromised account, such as modifying credentials or permission groups. These actions could also include account activity designed to subvert security policies, such as performing iterative password updates to bypass password duration policies and preserve the life of compromised credentials.","checks_status": {"fail": 0,"pass": 2,"total": 16,"manual": 0}},"T1110": {"name": "Brute Force","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_root_mfa_enabled": null,"inspector2_is_enabled": "FAIL","iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_hardware_mfa_enabled": null,"iam_user_console_access_unused": null,"inspector2_active_findings_exist": "FAIL","config_recorder_all_regions_enabled": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "This control provides significant coverage for all of this technique's sub-techniques, resulting in an overall score of Significant.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Significant","Comment": "This control provides significant coverage for all of this technique's sub-techniques, resulting in an overall score of Significant.","Category": "Protect","AWSService": "AWS IAM"},{"Value": "Partial","Comment": "This control may not provide any mitigation against password cracking.","Category": "Protect","AWSService": "AWS Single Sign-On"},{"Value": "Significant","Comment": "Amazon Cognito's MFA capability provides significant protection against password compromises, requiring the adversary to complete an additional authentication method before their access is permitted.","Category": "Protect","AWSService": "Amazon Cognito"},{"Value": "Minimal","Comment": "AWS Security Hub performs a check from the AWS Foundations CIS Benchmark that, if implemented, would help towards detecting the brute forcing of accounts. AWS Security Hub provides this detection with the following checks. 3.6 Ensure a log metric filter and alarm exist for AWS Management Console authentication failures. This is scored as Minimal because it only applies to the AWS Management Console and not other access mechanisms (e.g., CLI, SDK, etc.) and it only supports a subset of the sub-techniques (3 of 4). Furthermore, it does not detect brute-forcing methods for other components such as EC2 instances.","Category": "Detect","AWSService": "AWS Security Hub"},{"Value": "Minimal","Comment": "Finding types such as UnauthorizedAccess:EC2/RDPBruteForce, UnauthorizedAccess:EC2/SSHBruteForce, Impact:EC2/WinRMBruteForce, and Stealth:IAMUser/PasswordPolicyChange can detect when an EC2 instance may be involved in a brute force attack aimed at obtaining passwords. Due to the detection being limited to a specific set of application protocols, its coverage is Minimal resulting in a Minimal score.","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Minimal","Comment": "The Amazon Inspector Best Practices assessment package can detect security control settings related to authentication and password policies on Linux endpoints. Specific security controls it can assess include 'Disable password authentication over SSH', 'Configure password maximum age', 'Configure password minimum length', and 'Configure password complexity' all of which impact the ability to brute force a password. This information can be used identify insecure configurations and harden the endpoints. Amazon Inspector does not directly protect against brute force attacks. Given Amazon Inspector can only assess these security controls on Linux platforms (although it also supports Windows), the coverage score is Minimal leading to an overall Minimal score.","Category": "Protect","AWSService": "Amazon Inspector"}],"description": "Adversaries may use brute force techniques to gain access to accounts when passwords are unknown or when password hashes are obtained. Without knowledge of the password for an account or set of accounts, an adversary may systematically guess the password using a repetitive or iterative mechanism. Brute forcing passwords can take place via interaction with a service that will check the validity of those credentials or offline against previously acquired credential data, such as password hashes.","checks_status": {"fail": 2,"pass": 2,"total": 19,"manual": 0}},"T1119": {"name": "Automated Collection","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","ec2_ebs_snapshots_encrypted": "FAIL","s3_bucket_default_encryption": "PASS","rds_instance_storage_encrypted": "FAIL","config_recorder_all_regions_enabled": null},"status": "FAIL","attributes": [{"Value": "Minimal","Comment": "The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure that storage volumes are encrypted, which may mitigate adversary attempts to automate collection within cloud environments: 'ec2-ebs-encryption-by-default' which is run periodically and 'encrypted-volumes' which is run on configuration changes. Coverage factor is minimal for these rules, since they are specific to EBS volumes and will only prevent certain forms of collection since adversaries with access to mounted volumes may be able to decrypt their contents, resulting in an overall score of Minimal.","Category": "Protect","AWSService": "AWS Config"}],"description": "Once established within a system or network, an adversary may use automated techniques for collecting internal data. Methods for performing this technique could include use of a Command and Scripting Interpreter to search for and copy information fitting set criteria such as file type, location, or name at specific time intervals. In cloud-based environments, adversaries may also use cloud APIs, command line interfaces, or extract, transform, and load (ETL) services to automatically collect data. This functionality could also be built into remote access tools.","checks_status": {"fail": 2,"pass": 3,"total": 6,"manual": 0}},"T1136": {"name": "Create Account","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Value": "Minimal","Comment": "This control provides partial coverage for one of this technique's SubTechniques, resulting in an overall score of Minimal.","Category": "Protect","AWSService": "AWS Config"}],"description": "Adversaries may create an account to maintain access to victim systems. With a sufficient level of access, creating such accounts may be used to establish secondary credentialed access that do not require persistent remote access tools to be deployed on the system.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"T1190": {"name": "Exploit Public-Facing Application","checks": {"drs_job_exist": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","rds_instance_backup_enabled": "PASS","inspector2_active_findings_exist": "FAIL","config_recorder_all_regions_enabled": null,"awslambda_function_not_publicly_accessible": "PASS","rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "AWS CloudEndure Disaster Recovery enables the replication and recovery of servers into AWS Cloud. In the event that a public-facing application or server is compromised, AWS CloudEndure can be used to provision an instance of the server from a previous point in time within minutes. As a result, this mapping is given a score of Significant.","Category": "Respond","AWSService": "AWS CloudEndure Disaster Recovery"},{"Value": "Partial","Comment": "The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure that applications intended for internal use cannot be accessed externally for exploitation: 'api-gw-endpoint-type-check' can ensure that Amazon API Gateway APIs are private and can only be accessed from within VPCs, 'elasticsearch-in-vpc-only' can ensure that Amazon ElasticSearch Service (Amazon ES) domains are in the same VPC and the domain endpoint is not public, 'lambda-function-public-access-prohibited' can verify that AWS Lambda functions are not publicly available, and 'ec2-instance-no-public-ip' can verify whether EC2 instances have public IP addresses. The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure that insecure applications are not installed and installed packages are kept updated, reducing the likelihood of adversary exploitation: the 'ec2-managedinstance-applications-blacklisted' managed rule verifies that a pre-defined list of applications are not installed on specified managed instances. It can be used to identify the presence of vulnerable applications (prompting removal before they can be exploited) and/or to identify the presence of allowed packages below a minimum version (prompting updates before they can be exploited). The 'ec2-managedinstance-platform-check' managed rule verifies that managed instances are running desired platform types, including using a desired version (as opposed to an out-of-date one). Both can reduce instances' attack surface for adversary exploitation. 'rds-automatic-minor-version-upgrade-enabled' can verify that Amazon RDS is being patched, and 'elastic-beanstalk-managed-updates-enabled' can verify that Elastic Beanstalk is being patched. Coverage factor is partial for these rules, since they are specific to a subset of the available AWS services that can be used to host public-facing applications and will only protect against certain forms of identifiable exploitation, resulting in an overall score of Partial.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Partial","Comment": "AWS RDS supports the automatic patching of minor versions of database instances. This can result in security flaws in the database instances being fixed before they can be exploited. This mapping is given a score of Partial because it does not protect against misconfigured database instances which may be susceptible to exploitation.","Category": "Protect","AWSService": "AWS RDS"},{"Value": "Significant","Comment": "AWS RDS supports the replication and recovery of database instances. In the event that a database instance is compromised, AWS RDS can be used to restore the database instance to a previous point in time. As a result, this mapping is given a score of Significant.","Category": "Respond","AWSService": "AWS RDS"},{"Value": "Minimal","Comment": "There is a GuardDuty finding type that captures when vulnerable publicly facing resources are leveraged to capture data not intended to be viewable (e.g., IAM credentials associated with the resource). UnauthorizedAccess:EC2/MetadataDNSRebind - This finding type only detects MetadataDNSRebind and is more focused on the EC2 instance and not the application running on the instance itself resulting in Minimal coverage.","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Partial","Comment": "AWS Security Hub reports on EC2 instances that are missing security patches for vulnerabilities which could enable an adversary to exploit vulnerabilities through the attack lifecycle. AWS Security Hub provides this detection with the following managed insight. EC2 instances that have missing security patches for important vulnerabilities. This is scored as Partial because the checks associated with Security Hub would only report on missing patches for known vulnerabilities. It doesn't not cover zero-day vulnerabilities.","Category": "Detect","AWSService": "AWS Security Hub"},{"Value": "Significant","Comment": "The AWS WAF protects public-facing applications against a range of vulnerabilities including those listed in the OWASP Top 10. AWS WAF provides this protection via the following rule sets that block malicious traffic across a variety of operating systems and applications. AWSManagedRulesCommonRuleSet AWSManagedRulesKnownBadInputRuleSet AWSManagedRulesSQLiRuleSet AWSManagedRulesLinuxRuleSet AWSManagedRulesUnixRuleSet AWSManagedRulesWindowsRuleSet AWSManagedRulesPHPRuleSet AWSManagedRulesWordPressRuleSet. This is given a score of Significant because it protects against vulnerabilities across multiple operating systems (Windows, Linux, POSIX) and technologies (JavaScript, SQL, PHP, WordPress). Furthermore, it blocks the malicious content in near real-time.","Category": "Protect","AWSService": "AWS Web Application Firewall"},{"Value": "Partial","Comment": "Amazon Inspector can detect known vulnerabilities on various Windows and Linux endpoints. Furthermore, the Amazon Inspector Best Practices assessment package can assess security controls for 'Enable Address Space Layout Randomization (ASLR)' and 'Enable Data Execution Prevention (DEP)' that makes it more difficult for an attacker to exploit vulnerabilities in software. This information can be used to patch, isolate, and remove vulnerable software and endpoints. Amazon Inspector does not directly protect against exploitation and it is not effective against zero-day attacks, vulnerabilities with no available patch, and software that may not be analyzed by the scanner. As a result, the score is capped at Partial.","Category": "Protect","AWSService": "Amazon Inspector"}],"description": "Adversaries may attempt to exploit a weakness in an Internet-facing host or system to initially access a network. The weakness in the system can be a software bug, a temporary glitch, or a misconfiguration.","checks_status": {"fail": 5,"pass": 5,"total": 11,"manual": 0}},"T1199": {"name": "Trusted Relationship","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Value": "Partial","Comment": "VPC network access control lists (NACLs) can isolate portions of the network that do not require network-wide access, limiting some attackers that leverage trusted relationships such as remote access for vendor maintenance. Coverage partial, Temporal Immediate.","Category": "Protect","AWSService": "Amazon Virtual Private Cloud"}],"description": "Adversaries may breach or otherwise leverage organizations who have access to intended victims. Access through trusted third party relationship abuses an existing connection that may not be protected or receives less scrutiny than standard mechanisms of gaining access to a network.","checks_status": {"fail": 3,"pass": 15,"total": 18,"manual": 0}},"T1201": {"name": "Password Policy Discovery","checks": {"iam_policy_allows_privilege_escalation": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Value": "Significant","Comment": "Ensure least privilege in IAM since password policies can be discovered in cloud environments using available APIs such as GetAccountPasswordPolicy in AWS.","Category": "Protect","AWSService": "AWS IAM"}],"description": "Adversaries may attempt to access detailed information about the password policy used within an enterprise network or cloud environment. Password policies are a way to enforce complex passwords that are difficult to guess or crack through Brute Force. This information may help the adversary to create a list of common passwords and launch dictionary and/or brute force attacks which adheres to the policy (e.g. if the minimum password length should be 8, then not trying passwords such as 'pass123'; not checking for more than 3-4 passwords per account if the lockout is set to 6 as to not lock out accounts).","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"T1204": {"name": "User Execution","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Value": "Minimal","Comment": "This control provides significant coverage for one of this technique's SubTechniques, resulting in an overall score of Minimal.","Category": "Detect","AWSService": "AWS Config"}],"description": "An adversary may rely upon specific actions by a user in order to gain execution. Users may be subjected to social engineering to get them to execute malicious code by, for example, opening a malicious document file or link. These user actions will typically be observed as follow-on behavior from forms of Phishing.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"T1213": {"name": "Data from Information Repositories","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may leverage information repositories to mine valuable information. Information repositories are tools that allow for storage of information, typically to facilitate collaboration or information sharing between users, and can store a wide variety of data that may aid adversaries in further objectives, or direct access to the target information. Adversaries may also abuse external sharing features to share sensitive documents with recipients outside of the organization.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1485": {"name": "Data Destruction","checks": {"drs_job_exist": "FAIL","backup_plans_exist": "PASS","s3_bucket_object_lock": "FAIL","efs_have_backup_enabled": "FAIL","s3_bucket_no_mfa_delete": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL","config_recorder_all_regions_enabled": null,"s3_bucket_policy_public_write_access": "PASS","cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "AWS CloudEndure Disaster Recovery enables the replication and recovery of servers into AWS Cloud. In the event that data on servers is destroyed, AWS CloudEndure can be used to provision an instance of the server from a previous point in time within minutes. As a result, this mapping is given a score of Significant.","Category": "Respond","AWSService": "AWS CloudEndure Disaster Recovery"},{"Value": "Partial","Comment": "The following AWS Config managed rules can identify configuration problems that should be fixed in order to prevent malicious write access to data within Amazon Simple Storage Service (S3) storage, which may include data destruction: 's3-bucket-blacklisted-actions-prohibited' checks whether bucket policies prohibit disallowed actions (including S3:DeleteObject) for principals from other AWS accounts, 's3-bucket-default-lock-enabled' checks whether a bucket that should be locked in write-once-read-many (WORM) mode is configured to prevent modification, and 's3-bucket-public-write-prohibited' checks whether a bucket is configured to allow public access and modification. All of these controls are run on configuration changes. The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure backups and redundancy are in place which can mitigate the effects of data destruction: 'aurora-mysql-backtracking-enabled' for data in Aurora MySQL; 'db-instance-backup-enabled' and 'rds-in-backup-plan' for Amazon Relational Database Service (RDS) data; 'dynamodb-in-backup-plan' and 'dynamodb-pitr-enabled' for Amazon DynamoDB table contents; 'ebs-in-backup-plan' for Elastic Block Store (EBS) volumes; 'efs-in-backup-plan' for Amazon Elastic File System (EFS) file systems; 'elasticache-redis-cluster-automatic-backup-check' for Amazon ElastiCache Redis cluster data; 'redshift-backup-enabled' and 'redshift-cluster-maintenancesettings-check' for Redshift; 's3-bucket-replication-enabled' and 's3-bucket-versioning-enabled' for S3 storage; and 'cloudfront-origin-failover-enabled' for CloudFront. The following AWS Config managed rules provide specific detections for configuration problems that should be fixed in order to prevent malicious deletion of specific data: 'elb-deletion-protection-enabled' for Elastic Block Store (EBS) volumes, and 'rds-cluster-deletion-protection-enabled' and 'rds-instance-deletion-protection-enabled' for RDS data. Coverage factor is partial for these rules, since they are specific to a subset of the available AWS services and will only protect certain types of data against destruction, resulting in an overall score of Partial.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Partial","Comment": "AWS RDS generates events for database instances and includes the following events that may indicate that an adversary has destroyed the database instance. RDS-EVENT-0003: The DB instance has been deleted RDS-EVENT-0041: A DB snapshot has been deleted. This mapping is given a score of Partial because it can't differentiate between an authorized and unauthorized deletion.","Category": "Detect","AWSService": "AWS RDS"},{"Value": "Significant","Comment": "AWS RDS provides deletion protection which prevents any user from deleting a database instance. If applied, the setting may mitigate attempts to delete a database instance. As a result, this mapping is given a score of Significant.","Category": "Protect","AWSService": "AWS RDS"},{"Value": "Significant","Comment": "AWS RDS supports the replication and recovery of database instances. In the event that a database instance is deleted, AWS RDS can be used to restore the database instance to a previous point in time. As a result, this mapping is given a score of Significant.","Category": "Respond","AWSService": "AWS RDS"},{"Value": "Significant","Comment": "AWS S3 may protect against data destruction through application of several best practices. Multi-factor authentication can be enabled for delete operations and for changing the versioning state of a bucket. Versioning can be enabled to revert objects to a previous state after malicious destruction or corruption. S3 Object Lock can help prevent objects from being deleted or overwritten for a fixed amount of time or indefinitely. In addition, S3 Cross Region Replication can be used to replicate S3 buckets to another AWS region for add protection.","Category": "Protect","AWSService": "AWS S3"},{"Value": "Minimal","Comment": "AWS Security Hub performs a check from the AWS Foundations CIS Benchmark that, if implemented, would help towards detecting the scheduled destruction of Customer Master Keys (CMKs) which are critical for being able to decrypt data. AWS Security Hub provides this detection with the following check. Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs. This is scored as Minimal because CMKs only represent one type of data that could be destroyed by an adversary.","Category": "Detect","AWSService": "AWS Security Hub"},{"Value": "Partial","Comment": "The following GuardDuty finding type flags events where adversaries may destroy data and files on specific systems or in large numbers on a network to interrupt availability to systems, services, and network resources. Impact:S3/MaliciousIPCaller, Impact:IAMUser/AnomalousBehavior Stealth:S3/ServerAccessLoggingDisabled UnauthorizedAccess:S3/MaliciousIPCaller.Custom UnauthorizedAccess:S3/TorIPCaller PenTest:S3/PentooLinux PenTest:S3/ParrotLinux PenTest:S3/KaliLinux.","Category": "Detect","AWSService": "Amazon GuardDuty"}],"description": "Adversaries may destroy data and files on specific systems or in large numbers on a network to interrupt availability to systems, services, and network resources. Data destruction is likely to render stored data irrecoverable by forensic techniques through overwriting files or data on local and remote drives.[1][2][3][4][5][6] Common operating system file deletion commands such as del and rm often only remove pointers to files without wiping the contents of the files themselves, making the files recoverable by proper forensic methodology. This behavior is distinct from Disk Content Wipe and Disk Structure Wipe because individual files are destroyed rather than sections of a storage disk or the disk's logical structure.","checks_status": {"fail": 6,"pass": 3,"total": 12,"manual": 0}},"T1486": {"name": "Data Encrypted for Impact","checks": {"drs_job_exist": "FAIL","backup_plans_exist": "PASS","s3_bucket_object_lock": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"config_recorder_all_regions_enabled": null,"s3_bucket_policy_public_write_access": "PASS"},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "AWS CloudEndure Disaster Recovery enables the replication and recovery of servers into AWS Cloud. In the event that data on servers is destroyed, AWS CloudEndure can be used to provision an instance of the server from a previous point in time within minutes. As a result, this mapping is given a score of Significant.","Category": "Respond","AWSService": "AWS CloudEndure Disaster Recovery"},{"Value": "Partial","Comment": "The following AWS Config managed rules can identify configuration problems that should be fixed in order to prevent malicious changes to data encryption within Amazon Simple Storage Service (S3) storage: 's3-bucket-blacklisted-actions-prohibited' checks whether bucket policies prohibit disallowed actions (including encryption configuration changes) for principals from other AWS accounts, 's3-bucket-default-lock-enabled' checks whether a bucket that should be locked in write-once-read-many (WORM) mode is configured to prevent modification, and 's3-bucket-public-write-prohibited' checks whether a bucket is configured to allow public access and modification. All of these controls are run on configuration changes. The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure backups and redundancy are in place which can mitigate the effects of malicious changes to data encryption: 'aurora-mysql-backtracking-enabled' for data in Aurora MySQL; 'db-instance-backup-enabled' and 'rds-in-backup-plan' for Amazon Relational Database Service (RDS) data; 'dynamodb-in-backup-plan' and 'dynamodb-pitr-enabled' for Amazon DynamoDB table contents; 'ebs-in-backup-plan' for Elastic Block Store (EBS) volumes; 'efs-in-backup-plan' for Amazon Elastic File System (EFS) file systems; 'elasticache-redis-cluster-automatic-backup-check' for Amazon ElastiCache Redis cluster data; 'redshift-backup-enabled' and 'redshift-cluster-maintenancesettings-check' for Redshift; 's3-bucket-replication-enabled' and 's3-bucket-versioning-enabled' for S3 storage; and 'cloudfront-origin-failover-enabled' for CloudFront. Coverage factor is partial for these rules, since they are specific to a subset of the available AWS services and will only protect certain types of data against malicious encryption changes, resulting in an overall score of Partial.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Significant","Comment": "AWS RDS supports the replication and recovery of database instances. In the event that a database instance is encrypted by an adversary (e.g., ransomware), AWS RDS can be used to restore the database instance to a previous point in time. As a result, this mapping is given a score of Significant.","Category": "Respond","AWSService": "AWS RDS"},{"Value": "Partial","Comment": "The following GuardDuty finding type flags events where adversaries may encrypt data on target systems or on large numbers of systems in a network to interrupt availability to system and network resources. Impact:S3/MaliciousIPCaller Stealth:S3/ServerAccessLoggingDisabled UnauthorizedAccess:S3/MaliciousIPCaller.Custom UnauthorizedAccess:S3/TorIPCaller PenTest:S3/PentooLinux PenTest:S3/ParrotLinux PenTest:S3/KaliLinux","Category": "Detect","AWSService": "Amazon GuardDuty"}],"description": "Adversaries may encrypt data on target systems or on large numbers of systems in a network to interrupt availability to system and network resources. They can attempt to render stored data inaccessible by encrypting files or data on local and remote drives and withholding access to a decryption key. This may be done in order to extract monetary compensation from a victim in exchange for decryption or a decryption key (ransomware) or to render data permanently inaccessible in cases where the key is not saved or transmitted.","checks_status": {"fail": 4,"pass": 3,"total": 9,"manual": 0}},"T1490": {"name": "Inhibit System Recovery","checks": {"drs_job_exist": "FAIL","rds_instance_backup_enabled": "PASS"},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "AWS CloudEndure Disaster Recovery enables the replication and recovery of servers into AWS Cloud. In the event that servers are defaced, AWS CloudEndure can be used to provision an instance of the server from a previous point in time within minutes. This mapping is given a score of Significant because it supports all of the sub-techniques (2 of 2).","Category": "Respond","AWSService": "AWS CloudEndure Disaster Recovery"},{"Value": "Partial","Comment": "AWS RDS generates events for database instances and includes the following event that may indicate that an adversary has attempted to inhibit system recovery. RDS-EVENT-0028: Automatic backups for this DB instance have been disabled. This mapping is given a score of Partial because it can't differentiate between an authorized and unauthorized disabling of automatic backups.","Category": "Detect","AWSService": "AWS RDS"},{"Value": "Significant","Comment": "AWS RDS supports the replication and recovery of database instances. In the event that a database instance is compromised and modified to disrupt recovery, AWS RDS can be used to restore the database instance to a previous point in time. As a result, this mapping is given a score of Significant.","Category": "Respond","AWSService": "AWS RDS"}],"description": "Adversaries may delete or remove built-in data and turn off services designed to aid in the recovery of a corrupted system to prevent recovery.[1][2] This may deny access to available backups and recovery options.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"T1491": {"name": "Defacement","checks": {"drs_job_exist": "FAIL","config_recorder_all_regions_enabled": null},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "AWS CloudEndure Disaster Recovery enables the replication and recovery of servers into AWS Cloud. In the event that servers are defaced, AWS CloudEndure can be used to provision an instance of the server from a previous point in time within minutes. This mapping is given a score of Significant because it supports all of the sub-techniques (2 of 2).","Category": "Respond","AWSService": "AWS CloudEndure Disaster Recovery"},{"Value": "Significant","Comment": "This control provides significant coverage for all of this technique's sub-techniques, resulting in an overall score of Significant.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Partial","Comment": "GuardDuty provides multiple finding types that flag malicious activity against resources. These findings focus on API calls that look suspicious and although they do not flag events such as Defacement specifically, it can be inferred that these findings can result in mitigating this technique's negative impact. With this assumption the score is capped at Partial.","Category": "Detect","AWSService": "Amazon GuardDuty"}],"description": "Adversaries may modify visual content available internally or externally to an enterprise network, thus affecting the integrity of the original content. Reasons for Defacement include delivering messaging, intimidation, or claiming (possibly false) credit for an intrusion. Disturbing or offensive images may be used as a part of Defacement in order to cause user discomfort, or to pressure compliance with accompanying messages.","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"T1496": {"name": "Resource Hijacking","checks": {"guardduty_is_enabled": "PASS","config_recorder_all_regions_enabled": null,"cloudwatch_log_metric_filter_root_usage": null,"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Value": "Partial","Comment": "AWS CloudWatch provides various metrics including CPU utilization, connections, disk space, memory, bytes sent/received, and the number of running containers among others. The following metrics (not an exhaustive list) could be used to detect if the usage of a resource has increased such as when an adversary hijacks a resource to perform intensive tasks. Linux/Mac OS ------------- cpu_time_active cpu_time_guest cpu_usage_active cpu_usage_guest disk_free disk_total disk_used ethtool_bw_in_allowance_exceeded ethtool_bw_out_allowance_exceeded ethtool_conntrack_allowance_exceeded mem_active mem_available_percent mem_free net_bytes_recv net_bytes_sent net_packets_sent net_packets_recv netstat_tcp_established netstat_tcp_listen processes_running processes_total swap_free swap_used. Containers ---------- CpuUtilized MemoryUtilized NetworkRxBytes NetworkTxBytes node_cpu_usage_total node_cpu_utilization node_filesystem_utilization node_memory_utilization. This mapping is given a score of Partial because it is not possible to differentiate between an authorized and unauthorized increase in resource utilization.","Category": "Detect","AWSService": "AWS CloudWatch"},{"Value": "Partial","Comment": "The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure alarms exist for spikes in resource utilization, which help to identify malicious use of resources within a cloud environment: 'cloudwatch-alarm-action-check', 'cloudwatch-alarm-resource-check', 'cloudwatch-alarm-settings-check', 'desired-instance-tenancy', 'desired-instance-type', 'dynamodb-autoscaling-enabled', 'dynamodb-throughput-limit-check', 'ec2-instance-detailed-monitoring-enabled', and 'rds-enhanced-monitoring-enabled'. Coverage factor is partial for these rules, since they are specific to a subset of the available AWS services and will only detect resource hijacking that results in a change in utilization that is significant enough to trigger alarms, resulting in an overall score of Partial.","Category": "Detect","AWSService": "AWS Config"},{"Value": "Partial","Comment": "The following AWS IoT Device Defender device-side detection metrics can detect indicators that an adversary may be leveraging compromised AWS IoT devices' resources to perform resource-intensive operations like mining cryptocurrency or performing denial of service attacks on other environments: 'Destination IPs' ('aws:destination-ip-addresses') outside of expected IP address ranges may suggest that a device is communicating with unexpected parties. 'Bytes in' ('aws:all-bytes-in'), 'Bytes out' ('aws:all-bytes-out'), 'Packets in' ('aws:all-packets-in'), and 'Packets out' ('aws:all-packets-out') values outside of expected norms may indicate that the device is sending and/or receiving non-standard traffic, which may include traffic related to resource hijacking activities. 'Listening TCP ports' ('aws:listening-tcp-ports'), 'Listening TCP port count' ('aws:num-listening-tcp-ports'), 'Established TCP connections count' ('aws:num-established-tcp-connections'), 'Listening UDP ports' ('aws:listening-udp-ports'), and 'Listening UDP port count' ('aws:num-listening-udp-ports') values outside of expected norms may indicate that devices are communicating via unexpected ports/protocols which may include traffic related to resource hijacking activities. Coverage factor is partial, since these metrics are limited to IoT device hijacking, resulting in an overall score of Partial.","Category": "Detect","AWSService": "AWS IoT Device Defender"},{"Value": "Partial","Comment": "The following GuardDuty finding types flag events where adversaries may leverage the resources of co-opted systems in order to solve resource intensive problems which may impact system and/or hosted service availability. CryptoCurrency:EC2/BitcoinTool.B CryptoCurrency:EC2/BitcoinTool.B!DNS Impact:EC2/BitcoinDomainRequest.Reputation UnauthorizedAccess:EC2/TorRelay","Category": "Detect","AWSService": "Amazon GuardDuty"}],"description": "Adversaries may leverage the resources of co-opted systems in order to solve resource intensive problems, which may impact system and/or hosted service availability.","checks_status": {"fail": 1,"pass": 1,"total": 18,"manual": 0}},"T1498": {"name": "Network Denial of Service","checks": {"guardduty_is_enabled": "PASS","networkfirewall_in_all_vpc": "FAIL","config_recorder_all_regions_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","shield_advanced_protection_in_global_accelerators": null,"shield_advanced_protection_in_route53_hosted_zones": null,"shield_advanced_protection_in_associated_elastic_ips": null,"shield_advanced_protection_in_classic_load_balancers": null,"shield_advanced_protection_in_cloudfront_distributions": null,"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","shield_advanced_protection_in_internet_facing_load_balancers": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Value": "Minimal","Comment": "This control provides minimal coverage for this technique's sub-techniques as well as its procedures, resulting in an overall score of Minimal.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Minimal","Comment": "AWS Network Firewall has the ability to pass, drop, or alert on traffic based on the network protocol as well as perform deep packet inspection on the payload. This functionality can be used to block the sources of smaller-scale network denial of service attacks. While AWS Network Firewall supports both all sub-techniques (2 of 2), this mapping is given a score of Minimal because often times it is necessary to block the traffic at an Internet Service Provider or Content Provider Network level.","Category": "Protect","AWSService": "AWS Network Firewall"},{"Value": "Significant","Comment": "AWS Shield is a service that protects against Distributed Denial of Service attacks. There are two tiers for this service Standard and Advanced. AWS Shield Standard defends against most common, frequently occurring network and transport (Layer 3 and 4 attacks) layer DDoS attacks that target your web site or applications. AWS Shield Advanced adds on to standard by providing additional detection and mitigation against large and sophisticated DDoS attacks. There is near real-time visibility into attacks. AWS Shield Advanced also comes with 24x7 access to the AWS DDoS Response Team (DRT).","Category": "Respond","AWSService": "AWS Shield"},{"Value": "Partial","Comment": "The following finding types in GuardDuty flag events where adversaries may perform Network Denial of Service (DoS) attacks to degrade or block the availability of targeted resources to users. Backdoor:EC2/DenialOfService.UdpOnTcpPorts Backdoor:EC2/DenialOfService.UnusualProtocol Backdoor:EC2/DenialOfService.Udp Backdoor:EC2/DenialOfService.Tcp Backdoor:EC2/DenialOfService.Dns","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Minimal","Comment": "VPC security groups and network access control lists (NACLs) can be used to restrict access to endpoints but will prove effective at mitigating only low-end DOS attacks resulting in a Minimal score.","Category": "Protect","AWSService": "Amazon Virtual Private Cloud"}],"description": "Adversaries may perform Network Denial of Service (DoS) attacks to degrade or block the availability of targeted resources to users. Network DoS can be performed by exhausting the network bandwidth services rely on. Example resources include specific websites, email services, DNS, and web-based applications. Adversaries have been observed conducting network DoS attacks for political purposes[1] and to support other malicious activities, including distraction[2], hacktivism, and extortion.","checks_status": {"fail": 4,"pass": 16,"total": 27,"manual": 0}},"T1499": {"name": "Endpoint Denial of Service","checks": {"networkfirewall_in_all_vpc": "FAIL","config_recorder_all_regions_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","shield_advanced_protection_in_global_accelerators": null,"shield_advanced_protection_in_route53_hosted_zones": null,"shield_advanced_protection_in_associated_elastic_ips": null,"shield_advanced_protection_in_classic_load_balancers": null,"shield_advanced_protection_in_cloudfront_distributions": null,"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","shield_advanced_protection_in_internet_facing_load_balancers": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "AWS Shield is a service that protects against Distributed Denial of Service attacks. There are two tiers for this service Standard and Advanced. AWS Shield Standard defends against most common, frequently occurring network and transport (Layer 3 and 4 attacks) layer DDoS attacks that target your web site or applications. AWS Shield Advanced adds on to standard by providing additional detection and mitigation against large and sophisticated DDoS attacks. There is near real-time visibility into attacks. AWS Shield Advanced also comes with 24x7 access to the AWS DDoS Response Team (DRT).","Category": "Respond","AWSService": "AWS Shield"},{"Value": "Minimal","Comment": "This control provides minimal coverage for this technique's sub-techniques as well as its procedures, resulting in an overall score of Minimal.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Partial","Comment": "AWS Network Firewall has the ability to pass, drop, or alert on traffic based on the network protocol as well as perform deep packet inspection on the payload. This functionality can be used to block adversaries from carrying out denial of service attacks by implementing restrictions on which IP addresses and domains can access the resources (e.g., allow lists) as well as which protocol traffic is permitted. That is, the AWS Network Firewall could block the source of the denial of service attack. This mapping is given a score of Partial because it only supports a subset of the sub-techniques (3 of 4) and because the source of the attack would have to be known before rules could be put in place to protect against it.","Category": "Protect","AWSService": "AWS Network Firewall"},{"Value": "Minimal","Comment": "VPC security groups and network access control lists (NACLs) provides minimal protection for a majority of this control's sub-techniques and procedure examples resulting in an overall score of Minimal.","Category": "Protect","AWSService": "Amazon Virtual Private Cloud"}],"description": "Adversaries may perform Endpoint Denial of Service (DoS) attacks to degrade or block the availability of services to users. Endpoint DoS can be performed by exhausting the system resources those services are hosted on or exploiting the system to cause a persistent crash condition. Example services include websites, email services, DNS, and web-based applications. Adversaries have been observed conducting DoS attacks for political purposes[1] and to support other malicious activities, including distraction[2], hacktivism, and extortion.","checks_status": {"fail": 4,"pass": 15,"total": 26,"manual": 0}},"T1518": {"name": "Software Discovery","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may attempt to get a listing of software and software versions that are installed on a system or in a cloud environment. Adversaries may use the information from Software Discovery during automated discovery to shape follow-on behaviors, including whether or not the adversary fully infects the target and/or attempts specific actions.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1525": {"name": "Implant Internal Image","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Value": "Minimal","Comment": "The following AWS Config managed rules can identify running instances that are not using AMIs within a specified allow list: 'approved-amis-by-id' and 'approved-amis-by-tag', both of which are run on configuration changes. This does not provide detection of the image implanting itself, but does provide detection for any subsequent use of images that are implanted and not present within the allow list, resulting in a score of Minimal.","Category": "Detect","AWSService": "AWS Config"}],"description": "Adversaries may implant cloud or container images with malicious code to establish persistence after gaining access to an environment. Amazon Web Services (AWS) Amazon Machine Images (AMIs), Google Cloud Platform (GCP) Images, and Azure Images as well as popular container runtimes such as Docker can be implanted or backdoored. Unlike Upload Malware, this technique focuses on adversaries implanting an image in a registry within a victim’s environment. Depending on how the infrastructure is provisioned, this could provide persistent access if the infrastructure provisioning tool is instructed to always use the latest image.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"T1526": {"name": "Cloud Service Discovery","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Value": "Partial","Comment": "GuardDuty has the following finding types to flag events where there is an attempt to discover information about resources on the account. Recon:IAMUser/MaliciousIPCaller Recon:IAMUser/MaliciousIPCaller.Custom Recon:IAMUser/TorIPCaller","Category": "Detect","AWSService": "Amazon GuardDuty"}],"description": "An adversary may attempt to enumerate the cloud services running on a system after gaining access. These methods can differ from platform-as-a-service (PaaS), to infrastructure-as-a-service (IaaS), or software-as-a-service (SaaS). Many services exist throughout the various cloud providers and can include Continuous Integration and Continuous Delivery (CI/CD), Lambda Functions, Azure AD, etc. They may also include security services, such as AWS GuardDuty and Microsoft Defender for Cloud, and logging services, such as AWS CloudTrail and Google Cloud Audit Logs.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"T1530": {"name": "Data from Cloud Storage","checks": {"macie_is_enabled": "PASS","securityhub_enabled": "PASS","s3_bucket_public_access": null,"networkfirewall_in_all_vpc": "FAIL","efs_not_publicly_accessible": "FAIL","rds_snapshots_public_access": "PASS","s3_bucket_default_encryption": "PASS","rds_instance_no_public_access": "PASS","efs_encryption_at_rest_enabled": "FAIL","emr_cluster_publicly_accesible": null,"rds_instance_storage_encrypted": "FAIL","redshift_cluster_public_access": null,"rds_instance_transport_encrypted": "FAIL","config_recorder_all_regions_enabled": null,"s3_bucket_level_public_access_block": "PASS","s3_account_level_public_access_blocks": null,"sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"sagemaker_training_jobs_intercontainer_encryption_enabled": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "The following AWS Config managed rules can identify configuration problems that should be fixed in order to prevent malicious access of data within Amazon Simple Storage Service (S3) storage: 's3-account-level-public-access-blocks', 's3-bucket-level-public-access-prohibited', 's3-bucket-public-read-prohibited', 's3-bucket-policy-not-more-permissive', 'cloudfront-origin-access-identity-enabled', and 'cloudfront-default-root-object-configured' identify objects that are publicly available or subject to overly permissive access policies; 's3-bucket-blacklisted-actions-prohibited' checks whether bucket policies prohibit disallowed actions for principals from other AWS accounts; and 's3-bucket-policy-grantee-check' checks whether bucket policies appropriately control which AWS principals, federated users, service principals, IP addresses, and VPCs have access. All of these controls are run on configuration changes. The following AWS Config managed rules can identify configuration problems that should be fixed in order to prevent malicious access of data from other AWS services: 'dms-replication-not-public' for AWS Database Migration Service; 'emr-master-no-public-ip' for Amazon Elastic MapReduce (EMR); 'rds-cluster-iam-authentication-enabled', 'rds-instance-iam-authentication-enabled', 'rds-instance-public-access-check' and 'rds-snapshots-public-prohibited' for Amazon Relational Database Service; 'redshift-cluster-public-access-check' for Amazon Redshift; and 'sagemaker-notebook-no-direct-internet-access' for SageMaker. The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure that cloud storage data are encrypted to prevent malicious access: 'dax-encryption-enabled', 'dynamodb-table-encrypted-kms', and 'dynamodb-table-encryption-enabled' for Amazon DynamoDB table contents; 'efs-encrypted-check' for Amazon Elastic File System (EFS) file systems; 'elasticsearch-encrypted-at-rest' for Elasticsearch Service (ES) domains; 'rds-snapshot-encrypted' and 'rds-storage-encrypted' for Amazon Relational Database Service; 's3-bucket-server-side-encryption-enabled' and 's3-default-encryption-kms' for S3 storage; 'sns-encrypted-kms' for Amazon Simple Notification Service (SNS); 'redshift-cluster-configuration-check' and 'redshift-cluster-kms-enabled' for Redshift clusters; 'sagemaker-endpoint-configuration-kms-key-configured' and 'sagemaker-notebook-instance-kms-key-configured' for SageMaker. These rules provide a wide range of coverage for many AWS services, especially those most significant to procedures for this technique, resulting in an overall score of Significant.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Partial","Comment": "The following AWS IoT Device Defender cloud-side detection metrics can detect indicators that an adversary may be leveraging compromised AWS IoT devices and the Message Queuing Telemetry Transport (MQTT) protocol for unauthorized data transfer from cloud-side data sources: 'Source IP' ('aws:source-ip-address') values outside of expected IP address ranges may suggest that a device has been stolen. 'Messages sent' ('aws:num-messages-sent'), 'Messages received' ('aws:num-messages-received'), and 'Message size' ('aws:message-byte-size') values outside of expected norms may indicate that devices are sending and/or receiving non-standard traffic, which may include data retrieved from cloud storage. The following AWS IoT Device Defender device-side detection metrics can detect indicators that an adversary may be leveraging compromised AWS IoT devices and the Message Queuing Telemetry Transport (MQTT) protocol for unauthorized data transfer from cloud-side data sources: 'Bytes in' ('aws:all-bytes-in'), 'Bytes out' ('aws:all-bytes-out'), 'Packets in' ('aws:all-packets-in'), and 'Packets out' ('aws:all-packets-out') values outside of expected norms may indicate that devices are sending and/or receiving non-standard traffic, which may include data retrieved from cloud storage. Coverage factor is partial, since these metrics are limited to IoT device-based collection, resulting in an overall score of Partial.","Category": "Detect","AWSService": "AWS IoT Device Defender"},{"Value": "Partial","Comment": "AWS Network Firewall has the ability to pass, drop, or alert on traffic based on the network protocol as well as perform deep packet inspection on the payload. This functionality can be used to block adversaries from accessing resources such as cloud storage objects by implementing restrictions on which IP addresses and domains can access the resources (e.g., allow lists). However, since cloud storage objects are located outside the virtual private cloud where the AWS Network Firewall protects, the mapping is only given a score of Partial.","Category": "Protect","AWSService": "AWS Network Firewall"},{"Value": "Significant","Comment": "AWS RDS supports the encryption of the underlying storage for database instances, backups, read replicas, and snapshots using the AES-256 encryption algorithm. This can protect against an adversary from gaining access to a database instance in the event they get access to the underlying system where the database instance is hosted or to S3 where the backups are stored. Furthermore, with AWS RDS, there is a setting that specifies whether or not a database instances is publicly accessible. When public accessibility is turned off, the database instance will not be available outside the VPC in which it was created. As a result, this mapping is given a score of Significant.","Category": "Protect","AWSService": "AWS RDS"},{"Value": "Significant","Comment": "S3 provides full control of access via Identity and Access Management (IAM) policies and with its access control lists (ACLs). The S3 Block Public Access feature allows for policies limiting public access to Amazon S3 resources that are enforced regardless of how the resources are created or associated IAM policies. Server-side encryption can be enabled for data at rest and allows for use of S3-managed keys, AWS Key Management Service managed keys, or customer-provided keys.","Category": "Protect","AWSService": "AWS S3"},{"Value": "Partial","Comment": "AWS Security Hub detects improperly secured data from S3 buckets such as public read and write access that may result in an adversary getting access to data in cloud storage. AWS Security Hub provides this detection with the following managed insight. S3 buckets with public write or read permissions. AWS Security Hub also performs checks from the AWS Foundations CIS Benchmark that, if implemented, would help towards detecting improperly secured S3 buckets which could result in them being discovered. AWS Security Hub provides this detection with the following check. 3.8 Ensure a log metric filter and alarm exist for S3 bucket policy changes. This is scored as Partial because it only detects when S3 buckets have public read or write access and doesn't detect improperly secured data in other storage types (e.g., DBs, NFS, etc.).","Category": "Detect","AWSService": "AWS Security Hub"},{"Value": "Partial","Comment": "The following GuardDuty finding types flag events where adversaries may have access data objects from improperly secured cloud storage. UnauthorizedAccess:S3/MaliciousIPCaller.Custom UnauthorizedAccess:S3/TorIPCaller Impact:S3/MaliciousIPCaller Exfiltration:S3/MaliciousIPCaller Exfiltration:S3/ObjectRead.Unusual PenTest:S3/KaliLinux PenTest:S3/ParrotLinux PenTest:S3/PentooLinux UnauthorizedAccess:S3/MaliciousIPCaller.Custom UnauthorizedAccess:S3/TorIPCaller.","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Minimal","Comment": "The following Macie findings can detect the collection of data from S3 buckets: Policy:IAMUser/S3BlockPublicAccessDisabled Policy:IAMUser/S3BucketEncryptionDisabled Policy:IAMUser/S3BucketPublic Policy:IAMUser/S3BucketReplicatedExternally Policy:IAMUser/S3BucketSharedExternally. This type of detection is limited to only the S3 storage type and not other storage types available on the platform (such as file or block storage) and therefore has Minimal coverage resulting in a Minimal score.","Category": "Detect","AWSService": "Amazon Macie"},{"Value": "Minimal","Comment": "The following Macie findings can protect against collection of sensitive data from S3 buckets: SensitiveData:S3Object/Credentials SensitiveData:S3Object/CustomIdentifier SensitiveData:S3Object/Financial SensitiveData:S3Object/Multiple SensitiveData:S3Object/Personal. The ability to discover this type of sensitive data stored in a bucket may lead to hardening steps or removing the data altogether which would prevent an adversary from being able to collect the data. This type of protection is limited to only the S3 storage type and not other storage types available on the platform (such as file or block storage) and therefore has Minimal coverage resulting in a Minimal score.","Category": "Protect","AWSService": "Amazon Macie"}],"description": "Adversaries may collect sensitive data from these cloud storage solutions. Providers typically offer security guides to help end users configure systems, though misconfigurations are a common problem.[5][6][7] There have been numerous incidents where cloud storage has been improperly secured, typically by unintentionally allowing public access to unauthenticated users, overly-broad access by all users, or even access for any anonymous person outside the control of the Identity Access Management system without even needing basic user permissions.","checks_status": {"fail": 6,"pass": 6,"total": 22,"manual": 0}},"T1535": {"name": "Unused/Unsupported Cloud Regions","checks": {"organizations_scp_check_deny_regions": null},"status": "PASS","attributes": [],"description": "Adversaries may create cloud instances in unused geographic service regions in order to evade detection. Access is usually obtained through compromising accounts used to manage cloud infrastructure.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"T1537": {"name": "Transfer Data to Cloud Account","checks": {"macie_is_enabled": "PASS"},"status": "PASS","attributes": [{"Value": "Minimal","Comment": "The following Macie findings can detect attempts to replicate data objects from a monitored bucket to an Amazon Web Services account that isn't part of your organization: Policy:IAMUser/S3BucketReplicatedExternally Policy:IAMUser/S3BucketSharedExternally. This type of detection is limited to only the S3 storage type and not other storage types available on the platform (such as file or block storage) and therefore has Minimal coverage resulting in a Minimal score.","Category": "Detect","AWSService": "Amazon Macie"}],"description": "Adversaries may exfiltrate data by transferring the data, including backups of cloud environments, to another cloud account they control on the same service to avoid typical file transfers/downloads and network-based exfiltration detection.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"T1538": {"name": "Cloud Service Dashboard","checks": {"iam_user_mfa_enabled_console_access": null,"organizations_account_part_of_organizations": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Value": "Partial","Comment": "This control may protect against cloud service dashboard abuse by segmenting accounts into separate organizational units and restricting dashboard access by least privilege.","Category": "Protect","AWSService": "AWS Organizations"},{"Value": "Significant","Comment": "The 'mfa-enabled-for-iam-console-access' managed rule checks whether multi-factor authentication is enabled for all AWS IAM users that use a console password, protecting against misuse of those accounts' dashboard access. It is run periodically, and provides significant coverage, resulting in an overall score of Significant.","Category": "Protect","AWSService": "AWS Config"}],"description": "An adversary may use a cloud service dashboard GUI with stolen credentials to gain useful information from an operational cloud environment, such as specific services, resources, and features. For example, the GCP Command Center can be used to view all assets, findings of potential security risks, and to run additional queries, such as finding public IP addresses and open ports.","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"T1546": {"name": "Event Triggered Execution","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may establish persistence and/or elevate privileges using system mechanisms that trigger execution based on specific events. Various operating systems have means to monitor and subscribe to events such as logons or other user activity such as running specific applications/binaries. Cloud environments may also support various functions and services that monitor and can be invoked in response to specific cloud events.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1550": {"name": "Use Alternate Authentication Material","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_hardware_mfa_enabled": null,"iam_user_console_access_unused": null,"iam_user_two_active_access_key": null,"iam_policy_no_full_access_to_kms": null,"iam_administrator_access_with_mfa": null,"iam_user_mfa_enabled_console_access": null,"iam_user_no_setup_initial_access_key": null,"iam_policy_allows_privilege_escalation": null,"iam_policy_no_full_access_to_cloudtrail": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Value": "Minimal","Comment": "This control provides significant coverage for one of this technique's SubTechniques, resulting in an overall score of Minimal.","Category": "Protect","AWSService": "AWS IAM"}],"description": "Adversaries may use alternate authentication material, such as password hashes, Kerberos tickets, and application access tokens, in order to move laterally within an environment and bypass normal system access controls.","checks_status": {"fail": 0,"pass": 0,"total": 17,"manual": 0}},"T1552": {"name": "Unsecured Credentials","checks": {"macie_is_enabled": "PASS","guardduty_is_enabled": "PASS","ssm_document_secrets": "PASS","ec2_instance_imdsv2_enabled": "PASS","ec2_instance_secrets_user_data": "PASS","ec2_launch_template_no_secrets": "PASS","awslambda_function_no_secrets_in_code": "PASS","cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudformation_stack_outputs_find_secrets": "PASS","secretsmanager_automatic_rotation_enabled": "FAIL","awslambda_function_no_secrets_in_variables": "PASS","ecs_task_definitions_no_environment_secrets": "PASS","autoscaling_find_secrets_ec2_launch_configuration": "PASS","eks_cluster_kms_cmk_encryption_in_secrets_enabled": null},"status": "FAIL","attributes": [{"Value": "Minimal","Comment": "This control's protection is specific to a minority of this technique's sub-techniques and procedure examples resulting in a Minimal Coverage score and consequently an overall score of Minimal.","Category": "Protect","AWSService": "AWS CloudHSM"},{"Value": "Significant","Comment": "The following AWS Config managed rules can identify insecure plaintext credentials within specific parts of a cloud environment: 'codebuild-project-envvar-awscred-check' for credentials (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY) stored within environment variables, 'codebuild-project-source-repo-url-check' for personal access tokens and/or credentials within source repository URLs. The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure that the contents of secrets in AWS Secrets Manager (including credentials) are properly secured to avoid adversary access: 'secretsmanager-rotation-enabled-check', 'secretsmanager-scheduled-rotation-success-check', 'secretsmanager-secret-periodic-rotation', and 'secretsmanager-using-cmk'. This control provides partial coverage for a minority of this technique's sub-techniques, in addition to the parent coverage above, resulting in an overall score of Partial.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Minimal","Comment": "This control provides partial coverage for a minority of this technique's sub-techniques, resulting in an overall score of Minimal.","Category": "Detect","AWSService": "AWS IoT Device Defender"},{"Value": "Minimal","Comment": "This control's protection is specific to a minority of this technique's sub-techniques and procedure examples resulting in a Minimal Coverage score and consequently an overall score of Minimal.","Category": "Protect","AWSService": "AWS Key Management Service"},{"Value": "Partial","Comment": "This control is relevant for credentials stored in applications or configuration files but not credentials entered directly by a user.","Category": "Protect","AWSService": "AWS Secrets Manager"},{"Value": "Minimal","Comment": "This control provides minimal to partial coverage for a minority of this technique's sub-techniques, and without specific coverage for its procedures, resulting in an overall score of Minimal.","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Minimal","Comment": "Macie only provides detection for the Credentials in Files sub-technique of this technique and only for the S3 storage type resulting in Minimal coverage and an overall Minimal score.","Category": "Protect","AWSService": "Amazon Macie"}],"description": "Adversaries may search compromised systems to find and obtain insecurely stored credentials. These credentials can be stored and/or misplaced in many locations on a system, including plaintext files (e.g. Bash History), operating system or application-specific repositories (e.g. Credentials in Registry), or other specialized files/artifacts (e.g. Private Keys).","checks_status": {"fail": 2,"pass": 11,"total": 14,"manual": 0}},"T1556": {"name": "Modify Authentication Process","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Value": "Partial","Comment": "This control provides coverage for one of this technique's SubTechniques, resulting in an overall score of Partial. Enforce MFA in IAM Users.","Category": "Protect","AWSService": "AWS IAM"}],"description": "Adversaries may modify authentication mechanisms and processes to access user credentials or enable otherwise unwarranted access to accounts. The authentication process is handled by mechanisms, such as the Local Security Authentication Server (LSASS) process and the Security Accounts Manager (SAM) on Windows, pluggable authentication modules (PAM) on Unix-based systems, and authorization plugins on MacOS systems, responsible for gathering, storing, and validating credentials. By modifying an authentication process, an adversary may be able to authenticate to a service or system without using Valid Accounts.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"T1562": {"name": "Impair Defenses","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","inspector2_active_findings_exist": "FAIL","config_recorder_all_regions_enabled": null},"status": "FAIL","attributes": [{"Value": "Minimal","Comment": "This control provides significant coverage for a minority of this technique's SubTechniques, resulting in an overall score of Minimal.","Category": "Detect","AWSService": "AWS Config"},{"Value": "Minimal","Comment": "This control provides partial coverage for a minority of this technique's SubTechniques, resulting in an overall score of Minimal.","Category": "Detect","AWSService": "AWS IoT Device Defender"},{"Value": "Minimal","Comment": "This control provides partial coverage for a minority of this technique's SubTechniques, resulting in an overall score of Minimal.","Category": "Respond","AWSService": "AWS IoT Device Defender"}],"description": "Adversaries may maliciously modify components of a victim environment in order to hinder or disable defensive mechanisms. This not only involves impairing preventative defenses, such as firewalls and anti-virus, but also detection capabilities that defenders can use to audit activity and identify malicious behavior. This may also span both native defenses as well as supplemental capabilities installed by users and administrators.","checks_status": {"fail": 2,"pass": 2,"total": 5,"manual": 0}},"T1578": {"name": "Modify Cloud Compute Infrastructure","checks": {"iam_policy_no_full_access_to_kms": null,"iam_policy_allows_privilege_escalation": null,"iam_policy_no_full_access_to_cloudtrail": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Value": "Significant","Comment": "Limit permissions for creating, deleting, and otherwise altering compute components in accordance with least privilege.","Category": "Protect","AWSService": "AWS IAM"}],"description": "An adversary may attempt to modify a cloud account's compute service infrastructure to evade defenses. A modification to the compute service infrastructure can include the creation, deletion, or modification of one or more components such as compute instances, virtual machines, and snapshots.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"T1580": {"name": "Cloud Infrastructure Discovery","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_policy_no_full_access_to_kms": null,"iam_policy_allows_privilege_escalation": null,"iam_policy_no_full_access_to_cloudtrail": null,"organizations_account_part_of_organizations": null,"iam_inline_policy_no_administrative_privileges": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Value": "Partial","Comment": "This control may protect against cloud infrastructure discovery by segmenting accounts into separate organizational units and restricting infrastructure access by least privilege.","Category": "Protect","AWSService": "AWS Organizations"},{"Value": "Partial","Comment": "AWS Security Hub detects improperly secured data from S3 buckets such as public read and write access as well as accessible EC2 instances that may result in an adversary learning about cloud infrastructure used by the organization. AWS Security Hub provides these detections with the following managed insights. S3 buckets with public write or read permissions EC2 instances that have ports accessible from the Internet EC2 instances that are open to the Internet. AWS Security Hub also performs checks from the AWS Foundations CIS Benchmark that, if implemented, would help towards detecting improperly secured S3 buckets which could result in them being discovered. AWS Security Hub provides this detection with the following check. 3.8 Ensure a log metric filter and alarm exist for S3 bucket policy changes. This is scored as Partial because S3 and EC2 only represent a subset of available cloud infrastructure components.","Category": "Detect","AWSService": "AWS Security Hub"},{"Value": "Partial","Comment": "The following GuardDuty finding types flag events that are linked to Discovery techniques and can be used to capture events where a malicious user may be searching through the account looking for available resources. The finding types are also used to flag certain signatures of running services to detect malicious user activities from commonly used pentest operating systems. Discovery:IAMUser/AnomalousBehavior Discovery:S3/MaliciousIPCaller Discovery:S3/MaliciousIPCaller.Custom Discovery:S3/TorIPCaller PenTest:IAMUser/KaliLinux PenTest:IAMUser/ParrotLinux PenTest:IAMUser/PentooLinux PenTest:S3/KaliLinux PenTest:S3/ParrotLinux PenTest:S3/PentooLinux.","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Significant","Comment": "Limit IAM permissions to discover cloud infrastructure in accordance with least privilege. Organizations should limit the number of users within the organization with an IAM role that has administrative privileges, strive to reduce all permanent privileged role assignments, and conduct periodic entitlement reviews on IAM users, roles and policies.","Category": "Protect","AWSService": "AWS IAM"}],"description": "An adversary may attempt to discover infrastructure and resources that are available within an infrastructure-as-a-service (IaaS) environment. This includes compute service resources such as instances, virtual machines, and snapshots as well as resources of other services including the storage and database services.","checks_status": {"fail": 0,"pass": 2,"total": 10,"manual": 0}},"T1606": {"name": "Forge Web Credentials","checks": {"iam_policy_allows_privilege_escalation": null,"iam_no_custom_policy_permissive_role_assumption": null},"status": "PASS","attributes": [{"Value": "Partial","Comment": "Limit IAM permissions from calling the sts:GetFederationToken API unless explicitly required, in accordance with least privilege.","Category": "Protect","AWSService": "AWS IAM"}],"description": "Adversaries may forge credential materials that can be used to gain access to web applications or Internet services. Web applications and services (hosted in cloud SaaS environments or on-premise servers) often use session cookies, tokens, or other materials to authenticate and authorize user access.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"T1614": {"name": "System Location Discovery","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may gather information in an attempt to calculate the geographical location of a victim host. Adversaries may use the information from System Location Discovery during automated discovery to shape follow-on behaviors, including whether or not the adversary fully infects the target and/or attempts specific actions.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1619": {"name": "Cloud Storage Object Discovery","checks": {"iam_policy_allows_privilege_escalation": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Value": "Significant","Comment": "Restrict granting of permissions related to listing objects in AWS S3 Buckets to necessary accounts.","Category": "Protect","AWSService": "AWS IAM"}],"description": "Adversaries may enumerate objects in cloud storage infrastructure. Adversaries may use this information during automated discovery to shape follow-on behaviors, including requesting all or specific objects from cloud storage. Similar to File and Directory Discovery on a local host, after identifying available storage services (i.e. Cloud Infrastructure Discovery) adversaries may access the contents/objects stored in cloud infrastructure.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"T1621": {"name": "Multi-Factor Authentication Request Generation","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may attempt to bypass multi-factor authentication (MFA) mechanisms and gain access to accounts by generating MFA requests sent to users.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1648": {"name": "Serverless Execution","checks": {"iam_policy_no_full_access_to_kms": null,"iam_policy_allows_privilege_escalation": null,"iam_policy_no_full_access_to_cloudtrail": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Value": "Significant","Comment": "Remove permissions to create, modify, or run serverless resources from users that do not explicitly require them.","Category": "Protect","AWSService": "AWS IAM"}],"description": "Adversaries may abuse serverless computing, integration, and automation services to execute arbitrary code in cloud environments. Many cloud providers offer a variety of serverless resources, including compute engines, application integration services, and web servers.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"T1651": {"name": "Cloud Administration Command","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may abuse cloud management services to execute commands within virtual machines or hybrid-joined devices. Resources such as AWS Systems Manager, Azure RunCommand, and Runbooks allow users to remotely run scripts in virtual machines by leveraging installed virtual machine agents. Similarly, in Azure AD environments, Microsoft Endpoint Manager allows Global or Intune Administrators to run scripts as SYSTEM on on-premises devices joined to the Azure AD.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}}},"requirements_passed": 18,"requirements_failed": 18,"requirements_manual": 10,"total_requirements": 46,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "6e52644d-3557-4704-9cf6-e33e4c1a316b","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "ffiec_aws","framework": "FFIEC","version": "","description": "In light of the increasing volume and sophistication of cyber threats, the Federal Financial Institutions Examination Council (FFIEC) developed the Cybersecurity Assessment Tool (Assessment), on behalf of its members, to help institutions identify their risks and determine their cybersecurity maturity.","region": "eu-west-1","requirements": {"d1-g-it-b-1": {"name": "D1.G.IT.B.1","checks": {"ec2_elastic_ip_unassigned": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d1-g-it-b-1","Section": "Cyber Risk Management and Oversight (Domain 1)","Service": "aws","SubGroup": null,"SubSection": "Governance (G)"}],"description": "An inventory of organizational assets (e.g., hardware, software, data, and systems hosted externally) is maintained.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"d4-c-co-b-2": {"name": "D4.C.Co.B.2","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d4-c-co-b-2","Section": "External Dependency Management (Domain 4)","Service": "aws","SubGroup": null,"SubSection": "Connections (C)"}],"description": "The institution ensures that third-party connections are authorized.","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"d1-rm-ra-b-2": {"name": "D1.RM.RA.B.2","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "d1-rm-ra-b-2","Section": "Cyber Risk Management and Oversight (Domain 1)","Service": "aws","SubGroup": null,"SubSection": "Risk Management (RM)"}],"description": "The risk assessment identifies Internet- based systems and high-risk transactions that warrant additional authentication controls.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"d1-rm-rm-b-1": {"name": "D1.RM.Rm.B.1","checks": {"rds_instance_multi_az": "FAIL","rds_instance_backup_enabled": "PASS","redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d1-rm-rm-b-1","Section": "Cyber Risk Management and Oversight (Domain 1)","Service": "aws","SubGroup": null,"SubSection": "Risk Management (RM)"}],"description": "An information security and business continuity risk management function(s) exists within the institution.","checks_status": {"fail": 1,"pass": 1,"total": 4,"manual": 0}},"d2-is-is-b-1": {"name": "D2.IS.Is.B.1","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d2-is-is-b-1","Section": "Threat Intelligence and Collaboration (Domain 2)","Service": "aws","SubGroup": null,"SubSection": "Information Sharing (IS)"}],"description": "Information security threats are gathered and shared with applicable internal employees.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"d2-ma-ma-b-1": {"name": "D2.MA.Ma.B.1","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","opensearch_service_domains_cloudwatch_logging_enabled": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d2-ma-ma-b-1","Section": "Threat Intelligence and Collaboration (Domain 2)","Service": "aws","SubGroup": null,"SubSection": "Monitoring and Analyzing (MA)"}],"description": "Information security threats are gathered and shared with applicable internal employees.","checks_status": {"fail": 7,"pass": 2,"total": 14,"manual": 0}},"d2-ma-ma-b-2": {"name": "D2.MA.Ma.B.2","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","opensearch_service_domains_cloudwatch_logging_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d2-ma-ma-b-2","Section": "Threat Intelligence and Collaboration (Domain 2)","Service": "aws","SubGroup": null,"SubSection": "Monitoring and Analyzing (MA)"}],"description": "Computer event logs are used for investigations once an event has occurred.","checks_status": {"fail": 5,"pass": 2,"total": 12,"manual": 0}},"d2-ti-ti-b-1": {"name": "D2.TI.Ti.B.1","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "d2-ti-ti-b-1","Section": "Threat Intelligence and Collaboration (Domain 2)","Service": "aws","SubGroup": null,"SubSection": "Threat Intelligence (TI)"}],"description": "The institution belongs or subscribes to a threat and vulnerability information-sharing source(s) that provides information on threats (e.g., FS-ISAC, US- CERT).","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"d2-ti-ti-b-2": {"name": "D2.TI.Ti.B.2","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d2-ti-ti-b-2","Section": "Threat Intelligence and Collaboration (Domain 2)","Service": "aws","SubGroup": null,"SubSection": "Threat Intelligence (TI)"}],"description": "Threat information is used to monitor threats and vulnerabilities.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"d2-ti-ti-b-3": {"name": "D2.TI.Ti.B.3","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "d2-ti-ti-b-3","Section": "Threat Intelligence and Collaboration (Domain 2)","Service": "aws","SubGroup": null,"SubSection": "Threat Intelligence (TI)"}],"description": "Threat information is used to enhance internal risk management and controls.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"d3-cc-pm-b-1": {"name": "D3.CC.PM.B.1","checks": {"ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-cc-pm-b-1","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Corrective Controls (CC)"}],"description": "A patch management program is implemented and ensures that software and firmware patches are applied in a timely manner.","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"d3-cc-pm-b-3": {"name": "D3.CC.PM.B.3","checks": {"ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-cc-pm-b-3","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Corrective Controls (CC)"}],"description": "Patch management reports are reviewed and reflect missing security patches.","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"d3-dc-an-b-1": {"name": "D3.DC.An.B.1","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-dc-an-b-1","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "The institution is able to detect anomalous activities through monitoring across the environment.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"d3-dc-an-b-2": {"name": "D3.DC.An.B.2","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-dc-an-b-2","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "Customer transactions generating anomalous activity alerts are monitored and reviewed.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"d3-dc-an-b-3": {"name": "D3.DC.An.B.3","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","opensearch_service_domains_cloudwatch_logging_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-dc-an-b-3","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "Logs of physical and/or logical access are reviewed following events.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"d3-dc-an-b-4": {"name": "D3.DC.An.B.4","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","opensearch_service_domains_cloudwatch_logging_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-dc-an-b-4","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "Access to critical systems by third parties is monitored for unauthorized or unusual activity.","checks_status": {"fail": 6,"pass": 2,"total": 13,"manual": 0}},"d3-dc-an-b-5": {"name": "D3.DC.An.B.5","checks": {"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-dc-an-b-5","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "Elevated privileges are monitored.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"d3-dc-ev-b-1": {"name": "D3.DC.Ev.B.1","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-dc-ev-b-1","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "A normal network activity baseline is established.","checks_status": {"fail": 4,"pass": 2,"total": 10,"manual": 0}},"d3-dc-ev-b-2": {"name": "D3.DC.Ev.B.2","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-dc-ev-b-2","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "Mechanisms (e.g., antivirus alerts, log event alerts) are in place to alert management to potential attacks.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"d3-dc-ev-b-3": {"name": "D3.DC.Ev.B.3","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-dc-ev-b-3","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "Processes are in place to monitor for the presence of unauthorized users, devices, connections, and software.","checks_status": {"fail": 1,"pass": 3,"total": 4,"manual": 0}},"d3-dc-th-b-1": {"name": "D3.DC.Th.B.1","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-dc-th-b-1","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "Independent testing (including penetration testing and vulnerability scanning) is conducted according to the risk assessment for external-facing systems and the internal network.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"d3-pc-am-b-1": {"name": "D3.PC.Am.B.1","checks": {"iam_no_root_access_key": null,"ec2_instance_profile_attached": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-1","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Employee access is granted to systems and confidential data based on job responsibilities and the principles of least privilege.","checks_status": {"fail": 0,"pass": 1,"total": 6,"manual": 0}},"d3-pc-am-b-2": {"name": "D3.PC.Am.B.2","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-2","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Employee access to systems and confidential data provides for separation of duties.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"d3-pc-am-b-3": {"name": "D3.PC.Am.B.3","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_root_hardware_mfa_enabled": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-3","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Elevated privileges (e.g., administrator privileges) are limited and tightly controlled (e.g., assigned to individuals, not shared, and require stronger password controls","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"d3-pc-am-b-6": {"name": "D3.PC.Am.B.6","checks": {"iam_root_mfa_enabled": null,"iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-6","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Identification and authentication are required and managed for access to systems, applications, and hardware.","checks_status": {"fail": 0,"pass": 0,"total": 16,"manual": 0}},"d3-pc-am-b-7": {"name": "D3.PC.Am.B.7","checks": {"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-7","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Access controls include password complexity and limits to password attempts and reuse.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"d3-pc-am-b-8": {"name": "D3.PC.Am.B.8","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-8","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "All default passwords and unnecessary default accounts are changed before system implementation.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"d3-pc-im-b-1": {"name": "D3.PC.Im.B.1","checks": {"ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"acm_certificates_expiration_check": "PASS","apigateway_restapi_waf_acl_attached": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-im-b-1","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Network perimeter defense tools (e.g., border router and firewall) are used.","checks_status": {"fail": 5,"pass": 7,"total": 20,"manual": 0}},"d3-pc-im-b-2": {"name": "D3.PC.Im.B.2","checks": {"elbv2_waf_acl_attached": "FAIL","apigateway_restapi_waf_acl_attached": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-im-b-2","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Systems that are accessed from the Internet or by external parties are protected by firewalls or other similar devices.","checks_status": {"fail": 4,"pass": 1,"total": 6,"manual": 0}},"d3-pc-im-b-3": {"name": "D3.PC.Im.B.3","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-im-b-3","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "All ports are monitored.","checks_status": {"fail": 4,"pass": 2,"total": 6,"manual": 0}},"d3-pc-im-b-5": {"name": "D3.PC.Im.B.5","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-im-b-5","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Systems configurations (for servers, desktops, routers, etc.) follow industry standards and are enforced","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"d3-pc-im-b-6": {"name": "D3.PC.Im.B.6","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-im-b-6","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Ports, functions, protocols and services are prohibited if no longer needed for business purposes.","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"d3-pc-im-b-7": {"name": "D3.PC.Im.B.7","checks": {"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-im-b-7","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Access to make changes to systems configurations (including virtual machines and hypervisors) is controlled and monitored.","checks_status": {"fail": 1,"pass": 1,"total": 6,"manual": 0}},"d3-pc-se-b-1": {"name": "D3.PC.Se.B.1","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-pc-se-b1","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Developers working for the institution follow secure program coding practices, as part of a system development life cycle (SDLC), that meet industry standards.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"d5-dr-de-b-1": {"name": "D5.DR.De.B.1","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "d5-dr-de-b-1","Section": "Cyber Incident Management and Resilience (Domain 5)","Service": "aws","SubGroup": null,"SubSection": "Detection, Response, & Mitigation (DR)"}],"description": "Alert parameters are set for detecting information security incidents that prompt mitigating actions.","checks_status": {"fail": 0,"pass": 2,"total": 6,"manual": 0}},"d5-dr-de-b-2": {"name": "D5.DR.De.B.2","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "d5-dr-de-b-2","Section": "Cyber Incident Management and Resilience (Domain 5)","Service": "aws","SubGroup": null,"SubSection": "Detection, Response, & Mitigation (DR)"}],"description": "System performance reports contain information that can be used as a risk indicator to detect information security incidents.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"d5-dr-de-b-3": {"name": "D5.DR.De.B.3","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d5-dr-de-b-3","Section": "Cyber Incident Management and Resilience (Domain 5)","Service": "aws","SubGroup": null,"SubSection": "Detection, Response, & Mitigation (DR)"}],"description": "Tools and processes are in place to detect, alert, and trigger the incident response program.","checks_status": {"fail": 5,"pass": 3,"total": 16,"manual": 0}},"d5-er-es-b-4": {"name": "D5.ER.Es.B.4","checks": {"guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d5-er-es-b-4","Section": "Cyber Incident Management and Resilience (Domain 5)","Service": "aws","SubGroup": null,"SubSection": "Escalation and Reporting (ER)"}],"description": "Incidents are classified, logged and tracked.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"d5-ir-pl-b-6": {"name": "D5.IR.Pl.B.6","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d5-ir-pl-b-6","Section": "Cyber Incident Management and Resilience (Domain 5)","Service": "aws","SubGroup": null,"SubSection": "Incident Resilience Planning & Strategy (IR)"}],"description": "The institution plans to use business continuity, disaster recovery, and data backup programs to recover operations following an incident.","checks_status": {"fail": 5,"pass": 1,"total": 8,"manual": 0}},"d3-pc-am-b-10": {"name": "D3.PC.Am.B.10","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-10","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Production and non-production environments are segregated to prevent unauthorized access or changes to information assets. (*N/A if no production environment exists at the institution or the institution's third party.)","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"d3-pc-am-b-12": {"name": "D3.PC.Am.B.12","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-12","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "All passwords are encrypted in storage and in transit.","checks_status": {"fail": 4,"pass": 3,"total": 10,"manual": 0}},"d3-pc-am-b-13": {"name": "D3.PC.Am.B.13","checks": {"elb_ssl_listeners": "FAIL","elbv2_insecure_ssl_ciphers": "PASS","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-13","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Confidential data is encrypted when transmitted across public or untrusted networks (e.g., Internet).","checks_status": {"fail": 3,"pass": 1,"total": 4,"manual": 0}},"d3-pc-am-b-15": {"name": "D3.PC.Am.B.15","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"s3_bucket_secure_transport_policy": "FAIL","iam_user_mfa_enabled_console_access": null,"apigateway_restapi_client_certificate_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-15","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Remote access to critical systems by employees, contractors, and third parties uses encrypted connections and multifactor authentication.","checks_status": {"fail": 2,"pass": 0,"total": 5,"manual": 0}},"d3-pc-am-b-16": {"name": "D3.PC.Am.B.16","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-16","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Administrative, physical, or technical controls are in place to prevent users without administrative responsibilities from installing unauthorized software.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}}},"requirements_passed": 13,"requirements_failed": 29,"requirements_manual": 2,"total_requirements": 44,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "7058bd2a-3241-4e0e-9773-9a0136d861bc","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "cis_2.0_aws","framework": "CIS","version": "2.0","description": "The CIS Amazon Web Services Foundations Benchmark provides prescriptive guidance for configuring security options for a subset of Amazon Web Services with an emphasis on foundational, testable, and architecture agnostic settings.","region": "eu-west-1","requirements": {"1.1": {"name": "1.1","checks": {"account_maintain_current_contact_details": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/manage-account-payment.html#contact-info","Description": "Ensure contact email and telephone details for AWS accounts are current and map to more than one individual in your organization.An AWS account supports a number of contact details, and AWS will use these to contact the account owner if activity judged to be in breach of Acceptable Use Policy or indicative of likely security compromise is observed by the AWS Abuse team. Contact details should not be for a single individual, as circumstances may arise where that individual is unavailable. Email contact details should point to a mail alias which forwards email to multiple individuals within the organization; where feasible, phone contact details should point to a PABX hunt group or other call-forwarding system.","DefaultValue": null,"AuditProcedure": "This activity can only be performed via the AWS Console, with a user who has permission to read and write Billing information (aws-portal:\\*Billing )1. Sign in to the AWS Management Console and open the `Billing and Cost Management` console at https://console.aws.amazon.com/billing/home#/. 2. On the navigation bar, choose your account name, and then choose `My Account`. 3. On the `Account Settings` page, review and verify the current details. 4. Under `Contact Information`, review and verify the current details.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "If an AWS account is observed to be behaving in a prohibited or suspicious manner, AWS will attempt to contact the account owner by email and phone using the contact details listed. If this is unsuccessful and the account behavior needs urgent mitigation, proactive measures may be taken, including throttling of traffic between the account exhibiting suspicious behavior and the AWS API endpoints and the Internet. This will result in impaired service to and from the account in question, so it is in both the customers' and AWS' best interests that prompt contact can be established. This is best achieved by setting AWS account contact details to point to resources which have multiple individuals as recipients, such as email aliases and PABX hunt groups.","RemediationProcedure": "This activity can only be performed via the AWS Console, with a user who has permission to read and write Billing information (aws-portal:\\*Billing ).1. Sign in to the AWS Management Console and open the `Billing and Cost Management` console at https://console.aws.amazon.com/billing/home#/. 2. On the navigation bar, choose your account name, and then choose `My Account`. 3. On the `Account Settings` page, next to `Account Settings`, choose `Edit`. 4. Next to the field that you need to update, choose `Edit`. 5. After you have entered your changes, choose `Save changes`. 6. After you have made your changes, choose `Done`. 7. To edit your contact information, under `Contact Information`, choose `Edit`. 8. For the fields that you want to change, type your updated information, and then choose `Update`.","AdditionalInformation": ""}],"description": "Maintain current contact details","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.2": {"name": "1.2","checks": {"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "","Description": "AWS provides customers with the option of specifying the contact information for account's security team. It is recommended that this information be provided.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if security contact information is present:**From Console:**1. Click on your account name at the top right corner of the console 2. From the drop-down menu Click `My Account`3. Scroll down to the `Alternate Contacts` section 4. Ensure contact information is specified in the `Security` section","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Specifying security-specific contact information will help ensure that security advisories sent by AWS reach the team in your organization that is best equipped to respond to them.","RemediationProcedure": "Perform the following to establish security contact information:**From Console:**1. Click on your account name at the top right corner of the console. 2. From the drop-down menu Click `My Account`3. Scroll down to the `Alternate Contacts` section 4. Enter contact information in the `Security` section**Note:** Consider specifying an internal email distribution list to ensure emails are regularly monitored by more than one individual.","AdditionalInformation": ""}],"description": "Ensure security contact information is registered","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.3": {"name": "1.3","checks": {"account_security_questions_are_registered_in_the_aws_account": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "","Description": "The AWS support portal allows account owners to establish security questions that can be used to authenticate individuals calling AWS customer service for support. It is recommended that security questions be established.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS account as the 'root' user 2. On the top right you will see the __ 3. Click on the __ 4. From the drop-down menu Click `My Account`5. In the `Configure Security Challenge Questions` section on the `Personal Information` page, configure three security challenge questions. 6. Click `Save questions` .","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "When creating a new AWS account, a default super user is automatically created. This account is referred to as the 'root user' or 'root' account. It is recommended that the use of this account be limited and highly controlled. During events in which the 'root' password is no longer accessible or the MFA token associated with 'root' is lost/destroyed it is possible, through authentication using secret questions and associated answers, to recover 'root' user login access.","RemediationProcedure": "**From Console:**1. Login to the AWS Account as the 'root' user 2. Click on the __ from the top right of the console 3. From the drop-down menu Click _My Account_ 4. Scroll down to the `Configure Security Questions` section 5. Click on `Edit`6. Click on each `Question` - From the drop-down select an appropriate question- Click on the `Answer` section- Enter an appropriate answer - Follow process for all 3 questions 7. Click `Update` when complete 8. Save Questions and Answers and place in a secure physical location","AdditionalInformation": ""}],"description": "Ensure security questions are registered in the AWS account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.4": {"name": "1.4","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "http://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html:http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html:http://docs.aws.amazon.com/IAM/latest/APIReference/API_GetAccountSummary.html:https://aws.amazon.com/blogs/security/an-easier-way-to-determine-the-presence-of-aws-account-access-keys/","Description": "The 'root' user account is the most privileged user in an AWS account. AWS Access Keys provide programmatic access to a given AWS account. It is recommended that all access keys associated with the 'root' user account be removed.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has access keys:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on `Credential Report`5. This will download a `.csv` file which contains credential usage for all IAM users within an AWS Account - open this file 6. For the `` user, ensure the `access_key_1_active` and `access_key_2_active` fields are set to `FALSE` .**From Command Line:**Run the following command: ```aws iam get-account-summary | grep \"AccountAccessKeysPresent\"``` If no 'root' access keys exist the output will show \"AccountAccessKeysPresent\": 0,. If the output shows a \"1\" than 'root' keys exist, refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Removing access keys associated with the 'root' user account limits vectors by which the account can be compromised. Additionally, removing the 'root' access keys encourages the creation and use of role based accounts that are least privileged.","RemediationProcedure": "Perform the following to delete or disable active 'root' user access keys**From Console:**1. Sign in to the AWS Management Console as 'root' and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. Click on __ at the top right and select `My Security Credentials` from the drop down list 3. On the pop out screen Click on `Continue to Security Credentials`4. Click on `Access Keys` _(Access Key ID and Secret Access Key)_ 5. Under the `Status` column if there are any Keys which are Active- Click on `Make Inactive` - (Temporarily disable Key - may be needed again)- Click `Delete` - (Deleted keys cannot be recovered)","AdditionalInformation": "IAM User account \"root\" for us-gov cloud regions is not enabled by default. However, on request to AWS support enables 'root' access only through access-keys (CLI, API methods) for us-gov cloud region."}],"description": "Ensure no 'root' user account access key exists","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.5": {"name": "1.5","checks": {"iam_root_mfa_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#id_root-user_manage_mfa:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html#enable-virt-mfa-for-root","Description": "The 'root' user account is the most privileged user in an AWS account. Multi-factor Authentication (MFA) adds an extra layer of protection on top of a username and password. With MFA enabled, when a user signs in to an AWS website, they will be prompted for their username and password as well as for an authentication code from their AWS MFA device.**Note:** When virtual MFA is used for 'root' accounts, it is recommended that the device used is NOT a personal device, but rather a dedicated mobile device (tablet or phone) that is managed to be kept charged and secured independent of any individual personal devices. (\"non-personal virtual MFA\") This lessens the risks of losing access to the MFA due to device loss, device trade-in or if the individual owning the device is no longer employed at the company.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has MFA setup:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on `Credential Report`5. This will download a `.csv` file which contains credential usage for all IAM users within an AWS Account - open this file 6. For the `` user, ensure the `mfa_active` field is set to `TRUE` .**From Command Line:**1. Run the following command: ```aws iam get-account-summary | grep \"AccountMFAEnabled\" ``` 2. Ensure the AccountMFAEnabled property is set to 1","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling MFA provides increased security for console access as it requires the authenticating principal to possess a device that emits a time-sensitive key and have knowledge of a credential.","RemediationProcedure": "Perform the following to establish MFA for the 'root' user account:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). Note: to manage MFA devices for the 'root' AWS account, you must use your 'root' account credentials to sign in to AWS. You cannot manage MFA devices for the 'root' account using other credentials.2. Choose `Dashboard` , and under `Security Status` , expand `Activate MFA` on your root account. 3. Choose `Activate MFA`4. In the wizard, choose `A virtual MFA` device and then choose `Next Step` . 5. IAM generates and displays configuration information for the virtual MFA device, including a QR code graphic. The graphic is a representation of the 'secret configuration key' that is available for manual entry on devices that do not support QR codes. 6. Open your virtual MFA application. (For a list of apps that you can use for hosting virtual MFA devices, see [Virtual MFA Applications](http://aws.amazon.com/iam/details/mfa/#Virtual_MFA_Applications).) If the virtual MFA application supports multiple accounts (multiple virtual MFA devices), choose the option to create a new account (a new virtual MFA device). 7. Determine whether the MFA app supports QR codes, and then do one of the following: - Use the app to scan the QR code. For example, you might choose the camera icon or choose an option similar to Scan code, and then use the device's camera to scan the code.- In the Manage MFA Device wizard, choose Show secret key for manual configuration, and then type the secret configuration key into your MFA application.When you are finished, the virtual MFA device starts generating one-time passwords.In the Manage MFA Device wizard, in the Authentication Code 1 box, type the one-time password that currently appears in the virtual MFA device. Wait up to 30 seconds for the device to generate a new one-time password. Then type the second one-time password into the Authentication Code 2 box. Choose Assign Virtual MFA.","AdditionalInformation": "IAM User account \"root\" for us-gov cloud regions does not have console access. This recommendation is not applicable for us-gov cloud regions."}],"description": "Ensure MFA is enabled for the 'root' user account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.6": {"name": "1.6","checks": {"iam_root_hardware_mfa_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_physical.html#enable-hw-mfa-for-root","Description": "The 'root' user account is the most privileged user in an AWS account. MFA adds an extra layer of protection on top of a user name and password. With MFA enabled, when a user signs in to an AWS website, they will be prompted for their user name and password as well as for an authentication code from their AWS MFA device. For Level 2, it is recommended that the 'root' user account be protected with a hardware MFA.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has a hardware MFA setup:1. Run the following command to determine if the 'root' account has MFA setup: ```aws iam get-account-summary | grep \"AccountMFAEnabled\" ```The `AccountMFAEnabled` property is set to `1` will ensure that the 'root' user account has MFA (Virtual or Hardware) Enabled. If `AccountMFAEnabled` property is set to `0` the account is not compliant with this recommendation.2. If `AccountMFAEnabled` property is set to `1`, determine 'root' account has Hardware MFA enabled. Run the following command to list all virtual MFA devices: ```aws iam list-virtual-mfa-devices``` If the output contains one MFA with the following Serial Number, it means the MFA is virtual, not hardware and the account is not compliant with this recommendation: `\"SerialNumber\": \"arn:aws:iam::__:mfa/root-account-mfa-device\"`","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "A hardware MFA has a smaller attack surface than a virtual MFA. For example, a hardware MFA does not suffer the attack surface introduced by the mobile smartphone on which a virtual MFA resides.**Note**: Using hardware MFA for many, many AWS accounts may create a logistical device management issue. If this is the case, consider implementing this Level 2 recommendation selectively to the highest security AWS accounts and the Level 1 recommendation applied to the remaining accounts.","RemediationProcedure": "Perform the following to establish a hardware MFA for the 'root' user account:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). Note: to manage MFA devices for the AWS 'root' user account, you must use your 'root' account credentials to sign in to AWS. You cannot manage MFA devices for the 'root' account using other credentials. 2. Choose `Dashboard` , and under `Security Status` , expand `Activate MFA` on your root account. 3. Choose `Activate MFA`4. In the wizard, choose `A hardware MFA` device and then choose `Next Step` . 5. In the `Serial Number` box, enter the serial number that is found on the back of the MFA device. 6. In the `Authentication Code 1` box, enter the six-digit number displayed by the MFA device. You might need to press the button on the front of the device to display the number. 7. Wait 30 seconds while the device refreshes the code, and then enter the next six-digit number into the `Authentication Code 2` box. You might need to press the button on the front of the device again to display the second number. 8. Choose `Next Step` . The MFA device is now associated with the AWS account. The next time you use your AWS account credentials to sign in, you must type a code from the hardware MFA device.Remediation for this recommendation is not available through AWS CLI.","AdditionalInformation": "IAM User account 'root' for us-gov cloud regions does not have console access. This control is not applicable for us-gov cloud regions."}],"description": "Ensure hardware MFA is enabled for the 'root' user account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.7": {"name": "1.7","checks": {"iam_avoid_root_usage": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html:https://docs.aws.amazon.com/general/latest/gr/aws_tasks-that-require-root.html","Description": "With the creation of an AWS account, a 'root user' is created that cannot be disabled or deleted. That user has unrestricted access to and control over all resources in the AWS account. It is highly recommended that the use of this account be avoided for everyday tasks.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console at `https://console.aws.amazon.com/iam/` 2. In the left pane, click `Credential Report` 3. Click on `Download Report` 4. Open of Save the file locally 5. Locate the `` under the user column 6. Review `password_last_used, access_key_1_last_used_date, access_key_2_last_used_date` to determine when the 'root user' was last used.**From Command Line:**Run the following CLI commands to provide a credential report for determining the last time the 'root user' was used: ``` aws iam generate-credential-report ``` ``` aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,5,11,16 | grep -B1 '' ```Review `password_last_used`, `access_key_1_last_used_date`, `access_key_2_last_used_date` to determine when the _root user_ was last used.**Note:** There are a few conditions under which the use of the 'root' user account is required. Please see the reference links for all of the tasks that require use of the 'root' user.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "The 'root user' has unrestricted access to and control over all account resources. Use of it is inconsistent with the principles of least privilege and separation of duties, and can lead to unnecessary harm due to error or account compromise.","RemediationProcedure": "If you find that the 'root' user account is being used for daily activity to include administrative tasks that do not require the 'root' user:1. Change the 'root' user password. 2. Deactivate or delete any access keys associate with the 'root' user.**Remember, anyone who has 'root' user credentials for your AWS account has unrestricted access to and control of all the resources in your account, including billing information.","AdditionalInformation": "The 'root' user for us-gov cloud regions is not enabled by default. However, on request to AWS support, they can enable the 'root' user and grant access only through access-keys (CLI, API methods) for us-gov cloud region. If the 'root' user for us-gov cloud regions is enabled, this recommendation is applicable.Monitoring usage of the 'root' user can be accomplished by implementing recommendation 3.3 Ensure a log metric filter and alarm exist for usage of the 'root' user."}],"description": "Eliminate use of the 'root' user for administrative and daily tasks","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.8": {"name": "1.8","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy","Description": "Password policies are, in part, used to enforce password complexity requirements. IAM password policies can be used to ensure password are at least a given length. It is recommended that the password policy require a minimum password length 14.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure the password policy is configured as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Ensure \"Minimum password length\" is set to 14 or greater.**From Command Line:** ``` aws iam get-account-password-policy ``` Ensure the output of the above command includes \"MinimumPasswordLength\": 14 (or higher)","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Setting a password complexity policy increases account resiliency against brute force login attempts.","RemediationProcedure": "Perform the following to set the password policy as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Set \"Minimum password length\" to `14` or greater. 5. Click \"Apply password policy\"**From Command Line:** ```aws iam update-account-password-policy --minimum-password-length 14 ``` Note: All commands starting with \"aws iam update-account-password-policy\" can be combined into a single command.","AdditionalInformation": ""}],"description": "Ensure IAM password policy requires minimum length of 14 or greater","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.9": {"name": "1.9","checks": {"iam_password_policy_reuse_24": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy","Description": "IAM password policies can prevent the reuse of a given password by the same user. It is recommended that the password policy prevent the reuse of passwords.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure the password policy is configured as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Ensure \"Prevent password reuse\" is checked 5. Ensure \"Number of passwords to remember\" is set to 24**From Command Line:** ``` aws iam get-account-password-policy``` Ensure the output of the above command includes \"PasswordReusePrevention\": 24","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Preventing password reuse increases account resiliency against brute force login attempts.","RemediationProcedure": "Perform the following to set the password policy as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Check \"Prevent password reuse\" 5. Set \"Number of passwords to remember\" is set to `24` **From Command Line:** ```aws iam update-account-password-policy --password-reuse-prevention 24 ``` Note: All commands starting with \"aws iam update-account-password-policy\" can be combined into a single command.","AdditionalInformation": ""}],"description": "Ensure IAM password policy prevents password reuse","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.1": {"name": "3.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-management-events:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-management-and-data-events-with-cloudtrail.html?icmpid=docs_cloudtrail_console#logging-management-events:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-supported-services.html#cloud-trail-supported-services-data-events","Description": "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. CloudTrail provides a history of AWS API calls for an account, including API calls made via the Management Console, SDKs, command line tools, and higher-level AWS services (such as CloudFormation).","DefaultValue": null,"AuditProcedure": "Perform the following to determine if CloudTrail is enabled for all regions:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane- You will be presented with a list of trails across all regions 3. Ensure at least one Trail has `All` specified in the `Region` column 4. Click on a trail via the link in the _Name_ column 5. Ensure `Logging` is set to `ON`6. Ensure `Apply trail to all regions` is set to `Yes` 7. In section `Management Events` ensure `Read/Write Events` set to `ALL`**From Command Line:** ```aws cloudtrail describe-trails ``` Ensure `IsMultiRegionTrail` is set to `true```` aws cloudtrail get-trail-status --name  ``` Ensure `IsLogging` is set to `true` ``` aws cloudtrail get-event-selectors --trail-name  ``` Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`","ImpactStatement": "S3 lifecycle features can be used to manage the accumulation and management of logs over time. See the following AWS resource for more information on these features:1. https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html","AssessmentStatus": "Automated","RationaleStatement": "The AWS API call history produced by CloudTrail enables security analysis, resource change tracking, and compliance auditing. Additionally, - ensuring that a multi-regions trail exists will ensure that unexpected activity occurring in otherwise unused regions is detected- ensuring that a multi-regions trail exists will ensure that `Global Service Logging` is enabled for a trail by default to capture recording of events generated onAWS global services- for a multi-regions trail, ensuring that management events configured for all type of Read/Writes ensures recording of management operations that are performed on all resources in an AWS account","RemediationProcedure": "Perform the following to enable global (Multi-region) CloudTrail logging:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on _Trails_ on the left navigation pane 3. Click `Get Started Now` , if presented- Click `Add new trail` - Enter a trail name in the `Trail name` box- Set the `Apply trail to all regions` option to `Yes` - Specify an S3 bucket name in the `S3 bucket` box- Click `Create`4. If 1 or more trails already exist, select the target trail to enable for global logging 5. Click the edit icon (pencil) next to `Apply trail to all regions` , Click `Yes` and Click `Save`. 6. Click the edit icon (pencil) next to `Management Events` click `All` for setting `Read/Write Events` and Click `Save`.**From Command Line:** ``` aws cloudtrail create-trail --name  --bucket-name  --is-multi-region-trailaws cloudtrail update-trail --name  --is-multi-region-trail ```Note: Creating CloudTrail via CLI without providing any overriding options configures `Management Events` to set `All` type of `Read/Writes` by default.","AdditionalInformation": ""}],"description": "Ensure CloudTrail is enabled in all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3.2": {"name": "3.2","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-file-validation-enabling.html","Description": "CloudTrail log file validation creates a digitally signed digest file containing a hash of each log that CloudTrail writes to S3. These digest files can be used to determine whether a log file was changed, deleted, or unchanged after CloudTrail delivered the log. It is recommended that file validation be enabled on all CloudTrails.","DefaultValue": null,"AuditProcedure": "Perform the following on each trail to determine if log file validation is enabled:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane 3. For Every Trail: - Click on a trail via the link in the _Name_ column - Under the `General details` section, ensure `Log file validation` is set to `Enabled` **From Command Line:** ``` aws cloudtrail describe-trails ``` Ensure `LogFileValidationEnabled` is set to `true` for each trail","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling log file validation will provide additional integrity checking of CloudTrail logs.","RemediationProcedure": "Perform the following to enable log file validation on a given trail:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane 3. Click on target trail 4. Within the `General details` section click `edit` 5. Under the `Advanced settings` section 6. Check the enable box under `Log file validation`7. Click `Save changes` **From Command Line:** ``` aws cloudtrail update-trail --name  --enable-log-file-validation ``` Note that periodic validation of logs using these digests can be performed by running the following command: ``` aws cloudtrail validate-logs --trail-arn  --start-time  --end-time  ```","AdditionalInformation": ""}],"description": "Ensure CloudTrail log file validation is enabled","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.3": {"name": "3.3","checks": {"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html","Description": "CloudTrail logs a record of every API call made in your AWS account. These logs file are stored in an S3 bucket. It is recommended that the bucket policy or access control list (ACL) applied to the S3 bucket that CloudTrail logs to prevent public access to the CloudTrail logs.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if any public access is granted to an S3 bucket via an ACL or S3 bucket policy:**From Console:**1. Go to the Amazon CloudTrail console at [https://console.aws.amazon.com/cloudtrail/home](https://console.aws.amazon.com/cloudtrail/home) 2. In the `API activity history` pane on the left, click `Trails`3. In the `Trails` pane, note the bucket names in the `S3 bucket` column 4. Go to Amazon S3 console at [https://console.aws.amazon.com/s3/home](https://console.aws.amazon.com/s3/home) 5. For each bucket noted in step 3, right-click on the bucket and click `Properties`6. In the `Properties` pane, click the `Permissions` tab. 7. The tab shows a list of grants, one row per grant, in the bucket ACL. Each row identifies the grantee and the permissions granted. 8. Ensure no rows exists that have the `Grantee` set to `Everyone` or the `Grantee` set to `Any Authenticated User.`9. If the `Edit bucket policy` button is present, click it to review the bucket policy. 10. Ensure the policy does not contain a `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ```aws cloudtrail describe-trails --query 'trailList[*].S3BucketName' ``` 2. Ensure the `AllUsers` principal is not granted privileges to that `` : ```aws s3api get-bucket-acl --bucket  --query 'Grants[?Grantee.URI== `https://acs.amazonaws.com/groups/global/AllUsers` ]' ``` 3. Ensure the `AuthenticatedUsers` principal is not granted privileges to that ``: ```aws s3api get-bucket-acl --bucket  --query 'Grants[?Grantee.URI== `https://acs.amazonaws.com/groups/global/Authenticated Users` ]' ``` 4. Get the S3 Bucket Policy ```aws s3api get-bucket-policy --bucket ``` 5. Ensure the policy does not contain a `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}**Note:** Principal set to \"\\*\" or {\"AWS\" : \"\\*\"} allows anonymous access.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Allowing public access to CloudTrail log content may aid an adversary in identifying weaknesses in the affected account's use or configuration.","RemediationProcedure": "Perform the following to remove any public access that has been granted to the bucket via an ACL or S3 bucket policy:1. Go to Amazon S3 console at [https://console.aws.amazon.com/s3/home](https://console.aws.amazon.com/s3/home) 2. Right-click on the bucket and click Properties 3. In the `Properties` pane, click the `Permissions` tab. 4. The tab shows a list of grants, one row per grant, in the bucket ACL. Each row identifies the grantee and the permissions granted. 5. Select the row that grants permission to `Everyone` or `Any Authenticated User`6. Uncheck all the permissions granted to `Everyone` or `Any Authenticated User` (click `x` to delete the row). 7. Click `Save` to save the ACL. 8. If the `Edit bucket policy` button is present, click it. 9. Remove any `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}.","AdditionalInformation": ""}],"description": "Ensure the S3 bucket used to store CloudTrail logs is not publicly accessible","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3.4": {"name": "3.4","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-user-guide.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/how-cloudtrail-works.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-aws-service-specific-topics.html","Description": "AWS CloudTrail is a web service that records AWS API calls made in a given AWS account. 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. CloudTrail uses Amazon S3 for log file storage and delivery, so log files are stored durably. In addition to capturing CloudTrail logs within a specified S3 bucket for long term analysis, realtime analysis can be performed by configuring CloudTrail to send logs to CloudWatch Logs. For a trail that is enabled in all regions in an account, CloudTrail sends log files from all those regions to a CloudWatch Logs log group. It is recommended that CloudTrail logs be sent to CloudWatch Logs.Note: The intent of this recommendation is to ensure AWS account activity is being captured, monitored, and appropriately alarmed on. CloudWatch Logs is a native way to accomplish this using AWS services but does not preclude the use of an alternate solution.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure CloudTrail is configured as prescribed:**From Console:**1. Login to the CloudTrail console at `https://console.aws.amazon.com/cloudtrail/` 2. Under `Trails` , click on the CloudTrail you wish to evaluate 3. Under the `CloudWatch Logs` section. 4. Ensure a `CloudWatch Logs` log group is configured and listed. 5. Under `General details` confirm `Last log file delivered` has a recent (~one day old) timestamp.**From Command Line:**1. Run the following command to get a listing of existing trails: ```aws cloudtrail describe-trails ``` 2. Ensure `CloudWatchLogsLogGroupArn` is not empty and note the value of the `Name` property. 3. Using the noted value of the `Name` property, run the following command: ```aws cloudtrail get-trail-status --name  ``` 4. Ensure the `LatestcloudwatchLogdDeliveryTime` property is set to a recent (~one day old) timestamp.If the `CloudWatch Logs` log group is not setup and the delivery time is not recent refer to the remediation below.","ImpactStatement": "Note: By default, CloudWatch Logs will store Logs indefinitely unless a specific retention period is defined for the log group. When choosing the number of days to retain, keep in mind the average days it takes an organization to realize they have been breached is 210 days (at the time of this writing). Since additional time is required to research a breach, a minimum 365 day retention policy allows time for detection and research. You may also wish to archive the logs to a cheaper storage service rather than simply deleting them. See the following AWS resource to manage CloudWatch Logs retention periods:1. https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/SettingLogRetention.html","AssessmentStatus": "Automated","RationaleStatement": "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.","RemediationProcedure": "Perform the following to establish the prescribed state:**From Console:**1. Login to the CloudTrail console at `https://console.aws.amazon.com/cloudtrail/` 2. Select the `Trail` the needs to be updated. 3. Scroll down to `CloudWatch Logs` 4. Click `Edit` 5. Under `CloudWatch Logs` click the box `Enabled` 6. Under `Log Group` pick new or select an existing log group 7. Edit the `Log group name` to match the CloudTrail or pick the existing CloudWatch Group. 8. Under `IAM Role` pick new or select an existing. 9. Edit the `Role name` to match the CloudTrail or pick the existing IAM Role. 10. Click `Save changes.**From Command Line:** ``` aws cloudtrail update-trail --name  --cloudwatch-logs-log-group-arn  --cloudwatch-logs-role-arn  ```","AdditionalInformation": ""}],"description": "Ensure CloudTrail trails are integrated with CloudWatch Logs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.5": {"name": "3.5","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/cli/latest/reference/configservice/describe-configuration-recorder-status.html","Description": "AWS Config is a web service that performs configuration management of supported AWS resources within your account and delivers log files to you. The recorded information includes the configuration item (AWS resource), relationships between configuration items (AWS resources), any configuration changes between resources. It is recommended AWS Config be enabled in all regions.","DefaultValue": null,"AuditProcedure": "Process to evaluate AWS Config configuration per region**From Console:**1. Sign in to the AWS Management Console and open the AWS Config console at [https://console.aws.amazon.com/config/](https://console.aws.amazon.com/config/). 2. On the top right of the console select target Region. 3. If presented with Setup AWS Config - follow remediation procedure: 4. On the Resource inventory page, Click on edit (the gear icon). The Set Up AWS Config page appears. 5. Ensure 1 or both check-boxes under \"All Resources\" is checked.- Include global resources related to IAM resources - which needs to be enabled in 1 region only 6. Ensure the correct S3 bucket has been defined. 7. Ensure the correct SNS topic has been defined. 8. Repeat steps 2 to 7 for each region.**From Command Line:**1. Run this command to show all AWS Config recorders and their properties: ``` aws configservice describe-configuration-recorders ``` 2. Evaluate the output to ensure that there's at least one recorder for which `recordingGroup` object includes `\"allSupported\": true` AND `\"includeGlobalResourceTypes\": true`Note: There is one more parameter \"ResourceTypes\" in recordingGroup object. We don't need to check the same as whenever we set \"allSupported\": true, AWS enforces resource types to be empty (\"ResourceTypes\":[])Sample Output:``` {\"ConfigurationRecorders\": [{\"recordingGroup\": {\"allSupported\": true,\"resourceTypes\": [],\"includeGlobalResourceTypes\": true},\"roleARN\": \"arn:aws:iam:::role/service-role/\",\"name\": \"default\"}] } ```3. Run this command to show the status for all AWS Config recorders: ``` aws configservice describe-configuration-recorder-status ``` 4. In the output, find recorders with `name` key matching the recorders that met criteria in step 2. Ensure that at least one of them includes `\"recording\": true` and `\"lastStatus\": \"SUCCESS\"`","ImpactStatement": "It is recommended AWS Config be enabled in all regions.","AssessmentStatus": "Automated","RationaleStatement": "The AWS configuration item history captured by AWS Config enables security analysis, resource change tracking, and compliance auditing.","RemediationProcedure": "To implement AWS Config configuration:**From Console:**1. Select the region you want to focus on in the top right of the console 2. Click `Services`3. Click `Config`4. Define which resources you want to record in the selected region 5. Choose to include global resources (IAM resources) 6. Specify an S3 bucket in the same account or in another managed AWS account 7. Create an SNS Topic from the same AWS account or another managed AWS account**From Command Line:**1. Ensure there is an appropriate S3 bucket, SNS topic, and IAM role per the [AWS Config Service prerequisites](http://docs.aws.amazon.com/config/latest/developerguide/gs-cli-prereq.html). 2. Run this command to set up the configuration recorder ``` aws configservice subscribe --s3-bucket my-config-bucket --sns-topic arn:aws:sns:us-east-1:012345678912:my-config-notice --iam-role arn:aws:iam::012345678912:role/myConfigRole ``` 3. Run this command to start the configuration recorder: ``` start-configuration-recorder --configuration-recorder-name  ```","AdditionalInformation": ""}],"description": "Ensure AWS Config is enabled in all regions","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.6": {"name": "3.6","checks": {"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerLogs.html","Description": "S3 Bucket Access Logging generates a log that contains access records for each request made to your S3 bucket. An access log record contains details about the request, such as the request type, the resources specified in the request worked, and the time and date the request was processed. It is recommended that bucket access logging be enabled on the CloudTrail S3 bucket.","DefaultValue": null,"AuditProcedure": "Perform the following ensure the CloudTrail S3 bucket has access logging is enabled:**From Console:**1. Go to the Amazon CloudTrail console at [https://console.aws.amazon.com/cloudtrail/home](https://console.aws.amazon.com/cloudtrail/home) 2. In the API activity history pane on the left, click Trails 3. In the Trails pane, note the bucket names in the S3 bucket column 4. Sign in to the AWS Management Console and open the S3 console at [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3). 5. Under `All Buckets` click on a target S3 bucket 6. Click on `Properties` in the top right of the console 7. Under `Bucket:` _ `` _ click on `Logging`8. Ensure `Enabled` is checked.**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ```aws cloudtrail describe-trails --query 'trailList[*].S3BucketName'``` 2. Ensure Bucket Logging is enabled: ``` aws s3api get-bucket-logging --bucket  ``` Ensure command does not returns empty output.Sample Output for a bucket with logging enabled:``` {\"LoggingEnabled\": {\"TargetPrefix\": \"\",\"TargetBucket\": \"\"} } ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "By enabling S3 bucket logging on target S3 buckets, it is possible to capture all events which may affect objects within any target buckets. Configuring logs to be placed in a separate bucket allows access to log information which can be useful in security and incident response workflows.","RemediationProcedure": "Perform the following to enable S3 bucket logging:**From Console:**1. Sign in to the AWS Management Console and open the S3 console at [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3). 2. Under `All Buckets` click on the target S3 bucket 3. Click on `Properties` in the top right of the console 4. Under `Bucket:`  click on `Logging`5. Configure bucket logging- Click on the `Enabled` checkbox- Select Target Bucket from list- Enter a Target Prefix 6. Click `Save`.**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ``` aws cloudtrail describe-trails --region  --query trailList[*].S3BucketName ``` 2. Copy and add target bucket name at ``, Prefix for logfile at `` and optionally add an email address in the following template and save it as ``: ``` {\"LoggingEnabled\": {\"TargetBucket\": \"\",\"TargetPrefix\": \"\",\"TargetGrants\": [{\"Grantee\": {\"Type\": \"AmazonCustomerByEmail\",\"EmailAddress\": \"\"},\"Permission\": \"FULL_CONTROL\"}]}} ``` 3. Run the `put-bucket-logging` command with bucket name and `` as input, for more information refer at [put-bucket-logging](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-logging.html): ``` aws s3api put-bucket-logging --bucket  --bucket-logging-status file:// ```","AdditionalInformation": ""}],"description": "Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.7": {"name": "3.7","checks": {"cloudtrail_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/encrypting-cloudtrail-log-files-with-aws-kms.html:https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html","Description": "AWS CloudTrail is a web service that records AWS API calls for an account and makes those logs available to users and resources in accordance with IAM policies. AWS Key Management Service (KMS) is a managed service that helps create and control the encryption keys used to encrypt account data, and uses Hardware Security Modules (HSMs) to protect the security of encryption keys. CloudTrail logs can be configured to leverage server side encryption (SSE) and KMS customer created master keys (CMK) to further protect CloudTrail logs. It is recommended that CloudTrail be configured to use SSE-KMS.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if CloudTrail is configured to use SSE-KMS:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. In the left navigation pane, choose `Trails` . 3. Select a Trail 4. Under the `S3` section, ensure `Encrypt log files` is set to `Yes` and a KMS key ID is specified in the `KSM Key Id` field.**From Command Line:**1. Run the following command: ```aws cloudtrail describe-trails``` 2. For each trail listed, SSE-KMS is enabled if the trail has a `KmsKeyId` property defined.","ImpactStatement": "Customer created keys incur an additional cost. See https://aws.amazon.com/kms/pricing/ for more information.","AssessmentStatus": "Automated","RationaleStatement": "Configuring CloudTrail to use SSE-KMS provides additional confidentiality controls on log data as a given user must have S3 read permission on the corresponding log bucket and must be granted decrypt permission by the CMK policy.","RemediationProcedure": "Perform the following to configure CloudTrail to use SSE-KMS:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. In the left navigation pane, choose `Trails` . 3. Click on a Trail 4. Under the `S3` section click on the edit button (pencil icon) 5. Click `Advanced`6. Select an existing CMK from the `KMS key Id` drop-down menu- Note: Ensure the CMK is located in the same region as the S3 bucket- Note: You will need to apply a KMS Key policy on the selected CMK in order for CloudTrail as a service to encrypt and decrypt log files using the CMK provided. Steps are provided [here](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/create-kms-key-policy-for-cloudtrail.html) for editing the selected CMK Key policy 7. Click `Save`8. You will see a notification message stating that you need to have decrypt permissions on the specified KMS key to decrypt log files. 9. Click `Yes` **From Command Line:** ``` aws cloudtrail update-trail --name  --kms-id  aws kms put-key-policy --key-id  --policy  ```","AdditionalInformation": "3 statements which need to be added to the CMK policy:1\\. Enable Cloudtrail to describe CMK properties ``` 
{\"Sid\": \"Allow CloudTrail access\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\"Action\": \"kms:DescribeKey\",\"Resource\": \"*\" } ``` 2\\. Granting encrypt permissions ``` 
{\"Sid\": \"Allow CloudTrail to encrypt logs\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\"Action\": \"kms:GenerateDataKey*\",\"Resource\": \"*\",\"Condition\": {\"StringLike\": {\"kms:EncryptionContext:aws:cloudtrail:arn\": [\"arn:aws:cloudtrail:*:aws-account-id:trail/*\"]}} } ``` 3\\. Granting decrypt permissions ``` 
{\"Sid\": \"Enable CloudTrail log decrypt permissions\",\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"arn:aws:iam::aws-account-id:user/username\"},\"Action\": \"kms:Decrypt\",\"Resource\": \"*\",\"Condition\": {\"Null\": {\"kms:EncryptionContext:aws:cloudtrail:arn\": \"false\"}} } ```"}],"description": "Ensure CloudTrail logs are encrypted at rest using KMS CMKs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.8": {"name": "3.8","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://aws.amazon.com/kms/pricing/:https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final","Description": "AWS Key Management Service (KMS) allows customers to rotate the backing key which is key material stored within the KMS which is tied to the key ID of the Customer Created customer master key (CMK). It is the backing key that is used to perform cryptographic operations such as encryption and decryption. Automated key rotation currently retains all prior backing keys so that decryption of encrypted data can take place transparently. It is recommended that CMK key rotation be enabled for symmetric keys. Key rotation can not be enabled for any asymmetric CMK.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam](https://console.aws.amazon.com/iam). 2. In the left navigation pane, choose `Customer managed keys` 3. Select a customer managed CMK where `Key spec = SYMMETRIC_DEFAULT` 4. Underneath the `General configuration` panel open the tab `Key rotation` 5. Ensure that the checkbox `Automatically rotate this KMS key every year.` is activated 6. Repeat steps 3 - 5 for all customer managed CMKs where \"Key spec = SYMMETRIC_DEFAULT\"**From Command Line:**1. Run the following command to get a list of all keys and their associated `KeyIds````aws kms list-keys ``` 2. For each key, note the KeyId and run the following command ``` describe-key --key-id  ``` 3. If the response contains \"KeySpec = SYMMETRIC_DEFAULT\" run the following command ```aws kms get-key-rotation-status --key-id  ``` 4. Ensure `KeyRotationEnabled` is set to `true` 5. Repeat steps 2 - 4 for all remaining CMKs","ImpactStatement": "Creation, management, and storage of CMKs may require additional time from and administrator.","AssessmentStatus": "Automated","RationaleStatement": "Rotating encryption keys helps reduce the potential impact of a compromised key as data encrypted with a new key cannot be accessed with a previous key that may have been exposed. Keys should be rotated every year, or upon event that would result in the compromise of that key.","RemediationProcedure": "**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam](https://console.aws.amazon.com/iam). 2. In the left navigation pane, choose `Customer managed keys` . 3. Select a customer managed CMK where `Key spec = SYMMETRIC_DEFAULT` 4. Underneath the \"General configuration\" panel open the tab \"Key rotation\" 5. Check the \"Automatically rotate this KMS key every year.\" checkbox**From Command Line:**1. Run the following command to enable key rotation: ```aws kms enable-key-rotation --key-id  ```","AdditionalInformation": ""}],"description": "Ensure rotation for customer created symmetric CMKs is enabled","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.9": {"name": "3.9","checks": {"vpc_flow_logs_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/flow-logs.html","Description": "VPC Flow Logs is a feature that enables you to capture information about the IP traffic going to and from network interfaces in your VPC. After you've created a flow log, you can view and retrieve its data in Amazon CloudWatch Logs. It is recommended that VPC Flow Logs be enabled for packet \"Rejects\" for VPCs.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if VPC Flow logs are enabled:**From Console:**1. Sign into the management console 2. Select `Services` then `VPC`3. In the left navigation pane, select `Your VPCs`4. Select a VPC 5. In the right pane, select the `Flow Logs` tab. 6. Ensure a Log Flow exists that has `Active` in the `Status` column.**From Command Line:**1. Run `describe-vpcs` command (OSX/Linux/UNIX) to list the VPC networks available in the current AWS region: ``` aws ec2 describe-vpcs --region  --query Vpcs[].VpcId ``` 2. The command output returns the `VpcId` available in the selected region. 3. Run `describe-flow-logs` command (OSX/Linux/UNIX) using the VPC ID to determine if the selected virtual network has the Flow Logs feature enabled: ``` aws ec2 describe-flow-logs --filter \"Name=resource-id,Values=\" ``` 4. If there are no Flow Logs created for the selected VPC, the command output will return an `empty list []`. 5. Repeat step 3 for other VPCs available in the same region. 6. Change the region by updating `--region` and repeat steps 1 - 5 for all the VPCs.","ImpactStatement": "By default, CloudWatch Logs will store Logs indefinitely unless a specific retention period is defined for the log group. When choosing the number of days to retain, keep in mind the average days it takes an organization to realize they have been breached is 210 days (at the time of this writing). Since additional time is required to research a breach, a minimum 365 day retention policy allows time for detection and research. You may also wish to archive the logs to a cheaper storage service rather than simply deleting them. See the following AWS resource to manage CloudWatch Logs retention periods:1. https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/SettingLogRetention.html","AssessmentStatus": "Automated","RationaleStatement": "VPC Flow Logs provide visibility into network traffic that traverses the VPC and can be used to detect anomalous traffic or insight during security workflows.","RemediationProcedure": "Perform the following to determine if VPC Flow logs is enabled:**From Console:**1. Sign into the management console 2. Select `Services` then `VPC`3. In the left navigation pane, select `Your VPCs`4. Select a VPC 5. In the right pane, select the `Flow Logs` tab. 6. If no Flow Log exists, click `Create Flow Log`7. For Filter, select `Reject` 8. Enter in a `Role` and `Destination Log Group`9. Click `Create Log Flow`10. Click on `CloudWatch Logs Group` **Note:** Setting the filter to \"Reject\" will dramatically reduce the logging data accumulation for this recommendation and provide sufficient information for the purposes of breach detection, research and remediation. However, during periods of least privilege security group engineering, setting this the filter to \"All\" can be very helpful in discovering existing traffic flows required for proper operation of an already running environment.**From Command Line:**1. Create a policy document and name it as `role_policy_document.json` and paste the following content: ``` {\"Version\": \"2012-10-17\",\"Statement\": [{\"Sid\": \"test\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"ec2.amazonaws.com\"},\"Action\": \"sts:AssumeRole\"}] } ``` 2. Create another policy document and name it as `iam_policy.json` and paste the following content: ``` {\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Action\":[\"logs:CreateLogGroup\",\"logs:CreateLogStream\",\"logs:DescribeLogGroups\",\"logs:DescribeLogStreams\",\"logs:PutLogEvents\",\"logs:GetLogEvents\",\"logs:FilterLogEvents\"],\"Resource\": \"*\"}] } ``` 3. Run the below command to create an IAM role: ``` aws iam create-role --role-name  --assume-role-policy-document file://role_policy_document.json``` 4. Run the below command to create an IAM policy: ``` aws iam create-policy --policy-name  --policy-document file://iam-policy.json ``` 5. Run `attach-group-policy` command using the IAM policy ARN returned at the previous step to attach the policy to the IAM role (if the command succeeds, no output is returned): ``` aws iam attach-group-policy --policy-arn arn:aws:iam:::policy/ --group-name  ``` 6. Run `describe-vpcs` to get the VpcId available in the selected region: ``` aws ec2 describe-vpcs --region  ``` 7. The command output should return the VPC Id available in the selected region. 8. Run `create-flow-logs` to create a flow log for the vpc: ``` aws ec2 create-flow-logs --resource-type VPC --resource-ids  --traffic-type REJECT --log-group-name  --deliver-logs-permission-arn  ``` 9. Repeat step 8 for other vpcs available in the selected region. 10. Change the region by updating --region and repeat remediation procedure for other vpcs.","AdditionalInformation": ""}],"description": "Ensure VPC flow logging is enabled in all VPCs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"4.1": {"name": "4.1","checks": {"cloudwatch_log_metric_filter_unauthorized_api_calls": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://aws.amazon.com/sns/:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for unauthorized API calls.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with \"Name\":` note ``- From value associated with \"CloudWatchLogsLogGroupArn\" note Example: for CloudWatchLogsLogGroupArn that looks like arn:aws:logs:::log-group:NewGroup:*,  would be NewGroup- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name <\"Name\" as shown in describe-trails>`Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this `` that you captured in step 1:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.errorCode = *UnauthorizedOperation) || ($.errorCode = AccessDenied*) || ($.sourceIPAddress!=delivery.logs.amazonaws.com) || ($.eventName!=HeadBucket) }\", ```4. Note the \"filterName\" `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query \"MetricAlarms[?MetricName == `unauthorized_api_calls_metric`]\" ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "This alert may be triggered by normal read-only console activities that attempt to opportunistically gather optional information, but gracefully fail if they don't have permissions.If an excessive number of alerts are being generated then an organization may wish to consider adding read access to the limited IAM user permissions simply to quiet the alerts.In some cases doing this may allow the users to actually view some areas of the system - any additional access given should be reviewed for alignment with the original limited IAM user intent.","AssessmentStatus": "Automated","RationaleStatement": "Monitoring unauthorized API calls will help reveal application errors and may reduce time to detect malicious activity.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for unauthorized API calls and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name \"cloudtrail_log_group_name\" --filter-name \"\" --metric-transformations metricName=unauthorized_api_calls_metric,metricNamespace=CISBenchmark,metricValue=1 --filter-pattern \"{ ($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\") || ($.sourceIPAddress!=\"delivery.logs.amazonaws.com\") || ($.eventName!=\"HeadBucket\") }\" ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms. **Note**: Capture the TopicArn displayed when creating the SNS Topic in Step 2.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name \"unauthorized_api_calls_alarm\" --metric-name \"unauthorized_api_calls_metric\" --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace \"CISBenchmark\" --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for unauthorized API calls","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.2": {"name": "4.2","checks": {"cloudwatch_log_metric_filter_sign_in_without_mfa": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/viewing_metrics_with_cloudwatch.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for console logins that are not protected by multi-factor authentication (MFA).","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all `CloudTrails`:``` aws cloudtrail describe-trails ```- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region `CloudTrail` is active``` aws cloudtrail get-trail-status --name  ```Ensure in the output that `IsLogging` is set to `TRUE`- Ensure identified Multi-region 'Cloudtrail' captures all Management Events``` aws cloudtrail get-event-selectors --trail-name  ```Ensure in the output there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }\" ```Or (To reduce false positives incase Single Sign-On (SSO) is used in organization):``` \"filterPattern\": \"{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\") }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring for single-factor console logins will increase visibility into accounts that are not protected by MFA.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Management Console sign-in without MFA and the `` taken from audit step 1.Use Command: ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }' ```Or (To reduce false positives incase Single Sign-On (SSO) is used in organization):``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\") }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored -Filter pattern set to `{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\"}` reduces false alarms raised when user logs in via SSO account."}],"description": "Ensure a log metric filter and alarm exist for Management Console sign-in without MFA","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.3": {"name": "4.3","checks": {"cloudwatch_log_metric_filter_root_usage": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for 'root' login attempts.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails:`aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring for 'root' account logins will provide visibility into the use of a fully privileged account and an opportunity to reduce the use of it.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for 'Root' account usage and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name `` --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "**Configuring log metric filter and alarm on Multi-region (global) CloudTrail**- ensures that activities from all regions (used as well as unused) are monitored- ensures that activities on all supported global services are monitored- ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for usage of 'root' account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.4": {"name": "4.4","checks": {"cloudwatch_log_metric_filter_policy_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established changes made to Identity and Access Management (IAM) policies.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails:`aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to IAM policies will help ensure authentication and authorization controls remain intact.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for IAM policy changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name `` --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for IAM policy changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.5": {"name": "4.5","checks": {"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for detecting changes to CloudTrail's configurations.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to CloudTrail's configuration will help ensure sustained visibility to activities performed in the AWS account.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for cloudtrail configuration changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for CloudTrail configuration changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.6": {"name": "4.6","checks": {"cloudwatch_log_metric_filter_authentication_failures": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for failed console authentication attempts.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring failed console logins may decrease lead time to detect an attempt to brute force a credential, which may provide an indicator, such as source IP, that can be used in other event correlation.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS management Console Login Failures and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }' ``` **Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for AWS Management Console authentication failures","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.7": {"name": "4.7","checks": {"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for customer created CMKs which have changed state to disabled or scheduled deletion.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Data encrypted with disabled or deleted keys will no longer be accessible.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for disabled or scheduled for deletion CMK's and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }' ``` **Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.8": {"name": "4.8","checks": {"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for changes to S3 bucket policies.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to S3 bucket policies may reduce time to detect and correct permissive policies on sensitive S3 buckets.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for S3 bucket policy changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for S3 bucket policy changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.9": {"name": "4.9","checks": {"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for detecting changes to CloudTrail's configurations.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to AWS Config configuration will help ensure sustained visibility of configuration items within the AWS account.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Configuration changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for AWS Config configuration changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"5.1": {"name": "5.1","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html:https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Security.html#VPC_Security_Comparison","Description": "The Network Access Control List (NACL) function provide stateless filtering of ingress and egress network traffic to AWS resources. It is recommended that no NACL allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "**From Console:**Perform the following to determine if the account is configured as prescribed: 1. Login to the AWS Management Console at https://console.aws.amazon.com/vpc/home 2. In the left pane, click `Network ACLs` 3. For each network ACL, perform the following:- Select the network ACL- Click the `Inbound Rules` tab- Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `0.0.0.0/0` and shows `ALLOW`**Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "**From Console:**Perform the following: 1. Login to the AWS Management Console at https://console.aws.amazon.com/vpc/home 2. In the left pane, click `Network ACLs` 3. For each network ACL to remediate, perform the following:- Select the network ACL- Click the `Inbound Rules` tab- Click `Edit inbound rules`- Either A) update the Source field to a range other than 0.0.0.0/0, or, B) Click `Delete` to remove the offending inbound rule- Click `Save`","AdditionalInformation": ""}],"description": "Ensure no Network ACLs allow ingress from 0.0.0.0/0 to remote server administration ports","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"5.2": {"name": "5.2","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#deleting-security-group-rule","Description": "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `0.0.0.0/0` **Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports.","ImpactStatement": "When updating an existing environment, ensure that administrators have access to remote server administration ports through another mechanism before removing access by deleting the 0.0.0.0/0 inbound rule.","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "Perform the following to implement the prescribed state:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Click the `Edit inbound rules` button 4. Identify the rules to be edited or removed 5. Either A) update the Source field to a range other than 0.0.0.0/0, or, B) Click `Delete` to remove the offending inbound rule 6. Click `Save rules`","AdditionalInformation": ""}],"description": "Ensure no security groups allow ingress from 0.0.0.0/0 to remote server administration ports","checks_status": {"fail": 0,"pass": 3,"total": 3,"manual": 0}},"5.3": {"name": "5.3","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#deleting-security-group-rule","Description": "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `::/0` **Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports.","ImpactStatement": "When updating an existing environment, ensure that administrators have access to remote server administration ports through another mechanism before removing access by deleting the ::/0 inbound rule.","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "Perform the following to implement the prescribed state:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Click the `Edit inbound rules` button 4. Identify the rules to be edited or removed 5. Either A) update the Source field to a range other than ::/0, or, B) Click `Delete` to remove the offending inbound rule 6. Click `Save rules`","AdditionalInformation": ""}],"description": "Ensure no security groups allow ingress from ::/0 to remote server administration ports","checks_status": {"fail": 0,"pass": 3,"total": 3,"manual": 0}},"5.4": {"name": "5.4","checks": {"ec2_securitygroup_default_restrict_traffic": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#default-security-group","Description": "A VPC comes with a default security group whose initial settings deny all inbound traffic, allow all outbound traffic, and allow all traffic between instances assigned to the security group. If you don't specify a security group when you launch an instance, the instance is automatically assigned to this default security group. Security groups provide stateful filtering of ingress/egress network traffic to AWS resources. It is recommended that the default security group restrict all traffic.The default VPC in every region should have its default security group updated to comply. Any newly created VPCs will automatically contain a default security group that will need remediation to comply with this recommendation.**NOTE:** When implementing this recommendation, VPC flow logging is invaluable in determining the least privilege port access required by systems to work properly because it can log all packet acceptances and rejections occurring under the current security groups. This dramatically reduces the primary barrier to least privilege engineering - discovering the minimum ports required by systems in the environment. Even if the VPC flow logging recommendation in this benchmark is not adopted as a permanent security measure, it should be used during any period of discovery and engineering for least privileged security groups.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:Security Group State1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. For each default security group, perform the following: 1. Select the `default` security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exist 4. Click the `Outbound Rules` tab 5. Ensure no rules existSecurity Group Members1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all default groups in all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. Copy the id of the default security group. 5. Change to the EC2 Management Console at https://console.aws.amazon.com/ec2/v2/home 6. In the filter column type 'Security Group ID : < security group id from #4 >'","ImpactStatement": "Implementing this recommendation in an existing VPC containing operating resources requires extremely careful migration planning as the default security groups are likely to be enabling many ports that are unknown. Enabling VPC flow logging (of accepts) in an existing environment that is known to be breach free will reveal the current pattern of ports being used for each instance to communicate successfully.","AssessmentStatus": "Automated","RationaleStatement": "Configuring all VPC default security groups to restrict all traffic will encourage least privilege security group development and mindful placement of AWS resources into security groups which will in-turn reduce the exposure of those resources.","RemediationProcedure": "Security Group MembersPerform the following to implement the prescribed state:1. Identify AWS resources that exist within the default security group 2. Create a set of least privilege security groups for those resources 3. Place the resources in those security groups 4. Remove the resources noted in #1 from the default security groupSecurity Group State1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. For each default security group, perform the following: 1. Select the `default` security group 2. Click the `Inbound Rules` tab 3. Remove any inbound rules 4. Click the `Outbound Rules` tab 5. Remove any Outbound rulesRecommended:IAM groups allow you to edit the \"name\" field. After remediating default groups rules for all VPCs in all regions, edit this field to add text similar to \"DO NOT USE. DO NOT ADD RULES\"","AdditionalInformation": ""}],"description": "Ensure the default security group of every VPC restricts all traffic","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"5.5": {"name": "5.5","checks": {"vpc_peering_routing_tables_with_least_privilege": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "5. Networking","References": "https://docs.aws.amazon.com/AmazonVPC/latest/PeeringGuide/peering-configurations-partial-access.html:https://docs.aws.amazon.com/cli/latest/reference/ec2/create-vpc-peering-connection.html","Description": "Once a VPC peering connection is established, routing tables must be updated to establish any connections between the peered VPCs. These routes can be as specific as desired - even peering a VPC to only a single host on the other side of the connection.","DefaultValue": null,"AuditProcedure": "Review routing tables of peered VPCs for whether they route all subnets of each VPC and whether that is necessary to accomplish the intended purposes for peering the VPCs.**From Command Line:**1. List all the route tables from a VPC and check if \"GatewayId\" is pointing to a __ (e.g. pcx-1a2b3c4d) and if \"DestinationCidrBlock\" is as specific as desired. ``` aws ec2 describe-route-tables --filter \"Name=vpc-id,Values=\" --query \"RouteTables[*].{RouteTableId:RouteTableId, VpcId:VpcId, Routes:Routes, AssociatedSubnets:Associations[*].SubnetId}\" ```","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Being highly selective in peering routing tables is a very effective way of minimizing the impact of breach as resources outside of these routes are inaccessible to the peered VPC.","RemediationProcedure": "Remove and add route table entries to ensure that the least number of subnets or hosts as is required to accomplish the purpose for peering are routable.**From Command Line:**1. For each __ containing routes non compliant with your routing policy (which grants more than desired \"least access\"), delete the non compliant route: ``` aws ec2 delete-route --route-table-id  --destination-cidr-block  ```2. Create a new compliant route: ``` aws ec2 create-route --route-table-id  --destination-cidr-block  --vpc-peering-connection-id  ```","AdditionalInformation": "If an organization has AWS transit gateway implemented in their VPC architecture they should look to apply the recommendation above for \"least access\" routing architecture at the AWS transit gateway level in combination with what must be implemented at the standard VPC route table. More specifically, to route traffic between two or more VPCs via a transit gateway VPCs must have an attachment to a transit gateway route table as well as a route, therefore to avoid routing traffic between VPCs an attachment to the transit gateway route table should only be added where there is an intention to route traffic between the VPCs. As transit gateways are able to host multiple route tables it is possible to group VPCs by attaching them to a common route table."}],"description": "Ensure routing tables for VPC peering are \"least access\"","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"5.6": {"name": "5.6","checks": {"ec2_instance_imdsv2_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service/:https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html","Description": "When enabling the Metadata Service on AWS EC2 instances, users have the option of using either Instance Metadata Service Version 1 (IMDSv1; a request/response method) or Instance Metadata Service Version 2 (IMDSv2; a session-oriented method).","DefaultValue": null,"AuditProcedure": "From Console:1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under the Instances menu, select Instances.3. For each Instance, select the instance, then choose Actions > Modify instance metadata options.4. If the Instance metadata service is enabled, verify whether IMDSv2 is set to required. From Command Line:1. Use the describe-instances CLI command2. Ensure for all ec2 instances that the metadata-options.http-tokens setting is set to required.3. Repeat for all active regions.```aws ec2 describe-instances --filters \"\"Name=metadata-options.http-tokens\",\"Values=optional\" \"\"Name=metadata-options.state\"\",\"\"Values=applied\"\" --query \"\"Reservations[*].Instances[*].\"\" ``` ","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Allowing Version 1 of the service may open EC2 instances to Server-Side Request Forgery (SSRF) attacks, so Amazon recommends utilizing Version 2 for better instance security.","RemediationProcedure": "From Console:1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/ 2. Under the Instances menu, select Instances.3. For each Instance, select the instance, then choose Actions > Modify instance metadata options.4. If the Instance metadata service is enabled, set IMDSv2 to Required. From Command Line:```aws ec2 modify-instance-metadata-options --instance-id  --http-tokens required``` ","AdditionalInformation": ""}],"description": "Ensure that EC2 Metadata Service only allows IMDSv2","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.10": {"name": "1.10","checks": {"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://tools.ietf.org/html/rfc6238:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#enable-mfa-for-privileged-users:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html:https://blogs.aws.amazon.com/security/post/Tx2SJJYE082KBUK/How-to-Delegate-Management-of-Multi-Factor-Authentication-to-AWS-IAM-Users","Description": "Multi-Factor Authentication (MFA) adds an extra layer of authentication assurance beyond traditional credentials. With MFA enabled, when a user signs in to the AWS Console, they will be prompted for their user name and password as well as for an authentication code from their physical or virtual MFA token. It is recommended that MFA be enabled for all accounts that have a console password.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if a MFA device is enabled for all IAM users having a console password:**From Console:**1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the left pane, select `Users`3. If the `MFA` or `Password age` columns are not visible in the table, click the gear icon at the upper right corner of the table and ensure a checkmark is next to both, then click `Close`. 4. Ensure that for each user where the `Password age` column shows a password age, the `MFA` column shows `Virtual`, `U2F Security Key`, or `Hardware`.**From Command Line:**1. Run the following command (OSX/Linux/UNIX) to generate a list of all IAM users along with their password and MFA status: ```aws iam generate-credential-report ``` ```aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,8``` 2. The output of this command will produce a table similar to the following: ```user,password_enabled,mfa_activeelise,false,falsebrandon,true,truerakesh,false,falsehelene,false,falseparas,true,trueanitha,false,false``` 3. For any column having `password_enabled` set to `true` , ensure `mfa_active` is also set to `true.`","ImpactStatement": "AWS will soon end support for SMS multi-factor authentication (MFA). New customers are not allowed to use this feature. We recommend that existing customers switch to one of the following alternative methods of MFA.","AssessmentStatus": "Automated","RationaleStatement": "Enabling MFA provides increased security for console access as it requires the authenticating principal to possess a device that displays a time-sensitive key and have knowledge of a credential.","RemediationProcedure": "Perform the following to enable MFA:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at 'https://console.aws.amazon.com/iam/' 2. In the left pane, select `Users`. 3. In the `User Name` list, choose the name of the intended MFA user. 4. Choose the `Security Credentials` tab, and then choose `Manage MFA Device`. 5. In the `Manage MFA Device wizard`, choose `Virtual MFA` device, and then choose `Continue`. IAM generates and displays configuration information for the virtual MFA device, including a QR code graphic. The graphic is a representation of the 'secret configuration key' that is available for manual entry on devices that do not support QR codes.6. Open your virtual MFA application. (For a list of apps that you can use for hosting virtual MFA devices, see Virtual MFA Applications at https://aws.amazon.com/iam/details/mfa/#Virtual_MFA_Applications). If the virtual MFA application supports multiple accounts (multiple virtual MFA devices), choose the option to create a new account (a new virtual MFA device). 7. Determine whether the MFA app supports QR codes, and then do one of the following: - Use the app to scan the QR code. For example, you might choose the camera icon or choose an option similar to Scan code, and then use the device's camera to scan the code.- In the Manage MFA Device wizard, choose Show secret key for manual configuration, and then type the secret configuration key into your MFA application. When you are finished, the virtual MFA device starts generating one-time passwords.8. In the `Manage MFA Device wizard`, in the `MFA Code 1 box`, type the `one-time password` that currently appears in the virtual MFA device. Wait up to 30 seconds for the device to generate a new one-time password. Then type the second `one-time password` into the `MFA Code 2 box`.9. Click `Assign MFA`.","AdditionalInformation": "**Forced IAM User Self-Service Remediation**Amazon has published a pattern that forces users to self-service setup MFA before they have access to their complete permissions set. Until they complete this step, they cannot access their full permissions. This pattern can be used on new AWS accounts. It can also be used on existing accounts - it is recommended users are given instructions and a grace period to accomplish MFA enrollment before active enforcement on existing AWS accounts."}],"description": "Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.11": {"name": "1.11","checks": {"iam_user_no_setup_initial_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/cli/latest/reference/iam/delete-access-key.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html","Description": "AWS console defaults to no check boxes selected when creating a new IAM user. When cerating the IAM User credentials you have to determine what type of access they require. Programmatic access: The IAM user might need to make API calls, use the AWS CLI, or use the Tools for Windows PowerShell. In that case, create an access key (access key ID and a secret access key) for that user. AWS Management Console access: If the user needs to access the AWS Management Console, create a password for the user.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if access keys were created upon user creation and are being used and rotated as prescribed:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on a User where column `Password age` and `Access key age` is not set to `None` 5. Click on `Security credentials` Tab 6. Compare the user 'Creation time` to the Access Key `Created` date. 6. For any that match, the key was created during initial user setup.- Keys that were created at the same time as the user profile and do not have a last used date should be deleted. Refer to the remediation below.**From Command Line:**1. Run the following command (OSX/Linux/UNIX) to generate a list of all IAM users along with their access keys utilization: ```aws iam generate-credential-report ``` ```aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,9,11,14,16 ``` 2. The output of this command will produce a table similar to the following: ``` user,password_enabled,access_key_1_active,access_key_1_last_used_date,access_key_2_active,access_key_2_last_used_dateelise,false,true,2015-04-16T15:14:00+00:00,false,N/Abrandon,true,true,N/A,false,N/Arakesh,false,false,N/A,false,N/Ahelene,false,true,2015-11-18T17:47:00+00:00,false,N/Aparas,true,true,2016-08-28T12:04:00+00:00,true,2016-03-04T10:11:00+00:00anitha,true,true,2016-06-08T11:43:00+00:00,true,N/A``` 3. For any user having `password_enabled` set to `true` AND `access_key_last_used_date` set to `N/A` refer to the remediation below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Requiring the additional steps be taken by the user for programmatic access after their profile has been created will give a stronger indication of intent that access keys are [a] necessary for their work and [b] once the access key is established on an account that the keys may be in use somewhere in the organization.**Note**: Even if it is known the user will need access keys, require them to create the keys themselves or put in a support ticket to have them created as a separate step from user creation.","RemediationProcedure": "Perform the following to delete access keys that do not pass the audit:**From Console:**1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. As an Administrator - Click on the X `(Delete)` for keys that were created at the same time as the user profile but have not been used. 7. As an IAM User- Click on the X `(Delete)` for keys that were created at the same time as the user profile but have not been used.**From Command Line:** ``` aws iam delete-access-key --access-key-id  --user-name  ```","AdditionalInformation": "Credential report does not appear to contain \"Key Creation Date\""}],"description": "Do not setup access keys during initial user setup for all IAM users that have a console password","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.12": {"name": "1.12","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#remove-credentials:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_admin-change-user.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "AWS IAM users can access AWS resources using different types of credentials, such as passwords or access keys. It is recommended that all credentials that have been unused in 45 or greater days be deactivated or removed.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if unused credentials exist:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM` 4. Click on `Users` 5. Click the `Settings` (gear) icon. 6. Select `Console last sign-in`, `Access key last used`, and `Access Key Id` 7. Click on `Close`8. Check and ensure that `Console last sign-in` is less than 45 days ago.**Note** - `Never` means the user has never logged in.9. Check and ensure that `Access key age` is less than 45 days and that `Access key last used` does not say `None`If the user hasn't signed into the Console in the last 45 days or Access keys are over 45 days old refer to the remediation.**From Command Line:****Download Credential Report:**1. Run the following commands: ```aws iam generate-credential-report aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,5,6,9,10,11,14,15,16 | grep -v '^' ```**Ensure unused credentials do not exist:**2. For each user having `password_enabled` set to `TRUE` , ensure `password_last_used_date` is less than `45` days ago.- When `password_enabled` is set to `TRUE` and `password_last_used` is set to `No_Information` , ensure `password_last_changed` is less than 45 days ago.3. For each user having an `access_key_1_active` or `access_key_2_active` to `TRUE` , ensure the corresponding `access_key_n_last_used_date` is less than `45` days ago.- When a user having an `access_key_x_active` (where x is 1 or 2) to `TRUE` and corresponding access_key_x_last_used_date is set to `N/A', ensure `access_key_x_last_rotated` is less than 45 days ago.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Disabling or removing unnecessary credentials will reduce the window of opportunity for credentials associated with a compromised or abandoned account to be used.","RemediationProcedure": "**From Console:**Perform the following to manage Unused Password (IAM user console access)1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. Select user whose `Console last sign-in` is greater than 45 days 7. Click `Security credentials` 8. In section `Sign-in credentials`, `Console password` click `Manage`9. Under Console Access select `Disable` 10.Click `Apply`Perform the following to deactivate Access Keys:1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. Select any access keys that are over 45 days old and that have been used and - Click on `Make Inactive` 7. Select any access keys that are over 45 days old and that have not been used and - Click the X to `Delete`","AdditionalInformation": " is excluded in the audit since the root account should not be used for day to day business and would likely be unused for more than 45 days."}],"description": "Ensure credentials unused for 45 days or greater are disabled","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1.13": {"name": "1.13","checks": {"iam_user_two_active_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "Access keys are long-term credentials for an IAM user or the AWS account 'root' user. You can use access keys to sign programmatic requests to the AWS CLI or AWS API (directly or using the AWS SDK)","DefaultValue": null,"AuditProcedure": "**From Console:**1. Sign in to the AWS Management Console and navigate to IAM dashboard at `https://console.aws.amazon.com/iam/`. 2. In the left navigation panel, choose `Users`. 3. Click on the IAM user name that you want to examine. 4. On the IAM user configuration page, select `Security Credentials` tab. 5. Under `Access Keys` section, in the Status column, check the current status for each access key associated with the IAM user. If the selected IAM user has more than one access key activated then the users access configuration does not adhere to security best practices and the risk of accidental exposures increases. - Repeat steps no. 3 – 5 for each IAM user in your AWS account.**From Command Line:**1. Run `list-users` command to list all IAM users within your account: ``` aws iam list-users --query \"Users[*].UserName\" ``` The command output should return an array that contains all your IAM user names.2. Run `list-access-keys` command using the IAM user name list to return the current status of each access key associated with the selected IAM user: ``` aws iam list-access-keys --user-name  ``` The command output should expose the metadata `(\"Username\", \"AccessKeyId\", \"Status\", \"CreateDate\")` for each access key on that user account.3. Check the `Status` property value for each key returned to determine each keys current state. If the `Status` property value for more than one IAM access key is set to `Active`, the user access configuration does not adhere to this recommendation, refer to the remediation below.- Repeat steps no. 2 and 3 for each IAM user in your AWS account.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Access keys are long-term credentials for an IAM user or the AWS account 'root' user. You can use access keys to sign programmatic requests to the AWS CLI or AWS API. One of the best ways to protect your account is to not allow users to have multiple access keys.","RemediationProcedure": "**From Console:**1. Sign in to the AWS Management Console and navigate to IAM dashboard at `https://console.aws.amazon.com/iam/`. 2. In the left navigation panel, choose `Users`. 3. Click on the IAM user name that you want to examine. 4. On the IAM user configuration page, select `Security Credentials` tab. 5. In `Access Keys` section, choose one access key that is less than 90 days old. This should be the only active key used by this IAM user to access AWS resources programmatically. Test your application(s) to make sure that the chosen access key is working. 6. In the same `Access Keys` section, identify your non-operational access keys (other than the chosen one) and deactivate it by clicking the `Make Inactive` link. 7. If you receive the `Change Key Status` confirmation box, click `Deactivate` to switch off the selected key. 8. Repeat steps no. 3 – 7 for each IAM user in your AWS account.**From Command Line:**1. Using the IAM user and access key information provided in the `Audit CLI`, choose one access key that is less than 90 days old. This should be the only active key used by this IAM user to access AWS resources programmatically. Test your application(s) to make sure that the chosen access key is working.2. Run the `update-access-key` command below using the IAM user name and the non-operational access key IDs to deactivate the unnecessary key(s). Refer to the Audit section to identify the unnecessary access key ID for the selected IAM user**Note** - the command does not return any output: ``` aws iam update-access-key --access-key-id  --status Inactive --user-name  ``` 3. To confirm that the selected access key pair has been successfully `deactivated` run the `list-access-keys` audit command again for that IAM User: ``` aws iam list-access-keys --user-name  ``` - The command output should expose the metadata for each access key associated with the IAM user. If the non-operational key pair(s) `Status` is set to `Inactive`, the key has been successfully deactivated and the IAM user access configuration adheres now to this recommendation.4. Repeat steps no. 1 – 3 for each IAM user in your AWS account.","AdditionalInformation": ""}],"description": "Ensure there is only one active access key available for any single IAM user","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.14": {"name": "1.14","checks": {"iam_rotate_access_key_90_days": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#rotate-credentials:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html:https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "Access keys consist of an access key ID and secret access key, which are used to sign programmatic requests that you make to AWS. AWS users need their own access keys to make programmatic calls to AWS from the AWS Command Line Interface (AWS CLI), Tools for Windows PowerShell, the AWS SDKs, or direct HTTP calls using the APIs for individual AWS services. It is recommended that all access keys be regularly rotated.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if access keys are rotated as prescribed:**From Console:**1. Go to Management Console (https://console.aws.amazon.com/iam) 2. Click on `Users` 3. Click `setting` icon 4. Select `Console last sign-in` 5. Click `Close` 6. Ensure that `Access key age` is less than 90 days ago. note) `None` in the `Access key age` means the user has not used the access key.**From Command Line:**``` aws iam generate-credential-report aws iam get-credential-report --query 'Content' --output text | base64 -d ``` The `access_key_1_last_rotated` field in this file notes The date and time, in ISO 8601 date-time format, when the user's access key was created or last changed. If the user does not have an active access key, the value in this field is N/A (not applicable).","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Rotating access keys will reduce the window of opportunity for an access key that is associated with a compromised or terminated account to be used.Access keys should be rotated to ensure that data cannot be accessed with an old key which might have been lost, cracked, or stolen.","RemediationProcedure": "Perform the following to rotate access keys:**From Console:**1. Go to Management Console (https://console.aws.amazon.com/iam) 2. Click on `Users` 3. Click on `Security Credentials`4. As an Administrator - Click on `Make Inactive` for keys that have not been rotated in `90` Days 5. As an IAM User- Click on `Make Inactive` or `Delete` for keys which have not been rotated or used in `90` Days 6. Click on `Create Access Key`7. Update programmatic call with new Access Key credentials**From Command Line:**1. While the first access key is still active, create a second access key, which is active by default. Run the following command: ``` aws iam create-access-key ```At this point, the user has two active access keys.2. Update all applications and tools to use the new access key. 3. Determine whether the first access key is still in use by using this command: ``` aws iam get-access-key-last-used ``` 4. One approach is to wait several days and then check the old access key for any use before proceeding.Even if step Step 3 indicates no use of the old key, it is recommended that you do not immediately delete the first access key. Instead, change the state of the first access key to Inactive using this command: ``` aws iam update-access-key ``` 5. Use only the new access key to confirm that your applications are working. Any applications and tools that still use the original access key will stop working at this point because they no longer have access to AWS resources. If you find such an application or tool, you can switch its state back to Active to reenable the first access key. Then return to step Step 2 and update this application to use the new key.6. After you wait some period of time to ensure that all applications and tools have been updated, you can delete the first access key with this command: ``` aws iam delete-access-key ```","AdditionalInformation": ""}],"description": "Ensure access keys are rotated every 90 days or less","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.15": {"name": "1.15","checks": {"iam_policy_attached_only_to_group_or_roles": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html","Description": "IAM users are granted access to services, functions, and data through IAM policies. There are three ways to define policies for a user: 1) Edit the user policy directly, aka an inline, or user, policy; 2) attach a policy directly to a user; 3) add the user to an IAM group that has an attached policy. Only the third implementation is recommended.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if an inline policy is set or a policy is directly attached to users:1. Run the following to get a list of IAM users: ```aws iam list-users --query 'Users[*].UserName' --output text``` 2. For each user returned, run the following command to determine if any policies are attached to them: ```aws iam list-attached-user-policies --user-name aws iam list-user-policies --user-name ``` 3. If any policies are returned, the user has an inline policy or direct policy attachment.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Assigning IAM policy only through groups unifies permissions management to a single, flexible layer consistent with organizational functional roles. By unifying permissions management, the likelihood of excessive permissions is reduced.","RemediationProcedure": "Perform the following to create an IAM group and assign a policy to it:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click `Groups` and then click `Create New Group` . 3. In the `Group Name` box, type the name of the group and then click `Next Step` . 4. In the list of policies, select the check box for each policy that you want to apply to all members of the group. Then click `Next Step` . 5. Click `Create Group` Perform the following to add a user to a given group:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click `Groups`3. Select the group to add a user to 4. Click `Add Users To Group`5. Select the users to be added to the group 6. Click `Add Users` Perform the following to remove a direct association between a user and policy:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the left navigation pane, click on Users 3. For each user:- Select the user- Click on the `Permissions` tab- Expand `Permissions policies` - Click `X` for each policy; then click Detach or Remove (depending on policy type)","AdditionalInformation": ""}],"description": "Ensure IAM Users Receive Permissions Only Through Groups","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.16": {"name": "1.16","checks": {"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html:https://docs.aws.amazon.com/cli/latest/reference/iam/index.html#cli-aws-iam","Description": "IAM policies are the means by which privileges are granted to users, groups, or roles. It is recommended and considered a standard security advice to grant _least privilege_ -that is, granting only the permissions required to perform a task. Determine what users need to do and then craft policies for them that let the users perform _only_ those tasks, instead of allowing full administrative privileges.","DefaultValue": null,"AuditProcedure": "Perform the following to determine what policies are created:**From Command Line:**1. Run the following to get a list of IAM policies: ```aws iam list-policies --only-attached --output text ``` 2. For each policy returned, run the following command to determine if any policies is allowing full administrative privileges on the account: ```aws iam get-policy-version --policy-arn  --version-id  ``` 3. In output ensure policy should not have any Statement block with `\"Effect\": \"Allow\"` and `Action` set to `\"*\"` and `Resource` set to `\"*\"`","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "It's more secure to start with a minimum set of permissions and grant additional permissions as necessary, rather than starting with permissions that are too lenient and then trying to tighten them later.Providing full administrative privileges instead of restricting to the minimum set of permissions that the user is required to do exposes the resources to potentially unwanted actions.IAM policies that have a statement with \"Effect\": \"Allow\" with \"Action\": \"\\*\" over \"Resource\": \"\\*\" should be removed.","RemediationProcedure": "**From Console:**Perform the following to detach the policy that has full administrative privileges:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click Policies and then search for the policy name found in the audit step. 3. Select the policy that needs to be deleted. 4. In the policy action menu, select first `Detach`5. Select all Users, Groups, Roles that have this policy attached 6. Click `Detach Policy`7. In the policy action menu, select `Detach` **From Command Line:**Perform the following to detach the policy that has full administrative privileges as found in the audit step:1. Lists all IAM users, groups, and roles that the specified managed policy is attached to.```aws iam list-entities-for-policy --policy-arn  ``` 2. Detach the policy from all IAM Users: ```aws iam detach-user-policy --user-name  --policy-arn  ``` 3. Detach the policy from all IAM Groups: ```aws iam detach-group-policy --group-name  --policy-arn  ``` 4. Detach the policy from all IAM Roles: ```aws iam detach-role-policy --role-name  --policy-arn  ```","AdditionalInformation": ""}],"description": "Ensure IAM policies that allow full \"*:*\" administrative privileges are not attached","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1.17": {"name": "1.17","checks": {"iam_support_role_created": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html:https://aws.amazon.com/premiumsupport/pricing/:https://docs.aws.amazon.com/cli/latest/reference/iam/list-policies.html:https://docs.aws.amazon.com/cli/latest/reference/iam/attach-role-policy.html:https://docs.aws.amazon.com/cli/latest/reference/iam/list-entities-for-policy.html","Description": "AWS provides a support center that can be used for incident notification and response, as well as technical support and customer services. Create an IAM Role to allow authorized users to manage incidents with AWS Support.","DefaultValue": null,"AuditProcedure": "**From Command Line:**1. List IAM policies, filter for the 'AWSSupportAccess' managed policy, and note the \"Arn\" element value: ``` aws iam list-policies --query \"Policies[?PolicyName == 'AWSSupportAccess']\" ``` 2. Check if the 'AWSSupportAccess' policy is attached to any role:``` aws iam list-entities-for-policy --policy-arn arn:aws:iam::aws:policy/AWSSupportAccess ```3. In Output, Ensure `PolicyRoles` does not return empty. 'Example: Example: PolicyRoles: [ ]'If it returns empty refer to the remediation below.","ImpactStatement": "All AWS Support plans include an unlimited number of account and billing support cases, with no long-term contracts. Support billing calculations are performed on a per-account basis for all plans. Enterprise Support plan customers have the option to include multiple enabled accounts in an aggregated monthly billing calculation. Monthly charges for the Business and Enterprise support plans are based on each month's AWS usage charges, subject to a monthly minimum, billed in advance.","AssessmentStatus": "Automated","RationaleStatement": "By implementing least privilege for access control, an IAM Role will require an appropriate IAM Policy to allow Support Center Access in order to manage Incidents with AWS Support.","RemediationProcedure": "**From Command Line:**1. Create an IAM role for managing incidents with AWS:- Create a trust relationship policy document that allows  to manage AWS incidents, and save it locally as /tmp/TrustPolicy.json: ```{\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"\"},\"Action\": \"sts:AssumeRole\"}]} ``` 2. Create the IAM role using the above trust policy: ``` aws iam create-role --role-name  --assume-role-policy-document file:///tmp/TrustPolicy.json ``` 3. Attach 'AWSSupportAccess' managed policy to the created IAM role: ``` aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AWSSupportAccess --role-name  ```","AdditionalInformation": "AWSSupportAccess policy is a global AWS resource. It has same ARN as `arn:aws:iam::aws:policy/AWSSupportAccess` for every account."}],"description": "Ensure a support role has been created to manage incidents with AWS Support","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.18": {"name": "1.18","checks": {"ec2_instance_profile_attached": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html","Description": "AWS access from within AWS instances can be done by either encoding AWS keys into AWS API calls or by assigning the instance to a role which has an appropriate permissions policy for the required access. \"AWS Access\" means accessing the APIs of AWS in order to access AWS resources or manage AWS account resources.","DefaultValue": null,"AuditProcedure": "Where an instance is associated with a Role:For instances that are known to perform AWS actions, ensure that they belong to an instance role that has the necessary permissions:1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Open the EC2 Dashboard and choose \"Instances\" 3. Click the EC2 instance that performs AWS actions, in the lower pane details find \"IAM Role\" 4. If the Role is blank, the instance is not assigned to one. 5. If the Role is filled in, it does not mean the instance might not \\*also\\* have credentials encoded on it for some activities.Where an Instance Contains Embedded Credentials:- On the instance that is known to perform AWS actions, audit all scripts and environment variables to ensure that none of them contain AWS credentials.Where an Instance Application Contains Embedded Credentials:- Applications that run on an instance may also have credentials embedded. This is a bad practice, but even worse if the source code is stored in a public code repository such as github. When an application contains credentials can be determined by eliminating all other sources of credentials and if the application can still access AWS resources - it likely contains embedded credentials. Another method is to examine all source code and configuration files of the application.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "AWS IAM roles reduce the risks associated with sharing and rotating credentials that can be used outside of AWS itself. If credentials are compromised, they can be used from outside of the AWS account they give access to. In contrast, in order to leverage role permissions an attacker would need to gain and maintain access to a specific instance to use the privileges associated with it.Additionally, if credentials are encoded into compiled applications or other hard to change mechanisms, then they are even more unlikely to be properly rotated due to service disruption risks. As time goes on, credentials that cannot be rotated are more likely to be known by an increasing number of individuals who no longer work for the organization owning the credentials.","RemediationProcedure": "IAM roles can only be associated at the launch of an instance. To remediate an instance to add it to a role you must create a new instance.If the instance has no external dependencies on its current private ip or public addresses are elastic IPs:1. In AWS IAM create a new role. Assign a permissions policy if needed permissions are already known. 2. In the AWS console launch a new instance with identical settings to the existing instance, and ensure that the newly created role is selected. 3. Shutdown both the existing instance and the new instance. 4. Detach disks from both instances. 5. Attach the existing instance disks to the new instance. 6. Boot the new instance and you should have the same machine, but with the associated role.**Note:** if your environment has dependencies on a dynamically assigned PRIVATE IP address you can create an AMI from the existing instance, destroy the old one and then when launching from the AMI, manually assign the previous private IP address.**Note: **if your environment has dependencies on a dynamically assigned PUBLIC IP address there is not a way ensure the address is retained and assign an instance role. Dependencies on dynamically assigned public IP addresses are a bad practice and, if possible, you may wish to rebuild the instance with a new elastic IP address and make the investment to remediate affected systems while assigning the system to a role.","AdditionalInformation": ""}],"description": "Ensure IAM instance roles are used for AWS resource access from instances","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.19": {"name": "1.19","checks": {"iam_no_expired_server_certificates_stored": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_server-certs.html:https://docs.aws.amazon.com/cli/latest/reference/iam/delete-server-certificate.html","Description": "To enable HTTPS connections to your website or application in AWS, you need an SSL/TLS server certificate. You can use ACM or IAM to store and deploy server certificates.Use IAM as a certificate manager only when you must support HTTPS connections in a region that is not supported by ACM. IAM securely encrypts your private keys and stores the encrypted version in IAM SSL certificate storage. IAM supports deploying server certificates in all regions, but you must obtain your certificate from an external provider for use with AWS. You cannot upload an ACM certificate to IAM. Additionally, you cannot manage your certificates from the IAM Console.","DefaultValue": null,"AuditProcedure": "**From Console:**Getting the certificates expiration information via AWS Management Console is not currently supported.To request information about the SSL/TLS certificates stored in IAM via the AWS API use the Command Line Interface (CLI).**From Command Line:**Run list-server-certificates command to list all the IAM-stored server certificates:``` aws iam list-server-certificates ```The command output should return an array that contains all the SSL/TLS certificates currently stored in IAM and their metadata (name, ID, expiration date, etc):``` {\"ServerCertificateMetadataList\": [{\"ServerCertificateId\": \"EHDGFRW7EJFYTE88D\",\"ServerCertificateName\": \"MyServerCertificate\",\"Expiration\": \"2018-07-10T23:59:59Z\",\"Path\": \"/\",\"Arn\": \"arn:aws:iam::012345678910:server-certificate/MySSLCertificate\",\"UploadDate\": \"2018-06-10T11:56:08Z\"}] } ```Verify the `ServerCertificateName` and `Expiration` parameter value (expiration date) for each SSL/TLS certificate returned by the list-server-certificates command and determine if there are any expired server certificates currently stored in AWS IAM. If so, use the AWS API to remove them.If this command returns: ``` { { \"ServerCertificateMetadataList\": [] } ``` This means that there are no expired certificates, It DOES NOT mean that no certificates exist.","ImpactStatement": "Deleting the certificate could have implications for your application if you are using an expired server certificate with Elastic Load Balancing, CloudFront, etc. One has to make configurations at respective services to ensure there is no interruption in application functionality.","AssessmentStatus": "Automated","RationaleStatement": "Removing expired SSL/TLS certificates eliminates the risk that an invalid certificate will be deployed accidentally to a resource such as AWS Elastic Load Balancer (ELB), which can damage the credibility of the application/website behind the ELB. As a best practice, it is recommended to delete expired certificates.","RemediationProcedure": "**From Console:**Removing expired certificates via AWS Management Console is not currently supported. To delete SSL/TLS certificates stored in IAM via the AWS API use the Command Line Interface (CLI).**From Command Line:**To delete Expired Certificate run following command by replacing  with the name of the certificate to delete:``` aws iam delete-server-certificate --server-certificate-name  ```When the preceding command is successful, it does not return any output.","AdditionalInformation": ""}],"description": "Ensure that all the expired SSL/TLS certificates stored in AWS IAM are removed","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.20": {"name": "1.20","checks": {"accessanalyzer_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-getting-started.html:https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/get-analyzer.html:https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/create-analyzer.html","Description": "Enable IAM Access analyzer for IAM policies about all resources in each region.IAM Access Analyzer is a technology introduced at AWS reinvent 2019. After the Analyzer is enabled in IAM, scan results are displayed on the console showing the accessible resources. Scans show resources that other accounts and federated users can access, such as KMS keys and IAM roles. So the results allow you to determine if an unintended user is allowed, making it easier for administrators to monitor least privileges access. Access Analyzer analyzes only policies that are applied to resources in the same AWS Region.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Open the IAM console at `https://console.aws.amazon.com/iam/` 2. Choose `Access analyzer` 3. Click 'Analyzers' 4. Ensure that at least one analyzer is present 5. Ensure that the `STATUS` is set to `Active` 6. Repeat these step for each active region**From Command Line:**1. Run the following command: ``` aws accessanalyzer list-analyzers | grep status ``` 2. Ensure that at least one Analyzer the `status` is set to `ACTIVE`3. Repeat the steps above for each active region.If an Access analyzer is not listed for each region or the status is not set to active refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "AWS IAM Access Analyzer helps you identify the resources in your organization and accounts, such as Amazon S3 buckets or IAM roles, that are shared with an external entity. This lets you identify unintended access to your resources and data. Access Analyzer identifies resources that are shared with external principals by using logic-based reasoning to analyze the resource-based policies in your AWS environment. IAM Access Analyzer continuously monitors all policies for S3 bucket, IAM roles, KMS(Key Management Service) keys, AWS Lambda functions, and Amazon SQS(Simple Queue Service) queues.","RemediationProcedure": "**From Console:**Perform the following to enable IAM Access analyzer for IAM policies:1. Open the IAM console at `https://console.aws.amazon.com/iam/.` 2. Choose `Access analyzer`. 3. Choose `Create analyzer`. 4. On the `Create analyzer` page, confirm that the `Region` displayed is the Region where you want to enable Access Analyzer. 5. Enter a name for the analyzer. `Optional as it will generate a name for you automatically`. 6. Add any tags that you want to apply to the analyzer. `Optional`.7. Choose `Create Analyzer`. 8. Repeat these step for each active region**From Command Line:**Run the following command: ``` aws accessanalyzer create-analyzer --analyzer-name  --type  ``` Repeat this command above for each active region.**Note:** The IAM Access Analyzer is successfully configured only when the account you use has the necessary permissions.","AdditionalInformation": ""}],"description": "Ensure that IAM Access analyzer is enabled for all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.21": {"name": "1.21","checks": {"iam_check_saml_providers_sts": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "","Description": "In multi-account environments, IAM user centralization facilitates greater user control. User access beyond the initial account is then provided via role assumption. Centralization of users can be accomplished through federation with an external identity provider or through the use of AWS Organizations.","DefaultValue": null,"AuditProcedure": "For multi-account AWS environments with an external identity provider... 1. Determine the master account for identity federation or IAM user management 2. Login to that account through the AWS Management Console 3. Click `Services`4. Click `IAM`5. Click `Identity providers` 6. Verify the configurationThen..., determine all accounts that should not have local users present. For each account...1. Determine all accounts that should not have local users present 2. Log into the AWS Management Console 3. Switch role into each identified account 4. Click `Services`5. Click `IAM`6. Click `Users` 7. Confirm that no IAM users representing individuals are presentFor multi-account AWS environments implementing AWS Organizations without an external identity provider... 1. Determine all accounts that should not have local users present 2. Log into the AWS Management Console 3. Switch role into each identified account 4. Click `Services`5. Click `IAM`6. Click `Users` 7. Confirm that no IAM users representing individuals are present","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Centralizing IAM user management to a single identity store reduces complexity and thus the likelihood of access management errors.","RemediationProcedure": "The remediation procedure will vary based on the individual organization's implementation of identity federation and/or AWS Organizations with the acceptance criteria that no non-service IAM users, and non-root accounts, are present outside the account providing centralized IAM user management.","AdditionalInformation": ""}],"description": "Ensure IAM users are managed centrally via identity federation or AWS Organizations for multi-account environments","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.22": {"name": "1.22","checks": {},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/cloudshell/latest/userguide/sec-auth-with-identities.html","Description": "AWS CloudShell is a convenient way of running CLI commands against AWS services; a managed IAM policy ('AWSCloudShellFullAccess') provides full access to CloudShell, which allows file upload and download capability between a user's local system and the CloudShell environment. Within the CloudShell environment a user has sudo permissions, and can access the internet. So it is feasible to install file transfer software (for example) and move data from CloudShell to external internet servers.","DefaultValue": null,"AuditProcedure": "**From Console** 1. Open the IAM console at https://console.aws.amazon.com/iam/2. In the left pane, select Policies3. Search for and select AWSCloudShellFullAccess4. On the Entities attached tab, ensure that there are no entities using this policy **From Command Line**1. List IAM policies, filter for the 'AWSCloudShellFullAccess' managed policy, and note the \"\"Arn\"\" element value:```aws iam list-policies --query \"\"Policies[?PolicyName == 'AWSCloudShellFullAccess']\"\"``` 2. Check if the 'AWSCloudShellFullAccess' policy is attached to any role: ```aws iam list-entities-for-policy --policy-arn arn:aws:iam::aws:policy/AWSCloudShellFullAccess```3. In Output, Ensure PolicyRoles returns empty. 'Example: Example: PolicyRoles: [ ]'If it does not return empty refer to the remediation below.Note: Keep in mind that other policies may grant access.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Access to this policy should be restricted as it presents a potential channel for data exfiltration by malicious cloud admins that are given full permissions to the service. AWS documentation describes how to create a more restrictive IAM policy which denies file transfer permissions.","RemediationProcedure": "**From Console**1. Open the IAM console at https://console.aws.amazon.com/iam/2. In the left pane, select Policies 3. Search for and select AWSCloudShellFullAccess4. On the Entities attached tab, for each item, check the box and select Detach","AdditionalInformation": ""}],"description": "Ensure access to AWSCloudShellFullAccess is restricted","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.10": {"name": "3.10","checks": {"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-cloudtrail-events.html","Description": "S3 object-level API operations such as GetObject, DeleteObject, and PutObject are called data events. By default, CloudTrail trails don't log data events and so it is recommended to enable Object-level logging for S3 buckets.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to CloudTrail dashboard at `https://console.aws.amazon.com/cloudtrail/` 2. In the left panel, click `Trails` and then click on the CloudTrail Name that you want to examine. 3. Review `General details` 4. Confirm that `Multi-region trail` is set to `Yes` 5. Scroll down to `Data events` 6. Confirm that it reads: Data events: S3 Bucket Name: All current and future S3 buckets Read: Enabled Write: Enabled 7. Repeat steps 2 to 6 to verify that Multi-region trail and Data events logging of S3 buckets in CloudTrail. If the CloudTrails do not have multi-region and data events configured for S3 refer to the remediation below.**From Command Line:**1. Run `list-trails` command to list the names of all Amazon CloudTrail trails currently available in all AWS regions: ``` aws cloudtrail list-trails ``` 2. The command output will be a list of all the trail names to include. \"TrailARN\": \"arn:aws:cloudtrail:::trail/\", \"Name\": \"\", \"HomeRegion\": \"\" 3. Next run 'get-trail- command to determine Multi-region. ``` aws cloudtrail get-trail --name  --region  ``` 4. The command output should include: \"IsMultiRegionTrail\": true, 5. Next run `get-event-selectors` command using the `Name` of the trail and the `region` returned in step 2 to determine if Data events logging feature is enabled within the selected CloudTrail trail for all S3 buckets: ``` aws cloudtrail get-event-selectors --region  --trail-name  --query EventSelectors[*].DataResources[] ``` 6. The command output should be an array that contains the configuration of the AWS resource(S3 bucket) defined for the Data events selector. \"Type\": \"AWS::S3::Object\",\"Values\": [\"arn:aws:s3\" 7. If the `get-event-selectors` command returns an empty array '[]', the Data events are not included in the selected AWS Cloudtrail trail logging configuration, therefore the S3 object-level API operations performed within your AWS account are not recorded. 8. Repeat steps 1 to 5 for auditing each CloudTrail to determine if Data events for S3 are covered. If Multi-region is not set to true and the Data events does not show S3 defined as shown refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling object-level logging will help you meet data compliance requirements within your organization, perform comprehensive security analysis, monitor specific patterns of user behavior in your AWS account or take immediate actions on any object-level API activity within your S3 Buckets using Amazon CloudWatch Events.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. Click on the `Object-level` logging setting, enter the CloudTrail name for the recording activity. You can choose an existing Cloudtrail or create a new one by navigating to the Cloudtrail console link `https://console.aws.amazon.com/cloudtrail/` 5. Once the Cloudtrail is selected, check the `Write` event checkbox, so that `object-level` logging for Write events is enabled. 6. Repeat steps 2 to 5 to enable object-level logging of write events for other S3 buckets.**From Command Line:**1. To enable `object-level` data events logging for S3 buckets within your AWS account, run `put-event-selectors` command using the name of the trail that you want to reconfigure as identifier: ``` aws cloudtrail put-event-selectors --region  --trail-name  --event-selectors '[{ \"ReadWriteType\": \"WriteOnly\", \"IncludeManagementEvents\":true, \"DataResources\": [{ \"Type\": \"AWS::S3::Object\", \"Values\": [\"arn:aws:s3:::/\"] }] }]' ``` 2. The command output will be `object-level` event trail configuration. 3. If you want to enable it for all buckets at once then change Values parameter to `[\"arn:aws:s3\"]` in command given above. 4. Repeat step 1 for each s3 bucket to update `object-level` logging of write events. 5. Change the AWS region by updating the `--region` command parameter and perform the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that Object-level logging for write events is enabled for S3 bucket","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.11": {"name": "3.11","checks": {"cloudtrail_s3_dataevents_read_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-cloudtrail-events.html","Description": "S3 object-level API operations such as GetObject, DeleteObject, and PutObject are called data events. By default, CloudTrail trails don't log data events and so it is recommended to enable Object-level logging for S3 buckets.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. If the current status for `Object-level` logging is set to `Disabled`, then object-level logging of read events for the selected s3 bucket is not set. 5. If the current status for `Object-level` logging is set to `Enabled`, but the Read event check-box is unchecked, then object-level logging of read events for the selected s3 bucket is not set. 6. Repeat steps 2 to 5 to verify `object-level` logging for `read` events of your other S3 buckets.**From Command Line:** 1. Run `describe-trails` command to list the names of all Amazon CloudTrail trails currently available in the selected AWS region: ``` aws cloudtrail describe-trails --region  --output table --query trailList[*].Name ``` 2. The command output will be table of the requested trail names. 3. Run `get-event-selectors` command using the name of the trail returned at the previous step and custom query filters to determine if Data events logging feature is enabled within the selected CloudTrail trail configuration for s3 bucket resources: ``` aws cloudtrail get-event-selectors --region  --trail-name  --query EventSelectors[*].DataResources[] ``` 4. The command output should be an array that contains the configuration of the AWS resource(S3 bucket) defined for the Data events selector. 5. If the `get-event-selectors` command returns an empty array, the Data events are not included into the selected AWS Cloudtrail trail logging configuration, therefore the S3 object-level API operations performed within your AWS account are not recorded. 6. Repeat steps 1 to 5 for auditing each s3 bucket to identify other trails that are missing the capability to log Data events. 7. Change the AWS region by updating the `--region` command parameter and perform the audit process for other regions.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling object-level logging will help you meet data compliance requirements within your organization, perform comprehensive security analysis, monitor specific patterns of user behavior in your AWS account or take immediate actions on any object-level API activity using Amazon CloudWatch Events.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. Click on the `Object-level` logging setting, enter the CloudTrail name for the recording activity. You can choose an existing Cloudtrail or create a new one by navigating to the Cloudtrail console link `https://console.aws.amazon.com/cloudtrail/` 5. Once the Cloudtrail is selected, check the Read event checkbox, so that `object-level` logging for `Read` events is enabled. 6. Repeat steps 2 to 5 to enable `object-level` logging of read events for other S3 buckets.**From Command Line:** 1. To enable `object-level` data events logging for S3 buckets within your AWS account, run `put-event-selectors` command using the name of the trail that you want to reconfigure as identifier: ``` aws cloudtrail put-event-selectors --region  --trail-name  --event-selectors '[{ \"ReadWriteType\": \"ReadOnly\", \"IncludeManagementEvents\":true, \"DataResources\": [{ \"Type\": \"AWS::S3::Object\", \"Values\": [\"arn:aws:s3:::/\"] }] }]' ``` 2. The command output will be `object-level` event trail configuration. 3. If you want to enable it for all buckets at ones then change Values parameter to `[\"arn:aws:s3\"]` in command given above. 4. Repeat step 1 for each s3 bucket to update `object-level` logging of read events. 5. Change the AWS region by updating the `--region` command parameter and perform the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that Object-level logging for read events is enabled for S3 bucket","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.10": {"name": "4.10","checks": {"cloudwatch_log_metric_filter_security_group_changes": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Security Groups are a stateful packet filter that controls ingress and egress traffic within a VPC. It is recommended that a metric filter and alarm be established for detecting changes to Security Groups.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query \"MetricAlarms[?MetricName== '']\" ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to security group will help ensure that resources and services are not unintentionally exposed.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for security groups changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name \"\" --filter-name \"\" --metric-transformations metricName= \"\" ,metricNamespace=\"CISBenchmark\",metricValue=1 --filter-pattern \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\" ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name \"\" ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn \"\" --protocol  --notification-endpoint \"\" ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name \"\" --metric-name \"\" --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace \"CISBenchmark\" --alarm-actions \"\" ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for security group changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.11": {"name": "4.11","checks": {"cloudwatch_changes_to_network_acls_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. NACLs are used as a stateless packet filter to control ingress and egress traffic for subnets within a VPC. It is recommended that a metric filter and alarm be established for changes made to NACLs.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to NACLs will help ensure that AWS resources and services are not unintentionally exposed.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for NACL changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL)","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.12": {"name": "4.12","checks": {"cloudwatch_changes_to_network_gateways_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Network gateways are required to send/receive traffic to a destination outside of a VPC. It is recommended that a metric filter and alarm be established for changes to network gateways.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to network gateways will help ensure that all ingress/egress traffic traverses the VPC border via a controlled path.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for network gateways changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for changes to network gateways","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.13": {"name": "4.13","checks": {"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Routing tables are used to route network traffic between subnets and to network gateways. It is recommended that a metric filter and alarm be established for changes to route tables.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to route tables will help ensure that all VPC traffic flows through an expected path.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for route table changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for route table changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.14": {"name": "4.14","checks": {"cloudwatch_changes_to_vpcs_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is possible to have more than 1 VPC within an account, in addition it is also possible to create a peer connection between 2 VPCs enabling network traffic to route between VPCs. It is recommended that a metric filter and alarm be established for changes made to VPCs.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to VPC will help ensure VPC traffic flow is not getting impacted.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for VPC changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for VPC changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.15": {"name": "4.15","checks": {"cloudwatch_log_metric_filter_aws_organizations_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/organizations/latest/userguide/orgs_security_incident-response.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for AWS Organizations changes made in the master AWS Account.","DefaultValue": null,"AuditProcedure": "1. Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured: - Identify the log group name configured for use with active multi-region CloudTrail: - List all CloudTrails:``` aws cloudtrail describe-trails ``` - Identify Multi region Cloudtrails, Trails with `\"IsMultiRegionTrail\"` set to true - From value associated with CloudWatchLogsLogGroupArn note **Example:** for CloudWatchLogsLogGroupArn that looks like arn:aws:logs:::log-group:NewGroup:*,  would be NewGroup- Ensure Identified Multi region CloudTrail is active: ``` aws cloudtrail get-trail-status --name  ``` Ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events: ``` aws cloudtrail get-event-selectors --trail-name  ``` - Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to true and `ReadWriteType` set to `All`.2. Get a list of all associated metric filters for this : ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdatePolicy\") || ($.eventName = \"UpdateOrganizationalUnit\")) }\" ``` 4. Note the `` value associated with the filterPattern found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4: ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the AlarmActions value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic: ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. Example of valid \"SubscriptionArn\":``` \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring AWS Organizations changes can help you prevent any unwanted, accidental or intentional modifications that may lead to unauthorized access or other security breaches. This monitoring technique helps you to ensure that any unexpected changes performed within your AWS Organizations can be investigated and any unwanted changes can be rolled back.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Organizations changes and the `` taken from audit step 1: ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdatePolicy\") || ($.eventName = \"UpdateOrganizationalUnit\")) }' ``` **Note:** You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify: ``` aws sns create-topic --name  ``` **Note:** you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2: ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note:** you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2: ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": ""}],"description": "Ensure a log metric filter and alarm exists for AWS Organizations changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.16": {"name": "4.16","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-get-started.html:https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-enable.html#securityhub-enable-api:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/securityhub/enable-security-hub.html","Description": "Security Hub collects security data from across AWS accounts, services, and supported third-party partner products and helps you analyze your security trends and identify the highest priority security issues. When you enable Security Hub, it begins to consume, aggregate, organize, and prioritize findings from AWS services that you have enabled, such as Amazon GuardDuty, Amazon Inspector, and Amazon Macie. You can also enable integrations with AWS partner security products.","DefaultValue": null,"AuditProcedure": "The process to evaluate AWS Security Hub configuration per region **From Console:**1. Sign in to the AWS Management Console and open the AWS Security Hub console at https://console.aws.amazon.com/securityhub/. 2. On the top right of the console, select the target Region. 3. If presented with the Security Hub > Summary page then Security Hub is set-up for the selected region. 4. If presented with Setup Security Hub or Get Started With Security Hub - follow the online instructions. 5. Repeat steps 2 to 4 for each region.","ImpactStatement": "It is recommended AWS Security Hub be enabled in all regions. AWS Security Hub requires AWS Config to be enabled.","AssessmentStatus": "Automated","RationaleStatement": "AWS Security Hub provides you with a comprehensive view of your security state in AWS and helps you check your environment against security industry standards and best practices - enabling you to quickly assess the security posture across your AWS accounts.","RemediationProcedure": "To grant the permissions required to enable Security Hub, attach the Security Hub managed policy AWSSecurityHubFullAccess to an IAM user, group, or role.Enabling Security Hub**From Console:**1. Use the credentials of the IAM identity to sign in to the Security Hub console. 2. When you open the Security Hub console for the first time, choose Enable AWS Security Hub. 3. On the welcome page, Security standards list the security standards that Security Hub supports. 4. Choose Enable Security Hub.**From Command Line:**1. Run the enable-security-hub command. To enable the default standards, include `--enable-default-standards`. ``` aws securityhub enable-security-hub --enable-default-standards ```2. To enable the security hub without the default standards, include `--no-enable-default-standards`. ``` aws securityhub enable-security-hub --no-enable-default-standards ```","AdditionalInformation": ""}],"description": "Ensure AWS Security Hub is enabled","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.1": {"name": "2.1.1","checks": {"s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-policy-for-config-rule/:https://aws.amazon.com/blogs/security/how-to-use-bucket-policies-and-apply-defense-in-depth-to-help-secure-your-amazon-s3-data/:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-bucket-policy.html","Description": "At the Amazon S3 bucket level, you can configure permissions through a bucket policy making the objects accessible only through HTTPS.","DefaultValue": null,"AuditProcedure": "To allow access to HTTPS you can use a condition that checks for the key `\"aws:SecureTransport: true\"`. This means that the request is sent through HTTPS but that HTTP can still be used. So to make sure you do not allow HTTP access confirm that there is a bucket policy that explicitly denies access for HTTP requests and that it contains the key \"aws:SecureTransport\": \"false\".**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/ 2. Select the Check box next to the Bucket. 3. Click on 'Permissions', then Click on `Bucket Policy`. 4. Ensure that a policy is listed that matches: ``` '{\"Sid\": ,\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}' ``` `` and `` will be specific to your account5. Repeat for all the buckets in your AWS account.**From Command Line:**1. List all of the S3 Buckets``` aws s3 ls ``` 2. Using the list of buckets run this command on each of them: ``` aws s3api get-bucket-policy --bucket  | grep aws:SecureTransport ``` 3. Confirm that `aws:SecureTransport` is set to false `aws:SecureTransport:false` 4. Confirm that the policy line has Effect set to Deny 'Effect:Deny'","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "By default, Amazon S3 allows both HTTP and HTTPS requests. To achieve only allowing access to Amazon S3 objects through HTTPS you also have to explicitly deny access to HTTP requests. Bucket policies that allow HTTPS requests without explicitly denying HTTP requests will not comply with this recommendation.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/ 2. Select the Check box next to the Bucket. 3. Click on 'Permissions'. 4. Click 'Bucket Policy' 5. Add this to the existing policy filling in the required information ``` {\"Sid\": \",\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}}} ``` 6. Save 7. Repeat for all the buckets in your AWS account that contain sensitive data.**From Console** using AWS Policy Generator:1. Repeat steps 1-4 above. 2. Click on `Policy Generator` at the bottom of the Bucket Policy Editor 3. Select Policy Type `S3 Bucket Policy` 4. Add Statements - `Effect` = Deny - `Principal` = * - `AWS Service` = Amazon S3 - `Actions` = * - `Amazon Resource Name` =  5. Generate Policy 6. Copy the text and add it to the Bucket Policy.**From Command Line:**1. Export the bucket policy to a json file. ``` aws s3api get-bucket-policy --bucket  --query Policy --output text > policy.json ```2. Modify the policy.json file by adding in this statement: ``` {\"Sid\": \",\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}}} ``` 3. Apply this modified policy back to the S3 bucket: ``` aws s3api put-bucket-policy --bucket  --policy file://policy.json ```","AdditionalInformation": ""}],"description": "Ensure S3 Bucket Policy is set to deny HTTP requests","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.1.2": {"name": "2.1.2","checks": {"s3_bucket_no_mfa_delete": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html#MultiFactorAuthenticationDelete:https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMFADelete.html:https://aws.amazon.com/blogs/security/securing-access-to-aws-using-mfa-part-3/:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_lost-or-broken.html","Description": "Once MFA Delete is enabled on your sensitive and classified S3 bucket it requires the user to have two forms of authentication.","DefaultValue": null,"AuditProcedure": "Perform the steps below to confirm MFA delete is configured on an S3 Bucket**From Console:**1. Login to the S3 console at `https://console.aws.amazon.com/s3/`2. Click the `Check` box next to the Bucket name you want to confirm3. In the window under `Properties`4. Confirm that Versioning is `Enabled`5. Confirm that MFA Delete is `Enabled`**From Command Line:**1. Run the `get-bucket-versioning` ``` aws s3api get-bucket-versioning --bucket my-bucket ```Output example: ```  EnabledEnabled ```If the Console or the CLI output does not show Versioning and MFA Delete `enabled` refer to the remediation below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Adding MFA delete to an S3 bucket, requires additional authentication when you change the version state of your bucket or you delete and object version adding another layer of security in the event your security credentials are compromised or unauthorized access is granted.","RemediationProcedure": "Perform the steps below to enable MFA delete on an S3 bucket.Note: -You cannot enable MFA Delete using the AWS Management Console. You must use the AWS CLI or API. -You must use your 'root' account to enable MFA Delete on S3 buckets.**From Command line:**1. Run the s3api put-bucket-versioning command``` aws s3api put-bucket-versioning --profile my-root-profile --bucket Bucket_Name --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa ā€œarn:aws:iam::aws_account_id:mfa/root-account-mfa-device passcodeā€ ```","AdditionalInformation": ""}],"description": "Ensure MFA Delete is enabled on S3 buckets","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.1.3": {"name": "2.1.3","checks": {"macie_is_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://aws.amazon.com/macie/getting-started/:https://docs.aws.amazon.com/workspaces/latest/adminguide/data-protection.html:https://docs.aws.amazon.com/macie/latest/user/data-classification.html","Description": "Amazon S3 buckets can contain sensitive data, that for security purposes should be discovered, monitored, classified and protected. Macie along with other 3rd party tools can automatically provide an inventory of Amazon S3 buckets.","DefaultValue": null,"AuditProcedure": "Perform the following steps to determine if Macie is running:**From Console:** 1. Login to the Macie console at https://console.aws.amazon.com/macie/ 2. In the left hand pane click on By job under findings. 3. Confirm that you have a Job setup for your S3 BucketsWhen you log into the Macie console if you aren't taken to the summary page and you don't have a job setup and running then refer to the remediation procedure below.If you are using a 3rd Party tool to manage and protect your s3 data you meet this recommendation.","ImpactStatement": "There is a cost associated with using Amazon Macie. There is also typically a cost associated with 3rd Party tools that perform similar processes and protection.","AssessmentStatus": "Manual","RationaleStatement": "Using a Cloud service or 3rd Party software to continuously monitor and automate the process of data discovery and classification for S3 buckets using machine learning and pattern matching is a strong defense in protecting that information.Amazon Macie is a fully managed data security and data privacy service that uses machine learning and pattern matching to discover and protect your sensitive data in AWS.","RemediationProcedure": "Perform the steps below to enable and configure Amazon Macie**From Console:**1. Log on to the Macie console at `https://console.aws.amazon.com/macie/`2. Click `Get started`.3. Click `Enable Macie`.Setup a repository for sensitive data discovery results1. In the Left pane, under Settings, click `Discovery results`.2. Make sure `Create bucket` is selected.3. Create a bucket, enter a name for the bucket. The name must be unique across all S3 buckets. In addition, the name must start with a lowercase letter or a number.4. Click on `Advanced`.5. Block all public access, make sure `Yes` is selected.6. KMS encryption, specify the AWS KMS key that you want to use to encrypt the results. The key must be a symmetric, customer master key (CMK) that's in the same Region as the S3 bucket.7. Click on `Save`Create a job to discover sensitive data1. In the left pane, click `S3 buckets`. Macie displays a list of all the S3 buckets for your account.2. Select the `check box` for each bucket that you want Macie to analyze as part of the job3. Click `Create job`.3. Click `Quick create`.4. For the Name and description step, enter a name and, optionally, a description of the job.5. Then click `Next`.6. For the Review and create step, click `Submit`.Review your findings1. In the left pane, click `Findings`.2. To view the details of a specific finding, choose any field other than the check box for the finding.If you are using a 3rd Party tool to manage and protect your s3 data, follow the Vendor documentation for implementing and configuring that tool.","AdditionalInformation": ""}],"description": "Ensure all data in Amazon S3 has been discovered, classified and secured when required.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.4": {"name": "2.1.4","checks": {"s3_bucket_level_public_access_block": "PASS","s3_account_level_public_access_blocks": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/block-public-access-account.html","Description": "Amazon S3 provides `Block public access (bucket settings)` and `Block public access (account settings)` to help you manage public access to Amazon S3 resources. By default, S3 buckets and objects are created with public access disabled. However, an IAM principal with sufficient S3 permissions can enable public access at the bucket and/or object level. While enabled, `Block public access (bucket settings)` prevents an individual bucket, and its contained objects, from becoming publicly accessible. Similarly, `Block public access (account settings)` prevents all buckets, and contained objects, from becoming publicly accessible across the entire account.","DefaultValue": null,"AuditProcedure": "**If utilizing Block Public Access (bucket settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select the Check box next to the Bucket. 3. Click on 'Edit public access settings'. 4. Ensure that block public access settings are set appropriately for this bucket 5. Repeat for all the buckets in your AWS account.**From Command Line:**1. List all of the S3 Buckets ``` aws s3 ls ``` 2. Find the public access setting on that bucket ``` aws s3api get-public-access-block --bucket  ``` Output if Block Public access is enabled:``` {\"PublicAccessBlockConfiguration\": {\"BlockPublicAcls\": true,\"IgnorePublicAcls\": true,\"BlockPublicPolicy\": true,\"RestrictPublicBuckets\": true} } ```If the output reads `false` for the separate configuration settings then proceed to the remediation.**If utilizing Block Public Access (account settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Choose `Block public access (account settings)` 3. Ensure that block public access settings are set appropriately for your AWS account.**From Command Line:**To check Public access settings for this account status, run the following command, `aws s3control get-public-access-block --account-id  --region `Output if Block Public access is enabled:``` {\"PublicAccessBlockConfiguration\": {\"IgnorePublicAcls\": true, \"BlockPublicPolicy\": true, \"BlockPublicAcls\": true, \"RestrictPublicBuckets\": true} } ```If the output reads `false` for the separate configuration settings then proceed to the remediation.","ImpactStatement": "When you apply Block Public Access settings to an account, the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously, but they eventually propagate to all Regions.","AssessmentStatus": "Automated","RationaleStatement": "Amazon S3 `Block public access (bucket settings)` prevents the accidental or malicious public exposure of data contained within the respective bucket(s). Amazon S3 `Block public access (account settings)` prevents the accidental or malicious public exposure of data contained within all buckets of the respective AWS account.Whether blocking public access to all or some buckets is an organizational decision that should be based on data sensitivity, least privilege, and use case.","RemediationProcedure": "**If utilizing Block Public Access (bucket settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select the Check box next to the Bucket. 3. Click on 'Edit public access settings'. 4. Click 'Block all public access' 5. Repeat for all the buckets in your AWS account that contain sensitive data.**From Command Line:**1. List all of the S3 Buckets ``` aws s3 ls ``` 2. Set the Block Public Access to true on that bucket ``` aws s3api put-public-access-block --bucket  --public-access-block-configuration \"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true\" ```**If utilizing Block Public Access (account settings)****From Console:**If the output reads `true` for the separate configuration settings then it is set on the account.1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Choose `Block Public Access (account settings)` 3. Choose `Edit` to change the block public access settings for all the buckets in your AWS account 4. Choose the settings you want to change, and then choose `Save`. For details about each setting, pause on the `i` icons. 5. When you're asked for confirmation, enter `confirm`. Then Click `Confirm` to save your changes.**From Command Line:**To set Block Public access settings for this account, run the following command: ``` aws s3control put-public-access-block --public-access-block-configuration BlockPublicAcls=true, IgnorePublicAcls=true, BlockPublicPolicy=true, RestrictPublicBuckets=true --account-id  ```","AdditionalInformation": ""}],"description": "Ensure that S3 Buckets are configured with 'Block public access (bucket settings)'","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"2.2.1": {"name": "2.2.1","checks": {"ec2_ebs_volume_encryption": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.2. Elastic Compute Cloud (EC2)","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html:https://aws.amazon.com/blogs/aws/new-opt-in-to-default-encryption-for-new-ebs-volumes/","Description": "Elastic Compute Cloud (EC2) supports encryption at rest when using the Elastic Block Store (EBS) service. While disabled by default, forcing encryption at EBS volume creation is supported.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under `Account attributes`, click `EBS encryption`. 3. Verify `Always encrypt new EBS volumes` displays `Enabled`. 4. Review every region in-use.**Note:** EBS volume encryption is configured per region.**From Command Line:**1. Run``` aws --region  ec2 get-ebs-encryption-by-default ``` 2. Verify that `\"EbsEncryptionByDefault\": true` is displayed. 3. Review every region in-use.**Note:** EBS volume encryption is configured per region.","ImpactStatement": "Losing access or removing the KMS key in use by the EBS volumes will result in no longer being able to access the volumes.","AssessmentStatus": "Automated","RationaleStatement": "Encrypting data at rest reduces the likelihood that it is unintentionally exposed and can nullify the impact of disclosure if the encryption remains unbroken.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under `Account attributes`, click `EBS encryption`. 3. Click `Manage`. 4. Click the `Enable` checkbox. 5. Click `Update EBS encryption` 6. Repeat for every region requiring the change.**Note:** EBS volume encryption is configured per region.**From Command Line:**1. Run``` aws --region  ec2 enable-ebs-encryption-by-default ``` 2. Verify that `\"EbsEncryptionByDefault\": true` is displayed. 3. Repeat every region requiring the change.**Note:** EBS volume encryption is configured per region.","AdditionalInformation": "Default EBS volume encryption only applies to newly created EBS volumes. Existing EBS volumes are **not** converted automatically."}],"description": "Ensure EBS Volume Encryption is Enabled in all Regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.3.1": {"name": "2.3.1","checks": {"rds_instance_storage_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Encryption.html:https://aws.amazon.com/blogs/database/selecting-the-right-encryption-options-for-amazon-rds-and-amazon-aurora-database-engines/#:~:text=With%20RDS%2Dencrypted%20resources%2C%20data,transparent%20to%20your%20database%20engine.:https://aws.amazon.com/rds/features/security/","Description": "Amazon RDS encrypted DB instances use the industry standard AES-256 encryption algorithm to encrypt your data on the server that hosts your Amazon RDS DB instances. After your data is encrypted, Amazon RDS handles authentication of access and decryption of your data transparently with a minimal impact on performance.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and open the RDS dashboard at https://console.aws.amazon.com/rds/ 2. In the navigation pane, under RDS dashboard, click `Databases`. 3. Select the RDS Instance that you want to examine 4. Click `Instance Name` to see details, then click on `Configuration` tab. 5. Under Configuration Details section, In Storage pane search for the `Encryption Enabled` Status. 6. If the current status is set to `Disabled`, Encryption is not enabled for the selected RDS Instance database instance. 7. Repeat steps 3 to 7 to verify encryption status of other RDS Instance in same region. 8. Change region from the top of the navigation bar and repeat audit for other regions.**From Command Line:**1. Run `describe-db-instances` command to list all RDS Instance database names, available in the selected AWS region, Output will return each Instance database identifier-name.``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. Run again `describe-db-instances` command using the RDS Instance identifier returned earlier, to determine if the selected database instance is encrypted, The command output should return the encryption status `True` Or `False`. ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].StorageEncrypted' ``` 3. If the StorageEncrypted parameter value is `False`, Encryption is not enabled for the selected RDS database instance. 4. Repeat steps 1 to 3 for auditing each RDS Instance and change Region to verify for other regions","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Databases are likely to hold sensitive and critical data, it is highly recommended to implement encryption in order to protect your data from unauthorized access or disclosure. With RDS encryption enabled, the data stored on the instance's underlying storage, the automated backups, read replicas, and snapshots, are all encrypted.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and open the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases` 3. Select the Database instance that needs to be encrypted. 4. Click on `Actions` button placed at the top right and select `Take Snapshot`. 5. On the Take Snapshot page, enter a database name of which you want to take a snapshot in the `Snapshot Name` field and click on `Take Snapshot`. 6. Select the newly created snapshot and click on the `Action` button placed at the top right and select `Copy snapshot` from the Action menu. 7. On the Make Copy of DB Snapshot page, perform the following:- In the New DB Snapshot Identifier field, Enter a name for the `new snapshot`. - Check `Copy Tags`, New snapshot must have the same tags as the source snapshot. - Select `Yes` from the `Enable Encryption` dropdown list to enable encryption, You can choose to use the AWS default encryption key or custom key from Master Key dropdown list.8. Click `Copy Snapshot` to create an encrypted copy of the selected instance snapshot. 9. Select the new Snapshot Encrypted Copy and click on the `Action` button placed at the top right and select `Restore Snapshot` button from the Action menu, This will restore the encrypted snapshot to a new database instance. 10. On the Restore DB Instance page, enter a unique name for the new database instance in the DB Instance Identifier field. 11. Review the instance configuration details and click `Restore DB Instance`. 12. As the new instance provisioning process is completed can update application configuration to refer to the endpoint of the new Encrypted database instance Once the database endpoint is changed at the application level, can remove the unencrypted instance.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names available in the selected AWS region, The command output should return the database instance identifier. ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. Run `create-db-snapshot` command to create a snapshot for the selected database instance, The command output will return the `new snapshot` with name DB Snapshot Name. ``` aws rds create-db-snapshot --region  --db-snapshot-identifier  --db-instance-identifier  ``` 3. Now run `list-aliases` command to list the KMS keys aliases available in a specified region, The command output should return each `key alias currently available`. For our RDS encryption activation process, locate the ID of the AWS default KMS key. ``` aws kms list-aliases --region  ``` 4. Run `copy-db-snapshot` command using the default KMS key ID for RDS instances returned earlier to create an encrypted copy of the database instance snapshot, The command output will return the `encrypted instance snapshot configuration`. ``` aws rds copy-db-snapshot --region  --source-db-snapshot-identifier  --target-db-snapshot-identifier  --copy-tags --kms-key-id  ``` 5. Run `restore-db-instance-from-db-snapshot` command to restore the encrypted snapshot created at the previous step to a new database instance, If successful, the command output should return the new encrypted database instance configuration. ``` aws rds restore-db-instance-from-db-snapshot --region  --db-instance-identifier  --db-snapshot-identifier  ``` 6. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region, Output will return database instance identifier name Select encrypted database name that we just created DB-Name-Encrypted. ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 7. Run again `describe-db-instances` command using the RDS instance identifier returned earlier, to determine if the selected database instance is encrypted, The command output should return the encryption status `True`. ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].StorageEncrypted' ```","AdditionalInformation": ""}],"description": "Ensure that encryption is enabled for RDS Instances","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.3.2": {"name": "2.3.2","checks": {"rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_RDS_Managing.html:https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.Upgrading.html:https://aws.amazon.com/rds/faqs/","Description": "Ensure that RDS database instances have the Auto Minor Version Upgrade flag enabled in order to receive automatically minor engine upgrades during the specified maintenance window. So, RDS instances can get the new features, bug fixes, and security patches for their database engines.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases`. 3. Select the RDS instance that wants to examine. 4. Click on the `Maintenance and backups` panel. 5. Under the `Maintenance` section, search for the Auto Minor Version Upgrade status. - If the current status is set to `Disabled`, means the feature is not set and the minor engine upgrades released will not be applied to the selected RDS instance**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance identifier. 3. Run again `describe-db-instances` command using the RDS instance identifier returned earlier to determine the Auto Minor Version Upgrade status for the selected instance: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].AutoMinorVersionUpgrade' ``` 4. The command output should return the feature current status. If the current status is set to `true`, the feature is enabled and the minor engine upgrades will be applied to the selected RDS instance.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "AWS RDS will occasionally deprecate minor engine versions and provide new ones for an upgrade. When the last version number within the release is replaced, the version changed is considered minor. With Auto Minor Version Upgrade feature enabled, the version upgrades will occur automatically during the specified maintenance window so your RDS instances can get the new features, bug fixes, and security patches for their database engines.","RemediationProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases`. 3. Select the RDS instance that wants to update. 4. Click on the `Modify` button placed on the top right side. 5. On the `Modify DB Instance: ` page, In the `Maintenance` section, select `Auto minor version upgrade` click on the `Yes` radio button. 6. At the bottom of the page click on `Continue`, check to Apply Immediately to apply the changes immediately, or select `Apply during the next scheduled maintenance window` to avoid any downtime. 7. Review the changes and click on `Modify DB Instance`. The instance status should change from available to modifying and back to available. Once the feature is enabled, the `Auto Minor Version Upgrade` status should change to `Yes`.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database instance names, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance identifier. 3. Run the `modify-db-instance` command to modify the selected RDS instance configuration this command will apply the changes immediately, Remove `--apply-immediately` to apply changes during the next scheduled maintenance window and avoid any downtime: ``` aws rds modify-db-instance --region  --db-instance-identifier  --auto-minor-version-upgrade --apply-immediately ``` 4. The command output should reveal the new configuration metadata for the RDS instance and check `AutoMinorVersionUpgrade` parameter value. 5. Run `describe-db-instances` command to check if the Auto Minor Version Upgrade feature has been successfully enable: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].AutoMinorVersionUpgrade' ``` 6. The command output should return the feature current status set to `true`, the feature is `enabled` and the minor engine upgrades will be applied to the selected RDS instance.","AdditionalInformation": ""}],"description": "Ensure Auto Minor Version Upgrade feature is Enabled for RDS Instances","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.3.3": {"name": "2.3.3","checks": {"rds_instance_no_public_access": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.html:https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario2.html:https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html:https://aws.amazon.com/rds/faqs/","Description": "Ensure and verify that RDS database instances provisioned in your AWS account do restrict unauthorized access in order to minimize security risks. To restrict access to any publicly accessible RDS database instance, you must disable the database Publicly Accessible flag and update the VPC security group associated with the instance.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. Under the navigation panel, On RDS Dashboard, click `Databases`. 3. Select the RDS instance that you want to examine. 4. Click `Instance Name` from the dashboard, Under `Connectivity and Security. 5. On the `Security`, check if the Publicly Accessible flag status is set to `Yes`, follow the below-mentioned steps to check database subnet access. - In the `networking` section, click the subnet link available under `Subnets` - The link will redirect you to the VPC Subnets page. - Select the subnet listed on the page and click the `Route Table` tab from the dashboard bottom panel. If the route table contains any entries with the destination `CIDR block set to 0.0.0.0/0` and with an `Internet Gateway` attached. - The selected RDS database instance was provisioned inside a public subnet, therefore is not running within a logically isolated environment and can be accessible from the Internet. 6. Repeat steps no. 4 and 5 to determine the type (public or private) and subnet for other RDS database instances provisioned in the current region. 8. Change the AWS region from the navigation bar and repeat the audit process for other regions.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance `identifier`. 3. Run again `describe-db-instances` command using the `PubliclyAccessible` parameter as query filter to reveal the database instance Publicly Accessible flag status: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].PubliclyAccessible' ``` 4. Check for the Publicly Accessible parameter status, If the Publicly Accessible flag is set to `Yes`. Then selected RDS database instance is publicly accessible and insecure, follow the below-mentioned steps to check database subnet access 5. Run again `describe-db-instances` command using the RDS database instance identifier that you want to check and appropriate filtering to describe the VPC subnet(s) associated with the selected instance: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].DBSubnetGroup.Subnets[]' ``` - The command output should list the subnets available in the selected database subnet group. 6. Run `describe-route-tables` command using the ID of the subnet returned at the previous step to describe the routes of the VPC route table associated with the selected subnet: ``` aws ec2 describe-route-tables --region  --filters \"Name=association.subnet-id,Values=\" --query 'RouteTables[*].Routes[]' ``` - If the command returns the route table associated with database instance subnet ID. Check the `GatewayId` and `DestinationCidrBlock` attributes values returned in the output. If the route table contains any entries with the `GatewayId` value set to `igw-xxxxxxxx` and the `DestinationCidrBlock` value set to `0.0.0.0/0`, the selected RDS database instance was provisioned inside a public subnet. - Or - If the command returns empty results, the route table is implicitly associated with subnet, therefore the audit process continues with the next step 7. Run again `describe-db-instances` command using the RDS database instance identifier that you want to check and appropriate filtering to describe the VPC ID associated with the selected instance: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].DBSubnetGroup.VpcId' ``` - The command output should show the VPC ID in the selected database subnet group 8. Now run `describe-route-tables` command using the ID of the VPC returned at the previous step to describe the routes of the VPC main route table implicitly associated with the selected subnet: ``` aws ec2 describe-route-tables --region  --filters \"Name=vpc-id,Values=\" \"Name=association.main,Values=true\" --query 'RouteTables[*].Routes[]' ``` - The command output returns the VPC main route table implicitly associated with database instance subnet ID. Check the `GatewayId` and `DestinationCidrBlock` attributes values returned in the output. If the route table contains any entries with the `GatewayId` value set to `igw-xxxxxxxx` and the `DestinationCidrBlock` value set to `0.0.0.0/0`, the selected RDS database instance was provisioned inside a public subnet, therefore is not running within a logically isolated environment and does not adhere to AWS security best practices.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Ensure that no public-facing RDS database instances are provisioned in your AWS account and restrict unauthorized access in order to minimize security risks. When the RDS instance allows unrestricted access (0.0.0.0/0), everyone and everything on the Internet can establish a connection to your database and this can increase the opportunity for malicious activities such as brute force attacks, PostgreSQL injections, or DoS/DDoS attacks.","RemediationProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. Under the navigation panel, On RDS Dashboard, click `Databases`. 3. Select the RDS instance that you want to update. 4. Click `Modify` from the dashboard top menu. 5. On the Modify DB Instance panel, under the `Connectivity` section, click on `Additional connectivity configuration` and update the value for `Publicly Accessible` to Not publicly accessible to restrict public access. Follow the below steps to update subnet configurations: - Select the `Connectivity and security` tab, and click on the VPC attribute value inside the `Networking` section. - Select the `Details` tab from the VPC dashboard bottom panel and click on Route table configuration attribute value. - On the Route table details page, select the Routes tab from the dashboard bottom panel and click on `Edit routes`. - On the Edit routes page, update the Destination of Target which is set to `igw-xxxxx` and click on `Save` routes. 6. On the Modify DB Instance panel Click on `Continue` and In the Scheduling of modifications section, perform one of the following actions based on your requirements: - Select Apply during the next scheduled maintenance window to apply the changes automatically during the next scheduled maintenance window. - Select Apply immediately to apply the changes right away. With this option, any pending modifications will be asynchronously applied as soon as possible, regardless of the maintenance window setting for this RDS database instance. Note that any changes available in the pending modifications queue are also applied. If any of the pending modifications require downtime, choosing this option can cause unexpected downtime for the application. 7. Repeat steps 3 to 6 for each RDS instance available in the current region. 8. Change the AWS region from the navigation bar to repeat the process for other regions.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names identifiers, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance identifier. 3. Run `modify-db-instance` command to modify the selected RDS instance configuration. Then use the following command to disable the `Publicly Accessible` flag for the selected RDS instances. This command use the apply-immediately flag. If you want `to avoid any downtime --no-apply-immediately flag can be used`: ``` aws rds modify-db-instance --region  --db-instance-identifier  --no-publicly-accessible --apply-immediately ``` 4. The command output should reveal the `PubliclyAccessible` configuration under pending values and should get applied at the specified time. 5. Updating the Internet Gateway Destination via AWS CLI is not currently supported To update information about Internet Gateway use the AWS Console Procedure. 6. Repeat steps 1 to 5 for each RDS instance provisioned in the current region. 7. Change the AWS region by using the --region filter to repeat the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that public access is not given to RDS Instance","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.4.1": {"name": "2.4.1","checks": {"efs_encryption_at_rest_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.4 Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/efs/index.html#efs","Description": "EFS data should be encrypted at rest using AWS KMS (Key Management Service).","DefaultValue": null,"AuditProcedure": "**From Console:** 1. Login to the AWS Management Console and Navigate to `Elastic File System (EFS) dashboard. 2. Select `File Systems` from the left navigation panel. 3. Each item on the list has a visible Encrypted field that displays data at rest encryption status. 4. Validate that this field reads `Encrypted` for all EFS file systems in all AWS regions.**From CLI:** 1. Run describe-file-systems command using custom query filters to list the identifiers of all AWS EFS file systems currently available within the selected region: ``` aws efs describe-file-systems --region  --output table --query 'FileSystems[*].FileSystemId' ``` 2. The command output should return a table with the requested file system IDs. 3. Run describe-file-systems command using the ID of the file system that you want to examine as identifier and the necessary query filters: ``` aws efs describe-file-systems --region  --file-system-id  --query 'FileSystems[*].Encrypted' ``` 4. The command output should return the file system encryption status true or false. If the returned value is `false`, the selected AWS EFS file system is not encrypted and if the returned value is `true`, the selected AWS EFS file system is encrypted.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Data should be encrypted at rest to reduce the risk of a data breach via direct access to the storage device.","RemediationProcedure": "**It is important to note that EFS file system data at rest encryption must be turned on when creating the file system.**If an EFS file system has been created without data at rest encryption enabled then you must create another EFS file system with the correct configuration and transfer the data.**Steps to create an EFS file system with data encrypted at rest:****From Console:** 1. Login to the AWS Management Console and Navigate to `Elastic File System (EFS)` dashboard. 2. Select `File Systems` from the left navigation panel. 3. Click `Create File System` button from the dashboard top menu to start the file system setup process. 4. On the `Configure file system access` configuration page, perform the following actions. - Choose the right VPC from the VPC dropdown list. - Within Create mount targets section, select the checkboxes for all of the Availability Zones (AZs) within the selected VPC. These will be your mount targets. - Click `Next step` to continue.5. Perform the following on the `Configure optional settings` page. - Create `tags` to describe your new file system. - Choose `performance mode` based on your requirements. - Check `Enable encryption` checkbox and choose `aws/elasticfilesystem` from Select KMS master key dropdown list to enable encryption for the new file system using the default master key provided and managed by AWS KMS. - Click `Next step` to continue.6. Review the file system configuration details on the `review and create` page and then click `Create File System` to create your new AWS EFS file system. 7. Copy the data from the old unencrypted EFS file system onto the newly create encrypted file system. 8. Remove the unencrypted file system as soon as your data migration to the newly create encrypted file system is completed. 9. Change the AWS region from the navigation bar and repeat the entire process for other aws regions.**From CLI:** 1. Run describe-file-systems command to describe the configuration information available for the selected (unencrypted) file system (see Audit section to identify the right resource): ``` aws efs describe-file-systems --region  --file-system-id  ``` 2. The command output should return the requested configuration information. 3. To provision a new AWS EFS file system, you need to generate a universally unique identifier (UUID) in order to create the token required by the create-file-system command. To create the required token, you can use a randomly generated UUID from \"https://www.uuidgenerator.net\". 4. Run create-file-system command using the unique token created at the previous step. ``` aws efs create-file-system --region  --creation-token  --performance-mode generalPurpose --encrypted ``` 5. The command output should return the new file system configuration metadata. 6. Run create-mount-target command using the newly created EFS file system ID returned at the previous step as identifier and the ID of the Availability Zone (AZ) that will represent the mount target: ``` aws efs create-mount-target --region  --file-system-id  --subnet-id  ``` 7. The command output should return the new mount target metadata. 8. Now you can mount your file system from an EC2 instance. 9. Copy the data from the old unencrypted EFS file system onto the newly create encrypted file system. 10. Remove the unencrypted file system as soon as your data migration to the newly create encrypted file system is completed. ``` aws efs delete-file-system --region  --file-system-id  ``` 11. Change the AWS region by updating the --region and repeat the entire process for other aws regions.","AdditionalInformation": ""}],"description": "Ensure that encryption is enabled for EFS file systems","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 52,"requirements_failed": 11,"requirements_manual": 1,"total_requirements": 64,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "7aee25d8-9e9a-44e1-8e01-336bfd9d9582","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "aws_well_architected_framework_reliability_pillar_aws","framework": "AWS-Well-Architected-Framework-Reliability-Pillar","version": "","description": "Best Practices for the AWS Well-Architected Framework Reliability Pillar encompasses the ability of a workload to perform its intended function correctly and consistently when it’s expected to. This includes the ability to operate and test the workload through its total lifecycle.","region": "eu-west-1","requirements": {"REL06-BP01": {"name": "REL06-BP01","checks": {"elb_logging_enabled": "FAIL","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","apigatewayv2_api_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","opensearch_service_domains_audit_logging_enabled": null,"opensearch_service_domains_cloudwatch_logging_enabled": null,"awslambda_function_invoke_api_operations_cloudtrail_logging_enabled": "PASS"},"status": "FAIL","attributes": [{"Name": "REL06-BP01 Monitor all components for the workload (Generation)","Section": "Change management","SubSection": "Monitor workload resources","Description": "Monitor components and services of AWS workload effectifely, using tools like Amazon CloudWatch and AWS Health Dashboard. Define relevant metrics, set thresholds, and analyze metrics and logs for early detection of issues.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_monitor_aws_resources_monitor_resources.html#implementation-guidance","WellArchitectedPracticeId": "rel_monitor_aws_resources_monitor_resources","WellArchitectedQuestionId": "monitor-aws-resources"}],"description": "Monitor components and services of AWS workload effectifely, using tools like Amazon CloudWatch and AWS Health Dashboard. Define relevant metrics, set thresholds, and analyze metrics and logs for early detection of issues.","checks_status": {"fail": 5,"pass": 2,"total": 9,"manual": 0}},"REL09-BP03": {"name": "REL09-BP03","checks": {"rds_instance_backup_enabled": "PASS","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL","cloudformation_stacks_termination_protection_enabled": "FAIL"},"status": "FAIL","attributes": [{"Name": "REL09-BP03 Perform data backup automatically","Section": "Failure management","SubSection": "Backup up data","Description": "Configure backups to be taken automatically based on a periodic schedule informed by the Recovery Point Objective (RPO), or by changes in the dataset. Critical datasets with low data loss requirements need to be backed up automatically on a frequent basis, whereas less critical data where some loss is acceptable can be backed up less frequently.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_backing_up_data_automated_backups_data.html#implementation-guidance","WellArchitectedPracticeId": "rel_backing_up_data_automated_backups_data","WellArchitectedQuestionId": "backing-up-data"}],"description": "Configure backups to be taken automatically based on a periodic schedule informed by the Recovery Point Objective (RPO), or by changes in the dataset. Critical datasets with low data loss requirements need to be backed up automatically on a frequent basis, whereas less critical data where some loss is acceptable can be backed up less frequently.","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"REL10-BP01": {"name": "REL10-BP01","checks": {"rds_instance_multi_az": "FAIL"},"status": "FAIL","attributes": [{"Name": "REL10-BP01 Deploy the workload to multiple locations","Section": "Failure management","SubSection": "Use fault isolation to protect your workload","Description": "Distribute workload data and resources across multiple Availability Zones or, where necessary, across AWS Regions. These locations can be as diverse as required.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/use-fault-isolation-to-protect-your-workload.html#implementation-guidance.","WellArchitectedPracticeId": "rel_fault_isolation_multiaz_region_system","WellArchitectedQuestionId": "fault-isolation"}],"description": "Distribute workload data and resources across multiple Availability Zones or, where necessary, across AWS Regions. These locations can be as diverse as required.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 0,"requirements_failed": 3,"requirements_manual": 0,"total_requirements": 3,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "85c783d4-a01a-4297-b490-216e38ee144e","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "iso27001_2013_aws","framework": "ISO27001","version": "2013","description": "ISO (the International Organization for Standardization) and IEC (the International Electrotechnical Commission) form the specialized system for worldwide standardization. National bodies that are members of ISO or IEC participate in the development of International Standards through technical committees established by the respective organization to deal with particular fields of technical activity. ISO and IEC technical committees collaborate in fields of mutual interest. Other international organizations, governmental and non-governmental, in liaison with ISO and IEC, also take part in the work.","region": "eu-west-1","requirements": {"A.9.2": {"name": "User Access Management","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Category": "A.9 Access Control","Objetive_ID": "A.9.2","Check_Summary": "Ensure no root account access key exists","Objetive_Name": "User Access Management"}],"description": "Ensure no root account access key exists","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"A.9.3": {"name": "User Responsibilities","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Category": "A.9 Access Control","Objetive_ID": "A.9.3","Check_Summary": "Ensure credentials unused for 90 days or greater are disabled","Objetive_Name": "User Responsibilities"}],"description": "Ensure credentials unused for 90 days or greater are disabled","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"A.9.4": {"name": "System and Application Access Control","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Category": "A.9 Access Control","Objetive_ID": "A.9.4","Check_Summary": "Ensure no root account access key exists","Objetive_Name": "System and Application Access Control"}],"description": "Ensure no root account access key exists","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"A.10.1": {"name": "Cryptographic Controls","checks": {"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "PASS","attributes": [{"Category": "A.10 Cryptography","Objetive_ID": "A.10.1","Check_Summary": "Detect Customer Master Keys (CMKs) scheduled for deletion","Objetive_Name": "Cryptographic Controls"}],"description": "Detect Customer Master Keys (CMKs) scheduled for deletion","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"A.12.4": {"name": "Logging and Monitoring","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Category": "A.12 Operations Security","Objetive_ID": "A.12.4","Check_Summary": "Ensure CloudTrail is enabled in all regions","Objetive_Name": "Logging and Monitoring"}],"description": "Ensure CloudTrail is enabled in all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"A.12.6": {"name": "Technical Vulnerability Management","checks": {"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS"},"status": "PASS","attributes": [{"Category": "A.12 Operations Security","Objetive_ID": "A.12.6","Check_Summary": "Ensure the S3 bucket CloudTrail logs to is not publicly accessible","Objetive_Name": "Technical Vulnerability Management"}],"description": "Ensure the S3 bucket CloudTrail logs to is not publicly accessible","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"A.13.1": {"name": "Network Security Management","checks": {"rds_instance_no_public_access": "PASS"},"status": "PASS","attributes": [{"Category": "A.13 Communications Security","Objetive_ID": "A.13.1","Check_Summary": "Ensure RDS instances are not accessible to the world.","Objetive_Name": "Network Security Management"}],"description": "Ensure RDS instances are not accessible to the world.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}}},"requirements_passed": 79,"requirements_failed": 0,"requirements_manual": 0,"total_requirements": 79,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "86401f28-9311-42b9-ac06-a3cdcc9e5e39","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "soc2_aws","framework": "SOC2","version": "","description": "System and Organization Controls (SOC), defined by the American Institute of Certified Public Accountants (AICPA), is the name of a set of reports that's produced during an audit. It's intended for use by service organizations (organizations that provide information systems as a service to other organizations) to issue validated reports of internal controls over those information systems to the users of those services. The reports focus on controls grouped into five categories known as Trust Service Principles.","region": "eu-west-1","requirements": {"p_1_1": {"name": "P1.1 The entity provides notice to data subjects about its privacy practices to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_1_1","Section": "P1.0 - Privacy Criteria Related to Notice and Communication of Objectives Related to Privacy","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The entity provides notice to data subjects about its privacy practices to meet the entity’s objectives related to privacy. The notice is updated and communicated to data subjects in a timely manner for changes to the entity’s privacy practices, including changes in the use of personal information, to meet the entity’s objectives related to privacy. Communicates to Data Subjects - Notice is provided to data subjects regarding the following: Purpose for collecting personal informationChoice and consentTypes of personal information collectedMethods of collection (for example, use of cookies or other tracking techniques)Use, retention, and disposalAccessDisclosure to third partiesSecurity for privacyQuality, including data subjects’ responsibilities for qualityMonitoring and enforcementIf personal information is collected from sources other than the individual, such sources are described in the privacy notice. Provides Notice to Data Subjects - Notice is provided to data subjects (1) at or before the time personal information is collected or as soon as practical thereafter, (2) at or before the entity changes its privacy notice or as soon as practical thereafter, or (3) before personal information is used for new purposes not previously identified. Covers Entities and Activities in Notice - An objective description of the entities and activities covered is included in the entity’s privacy notice. Uses Clear and Conspicuous Language - The entity’s privacy notice is conspicuous and uses clear language.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_2_1": {"name": "P2.1 The entity communicates choices available regarding the collection, use, retention, disclosure, and disposal of personal information to the data subjects and the consequences, if any, of each choice","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_2_1","Section": "P2.0 - Privacy Criteria Related to Choice and Consent","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The entity communicates choices available regarding the collection, use, retention, disclosure, and disposal of personal information to the data subjects and the consequences, if any, of each choice. Explicit consent for the collection, use, retention, disclosure, and disposal of personal information is obtained from data subjects or other authorized persons, if required. Such consent is obtained only for the intended purpose of the information to meet the entity’s objectives related to privacy. The entity’s basis for determining implicit consent for the collection, use, retention, disclosure, and disposal of personal information is documented. Communicates to Data Subjects - Data subjects are informed (a) about the choices available to them with respect to the collection, use, and disclosure of personal information and (b) that implicit or explicit consent is required to collect, use, and disclose personal information, unless a law or regulation specifically requires or allows otherwise. Communicates Consequences of Denying or Withdrawing Consent - When personal information is collected, data subjects are informed of the consequences of refusing to provide personal information or denying or withdrawing consent to use personal information for purposes identified in the notice. Obtains Implicit or Explicit Consent - Implicit or explicit consent is obtained from data subjects at or before the time personal information is collected or soon thereafter. The individual’s preferences expressed in his or her consent are confirmed and implemented. Documents and Obtains Consent for New Purposes and Uses - If information that was previously collected is to be used for purposes not previously identified in the privacy notice, the new purpose is documented, the data subject is notified, and implicit or explicit consent is obtained prior to such new use or purpose. Obtains Explicit Consent for Sensitive Information - Explicit consent is obtained directly from the data subject when sensitive personal information is collected, used, or disclosed, unless a law or regulation specifically requires otherwise.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_3_1": {"name": "P3.1 Personal information is collected consistent with the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_3_1","Section": "P3.0 - Privacy Criteria Related to Collection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Limits the Collection of Personal Information - The collection of personal information is limited to that necessary to meet the entity’s objectives. Collects Information by Fair and Lawful Means - Methods of collecting personal information are reviewed by management before they are implemented to confirm that personal information is obtained (a) fairly, without intimidation or deception, and (b) lawfully, adhering to all relevant rules of law, whether derived from statute or common law, relating to the collection of personal information. Collects Information From Reliable Sources - Management confirms that third parties from whom personal information is collected (that is, sources other than the individual) are reliable sources that collect information fairly and lawfully. Informs Data Subjects When Additional Information Is Acquired - Data subjects are informed if the entity develops or acquires additional information about them for its use.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_3_2": {"name": "P3.2 For information requiring explicit consent, the entity communicates the need for such consent, as well as the consequences of a failure to provide consent for the request for personal information, and obtains the consent prior to the collection of the information to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_3_2","Section": "P3.0 - Privacy Criteria Related to Collection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Obtains Explicit Consent for Sensitive Information - Explicit consent is obtained directly from the data subject when sensitive personal information is collected, used, or disclosed, unless a law or regulation specifically requires otherwise. Documents Explicit Consent to Retain Information - Documentation of explicit consent for the collection, use, or disclosure of sensitive personal information is retained in accordance with objectives related to privacy.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_4_1": {"name": "P4.1 The entity limits the use of personal information to the purposes identified in the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_4_1","Section": "P4.0 - Privacy Criteria Related to Use, Retention, and Disposal","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Uses Personal Information for Intended Purposes - Personal information is used only for the intended purposes for which it was collected and only when implicit or explicit consent has been obtained unless a law or regulation specifically requires otherwise.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_4_2": {"name": "P4.2 The entity retains personal information consistent with the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_4_2","Section": "P4.0 - Privacy Criteria Related to Use, Retention, and Disposal","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Retains Personal Information - Personal information is retained for no longer than necessary to fulfill the stated purposes, unless a law or regulation specifically requires otherwise. Protects Personal Information - Policies and procedures have been implemented to protect personal information from erasure or destruction during the specified retention period of the information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_4_3": {"name": "P4.3 The entity securely disposes of personal information to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_4_3","Section": "P4.0 - Privacy Criteria Related to Use, Retention, and Disposal","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Captures, Identifies, and Flags Requests for Deletion - Requests for deletion of personal information are captured, and information related to the requests is identified and flagged for destruction to meet the entity’s objectives related to privacy. Disposes of, Destroys, and Redacts Personal Information - Personal information no longer retained is anonymized, disposed of, or destroyed in a manner that prevents loss, theft, misuse, or unauthorized access. Destroys Personal Information - Policies and procedures are implemented to erase or otherwise destroy personal information that has been identified for destruction.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_5_1": {"name": "P5.1 The entity grants identified and authenticated data subjects the ability to access their stored personal information for review and, upon request, provides physical or electronic copies of that information to data subjects to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_5_1","Section": "P5.0 - Privacy Criteria Related to Access","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The entity grants identified and authenticated data subjects the ability to access their stored personal information for review and, upon request, provides physical or electronic copies of that information to data subjects to meet the entity’s objectives related to privacy. If access is denied, data subjects are informed of the denial and reason for such denial, as required, to meet the entity’s objectives related to privacy. Authenticates Data Subjects’ Identity - The identity of data subjects who request access to their personal information is authenticated before they are given access to that information. Permits Data Subjects Access to Their Personal Information - Data subjects are able to determine whether the entity maintains personal information about them and, upon request, may obtain access to their personal information. Provides Understandable Personal Information Within Reasonable Time - Personal information is provided to data subjects in an understandable form, in a reasonable time frame, and at a reasonable cost, if any. Informs Data Subjects If Access Is Denied - When data subjects are denied access to their personal information, the entity informs them of the denial and the reason for the denial in a timely manner, unless prohibited by law or regulation.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_5_2": {"name": "P5.2 The entity corrects, amends, or appends personal information based on information provided by data subjects and communicates such information to third parties, as committed or required, to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_5_2","Section": "P5.0 - Privacy Criteria Related to Access","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The entity corrects, amends, or appends personal information based on information provided by data subjects and communicates such information to third parties, as committed or required, to meet the entity’s objectives related to privacy. If a request for correction is denied, data subjects are informed of the denial and reason for such denial to meet the entity’s objectives related to privacy. Communicates Denial of Access Requests - Data subjects are informed, in writing, of the reason a request for access to their personal information was denied, the source of the entity’s legal right to deny such access, if applicable, and the individual’s right, if any, to challenge such denial, as specifically permitted or required by law or regulation. Permits Data Subjects to Update or Correct Personal Information - Data subjects are able to update or correct personal information held by the entity. The entity provides such updated or corrected information to third parties that were previously provided with the data subject’s personal information consistent with the entity’s objective related to privacy. Communicates Denial of Correction Requests - Data subjects are informed, in writing, about the reason a request for correction of personal information was denied and how they may appeal.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_6_1": {"name": "P6.1 The entity discloses personal information to third parties with the explicit consent of data subjects, and such consent is obtained prior to disclosure to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_6_1","Section": "P6.0 - Privacy Criteria Related to Disclosure and Notification","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Communicates Privacy Policies to Third Parties - Privacy policies or other specific instructions or requirements for handling personal information are communicated to third parties to whom personal information is disclosed. Discloses Personal Information Only When Appropriate - Personal information is disclosed to third parties only for the purposes for which it was collected or created and only when implicit or explicit consent has been obtained from the data subject, unless a law or regulation specifically requires otherwise. Discloses Personal Information Only to Appropriate Third Parties - Personal information is disclosed only to third parties who have agreements with the entity to protect personal information in a manner consistent with the relevant aspects of the entity’s privacy notice or other specific instructions or requirements. The entity has procedures in place to evaluate that the third parties have effective controls to meet the terms of the agreement, instructions, or requirements.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_6_2": {"name": "P6.2 The entity creates and retains a complete, accurate, and timely record of authorized disclosures of personal information to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_6_2","Section": "P6.0 - Privacy Criteria Related to Disclosure and Notification","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Creates and Retains Record of Authorized Disclosures - The entity creates and maintains a record of authorized disclosures of personal information that is complete, accurate, and timely.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_6_3": {"name": "P6.3 The entity creates and retains a complete, accurate, and timely record of detected or reported unauthorized disclosures (including breaches) of personal information to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_6_3","Section": "P6.0 - Privacy Criteria Related to Disclosure and Notification","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Creates and Retains Record of Detected or Reported Unauthorized Disclosures - The entity creates and maintains a record of detected or reported unauthorized disclosures of personal information that is complete, accurate, and timely.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_6_4": {"name": "P6.4 The entity obtains privacy commitments from vendors and other third parties who have access to personal information to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_6_4","Section": "P6.0 - Privacy Criteria Related to Disclosure and Notification","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The entity obtains privacy commitments from vendors and other third parties who have access to personal information to meet the entity’s objectives related to privacy. The entity assesses those parties’ compliance on a periodic and as-needed basis and takes corrective action, if necessary. Discloses Personal Information Only to Appropriate Third Parties - Personal information is disclosed only to third parties who have agreements with the entity to protect personal information in a manner consistent with the relevant aspects of the entity’s privacy notice or other specific instructions or requirements. The entity has procedures in place to evaluate that the third parties have effective controls to meet the terms of the agreement, instructions, or requirements. Remediates Misuse of Personal Information by a Third Party - The entity takes remedial action in response to misuse of personal information by a third party to whom the entity has transferred such information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_6_5": {"name": "P6.5 The entity obtains commitments from vendors and other third parties with access to personal information to notify the entity in the event of actual or suspected unauthorized disclosures of personal information","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_6_5","Section": "P6.0 - Privacy Criteria Related to Disclosure and Notification","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The entity obtains commitments from vendors and other third parties with access to personal information to notify the entity in the event of actual or suspected unauthorized disclosures of personal information. Such notifications are reported to appropriate personnel and acted on in accordance with established incident response procedures to meet the entity’s objectives related to privacy. Remediates Misuse of Personal Information by a Third Party - The entity takes remedial action in response to misuse of personal information by a third party to whom the entity has transferred such information. Reports Actual or Suspected Unauthorized Disclosures - A process exists for obtaining commitments from vendors and other third parties to report to the entity actual or suspected unauthorized disclosures of personal information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_6_6": {"name": "P6.6 The entity provides notification of breaches and incidents to affected data subjects, regulators, and others to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_6_6","Section": "P6.0 - Privacy Criteria Related to Disclosure and Notification","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Remediates Misuse of Personal Information by a Third Party - The entity takes remedial action in response to misuse of personal information by a third party to whom the entity has transferred such information. Reports Actual or Suspected Unauthorized Disclosures - A process exists for obtaining commitments from vendors and other third parties to report to the entity actual or suspected unauthorized disclosures of personal information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_6_7": {"name": "P6.7 The entity provides data subjects with an accounting of the personal information held and disclosure of the data subjects’ personal information, upon the data subjects’ request, to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_6_7","Section": "P6.0 - Privacy Criteria Related to Disclosure and Notification","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Identifies Types of Personal Information and Handling Process - The types of personal information and sensitive personal information and the related processes, systems, and third parties involved in the handling of such information are identified. Captures, Identifies, and Communicates Requests for Information - Requests for an accounting of personal information held and disclosures of the data subjects’ personal information are captured, and information related to the requests is identified and communicated to data subjects to meet the entity’s objectives related to privacy.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_7_1": {"name": "P7.1 The entity collects and maintains accurate, up-to-date, complete, and relevant personal information to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_7_1","Section": "P7.0 - Privacy Criteria Related to Quality","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Ensures Accuracy and Completeness of Personal Information - Personal information is accurate and complete for the purposes for which it is to be used. Ensures Relevance of Personal Information - Personal information is relevant to the purposes for which it is to be used.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_8_1": {"name": "P8.1 The entity implements a process for receiving, addressing, resolving, and communicating the resolution of inquiries, complaints, and disputes from data subjects and others and periodically monitors compliance to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_8_1","Section": "P8.0 - Privacy Criteria Related to Monitoring and Enforcement","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The entity implements a process for receiving, addressing, resolving, and communicating the resolution of inquiries, complaints, and disputes from data subjects and others and periodically monitors compliance to meet the entity’s objectives related to privacy. Corrections and other necessary actions related to identified deficiencies are made or taken in a timely manner. Communicates to Data Subjects—Data subjects are informed about how to contact the entity with inquiries, complaints, and disputes. Addresses Inquiries, Complaints, and Disputes - A process is in place to address inquiries, complaints, and disputes. Documents and Communicates Dispute Resolution and Recourse - Each complaint is addressed, and the resolution is documented and communicated to the individual. Documents and Reports Compliance Review Results - Compliance with objectives related to privacy are reviewed and documented, and the results of such reviews are reported to management. If problems are identified, remediation plans are developed and implemented. Documents and Reports Instances of Noncompliance - Instances of noncompliance with objectives related to privacy are documented and reported and, if needed, corrective and disciplinary measures are taken on a timely basis. Performs Ongoing Monitoring - Ongoing procedures are performed for monitoring the effectiveness of controls over personal information and for taking timely corrective actions when necessary.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_1_1": {"name": "CC1.1 COSO Principle 1: The entity demonstrates a commitment to integrity and ethical values","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_1_1","Section": "CC1.0 - Common Criteria Related to Control Environment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Sets the Tone at the Top - The board of directors and management, at all levels, demonstrate through their directives, actions, and behavior the importance of integrity and ethical values to support the functioning of the system of internal control. Establishes Standards of Conduct - The expectations of the board of directors and senior management concerning integrity and ethical values are defined in the entity’s standards of conduct and understood at all levels of the entity and by outsourced service providers and business partners. Evaluates Adherence to Standards of Conduct - Processes are in place to evaluate the performance of individuals and teams against the entity’s expected standards of conduct. Addresses Deviations in a Timely Manner - Deviations from the entity’s expected standards of conduct are identified and remedied in a timely and consistent manner.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_1_2": {"name": "CC1.2 COSO Principle 2: The board of directors demonstrates independence from management and exercises oversight of the development and performance of internal control","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_1_2","Section": "CC1.0 - Common Criteria Related to Control Environment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establishes Oversight Responsibilities - The board of directors identifies and accepts its oversight responsibilities in relation to established requirements and expectations. Applies Relevant Expertise - The board of directors defines, maintains, and periodically evaluates the skills and expertise needed among its members to enable them to ask probing questions of senior management and take commensurate action. Operates Independently - The board of directors has sufficient members who are independent from management and objective in evaluations and decision making. Additional point of focus specifically related to all engagements using the trust services criteria: Supplements Board Expertise - The board of directors supplements its expertise relevant to security, availability, processing integrity, confidentiality, and privacy, as needed, through the use of a subcommittee or consultants.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_1_3": {"name": "CC1.3 COSO Principle 3: Management establishes, with board oversight, structures, reporting lines, and appropriate authorities and responsibilities in the pursuit of objectives","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_1_3","Section": "CC1.0 - Common Criteria Related to Control Environment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Considers All Structures of the Entity - Management and the board of directors consider the multiple structures used (including operating units, legal entities, geographic distribution, and outsourced service providers) to support the achievement of objectives. Establishes Reporting Lines - Management designs and evaluates lines of reporting for each entity structure to enable execution of authorities and responsibilities and flow of information to manage the activities of the entity. Defines, Assigns, and Limits Authorities and Responsibilities - Management and the board of directors delegate authority, define responsibilities, and use appropriate processes and technology to assign responsibility and segregate duties as necessary at the various levels of the organization. Additional points of focus specifically related to all engagements using the trust services criteria: Addresses Specific Requirements When Defining Authorities and Responsibilities—Management and the board of directors consider requirements relevant to security, availability, processing integrity, confidentiality, and privacy when defining authorities and responsibilities. Considers Interactions With External Parties When Establishing Structures, Reporting Lines, Authorities, and Responsibilities — Management and the board of directors consider the need for the entity to interact with and monitor the activities of external parties when establishing structures, reporting lines, authorities, and responsibilities.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"cc_1_4": {"name": "CC1.4 COSO Principle 4: The entity demonstrates a commitment to attract, develop, and retain competent individuals in alignment with objectives","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_1_4","Section": "CC1.0 - Common Criteria Related to Control Environment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establishes Policies and Practices - Policies and practices reflect expectations of competence necessary to support the achievement of objectives. Evaluates Competence and Addresses Shortcomings - The board of directors and management evaluate competence across the entity and in outsourced service providers in relation to established policies and practices and act as necessary to address shortcomings. Attracts, Develops, and Retains Individuals - The entity provides the mentoring and training needed to attract, develop, and retain sufficient and competent personnel and outsourced service providers to support the achievement of objectives. Plans and Prepares for Succession - Senior management and the board of directors develop contingency plans for assignments of responsibility important for internal control. Additional point of focus specifically related to all engagements using the trust services criteria: Considers the Background of Individuals - The entity considers the background of potential and existing personnel, contractors, and vendor employees when determining whether to employ and retain the individuals. Considers the Technical Competency of Individuals - The entity considers the technical competency of potential and existing personnel, contractors, and vendor employees when determining whether to employ and retain the individuals. Provides Training to Maintain Technical Competencies - The entity provides training programs, including continuing education and training, to ensure skill sets and technical competency of existing personnel, contractors, and vendor employees are developed and maintained.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_1_5": {"name": "CC1.5 COSO Principle 5: The entity holds individuals accountable for their internal control responsibilities in the pursuit of objectives","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_1_5","Section": "CC1.0 - Common Criteria Related to Control Environment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Enforces Accountability Through Structures, Authorities, and Responsibilities - Management and the board of directors establish the mechanisms to communicate and hold individuals accountable for performance of internal control responsibilities across the entity and implement corrective action as necessary. Establishes Performance Measures, Incentives, and Rewards - Management and the board of directors establish performance measures, incentives, and other rewards appropriate for responsibilities at all levels of the entity, reflecting appropriate dimensions of performance and expected standards of conduct, and considering the achievement of both short-term and longer-term objectives. Evaluates Performance Measures, Incentives, and Rewards for Ongoing Relevance - Management and the board of directors align incentives and rewards with the fulfillment of internal control responsibilities in the achievement of objectives. Considers Excessive Pressures - Management and the board of directors evaluate and adjust pressures associated with the achievement of objectives as they assign responsibilities, develop performance measures, and evaluate performance. Evaluates Performance and Rewards or Disciplines Individuals - Management and the board of directors evaluate performance of internal control responsibilities, including adherence to standards of conduct and expected levels of competence, and provide rewards or exercise disciplinary action, as appropriate.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_2_1": {"name": "CC2.1 COSO Principle 13: The entity obtains or generates and uses relevant, quality information to support the functioning of internal control","checks": {"cloudtrail_multi_region_enabled": "PASS","config_recorder_all_regions_enabled": null,"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_2_1","Section": "CC2.0 - Common Criteria Related to Communication and Information","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Identifies Information Requirements - A process is in place to identify the information required and expected to support the functioning of the other components of internal control and the achievement of the entity’s objectives. Captures Internal and External Sources of Data - Information systems capture internal and external sources of data. Processes Relevant Data Into Information - Information systems process and transform relevant data into information. Maintains Quality Throughout Processing - Information systems produce information that is timely, current, accurate, complete, accessible, protected, verifiable, and retained. Information is reviewed to assess its relevance in supporting the internal control components.","checks_status": {"fail": 0,"pass": 1,"total": 4,"manual": 0}},"cc_2_2": {"name": "CC2.2 COSO Principle 14: The entity internally communicates information, including objectives and responsibilities for internal control, necessary to support the functioning of internal control","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_2_2","Section": "CC2.0 - Common Criteria Related to Communication and Information","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Communicates Internal Control Information - A process is in place to communicate required information to enable all personnel to understand and carry out their internal control responsibilities. Communicates With the Board of Directors - Communication exists between management and the board of directors so that both have information needed to fulfill their roles with respect to the entity’s objectives. Provides Separate Communication Lines - Separate communication channels, such as whistle-blower hotlines, are in place and serve as fail-safe mechanisms to enable anonymous or confidential communication when normal channels are inoperative or ineffective. Selects Relevant Method of Communication - The method of communication considers the timing, audience, and nature of the information. Additional point of focus specifically related to all engagements using the trust services criteria: Communicates Responsibilities - Entity personnel with responsibility for designing, developing, implementing,operating, maintaining, or monitoring system controls receive communications about their responsibilities, including changes in their responsibilities, and have the information necessary to carry out those responsibilities. Communicates Information on Reporting Failures, Incidents, Concerns, and Other Matters—Entity personnel are provided with information on how to report systems failures, incidents, concerns, and other complaints to personnel. Communicates Objectives and Changes to Objectives - The entity communicates its objectives and changes to those objectives to personnel in a timely manner. Communicates Information to Improve Security Knowledge and Awareness - The entity communicates information to improve security knowledge and awareness and to model appropriate security behaviors to personnel through a security awareness training program. Additional points of focus that apply only when an engagement using the trust services criteria is performed at the system level: Communicates Information About System Operation and Boundaries - The entity prepares and communicates information about the design and operation of the system and its boundaries to authorized personnel to enable them to understand their role in the system and the results of system operation. Communicates System Objectives - The entity communicates its objectives to personnel to enable them to carry out their responsibilities. Communicates System Changes - System changes that affect responsibilities or the achievement of the entity's objectives are communicated in a timely manner.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_2_3": {"name": "CC2.3 COSO Principle 15: The entity communicates with external parties regarding matters affecting the functioning of internal control","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_2_3","Section": "CC2.0 - Common Criteria Related to Communication and Information","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Communicates to External Parties - Processes are in place to communicate relevant and timely information to external parties, including shareholders, partners, owners, regulators, customers, financial analysts, and other external parties. Enables Inbound Communications - Open communication channels allow input from customers, consumers, suppliers, external auditors, regulators, financial analysts, and others, providing management and the board of directors with relevant information. Communicates With the Board of Directors - Relevant information resulting from assessments conducted by external parties is communicated to the board of directors. Provides Separate Communication Lines - Separate communication channels, such as whistle-blower hotlines, are in place and serve as fail-safe mechanisms to enable anonymous or confidential communication when normal channels are inoperative or ineffective. Selects Relevant Method of Communication - The method of communication considers the timing, audience, and nature of the communication and legal, regulatory, and fiduciary requirements and expectations. Communicates Objectives Related to Confidentiality and Changes to Objectives - The entity communicates, to external users, vendors, business partners and others whose products and services are part of the system, objectives and changes to objectives related to confidentiality. Additional point of focus that applies only to an engagement using the trust services criteria for privacy: Communicates Objectives Related to Privacy and Changes to Objectives - The entity communicates, to external users, vendors, business partners and others whose products and services are part of the system, objectives related to privacy and changes to those objectives. Additional points of focus that apply only when an engagement using the trust services criteria is performed at the system level: Communicates Information About System Operation and Boundaries - The entity prepares and communicates information about the design and operation of the system and its boundaries to authorized external users to permit users to understand their role in the system and the results of system operation. Communicates System Objectives - The entity communicates its system objectives to appropriate external users. Communicates System Responsibilities - External users with responsibility for designing, developing, implementing, operating, maintaining, and monitoring system controls receive communications about their responsibilities and have the information necessary to carry out those responsibilities. Communicates Information on Reporting System Failures, Incidents, Concerns, and Other Matters - External users are provided with information on how to report systems failures, incidents, concerns, and other complaints to appropriate personnel.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_3_1": {"name": "CC3.1 COSO Principle 6: The entity specifies objectives with sufficient clarity to enable the identification and assessment of risks relating to objectives","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_3_1","Section": "CC3.0 - Common Criteria Related to Risk Assessment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Operations Objectives: Reflects Management's Choices - Operations objectives reflect management's choices about structure, industry considerations, and performance of the entity. Considers Tolerances for Risk - Management considers the acceptable levels of variation relative to the achievement of operations objectives. External Financial Reporting Objectives: Complies With Applicable Accounting Standards - Financial reporting objectives are consistent with accounting principles suitable and available for that entity. The accounting principles selected are appropriate in the circumstances. External Nonfinancial Reporting Objectives: Complies With Externally Established Frameworks - Management establishes objectives consistent with laws and regulations or standards and frameworks of recognized external organizations. Reflects Entity Activities - External reporting reflects the underlying transactions and events within a range of acceptable limits. Considers the Required Level of Precision—Management reflects the required level of precision and accuracy suitable for user needs and based on criteria established by third parties in nonfinancial reporting. Internal Reporting Objectives: Reflects Management's Choices - Internal reporting provides management with accurate and complete information regarding management's choices and information needed in managing the entity. Considers the Required Level of Precision—Management reflects the required level of precision and accuracy suitable for user needs in nonfinancial reporting objectives and materiality within financial reporting objectives. Reflects Entity Activities—Internal reporting reflects the underlying transactions and events within a range of acceptable limits. Compliance Objectives: Reflects External Laws and Regulations - Laws and regulations establish minimum standards of conduct, which the entity integrates into compliance objectives. Considers Tolerances for Risk - Management considers the acceptable levels of variation relative to the achievement of operations objectives. Additional point of focus specifically related to all engagements using the trust services criteria: Establishes Sub-objectives to Support Objectives—Management identifies sub-objectives related to security, availability, processing integrity, confidentiality, and privacy to support the achievement of the entity’s objectives related to reporting, operations, and compliance.","checks_status": {"fail": 0,"pass": 2,"total": 3,"manual": 0}},"cc_3_2": {"name": "CC3.2 COSO Principle 7: The entity identifies risks to the achievement of its objectives across the entity and analyzes risks as a basis for determining how the risks should be managed","checks": {"guardduty_is_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_3_2","Section": "CC3.0 - Common Criteria Related to Risk Assessment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Includes Entity, Subsidiary, Division, Operating Unit, and Functional Levels - The entity identifies and assesses risk at the entity, subsidiary, division, operating unit, and functional levels relevant to the achievement of objectives. Analyzes Internal and External Factors - Risk identification considers both internal and external factors and their impact on the achievement of objectives. Involves Appropriate Levels of Management - The entity puts into place effective risk assessment mechanisms that involve appropriate levels of management. Estimates Significance of Risks Identified - Identified risks are analyzed through a process that includes estimating the potential significance of the risk. Determines How to Respond to Risks - Risk assessment includes considering how the risk should be managed and whether to accept, avoid, reduce, or share the risk. Additional points of focus specifically related to all engagements using the trust services criteria: Identifies and Assesses Criticality of Information Assets and Identifies Threats and Vulnerabilities - The entity's risk identification and assessment process includes (1) identifying information assets, including physical devices and systems, virtual devices, software, data and data flows, external information systems, and organizational roles; (2) assessing the criticality of those information assets; (3) identifying the threats to the assets from intentional (including malicious) and unintentional acts and environmental events; and (4) identifying the vulnerabilities of the identified assets.","checks_status": {"fail": 3,"pass": 1,"total": 5,"manual": 0}},"cc_3_3": {"name": "CC3.3 COSO Principle 8: The entity considers the potential for fraud in assessing risks to the achievement of objectives","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_3_3","Section": "CC3.0 - Common Criteria Related to Risk Assessment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Considers Various Types of Fraud - The assessment of fraud considers fraudulent reporting, possible loss of assets, and corruption resulting from the various ways that fraud and misconduct can occur. Assesses Incentives and Pressures - The assessment of fraud risks considers incentives and pressures. Assesses Opportunities - The assessment of fraud risk considers opportunities for unauthorized acquisition,use, or disposal of assets, altering the entity’s reporting records, or committing other inappropriate acts. Assesses Attitudes and Rationalizations - The assessment of fraud risk considers how management and other personnel might engage in or justify inappropriate actions. Additional point of focus specifically related to all engagements using the trust services criteria: Considers the Risks Related to the Use of IT and Access to Information - The assessment of fraud risks includes consideration of threats and vulnerabilities that arise specifically from the use of IT and access to information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_3_4": {"name": "CC3.4 COSO Principle 9: The entity identifies and assesses changes that could significantly impact the system of internal control","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_3_4","Section": "CC3.0 - Common Criteria Related to Risk Assessment","Service": "config","SubGroup": null,"SubSection": null}],"description": "Assesses Changes in the External Environment - The risk identification process considers changes to the regulatory, economic, and physical environment in which the entity operates. Assesses Changes in the Business Model - The entity considers the potential impacts of new business lines, dramatically altered compositions of existing business lines, acquired or divested business operations on the system of internal control, rapid growth, changing reliance on foreign geographies, and new technologies. Assesses Changes in Leadership - The entity considers changes in management and respective attitudes and philosophies on the system of internal control. Assess Changes in Systems and Technology - The risk identification process considers changes arising from changes in the entity’s systems and changes in the technology environment. Assess Changes in Vendor and Business Partner Relationships - The risk identification process considers changes in vendor and business partner relationships.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"cc_4_1": {"name": "CC4.1 COSO Principle 16: The entity selects, develops, and performs ongoing and/or separate evaluations to ascertain whether the components of internal control are present and functioning","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_4_1","Section": "CC4.0 - Monitoring Activities","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Considers a Mix of Ongoing and Separate Evaluations - Management includes a balance of ongoing and separate evaluations. Considers Rate of Change - Management considers the rate of change in business and business processes when selecting and developing ongoing and separate evaluations. Establishes Baseline Understanding - The design and current state of an internal control system are used to establish a baseline for ongoing and separate evaluations. Uses Knowledgeable Personnel - Evaluators performing ongoing and separate evaluations have sufficient knowledge to understand what is being evaluated. Integrates With Business Processes - Ongoing evaluations are built into the business processes and adjust to changing conditions. Adjusts Scope and Frequency—Management varies the scope and frequency of separate evaluations depending on risk. Objectively Evaluates - Separate evaluations are performed periodically to provide objective feedback. Considers Different Types of Ongoing and Separate Evaluations - Management uses a variety of different types of ongoing and separate evaluations, including penetration testing, independent certification made against established specifications (for example, ISO certifications), and internal audit assessments.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_4_2": {"name": "CC4.2 COSO Principle 17: The entity evaluates and communicates internal control deficiencies in a timely manner to those parties responsible for taking corrective action, including senior management and the board of directors, as appropriate","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_4_2","Section": "CC4.0 - Monitoring Activities","Service": "guardduty","SubGroup": null,"SubSection": null}],"description": "Assesses Results - Management and the board of directors, as appropriate, assess results of ongoing and separate evaluations. Communicates Deficiencies - Deficiencies are communicated to parties responsible for taking corrective action and to senior management and the board of directors, as appropriate. Monitors Corrective Action - Management tracks whether deficiencies are remedied on a timely basis.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"cc_5_1": {"name": "CC5.1 COSO Principle 10: The entity selects and develops control activities that contribute to the mitigation of risks to the achievement of objectives to acceptable levels","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_5_1","Section": "CC5.0 - Control Activities","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Integrates With Risk Assessment - Control activities help ensure that risk responses that address and mitigate risks are carried out. Considers Entity-Specific Factors - Management considers how the environment, complexity, nature, and scope of its operations, as well as the specific characteristics of its organization, affect the selection and development of control activities. Determines Relevant Business Processes - Management determines which relevant business processes require control activities. Evaluates a Mix of 2017 Data Submitted Types - Control activities include a range and variety of controls and may include a balance of approaches to mitigate risks, considering both manual and automated controls, and preventive and detective controls. Considers at What Level Activities Are Applied - Management considers control activities at various levels in the entity. Addresses Segregation of Duties - Management segregates incompatible duties, and where such segregation is not practical, management selects and develops alternative control activities.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_5_2": {"name": "CC5.2 COSO Principle 11: The entity also selects and develops general control activities over technology to support the achievement of objectives","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_5_2","Section": "CC5.0 - Control Activities","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Determines Dependency Between the Use of Technology in Business Processes and Technology General Controls - Management understands and determines the dependency and linkage between business processes, automated control activities, and technology general controls. Establishes Relevant Technology Infrastructure Control Activities - Management selects and develops control activities over the technology infrastructure, which are designed and implemented to help ensure the completeness, accuracy, and availability of technology processing. Establishes Relevant Security Management Process Controls Activities - Management selects and develops control activities that are designed and implemented to restrict technology access rights to authorized users commensurate with their job responsibilities and to protect the entity’s assets from external threats. Establishes Relevant Technology Acquisition, Development, and Maintenance Process Control Activities - Management selects and develops control activities over the acquisition, development, and maintenance of technology and its infrastructure to achieve management’s objectives.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_5_3": {"name": "CCC5.3 COSO Principle 12: The entity deploys control activities through policies that establish what is expected and in procedures that put policies into action","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_5_3","Section": "CC5.0 - Control Activities","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establishes Policies and Procedures to Support Deployment of Management ā€˜s Directives - Management establishes control activities that are built into business processes and employees’ day-to-day activities through policies establishing what is expected and relevant procedures specifying actions. Establishes Responsibility and Accountability for Executing Policies and Procedures - Management establishes responsibility and accountability for control activities with management (or other designated personnel) of the business unit or function in which the relevant risks reside. Performs in a Timely Manner - Responsible personnel perform control activities in a timely manner as defined by the policies and procedures. Takes Corrective Action - Responsible personnel investigate and act on matters identified as a result of executing control activities. Performs Using Competent Personnel - Competent personnel with sufficient authority perform control activities with diligence and continuing focus. Reassesses Policies and Procedures - Management periodically reviews control activities to determine their continued relevance and refreshes them when necessary.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_6_1": {"name": "CC6.1 The entity implements logical access security software, infrastructure, and architectures over protected information assets to protect them from security events to meet the entity's objectives","checks": {"s3_bucket_public_access": null},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_6_1","Section": "CC6.0 - Logical and Physical Access","Service": "s3","SubGroup": null,"SubSection": null}],"description": "Identifies and Manages the Inventory of Information Assets - The entity identifies, inventories, classifies, and manages information assets. Restricts Logical Access - Logical access to information assets, including hardware, data (at-rest, during processing, or in transmission), software, administrative authorities, mobile devices, output, and offline system components is restricted through the use of access control software and rule sets. Identifies and Authenticates Users - Persons, infrastructure and software are identified and authenticated prior to accessing information assets, whether locally or remotely. Considers Network Segmentation - Network segmentation permits unrelated portions of the entity's information system to be isolated from each other. Manages Points of Access - Points of access by outside entities and the types of data that flow through the points of access are identified, inventoried, and managed. The types of individuals and systems using each point of access are identified, documented, and managed. Restricts Access to Information Assets - Combinations of data classification, separate data structures, port restrictions, access protocol restrictions, user identification, and digital certificates are used to establish access control rules for information assets. Manages Identification and Authentication - Identification and authentication requirements are established, documented, and managed for individuals and systems accessing entity information, infrastructure and software. Manages Credentials for Infrastructure and Software - New internal and external infrastructure and software are registered, authorized, and documented prior to being granted access credentials and implemented on the network or access point. Credentials are removed and access is disabled when access is no longer required or the infrastructure and software are no longer in use. Uses Encryption to Protect Data - The entity uses encryption to supplement other measures used to protect data-at-rest, when such protections are deemed appropriate based on assessed risk. Protects Encryption Keys - Processes are in place to protect encryption keys during generation, storage, use, and destruction.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"cc_6_2": {"name": "CC6.2 Prior to issuing system credentials and granting system access, the entity registers and authorizes new internal and external users whose access is administered by the entity","checks": {"rds_instance_no_public_access": "PASS"},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_6_2","Section": "CC6.0 - Logical and Physical Access","Service": "rds","SubGroup": null,"SubSection": null}],"description": "Prior to issuing system credentials and granting system access, the entity registers and authorizes new internal and external users whose access is administered by the entity. For those users whose access is administered by the entity, user system credentials are removed when user access is no longer authorized. Controls Access Credentials to Protected Assets - Information asset access credentials are created based on an authorization from the system's asset owner or authorized custodian. Removes Access to Protected Assets When Appropriate - Processes are in place to remove credential access when an individual no longer requires such access. Reviews Appropriateness of Access Credentials - The appropriateness of access credentials is reviewed on a periodic basis for unnecessary and inappropriate individuals with credentials.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"cc_6_3": {"name": "CC6.3 The entity authorizes, modifies, or removes access to data, software, functions, and other protected information assets based on roles, responsibilities, or the system design and changes, giving consideration to the concepts of least privilege and segregation of duties, to meet the entity’s objectives","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_6_3","Section": "CC6.0 - Logical and Physical Access","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Creates or Modifies Access to Protected Information Assets - Processes are in place to create or modify access to protected information assets based on authorization from the asset’s owner. Removes Access to Protected Information Assets - Processes are in place to remove access to protected information assets when an individual no longer requires access. Uses Role-Based Access Controls - Role-based access control is utilized to support segregation of incompatible functions.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"cc_6_4": {"name": "CC6.4 The entity restricts physical access to facilities and protected information assets to authorized personnel to meet the entity’s objectives","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_6_4","Section": "CC6.0 - Logical and Physical Access","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Creates or Modifies Physical Access - Processes are in place to create or modify physical access to facilities such as data centers, office spaces, and work areas, based on authorization from the system's asset owner. Removes Physical Access - Processes are in place to remove access to physical resources when an individual no longer requires access. Reviews Physical Access - Processes are in place to periodically review physical access to ensure consistency with job responsibilities.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_6_5": {"name": "CC6.5 The entity discontinues logical and physical protections over physical assets only after the ability to read or recover data and software from those assets has been diminished and is no longer required to meet the entity’s objectives","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_6_5","Section": "CC6.0 - Logical and Physical Access","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Identifies Data and Software for Disposal - Procedures are in place to identify data and software stored on equipment to be disposed and to render such data and software unreadable. Removes Data and Software From Entity Control - Procedures are in place to remove data and software stored on equipment to be removed from the physical control of the entity and to render such data and software unreadable.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_6_6": {"name": "CC6.6 The entity implements logical access security measures to protect against threats from sources outside its system boundaries","checks": {"ec2_instance_public_ip": "FAIL"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_6_6","Section": "CC6.0 - Logical and Physical Access","Service": "ec2","SubGroup": null,"SubSection": null}],"description": "Restricts Access — The types of activities that can occur through a communication channel (for example, FTP site, router port) are restricted. Protects Identification and Authentication Credentials — Identification and authentication credentials are protected during transmission outside its system boundaries. Requires Additional Authentication or Credentials — Additional authentication information or credentials are required when accessing the system from outside its boundaries. Implements Boundary Protection Systems — Boundary protection systems (for example, firewalls, demilitarized zones, and intrusion detection systems) are implemented to protect external access points from attempts and unauthorized access and are monitored to detect such attempts.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cc_6_7": {"name": "CC6.7 The entity restricts the transmission, movement, and removal of information to authorized internal and external users and processes, and protects it during transmission, movement, or removal to meet the entity’s objectives","checks": {"acm_certificates_expiration_check": "PASS"},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_6_7","Section": "CC6.0 - Logical and Physical Access","Service": "acm","SubGroup": null,"SubSection": null}],"description": "Restricts the Ability to Perform Transmission - Data loss prevention processes and technologies are used to restrict ability to authorize and execute transmission, movement and removal of information. Uses Encryption Technologies or Secure Communication Channels to Protect Data - Encryption technologies or secured communication channels are used to protect transmission of data and other communications beyond connectivity access points. Protects Removal Media - Encryption technologies and physical asset protections are used for removable media (such as USB drives and back-up tapes), as appropriate. Protects Mobile Devices - Processes are in place to protect mobile devices (such as laptops, smart phones and tablets) that serve as information assets.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"cc_6_8": {"name": "CC6.8 The entity implements controls to prevent or detect and act upon the introduction of unauthorized or malicious software to meet the entity’s objectives","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_6_8","Section": "CC6.0 - Logical and Physical Access","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Restricts Application and Software Installation - The ability to install applications and software is restricted to authorized individuals. Detects Unauthorized Changes to Software and Configuration Parameters - Processes are in place to detect changes to software and configuration parameters that may be indicative of unauthorized or malicious software. Uses a Defined Change Control Process - A management-defined change control process is used for the implementation of software. Uses Antivirus and Anti-Malware Software - Antivirus and anti-malware software is implemented and maintained to provide for the interception or detection and remediation of malware. Scans Information Assets from Outside the Entity for Malware and Other Unauthorized Software - Procedures are in place to scan information assets that have been transferred or returned to the entity’s custody for malware and other unauthorized software and to remove any items detected prior to its implementation on the network.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"cc_7_1": {"name": "CC7.1 To meet its objectives, the entity uses detection and monitoring procedures to identify (1) changes to configurations that result in the introduction of new vulnerabilities, and (2) susceptibilities to newly discovered vulnerabilities","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_7_1","Section": "CC7.0 - System Operations","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Uses Defined Configuration Standards - Management has defined configuration standards. Monitors Infrastructure and Software - The entity monitors infrastructure and software for noncompliance with the standards, which could threaten the achievement of the entity's objectives. Implements Change-Detection Mechanisms - The IT system includes a change-detection mechanism (for example, file integrity monitoring tools) to alert personnel to unauthorized modifications of critical system files, configuration files, or content files. Detects Unknown or Unauthorized Components - Procedures are in place to detect the introduction of unknown or unauthorized components. Conducts Vulnerability Scans - The entity conducts vulnerability scans designed to identify potential vulnerabilities or misconfigurations on a periodic basis and after any significant change in the environment and takes action to remediate identified deficiencies on a timely basis.","checks_status": {"fail": 2,"pass": 2,"total": 4,"manual": 0}},"cc_7_2": {"name": "CC7.2 The entity monitors system components and the operation of those components for anomalies that are indicative of malicious acts, natural disasters, and errors affecting the entity's ability to meet its objectives; anomalies are analyzed to determine whether they represent security events","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","ec2_instance_imdsv2_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_7_2","Section": "CC7.0 - System Operations","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implements Detection Policies, Procedures, and Tools - Detection policies and procedures are defined and implemented, and detection tools are implemented on Infrastructure and software to identify anomalies in the operation or unusual activity on systems. Procedures may include (1) a defined governance process for security event detection and management that includes provision of resources; (2) use of intelligence sources to identify newly discovered threats and vulnerabilities; and (3) logging of unusual system activities. Designs Detection Measures - Detection measures are designed to identify anomalies that could result from actual or attempted (1) compromise of physical barriers; (2) unauthorized actions of authorized personnel; (3) use of compromised identification and authentication credentials; (4) unauthorized access from outside the system boundaries; (5) compromise of authorized external parties; and (6) implementation or connection of unauthorized hardware and software. Implements Filters to Analyze Anomalies - Management has implemented procedures to filter, summarize, and analyze anomalies to identify security events. Monitors Detection Tools for Effective Operation - Management has implemented processes to monitor the effectiveness of detection tools.","checks_status": {"fail": 7,"pass": 6,"total": 21,"manual": 0}},"cc_7_3": {"name": "CC7.3 The entity evaluates security events to determine whether they could or have resulted in a failure of the entity to meet its objectives (security incidents) and, if so, takes actions to prevent or address such failures","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","apigateway_restapi_logging_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL","s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_7_3","Section": "CC7.0 - System Operations","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Responds to Security Incidents - Procedures are in place for responding to security incidents and evaluating the effectiveness of those policies and procedures on a periodic basis. Communicates and Reviews Detected Security Events - Detected security events are communicated to and reviewed by the individuals responsible for the management of the security program and actions are taken, if necessary. Develops and Implements Procedures to Analyze Security Incidents - Procedures are in place to analyze security incidents and determine system impact. Assesses the Impact on Personal Information - Detected security events are evaluated to determine whether they could or did result in the unauthorized disclosure or use of personal information and whether there has been a failure to comply with applicable laws or regulations. Determines Personal Information Used or Disclosed - When an unauthorized use or disclosure of personal information has occurred, the affected information is identified.","checks_status": {"fail": 10,"pass": 3,"total": 17,"manual": 0}},"cc_7_4": {"name": "CC7.4 The entity responds to identified security incidents by executing a defined incident response program to understand, contain, remediate, and communicate security incidents, as appropriate","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"guardduty_no_high_severity_findings": "FAIL","redshift_cluster_automated_snapshot": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_7_4","Section": "CC7.0 - System Operations","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Assigns Roles and Responsibilities - Roles and responsibilities for the design, implementation, maintenance, and execution of the incident response program are assigned, including the use of external resources when necessary. Contains Security Incidents - Procedures are in place to contain security incidents that actively threaten entity objectives. Mitigates Ongoing Security Incidents - Procedures are in place to mitigate the effects of ongoing security incidents. Ends Threats Posed by Security Incidents - Procedures are in place to end the threats posed by security incidents through closure of the vulnerability, removal of unauthorized access, and other remediation actions. Restores Operations - Procedures are in place to restore data and business operations to an interim state that permits the achievement of entity objectives. Develops and Implements Communication Protocols for Security Incidents - Protocols for communicating security incidents and actions taken to affected parties are developed and implemented to meet the entity's objectives. Obtains Understanding of Nature of Incident and Determines Containment Strategy - An understanding of the nature (for example, the method by which the incident occurred and the affected system resources) and severity of the security incident is obtained to determine the appropriate containment strategy, including (1) a determination of the appropriate response time frame, and (2) the determination and execution of the containment approach. Remediates Identified Vulnerabilities - Identified vulnerabilities are remediated through the development and execution of remediation activities. Communicates Remediation Activities - Remediation activities are documented and communicated in accordance with the incident response program. Evaluates the Effectiveness of Incident Response - The design of incident response activities is evaluated for effectiveness on a periodic basis. Periodically Evaluates Incidents - Periodically, management reviews incidents related to security, availability, processing integrity, confidentiality, and privacy and identifies the need for system changes based on incident patterns and root causes. Communicates Unauthorized Use and Disclosure - Events that resulted in unauthorized use or disclosure of personal information are communicated to the data subjects, legal and regulatory authorities, and others as required. Application of Sanctions - The conduct of individuals and organizations operating under the authority of the entity and involved in the unauthorized use or disclosure of personal information is evaluated and, if appropriate, sanctioned in accordance with entity policies and legal and regulatory requirements.","checks_status": {"fail": 3,"pass": 3,"total": 16,"manual": 0}},"cc_7_5": {"name": "CC7.5 The entity identifies, develops, and implements activities to recover from identified security incidents","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_7_5","Section": "CC7.0 - System Operations","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Restores the Affected Environment - The activities restore the affected environment to functional operation by rebuilding systems, updating software, installing patches, and changing configurations, as needed. Communicates Information About the Event - Communications about the nature of the incident, recovery actions taken, and activities required for the prevention of future security events are made to management and others as appropriate (internal and external). Determines Root Cause of the Event - The root cause of the event is determined. Implements Changes to Prevent and Detect Recurrences - Additional architecture or changes to preventive and detective controls, or both, are implemented to prevent and detect recurrences on a timely basis. Improves Response and Recovery Procedures - Lessons learned are analyzed, and the incident response plan and recovery procedures are improved. Implements Incident Recovery Plan Testing - Incident recovery plan testing is performed on a periodic basis. The testing includes (1) development of testing scenarios based on threat likelihood and magnitude; (2) consideration of relevant system components from across the entity that can impair availability; (3) scenarios that consider the potential for the lack of availability of key personnel; and (4) revision of continuity plans and systems based on test results.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_8_1": {"name": "CC8.1 The entity authorizes, designs, develops or acquires, configures, documents, tests, approves, and implements changes to infrastructure, data, software, and procedures to meet its objectives","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_8_1","Section": "CC8.0 - Change Management","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Manages Changes Throughout the System Lifecycle - A process for managing system changes throughout the lifecycle of the system and its components (infrastructure, data, software and procedures) is used to support system availability and processing integrity. Authorizes Changes - A process is in place to authorize system changes prior to development. Designs and Develops Changes - A process is in place to design and develop system changes. Documents Changes - A process is in place to document system changes to support ongoing maintenance of the system and to support system users in performing their responsibilities. Tracks System Changes - A process is in place to track system changes prior to implementation. Configures Software - A process is in place to select and implement the configuration parameters used to control the functionality of software. Tests System Changes - A process is in place to test system changes prior to implementation. Approves System Changes - A process is in place to approve system changes prior to implementation. Deploys System Changes - A process is in place to implement system changes. Identifies and Evaluates System Changes - Objectives affected by system changes are identified, and the ability of the modified system to meet the objectives is evaluated throughout the system development life cycle. Identifies Changes in Infrastructure, Data, Software, and Procedures Required to Remediate Incidents - Changes in infrastructure, data, software, and procedures required to remediate incidents to continue to meet objectives are identified, and the change process is initiated upon identification. Creates Baseline Configuration of IT Technology - A baseline configuration of IT and control systems is created and maintained. Provides for Changes Necessary in Emergency Situations - A process is in place for authorizing, designing, testing, approving and implementing changes necessary in emergency situations (that is, changes that need to be implemented in an urgent timeframe). Protects Confidential Information - The entity protects confidential information during system design, development, testing, implementation, and change processes to meet the entity’s objectives related to confidentiality. Protects Personal Information - The entity protects personal information during system design, development, testing, implementation, and change processes to meet the entity’s objectives related to privacy.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"cc_9_1": {"name": "CC9.1 The entity identifies, selects, and develops risk mitigation activities for risks arising from potential business disruptions","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_9_1","Section": "CC9.0 - Risk Mitigation","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Considers Mitigation of Risks of Business Disruption - Risk mitigation activities include the development of planned policies, procedures, communications, and alternative processing solutions to respond to, mitigate, and recover from security events that disrupt business operations. Those policies and procedures include monitoring processes and information and communications to meet the entity's objectives during response, mitigation, and recovery efforts. Considers the Use of Insurance to Mitigate Financial Impact Risks - The risk management activities consider the use of insurance to offset the financial impact of loss events that would otherwise impair the ability of the entity to meet its objectives.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_9_2": {"name": "CC9.2 The entity assesses and manages risks associated with vendors and business partners","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_9_2","Section": "CC9.0 - Risk Mitigation","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establishes Requirements for Vendor and Business Partner Engagements - The entity establishes specific requirements for a vendor and business partner engagement that includes (1) scope of services and product specifications, (2) roles and responsibilities, (3) compliance requirements, and (4) service levels. Assesses Vendor and Business Partner Risks - The entity assesses, on a periodic basis, the risks that vendors and business partners (and those entities’ vendors and business partners) represent to the achievement of the entity's objectives. Assigns Responsibility and Accountability for Managing Vendors and Business Partners - The entity assigns responsibility and accountability for the management of risks associated with vendors and business partners. Establishes Communication Protocols for Vendors and Business Partners - The entity establishes communication and resolution protocols for service or product issues related to vendors and business partners. Establishes Exception Handling Procedures From Vendors and Business Partners - The entity establishes exception handling procedures for service or product issues related to vendors and business partners. Assesses Vendor and Business Partner Performance - The entity periodically assesses the performance of vendors and business partners. Implements Procedures for Addressing Issues Identified During Vendor and Business Partner Assessments - The entity implements procedures for addressing issues identified with vendor and business partner relationships. Implements Procedures for Terminating Vendor and Business Partner Relationships - The entity implements procedures for terminating vendor and business partner relationships. Obtains Confidentiality Commitments from Vendors and Business Partners - The entity obtains confidentiality commitments that are consistent with the entity’s confidentiality commitments and requirements from vendors and business partners who have access to confidential information. Assesses Compliance With Confidentiality Commitments of Vendors and Business Partners - On a periodic and as-needed basis, the entity assesses compliance by vendors and business partners with the entity’s confidentiality commitments and requirements. Obtains Privacy Commitments from Vendors and Business Partners - The entity obtains privacy commitments, consistent with the entity’s privacy commitments and requirements, from vendors and business partners who have access to personal information. Assesses Compliance with Privacy Commitments of Vendors and Business Partners - On a periodic and as-needed basis, the entity assesses compliance by vendors and business partners with the entity’s privacy commitments and requirements and takes corrective action as necessary.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_a_1_1": {"name": "A1.1 The entity maintains, monitors, and evaluates current processing capacity and use of system components (infrastructure, data, and software) to manage capacity demand and to enable the implementation of additional capacity to help meet its objectives","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_a_1_1","Section": "CCA1.0 - Additional Criterial for Availability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Measures Current Usage - The use of the system components is measured to establish a baseline for capacity management and to use when evaluating the risk of impaired availability due to capacity constraints. Forecasts Capacity - The expected average and peak use of system components is forecasted and compared to system capacity and associated tolerances. Forecasting considers capacity in the event of the failure of system components that constrain capacity. Makes Changes Based on Forecasts - The system change management process is initiated when forecasted usage exceeds capacity tolerances.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_a_1_2": {"name": "A1.2 The entity authorizes, designs, develops or acquires, implements, operates, approves, maintains, and monitors environmental protections, software, data back-up processes, and recovery infrastructure to meet its objectives","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","redshift_cluster_automated_snapshot": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_a_1_2","Section": "CCA1.0 - Additional Criterial for Availability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Measures Current Usage - The use of the system components is measured to establish a baseline for capacity management and to use when evaluating the risk of impaired availability due to capacity constraints. Forecasts Capacity - The expected average and peak use of system components is forecasted and compared to system capacity and associated tolerances. Forecasting considers capacity in the event of the failure of system components that constrain capacity. Makes Changes Based on Forecasts - The system change management process is initiated when forecasted usage exceeds capacity tolerances.","checks_status": {"fail": 6,"pass": 3,"total": 16,"manual": 0}},"cc_a_1_3": {"name": "A1.3 The entity tests recovery plan procedures supporting system recovery to meet its objectives","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_a_1_3","Section": "CCA1.0 - Additional Criterial for Availability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implements Business Continuity Plan Testing - Business continuity plan testing is performed on a periodic basis. The testing includes (1) development of testing scenarios based on threat likelihood and magnitude; (2) consideration of system components from across the entity that can impair the availability; (3) scenarios that consider the potential for the lack of availability of key personnel; and (4) revision of continuity plans and systems based on test results. Tests Integrity and Completeness of Back-Up Data - The integrity and completeness of back-up information is tested on a periodic basis.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_c_1_1": {"name": "C1.1 The entity identifies and maintains confidential information to meet the entity’s objectives related to confidentiality","checks": {"rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_c_1_1","Section": "CCC1.0 - Additional Criterial for Confidentiality","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Identifies Confidential information - Procedures are in place to identify and designate confidential information when it is received or created and to determine the period over which the confidential information is to be retained. Protects Confidential Information from Destruction - Procedures are in place to protect confidential information from erasure or destruction during the specified retention period of the information","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cc_c_1_2": {"name": "C1.2 The entity disposes of confidential information to meet the entity’s objectives related to confidentiality","checks": {"s3_bucket_object_versioning": "FAIL"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_c_1_2","Section": "CCC1.0 - Additional Criterial for Confidentiality","Service": "s3","SubGroup": null,"SubSection": null}],"description": "Identifies Confidential Information for Destruction - Procedures are in place to identify confidential information requiring destruction when the end of the retention period is reached. Destroys Confidential Information - Procedures are in place to erase or otherwise destroy confidential information that has been identified for destruction.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 10,"requirements_failed": 10,"requirements_manual": 36,"total_requirements": 56,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "8f43ba1e-a5fb-42c5-95ca-d0b199c62975","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "cis_3.0_aws","framework": "CIS","version": "3.0","description": "The CIS Amazon Web Services Foundations Benchmark provides prescriptive guidance for configuring security options for a subset of Amazon Web Services with an emphasis on foundational, testable, and architecture agnostic settings.","region": "eu-west-1","requirements": {"1.1": {"name": "1.1","checks": {"account_maintain_current_contact_details": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/manage-account-payment.html#contact-info","Description": "Ensure contact email and telephone details for AWS accounts are current and map to more than one individual in your organization.An AWS account supports a number of contact details, and AWS will use these to contact the account owner if activity judged to be in breach of Acceptable Use Policy or indicative of likely security compromise is observed by the AWS Abuse team. Contact details should not be for a single individual, as circumstances may arise where that individual is unavailable. Email contact details should point to a mail alias which forwards email to multiple individuals within the organization; where feasible, phone contact details should point to a PABX hunt group or other call-forwarding system.","DefaultValue": null,"AuditProcedure": "This activity can only be performed via the AWS Console, with a user who has permission to read and write Billing information (aws-portal:*Billing ) 1. Sign in to the AWS Management Console and open the Billing and Cost Management console at https://console.aws.amazon.com/billing/home#/. 2. On the navigation bar, choose your account name, and then choose Account. 3. On the Account Settings page, review and verify the current details. 4. Under Contact Information, review and verify the current details.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "If an AWS account is observed to be behaving in a prohibited or suspicious manner, AWS will attempt to contact the account owner by email and phone using the contact details listed. If this is unsuccessful and the account behavior needs urgent mitigation, proactive measures may be taken, including throttling of traffic between the account exhibiting suspicious behavior and the AWS API endpoints and the Internet. This will result in impaired service to and from the account in question, so it is in both the customers' and AWS' best interests that prompt contact can be established. This is best achieved by setting AWS account contact details to point to resources which have multiple individuals as recipients, such as email aliases and PABX hunt groups.","RemediationProcedure": "This activity can only be performed via the AWS Console, with a user who has permission to read and write Billing information (aws-portal:*Billing ). 1. Sign in to the AWS Management Console and open the Billing and Cost Management console at https://console.aws.amazon.com/billing/home#/. 2. On the navigation bar, choose your account name, and then choose Account. 3. On the Account Settings page, next to Account Settings, choose Edit. 4. Next to the field that you need to update, choose Edit. 5. After you have entered your changes, choose Save changes. 6. After you have made your changes, choose Done. 7. To edit your contact information, under Contact Information, choose Edit. 8. For the fields that you want to change, type your updated information, and then choose Update.","AdditionalInformation": ""}],"description": "Maintain current contact details","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.2": {"name": "1.2","checks": {"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "","Description": "AWS provides customers with the option of specifying the contact information for account's security team. It is recommended that this information be provided.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if security contact information is present:**From Console:**1. Click on your account name at the top right corner of the console 2. From the drop-down menu Click `My Account`3. Scroll down to the `Alternate Contacts` section 4. Ensure contact information is specified in the `Security` section","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Specifying security-specific contact information will help ensure that security advisories sent by AWS reach the team in your organization that is best equipped to respond to them.","RemediationProcedure": "Perform the following to establish security contact information:**From Console:**1. Click on your account name at the top right corner of the console. 2. From the drop-down menu Click `My Account`3. Scroll down to the `Alternate Contacts` section 4. Enter contact information in the `Security` section**Note:** Consider specifying an internal email distribution list to ensure emails are regularly monitored by more than one individual.","AdditionalInformation": ""}],"description": "Ensure security contact information is registered","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.3": {"name": "1.3","checks": {"account_security_questions_are_registered_in_the_aws_account": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "","Description": "The AWS support portal allows account owners to establish security questions that can be used to authenticate individuals calling AWS customer service for support. It is recommended that security questions be established.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS account as the 'root' user 2. On the top right you will see the __ 3. Click on the __ 4. From the drop-down menu Click `My Account`5. In the `Configure Security Challenge Questions` section on the `Personal Information` page, configure three security challenge questions. 6. Click `Save questions` .","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "When creating a new AWS account, a default super user is automatically created. This account is referred to as the 'root user' or 'root' account. It is recommended that the use of this account be limited and highly controlled. During events in which the 'root' password is no longer accessible or the MFA token associated with 'root' is lost/destroyed it is possible, through authentication using secret questions and associated answers, to recover 'root' user login access.","RemediationProcedure": "**From Console:**1. Login to the AWS Account as the 'root' user 2. Click on the __ from the top right of the console 3. From the drop-down menu Click _My Account_ 4. Scroll down to the `Configure Security Questions` section 5. Click on `Edit`6. Click on each `Question` - From the drop-down select an appropriate question- Click on the `Answer` section- Enter an appropriate answer - Follow process for all 3 questions 7. Click `Update` when complete 8. Save Questions and Answers and place in a secure physical location","AdditionalInformation": ""}],"description": "Ensure security questions are registered in the AWS account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.4": {"name": "1.4","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "http://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html:http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html:http://docs.aws.amazon.com/IAM/latest/APIReference/API_GetAccountSummary.html:https://aws.amazon.com/blogs/security/an-easier-way-to-determine-the-presence-of-aws-account-access-keys/","Description": "The 'root' user account is the most privileged user in an AWS account. AWS Access Keys provide programmatic access to a given AWS account. It is recommended that all access keys associated with the 'root' user account be removed.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has access keys:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on `Credential Report`5. This will download a `.csv` file which contains credential usage for all IAM users within an AWS Account - open this file 6. For the `` user, ensure the `access_key_1_active` and `access_key_2_active` fields are set to `FALSE` .**From Command Line:**Run the following command: ```aws iam get-account-summary | grep \"AccountAccessKeysPresent\"``` If no 'root' access keys exist the output will show \"AccountAccessKeysPresent\": 0,. If the output shows a \"1\" than 'root' keys exist, refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Removing access keys associated with the 'root' user account limits vectors by which the account can be compromised. Additionally, removing the 'root' access keys encourages the creation and use of role based accounts that are least privileged.","RemediationProcedure": "Perform the following to delete or disable active 'root' user access keys**From Console:**1. Sign in to the AWS Management Console as 'root' and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. Click on __ at the top right and select `My Security Credentials` from the drop down list 3. On the pop out screen Click on `Continue to Security Credentials`4. Click on `Access Keys` _(Access Key ID and Secret Access Key)_ 5. Under the `Status` column if there are any Keys which are Active- Click on `Make Inactive` - (Temporarily disable Key - may be needed again)- Click `Delete` - (Deleted keys cannot be recovered)","AdditionalInformation": "IAM User account \"root\" for us-gov cloud regions is not enabled by default. However, on request to AWS support enables 'root' access only through access-keys (CLI, API methods) for us-gov cloud region."}],"description": "Ensure no 'root' user account access key exists","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.5": {"name": "1.5","checks": {"iam_root_mfa_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#id_root-user_manage_mfa:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html#enable-virt-mfa-for-root","Description": "The 'root' user account is the most privileged user in an AWS account. Multi-factor Authentication (MFA) adds an extra layer of protection on top of a username and password. With MFA enabled, when a user signs in to an AWS website, they will be prompted for their username and password as well as for an authentication code from their AWS MFA device.**Note:** When virtual MFA is used for 'root' accounts, it is recommended that the device used is NOT a personal device, but rather a dedicated mobile device (tablet or phone) that is managed to be kept charged and secured independent of any individual personal devices. (\"non-personal virtual MFA\") This lessens the risks of losing access to the MFA due to device loss, device trade-in or if the individual owning the device is no longer employed at the company.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has MFA setup:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on `Credential Report`5. This will download a `.csv` file which contains credential usage for all IAM users within an AWS Account - open this file 6. For the `` user, ensure the `mfa_active` field is set to `TRUE` .**From Command Line:**1. Run the following command: ```aws iam get-account-summary | grep \"AccountMFAEnabled\" ``` 2. Ensure the AccountMFAEnabled property is set to 1","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling MFA provides increased security for console access as it requires the authenticating principal to possess a device that emits a time-sensitive key and have knowledge of a credential.","RemediationProcedure": "Perform the following to establish MFA for the 'root' user account:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). Note: to manage MFA devices for the 'root' AWS account, you must use your 'root' account credentials to sign in to AWS. You cannot manage MFA devices for the 'root' account using other credentials.2. Choose `Dashboard` , and under `Security Status` , expand `Activate MFA` on your root account. 3. Choose `Activate MFA`4. In the wizard, choose `A virtual MFA` device and then choose `Next Step` . 5. IAM generates and displays configuration information for the virtual MFA device, including a QR code graphic. The graphic is a representation of the 'secret configuration key' that is available for manual entry on devices that do not support QR codes. 6. Open your virtual MFA application. (For a list of apps that you can use for hosting virtual MFA devices, see [Virtual MFA Applications](http://aws.amazon.com/iam/details/mfa/#Virtual_MFA_Applications).) If the virtual MFA application supports multiple accounts (multiple virtual MFA devices), choose the option to create a new account (a new virtual MFA device). 7. Determine whether the MFA app supports QR codes, and then do one of the following: - Use the app to scan the QR code. For example, you might choose the camera icon or choose an option similar to Scan code, and then use the device's camera to scan the code.- In the Manage MFA Device wizard, choose Show secret key for manual configuration, and then type the secret configuration key into your MFA application.When you are finished, the virtual MFA device starts generating one-time passwords.In the Manage MFA Device wizard, in the Authentication Code 1 box, type the one-time password that currently appears in the virtual MFA device. Wait up to 30 seconds for the device to generate a new one-time password. Then type the second one-time password into the Authentication Code 2 box. Choose Assign Virtual MFA.","AdditionalInformation": "IAM User account \"root\" for us-gov cloud regions does not have console access. This recommendation is not applicable for us-gov cloud regions."}],"description": "Ensure MFA is enabled for the 'root' user account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.6": {"name": "1.6","checks": {"iam_root_hardware_mfa_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_physical.html#enable-hw-mfa-for-root","Description": "The 'root' user account is the most privileged user in an AWS account. MFA adds an extra layer of protection on top of a user name and password. With MFA enabled, when a user signs in to an AWS website, they will be prompted for their user name and password as well as for an authentication code from their AWS MFA device. For Level 2, it is recommended that the 'root' user account be protected with a hardware MFA.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has a hardware MFA setup:1. Run the following command to determine if the 'root' account has MFA setup: ```aws iam get-account-summary | grep \"AccountMFAEnabled\" ```The `AccountMFAEnabled` property is set to `1` will ensure that the 'root' user account has MFA (Virtual or Hardware) Enabled. If `AccountMFAEnabled` property is set to `0` the account is not compliant with this recommendation.2. If `AccountMFAEnabled` property is set to `1`, determine 'root' account has Hardware MFA enabled. Run the following command to list all virtual MFA devices: ```aws iam list-virtual-mfa-devices``` If the output contains one MFA with the following Serial Number, it means the MFA is virtual, not hardware and the account is not compliant with this recommendation: `\"SerialNumber\": \"arn:aws:iam::__:mfa/root-account-mfa-device\"`","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "A hardware MFA has a smaller attack surface than a virtual MFA. For example, a hardware MFA does not suffer the attack surface introduced by the mobile smartphone on which a virtual MFA resides.**Note**: Using hardware MFA for many, many AWS accounts may create a logistical device management issue. If this is the case, consider implementing this Level 2 recommendation selectively to the highest security AWS accounts and the Level 1 recommendation applied to the remaining accounts.","RemediationProcedure": "Perform the following to establish a hardware MFA for the 'root' user account:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). Note: to manage MFA devices for the AWS 'root' user account, you must use your 'root' account credentials to sign in to AWS. You cannot manage MFA devices for the 'root' account using other credentials. 2. Choose `Dashboard` , and under `Security Status` , expand `Activate MFA` on your root account. 3. Choose `Activate MFA`4. In the wizard, choose `A hardware MFA` device and then choose `Next Step` . 5. In the `Serial Number` box, enter the serial number that is found on the back of the MFA device. 6. In the `Authentication Code 1` box, enter the six-digit number displayed by the MFA device. You might need to press the button on the front of the device to display the number. 7. Wait 30 seconds while the device refreshes the code, and then enter the next six-digit number into the `Authentication Code 2` box. You might need to press the button on the front of the device again to display the second number. 8. Choose `Next Step` . The MFA device is now associated with the AWS account. The next time you use your AWS account credentials to sign in, you must type a code from the hardware MFA device.Remediation for this recommendation is not available through AWS CLI.","AdditionalInformation": "IAM User account 'root' for us-gov cloud regions does not have console access. This control is not applicable for us-gov cloud regions."}],"description": "Ensure hardware MFA is enabled for the 'root' user account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.7": {"name": "1.7","checks": {"iam_avoid_root_usage": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html:https://docs.aws.amazon.com/general/latest/gr/aws_tasks-that-require-root.html","Description": "With the creation of an AWS account, a 'root user' is created that cannot be disabled or deleted. That user has unrestricted access to and control over all resources in the AWS account. It is highly recommended that the use of this account be avoided for everyday tasks.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console at `https://console.aws.amazon.com/iam/` 2. In the left pane, click `Credential Report` 3. Click on `Download Report` 4. Open of Save the file locally 5. Locate the `` under the user column 6. Review `password_last_used, access_key_1_last_used_date, access_key_2_last_used_date` to determine when the 'root user' was last used.**From Command Line:**Run the following CLI commands to provide a credential report for determining the last time the 'root user' was used: ``` aws iam generate-credential-report ``` ``` aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,5,11,16 | grep -B1 '' ```Review `password_last_used`, `access_key_1_last_used_date`, `access_key_2_last_used_date` to determine when the _root user_ was last used.**Note:** There are a few conditions under which the use of the 'root' user account is required. Please see the reference links for all of the tasks that require use of the 'root' user.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "The 'root user' has unrestricted access to and control over all account resources. Use of it is inconsistent with the principles of least privilege and separation of duties, and can lead to unnecessary harm due to error or account compromise.","RemediationProcedure": "If you find that the 'root' user account is being used for daily activity to include administrative tasks that do not require the 'root' user:1. Change the 'root' user password. 2. Deactivate or delete any access keys associate with the 'root' user.**Remember, anyone who has 'root' user credentials for your AWS account has unrestricted access to and control of all the resources in your account, including billing information.","AdditionalInformation": "The 'root' user for us-gov cloud regions is not enabled by default. However, on request to AWS support, they can enable the 'root' user and grant access only through access-keys (CLI, API methods) for us-gov cloud region. If the 'root' user for us-gov cloud regions is enabled, this recommendation is applicable.Monitoring usage of the 'root' user can be accomplished by implementing recommendation 3.3 Ensure a log metric filter and alarm exist for usage of the 'root' user."}],"description": "Eliminate use of the 'root' user for administrative and daily tasks","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.8": {"name": "1.8","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy","Description": "Password policies are, in part, used to enforce password complexity requirements. IAM password policies can be used to ensure password are at least a given length. It is recommended that the password policy require a minimum password length 14.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure the password policy is configured as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Ensure \"Minimum password length\" is set to 14 or greater.**From Command Line:** ``` aws iam get-account-password-policy ``` Ensure the output of the above command includes \"MinimumPasswordLength\": 14 (or higher)","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Setting a password complexity policy increases account resiliency against brute force login attempts.","RemediationProcedure": "Perform the following to set the password policy as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Set \"Minimum password length\" to `14` or greater. 5. Click \"Apply password policy\"**From Command Line:** ```aws iam update-account-password-policy --minimum-password-length 14 ``` Note: All commands starting with \"aws iam update-account-password-policy\" can be combined into a single command.","AdditionalInformation": ""}],"description": "Ensure IAM password policy requires minimum length of 14 or greater","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.9": {"name": "1.9","checks": {"iam_password_policy_reuse_24": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy","Description": "IAM password policies can prevent the reuse of a given password by the same user. It is recommended that the password policy prevent the reuse of passwords.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure the password policy is configured as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Ensure \"Prevent password reuse\" is checked 5. Ensure \"Number of passwords to remember\" is set to 24**From Command Line:** ``` aws iam get-account-password-policy``` Ensure the output of the above command includes \"PasswordReusePrevention\": 24","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Preventing password reuse increases account resiliency against brute force login attempts.","RemediationProcedure": "Perform the following to set the password policy as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Check \"Prevent password reuse\" 5. Set \"Number of passwords to remember\" is set to `24` **From Command Line:** ```aws iam update-account-password-policy --password-reuse-prevention 24 ``` Note: All commands starting with \"aws iam update-account-password-policy\" can be combined into a single command.","AdditionalInformation": ""}],"description": "Ensure IAM password policy prevents password reuse","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.1": {"name": "3.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-management-events:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-management-and-data-events-with-cloudtrail.html?icmpid=docs_cloudtrail_console#logging-management-events:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-supported-services.html#cloud-trail-supported-services-data-events","Description": "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. CloudTrail provides a history of AWS API calls for an account, including API calls made via the Management Console, SDKs, command line tools, and higher-level AWS services (such as CloudFormation).","DefaultValue": null,"AuditProcedure": "Perform the following to determine if CloudTrail is enabled for all regions:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane- You will be presented with a list of trails across all regions 3. Ensure at least one Trail has `All` specified in the `Region` column 4. Click on a trail via the link in the _Name_ column 5. Ensure `Logging` is set to `ON`6. Ensure `Apply trail to all regions` is set to `Yes` 7. In section `Management Events` ensure `Read/Write Events` set to `ALL`**From Command Line:** ```aws cloudtrail describe-trails ``` Ensure `IsMultiRegionTrail` is set to `true```` aws cloudtrail get-trail-status --name  ``` Ensure `IsLogging` is set to `true` ``` aws cloudtrail get-event-selectors --trail-name  ``` Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`","ImpactStatement": "S3 lifecycle features can be used to manage the accumulation and management of logs over time. See the following AWS resource for more information on these features:1. https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html","AssessmentStatus": "Automated","RationaleStatement": "The AWS API call history produced by CloudTrail enables security analysis, resource change tracking, and compliance auditing. Additionally, - ensuring that a multi-regions trail exists will ensure that unexpected activity occurring in otherwise unused regions is detected- ensuring that a multi-regions trail exists will ensure that `Global Service Logging` is enabled for a trail by default to capture recording of events generated onAWS global services- for a multi-regions trail, ensuring that management events configured for all type of Read/Writes ensures recording of management operations that are performed on all resources in an AWS account","RemediationProcedure": "Perform the following to enable global (Multi-region) CloudTrail logging:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on _Trails_ on the left navigation pane 3. Click `Get Started Now` , if presented- Click `Add new trail` - Enter a trail name in the `Trail name` box- Set the `Apply trail to all regions` option to `Yes` - Specify an S3 bucket name in the `S3 bucket` box- Click `Create`4. If 1 or more trails already exist, select the target trail to enable for global logging 5. Click the edit icon (pencil) next to `Apply trail to all regions` , Click `Yes` and Click `Save`. 6. Click the edit icon (pencil) next to `Management Events` click `All` for setting `Read/Write Events` and Click `Save`.**From Command Line:** ``` aws cloudtrail create-trail --name  --bucket-name  --is-multi-region-trailaws cloudtrail update-trail --name  --is-multi-region-trail ```Note: Creating CloudTrail via CLI without providing any overriding options configures `Management Events` to set `All` type of `Read/Writes` by default.","AdditionalInformation": ""}],"description": "Ensure CloudTrail is enabled in all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3.2": {"name": "3.2","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-file-validation-enabling.html","Description": "CloudTrail log file validation creates a digitally signed digest file containing a hash of each log that CloudTrail writes to S3. These digest files can be used to determine whether a log file was changed, deleted, or unchanged after CloudTrail delivered the log. It is recommended that file validation be enabled on all CloudTrails.","DefaultValue": null,"AuditProcedure": "Perform the following on each trail to determine if log file validation is enabled:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane 3. For Every Trail: - Click on a trail via the link in the _Name_ column - Under the `General details` section, ensure `Log file validation` is set to `Enabled` **From Command Line:** ``` aws cloudtrail describe-trails ``` Ensure `LogFileValidationEnabled` is set to `true` for each trail","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling log file validation will provide additional integrity checking of CloudTrail logs.","RemediationProcedure": "Perform the following to enable log file validation on a given trail:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane 3. Click on target trail 4. Within the `General details` section click `edit` 5. Under the `Advanced settings` section 6. Check the enable box under `Log file validation`7. Click `Save changes` **From Command Line:** ``` aws cloudtrail update-trail --name  --enable-log-file-validation ``` Note that periodic validation of logs using these digests can be performed by running the following command: ``` aws cloudtrail validate-logs --trail-arn  --start-time  --end-time  ```","AdditionalInformation": ""}],"description": "Ensure CloudTrail log file validation is enabled","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.3": {"name": "3.3","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/cli/latest/reference/configservice/describe-configuration-recorder-status.html","Description": "AWS Config is a web service that performs configuration management of supported AWS resources within your account and delivers log files to you. The recorded information includes the configuration item (AWS resource), relationships between configuration items (AWS resources), any configuration changes between resources. It is recommended AWS Config be enabled in all regions.","DefaultValue": null,"AuditProcedure": "Process to evaluate AWS Config configuration per region**From Console:**1. Sign in to the AWS Management Console and open the AWS Config console at [https://console.aws.amazon.com/config/](https://console.aws.amazon.com/config/). 2. On the top right of the console select target Region. 3. If presented with Setup AWS Config - follow remediation procedure: 4. On the Resource inventory page, Click on edit (the gear icon). The Set Up AWS Config page appears. 5. Ensure 1 or both check-boxes under \"All Resources\" is checked.- Include global resources related to IAM resources - which needs to be enabled in 1 region only 6. Ensure the correct S3 bucket has been defined. 7. Ensure the correct SNS topic has been defined. 8. Repeat steps 2 to 7 for each region.**From Command Line:**1. Run this command to show all AWS Config recorders and their properties: ``` aws configservice describe-configuration-recorders ``` 2. Evaluate the output to ensure that there's at least one recorder for which `recordingGroup` object includes `\"allSupported\": true` AND `\"includeGlobalResourceTypes\": true`Note: There is one more parameter \"ResourceTypes\" in recordingGroup object. We don't need to check the same as whenever we set \"allSupported\": true, AWS enforces resource types to be empty (\"ResourceTypes\":[])Sample Output:``` {\"ConfigurationRecorders\": [{\"recordingGroup\": {\"allSupported\": true,\"resourceTypes\": [],\"includeGlobalResourceTypes\": true},\"roleARN\": \"arn:aws:iam:::role/service-role/\",\"name\": \"default\"}] } ```3. Run this command to show the status for all AWS Config recorders: ``` aws configservice describe-configuration-recorder-status ``` 4. In the output, find recorders with `name` key matching the recorders that met criteria in step 2. Ensure that at least one of them includes `\"recording\": true` and `\"lastStatus\": \"SUCCESS\"`","ImpactStatement": "It is recommended AWS Config be enabled in all regions.","AssessmentStatus": "Automated","RationaleStatement": "The AWS configuration item history captured by AWS Config enables security analysis, resource change tracking, and compliance auditing.","RemediationProcedure": "To implement AWS Config configuration:**From Console:**1. Select the region you want to focus on in the top right of the console 2. Click `Services`3. Click `Config`4. Define which resources you want to record in the selected region 5. Choose to include global resources (IAM resources) 6. Specify an S3 bucket in the same account or in another managed AWS account 7. Create an SNS Topic from the same AWS account or another managed AWS account**From Command Line:**1. Ensure there is an appropriate S3 bucket, SNS topic, and IAM role per the [AWS Config Service prerequisites](http://docs.aws.amazon.com/config/latest/developerguide/gs-cli-prereq.html). 2. Run this command to set up the configuration recorder ``` aws configservice subscribe --s3-bucket my-config-bucket --sns-topic arn:aws:sns:us-east-1:012345678912:my-config-notice --iam-role arn:aws:iam::012345678912:role/myConfigRole ``` 3. Run this command to start the configuration recorder: ``` start-configuration-recorder --configuration-recorder-name  ```","AdditionalInformation": ""}],"description": "Ensure AWS Config is enabled in all regions","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.4": {"name": "3.4","checks": {"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerLogs.html","Description": "S3 Bucket Access Logging generates a log that contains access records for each request made to your S3 bucket. An access log record contains details about the request, such as the request type, the resources specified in the request worked, and the time and date the request was processed. It is recommended that bucket access logging be enabled on the CloudTrail S3 bucket.","DefaultValue": null,"AuditProcedure": "Perform the following ensure the CloudTrail S3 bucket has access logging is enabled:**From Console:**1. Go to the Amazon CloudTrail console at [https://console.aws.amazon.com/cloudtrail/home](https://console.aws.amazon.com/cloudtrail/home) 2. In the API activity history pane on the left, click Trails 3. In the Trails pane, note the bucket names in the S3 bucket column 4. Sign in to the AWS Management Console and open the S3 console at [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3). 5. Under `All Buckets` click on a target S3 bucket 6. Click on `Properties` in the top right of the console 7. Under `Bucket:` _ `` _ click on `Logging`8. Ensure `Enabled` is checked.**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ```aws cloudtrail describe-trails --query 'trailList[*].S3BucketName'``` 2. Ensure Bucket Logging is enabled: ``` aws s3api get-bucket-logging --bucket  ``` Ensure command does not returns empty output.Sample Output for a bucket with logging enabled:``` {\"LoggingEnabled\": {\"TargetPrefix\": \"\",\"TargetBucket\": \"\"} } ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "By enabling S3 bucket logging on target S3 buckets, it is possible to capture all events which may affect objects within any target buckets. Configuring logs to be placed in a separate bucket allows access to log information which can be useful in security and incident response workflows.","RemediationProcedure": "Perform the following to enable S3 bucket logging:**From Console:**1. Sign in to the AWS Management Console and open the S3 console at [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3). 2. Under `All Buckets` click on the target S3 bucket 3. Click on `Properties` in the top right of the console 4. Under `Bucket:`  click on `Logging`5. Configure bucket logging- Click on the `Enabled` checkbox- Select Target Bucket from list- Enter a Target Prefix 6. Click `Save`.**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ``` aws cloudtrail describe-trails --region  --query trailList[*].S3BucketName ``` 2. Copy and add target bucket name at ``, Prefix for logfile at `` and optionally add an email address in the following template and save it as ``: ``` {\"LoggingEnabled\": {\"TargetBucket\": \"\",\"TargetPrefix\": \"\",\"TargetGrants\": [{\"Grantee\": {\"Type\": \"AmazonCustomerByEmail\",\"EmailAddress\": \"\"},\"Permission\": \"FULL_CONTROL\"}]}} ``` 3. Run the `put-bucket-logging` command with bucket name and `` as input, for more information refer at [put-bucket-logging](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-logging.html): ``` aws s3api put-bucket-logging --bucket  --bucket-logging-status file:// ```","AdditionalInformation": ""}],"description": "Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.5": {"name": "3.5","checks": {"cloudtrail_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/encrypting-cloudtrail-log-files-with-aws-kms.html:https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html","Description": "AWS CloudTrail is a web service that records AWS API calls for an account and makes those logs available to users and resources in accordance with IAM policies. AWS Key Management Service (KMS) is a managed service that helps create and control the encryption keys used to encrypt account data, and uses Hardware Security Modules (HSMs) to protect the security of encryption keys. CloudTrail logs can be configured to leverage server side encryption (SSE) and KMS customer created master keys (CMK) to further protect CloudTrail logs. It is recommended that CloudTrail be configured to use SSE-KMS.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if CloudTrail is configured to use SSE-KMS:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. In the left navigation pane, choose `Trails` . 3. Select a Trail 4. Under the `S3` section, ensure `Encrypt log files` is set to `Yes` and a KMS key ID is specified in the `KSM Key Id` field.**From Command Line:**1. Run the following command: ```aws cloudtrail describe-trails``` 2. For each trail listed, SSE-KMS is enabled if the trail has a `KmsKeyId` property defined.","ImpactStatement": "Customer created keys incur an additional cost. See https://aws.amazon.com/kms/pricing/ for more information.","AssessmentStatus": "Automated","RationaleStatement": "Configuring CloudTrail to use SSE-KMS provides additional confidentiality controls on log data as a given user must have S3 read permission on the corresponding log bucket and must be granted decrypt permission by the CMK policy.","RemediationProcedure": "Perform the following to configure CloudTrail to use SSE-KMS:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. In the left navigation pane, choose `Trails` . 3. Click on a Trail 4. Under the `S3` section click on the edit button (pencil icon) 5. Click `Advanced`6. Select an existing CMK from the `KMS key Id` drop-down menu- Note: Ensure the CMK is located in the same region as the S3 bucket- Note: You will need to apply a KMS Key policy on the selected CMK in order for CloudTrail as a service to encrypt and decrypt log files using the CMK provided. Steps are provided [here](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/create-kms-key-policy-for-cloudtrail.html) for editing the selected CMK Key policy 7. Click `Save`8. You will see a notification message stating that you need to have decrypt permissions on the specified KMS key to decrypt log files. 9. Click `Yes` **From Command Line:** ``` aws cloudtrail update-trail --name  --kms-id  aws kms put-key-policy --key-id  --policy  ```","AdditionalInformation": "3 statements which need to be added to the CMK policy:1\\. Enable Cloudtrail to describe CMK properties ``` 
{\"Sid\": \"Allow CloudTrail access\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\"Action\": \"kms:DescribeKey\",\"Resource\": \"*\" } ``` 2\\. Granting encrypt permissions ``` 
{\"Sid\": \"Allow CloudTrail to encrypt logs\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\"Action\": \"kms:GenerateDataKey*\",\"Resource\": \"*\",\"Condition\": {\"StringLike\": {\"kms:EncryptionContext:aws:cloudtrail:arn\": [\"arn:aws:cloudtrail:*:aws-account-id:trail/*\"]}} } ``` 3\\. Granting decrypt permissions ``` 
{\"Sid\": \"Enable CloudTrail log decrypt permissions\",\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"arn:aws:iam::aws-account-id:user/username\"},\"Action\": \"kms:Decrypt\",\"Resource\": \"*\",\"Condition\": {\"Null\": {\"kms:EncryptionContext:aws:cloudtrail:arn\": \"false\"}} } ```"}],"description": "Ensure CloudTrail logs are encrypted at rest using KMS CMKs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.6": {"name": "3.6","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://aws.amazon.com/kms/pricing/:https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final","Description": "AWS Key Management Service (KMS) allows customers to rotate the backing key which is key material stored within the KMS which is tied to the key ID of the Customer Created customer master key (CMK). It is the backing key that is used to perform cryptographic operations such as encryption and decryption. Automated key rotation currently retains all prior backing keys so that decryption of encrypted data can take place transparently. It is recommended that CMK key rotation be enabled for symmetric keys. Key rotation can not be enabled for any asymmetric CMK.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Sign in to the AWS Management Console and open the KMS console at: https://console.aws.amazon.com/kms. 2. In the left navigation pane, click Customer-managed keys. 3. Select a customer managed CMK where Key spec = SYMMETRIC_DEFAULT. 4. Select the Key rotation tab. 5. Ensure the Automatically rotate this KMS key every year checkbox is checked. 6. Repeat steps 3–5 for all customer-managed CMKs where 'Key spec = SYMMETRIC_DEFAULT'.","ImpactStatement": "Creation, management, and storage of CMKs may require additional time from and administrator.","AssessmentStatus": "Automated","RationaleStatement": "Rotating encryption keys helps reduce the potential impact of a compromised key as data encrypted with a new key cannot be accessed with a previous key that may have been exposed. Keys should be rotated every year, or upon event that would result in the compromise of that key.","RemediationProcedure": "**From Console:**1. Sign in to the AWS Management Console and open the KMS console at: https://console.aws.amazon.com/kms. 2. In the left navigation pane, click Customer-managed keys. 3. Select a key where Key spec = SYMMETRIC_DEFAULT that does not have automatic rotation enabled. 4. Select the Key rotation tab. 5. Check the Automatically rotate this KMS key every year checkbox. 6. Click Save. 7. Repeat steps 3–6 for all customer-managed CMKs that do not have automatic rotation enabled.","AdditionalInformation": ""}],"description": "Ensure rotation for customer created symmetric CMKs is enabled","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.7": {"name": "3.7","checks": {"vpc_flow_logs_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/flow-logs.html","Description": "VPC Flow Logs is a feature that enables you to capture information about the IP traffic going to and from network interfaces in your VPC. After you've created a flow log, you can view and retrieve its data in Amazon CloudWatch Logs. It is recommended that VPC Flow Logs be enabled for packet \"Rejects\" for VPCs.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if VPC Flow logs are enabled:**From Console:**1. Sign into the management console 2. Select `Services` then `VPC`3. In the left navigation pane, select `Your VPCs`4. Select a VPC 5. In the right pane, select the `Flow Logs` tab. 6. Ensure a Log Flow exists that has `Active` in the `Status` column.**From Command Line:**1. Run `describe-vpcs` command (OSX/Linux/UNIX) to list the VPC networks available in the current AWS region: ``` aws ec2 describe-vpcs --region  --query Vpcs[].VpcId ``` 2. The command output returns the `VpcId` available in the selected region. 3. Run `describe-flow-logs` command (OSX/Linux/UNIX) using the VPC ID to determine if the selected virtual network has the Flow Logs feature enabled: ``` aws ec2 describe-flow-logs --filter \"Name=resource-id,Values=\" ``` 4. If there are no Flow Logs created for the selected VPC, the command output will return an `empty list []`. 5. Repeat step 3 for other VPCs available in the same region. 6. Change the region by updating `--region` and repeat steps 1 - 5 for all the VPCs.","ImpactStatement": "By default, CloudWatch Logs will store Logs indefinitely unless a specific retention period is defined for the log group. When choosing the number of days to retain, keep in mind the average days it takes an organization to realize they have been breached is 210 days (at the time of this writing). Since additional time is required to research a breach, a minimum 365 day retention policy allows time for detection and research. You may also wish to archive the logs to a cheaper storage service rather than simply deleting them. See the following AWS resource to manage CloudWatch Logs retention periods:1. https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/SettingLogRetention.html","AssessmentStatus": "Automated","RationaleStatement": "VPC Flow Logs provide visibility into network traffic that traverses the VPC and can be used to detect anomalous traffic or insight during security workflows.","RemediationProcedure": "Perform the following to determine if VPC Flow logs is enabled:**From Console:**1. Sign into the management console 2. Select `Services` then `VPC`3. In the left navigation pane, select `Your VPCs`4. Select a VPC 5. In the right pane, select the `Flow Logs` tab. 6. If no Flow Log exists, click `Create Flow Log`7. For Filter, select `Reject` 8. Enter in a `Role` and `Destination Log Group`9. Click `Create Log Flow`10. Click on `CloudWatch Logs Group` **Note:** Setting the filter to \"Reject\" will dramatically reduce the logging data accumulation for this recommendation and provide sufficient information for the purposes of breach detection, research and remediation. However, during periods of least privilege security group engineering, setting this the filter to \"All\" can be very helpful in discovering existing traffic flows required for proper operation of an already running environment.**From Command Line:**1. Create a policy document and name it as `role_policy_document.json` and paste the following content: ``` {\"Version\": \"2012-10-17\",\"Statement\": [{\"Sid\": \"test\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"ec2.amazonaws.com\"},\"Action\": \"sts:AssumeRole\"}] } ``` 2. Create another policy document and name it as `iam_policy.json` and paste the following content: ``` {\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Action\":[\"logs:CreateLogGroup\",\"logs:CreateLogStream\",\"logs:DescribeLogGroups\",\"logs:DescribeLogStreams\",\"logs:PutLogEvents\",\"logs:GetLogEvents\",\"logs:FilterLogEvents\"],\"Resource\": \"*\"}] } ``` 3. Run the below command to create an IAM role: ``` aws iam create-role --role-name  --assume-role-policy-document file://role_policy_document.json``` 4. Run the below command to create an IAM policy: ``` aws iam create-policy --policy-name  --policy-document file://iam-policy.json ``` 5. Run `attach-group-policy` command using the IAM policy ARN returned at the previous step to attach the policy to the IAM role (if the command succeeds, no output is returned): ``` aws iam attach-group-policy --policy-arn arn:aws:iam:::policy/ --group-name  ``` 6. Run `describe-vpcs` to get the VpcId available in the selected region: ``` aws ec2 describe-vpcs --region  ``` 7. The command output should return the VPC Id available in the selected region. 8. Run `create-flow-logs` to create a flow log for the vpc: ``` aws ec2 create-flow-logs --resource-type VPC --resource-ids  --traffic-type REJECT --log-group-name  --deliver-logs-permission-arn  ``` 9. Repeat step 8 for other vpcs available in the selected region. 10. Change the region by updating --region and repeat remediation procedure for other vpcs.","AdditionalInformation": ""}],"description": "Ensure VPC flow logging is enabled in all VPCs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.8": {"name": "3.8","checks": {"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-cloudtrail-events.html","Description": "S3 object-level API operations such as GetObject, DeleteObject, and PutObject are called data events. By default, CloudTrail trails don't log data events and so it is recommended to enable Object-level logging for S3 buckets.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to CloudTrail dashboard at https://console.aws.amazon.com/cloudtrail/ 2. In the left panel, click Trails and then click on the CloudTrail Name that you want to examine. 3. Review General details 4. Confirm that Multi-region trail is set to Yes 5. Scroll down to Data events 6. Confirm that it reads: Data Events:S3 Log selector template Log all events If 'basic events selectors' is being used it should read: Data events: S3 Bucket Name: All current and future S3 buckets Write: Enabled 7. Repeat steps 2 to 6 to verify that Multi-region trail and Data events logging of S3 buckets in CloudTrail. If the CloudTrails do not have multi-region and data events configured for S3 refer to the remediation below..","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling object-level logging will help you meet data compliance requirements within your organization, perform comprehensive security analysis, monitor specific patterns of user behavior in your AWS account or take immediate actions on any object-level API activity within your S3 Buckets using Amazon CloudWatch Events.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at https://console.aws.amazon.com/s3/ 2. In the left navigation panel, click buckets and then click on the S3 Bucket Name that you want to examine. 3. Click Properties tab to see in detail bucket configuration. 4. In the AWS Cloud Trail data events' section select the CloudTrail name for the recording activity. You can choose an existing Cloudtrail or create a new one by slicking the Configure in Cloudtrailbutton or navigating to the Cloudtrail console linkhttps://console.aws.amazon.com/cloudtrail/` 5. Once the Cloudtrail is selected, Select the data Data Events check box. 6. Select S3 from the `Data event type drop down. 7. Select Log all events from the Log selector template drop down. 8. Repeat steps 2 to 5 to enable object-level logging of write events for other S3 buckets.","AdditionalInformation": ""}],"description": "Ensure that Object-level logging for write events is enabled for S3 bucket","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.9": {"name": "3.9","checks": {"cloudtrail_s3_dataevents_read_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-cloudtrail-events.html","Description": "S3 object-level API operations such as GetObject, DeleteObject, and PutObject are called data events. By default, CloudTrail trails don't log data events and so it is recommended to enable Object-level logging for S3 buckets.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. If the current status for `Object-level` logging is set to `Disabled`, then object-level logging of read events for the selected s3 bucket is not set. 5. If the current status for `Object-level` logging is set to `Enabled`, but the Read event check-box is unchecked, then object-level logging of read events for the selected s3 bucket is not set. 6. Repeat steps 2 to 5 to verify `object-level` logging for `read` events of your other S3 buckets.**From Command Line:** 1. Run `describe-trails` command to list the names of all Amazon CloudTrail trails currently available in the selected AWS region: ``` aws cloudtrail describe-trails --region  --output table --query trailList[*].Name ``` 2. The command output will be table of the requested trail names. 3. Run `get-event-selectors` command using the name of the trail returned at the previous step and custom query filters to determine if Data events logging feature is enabled within the selected CloudTrail trail configuration for s3 bucket resources: ``` aws cloudtrail get-event-selectors --region  --trail-name  --query EventSelectors[*].DataResources[] ``` 4. The command output should be an array that contains the configuration of the AWS resource(S3 bucket) defined for the Data events selector. 5. If the `get-event-selectors` command returns an empty array, the Data events are not included into the selected AWS Cloudtrail trail logging configuration, therefore the S3 object-level API operations performed within your AWS account are not recorded. 6. Repeat steps 1 to 5 for auditing each s3 bucket to identify other trails that are missing the capability to log Data events. 7. Change the AWS region by updating the `--region` command parameter and perform the audit process for other regions.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling object-level logging will help you meet data compliance requirements within your organization, perform comprehensive security analysis, monitor specific patterns of user behavior in your AWS account or take immediate actions on any object-level API activity using Amazon CloudWatch Events.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. Click on the `Object-level` logging setting, enter the CloudTrail name for the recording activity. You can choose an existing Cloudtrail or create a new one by navigating to the Cloudtrail console link `https://console.aws.amazon.com/cloudtrail/` 5. Once the Cloudtrail is selected, check the Read event checkbox, so that `object-level` logging for `Read` events is enabled. 6. Repeat steps 2 to 5 to enable `object-level` logging of read events for other S3 buckets.**From Command Line:** 1. To enable `object-level` data events logging for S3 buckets within your AWS account, run `put-event-selectors` command using the name of the trail that you want to reconfigure as identifier: ``` aws cloudtrail put-event-selectors --region  --trail-name  --event-selectors '[{ \"ReadWriteType\": \"ReadOnly\", \"IncludeManagementEvents\":true, \"DataResources\": [{ \"Type\": \"AWS::S3::Object\", \"Values\": [\"arn:aws:s3:::/\"] }] }]' ``` 2. The command output will be `object-level` event trail configuration. 3. If you want to enable it for all buckets at ones then change Values parameter to `[\"arn:aws:s3\"]` in command given above. 4. Repeat step 1 for each s3 bucket to update `object-level` logging of read events. 5. Change the AWS region by updating the `--region` command parameter and perform the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that Object-level logging for read events is enabled for S3 bucket","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.1": {"name": "4.1","checks": {"cloudwatch_log_metric_filter_unauthorized_api_calls": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://aws.amazon.com/sns/:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for unauthorized API calls.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with \"Name\":` note ``- From value associated with \"CloudWatchLogsLogGroupArn\" note Example: for CloudWatchLogsLogGroupArn that looks like arn:aws:logs:::log-group:NewGroup:*,  would be NewGroup- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name <\"Name\" as shown in describe-trails>`Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this `` that you captured in step 1:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.errorCode = *UnauthorizedOperation) || ($.errorCode = AccessDenied*) || ($.sourceIPAddress!=delivery.logs.amazonaws.com) || ($.eventName!=HeadBucket) }\", ```4. Note the \"filterName\" `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query \"MetricAlarms[?MetricName == `unauthorized_api_calls_metric`]\" ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "This alert may be triggered by normal read-only console activities that attempt to opportunistically gather optional information, but gracefully fail if they don't have permissions.If an excessive number of alerts are being generated then an organization may wish to consider adding read access to the limited IAM user permissions simply to quiet the alerts.In some cases doing this may allow the users to actually view some areas of the system - any additional access given should be reviewed for alignment with the original limited IAM user intent.","AssessmentStatus": "Automated","RationaleStatement": "Monitoring unauthorized API calls will help reveal application errors and may reduce time to detect malicious activity.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for unauthorized API calls and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name \"cloudtrail_log_group_name\" --filter-name \"\" --metric-transformations metricName=unauthorized_api_calls_metric,metricNamespace=CISBenchmark,metricValue=1 --filter-pattern \"{ ($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\") || ($.sourceIPAddress!=\"delivery.logs.amazonaws.com\") || ($.eventName!=\"HeadBucket\") }\" ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms. **Note**: Capture the TopicArn displayed when creating the SNS Topic in Step 2.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name \"unauthorized_api_calls_alarm\" --metric-name \"unauthorized_api_calls_metric\" --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace \"CISBenchmark\" --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for unauthorized API calls","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.2": {"name": "4.2","checks": {"cloudwatch_log_metric_filter_sign_in_without_mfa": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/viewing_metrics_with_cloudwatch.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for console logins that are not protected by multi-factor authentication (MFA).","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all `CloudTrails`:``` aws cloudtrail describe-trails ```- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region `CloudTrail` is active``` aws cloudtrail get-trail-status --name  ```Ensure in the output that `IsLogging` is set to `TRUE`- Ensure identified Multi-region 'Cloudtrail' captures all Management Events``` aws cloudtrail get-event-selectors --trail-name  ```Ensure in the output there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }\" ```Or (To reduce false positives incase Single Sign-On (SSO) is used in organization):``` \"filterPattern\": \"{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\") }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring for single-factor console logins will increase visibility into accounts that are not protected by MFA.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Management Console sign-in without MFA and the `` taken from audit step 1.Use Command: ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }' ```Or (To reduce false positives incase Single Sign-On (SSO) is used in organization):``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\") }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored -Filter pattern set to `{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\"}` reduces false alarms raised when user logs in via SSO account."}],"description": "Ensure a log metric filter and alarm exist for Management Console sign-in without MFA","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.3": {"name": "4.3","checks": {"cloudwatch_log_metric_filter_root_usage": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for 'root' login attempts.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails:`aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring for 'root' account logins will provide visibility into the use of a fully privileged account and an opportunity to reduce the use of it.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for 'Root' account usage and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name `` --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "**Configuring log metric filter and alarm on Multi-region (global) CloudTrail**- ensures that activities from all regions (used as well as unused) are monitored- ensures that activities on all supported global services are monitored- ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for usage of 'root' account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.4": {"name": "4.4","checks": {"cloudwatch_log_metric_filter_policy_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established changes made to Identity and Access Management (IAM) policies.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails:`aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to IAM policies will help ensure authentication and authorization controls remain intact.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for IAM policy changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name `` --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for IAM policy changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.5": {"name": "4.5","checks": {"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for detecting changes to CloudTrail's configurations.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to CloudTrail's configuration will help ensure sustained visibility to activities performed in the AWS account.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for cloudtrail configuration changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for CloudTrail configuration changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.6": {"name": "4.6","checks": {"cloudwatch_log_metric_filter_authentication_failures": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for failed console authentication attempts.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring failed console logins may decrease lead time to detect an attempt to brute force a credential, which may provide an indicator, such as source IP, that can be used in other event correlation.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS management Console Login Failures and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }' ``` **Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for AWS Management Console authentication failures","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.7": {"name": "4.7","checks": {"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for customer created CMKs which have changed state to disabled or scheduled deletion.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Data encrypted with disabled or deleted keys will no longer be accessible.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for disabled or scheduled for deletion CMK's and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }' ``` **Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.8": {"name": "4.8","checks": {"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for changes to S3 bucket policies.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to S3 bucket policies may reduce time to detect and correct permissive policies on sensitive S3 buckets.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for S3 bucket policy changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for S3 bucket policy changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.9": {"name": "4.9","checks": {"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for detecting changes to CloudTrail's configurations.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to AWS Config configuration will help ensure sustained visibility of configuration items within the AWS account.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Configuration changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for AWS Config configuration changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"5.1": {"name": "5.1","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html:https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Security.html#VPC_Security_Comparison","Description": "The Network Access Control List (NACL) function provide stateless filtering of ingress and egress network traffic to AWS resources. It is recommended that no NACL allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "**From Console:**Perform the following to determine if the account is configured as prescribed: 1. Login to the AWS Management Console at https://console.aws.amazon.com/vpc/home 2. In the left pane, click `Network ACLs` 3. For each network ACL, perform the following:- Select the network ACL- Click the `Inbound Rules` tab- Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `0.0.0.0/0` and shows `ALLOW`**Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "**From Console:**Perform the following: 1. Login to the AWS Management Console at https://console.aws.amazon.com/vpc/home 2. In the left pane, click `Network ACLs` 3. For each network ACL to remediate, perform the following:- Select the network ACL- Click the `Inbound Rules` tab- Click `Edit inbound rules`- Either A) update the Source field to a range other than 0.0.0.0/0, or, B) Click `Delete` to remove the offending inbound rule- Click `Save`","AdditionalInformation": ""}],"description": "Ensure no Network ACLs allow ingress from 0.0.0.0/0 to remote server administration ports","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"5.2": {"name": "5.2","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#deleting-security-group-rule","Description": "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `0.0.0.0/0` **Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports.","ImpactStatement": "When updating an existing environment, ensure that administrators have access to remote server administration ports through another mechanism before removing access by deleting the 0.0.0.0/0 inbound rule.","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "Perform the following to implement the prescribed state:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Click the `Edit inbound rules` button 4. Identify the rules to be edited or removed 5. Either A) update the Source field to a range other than 0.0.0.0/0, or, B) Click `Delete` to remove the offending inbound rule 6. Click `Save rules`","AdditionalInformation": ""}],"description": "Ensure no security groups allow ingress from 0.0.0.0/0 to remote server administration ports","checks_status": {"fail": 0,"pass": 3,"total": 3,"manual": 0}},"5.3": {"name": "5.3","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#deleting-security-group-rule","Description": "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `::/0` **Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports.","ImpactStatement": "When updating an existing environment, ensure that administrators have access to remote server administration ports through another mechanism before removing access by deleting the ::/0 inbound rule.","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "Perform the following to implement the prescribed state:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Click the `Edit inbound rules` button 4. Identify the rules to be edited or removed 5. Either A) update the Source field to a range other than ::/0, or, B) Click `Delete` to remove the offending inbound rule 6. Click `Save rules`","AdditionalInformation": ""}],"description": "Ensure no security groups allow ingress from ::/0 to remote server administration ports","checks_status": {"fail": 0,"pass": 3,"total": 3,"manual": 0}},"5.4": {"name": "5.4","checks": {"ec2_securitygroup_default_restrict_traffic": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#default-security-group","Description": "A VPC comes with a default security group whose initial settings deny all inbound traffic, allow all outbound traffic, and allow all traffic between instances assigned to the security group. If you don't specify a security group when you launch an instance, the instance is automatically assigned to this default security group. Security groups provide stateful filtering of ingress/egress network traffic to AWS resources. It is recommended that the default security group restrict all traffic.The default VPC in every region should have its default security group updated to comply. Any newly created VPCs will automatically contain a default security group that will need remediation to comply with this recommendation.**NOTE:** When implementing this recommendation, VPC flow logging is invaluable in determining the least privilege port access required by systems to work properly because it can log all packet acceptances and rejections occurring under the current security groups. This dramatically reduces the primary barrier to least privilege engineering - discovering the minimum ports required by systems in the environment. Even if the VPC flow logging recommendation in this benchmark is not adopted as a permanent security measure, it should be used during any period of discovery and engineering for least privileged security groups.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:Security Group State1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. For each default security group, perform the following: 1. Select the `default` security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exist 4. Click the `Outbound Rules` tab 5. Ensure no rules existSecurity Group Members1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all default groups in all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. Copy the id of the default security group. 5. Change to the EC2 Management Console at https://console.aws.amazon.com/ec2/v2/home 6. In the filter column type 'Security Group ID : < security group id from #4 >'","ImpactStatement": "Implementing this recommendation in an existing VPC containing operating resources requires extremely careful migration planning as the default security groups are likely to be enabling many ports that are unknown. Enabling VPC flow logging (of accepts) in an existing environment that is known to be breach free will reveal the current pattern of ports being used for each instance to communicate successfully.","AssessmentStatus": "Automated","RationaleStatement": "Configuring all VPC default security groups to restrict all traffic will encourage least privilege security group development and mindful placement of AWS resources into security groups which will in-turn reduce the exposure of those resources.","RemediationProcedure": "Security Group MembersPerform the following to implement the prescribed state:1. Identify AWS resources that exist within the default security group 2. Create a set of least privilege security groups for those resources 3. Place the resources in those security groups 4. Remove the resources noted in #1 from the default security groupSecurity Group State1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. For each default security group, perform the following: 1. Select the `default` security group 2. Click the `Inbound Rules` tab 3. Remove any inbound rules 4. Click the `Outbound Rules` tab 5. Remove any Outbound rulesRecommended:IAM groups allow you to edit the \"name\" field. After remediating default groups rules for all VPCs in all regions, edit this field to add text similar to \"DO NOT USE. DO NOT ADD RULES\"","AdditionalInformation": ""}],"description": "Ensure the default security group of every VPC restricts all traffic","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"5.5": {"name": "5.5","checks": {"vpc_peering_routing_tables_with_least_privilege": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "5. Networking","References": "https://docs.aws.amazon.com/AmazonVPC/latest/PeeringGuide/peering-configurations-partial-access.html:https://docs.aws.amazon.com/cli/latest/reference/ec2/create-vpc-peering-connection.html","Description": "Once a VPC peering connection is established, routing tables must be updated to establish any connections between the peered VPCs. These routes can be as specific as desired - even peering a VPC to only a single host on the other side of the connection.","DefaultValue": null,"AuditProcedure": "Review routing tables of peered VPCs for whether they route all subnets of each VPC and whether that is necessary to accomplish the intended purposes for peering the VPCs.**From Command Line:**1. List all the route tables from a VPC and check if \"GatewayId\" is pointing to a __ (e.g. pcx-1a2b3c4d) and if \"DestinationCidrBlock\" is as specific as desired. ``` aws ec2 describe-route-tables --filter \"Name=vpc-id,Values=\" --query \"RouteTables[*].{RouteTableId:RouteTableId, VpcId:VpcId, Routes:Routes, AssociatedSubnets:Associations[*].SubnetId}\" ```","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Being highly selective in peering routing tables is a very effective way of minimizing the impact of breach as resources outside of these routes are inaccessible to the peered VPC.","RemediationProcedure": "Remove and add route table entries to ensure that the least number of subnets or hosts as is required to accomplish the purpose for peering are routable.**From Command Line:**1. For each __ containing routes non compliant with your routing policy (which grants more than desired \"least access\"), delete the non compliant route: ``` aws ec2 delete-route --route-table-id  --destination-cidr-block  ```2. Create a new compliant route: ``` aws ec2 create-route --route-table-id  --destination-cidr-block  --vpc-peering-connection-id  ```","AdditionalInformation": "If an organization has AWS transit gateway implemented in their VPC architecture they should look to apply the recommendation above for \"least access\" routing architecture at the AWS transit gateway level in combination with what must be implemented at the standard VPC route table. More specifically, to route traffic between two or more VPCs via a transit gateway VPCs must have an attachment to a transit gateway route table as well as a route, therefore to avoid routing traffic between VPCs an attachment to the transit gateway route table should only be added where there is an intention to route traffic between the VPCs. As transit gateways are able to host multiple route tables it is possible to group VPCs by attaching them to a common route table."}],"description": "Ensure routing tables for VPC peering are \"least access\"","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"5.6": {"name": "5.6","checks": {"ec2_instance_imdsv2_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service/:https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html","Description": "When enabling the Metadata Service on AWS EC2 instances, users have the option of using either Instance Metadata Service Version 1 (IMDSv1; a request/response method) or Instance Metadata Service Version 2 (IMDSv2; a session-oriented method).","DefaultValue": null,"AuditProcedure": "From Console: 1. Sign in to the AWS Management Console and navigate to the EC2 dashboard at https://console.aws.amazon.com/ec2/. 2. In the left navigation panel, under the INSTANCES section, choose Instances. 3. Select the EC2 instance that you want to examine. 4. Check for the IMDSv2 status, and ensure that it is set to Required. From Command Line: 1. Run the describe-instances command using appropriate filtering to list the IDs of all the existing EC2 instances currently available in the selected region: aws ec2 describe-instances --region  --output table --query 'Reservations[*].Instances[*].InstanceId' 2. The command output should return a table with the requested instance IDs. 3. Now run the describe-instances command using an instance ID returned at the previous step and custom filtering to determine whether the selected instance has IMDSv2: aws ec2 describe-instances --region  --instance-ids  --query 'Reservations[*].Instances[*].MetadataOptions' --output table 4. Ensure for all ec2 instances HttpTokens is set to required and State is set to applied. 5. Repeat steps no. 3 and 4 to verify other EC2 instances provisioned within the current region. 6. Repeat steps no. 1 – 5 to perform the audit process for other AWS regions.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Instance metadata is data about your instance that you can use to configure or manage the running instance. Instance metadata is divided into categories, for example, host name, events, and security groups. When enabling the Metadata Service on AWS EC2 instances, users have the option of using either Instance Metadata Service Version 1 (IMDSv1; a request/response method) or Instance Metadata Service Version 2 (IMDSv2; a session-oriented method). With IMDSv2, every request is now protected by session authentication. A session begins and ends a series of requests that software running on an EC2 instance uses to access the locally-stored EC2 instance metadata and credentials. Allowing Version 1 of the service may open EC2 instances to Server-Side Request Forgery (SSRF) attacks, so Amazon recommends utilizing Version 2 for better instance security.","RemediationProcedure": "From Console: 1. Sign in to the AWS Management Console and navigate to the EC2 dashboard at https://console.aws.amazon.com/ec2/. 2. In the left navigation panel, under the INSTANCES section, choose Instances. 3. Select the EC2 instance that you want to examine. 4. Choose Actions > Instance Settings > Modify instance metadata options. 5. Ensure Instance metadata service is set to Enable and set IMDSv2 to Required. 6. Repeat steps no. 1 – 5 to perform the remediation process for other EC2 Instances in the all applicable AWS region(s). From Command Line: 1. Run the describe-instances command using appropriate filtering to list the IDs of all the existing EC2 instances currently available in the selected region: aws ec2 describe-instances --region  --output table -- query 'Reservations[*].Instances[*].InstanceId' 2. The command output should return a table with the requested instance IDs. 3. Now run the modify-instance-metadata-options command using an instance ID returned at the previous step to update the Instance Metadata Version: aws ec2 modify-instance-metadata-options --instance-id  --http-tokens required --region  4. Repeat steps no. 1 – 3 to perform the remediation process for other EC2 Instances in the same AWS region. 5. Change the region by updating --region and repeat the entire process for other regions.","AdditionalInformation": ""}],"description": "Ensure that EC2 Metadata Service only allows IMDSv2","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.10": {"name": "1.10","checks": {"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://tools.ietf.org/html/rfc6238:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#enable-mfa-for-privileged-users:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html:https://blogs.aws.amazon.com/security/post/Tx2SJJYE082KBUK/How-to-Delegate-Management-of-Multi-Factor-Authentication-to-AWS-IAM-Users","Description": "Multi-Factor Authentication (MFA) adds an extra layer of authentication assurance beyond traditional credentials. With MFA enabled, when a user signs in to the AWS Console, they will be prompted for their user name and password as well as for an authentication code from their physical or virtual MFA token. It is recommended that MFA be enabled for all accounts that have a console password.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if a MFA device is enabled for all IAM users having a console password:**From Console:**1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the left pane, select `Users`3. If the `MFA` or `Password age` columns are not visible in the table, click the gear icon at the upper right corner of the table and ensure a checkmark is next to both, then click `Close`. 4. Ensure that for each user where the `Password age` column shows a password age, the `MFA` column shows `Virtual`, `U2F Security Key`, or `Hardware`.**From Command Line:**1. Run the following command (OSX/Linux/UNIX) to generate a list of all IAM users along with their password and MFA status: ```aws iam generate-credential-report ``` ```aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,8``` 2. The output of this command will produce a table similar to the following: ```user,password_enabled,mfa_activeelise,false,falsebrandon,true,truerakesh,false,falsehelene,false,falseparas,true,trueanitha,false,false``` 3. For any column having `password_enabled` set to `true` , ensure `mfa_active` is also set to `true.`","ImpactStatement": "AWS will soon end support for SMS multi-factor authentication (MFA). New customers are not allowed to use this feature. We recommend that existing customers switch to one of the following alternative methods of MFA.","AssessmentStatus": "Automated","RationaleStatement": "Enabling MFA provides increased security for console access as it requires the authenticating principal to possess a device that displays a time-sensitive key and have knowledge of a credential.","RemediationProcedure": "Perform the following to enable MFA:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at 'https://console.aws.amazon.com/iam/' 2. In the left pane, select `Users`. 3. In the `User Name` list, choose the name of the intended MFA user. 4. Choose the `Security Credentials` tab, and then choose `Manage MFA Device`. 5. In the `Manage MFA Device wizard`, choose `Virtual MFA` device, and then choose `Continue`. IAM generates and displays configuration information for the virtual MFA device, including a QR code graphic. The graphic is a representation of the 'secret configuration key' that is available for manual entry on devices that do not support QR codes.6. Open your virtual MFA application. (For a list of apps that you can use for hosting virtual MFA devices, see Virtual MFA Applications at https://aws.amazon.com/iam/details/mfa/#Virtual_MFA_Applications). If the virtual MFA application supports multiple accounts (multiple virtual MFA devices), choose the option to create a new account (a new virtual MFA device). 7. Determine whether the MFA app supports QR codes, and then do one of the following: - Use the app to scan the QR code. For example, you might choose the camera icon or choose an option similar to Scan code, and then use the device's camera to scan the code.- In the Manage MFA Device wizard, choose Show secret key for manual configuration, and then type the secret configuration key into your MFA application. When you are finished, the virtual MFA device starts generating one-time passwords.8. In the `Manage MFA Device wizard`, in the `MFA Code 1 box`, type the `one-time password` that currently appears in the virtual MFA device. Wait up to 30 seconds for the device to generate a new one-time password. Then type the second `one-time password` into the `MFA Code 2 box`.9. Click `Assign MFA`.","AdditionalInformation": "**Forced IAM User Self-Service Remediation**Amazon has published a pattern that forces users to self-service setup MFA before they have access to their complete permissions set. Until they complete this step, they cannot access their full permissions. This pattern can be used on new AWS accounts. It can also be used on existing accounts - it is recommended users are given instructions and a grace period to accomplish MFA enrollment before active enforcement on existing AWS accounts."}],"description": "Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.11": {"name": "1.11","checks": {"iam_user_no_setup_initial_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/cli/latest/reference/iam/delete-access-key.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html","Description": "AWS console defaults to no check boxes selected when creating a new IAM user. When cerating the IAM User credentials you have to determine what type of access they require. Programmatic access: The IAM user might need to make API calls, use the AWS CLI, or use the Tools for Windows PowerShell. In that case, create an access key (access key ID and a secret access key) for that user. AWS Management Console access: If the user needs to access the AWS Management Console, create a password for the user.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if access keys were created upon user creation and are being used and rotated as prescribed:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on a User where column `Password age` and `Access key age` is not set to `None` 5. Click on `Security credentials` Tab 6. Compare the user 'Creation time` to the Access Key `Created` date. 6. For any that match, the key was created during initial user setup.- Keys that were created at the same time as the user profile and do not have a last used date should be deleted. Refer to the remediation below.**From Command Line:**1. Run the following command (OSX/Linux/UNIX) to generate a list of all IAM users along with their access keys utilization: ```aws iam generate-credential-report ``` ```aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,9,11,14,16 ``` 2. The output of this command will produce a table similar to the following: ``` user,password_enabled,access_key_1_active,access_key_1_last_used_date,access_key_2_active,access_key_2_last_used_dateelise,false,true,2015-04-16T15:14:00+00:00,false,N/Abrandon,true,true,N/A,false,N/Arakesh,false,false,N/A,false,N/Ahelene,false,true,2015-11-18T17:47:00+00:00,false,N/Aparas,true,true,2016-08-28T12:04:00+00:00,true,2016-03-04T10:11:00+00:00anitha,true,true,2016-06-08T11:43:00+00:00,true,N/A``` 3. For any user having `password_enabled` set to `true` AND `access_key_last_used_date` set to `N/A` refer to the remediation below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Requiring the additional steps be taken by the user for programmatic access after their profile has been created will give a stronger indication of intent that access keys are [a] necessary for their work and [b] once the access key is established on an account that the keys may be in use somewhere in the organization.**Note**: Even if it is known the user will need access keys, require them to create the keys themselves or put in a support ticket to have them created as a separate step from user creation.","RemediationProcedure": "Perform the following to delete access keys that do not pass the audit:**From Console:**1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. As an Administrator - Click on the X `(Delete)` for keys that were created at the same time as the user profile but have not been used. 7. As an IAM User- Click on the X `(Delete)` for keys that were created at the same time as the user profile but have not been used.**From Command Line:** ``` aws iam delete-access-key --access-key-id  --user-name  ```","AdditionalInformation": "Credential report does not appear to contain \"Key Creation Date\""}],"description": "Do not setup access keys during initial user setup for all IAM users that have a console password","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.12": {"name": "1.12","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#remove-credentials:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_admin-change-user.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "AWS IAM users can access AWS resources using different types of credentials, such as passwords or access keys. It is recommended that all credentials that have been unused in 45 or greater days be deactivated or removed.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if unused credentials exist:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM` 4. Click on `Users` 5. Click the `Settings` (gear) icon. 6. Select `Console last sign-in`, `Access key last used`, and `Access Key Id` 7. Click on `Close`8. Check and ensure that `Console last sign-in` is less than 45 days ago.**Note** - `Never` means the user has never logged in.9. Check and ensure that `Access key age` is less than 45 days and that `Access key last used` does not say `None`If the user hasn't signed into the Console in the last 45 days or Access keys are over 45 days old refer to the remediation.**From Command Line:****Download Credential Report:**1. Run the following commands: ```aws iam generate-credential-report aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,5,6,9,10,11,14,15,16 | grep -v '^' ```**Ensure unused credentials do not exist:**2. For each user having `password_enabled` set to `TRUE` , ensure `password_last_used_date` is less than `45` days ago.- When `password_enabled` is set to `TRUE` and `password_last_used` is set to `No_Information` , ensure `password_last_changed` is less than 45 days ago.3. For each user having an `access_key_1_active` or `access_key_2_active` to `TRUE` , ensure the corresponding `access_key_n_last_used_date` is less than `45` days ago.- When a user having an `access_key_x_active` (where x is 1 or 2) to `TRUE` and corresponding access_key_x_last_used_date is set to `N/A', ensure `access_key_x_last_rotated` is less than 45 days ago.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Disabling or removing unnecessary credentials will reduce the window of opportunity for credentials associated with a compromised or abandoned account to be used.","RemediationProcedure": "**From Console:**Perform the following to manage Unused Password (IAM user console access)1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. Select user whose `Console last sign-in` is greater than 45 days 7. Click `Security credentials` 8. In section `Sign-in credentials`, `Console password` click `Manage`9. Under Console Access select `Disable` 10.Click `Apply`Perform the following to deactivate Access Keys:1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. Select any access keys that are over 45 days old and that have been used and - Click on `Make Inactive` 7. Select any access keys that are over 45 days old and that have not been used and - Click the X to `Delete`","AdditionalInformation": " is excluded in the audit since the root account should not be used for day to day business and would likely be unused for more than 45 days."}],"description": "Ensure credentials unused for 45 days or greater are disabled","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1.13": {"name": "1.13","checks": {"iam_user_two_active_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html","Description": "Access keys are long-term credentials for an IAM user or the AWS account 'root' user. You can use access keys to sign programmatic requests to the AWS CLI or AWS API (directly or using the AWS SDK)","DefaultValue": null,"AuditProcedure": "**From Console:**1. Sign in to the AWS Management Console and navigate to IAM dashboard at `https://console.aws.amazon.com/iam/`. 2. In the left navigation panel, choose `Users`. 3. Click on the IAM user name that you want to examine. 4. On the IAM user configuration page, select `Security Credentials` tab. 5. Under `Access Keys` section, in the Status column, check the current status for each access key associated with the IAM user. If the selected IAM user has more than one access key activated then the users access configuration does not adhere to security best practices and the risk of accidental exposures increases. - Repeat steps no. 3 – 5 for each IAM user in your AWS account.**From Command Line:**1. Run `list-users` command to list all IAM users within your account: ``` aws iam list-users --query \"Users[*].UserName\" ``` The command output should return an array that contains all your IAM user names.2. Run `list-access-keys` command using the IAM user name list to return the current status of each access key associated with the selected IAM user: ``` aws iam list-access-keys --user-name  ``` The command output should expose the metadata `(\"Username\", \"AccessKeyId\", \"Status\", \"CreateDate\")` for each access key on that user account.3. Check the `Status` property value for each key returned to determine each keys current state. If the `Status` property value for more than one IAM access key is set to `Active`, the user access configuration does not adhere to this recommendation, refer to the remediation below.- Repeat steps no. 2 and 3 for each IAM user in your AWS account.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Access keys are long-term credentials for an IAM user or the AWS account 'root' user. You can use access keys to sign programmatic requests to the AWS CLI or AWS API. One of the best ways to protect your account is to not allow users to have multiple access keys.","RemediationProcedure": "**From Console:**1. Sign in to the AWS Management Console and navigate to IAM dashboard at `https://console.aws.amazon.com/iam/`. 2. In the left navigation panel, choose `Users`. 3. Click on the IAM user name that you want to examine. 4. On the IAM user configuration page, select `Security Credentials` tab. 5. In `Access Keys` section, choose one access key that is less than 90 days old. This should be the only active key used by this IAM user to access AWS resources programmatically. Test your application(s) to make sure that the chosen access key is working. 6. In the same `Access Keys` section, identify your non-operational access keys (other than the chosen one) and deactivate it by clicking the `Make Inactive` link. 7. If you receive the `Change Key Status` confirmation box, click `Deactivate` to switch off the selected key. 8. Repeat steps no. 3 – 7 for each IAM user in your AWS account.**From Command Line:**1. Using the IAM user and access key information provided in the `Audit CLI`, choose one access key that is less than 90 days old. This should be the only active key used by this IAM user to access AWS resources programmatically. Test your application(s) to make sure that the chosen access key is working.2. Run the `update-access-key` command below using the IAM user name and the non-operational access key IDs to deactivate the unnecessary key(s). Refer to the Audit section to identify the unnecessary access key ID for the selected IAM user**Note** - the command does not return any output: ``` aws iam update-access-key --access-key-id  --status Inactive --user-name  ``` 3. To confirm that the selected access key pair has been successfully `deactivated` run the `list-access-keys` audit command again for that IAM User: ``` aws iam list-access-keys --user-name  ``` - The command output should expose the metadata for each access key associated with the IAM user. If the non-operational key pair(s) `Status` is set to `Inactive`, the key has been successfully deactivated and the IAM user access configuration adheres now to this recommendation.4. Repeat steps no. 1 – 3 for each IAM user in your AWS account.","AdditionalInformation": ""}],"description": "Ensure there is only one active access key available for any single IAM user","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.14": {"name": "1.14","checks": {"iam_rotate_access_key_90_days": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#rotate-credentials:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html:https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "Access keys consist of an access key ID and secret access key, which are used to sign programmatic requests that you make to AWS. AWS users need their own access keys to make programmatic calls to AWS from the AWS Command Line Interface (AWS CLI), Tools for Windows PowerShell, the AWS SDKs, or direct HTTP calls using the APIs for individual AWS services. It is recommended that all access keys be regularly rotated.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if access keys are rotated as prescribed:**From Console:**1. Go to Management Console (https://console.aws.amazon.com/iam) 2. Click on `Users` 3. Click `setting` icon 4. Select `Console last sign-in` 5. Click `Close` 6. Ensure that `Access key age` is less than 90 days ago. note) `None` in the `Access key age` means the user has not used the access key.**From Command Line:**``` aws iam generate-credential-report aws iam get-credential-report --query 'Content' --output text | base64 -d ``` The `access_key_1_last_rotated` field in this file notes The date and time, in ISO 8601 date-time format, when the user's access key was created or last changed. If the user does not have an active access key, the value in this field is N/A (not applicable).","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Rotating access keys will reduce the window of opportunity for an access key that is associated with a compromised or terminated account to be used.Access keys should be rotated to ensure that data cannot be accessed with an old key which might have been lost, cracked, or stolen.","RemediationProcedure": "Perform the following to rotate access keys:**From Console:**1. Go to Management Console (https://console.aws.amazon.com/iam) 2. Click on `Users` 3. Click on `Security Credentials`4. As an Administrator - Click on `Make Inactive` for keys that have not been rotated in `90` Days 5. As an IAM User- Click on `Make Inactive` or `Delete` for keys which have not been rotated or used in `90` Days 6. Click on `Create Access Key`7. Update programmatic call with new Access Key credentials**From Command Line:**1. While the first access key is still active, create a second access key, which is active by default. Run the following command: ``` aws iam create-access-key ```At this point, the user has two active access keys.2. Update all applications and tools to use the new access key. 3. Determine whether the first access key is still in use by using this command: ``` aws iam get-access-key-last-used ``` 4. One approach is to wait several days and then check the old access key for any use before proceeding.Even if step Step 3 indicates no use of the old key, it is recommended that you do not immediately delete the first access key. Instead, change the state of the first access key to Inactive using this command: ``` aws iam update-access-key ``` 5. Use only the new access key to confirm that your applications are working. Any applications and tools that still use the original access key will stop working at this point because they no longer have access to AWS resources. If you find such an application or tool, you can switch its state back to Active to reenable the first access key. Then return to step Step 2 and update this application to use the new key.6. After you wait some period of time to ensure that all applications and tools have been updated, you can delete the first access key with this command: ``` aws iam delete-access-key ```","AdditionalInformation": ""}],"description": "Ensure access keys are rotated every 90 days or less","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.15": {"name": "1.15","checks": {"iam_policy_attached_only_to_group_or_roles": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html","Description": "IAM users are granted access to services, functions, and data through IAM policies. There are three ways to define policies for a user: 1) Edit the user policy directly, aka an inline, or user, policy; 2) attach a policy directly to a user; 3) add the user to an IAM group that has an attached policy. Only the third implementation is recommended.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if an inline policy is set or a policy is directly attached to users:1. Run the following to get a list of IAM users: ```aws iam list-users --query 'Users[*].UserName' --output text``` 2. For each user returned, run the following command to determine if any policies are attached to them: ```aws iam list-attached-user-policies --user-name aws iam list-user-policies --user-name ``` 3. If any policies are returned, the user has an inline policy or direct policy attachment.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Assigning IAM policy only through groups unifies permissions management to a single, flexible layer consistent with organizational functional roles. By unifying permissions management, the likelihood of excessive permissions is reduced.","RemediationProcedure": "Perform the following to create an IAM group and assign a policy to it:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click `Groups` and then click `Create New Group` . 3. In the `Group Name` box, type the name of the group and then click `Next Step` . 4. In the list of policies, select the check box for each policy that you want to apply to all members of the group. Then click `Next Step` . 5. Click `Create Group` Perform the following to add a user to a given group:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click `Groups`3. Select the group to add a user to 4. Click `Add Users To Group`5. Select the users to be added to the group 6. Click `Add Users` Perform the following to remove a direct association between a user and policy:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the left navigation pane, click on Users 3. For each user:- Select the user- Click on the `Permissions` tab- Expand `Permissions policies` - Click `X` for each policy; then click Detach or Remove (depending on policy type)","AdditionalInformation": ""}],"description": "Ensure IAM Users Receive Permissions Only Through Groups","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.16": {"name": "1.16","checks": {"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html:https://docs.aws.amazon.com/cli/latest/reference/iam/index.html#cli-aws-iam","Description": "IAM policies are the means by which privileges are granted to users, groups, or roles. It is recommended and considered a standard security advice to grant _least privilege_ -that is, granting only the permissions required to perform a task. Determine what users need to do and then craft policies for them that let the users perform _only_ those tasks, instead of allowing full administrative privileges.","DefaultValue": null,"AuditProcedure": "Perform the following to determine what policies are created:**From Command Line:**1. Run the following to get a list of IAM policies: ```aws iam list-policies --only-attached --output text ``` 2. For each policy returned, run the following command to determine if any policies is allowing full administrative privileges on the account: ```aws iam get-policy-version --policy-arn  --version-id  ``` 3. In output ensure policy should not have any Statement block with `\"Effect\": \"Allow\"` and `Action` set to `\"*\"` and `Resource` set to `\"*\"`","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "It's more secure to start with a minimum set of permissions and grant additional permissions as necessary, rather than starting with permissions that are too lenient and then trying to tighten them later.Providing full administrative privileges instead of restricting to the minimum set of permissions that the user is required to do exposes the resources to potentially unwanted actions.IAM policies that have a statement with \"Effect\": \"Allow\" with \"Action\": \"\\*\" over \"Resource\": \"\\*\" should be removed.","RemediationProcedure": "From Console: Perform the following to detach the policy that has full administrative privileges: 1. Sign in to the AWS Management Console and open the IAM console at https://console.aws.amazon.com/iam/. 2. In the navigation pane, click Policies and then search for the policy name found in the audit step. 3. Select the policy that needs to be deleted. 4. In the policy action menu, select first Detach 5. Select all Users, Groups, Roles that have this policy attached 6. Click Detach Policy 7. In the policy action menu, select Detach 8. Select the newly detached policy and select Delete From Command Line: Perform the following to detach the policy that has full administrative privileges as found in the audit step: 1. Lists all IAM users, groups, and roles that the specified managed policy is attached to. aws iam list-entities-for-policy --policy-arn  2. Detach the policy from all IAM Users: aws iam detach-user-policy --user-name  --policy-arn  3. Detach the policy from all IAM Groups: aws iam detach-group-policy --group-name  --policy-arn  4. Detach the policy from all IAM Roles: aws iam detach-role-policy --role-name  --policy-arn ","AdditionalInformation": ""}],"description": "Ensure IAM policies that allow full \"*:*\" administrative privileges are not attached","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1.17": {"name": "1.17","checks": {"iam_support_role_created": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html:https://aws.amazon.com/premiumsupport/pricing/:https://docs.aws.amazon.com/cli/latest/reference/iam/list-policies.html:https://docs.aws.amazon.com/cli/latest/reference/iam/attach-role-policy.html:https://docs.aws.amazon.com/cli/latest/reference/iam/list-entities-for-policy.html","Description": "AWS provides a support center that can be used for incident notification and response, as well as technical support and customer services. Create an IAM Role to allow authorized users to manage incidents with AWS Support.","DefaultValue": null,"AuditProcedure": "**From Command Line:**1. List IAM policies, filter for the 'AWSSupportAccess' managed policy, and note the \"Arn\" element value: ``` aws iam list-policies --query \"Policies[?PolicyName == 'AWSSupportAccess']\" ``` 2. Check if the 'AWSSupportAccess' policy is attached to any role:``` aws iam list-entities-for-policy --policy-arn arn:aws:iam::aws:policy/AWSSupportAccess ```3. In Output, Ensure `PolicyRoles` does not return empty. 'Example: Example: PolicyRoles: [ ]'If it returns empty refer to the remediation below.","ImpactStatement": "All AWS Support plans include an unlimited number of account and billing supportcases, with no long-term contracts. Support billing calculations are performed on a per-account basis for all plans. Enterprise Support plan customers have the option toinclude multiple enabled accounts in an aggregated monthly billing calculation. Monthlycharges for the Business and Enterprise support plans are based on each month's AWSusage charges, subject to a monthly minimum, billed in advance.When assigning rights, keep in mind that other policies may grant access to Support aswell. This may include AdministratorAccess and other policies including customermanaged policies. Utilizing the AWS managed 'AWSSupportAccess' role is one simpleway of ensuring that this permission is properly granted.To better support the principle of separation of duties, it would be best to only attach thisrole where necessary.","AssessmentStatus": "Automated","RationaleStatement": "By implementing least privilege for access control, an IAM Role will require an appropriate IAM Policy to allow Support Center Access in order to manage Incidents with AWS Support.","RemediationProcedure": "**From Command Line:**1. Create an IAM role for managing incidents with AWS:- Create a trust relationship policy document that allows  to manage AWS incidents, and save it locally as /tmp/TrustPolicy.json: ```{\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"\"},\"Action\": \"sts:AssumeRole\"}]} ``` 2. Create the IAM role using the above trust policy: ``` aws iam create-role --role-name  --assume-role-policy-document file:///tmp/TrustPolicy.json ``` 3. Attach 'AWSSupportAccess' managed policy to the created IAM role: ``` aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AWSSupportAccess --role-name  ```","AdditionalInformation": "AWSSupportAccess policy is a global AWS resource. It has same ARN as `arn:aws:iam::aws:policy/AWSSupportAccess` for every account."}],"description": "Ensure a support role has been created to manage incidents with AWS Support","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.18": {"name": "1.18","checks": {"ec2_instance_profile_attached": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html","Description": "AWS access from within AWS instances can be done by either encoding AWS keys into AWS API calls or by assigning the instance to a role which has an appropriate permissions policy for the required access. \"AWS Access\" means accessing the APIs of AWS in order to access AWS resources or manage AWS account resources.","DefaultValue": null,"AuditProcedure": "Where an instance is associated with a Role:For instances that are known to perform AWS actions, ensure that they belong to an instance role that has the necessary permissions:1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Open the EC2 Dashboard and choose \"Instances\" 3. Click the EC2 instance that performs AWS actions, in the lower pane details find \"IAM Role\" 4. If the Role is blank, the instance is not assigned to one. 5. If the Role is filled in, it does not mean the instance might not \\*also\\* have credentials encoded on it for some activities.Where an Instance Contains Embedded Credentials:- On the instance that is known to perform AWS actions, audit all scripts and environment variables to ensure that none of them contain AWS credentials.Where an Instance Application Contains Embedded Credentials:- Applications that run on an instance may also have credentials embedded. This is a bad practice, but even worse if the source code is stored in a public code repository such as github. When an application contains credentials can be determined by eliminating all other sources of credentials and if the application can still access AWS resources - it likely contains embedded credentials. Another method is to examine all source code and configuration files of the application.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "AWS IAM roles reduce the risks associated with sharing and rotating credentials that can be used outside of AWS itself. If credentials are compromised, they can be used from outside of the AWS account they give access to. In contrast, in order to leverage role permissions an attacker would need to gain and maintain access to a specific instance to use the privileges associated with it.Additionally, if credentials are encoded into compiled applications or other hard to change mechanisms, then they are even more unlikely to be properly rotated due to service disruption risks. As time goes on, credentials that cannot be rotated are more likely to be known by an increasing number of individuals who no longer work for the organization owning the credentials.","RemediationProcedure": "IAM roles can only be associated at the launch of an instance. To remediate an instance to add it to a role you must create a new instance.If the instance has no external dependencies on its current private ip or public addresses are elastic IPs:1. In AWS IAM create a new role. Assign a permissions policy if needed permissions are already known. 2. In the AWS console launch a new instance with identical settings to the existing instance, and ensure that the newly created role is selected. 3. Shutdown both the existing instance and the new instance. 4. Detach disks from both instances. 5. Attach the existing instance disks to the new instance. 6. Boot the new instance and you should have the same machine, but with the associated role.**Note:** if your environment has dependencies on a dynamically assigned PRIVATE IP address you can create an AMI from the existing instance, destroy the old one and then when launching from the AMI, manually assign the previous private IP address.**Note: **if your environment has dependencies on a dynamically assigned PUBLIC IP address there is not a way ensure the address is retained and assign an instance role. Dependencies on dynamically assigned public IP addresses are a bad practice and, if possible, you may wish to rebuild the instance with a new elastic IP address and make the investment to remediate affected systems while assigning the system to a role.","AdditionalInformation": ""}],"description": "Ensure IAM instance roles are used for AWS resource access from instances","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.19": {"name": "1.19","checks": {"iam_no_expired_server_certificates_stored": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_server-certs.html:https://docs.aws.amazon.com/cli/latest/reference/iam/delete-server-certificate.html","Description": "To enable HTTPS connections to your website or application in AWS, you need an SSL/TLS server certificate. You can use ACM or IAM to store and deploy server certificates.Use IAM as a certificate manager only when you must support HTTPS connections in a region that is not supported by ACM. IAM securely encrypts your private keys and stores the encrypted version in IAM SSL certificate storage. IAM supports deploying server certificates in all regions, but you must obtain your certificate from an external provider for use with AWS. You cannot upload an ACM certificate to IAM. Additionally, you cannot manage your certificates from the IAM Console.","DefaultValue": null,"AuditProcedure": "**From Console:**Getting the certificates expiration information via AWS Management Console is not currently supported.To request information about the SSL/TLS certificates stored in IAM via the AWS API use the Command Line Interface (CLI).**From Command Line:**Run list-server-certificates command to list all the IAM-stored server certificates:``` aws iam list-server-certificates ```The command output should return an array that contains all the SSL/TLS certificates currently stored in IAM and their metadata (name, ID, expiration date, etc):``` {\"ServerCertificateMetadataList\": [{\"ServerCertificateId\": \"EHDGFRW7EJFYTE88D\",\"ServerCertificateName\": \"MyServerCertificate\",\"Expiration\": \"2018-07-10T23:59:59Z\",\"Path\": \"/\",\"Arn\": \"arn:aws:iam::012345678910:server-certificate/MySSLCertificate\",\"UploadDate\": \"2018-06-10T11:56:08Z\"}] } ```Verify the `ServerCertificateName` and `Expiration` parameter value (expiration date) for each SSL/TLS certificate returned by the list-server-certificates command and determine if there are any expired server certificates currently stored in AWS IAM. If so, use the AWS API to remove them.If this command returns: ``` { { \"ServerCertificateMetadataList\": [] } ``` This means that there are no expired certificates, It DOES NOT mean that no certificates exist.","ImpactStatement": "Deleting the certificate could have implications for your application if you are using an expired server certificate with Elastic Load Balancing, CloudFront, etc. One has to make configurations at respective services to ensure there is no interruption in application functionality.","AssessmentStatus": "Automated","RationaleStatement": "Removing expired SSL/TLS certificates eliminates the risk that an invalid certificate will be deployed accidentally to a resource such as AWS Elastic Load Balancer (ELB), which can damage the credibility of the application/website behind the ELB. As a best practice, it is recommended to delete expired certificates.","RemediationProcedure": "**From Console:**Removing expired certificates via AWS Management Console is not currently supported. To delete SSL/TLS certificates stored in IAM via the AWS API use the Command Line Interface (CLI).**From Command Line:**To delete Expired Certificate run following command by replacing  with the name of the certificate to delete:``` aws iam delete-server-certificate --server-certificate-name  ```When the preceding command is successful, it does not return any output.","AdditionalInformation": ""}],"description": "Ensure that all the expired SSL/TLS certificates stored in AWS IAM are removed","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.20": {"name": "1.20","checks": {"accessanalyzer_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-getting-started.html:https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/get-analyzer.html:https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/create-analyzer.html","Description": "Enable IAM Access analyzer for IAM policies about all resources in each region.IAM Access Analyzer is a technology introduced at AWS reinvent 2019. After the Analyzer is enabled in IAM, scan results are displayed on the console showing the accessible resources. Scans show resources that other accounts and federated users can access, such as KMS keys and IAM roles. So the results allow you to determine if an unintended user is allowed, making it easier for administrators to monitor least privileges access. Access Analyzer analyzes only policies that are applied to resources in the same AWS Region.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Open the IAM console at `https://console.aws.amazon.com/iam/` 2. Choose `Access analyzer` 3. Click 'Analyzers' 4. Ensure that at least one analyzer is present 5. Ensure that the `STATUS` is set to `Active` 6. Repeat these step for each active region**From Command Line:**1. Run the following command: ``` aws accessanalyzer list-analyzers | grep status ``` 2. Ensure that at least one Analyzer the `status` is set to `ACTIVE`3. Repeat the steps above for each active region.If an Access analyzer is not listed for each region or the status is not set to active refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "AWS IAM Access Analyzer helps you identify the resources in your organization and accounts, such as Amazon S3 buckets or IAM roles, that are shared with an external entity. This lets you identify unintended access to your resources and data. Access Analyzer identifies resources that are shared with external principals by using logic-based reasoning to analyze the resource-based policies in your AWS environment. IAM Access Analyzer continuously monitors all policies for S3 bucket, IAM roles, KMS(Key Management Service) keys, AWS Lambda functions, and Amazon SQS(Simple Queue Service) queues.","RemediationProcedure": "**From Console:**Perform the following to enable IAM Access analyzer for IAM policies:1. Open the IAM console at `https://console.aws.amazon.com/iam/.` 2. Choose `Access analyzer`. 3. Choose `Create analyzer`. 4. On the `Create analyzer` page, confirm that the `Region` displayed is the Region where you want to enable Access Analyzer. 5. Enter a name for the analyzer. `Optional as it will generate a name for you automatically`. 6. Add any tags that you want to apply to the analyzer. `Optional`.7. Choose `Create Analyzer`. 8. Repeat these step for each active region**From Command Line:**Run the following command: ``` aws accessanalyzer create-analyzer --analyzer-name  --type  ``` Repeat this command above for each active region.**Note:** The IAM Access Analyzer is successfully configured only when the account you use has the necessary permissions.","AdditionalInformation": ""}],"description": "Ensure that IAM Access analyzer is enabled for all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.21": {"name": "1.21","checks": {"iam_check_saml_providers_sts": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "","Description": "In multi-account environments, IAM user centralization facilitates greater user control. User access beyond the initial account is then provided via role assumption. Centralization of users can be accomplished through federation with an external identity provider or through the use of AWS Organizations.","DefaultValue": null,"AuditProcedure": "For multi-account AWS environments with an external identity provider: 1. Determine the master account for identity federation or IAM user management 2. Login to that account through the AWS Management Console 3. Click Services 4. Click IAM 5. Click Identity providers 6. Verify the configuration Then, determine all accounts that should not have local users present. For each account: 1. Determine all accounts that should not have local users present 2. Log into the AWS Management Console 3. Switch role into each identified account 4. Click Services 5. Click IAM 6. Click Users 7. Confirm that no IAM users representing individuals are present For multi-account AWS environments implementing AWS Organizations without an external identity provider: 1. Determine all accounts that should not have local users present 2. Log into the AWS Management Console 3. Switch role into each identified account 4. Click Services 5. Click IAM 6. Click Users 7. Confirm that no IAM users representing individuals are present","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Centralizing IAM user management to a single identity store reduces complexity and thus the likelihood of access management errors.","RemediationProcedure": "The remediation procedure will vary based on the individual organization's implementation of identity federation and/or AWS Organizations with the acceptance criteria that no non-service IAM users, and non-root accounts, are present outside the account providing centralized IAM user management.","AdditionalInformation": ""}],"description": "Ensure IAM users are managed centrally via identity federation or AWS Organizations for multi-account environments","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.22": {"name": "1.22","checks": {},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/cloudshell/latest/userguide/sec-auth-with-identities.html","Description": "AWS CloudShell is a convenient way of running CLI commands against AWS services; a managed IAM policy ('AWSCloudShellFullAccess') provides full access to CloudShell, which allows file upload and download capability between a user's local system and the CloudShell environment. Within the CloudShell environment a user has sudo permissions, and can access the internet. So it is feasible to install file transfer software (for example) and move data from CloudShell to external internet servers.","DefaultValue": null,"AuditProcedure": "**From Console** 1. Open the IAM console at https://console.aws.amazon.com/iam/2. In the left pane, select Policies3. Search for and select AWSCloudShellFullAccess4. On the Entities attached tab, ensure that there are no entities using this policy **From Command Line**1. List IAM policies, filter for the 'AWSCloudShellFullAccess' managed policy, and note the \"\"Arn\"\" element value:```aws iam list-policies --query \"\"Policies[?PolicyName == 'AWSCloudShellFullAccess']\"\"``` 2. Check if the 'AWSCloudShellFullAccess' policy is attached to any role: ```aws iam list-entities-for-policy --policy-arn arn:aws:iam::aws:policy/AWSCloudShellFullAccess```3. In Output, Ensure PolicyRoles returns empty. 'Example: Example: PolicyRoles: [ ]'If it does not return empty refer to the remediation below.Note: Keep in mind that other policies may grant access.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Access to this policy should be restricted as it presents a potential channel for data exfiltration by malicious cloud admins that are given full permissions to the service. AWS documentation describes how to create a more restrictive IAM policy which denies file transfer permissions.","RemediationProcedure": "**From Console**1. Open the IAM console at https://console.aws.amazon.com/iam/2. In the left pane, select Policies 3. Search for and select AWSCloudShellFullAccess4. On the Entities attached tab, for each item, check the box and select Detach","AdditionalInformation": ""}],"description": "Ensure access to AWSCloudShellFullAccess is restricted","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"4.10": {"name": "4.10","checks": {"cloudwatch_log_metric_filter_security_group_changes": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Security Groups are a stateful packet filter that controls ingress and egress traffic within a VPC. It is recommended that a metric filter and alarm be established for detecting changes to Security Groups.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query \"MetricAlarms[?MetricName== '']\" ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to security group will help ensure that resources and services are not unintentionally exposed.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for security groups changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name \"\" --filter-name \"\" --metric-transformations metricName= \"\" ,metricNamespace=\"CISBenchmark\",metricValue=1 --filter-pattern \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\" ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name \"\" ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn \"\" --protocol  --notification-endpoint \"\" ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name \"\" --metric-name \"\" --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace \"CISBenchmark\" --alarm-actions \"\" ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for security group changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.11": {"name": "4.11","checks": {"cloudwatch_changes_to_network_acls_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. NACLs are used as a stateless packet filter to control ingress and egress traffic for subnets within a VPC. It is recommended that a metric filter and alarm be established for changes made to NACLs.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to NACLs will help ensure that AWS resources and services are not unintentionally exposed.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for NACL changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL)","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.12": {"name": "4.12","checks": {"cloudwatch_changes_to_network_gateways_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Network gateways are required to send/receive traffic to a destination outside of a VPC. It is recommended that a metric filter and alarm be established for changes to network gateways.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to network gateways will help ensure that all ingress/egress traffic traverses the VPC border via a controlled path.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for network gateways changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for changes to network gateways","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.13": {"name": "4.13","checks": {"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Routing tables are used to route network traffic between subnets and to network gateways. It is recommended that a metric filter and alarm be established for changes to route tables.","DefaultValue": null,"AuditProcedure": "If you are using CloudTrails and CloudWatch , perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarmsconfigured:1. Identify the log group name configured for use with active multi-region CloudTrail:• List all CloudTrails: aws cloudtrail describe-trails• Identify Multi region Cloudtrails: Trails with 'IsMultiRegionTrail' set totrue• From value associated with CloudWatchLogsLogGroupArn noteExample: for CloudWatchLogsLogGroupArn that looks likearn:aws:logs:::log-group:NewGroup:*, would be NewGroup• Ensure Identified Multi region CloudTrail is activeaws cloudtrail get-trail-status --name ensure IsLogging is set to TRUE• Ensure identified Multi-region Cloudtrail captures all Management Eventsaws cloudtrail get-event-selectors --trail-name Ensure there is at least one Event Selector for a Trail with IncludeManagementEvents setto true and ReadWriteType set to All2. Get a list of all associated metric filters for this :aws logs describe-metric-filters --log-group-name''3. Ensure the output from the above command contains the following:'filterPattern': '{($.eventSource = ec2.amazonaws.com) && ($.eventName =CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName =ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName= DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName =DisassociateRouteTable) }'4. Note the  value associated with thefilterPattern found in step 3.5. Get a list of CloudWatch alarms and filter on the captured in step 4.aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName==``]'6. Note the AlarmActions value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topicaws sns list-subscriptions-by-topic --topic-arn at least one subscription should have 'SubscriptionArn' with valid aws ARN.Example of valid 'SubscriptionArn':'arn:aws:sns::::'","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "CloudWatch is an AWS native service that allows you to observe and monitor resources and applications. CloudTrail Logs can also be sent to an external Security informationand event management (SIEM) environment for monitoring and alerting.Monitoring changes to route tables will help ensure that all VPC traffic flows through anexpected path and prevent any accidental or intentional modifications that may lead touncontrolled network traffic. An alarm should be triggered every time an AWS API call isperformed to create, replace, delete, or disassociate a Route Table.","RemediationProcedure": "If you are using CloudTrails and CloudWatch, perform the following to setup the metric filter, alarm, SNS topic, and subscription: 1. Create a metric filter based on filter pattern provided which checks for route table changes and the  taken from audit step 1. aws logs put-metric-filter --log-group-name  -- filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }' Note: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together. 2. Create an SNS topic that the alarm will notify aws sns create-topic --name  Note: you can execute this command once and then re-use the same topic for all monitoring alarms. 3. Create an SNS subscription to the topic created in step 2 aws sns subscribe --topic-arn  --protocol  - -notification-endpoint  Note: you can execute this command once and then re-use the SNS subscription for all monitoring alarms. 4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 - -threshold 1 --comparison-operator GreaterThanOrEqualToThreshold -- evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions ","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure route table changes are monitored","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.14": {"name": "4.14","checks": {"cloudwatch_changes_to_vpcs_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is possible to have more than 1 VPC within an account, in addition it is also possible to create a peer connection between 2 VPCs enabling network traffic to route between VPCs. It is recommended that a metric filter and alarm be established for changes made to VPCs.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to VPC will help ensure VPC traffic flow is not getting impacted.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for VPC changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for VPC changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.15": {"name": "4.15","checks": {"cloudwatch_log_metric_filter_aws_organizations_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/organizations/latest/userguide/orgs_security_incident-response.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for AWS Organizations changes made in the master AWS Account.","DefaultValue": null,"AuditProcedure": "1. Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured: - Identify the log group name configured for use with active multi-region CloudTrail: - List all CloudTrails:``` aws cloudtrail describe-trails ``` - Identify Multi region Cloudtrails, Trails with `\"IsMultiRegionTrail\"` set to true - From value associated with CloudWatchLogsLogGroupArn note **Example:** for CloudWatchLogsLogGroupArn that looks like arn:aws:logs:::log-group:NewGroup:*,  would be NewGroup- Ensure Identified Multi region CloudTrail is active: ``` aws cloudtrail get-trail-status --name  ``` Ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events: ``` aws cloudtrail get-event-selectors --trail-name  ``` - Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to true and `ReadWriteType` set to `All`.2. Get a list of all associated metric filters for this : ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdatePolicy\") || ($.eventName = \"UpdateOrganizationalUnit\")) }\" ``` 4. Note the `` value associated with the filterPattern found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4: ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the AlarmActions value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic: ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. Example of valid \"SubscriptionArn\":``` \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring AWS Organizations changes can help you prevent any unwanted, accidental or intentional modifications that may lead to unauthorized access or other security breaches. This monitoring technique helps you to ensure that any unexpected changes performed within your AWS Organizations can be investigated and any unwanted changes can be rolled back.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Organizations changes and the `` taken from audit step 1: ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdatePolicy\") || ($.eventName = \"UpdateOrganizationalUnit\")) }' ``` **Note:** You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify: ``` aws sns create-topic --name  ``` **Note:** you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2: ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note:** you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2: ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": ""}],"description": "Ensure a log metric filter and alarm exists for AWS Organizations changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.16": {"name": "4.16","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-get-started.html:https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-enable.html#securityhub-enable-api:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/securityhub/enable-security-hub.html","Description": "Security Hub collects security data from across AWS accounts, services, and supported third-party partner products and helps you analyze your security trends and identify the highest priority security issues. When you enable Security Hub, it begins to consume, aggregate, organize, and prioritize findings from AWS services that you have enabled, such as Amazon GuardDuty, Amazon Inspector, and Amazon Macie. You can also enable integrations with AWS partner security products.","DefaultValue": null,"AuditProcedure": "The process to evaluate AWS Security Hub configuration per region **From Console:**1. Sign in to the AWS Management Console and open the AWS Security Hub console at https://console.aws.amazon.com/securityhub/. 2. On the top right of the console, select the target Region. 3. If presented with the Security Hub > Summary page then Security Hub is set-up for the selected region. 4. If presented with Setup Security Hub or Get Started With Security Hub - follow the online instructions. 5. Repeat steps 2 to 4 for each region.","ImpactStatement": "It is recommended AWS Security Hub be enabled in all regions. AWS Security Hub requires AWS Config to be enabled.","AssessmentStatus": "Automated","RationaleStatement": "AWS Security Hub provides you with a comprehensive view of your security state in AWS and helps you check your environment against security industry standards and best practices - enabling you to quickly assess the security posture across your AWS accounts.","RemediationProcedure": "To grant the permissions required to enable Security Hub, attach the Security Hub managed policy AWSSecurityHubFullAccess to an IAM user, group, or role.Enabling Security Hub**From Console:**1. Use the credentials of the IAM identity to sign in to the Security Hub console. 2. When you open the Security Hub console for the first time, choose Enable AWS Security Hub. 3. On the welcome page, Security standards list the security standards that Security Hub supports. 4. Choose Enable Security Hub.**From Command Line:**1. Run the enable-security-hub command. To enable the default standards, include `--enable-default-standards`. ``` aws securityhub enable-security-hub --enable-default-standards ```2. To enable the security hub without the default standards, include `--no-enable-default-standards`. ``` aws securityhub enable-security-hub --no-enable-default-standards ```","AdditionalInformation": ""}],"description": "Ensure AWS Security Hub is enabled","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.1": {"name": "2.1.1","checks": {"s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-policy-for-config-rule/:https://aws.amazon.com/blogs/security/how-to-use-bucket-policies-and-apply-defense-in-depth-to-help-secure-your-amazon-s3-data/:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-bucket-policy.html","Description": "At the Amazon S3 bucket level, you can configure permissions through a bucket policy making the objects accessible only through HTTPS.","DefaultValue": null,"AuditProcedure": "To allow access to HTTPS you can use a condition that checks for the key `\"aws:SecureTransport: true\"`. This means that the request is sent through HTTPS but that HTTP can still be used. So to make sure you do not allow HTTP access confirm that there is a bucket policy that explicitly denies access for HTTP requests and that it contains the key \"aws:SecureTransport\": \"false\".**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/ 2. Select the Check box next to the Bucket. 3. Click on 'Permissions', then Click on `Bucket Policy`. 4. Ensure that a policy is listed that matches: ``` '{\"Sid\": ,\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}' ``` `` and `` will be specific to your account5. Repeat for all the buckets in your AWS account.**From Command Line:**1. List all of the S3 Buckets``` aws s3 ls ``` 2. Using the list of buckets run this command on each of them: ``` aws s3api get-bucket-policy --bucket  | grep aws:SecureTransport ``` 3. Confirm that `aws:SecureTransport` is set to false `aws:SecureTransport:false` 4. Confirm that the policy line has Effect set to Deny 'Effect:Deny'","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "By default, Amazon S3 allows both HTTP and HTTPS requests. To achieve only allowing access to Amazon S3 objects through HTTPS you also have to explicitly deny access to HTTP requests. Bucket policies that allow HTTPS requests without explicitly denying HTTP requests will not comply with this recommendation.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/ 2. Select the Check box next to the Bucket. 3. Click on 'Permissions'. 4. Click 'Bucket Policy' 5. Add this to the existing policy filling in the required information ``` {\"Sid\": \",\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}}} ``` 6. Save 7. Repeat for all the buckets in your AWS account that contain sensitive data.**From Console** using AWS Policy Generator:1. Repeat steps 1-4 above. 2. Click on `Policy Generator` at the bottom of the Bucket Policy Editor 3. Select Policy Type `S3 Bucket Policy` 4. Add Statements - `Effect` = Deny - `Principal` = * - `AWS Service` = Amazon S3 - `Actions` = * - `Amazon Resource Name` =  5. Generate Policy 6. Copy the text and add it to the Bucket Policy.**From Command Line:**1. Export the bucket policy to a json file. ``` aws s3api get-bucket-policy --bucket  --query Policy --output text > policy.json ```2. Modify the policy.json file by adding in this statement: ``` {\"Sid\": \",\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}}} ``` 3. Apply this modified policy back to the S3 bucket: ``` aws s3api put-bucket-policy --bucket  --policy file://policy.json ```","AdditionalInformation": ""}],"description": "Ensure S3 Bucket Policy is set to deny HTTP requests","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.1.2": {"name": "2.1.2","checks": {"s3_bucket_no_mfa_delete": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html#MultiFactorAuthenticationDelete:https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMFADelete.html:https://aws.amazon.com/blogs/security/securing-access-to-aws-using-mfa-part-3/:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_lost-or-broken.html","Description": "Once MFA Delete is enabled on your sensitive and classified S3 bucket it requires the user to have two forms of authentication.","DefaultValue": null,"AuditProcedure": "Perform the steps below to confirm MFA delete is configured on an S3 Bucket**From Console:**1. Login to the S3 console at `https://console.aws.amazon.com/s3/`2. Click the `Check` box next to the Bucket name you want to confirm3. In the window under `Properties`4. Confirm that Versioning is `Enabled`5. Confirm that MFA Delete is `Enabled`**From Command Line:**1. Run the `get-bucket-versioning` ``` aws s3api get-bucket-versioning --bucket my-bucket ```Output example: ```  EnabledEnabled ```If the Console or the CLI output does not show Versioning and MFA Delete `enabled` refer to the remediation below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Adding MFA delete to an S3 bucket, requires additional authentication when you change the version state of your bucket or you delete and object version adding another layer of security in the event your security credentials are compromised or unauthorized access is granted.","RemediationProcedure": "Perform the steps below to enable MFA delete on an S3 bucket.Note: -You cannot enable MFA Delete using the AWS Management Console. You must use the AWS CLI or API. -You must use your 'root' account to enable MFA Delete on S3 buckets.**From Command line:**1. Run the s3api put-bucket-versioning command``` aws s3api put-bucket-versioning --profile my-root-profile --bucket Bucket_Name --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa ā€œarn:aws:iam::aws_account_id:mfa/root-account-mfa-device passcodeā€ ```","AdditionalInformation": ""}],"description": "Ensure MFA Delete is enabled on S3 buckets","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.1.3": {"name": "2.1.3","checks": {"macie_is_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://aws.amazon.com/macie/getting-started/:https://docs.aws.amazon.com/workspaces/latest/adminguide/data-protection.html:https://docs.aws.amazon.com/macie/latest/user/data-classification.html","Description": "Amazon S3 buckets can contain sensitive data, that for security purposes should be discovered, monitored, classified and protected. Macie along with other 3rd party tools can automatically provide an inventory of Amazon S3 buckets.","DefaultValue": null,"AuditProcedure": "Perform the following steps to determine if Macie is running:**From Console:** 1. Login to the Macie console at https://console.aws.amazon.com/macie/ 2. In the left hand pane click on By job under findings. 3. Confirm that you have a Job setup for your S3 BucketsWhen you log into the Macie console if you aren't taken to the summary page and you don't have a job setup and running then refer to the remediation procedure below.If you are using a 3rd Party tool to manage and protect your s3 data you meet this recommendation.","ImpactStatement": "There is a cost associated with using Amazon Macie. There is also typically a cost associated with 3rd Party tools that perform similar processes and protection.","AssessmentStatus": "Manual","RationaleStatement": "Using a Cloud service or 3rd Party software to continuously monitor and automate the process of data discovery and classification for S3 buckets using machine learning and pattern matching is a strong defense in protecting that information.Amazon Macie is a fully managed data security and data privacy service that uses machine learning and pattern matching to discover and protect your sensitive data in AWS.","RemediationProcedure": "Perform the steps below to enable and configure Amazon Macie**From Console:**1. Log on to the Macie console at `https://console.aws.amazon.com/macie/`2. Click `Get started`.3. Click `Enable Macie`.Setup a repository for sensitive data discovery results1. In the Left pane, under Settings, click `Discovery results`.2. Make sure `Create bucket` is selected.3. Create a bucket, enter a name for the bucket. The name must be unique across all S3 buckets. In addition, the name must start with a lowercase letter or a number.4. Click on `Advanced`.5. Block all public access, make sure `Yes` is selected.6. KMS encryption, specify the AWS KMS key that you want to use to encrypt the results. The key must be a symmetric, customer master key (CMK) that's in the same Region as the S3 bucket.7. Click on `Save`Create a job to discover sensitive data1. In the left pane, click `S3 buckets`. Macie displays a list of all the S3 buckets for your account.2. Select the `check box` for each bucket that you want Macie to analyze as part of the job3. Click `Create job`.3. Click `Quick create`.4. For the Name and description step, enter a name and, optionally, a description of the job.5. Then click `Next`.6. For the Review and create step, click `Submit`.Review your findings1. In the left pane, click `Findings`.2. To view the details of a specific finding, choose any field other than the check box for the finding.If you are using a 3rd Party tool to manage and protect your s3 data, follow the Vendor documentation for implementing and configuring that tool.","AdditionalInformation": ""}],"description": "Ensure all data in Amazon S3 has been discovered, classified and secured when required.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.4": {"name": "2.1.4","checks": {"s3_bucket_level_public_access_block": "PASS","s3_account_level_public_access_blocks": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/block-public-access-account.html","Description": "Amazon S3 provides `Block public access (bucket settings)` and `Block public access (account settings)` to help you manage public access to Amazon S3 resources. By default, S3 buckets and objects are created with public access disabled. However, an IAM principal with sufficient S3 permissions can enable public access at the bucket and/or object level. While enabled, `Block public access (bucket settings)` prevents an individual bucket, and its contained objects, from becoming publicly accessible. Similarly, `Block public access (account settings)` prevents all buckets, and contained objects, from becoming publicly accessible across the entire account.","DefaultValue": null,"AuditProcedure": "**If utilizing Block Public Access (bucket settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select the Check box next to the Bucket. 3. Click on 'Edit public access settings'. 4. Ensure that block public access settings are set appropriately for this bucket 5. Repeat for all the buckets in your AWS account.**From Command Line:**1. List all of the S3 Buckets ``` aws s3 ls ``` 2. Find the public access setting on that bucket ``` aws s3api get-public-access-block --bucket  ``` Output if Block Public access is enabled:``` {\"PublicAccessBlockConfiguration\": {\"BlockPublicAcls\": true,\"IgnorePublicAcls\": true,\"BlockPublicPolicy\": true,\"RestrictPublicBuckets\": true} } ```If the output reads `false` for the separate configuration settings then proceed to the remediation.**If utilizing Block Public Access (account settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Choose `Block public access (account settings)` 3. Ensure that block public access settings are set appropriately for your AWS account.**From Command Line:**To check Public access settings for this account status, run the following command, `aws s3control get-public-access-block --account-id  --region `Output if Block Public access is enabled:``` {\"PublicAccessBlockConfiguration\": {\"IgnorePublicAcls\": true, \"BlockPublicPolicy\": true, \"BlockPublicAcls\": true, \"RestrictPublicBuckets\": true} } ```If the output reads `false` for the separate configuration settings then proceed to the remediation.","ImpactStatement": "When you apply Block Public Access settings to an account, the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously, but they eventually propagate to all Regions.","AssessmentStatus": "Automated","RationaleStatement": "Amazon S3 `Block public access (bucket settings)` prevents the accidental or malicious public exposure of data contained within the respective bucket(s). Amazon S3 `Block public access (account settings)` prevents the accidental or malicious public exposure of data contained within all buckets of the respective AWS account.Whether blocking public access to all or some buckets is an organizational decision that should be based on data sensitivity, least privilege, and use case.","RemediationProcedure": "**If utilizing Block Public Access (bucket settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select the Check box next to the Bucket. 3. Click on 'Edit public access settings'. 4. Click 'Block all public access' 5. Repeat for all the buckets in your AWS account that contain sensitive data.**From Command Line:**1. List all of the S3 Buckets ``` aws s3 ls ``` 2. Set the Block Public Access to true on that bucket ``` aws s3api put-public-access-block --bucket  --public-access-block-configuration \"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true\" ```**If utilizing Block Public Access (account settings)****From Console:**If the output reads `true` for the separate configuration settings then it is set on the account.1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Choose `Block Public Access (account settings)` 3. Choose `Edit` to change the block public access settings for all the buckets in your AWS account 4. Choose the settings you want to change, and then choose `Save`. For details about each setting, pause on the `i` icons. 5. When you're asked for confirmation, enter `confirm`. Then Click `Confirm` to save your changes.**From Command Line:**To set Block Public access settings for this account, run the following command: ``` aws s3control put-public-access-block --public-access-block-configuration BlockPublicAcls=true, IgnorePublicAcls=true, BlockPublicPolicy=true, RestrictPublicBuckets=true --account-id  ```","AdditionalInformation": ""}],"description": "Ensure that S3 Buckets are configured with 'Block public access (bucket settings)'","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"2.2.1": {"name": "2.2.1","checks": {"ec2_ebs_volume_encryption": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.2. Elastic Compute Cloud (EC2)","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html:https://aws.amazon.com/blogs/aws/new-opt-in-to-default-encryption-for-new-ebs-volumes/","Description": "Elastic Compute Cloud (EC2) supports encryption at rest when using the Elastic Block Store (EBS) service. While disabled by default, forcing encryption at EBS volume creation is supported.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under `Account attributes`, click `EBS encryption`. 3. Verify `Always encrypt new EBS volumes` displays `Enabled`. 4. Review every region in-use.**Note:** EBS volume encryption is configured per region.**From Command Line:**1. Run``` aws --region  ec2 get-ebs-encryption-by-default ``` 2. Verify that `\"EbsEncryptionByDefault\": true` is displayed. 3. Review every region in-use.**Note:** EBS volume encryption is configured per region.","ImpactStatement": "Losing access or removing the KMS key in use by the EBS volumes will result in no longer being able to access the volumes.","AssessmentStatus": "Automated","RationaleStatement": "Encrypting data at rest reduces the likelihood that it is unintentionally exposed and can nullify the impact of disclosure if the encryption remains unbroken.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under `Account attributes`, click `EBS encryption`. 3. Click `Manage`. 4. Click the `Enable` checkbox. 5. Click `Update EBS encryption` 6. Repeat for every region requiring the change.**Note:** EBS volume encryption is configured per region.**From Command Line:**1. Run``` aws --region  ec2 enable-ebs-encryption-by-default ``` 2. Verify that `\"EbsEncryptionByDefault\": true` is displayed. 3. Repeat every region requiring the change.**Note:** EBS volume encryption is configured per region.","AdditionalInformation": "Default EBS volume encryption only applies to newly created EBS volumes. Existing EBS volumes are **not** converted automatically."}],"description": "Ensure EBS Volume Encryption is Enabled in all Regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.3.1": {"name": "2.3.1","checks": {"rds_instance_storage_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Encryption.html:https://aws.amazon.com/blogs/database/selecting-the-right-encryption-options-for-amazon-rds-and-amazon-aurora-database-engines/#:~:text=With%20RDS%2Dencrypted%20resources%2C%20data,transparent%20to%20your%20database%20engine.:https://aws.amazon.com/rds/features/security/","Description": "Amazon RDS encrypted DB instances use the industry standard AES-256 encryption algorithm to encrypt your data on the server that hosts your Amazon RDS DB instances. After your data is encrypted, Amazon RDS handles authentication of access and decryption of your data transparently with a minimal impact on performance.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and open the RDS dashboard at https://console.aws.amazon.com/rds/ 2. In the navigation pane, under RDS dashboard, click `Databases`. 3. Select the RDS Instance that you want to examine 4. Click `Instance Name` to see details, then click on `Configuration` tab. 5. Under Configuration Details section, In Storage pane search for the `Encryption Enabled` Status. 6. If the current status is set to `Disabled`, Encryption is not enabled for the selected RDS Instance database instance. 7. Repeat steps 3 to 7 to verify encryption status of other RDS Instance in same region. 8. Change region from the top of the navigation bar and repeat audit for other regions.**From Command Line:**1. Run `describe-db-instances` command to list all RDS Instance database names, available in the selected AWS region, Output will return each Instance database identifier-name.``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. Run again `describe-db-instances` command using the RDS Instance identifier returned earlier, to determine if the selected database instance is encrypted, The command output should return the encryption status `True` Or `False`. ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].StorageEncrypted' ``` 3. If the StorageEncrypted parameter value is `False`, Encryption is not enabled for the selected RDS database instance. 4. Repeat steps 1 to 3 for auditing each RDS Instance and change Region to verify for other regions","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Databases are likely to hold sensitive and critical data, it is highly recommended to implement encryption in order to protect your data from unauthorized access or disclosure. With RDS encryption enabled, the data stored on the instance's underlying storage, the automated backups, read replicas, and snapshots, are all encrypted.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and open the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases` 3. Select the Database instance that needs to be encrypted. 4. Click on `Actions` button placed at the top right and select `Take Snapshot`. 5. On the Take Snapshot page, enter a database name of which you want to take a snapshot in the `Snapshot Name` field and click on `Take Snapshot`. 6. Select the newly created snapshot and click on the `Action` button placed at the top right and select `Copy snapshot` from the Action menu. 7. On the Make Copy of DB Snapshot page, perform the following:- In the New DB Snapshot Identifier field, Enter a name for the `new snapshot`. - Check `Copy Tags`, New snapshot must have the same tags as the source snapshot. - Select `Yes` from the `Enable Encryption` dropdown list to enable encryption, You can choose to use the AWS default encryption key or custom key from Master Key dropdown list.8. Click `Copy Snapshot` to create an encrypted copy of the selected instance snapshot. 9. Select the new Snapshot Encrypted Copy and click on the `Action` button placed at the top right and select `Restore Snapshot` button from the Action menu, This will restore the encrypted snapshot to a new database instance. 10. On the Restore DB Instance page, enter a unique name for the new database instance in the DB Instance Identifier field. 11. Review the instance configuration details and click `Restore DB Instance`. 12. As the new instance provisioning process is completed can update application configuration to refer to the endpoint of the new Encrypted database instance Once the database endpoint is changed at the application level, can remove the unencrypted instance.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names available in the selected AWS region, The command output should return the database instance identifier. ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. Run `create-db-snapshot` command to create a snapshot for the selected database instance, The command output will return the `new snapshot` with name DB Snapshot Name. ``` aws rds create-db-snapshot --region  --db-snapshot-identifier  --db-instance-identifier  ``` 3. Now run `list-aliases` command to list the KMS keys aliases available in a specified region, The command output should return each `key alias currently available`. For our RDS encryption activation process, locate the ID of the AWS default KMS key. ``` aws kms list-aliases --region  ``` 4. Run `copy-db-snapshot` command using the default KMS key ID for RDS instances returned earlier to create an encrypted copy of the database instance snapshot, The command output will return the `encrypted instance snapshot configuration`. ``` aws rds copy-db-snapshot --region  --source-db-snapshot-identifier  --target-db-snapshot-identifier  --copy-tags --kms-key-id  ``` 5. Run `restore-db-instance-from-db-snapshot` command to restore the encrypted snapshot created at the previous step to a new database instance, If successful, the command output should return the new encrypted database instance configuration. ``` aws rds restore-db-instance-from-db-snapshot --region  --db-instance-identifier  --db-snapshot-identifier  ``` 6. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region, Output will return database instance identifier name Select encrypted database name that we just created DB-Name-Encrypted. ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 7. Run again `describe-db-instances` command using the RDS instance identifier returned earlier, to determine if the selected database instance is encrypted, The command output should return the encryption status `True`. ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].StorageEncrypted' ```","AdditionalInformation": ""}],"description": "Ensure that encryption is enabled for RDS Instances","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.3.2": {"name": "2.3.2","checks": {"rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_RDS_Managing.html:https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.Upgrading.html:https://aws.amazon.com/rds/faqs/","Description": "Ensure that RDS database instances have the Auto Minor Version Upgrade flag enabled in order to receive automatically minor engine upgrades during the specified maintenance window. So, RDS instances can get the new features, bug fixes, and security patches for their database engines.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases`. 3. Select the RDS instance that wants to examine. 4. Click on the `Maintenance and backups` panel. 5. Under the `Maintenance` section, search for the Auto Minor Version Upgrade status. - If the current status is set to `Disabled`, means the feature is not set and the minor engine upgrades released will not be applied to the selected RDS instance**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance identifier. 3. Run again `describe-db-instances` command using the RDS instance identifier returned earlier to determine the Auto Minor Version Upgrade status for the selected instance: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].AutoMinorVersionUpgrade' ``` 4. The command output should return the feature current status. If the current status is set to `true`, the feature is enabled and the minor engine upgrades will be applied to the selected RDS instance.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "AWS RDS will occasionally deprecate minor engine versions and provide new ones for an upgrade. When the last version number within the release is replaced, the version changed is considered minor. With Auto Minor Version Upgrade feature enabled, the version upgrades will occur automatically during the specified maintenance window so your RDS instances can get the new features, bug fixes, and security patches for their database engines.","RemediationProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases`. 3. Select the RDS instance that wants to update. 4. Click on the `Modify` button placed on the top right side. 5. On the `Modify DB Instance: ` page, In the `Maintenance` section, select `Auto minor version upgrade` click on the `Yes` radio button. 6. At the bottom of the page click on `Continue`, check to Apply Immediately to apply the changes immediately, or select `Apply during the next scheduled maintenance window` to avoid any downtime. 7. Review the changes and click on `Modify DB Instance`. The instance status should change from available to modifying and back to available. Once the feature is enabled, the `Auto Minor Version Upgrade` status should change to `Yes`.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database instance names, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance identifier. 3. Run the `modify-db-instance` command to modify the selected RDS instance configuration this command will apply the changes immediately, Remove `--apply-immediately` to apply changes during the next scheduled maintenance window and avoid any downtime: ``` aws rds modify-db-instance --region  --db-instance-identifier  --auto-minor-version-upgrade --apply-immediately ``` 4. The command output should reveal the new configuration metadata for the RDS instance and check `AutoMinorVersionUpgrade` parameter value. 5. Run `describe-db-instances` command to check if the Auto Minor Version Upgrade feature has been successfully enable: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].AutoMinorVersionUpgrade' ``` 6. The command output should return the feature current status set to `true`, the feature is `enabled` and the minor engine upgrades will be applied to the selected RDS instance.","AdditionalInformation": ""}],"description": "Ensure Auto Minor Version Upgrade feature is Enabled for RDS Instances","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.3.3": {"name": "2.3.3","checks": {"rds_instance_no_public_access": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "1. https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.html:https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario2.html:https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html:https://aws.amazon.com/rds/faqs/","Description": "Ensure and verify that RDS database instances provisioned in your AWS account do restrict unauthorized access in order to minimize security risks. To restrict access to anypublicly accessible RDS database instance, you must disable the database PubliclyAccessible flag and update the VPC security group associated with the instance","DefaultValue": null,"AuditProcedure": "From Console: 1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. Under the navigation panel, On RDS Dashboard, click Databases. 3. Select the RDS instance that you want to examine. 4. Click Instance Name from the dashboard, Under `Connectivity and Security. 5. On the Security, check if the Publicly Accessible flag status is set to Yes, follow the below-mentioned steps to check database subnet access. • In the networking section, click the subnet link available under Subnets • The link will redirect you to the VPC Subnets page. • Select the subnet listed on the page and click the Route Table tab from the dashboard bottom panel. If the route table contains any entries with the destination CIDR block set to 0.0.0.0/0 and with an Internet Gateway attached. • The selected RDS database instance was provisioned inside a public subnet, therefore is not running within a logically isolated environment and can be accessible from the Internet. 6. Repeat steps no. 4 and 5 to determine the type (public or private) and subnet for other RDS database instances provisioned in the current region. 7. Change the AWS region from the navigation bar and repeat the audit process for other regions. From Command Line: 1. Run describe-db-instances command to list all RDS database names, available in the selected AWS region: aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' 2. The command output should return each database instance identifier. 3. Run again describe-db-instances command using the PubliclyAccessible parameter as query filter to reveal the database instance Publicly Accessible flag status: aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].PubliclyAccessible' 4. Check for the Publicly Accessible parameter status, If the Publicly Accessible flag is set to Yes. Then selected RDS database instance is publicly accessible and insecure, follow the below-mentioned steps to check database subnet access 5. Run again describe-db-instances command using the RDS database instance identifier that you want to check and appropriate filtering to describe the VPC subnet(s) associated with the selected instance: aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].DBSubnetGroup.Subnets[]' • The command output should list the subnets available in the selected database subnet group. 6. Run describe-route-tables command using the ID of the subnet returned at the previous step to describe the routes of the VPC route table associated with the selected subnet: aws ec2 describe-route-tables --region  --filters 'Name=association.subnet-id,Values=' --query 'RouteTables[*].Routes[]' • If the command returns the route table associated with database instance subnet ID. Check the GatewayId and DestinationCidrBlock attributes values returned in the output. If the route table contains any entries with the GatewayId value set to igw-xxxxxxxx and the DestinationCidrBlock value set to 0.0.0.0/0, the selected RDS database instance was provisioned inside a public subnet. • Or • If the command returns empty results, the route table is implicitly associated with subnet, therefore the audit process continues with the next step 7. Run again describe-db-instances command using the RDS database instance identifier that you want to check and appropriate filtering to describe the VPC ID associated with the selected instance: aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].DBSubnetGroup.VpcId' • The command output should show the VPC ID in the selected database subnet group 8. Now run describe-route-tables command using the ID of the VPC returned at the previous step to describe the routes of the VPC main route table implicitly associated with the selected subnet: aws ec2 describe-route-tables --region  --filters 'Name=vpc- id,Values=' 'Name=association.main,Values=true' --query 'RouteTables[*].Routes[]' • The command output returns the VPC main route table implicitly associated with database instance subnet ID. Check the GatewayId and DestinationCidrBlock attributes values returned in the output. If the route table contains any entries with the GatewayId value set to igw-xxxxxxxx and the DestinationCidrBlock value set to 0.0.0.0/0, the selected RDS database instance was provisioned inside a public subnet, therefore is not running within a logically isolated environment and does not adhere to AWS security best practices.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Ensure that no public-facing RDS database instances are provisioned in your AWS account and restrict unauthorized access in order to minimize security risks. When the RDS instance allows unrestricted access (0.0.0.0/0), everyone and everything on the Internet can establish a connection to your database and this can increase the opportunity for malicious activities such as brute force attacks, PostgreSQL injections, or DoS/DDoS attacks.","RemediationProcedure": "From Console: 1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. Under the navigation panel, On RDS Dashboard, click Databases. 3. Select the RDS instance that you want to update. 4. Click Modify from the dashboard top menu. 5. On the Modify DB Instance panel, under the Connectivity section, click on Additional connectivity configuration and update the value for Publicly Accessible to Not publicly accessible to restrict public access. Follow the below steps to update subnet configurations: • Select the Connectivity and security tab, and click on the VPC attribute value inside the Networking section. • Select the Details tab from the VPC dashboard bottom panel and click on Route table configuration attribute value. • On the Route table details page, select the Routes tab from the dashboard bottom panel and click on Edit routes. • On the Edit routes page, update the Destination of Target which is set to igw- xxxxx and click on Save routes. 6. On the Modify DB Instance panel Click on Continue and In the Scheduling of modifications section, perform one of the following actions based on your requirements: • Select Apply during the next scheduled maintenance window to apply the changes automatically during the next scheduled maintenance window. • Select Apply immediately to apply the changes right away. With this option, any pending modifications will be asynchronously applied as soon as possible, regardless of the maintenance window setting for this RDS database instance. Note that any changes available in the pending modifications queue are also applied. If any of the pending modifications require downtime, choosing this option can cause unexpected downtime for the application. 7. Repeat steps 3 to 6 for each RDS instance available in the current region. 8. Change the AWS region from the navigation bar to repeat the process for other regions. From Command Line: 1. Run describe-db-instances command to list all RDS database names identifiers, available in the selected AWS region: aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' 2. The command output should return each database instance identifier. 3. Run modify-db-instance command to modify the selected RDS instance configuration. Then use the following command to disable the Publicly Accessible flag for the selected RDS instances. This command use the apply- immediately flag. If you want to avoid any downtime --no-apply-immediately flag can be used: aws rds modify-db-instance --region  --db-instance-identifier  --no-publicly-accessible --apply-immediately 4. The command output should reveal the PubliclyAccessible configuration under pending values and should get applied at the specified time. 5. Updating the Internet Gateway Destination via AWS CLI is not currently supported To update information about Internet Gateway use the AWS Console Procedure. 6. Repeat steps 1 to 5 for each RDS instance provisioned in the current region. 7. Change the AWS region by using the --region filter to repeat the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that public access is not given to RDS Instance","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.4.1": {"name": "2.4.1","checks": {"efs_encryption_at_rest_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.4 Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/efs/index.html#efs","Description": "EFS data should be encrypted at rest using AWS KMS (Key Management Service).","DefaultValue": null,"AuditProcedure": "**From Console:** 1. Login to the AWS Management Console and Navigate to `Elastic File System (EFS) dashboard. 2. Select `File Systems` from the left navigation panel. 3. Each item on the list has a visible Encrypted field that displays data at rest encryption status. 4. Validate that this field reads `Encrypted` for all EFS file systems in all AWS regions.**From CLI:** 1. Run describe-file-systems command using custom query filters to list the identifiers of all AWS EFS file systems currently available within the selected region: ``` aws efs describe-file-systems --region  --output table --query 'FileSystems[*].FileSystemId' ``` 2. The command output should return a table with the requested file system IDs. 3. Run describe-file-systems command using the ID of the file system that you want to examine as identifier and the necessary query filters: ``` aws efs describe-file-systems --region  --file-system-id  --query 'FileSystems[*].Encrypted' ``` 4. The command output should return the file system encryption status true or false. If the returned value is `false`, the selected AWS EFS file system is not encrypted and if the returned value is `true`, the selected AWS EFS file system is encrypted.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Data should be encrypted at rest to reduce the risk of a data breach via direct access to the storage device.","RemediationProcedure": "**It is important to note that EFS file system data at rest encryption must be turned on when creating the file system.**If an EFS file system has been created without data at rest encryption enabled then you must create another EFS file system with the correct configuration and transfer the data.**Steps to create an EFS file system with data encrypted at rest:****From Console:** 1. Login to the AWS Management Console and Navigate to `Elastic File System (EFS)` dashboard. 2. Select `File Systems` from the left navigation panel. 3. Click `Create File System` button from the dashboard top menu to start the file system setup process. 4. On the `Configure file system access` configuration page, perform the following actions. - Choose the right VPC from the VPC dropdown list. - Within Create mount targets section, select the checkboxes for all of the Availability Zones (AZs) within the selected VPC. These will be your mount targets. - Click `Next step` to continue.5. Perform the following on the `Configure optional settings` page. - Create `tags` to describe your new file system. - Choose `performance mode` based on your requirements. - Check `Enable encryption` checkbox and choose `aws/elasticfilesystem` from Select KMS master key dropdown list to enable encryption for the new file system using the default master key provided and managed by AWS KMS. - Click `Next step` to continue.6. Review the file system configuration details on the `review and create` page and then click `Create File System` to create your new AWS EFS file system. 7. Copy the data from the old unencrypted EFS file system onto the newly create encrypted file system. 8. Remove the unencrypted file system as soon as your data migration to the newly create encrypted file system is completed. 9. Change the AWS region from the navigation bar and repeat the entire process for other aws regions.**From CLI:** 1. Run describe-file-systems command to describe the configuration information available for the selected (unencrypted) file system (see Audit section to identify the right resource): ``` aws efs describe-file-systems --region  --file-system-id  ``` 2. The command output should return the requested configuration information. 3. To provision a new AWS EFS file system, you need to generate a universally unique identifier (UUID) in order to create the token required by the create-file-system command. To create the required token, you can use a randomly generated UUID from \"https://www.uuidgenerator.net\". 4. Run create-file-system command using the unique token created at the previous step. ``` aws efs create-file-system --region  --creation-token  --performance-mode generalPurpose --encrypted ``` 5. The command output should return the new file system configuration metadata. 6. Run create-mount-target command using the newly created EFS file system ID returned at the previous step as identifier and the ID of the Availability Zone (AZ) that will represent the mount target: ``` aws efs create-mount-target --region  --file-system-id  --subnet-id  ``` 7. The command output should return the new mount target metadata. 8. Now you can mount your file system from an EC2 instance. 9. Copy the data from the old unencrypted EFS file system onto the newly create encrypted file system. 10. Remove the unencrypted file system as soon as your data migration to the newly create encrypted file system is completed. ``` aws efs delete-file-system --region  --file-system-id  ``` 11. Change the AWS region by updating the --region and repeat the entire process for other aws regions.","AdditionalInformation": ""}],"description": "Ensure that encryption is enabled for EFS file systems","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 51,"requirements_failed": 10,"requirements_manual": 1,"total_requirements": 62,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "a349f7c9-fce3-4ac4-821a-d0c974496c2b","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "nist_800_53_revision_5_aws","framework": "NIST-800-53-Revision-5","version": "","description": "The NIST 800-53 (Rev. 5) Low-Moderate-High framework represents the security controls and the associated assessment procedures that are defined in NIST SP 800-53 Revision 5 Recommended Security Controls for Federal Information Systems and Organizations. For any discrepancies that are noted in the content between this NIST SP 800-53 framework and the latest published NIST Special Publication SP 800-53 Revision 5, refer to the official published documents that are available at the NIST Computer Security Resource Center.","region": "eu-west-1","requirements": {"ac_3": {"name": "Access Enforcement (AC-3)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"ec2_instance_profile_attached": "PASS","rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Enforce approved authorizations for logical access to information and system resources in accordance with applicable access control policies.","checks_status": {"fail": 1,"pass": 7,"total": 21,"manual": 0}},"ac_4": {"name": "Information Flow Enforcement (AC-4)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_4","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Enforce approved authorizations for controlling the flow of information within the system and between connected systems based on [Assignment: organization-defined information flow control policies].","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"ac_6": {"name": "Least Privilege (AC-6)","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_6","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Employ the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) that are necessary to accomplish assigned organizational tasks.","checks_status": {"fail": 1,"pass": 6,"total": 21,"manual": 0}},"ca_7": {"name": "Continuous Monitoring (CA-7)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ca_7","Section": "Assessment, Authorization, And Monitoring (CA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Continuously monitor configuration management processes. Determine security impact, environment and operational risks.","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"cm_6": {"name": "Configuration Settings (CM-6)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_6","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization: (i) establishes mandatory configuration settings for information technology products employed within the information system; (ii) configures the security settings of information technology products to the most restrictive mode consistent with operational requirements; (iii) documents the configuration settings; and (iv) enforces the configuration settings in all components of the information system.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"ia_2": {"name": "Identification and Authentication (Organizational users) (IA-2)","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": null}],"description": "The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5": {"name": "Authenticator Management (IA-5)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5","Section": "Identification and Authentication (IA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Authenticate users and devices. Automate administrative control. Enforce restrictions. Protect against unauthorized use.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"mp_2": {"name": "Media Access (MP-2)","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "mp_2","Section": "Media Protection (MP)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Restrict access to [Assignment: organization-defined types of digital and/or non-digital media] to [Assignment: organization-defined personnel or roles].","checks_status": {"fail": 1,"pass": 6,"total": 21,"manual": 0}},"sc_6": {"name": "Resource Availability (SC-6)","checks": {"rds_instance_multi_az": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_6","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Protect the availability of resources by allocating [Assignment: organization-defined resources] by [Selection (one or more): priority; quota; [Assignment: organization-defined controls]].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sc_8": {"name": "Transmission Confidentiality And Integrity (SC-8)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_8","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Protect the [Selection (one or more): confidentiality; integrity] of transmitted information.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"ac_24": {"name": "Access Control Decisions (AC-24)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_24","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "[Selection: Establish procedures; Implement mechanisms] to ensure [Assignment: organization-defined access control decisions] are applied to each access request prior to access enforcement.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"au_10": {"name": "Non-Repudiation (AU-10)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","opensearch_service_domains_cloudwatch_logging_enabled": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_10","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Provide irrefutable evidence that an individual (or process acting on behalf of an individual) has performed [Assignment: organization-defined actions to be covered by non-repudiation].","checks_status": {"fail": 6,"pass": 2,"total": 13,"manual": 0}},"au_11": {"name": "Audit Record Retention (AU-11)","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_11","Section": "Audit and Accountability (AU)","Service": "cloudwatch","SubGroup": null,"SubSection": null}],"description": "Retain audit records for [Assignment: organization-defined time period consistent with records retention policy] to provide support for after-the-fact investigations of incidents and to meet regulatory and organizational information retention requirements.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"au_16": {"name": "Cross-Organizational Audit Logging (AU-16)","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_16","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Employ [Assignment: organization-defined methods] for coordinating [Assignment: organization-defined audit information] among external organizations when audit information is transmitted across organizational boundaries.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cp_10": {"name": "System Recovery And Reconstitution (CP-10)","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_10","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Provide for the recovery and reconstitution of the system to a known state within [Assignment: organization-defined time period consistent with recovery time and recovery point objectives] after a disruption, compromise, or failure.","checks_status": {"fail": 3,"pass": 1,"total": 7,"manual": 0}},"pm_16": {"name": "Threat Awareness Program (PM-16)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "pm_16","Section": "Program Management (PM)","Service": "guarduty","SubGroup": null,"SubSection": null}],"description": "Implement a threat awareness program that includes a cross-organization information-sharing capability for threat intelligence.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"pm_31": {"name": "Continuous Monitoring Strategy (PM-31)","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pm_31","Section": "Program Management (PM)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Develop an organization-wide continuous monitoring strategy and implement continuous monitoring programs that include: a. Establishing the following organization-wide metrics to be monitored: [Assignment: organization-defined metrics]; b. Establishing [Assignment: organization-defined frequencies] for monitoring and [Assignment: organization-defined frequencies] for assessment of control effectiveness; c. Ongoing monitoring of organizationally-defined metrics in accordance with the continuous monitoring strategy; d. Correlation and analysis of information generated by control assessments and monitoring; e. Response actions to address results of the analysis of control assessment and monitoring information; and f. Reporting the security and privacy status of organizational systems to [Assignment: organization-defined personnel or roles] [Assignment: organization-defined frequency].","checks_status": {"fail": 8,"pass": 4,"total": 20,"manual": 0}},"sc_12": {"name": "Cryptographic Key Establishment And Management (SC-12)","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_12","Section": "System and Communications Protection (SC)","Service": "kms","SubGroup": null,"SubSection": null}],"description": "Establish and manage cryptographic keys when cryptography is employed within the system in accordance with the following key management requirements: [Assignment: organization-defined requirements for key generation, distribution, storage, access, and destruction].","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"sc_22": {"name": "Architecture And Provisioning For Name/Address Resolution Service (SC-22)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_22","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Ensure the systems that collectively provide name/address resolution service for an organization are fault-tolerant and implement internal and external role separation.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"sc_23": {"name": "Session Authenticity (SC-23)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_23","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Protect the authenticity of communications sessions.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"sc_25": {"name": "Thin Nodes (SC-25)","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_25","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Employ minimal functionality and information storage on the following system components: [Assignment: organization-defined system components].","checks_status": {"fail": 1,"pass": 5,"total": 17,"manual": 0}},"sc_36": {"name": "Distributed Processing And Storage (SC-36)","checks": {"rds_instance_multi_az": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_36","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Distribute the following processing and storage components across multiple [Selection: physical locations; logical domains]: [Assignment: organization-defined processing and storage components].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"si_12": {"name": "Information Management and Retention (SI-12)","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_12","Section": "System and Information integrity (SI)","Service": "cloudwatch","SubGroup": null,"SubSection": null}],"description": "Manage and retain information within the system and information output from the system in accordance with applicable laws, executive orders, directives, regulations, policies, standards, guidelines and operational requirements.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ac_2_1": {"name": "AC-2(1) Automated System Account Management","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_2_1","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "Support the management of system accounts using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 1,"pass": 0,"total": 14,"manual": 0}},"ac_2_3": {"name": "AC-2(3) Disable Accounts","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_3","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "Disable accounts within [Assignment: organization-defined time period] when the accounts: (a) Have expired; (b) Are no longer associated with a user or individual; (c) Are in violation of organizational policy; or (d) Have been inactive for [Assignment: organization-defined time period].","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"ac_2_4": {"name": "AC-2(4) Automated Audit Actions","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_2_4","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "Automatically audit account creation, modification, enabling, disabling, and removal actions.","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"ac_2_6": {"name": "AC-2(6) Dynamic Privilege Management","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_2_6","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "Implement [Assignment: organization-defined dynamic privilege management capabilities].","checks_status": {"fail": 1,"pass": 6,"total": 21,"manual": 0}},"ac_2_g": {"name": "AC-2(g)","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_g","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The organization: g. Monitors the use of information system accounts.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"ac_2_j": {"name": "AC-2(j)","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_j","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The organization: j. Reviews accounts for compliance with account management requirements [Assignment: organization-defined frequency].","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"ac_3_1": {"name": "AC-3(1) Restricted Access To Privileged Functions","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_1","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Access Enforcement (AC-3)"}],"description": "Employ an audited override of automated access control mechanisms under [Assignment: organization-defined conditions] by [Assignment: organization-defined roles].","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"ac_3_2": {"name": "AC-3(2) Dual Authorization","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_3_2","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce dual authorization for [Assignment: organization-defined privileged commands and/or other organization-defined actions].","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ac_3_3": {"name": "AC-3(3) Mandatory Access Control","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_3","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access control policy] over the set of covered subjects and objects specified in the policy, and where the policy: (a) Is uniformly enforced across the covered subjects and objects within the system; (b) Specifies that a subject that has been granted access to information is constrained from doing any of the following; (1) Passing the information to unauthorized subjects or objects; (2) Granting its privileges to other subjects; (3) Changing one or more security attributes (specified by the policy) on subjects, objects, the system, or system components; (4) Choosing the security attributes and attribute values (specified by the policy) to be associated with newly created or modified objects; and (5) Changing the rules governing access control; and (c) Specifies that [Assignment: organization-defined subjects] may explicitly be granted [Assignment: organization-defined privileges] such that they are not limited by any defined subset (or all) of the above constraints.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_4": {"name": "AC-3(4) Discretionary Access Control","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_4","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined discretionary access control policy] over the set of covered subjects and objects specified in the policy, and where the policy specifies that a subject that has been granted access to information can do one or more of the following: (a) Pass the information to any other subjects or objects; (b) Grant its privileges to other subjects; (c) Change security attributes on subjects, objects, the system, or the system’s components; (d) Choose the security attributes to be associated with newly created or revised objects; or (e) Change the rules governing access control.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_7": {"name": "AC-3(7) Role-Based Access Control","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_7","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce a role-based access control policy over defined subjects and objects and control access based upon [Assignment: organization-defined roles and users authorized to assume such roles].","checks_status": {"fail": 1,"pass": 6,"total": 21,"manual": 0}},"ac_3_8": {"name": "AC-3(8) Revocation Of Access Authorizations","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_8","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce the revocation of access authorizations resulting from changes to the security attributes of subjects and objects based on [Assignment: organization-defined rules governing the timing of revocations of access authorizations].","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_5_b": {"name": "AC-5(b)","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_5_b","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Separation Of Duties (AC-5)"}],"description": "Define system access authorizations to support separation of duties.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"ac_6_2": {"name": "AC-6(2)","checks": {"iam_no_root_access_key": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_6_2","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Least Privilege (AC-6)"}],"description": "Require that users of system accounts (or roles) with access to [Assignment: organization-defined security functions or security-relevant information] use non-privileged accounts or roles, when accessing nonsecurity functions.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ac_6_3": {"name": "AC-6(3)","checks": {"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_6_3","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Least Privilege (AC-6)"}],"description": "Authorize network access to [Assignment: organization-defined privileged commands] only for [Assignment: organization-defined compelling operational needs] and document the rationale for such access in the security plan for the system.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ac_6_9": {"name": "AC-6(9)","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_6_9","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Least Privilege (AC-6)"}],"description": "Log the execution of privileged functions.","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"ac_7_4": {"name": "AC-7(4) Use Of Alternate Authentication Factor","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_7_4","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Unsuccessful Logon Attempts (AC-7)"}],"description": "Prevent non-privileged users from executing privileged functions.","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"au_2_b": {"name": "AU-2(b)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_2_b","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Event Logging (AU-2)"}],"description": "Coordinate the event logging function with other organizational entities requiring audit-related information to guide and inform the selection criteria for events to be logged.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_3_1": {"name": "AU-3(1) Additional Audit Information","checks": {"guardduty_is_enabled": "PASS","cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "au_3_1","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Content of Audit Records (AU-3)"}],"description": "Generate audit records containing the following additional information: [Assignment: organization-defined additional information].","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"au_3_a": {"name": "AU-3(a)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_3_a","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Content of Audit Records (AU-3)"}],"description": "Ensure that audit records contain information that establishes the following: a. What type of event occurred.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_3_b": {"name": "AU-3(b)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_3_b","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Content of Audit Records (AU-3)"}],"description": "Ensure that audit records contain information that establishes the following: b. When the event occurred.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_3_c": {"name": "AU-3(c)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_3_c","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Content of Audit Records (AU-3)"}],"description": "Ensure that audit records contain information that establishes the following: c. Where the event occurred.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_3_d": {"name": "AU-3(d)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_3_d","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Content of Audit Records (AU-3)"}],"description": "Ensure that audit records contain information that establishes the following: d. Source of the event.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_3_e": {"name": "AU-3(e)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_3_e","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Content of Audit Records (AU-3)"}],"description": "Ensure that audit records contain information that establishes the following: e. Outcome of the event.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_3_f": {"name": "AU-3(f)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_3_f","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Content of Audit Records (AU-3)"}],"description": "Ensure that audit records contain information that establishes the following: e. Outcome of the event.","checks_status": {"fail": 5,"pass": 2,"total": 11,"manual": 0}},"au_4_1": {"name": "AU-4(1) Transfer To Alternate Storage","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_4_1","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Log Stprage Capacity (AU-4)"}],"description": "Transfer audit logs [Assignment: organization-defined frequency] to a different system, system component, or media other than the system or system component conducting the logging.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"au_6_1": {"name": "AU-6(1) Automated Process Integration","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_6_1","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Review, Analysis And Reporting (AU-6)"}],"description": "Integrate audit record review, analysis, and reporting processes using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"au_6_3": {"name": "AU-6(3) Correlate Audit Record Repositories","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_6_3","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Review, Analysis And Reporting (AU-6)"}],"description": "Analyze and correlate audit records across different repositories to gain organization-wide situational awareness.","checks_status": {"fail": 7,"pass": 2,"total": 13,"manual": 0}},"au_6_4": {"name": "AU-6(4) Central Review And Analysis","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_6_4","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Review, Analysis And Reporting (AU-6)"}],"description": "Provide and implement the capability to centrally review and analyze audit records from multiple components within the system.","checks_status": {"fail": 7,"pass": 2,"total": 13,"manual": 0}},"au_6_5": {"name": "AU-6(5) Central Review And Analysis","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_6_5","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Review, Analysis And Reporting (AU-6)"}],"description": "Integrate analysis of audit records with analysis of [Selection (one or more): vulnerability scanning information; performance data; system monitoring information; [Assignment: organization-defined data/information collected from other sources]] to further enhance the ability to identify inappropriate or unusual activity.","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"au_6_6": {"name": "AU-6(6) Correletion With Physical Monitoring","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_6_6","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Review, Analysis And Reporting (AU-6)"}],"description": "Correlate information from audit records with information obtained from monitoring physical access to further enhance the ability to identify suspicious, inappropriate, unusual, or malevolent activity.","checks_status": {"fail": 7,"pass": 2,"total": 13,"manual": 0}},"au_6_9": {"name": "AU-6(9) Correletion With From Nontechnical Sources","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_6_9","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Review, Analysis And Reporting (AU-6)"}],"description": "Correlate information from nontechnical sources with audit record information to enhance organization-wide situational awareness.","checks_status": {"fail": 7,"pass": 2,"total": 13,"manual": 0}},"au_7_1": {"name": "AU-7(1) Automatic Processing","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_7_1","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Reduction And Report Generation (AU-7)"}],"description": "Provide and implement the capability to process, sort, and search audit records for events of interest based on the following content: [Assignment: organization-defined fields within audit records].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"au_8_b": {"name": "AU-8(b)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_8_b","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Time Stamps (AU-8)"}],"description": "Record time stamps for audit records that meet [Assignment: organization-defined granularity of time measurement] and that use Coordinated Universal Time, have a fixed local time offset from Coordinated Universal Time, or that include the local time offset as part of the time stamp.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_9_2": {"name": "AU-9(2) Store On Separate Physical Systems Or Components","checks": {"s3_bucket_object_versioning": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_9_2","Section": "Audit and Accountability (AU)","Service": "s3","SubGroup": null,"SubSection": "Protection of Audit Information (AU-9)"}],"description": "Store audit records [Assignment: organization-defined frequency] in a repository that is part of a physically different system or system component than the system or component being audited.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"au_9_3": {"name": "AU-9(3) Cryptographic Protection","checks": {"elb_ssl_listeners": "FAIL","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_9_3","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Protection of Audit Information (AU-9)"}],"description": "Implement cryptographic mechanisms to protect the integrity of audit information and audit tools.","checks_status": {"fail": 8,"pass": 3,"total": 17,"manual": 0}},"au_9_7": {"name": "AU-9(7) Store On Component With Different Operation Systems","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_9_7","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Protection of Audit Information (AU-9)"}],"description": "Store audit information on a component running a different operating system than the system or component being audited.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"au_9_a": {"name": "AU-9(a)","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_9_a","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Protection of Audit Information (AU-9)"}],"description": "Protect audit information and audit logging tools from unauthorized access, modification, and deletion.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ca_2_2": {"name": "CA-2(2) Specialized Assessments","checks": {"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ca_2_2","Section": "Assessment, Authorization, And Monitoring (CA)","Service": "aws","SubGroup": null,"SubSection": "Control Assessments (CA-2)"}],"description": "Include as part of control assessments, [Assignment: organization-defined frequency], [Selection: announced; unannounced], [Selection (one or more): in-depth monitoring; security instrumentation; automated security test cases; vulnerability scanning; malicious user testing; insider threat assessment; performance and load testing; data leakage or data loss assessment; [Assignment: organization-defined other forms of assessment]].","checks_status": {"fail": 1,"pass": 0,"total": 5,"manual": 0}},"ca_2_d": {"name": "CA-2(d)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ca_2_d","Section": "Assessment, Authorization, And Monitoring (CA)","Service": "aws","SubGroup": null,"SubSection": "Control Assessments (CA-2)"}],"description": "Assess the controls in the system and its environment of operation [Assignment: organization-defined frequency] to determine the extent to which the controls are implemented correctly, operating as intended, and producing the desired outcome with respect to meeting established security and privacy requirements.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"ca_7_b": {"name": "CA-7(b)","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ca_7_b","Section": "Assessment, Authorization, And Monitoring (CA)","Service": "aws","SubGroup": null,"SubSection": "Continuous Monitoring (CA-7)"}],"description": "Develop a system-level continuous monitoring strategy and implement continuous monitoring in accordance with the organization-level continuous monitoring strategy that includes: b. Establishing [Assignment: organization-defined frequencies] for monitoring and [Assignment: organization-defined frequencies] for assessment of control effectiveness.","checks_status": {"fail": 8,"pass": 4,"total": 20,"manual": 0}},"ca_9_b": {"name": "CA-9(b)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ca_9_b","Section": "Assessment, Authorization, And Monitoring (CA)","Service": "aws","SubGroup": null,"SubSection": "Internal System Connections (CA-9)"}],"description": "Document, for each internal connection, the interface characteristics, security and privacy requirements, and the nature of the information communicated.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"cm_2_2": {"name": "CM-2(2) Automation Support For Accuracy And Currency","checks": {"elbv2_deletion_protection": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_2_2","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Baseline Configuration (CM-2)"}],"description": "Maintain the currency, completeness, accuracy, and availability of the baseline configuration of the system using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 5,"pass": 0,"total": 5,"manual": 0}},"cm_2_a": {"name": "CM-2(a)","checks": {"elbv2_deletion_protection": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_2_a","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Baseline Configuration (CM-2)"}],"description": "Develop, document, and maintain under configuration control, a current baseline configuration of the system.","checks_status": {"fail": 5,"pass": 0,"total": 5,"manual": 0}},"cm_2_b": {"name": "CM-2(b)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_2_b","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Baseline Configuration (CM-2)"}],"description": "Review and update the baseline configuration of the system: 1. [Assignment: organization-defined frequency]; 2. When required due to [Assignment: organization-defined circumstances]; and 3. When system components are installed or upgraded.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"cm_3_3": {"name": "CM-3(3) Automated Change Implementation","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_3_3","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Configuration Change Control (CM-3)"}],"description": "Implement changes to the current system baseline and deploy the updated baseline across the installed base using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"cm_3_a": {"name": "CM-3(a)","checks": {"elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_3_a","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Configuration Change Control (CM-3)"}],"description": "Determine and document the types of changes to the system that are configuration-controlled.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_6_a": {"name": "CM-6(a)","checks": {"iam_root_mfa_enabled": null,"vpc_flow_logs_enabled": "FAIL","iam_no_root_access_key": null,"s3_bucket_public_access": null,"kms_cmk_rotation_enabled": null,"ec2_ebs_volume_encryption": "PASS","iam_user_accesskey_unused": null,"ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","ec2_instance_profile_attached": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","iam_user_mfa_enabled_console_access": null,"s3_bucket_policy_public_write_access": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","iam_password_policy_minimum_length_14": null,"s3_account_level_public_access_blocks": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_6_a","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Configuration Settings (CM-6)"}],"description": "Establish and document configuration settings for components employed within the system that reflect the most restrictive mode consistent with operational requirements using [Assignment: organization-defined common secure configurations].","checks_status": {"fail": 8,"pass": 6,"total": 31,"manual": 0}},"cm_7_b": {"name": "CM-7(b)","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_7_b","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Least Functionality (CM-7)"}],"description": "Prohibit or restrict the use of the following functions, ports, protocols, software, and/or services: [Assignment: organization-defined prohibited or restricted functions, system ports, protocols, software, and/or services].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cm_8_1": {"name": "CM-8(1) Updates During Installation And Removals","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_1","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "System Component Inventory (CM-8)"}],"description": "Update the inventory of system components as part of component installations, removals, and system updates.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_8_2": {"name": "CM-8(2) Automated Maintenance","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_2","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "System Component Inventory (CM-8)"}],"description": "Maintain the currency, completeness, accuracy, and availability of the inventory of system components using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cm_8_6": {"name": "CM-8(6) Assessed Configurations And Approved Deviations","checks": {"elbv2_deletion_protection": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_6","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "System Component Inventory (CM-8)"}],"description": "Include assessed component configurations and any approved deviations to current deployed configurations in the system component inventory.","checks_status": {"fail": 5,"pass": 0,"total": 5,"manual": 0}},"cm_8_a": {"name": "CM-8(a)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_a","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "System Component Inventory (CM-8)"}],"description": "Develop and document an inventory of system components that: 1. Accurately reflects the system; 2. Includes all components within the system; 3. Does not include duplicate accounting of components or components assigned to any other system; 4. Is at the level of granularity deemed necessary for tracking and reporting; and 5. Includes the following information to achieve system component accountability: [Assignment: organization-defined information deemed necessary to achieve effective system component accountability].","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_8_b": {"name": "CM-8(b)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_b","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "System Component Inventory (CM-8)"}],"description": "Review and update the system component inventory [Assignment: organization-defined frequency].","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_9_b": {"name": "CM-9(b)","checks": {"iam_root_mfa_enabled": null,"vpc_flow_logs_enabled": "FAIL","iam_no_root_access_key": null,"s3_bucket_public_access": null,"kms_cmk_rotation_enabled": null,"ec2_ebs_volume_encryption": "PASS","iam_user_accesskey_unused": null,"ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","iam_user_mfa_enabled_console_access": null,"s3_bucket_policy_public_write_access": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","iam_password_policy_minimum_length_14": null,"s3_account_level_public_access_blocks": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_9_b","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Configuration Management Plan (CM-9)"}],"description": "Develop, document, and implement a configuration management plan for the system that: b. Establishes a process for identifying configuration items throughout the system development life cycle and for managing the configuration of the configuration items.","checks_status": {"fail": 8,"pass": 6,"total": 31,"manual": 0}},"cp_1_2": {"name": "CP-1(2)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_1_2","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Policy And Procedures (CP-1)"}],"description": "Implement transaction recovery for systems that are transaction-based.","checks_status": {"fail": 2,"pass": 1,"total": 6,"manual": 0}},"cp_2_5": {"name": "CP-2(5) Continue Mission And Business Functions","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL","redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_2_5","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Contingency Plan (CP-2)"}],"description": "Plan for the continuance of [Selection: all; essential] mission and business functions with minimal or no loss of operational continuity and sustains that continuity until full system restoration at primary processing and/or storage sites.","checks_status": {"fail": 5,"pass": 1,"total": 9,"manual": 0}},"cp_2_6": {"name": "CP-2(6) Alternate Processing And Storage Sites","checks": {"rds_instance_multi_az": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_2_6","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Contingency Plan (CP-2)"}],"description": "Plan for the transfer of [Selection: all; essential] mission and business functions to alternate processing and/or storage sites with minimal or no loss of operational continuity and sustain that continuity through system restoration to primary processing and/or storage sites.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cp_2_a": {"name": "CP-2(a)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_2_a","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Contingency Plan (CP-2)"}],"description": "a. Develop a contingency plan for the system that: 1. Identifies essential mission and business functions and associated contingency requirements; 2. Provides recovery objectives, restoration priorities, and metrics; 3. Addresses contingency roles, responsibilities, assigned individuals with contact information; 4. Addresses maintaining essential mission and business functions despite a system disruption, compromise, or failure; 5. Addresses eventual, full system restoration without deterioration of the controls originally planned and implemented; 6. Addresses the sharing of contingency information; and 7. Is reviewed and approved by [Assignment: organization-defined personnel or roles]","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"cp_2_d": {"name": "CP-2(d)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_2_d","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Contingency Plan (CP-2)"}],"description": "Review the contingency plan for the system [Assignment: organization-defined frequency]","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"cp_2_e": {"name": "CP-2(e)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_2_e","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Contingency Plan (CP-2)"}],"description": "Update the contingency plan to address changes to the organization, system, or environment of operation and problems encountered during contingency plan implementation, execution, or testing.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"cp_6_1": {"name": "CP-6(1) Separation From Primary Site","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_6_1","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Alternate Storage Sites (CP-6)"}],"description": "Identify an alternate storage site that is sufficiently separated from the primary storage site to reduce susceptibility to the same threats.","checks_status": {"fail": 2,"pass": 1,"total": 5,"manual": 0}},"cp_6_2": {"name": "CP-6(2) Recovery Time And Recovery Point Objectives","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_6_2","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Alternate Storage Sites (CP-6)"}],"description": "Configure the alternate storage site to facilitate recovery operations in accordance with recovery time and recovery point objectives.","checks_status": {"fail": 3,"pass": 1,"total": 7,"manual": 0}},"cp_6_a": {"name": "CP-6(a)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_6_a","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Alternate Storage Sites (CP-6)"}],"description": "Establish an alternate storage site, including necessary agreements to permit the storage and retrieval of system backup information.","checks_status": {"fail": 2,"pass": 1,"total": 5,"manual": 0}},"cp_9_8": {"name": "CP-9(8) Cryptographic Protection","checks": {"s3_bucket_default_encryption": "PASS","rds_instance_storage_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_9_8","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "System Backup (CP-9)"}],"description": "Implement cryptographic mechanisms to prevent unauthorized disclosure and modification of [Assignment: organization-defined backup information].","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"cp_9_a": {"name": "CP-9(a)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null,"redshift_cluster_automatic_upgrades": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_9_a","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "System Backup (CP-9)"}],"description": "Conduct backups of user-level information contained in [Assignment: organization-defined system components] [Assignment: organization-defined frequency consistent with recovery time and recovery point objectives].","checks_status": {"fail": 2,"pass": 1,"total": 7,"manual": 0}},"cp_9_b": {"name": "CP-9(b)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null,"redshift_cluster_automatic_upgrades": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_9_b","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "System Backup (CP-9)"}],"description": "Conduct backups of system-level information contained in the system [Assignment: organization-defined frequency consistent with recovery time and recovery point objectives].","checks_status": {"fail": 2,"pass": 1,"total": 7,"manual": 0}},"cp_9_c": {"name": "CP-9(c)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null,"redshift_cluster_automatic_upgrades": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_9_c","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "System Backup (CP-9)"}],"description": "Conduct backups of system documentation, including security- and privacy-related documentation [Assignment: organization-defined frequency consistent with recovery time and recovery point objectives].","checks_status": {"fail": 2,"pass": 1,"total": 7,"manual": 0}},"cp_9_d": {"name": "CP-9(d)","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_9_d","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "System Backup (CP-9)"}],"description": "Protect the confidentiality, integrity, and availability of backup information.","checks_status": {"fail": 5,"pass": 3,"total": 13,"manual": 0}},"ia_2_1": {"name": "IA-2(1) Multi-Factor Authentication To Privileged Accounts","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2_1","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "Implement multi-factor authentication for access to privileged accounts.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ia_2_2": {"name": "IA-2(2) Multi-Factor Authentication To Non-Privileged Accounts","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2_2","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "Implement multi-factor authentication for access to non-privileged accounts.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ia_2_6": {"name": "IA-2(6) Acces To Accounts — Separate Device","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2_6","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "Implement multi-factor authentication for [Selection (one or more): local; network; remote] access to [Selection (one or more): privileged accounts; non-privileged accounts] such that: (a) One of the factors is provided by a device separate from the system gaining access; and (b) The device meets [Assignment: organization-defined strength of mechanism requirements].","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ia_2_8": {"name": "IA-2(8) Access To Accounts — Replay Resistant","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2_8","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "Implement replay-resistant authentication mechanisms for access to [Selection (one or more): privileged accounts; non-privileged accounts].","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ia_4_4": {"name": "IA-4(4)","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_4_4","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identifier Management (IA-4)"}],"description": "Manage individual identifiers by uniquely identifying each individual as [Assignment: organization-defined characteristic identifying individual status].","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_4_8": {"name": "IA-4(8)","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_4_8","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identifier Management (IA-4)"}],"description": "Generate pairwise pseudonymous identifiers.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_4_b": {"name": "IA-4(b)","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_4_b","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identifier Management (IA-4)"}],"description": "Manage system identifiers by: b. Selecting an identifier that identifies an individual, group, role, service, or device.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_4_d": {"name": "IA-4(d)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_4_d","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identifier Management (IA-4)"}],"description": "Manage system identifiers by: d. Preventing reuse of identifiers for [Assignment: organization-defined time period].","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_8": {"name": "IA-5(8) Multiple System Accounts","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_8","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Implement [Assignment: organization-defined security controls] to manage the risk of compromise due to individuals having accounts on multiple systems.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_b": {"name": "IA-5(b)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_b","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "Manage system authenticators by: b. Establishing initial authenticator content for any authenticators issued by the organization.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_c": {"name": "IA-5(c)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_c","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "Manage system authenticators by: c. Ensuring that authenticators have sufficient strength of mechanism for their intended use.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_d": {"name": "IA-5(d)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_d","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "Manage system authenticators by: d. Establishing and implementing administrative procedures for initial authenticator distribution, for lost or compromised or damaged authenticators, and for revoking authenticators.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_f": {"name": "IA-5(f)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_f","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "Manage system authenticators by: f. Changing or refreshing authenticators [Assignment: organization-defined time period by authenticator type] or when [Assignment: organization-defined events] occur.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_h": {"name": "IA-5(h)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_h","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "Manage system authenticators by: h. Requiring individuals to take, and having devices implement, specific controls to protect authenticators.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ir_4_a": {"name": "IR-4(a)","checks": {"guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ir_4_a","Section": "Incident Response (IR)","Service": "guarduty","SubGroup": null,"SubSection": "Incident Handling (IR-4)"}],"description": "Implement an incident handling capability for incidents that is consistent with the incident response plan and includes preparation, detection and analysis, containment, eradication, and recovery.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ma_4_c": {"name": "MA-4(c)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ma_4_c","Section": "Maintenance (MA)","Service": "iam","SubGroup": null,"SubSection": "Nonlocal Maintenance (MA-4)"}],"description": "Employ strong authentication in the establishment of nonlocal maintenance and diagnostic sessions.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"pe_6_2": {"name": "PE-6(2) Monitoring Physical Access","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "pe_6_2","Section": "Physical And Environmental Protection (PE)","Service": "guarduty","SubGroup": null,"SubSection": "Monitoring Physical Access (PE-6)"}],"description": "Recognize [Assignment: organization-defined classes or types of intrusions] and initiate [Assignment: organization-defined response actions] using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"pe_6_4": {"name": "PE-6(4) Monitoring Physical Access","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "pe_6_4","Section": "Physical And Environmental Protection (PE)","Service": "guarduty","SubGroup": null,"SubSection": "Monitoring Physical Access (PE-6)"}],"description": "Monitor physical access to the system in addition to the physical access monitoring of the facility at [Assignment: organization-defined physical spaces containing one or more components of the system].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ra_1_a": {"name": "RA-1(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_1_a","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": null,"SubSection": "Policy And Procedures (RA-1)"}],"description": "Establish and maintain a cyber threat hunting capability to: 1. Search for indicators of compromise in organizational systems; and 2. Detect, track, and disrupt threats that evade existing controls.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ra_3_4": {"name": "RA-3(4) Predictive Cyber Analytics","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_3_4","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": null,"SubSection": "Risk Assessment (RA-3)"}],"description": "Employ the following advanced automation and analytics capabilities to predict and identify risks to [Assignment: organization-defined systems or system components]: [Assignment: organization-defined advanced automation and analytics capabilities].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ra_5_4": {"name": "RA-5(4) Discoverable Information","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_5_4","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": null,"SubSection": "Vulnerability Monitoring And Scanning (RA-5)"}],"description": "Determine information about the system that is discoverable and take [Assignment: organization-defined corrective actions].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ra_5_a": {"name": "RA-5(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_5_a","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": null,"SubSection": "Vulnerability Monitoring And Scanning (RA-5)"}],"description": "Monitor and scan for vulnerabilities in the system and hosted applications [Assignment: organization-defined frequency and/or randomly in accordance with organization-defined process] and when new vulnerabilities potentially affecting the system are identified and reported.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sa_1_1": {"name": "SA-1(1)","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sa_1_1","Section": "System and Services Acquisition (SA)","Service": "cloudtrail","SubGroup": null,"SubSection": "Policy And Procedures (SA-1)"}],"description": "Require the developer of the system, system component, or system service to enable integrity verification of software and firmware components.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sa_9_6": {"name": "SA-9(6) Organization-Controlled Cryptographic Keys","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sa_9_6","Section": "System and Services Acquisition (SA)","Service": "kms","SubGroup": null,"SubSection": "External System Services (SA-9)"}],"description": "Maintain exclusive control of cryptographic keys for encrypted material stored or transmitted through an external system.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"sc_5_1": {"name": "SC-5(1) Restrict Ability TO Attack Other Systems","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_5_1","Section": "System and Communications Protection (SC)","Service": "guarduty","SubGroup": null,"SubSection": "Denial Of Service Protection (SC-5)"}],"description": "Restrict the ability of individuals to launch the following denial-of-service attacks against other systems: [Assignment: organization-defined denial-of-service attacks].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sc_5_2": {"name": "SC-5(2) Capacity, Bandwidth, And Redundancy","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL","redshift_cluster_automated_snapshot": null,"redshift_cluster_automatic_upgrades": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_5_2","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Denial Of Service Protection (SC-5)"}],"description": "Manage capacity, bandwidth, or other redundancy to limit the effects of information flooding denial-of-service attacks.","checks_status": {"fail": 5,"pass": 1,"total": 10,"manual": 0}},"sc_5_a": {"name": "SC-5(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_5_a","Section": "System and Communications Protection (SC)","Service": "guarduty","SubGroup": null,"SubSection": "Denial Of Service Protection (SC-5)"}],"description": "[Selection: Protect against; Limit] the effects of the following types of denial-of-service events: [Assignment: organization-defined types of denial-of-service events].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sc_5_b": {"name": "SC-5(b)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_5_b","Section": "System and Communications Protection (SC)","Service": "guarduty","SubGroup": null,"SubSection": "Denial Of Service Protection (SC-5)"}],"description": "Employ the following controls to achieve the denial-of-service objective: [Assignment: organization-defined controls by type of denial-of-service event].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sc_7_2": {"name": "SC-7(2) Public Access","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_2","Section": "System and Communications Protection (SC)","Service": "guarduty","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Provide the capability to dynamically isolate [Assignment: organization-defined system components] from other system components.","checks_status": {"fail": 1,"pass": 5,"total": 13,"manual": 0}},"sc_7_3": {"name": "SC-7(3) Access Points","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_3","Section": "System and Communications Protection (SC)","Service": "guarduty","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Limit the number of external network connections to the system.","checks_status": {"fail": 1,"pass": 5,"total": 13,"manual": 0}},"sc_7_5": {"name": "SC-7(5) Deny By Default — Allow By Exception","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_5","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Deny network communications traffic by default and allow network communications traffic by exception [Selection (one or more): at managed interfaces; for [Assignment: organization-defined systems]].","checks_status": {"fail": 5,"pass": 0,"total": 6,"manual": 0}},"sc_7_7": {"name": "SC-7(7) Split Tunneling For Remote Devices","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_7","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Prevent split tunneling for remote devices connecting to organizational systems unless the split tunnel is securely provisioned using [Assignment: organization-defined safeguards].","checks_status": {"fail": 3,"pass": 5,"total": 16,"manual": 0}},"sc_7_a": {"name": "SC-7(a)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_a","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Monitor and control communications at the external managed interfaces to the system and at key internal managed interfaces within the system.","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"sc_7_b": {"name": "SC-7(b)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_b","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Implement subnetworks for publicly accessible system components that are [Selection: physically; logically] separated from internal organizational networks.","checks_status": {"fail": 1,"pass": 5,"total": 13,"manual": 0}},"sc_7_c": {"name": "SC-7(c)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_c","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Connect to external networks or systems only through managed interfaces consisting of boundary protection devices arranged in accordance with an organizational security and privacy architecture.","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"sc_8_1": {"name": "SC-8(1) Cryptographic Protection","checks": {"elb_ssl_listeners": "FAIL","elbv2_insecure_ssl_ciphers": "PASS","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_8_1","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Transmission Confidentiality And Integrity (SC-8)"}],"description": "Implement cryptographic mechanisms to [Selection (one or more): prevent unauthorized disclosure of information; detect changes to information] during transmission.","checks_status": {"fail": 3,"pass": 1,"total": 5,"manual": 0}},"sc_8_2": {"name": "SC-8(2) Pre- And Post-Transmission Handling","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_8_2","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Transmission Confidentiality And Integrity (SC-8)"}],"description": "Maintain the [Selection (one or more): confidentiality; integrity] of information during preparation for transmission and during reception.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"sc_8_3": {"name": "SC-8(3) Cryptographic Protection For Message Externals","checks": {"elb_ssl_listeners": "FAIL","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_8_3","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Transmission Confidentiality And Integrity (SC-8)"}],"description": "Implement cryptographic mechanisms to protect message externals unless otherwise protected by [Assignment: organization-defined alternative physical controls].","checks_status": {"fail": 8,"pass": 3,"total": 18,"manual": 0}},"sc_8_4": {"name": "SC-8(4) Conceal Or Ramdomize Communications","checks": {"elb_ssl_listeners": "FAIL","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_8_4","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Transmission Confidentiality And Integrity (SC-8)"}],"description": "Implement cryptographic mechanisms to conceal or randomize communication patterns unless otherwise protected by [Assignment: organization-defined alternative physical controls].","checks_status": {"fail": 8,"pass": 3,"total": 18,"manual": 0}},"sc_8_5": {"name": "SC-8(5) Protected Distribution System","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_8_5","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Transmission Confidentiality And Integrity (SC-8)"}],"description": "Implement [Assignment: organization-defined protected distribution system] to [Selection (one or more): prevent unauthorized disclosure of information; detect changes to information] during transmission.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"si_2_2": {"name": "SI-2(2) Automated Flaw Remediation Status","checks": {"ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_2_2","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Flaw Remediation (SI-2)"}],"description": "Determine if system components have applicable security-relevant software and firmware updates installed using [Assignment: organization-defined automated mechanisms] [Assignment: organization-defined frequency].","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"si_2_5": {"name": "SI-2(5) Automatic Software And Firmware Updated","checks": {"ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_2_5","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Flaw Remediation (SI-2)"}],"description": "Install [Assignment: organization-defined security-relevant software and firmware updates] automatically to [Assignment: organization-defined system components].","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"si_2_a": {"name": "SI-2(a)","checks": {"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_2_a","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Flaw Remediation (SI-2)"}],"description": "Identify, report, and correct system flaws.","checks_status": {"fail": 1,"pass": 0,"total": 5,"manual": 0}},"si_2_c": {"name": "SI-2(c)","checks": {"ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_2_c","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Flaw Remediation (SI-2)"}],"description": "Install security-relevant software and firmware updates within [Assignment: organization-defined time period] of the release of the updates.","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"si_2_d": {"name": "SI-2(d)","checks": {"ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_2_d","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Flaw Remediation (SI-2)"}],"description": "Incorporate flaw remediation into the organizational configuration management process.","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"si_4_1": {"name": "SI-4(1) System-Wide Intrusion Detection System","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_1","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Connect and configure individual intrusion detection tools into a system-wide intrusion detection system.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_2": {"name": "SI-4(2) Automated Tools For Real-Time Analysis","checks": {"guardduty_is_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_4_2","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Implement the following additional monitoring of privileged users: [Assignment: organization-defined additional monitoring]. Employ automated tools and mechanisms to support near real-time analysis of events.","checks_status": {"fail": 3,"pass": 2,"total": 9,"manual": 0}},"si_4_3": {"name": "SI-4(3) Automated Tools And Mechanism Integration","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_3","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Employ automated tools and mechanisms to integrate intrusion detection tools and mechanisms into access control and flow control mechanisms.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_a": {"name": "SI-4(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_a","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Monitor the system to detect: 1. Attacks and indicators of potential attacks in accordance with the following monitoring objectives: [Assignment: organization-defined monitoring objectives]; and 2. Unauthorized local, network, and remote connections.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_b": {"name": "SI-4(b)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_b","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Identify unauthorized use of the system through the following techniques and methods: [Assignment: organization-defined techniques and methods].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_c": {"name": "SI-4(c)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_c","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "c. Invoke internal monitoring capabilities or deploy monitoring devices: 1. Strategically within the system to collect organization-determined essential information; and 2. At ad hoc locations within the system to track specific types of transactions of interest to the organization.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_d": {"name": "SI-4(d)","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_4_d","Section": "System and Information integrity (SI)","Service": "cloudtrail","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Analyze detected events and anomalies.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"si_5_1": {"name": "SI-5(1) Automated Alerts And Advisories","checks": {"guardduty_is_enabled": "PASS","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_5_1","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Secuity Alerts, Advisories, And Directives (SI-5)"}],"description": "Broadcast security alert and advisory information throughout the organization using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 0,"pass": 1,"total": 5,"manual": 0}},"si_5_b": {"name": "SI-5(b)","checks": {"guardduty_is_enabled": "PASS","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_5_b","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Secuity Alerts, Advisories, And Directives (SI-5)"}],"description": "Generate internal security alerts, advisories, and directives as deemed necessary.","checks_status": {"fail": 0,"pass": 1,"total": 5,"manual": 0}},"si_7_1": {"name": "SI-7(1) Integrity Checks","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_7_1","Section": "System and Information integrity (SI)","Service": "cloudtrail","SubGroup": null,"SubSection": "Software, Firmware, and Information Integrity (SI-7)"}],"description": "Perform an integrity check of [Assignment: organization-defined software, firmware, and information] [Selection (one or more): at startup; at [Assignment: organization-defined transitional states or security-relevant events]; [Assignment: organization-defined frequency]].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"si_7_3": {"name": "SI-7(3) Centrally Managed Integrity Tools","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_7_3","Section": "System and Information integrity (SI)","Service": "cloudtrail","SubGroup": null,"SubSection": "Software, Firmware, and Information Integrity (SI-7)"}],"description": "Employ centrally managed integrity verification tools.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"si_7_7": {"name": "SI-7(7) Integration Of Detection And Response","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_7_7","Section": "System and Information integrity (SI)","Service": "cloudtrail","SubGroup": null,"SubSection": "Software, Firmware, and Information Integrity (SI-7)"}],"description": "Incorporate the detection of the following unauthorized changes into the organizational incident response capability: [Assignment: organization-defined security-relevant changes to the system].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"si_7_8": {"name": "SI-7(8) Auditing Capability For Significant Events","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_7_8","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Software, Firmware, and Information Integrity (SI-7)"}],"description": "Upon detection of a potential integrity violation, provide the capability to audit the event and initiate the following actions: [Selection (one or more): generate an audit record; alert current user; alert [Assignment: organization-defined personnel or roles]; [Assignment: organization-defined other actions]].","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"si_7_a": {"name": "SI-7(a)","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_7_a","Section": "System and Information integrity (SI)","Service": "cloudtrail","SubGroup": null,"SubSection": "Software, Firmware, and Information Integrity (SI-7)"}],"description": "Employ integrity verification tools to detect unauthorized changes to the following software, firmware, and information: [Assignment: organization-defined software, firmware, and information].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ac_16_b": {"name": "AC-16(b)","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_16_b","Section": "Access Control (AC)","Service": "cloudwatch","SubGroup": null,"SubSection": "Security And Privacy Attributes (AC-16)"}],"description": "Ensure that the attribute associations are made and retained with the information.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ac_17_1": {"name": "AC-17(1) Monitoring And Control","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_17_1","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Remote Access (AC-17)"}],"description": "Employ automated mechanisms to monitor and control remote access methods.","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"ac_17_2": {"name": "AC-17(2) Protection Of Confidentiality And Integrity Using Encryption","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_17_2","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Remote Access (AC-17)"}],"description": "Implement cryptographic mechanisms to protect the confidentiality and integrity of remote access sessions.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"ac_17_9": {"name": "AC-17(9) Disconnect Or Disable Access","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_17_9","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Remote Access (AC-17)"}],"description": "Provide the capability to disconnect or disable remote access to the system within [Assignment: organization-defined time period].","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"ac_17_b": {"name": "AC-17(b)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_17_b","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Remote Access (AC-17)"}],"description": "Authorize each type of remote access to the system prior to allowing such connections.","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"ac_24_1": {"name": "AC-24(1)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_24_1","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Access Control Decisions (AC-24)"}],"description": "Transmit [Assignment: organization-defined access authorization information] using [Assignment: organization-defined controls] to [Assignment: organization-defined systems] that enforce access control decisions.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"ac_3_10": {"name": "AC-3(10) Audited Override Of Access Control Mechanisms","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_10","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Access Enforcement (AC-3)"}],"description": "Employ an audited override of automated access mechanisms under [Assignment: organization-defined conditions] by [Assignment: organization-defined roles].","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"ac_3_13": {"name": "AC-3(13) Attribute-Based Access Control","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_13","Section": "Access Control (AC)","Service": "guarduty","SubGroup": null,"SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce attribute-based access control policy over defined subjects and objects and control access based upon [Assignment: organization-defined attributes to assume access permissions].","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_4_21": {"name": "AC-4(21) Physical Or Logical Separation Of Infomation Flows","checks": {"ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"apigateway_restapi_waf_acl_attached": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_4_21","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Information Flow Enforcement (AC-4)"}],"description": "Separate information flows logically or physically using [Assignment: organization-defined mechanisms and/or techniques] to accomplish [Assignment: organization-defined required separations by types of information].","checks_status": {"fail": 5,"pass": 5,"total": 18,"manual": 0}},"ac_4_22": {"name": "AC-4(22) Access Only","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_4_22","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Information Flow Enforcement (AC-4)"}],"description": "Provide access from a single device to computing platforms, applications, or data residing in multiple different security domains, while preventing information flow between the different security domains.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"ac_4_26": {"name": "AC-4(26) Audit Filtering Actions","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_4_26","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Information Flow Enforcement (AC-4)"}],"description": "When transferring information between different security domains, record and audit content filtering actions and results for the information being filtered.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"ac_4_28": {"name": "AC-4(28) Linear Filter Pipelines","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_4_28","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Information Flow Enforcement (AC-4)"}],"description": "When transferring information between different security domains, implement a linear content filter pipeline that is enforced with discretionary and mandatory access controls.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_6_10": {"name": "AC-6(10)","checks": {"iam_no_root_access_key": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_6_10","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Least Privilege (AC-6)"}],"description": "Prevent non-privileged users from executing privileged functions.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"au_11_1": {"name": "AU-11(1) Long-Term Retrieval Capability","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_11_1","Section": "Audit and Accountability (AU)","Service": "cloudwatch","SubGroup": null,"SubSection": "Audit Record Retention (AU-11)"}],"description": "Employ [Assignment: organization-defined measures] to ensure that long-term audit records generated by the system can be retrieved.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"au_12_1": {"name": "AU-12(1) System-Wide And Time-Correlated Audit Trial","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_12_1","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Generation (AU-12)"}],"description": "Compile audit records from [Assignment: organization-defined system components] into a system-wide (logical or physical) audit trail that is time-correlated to within [Assignment: organization-defined level of tolerance for the relationship between time stamps of individual records in the audit trail].","checks_status": {"fail": 7,"pass": 2,"total": 13,"manual": 0}},"au_12_2": {"name": "AU-12(2) Standardized Formats","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_12_2","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Generation (AU-12)"}],"description": "Produce a system-wide (logical or physical) audit trail composed of audit records in a standardized format.","checks_status": {"fail": 7,"pass": 2,"total": 13,"manual": 0}},"au_12_3": {"name": "AU-12(3) Changes By Authorized Individuals","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_12_3","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Generation (AU-12)"}],"description": "Provide and implement the capability for [Assignment: organization-defined individuals or roles] to change the logging to be performed on [Assignment: organization-defined system components] based on [Assignment: organization-defined selectable event criteria] within [Assignment: organization-defined time thresholds].","checks_status": {"fail": 8,"pass": 4,"total": 20,"manual": 0}},"au_12_4": {"name": "AU-12(4) Query Parameter Audits Of Personally Identifiable Information","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_12_4","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Generation (AU-12)"}],"description": "Provide and implement the capability for auditing the parameters of user query events for data sets containing personally identifiable information.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_12_a": {"name": "AU-12(a)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_12_a","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Generation (AU-12)"}],"description": "Provide audit record generation capability for the event types the system is capable of auditing as defined in AU-2a on [Assignment: organization-defined system components].","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_12_c": {"name": "AU-12(c)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_12_c","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Generation (AU-12)"}],"description": "Generate audit records for the event types defined in AU-2c that include the audit record content defined in AU-3.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_14_3": {"name": "AU-14(3) Remote Viewing And Listening","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_14_3","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Session Audit (AU-14)"}],"description": "Provide and implement the capability for authorized users to remotely view and hear content related to an established user session in real time.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_14_a": {"name": "AU-14(a)","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_14_a","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Session Audit (AU-14)"}],"description": "Provide and implement the capability for [Assignment: organization-defined users or roles] to [Selection (one or more): record; view; hear; log] the content of a user session under [Assignment: organization-defined circumstances].","checks_status": {"fail": 8,"pass": 4,"total": 20,"manual": 0}},"au_14_b": {"name": "AU-14(b)","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_14_b","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Session Audit (AU-14)"}],"description": "Develop, integrate, and use session auditing activities in consultation with legal counsel and in accordance with applicable laws, executive orders, directives, regulations, policies, standards, and guidelines.","checks_status": {"fail": 8,"pass": 4,"total": 20,"manual": 0}},"cm_12_b": {"name": "CM-12(b)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "cm_12_b","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Information Location (CM-12)"}],"description": "Identify and document the users who have access to the system and system components where the information is processed and stored.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"cp_10_2": {"name": "CP-10(2) Transaction Recovery","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_10_2","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "System Recovery And Reconstitution (CP-10)"}],"description": "Implement transaction recovery for systems that are transaction-based.","checks_status": {"fail": 2,"pass": 1,"total": 6,"manual": 0}},"pm_11_b": {"name": "PM-11(b)","checks": {"s3_bucket_object_versioning": "FAIL","s3_bucket_default_encryption": "PASS","s3_bucket_secure_transport_policy": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pm_11_b","Section": "Program Management (PM)","Service": "aws","SubGroup": null,"SubSection": "Mission And Business Process Defination (PM-11)"}],"description": "Determine information protection and personally identifiable information processing needs arising from the defined mission and business processes.","checks_status": {"fail": 3,"pass": 1,"total": 4,"manual": 0}},"pm_14_b": {"name": "PM-14(b)","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pm_14_b","Section": "Program Management (PM)","Service": "aws","SubGroup": null,"SubSection": "Testing, Training, And Monitoring (PM-14)"}],"description": "Review testing, training, and monitoring plans for consistency with the organizational risk management strategy and organization-wide priorities for risk response actions.","checks_status": {"fail": 8,"pass": 4,"total": 20,"manual": 0}},"pm_17_b": {"name": "PM-17(b)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_object_versioning": "FAIL","s3_bucket_secure_transport_policy": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pm_17_b","Section": "Program Management (PM)","Service": "aws","SubGroup": null,"SubSection": "Protecting Controlled Unclassified Information On External Systems (PM-17)"}],"description": "Review and update the policy and procedures [Assignment: organization-defined frequency].","checks_status": {"fail": 5,"pass": 0,"total": 6,"manual": 0}},"pm_21_b": {"name": "PM-21(b)","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pm_21_b","Section": "Program Management (PM)","Service": "cloudwatch","SubGroup": null,"SubSection": "Accounting Of Disclosures (PM-21)"}],"description": "Retain the accounting of disclosures for the length of the time the personally identifiable information is maintained or five years after the disclosure is made, whichever is longer.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ra_10_a": {"name": "RA-10(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_10_a","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": null,"SubSection": "Threat Hunting (RA-10)"}],"description": "Establish and maintain a cyber threat hunting capability to: 1. Search for indicators of compromise in organizational systems; and 2. Detect, track, and disrupt threats that evade existings.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sa_10_1": {"name": "SA-10(1) Software And Firmware Integrity Verification","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sa_10_1","Section": "System and Services Acquisition (SA)","Service": "kms","SubGroup": null,"SubSection": "Developer Configuration Management (SA-10)"}],"description": "Require the developer of the system, system component, or system service to enable integrity verification of software and firmware components.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sc_12_2": {"name": "SC-12(2) Symmetric Keys","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_12_2","Section": "System and Communications Protection (SC)","Service": "kms","SubGroup": null,"SubSection": "Cryptographic Key Establishment And Management (SC-12)"}],"description": "Produce, control, and distribute symmetric cryptographic keys using [Selection: NIST FIPS-validated; NSA-approved] key management technology and processes.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"sc_12_6": {"name": "SC-12(6) Physical Control Of Keys","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_12_6","Section": "System and Communications Protection (SC)","Service": "kms","SubGroup": null,"SubSection": "Cryptographic Key Establishment And Management (SC-12)"}],"description": "Maintain physical control of cryptographic keys when stored information is encrypted by external service providers.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"sc_13_a": {"name": "SC-13(a)","checks": {"elb_ssl_listeners": "FAIL","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_13_a","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Cryptographic Protection (SC-13)"}],"description": "Determine the [Assignment: organization-defined cryptographic uses].","checks_status": {"fail": 8,"pass": 3,"total": 18,"manual": 0}},"sc_16_1": {"name": "SC-16(1) Integrity Verification","checks": {"s3_bucket_object_versioning": "FAIL","s3_bucket_default_encryption": "PASS","s3_bucket_secure_transport_policy": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_16_1","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Transmission Of Security And Privacy Attributes (SC-16)"}],"description": "Verify the integrity of transmitted security and privacy attributes.","checks_status": {"fail": 3,"pass": 1,"total": 4,"manual": 0}},"sc_23_3": {"name": "SC-23(3) Unique System-Generated Session Identifiers","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_23_3","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Session Authenticity (SC-23)"}],"description": "Generate a unique session identifier for each session with [Assignment: organization-defined randomness requirements] and recognize only session identifiers that are system-generated.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"sc_23_5": {"name": "SC-23(5) Allowed Certificate Authorities","checks": {"elb_ssl_listeners": "FAIL","elbv2_insecure_ssl_ciphers": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_23_5","Section": "System and Communications Protection (SC)","Service": "elb","SubGroup": null,"SubSection": "Session Authenticity (SC-23)"}],"description": "Only allow the use of [Assignment: organization-defined certificate authorities] for verification of the establishment of protected sessions.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"sc_28_1": {"name": "SC-28(1) Cryptographic Protection","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_28_1","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Protection Of Information At Rest (SC-28)"}],"description": "Implement cryptographic mechanisms to prevent unauthorized disclosure and modification of the following information at rest on [Assignment: organization-defined system components or media]: [Assignment: organization-defined information].","checks_status": {"fail": 5,"pass": 3,"total": 14,"manual": 0}},"sc_28_2": {"name": "SC-28(2) Offline Storage","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_28_2","Section": "System and Communications Protection (SC)","Service": "cloudwatch","SubGroup": null,"SubSection": "Protection Of Information At Rest (SC-28)"}],"description": "Remove the following information from online storage and store offline in a secure location: [Assignment: organization-defined information].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sc_43_b": {"name": "SC-43(b)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_43_b","Section": "System and Communications Protection (SC)","Service": "guarduty","SubGroup": null,"SubSection": "Usage Restrictions (SC-43)"}],"description": "Authorize, monitor, and control the use of such components within the system.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sc_7_11": {"name": "SC-7(11) Restrict Incoming communications Traffic","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_11","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Only allow incoming communications from [Assignment: organization-defined authorized sources] to be routed to [Assignment: organization-defined authorized destinations].","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"sc_7_12": {"name": "SC-7(12) Host-Based Protection","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"acm_certificates_expiration_check": "PASS","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_12","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Implement [Assignment: organization-defined host-based boundary protection mechanisms] at [Assignment: organization-defined system components].","checks_status": {"fail": 3,"pass": 7,"total": 17,"manual": 0}},"sc_7_16": {"name": "SC-7(16) Prevent Discovery Of System Components","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"acm_certificates_expiration_check": "PASS","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_16","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Prevent the discovery of specific system components that represent a managed interface.","checks_status": {"fail": 3,"pass": 7,"total": 17,"manual": 0}},"sc_7_20": {"name": "SC-7(20) Prevent Discovery Of System Components","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_20","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Prevent the discovery of specific system components that represent a managed interface.","checks_status": {"fail": 1,"pass": 5,"total": 13,"manual": 0}},"sc_7_21": {"name": "SC-7(21) Isolation Of System Components","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_21","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Employ boundary protection mechanisms to isolate [Assignment: organization-defined system components] supporting [Assignment: organization-defined missions and/or business functions].","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"sc_7_25": {"name": "SC-7(25) Unclassified National Security System Connections","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_25","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Prohibit the direct connection of [Assignment: organization-defined unclassified national security system] to an external network without the use of [Assignment: organization-defined boundary protection device].","checks_status": {"fail": 3,"pass": 5,"total": 15,"manual": 0}},"sc_7_26": {"name": "SC-7(26) Classified National Security System Connections","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_26","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Prohibit the direct connection of a classified national security system to an external network without the use of [Assignment: organization-defined boundary protection device].","checks_status": {"fail": 3,"pass": 5,"total": 15,"manual": 0}},"sc_7_27": {"name": "SC-7(27) Unclassified Non-National Security System Connections","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_27","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Prohibit the direct connection of [Assignment: organization-defined unclassified non-national security system] to an external network without the use of [Assignment: organization-defined boundary protection device].","checks_status": {"fail": 3,"pass": 5,"total": 15,"manual": 0}},"sc_7_28": {"name": "SC-7(28) Connections To Public Networks","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_28","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Prohibit the direct connection of [Assignment: organization-defined system] to a public network.","checks_status": {"fail": 3,"pass": 5,"total": 15,"manual": 0}},"si_13_5": {"name": "SI-13(5) Failover Capability","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL","redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_13_5","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Predictable Failure Prevention (SI-13)"}],"description": "Provide [Selection: real-time; near real-time] [Assignment: organization-defined failover capability] for the system.","checks_status": {"fail": 4,"pass": 1,"total": 8,"manual": 0}},"si_19_4": {"name": "SI-19(4) Removal, Masking, Encryption, Hashing, Or Replacement Of Direct Identifiers","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_19_4","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "De-Identification (SI-19)"}],"description": "Remove, mask, encrypt, hash, or replace direct identifiers in a dataset.","checks_status": {"fail": 4,"pass": 3,"total": 13,"manual": 0}},"si_4_10": {"name": "SI-4(10) Visibility Of Encrypted Communications","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_10","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Make provisions so that [Assignment: organization-defined encrypted communications traffic] is visible to [Assignment: organization-defined system monitoring tools and mechanisms].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_12": {"name": "SI-4(12) Automated Organization-Generated Alerts","checks": {"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_12","Section": "System and Information integrity (SI)","Service": "cloudwatch","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Alert [Assignment: organization-defined personnel or roles] using [Assignment: organization-defined automated mechanisms] when the following indications of inappropriate or unusual activities with security or privacy implications occur: [Assignment: organization-defined activities that trigger alerts].","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"si_4_14": {"name": "SI-4(14) Wireless Intrusion Detection","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_14","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Employ a wireless intrusion detection system to identify rogue wireless devices and to detect attack attempts and potential compromises or breaches to the system.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_17": {"name": "SI-4(17) Integrated Situational Awareness","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_4_17","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Correlate information from monitoring physical, cyber, and supply chain activities to achieve integrated, organization-wide situational awareness.","checks_status": {"fail": 7,"pass": 2,"total": 13,"manual": 0}},"si_4_20": {"name": "SI-4(20) Privileged Users","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_4_20","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Implement the following additional monitoring of privileged users: [Assignment: organization-defined additional monitoring].","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"si_4_23": {"name": "SI-4(23) Host-Based Devices","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_23","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Implement the following host-based monitoring mechanisms at [Assignment: organization-defined system components]: [Assignment: organization-defined host-based monitoring mechanisms].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_25": {"name": "SI-4(25) Optimize Network Traffic Analysis","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_25","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Provide visibility into network traffic at external and key internal system interfaces to optimize the effectiveness of monitoring devices.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ac_17_10": {"name": "AC-17(10) Authenticate Remote Commands","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_17_10","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Remote Access (AC-17)"}],"description": "Provide the capability to disconnect or disable remote access to the system within [Assignment: organization-defined time period].","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"ac_2_3_a": {"name": "AC-2(3)(a)","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_3_a","Section": "Access Control (AC)","Service": "iam","SubGroup": "AC-2(3) Disable Accounts","SubSection": "Account Management (AC-2)"}],"description": "Support the management of system accounts using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"ac_2_3_b": {"name": "AC-2(3)(b)","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_3_b","Section": "Access Control (AC)","Service": "iam","SubGroup": "AC-2(3) Disable Accounts","SubSection": "Account Management (AC-2)"}],"description": "Disable accounts within [Assignment: organization-defined time period] when the accounts: (b) Are no longer associated with a user or individual.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"ac_2_3_c": {"name": "AC-2(3)(c)","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_3_c","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-2(3) Disable Accounts","SubSection": "Account Management (AC-2)"}],"description": "Disable accounts within [Assignment: organization-defined time period] when the accounts: (c) Are in violation of organizational policy.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"ac_2_3_d": {"name": "AC-2(3)(d)","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_3_d","Section": "Access Control (AC)","Service": "iam","SubGroup": "AC-2(3) Disable Accounts","SubSection": "Account Management (AC-2)"}],"description": "Disable accounts within [Assignment: organization-defined time period] when the accounts: (d) Have been inactive for [Assignment: organization-defined time period].","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"ac_2_d_1": {"name": "AC-2(d)(1)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_d_1","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "d. Specify: 1. Authorized users of the system;personnel termination and transfer processes.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ac_2_i_2": {"name": "AC-2(i)(2)","checks": {"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_Ā”_2","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "i. Authorize access to the system based on: 2. Intended system usage.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ac_3_3_a": {"name": "AC-3(3)(a)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_3_a","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(3) Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access policy] over the set of covered subjects and objects specified in the policy, and where the policy: (a) Is uniformly enforced across the covered subjects and objects within the system.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_3_c": {"name": "AC-3(3)(c)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_3_c","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(3) Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access policy] over the set of covered subjects and objects specified in the policy, and where the policy: (c) Specifies that [Assignment: organization-defined subjects] may explicitly be granted [Assignment: organization-defined privileges] such that they are not limited by any defined subset (or all) of the above constraints.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_4_a": {"name": "AC-3(4)(a)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_4_a","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(4) Discretionary Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined discretionary access policy] over the set of covered subjects and objects specified in the policy, and where the policy specifies that a subject that has been granted access to information can do one or more of the following: (a) Pass the information to any other subjects or objects.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_4_b": {"name": "AC-3(4)(b)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_4_b","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(4) Discretionary Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined discretionary access policy] over the set of covered subjects and objects specified in the policy, and where the policy specifies that a subject that has been granted access to information can do one or more of the following: (b) Grant its privileges to other subjects.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_4_c": {"name": "AC-3(4)(c)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_4_c","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(4) Discretionary Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined discretionary access policy] over the set of covered subjects and objects specified in the policy, and where the policy specifies that a subject that has been granted access to information can do one or more of the following: (c) Change security attributes on subjects, objects, the system, or the system’s components.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_4_d": {"name": "AC-3(4)(d)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_4_d","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(4) Discretionary Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined discretionary access policy] over the set of covered subjects and objects specified in the policy, and where the policy specifies that a subject that has been granted access to information can do one or more of the following: (d) Choose the security attributes to be associated with newly created or revised objects.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_4_e": {"name": "AC-3(4)(e)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_4_e","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(4) Discretionary Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined discretionary access policy] over the set of covered subjects and objects specified in the policy, and where the policy specifies that a subject that has been granted access to information can do one or more of the following: (e) Change the rules governing access.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_7_4_a": {"name": "AC-7(4)(a)","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_7_4_a","Section": "Access Control (AC)","Service": "iam","SubGroup": "AC-7(4) Use Of Alternate Authentication Factor","SubSection": "Unsuccessful Logon Attempts (AC-7)"}],"description": "Allow the use of [Assignment: organization-defined authentication factors] that are different from the primary authentication factors after the number of organization-defined consecutive invalid logon attempts have been exceeded.","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"ca_7_4_c": {"name": "CA-7(4)(c)","checks": {"elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ca_7_4_c","Section": "Assessment, Authorization, And Monitoring (CA)","Service": "aws","SubGroup": "CA-7(4) Risk Monitoring","SubSection": "Continuous Monitoring (CA-7)"}],"description": "Ensure risk monitoring is an integral part of the continuous monitoring strategy that includes the following: (c) Change monitoring.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_2_b_1": {"name": "CM-2(b)(1)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_2_b_1","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-2(b)","SubSection": "Baseline Configuration (CM-2)"}],"description": "Review and update the baseline configuration of the system: 1. [Assignment: organization-defined frequency].","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"cm_2_b_2": {"name": "CM-2(b)(2)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_2_b_2","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-2(b)","SubSection": "Baseline Configuration (CM-2)"}],"description": "Review and update the baseline configuration of the system: 2. When required due to [Assignment: organization-defined circumstances].","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"cm_2_b_3": {"name": "CM-2(b)(3)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_2_b_3","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-2(b)","SubSection": "Baseline Configuration (CM-2)"}],"description": "Review and update the baseline configuration of the system: 3 When system components are installed or upgraded.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"cm_5_1_a": {"name": "CM-5(1)(a)","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","ec2_instance_profile_attached": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_5_1_a","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-5(1) Automated Access Enforcement And Audit Records","SubSection": "Access Restrictions For Change (CM-5)"}],"description": "Enforce access restrictions using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 1,"pass": 2,"total": 15,"manual": 0}},"cm_5_1_b": {"name": "CM-5(1)(b)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_5_1_b","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-5(1) Automated Access Enforcement And Audit Records","SubSection": "Access Restrictions For Change (CM-5)"}],"description": "Automatically generate audit records of the enforcement actions.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"cm_8_3_a": {"name": "CM-8(3)(a)","checks": {"guardduty_is_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_3_a","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-8(3) Automated Unauthorized Component Detection","SubSection": "System Component Inventory (CM-8)"}],"description": "Detect the presence of unauthorized hardware, software, and firmware components within the system using [Assignment: organization-defined automated mechanisms] [Assignment: organization-defined frequency].","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"cm_8_a_1": {"name": "CM-8(a)(1)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_a_1","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-8(a)","SubSection": "System Component Inventory (CM-8)"}],"description": "Develop and document an inventory of system components that: 1. Accurately reflects the system.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_8_a_2": {"name": "CM-8(a)(2)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_a_2","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-8(a)","SubSection": "System Component Inventory (CM-8)"}],"description": "Develop and document an inventory of system components that: 2. Includes all components within the system.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_8_a_3": {"name": "CM-8(a)(3)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_a_3","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-8(a)","SubSection": "System Component Inventory (CM-8)"}],"description": "Develop and document an inventory of system components that: 3. Does not include duplicate accounting of components or components assigned to any other system.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_8_a_4": {"name": "CM-8(a)(4)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_a_4","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-8(a)","SubSection": "System Component Inventory (CM-8)"}],"description": "Develop and document an inventory of system components that: 4. Is at the level of granularity deemed necessary for tracking and reporting.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_8_a_5": {"name": "CM-8(a)(5)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_a_5","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-8(a)","SubSection": "System Component Inventory (CM-8)"}],"description": "Develop and document an inventory of system components that: 5. Includes the following information to achieve system component accountability: [Assignment: organization-defined information deemed necessary to achieve effective system component accountability].","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cp_1_a_2": {"name": "CP-1(a)(2)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_1_a_2","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": "CP-1(a)","SubSection": "Policy And Procedures (CP-1)"}],"description": "a. Develop, document, and disseminate to [Assignment: organization-defined personnel or roles]: 2. Procedures to facilitate the implementation of the contingency planning policy and the associated contingency planning controls.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"cp_2_a_6": {"name": "CP-2(a)(6)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_2_a_6","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": "CP-2(a)","SubSection": "Contingency Plan (CP-2)"}],"description": "Develop a contingency plan for the system that: 6. Addresses the sharing of contingency information.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"cp_2_a_7": {"name": "CP-2(a)(7)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_2_a_7","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": "CP-2(a)","SubSection": "Contingency Plan (CP-2)"}],"description": "Develop a contingency plan for the system that: 7. Is reviewed and approved by [Assignment: organization-defined personnel or roles].","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"ia_2_6_a": {"name": "IA-2(6)(a)","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2_6_a","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": "IA-2(6) Acces To Accounts — Separate Device","SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "Implement multi-factor authentication for [Selection (one or more): local; network; remote] access to [Selection (one or more): privileged accounts; non-privileged accounts] such that: (a) One of the factors is provided by a device separate from the system gaining access.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ia_3_3_b": {"name": "IA-3(3)(b)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ia_3_3_b","Section": "Identification and Authentication (IA)","Service": "aws","SubGroup": "IA-3(3) Dynamic Address Allocation","SubSection": "Device Identification And Authentication (IA-3)"}],"description": "Audit lease information when assigned to a device.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"ia_5_1_c": {"name": "IA-5(1)(c)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ia_5_1_c","Section": "Identification and Authentication (IA)","Service": "aws","SubGroup": "IA-5(1) Password-Based Authentication","SubSection": "Authenticator Management (IA-5)"}],"description": "For password-based authentication: (c) Transmit passwords only over cryptographically-protected channels.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"ia_5_1_f": {"name": "IA-5(1)(f)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_1_f","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": "IA-5(1) Password-Based Authentication","SubSection": "Authenticator Management (IA-5)"}],"description": "For password-based authentication: (f) Allow user selection of long passwords and passphrases, including spaces and all printable characters.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_1_g": {"name": "IA-5(1)(g)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_1_g","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": "IA-5(1) Password-Based Authentication","SubSection": "Authenticator Management (IA-5)"}],"description": "For password-based authentication: (g) Employ automated tools to assist the user in selecting strong password authenticators.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_1_h": {"name": "IA-5(1)(h)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_1_h","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": "IA-5(1) Password-Based Authentication","SubSection": "Authenticator Management (IA-5)"}],"description": "For password-based authentication: (h) Enforce the following composition and complexity rules: [Assignment: organization-defined composition and complexity rules].","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_8_2_b": {"name": "IA-8(2)(b)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_8_2_b","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": "IA-8(2) Acceptance Of External Authenticators","SubSection": "Identification And Authentication (Non-Organizational Users) (IA-8)"}],"description": "Document and maintain a list of accepted external authenticators.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ma_4_1_a": {"name": "MA-4(1)(a)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ma_4_1_a","Section": "Maintenance (MA)","Service": "aws","SubGroup": "MA-4(1) Logging And Review","SubSection": "Nonlocal Maintenance (MA-4)"}],"description": "Log [Assignment: organization-defined audit events] for nonlocal maintenance and diagnostic sessions.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"ra_1_a_1": {"name": "RA-1(a)(1)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_1_a_1","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": "RA-1(a)","SubSection": "Policy And Procedures (RA-1)"}],"description": "Establish and maintain a cyber threat hunting capability to: 1. Search for indicators of compromise in organizational systems.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ra_1_a_2": {"name": "RA-1(a)(2)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_1_a_2","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": "RA-1(a)","SubSection": "Policy And Procedures (RA-1)"}],"description": "a. Establish and maintain a cyber threat hunting capability to: 2. Detect, track, and disrupt threats that evade existing controls.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ra_3_a_1": {"name": "RA-3(a)(1)","checks": {"guardduty_is_enabled": "PASS","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ra_3_a_1","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": null,"SubSection": "Risk Assessment (RA-3)"}],"description": "a. Conduct a risk assessment, including: 1. Identifying threats to and vulnerabilities in the system.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"sc_5_3_a": {"name": "SC-5(3)(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_5_3_a","Section": "System and Communications Protection (SC)","Service": "guarduty","SubGroup": "SC-5(3) Detection And Monitoring","SubSection": "Denial Of Service Protection (SC-5)"}],"description": "Employ the following monitoring tools to detect indicators of denial-of-service attacks against, or launched from, the system: [Assignment: organization-defined monitoring tools].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sc_5_3_b": {"name": "SC-5(3)(b)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_5_3_b","Section": "System and Communications Protection (SC)","Service": "guarduty","SubGroup": "SC-5(3) Detection And Monitoring","SubSection": "Denial Of Service Protection (SC-5)"}],"description": "Monitor the following system resources to determine if sufficient resources exist to prevent effective denial-of-service attacks: [Assignment: organization-defined system resources].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sc_7_4_b": {"name": "SC-7(4)(b)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_4_b","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": "SC-7(4) External Telecommunications Services","SubSection": "Boundary Protection (SC-7)"}],"description": "Establish a traffic flow policy for each managed interface.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"sc_7_4_g": {"name": "SC-7(4)(g)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_4_g","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": "SC-7(4) External Telecommunications Services","SubSection": "Boundary Protection (SC-7)"}],"description": "Publish information to enable remote networks to detect unauthorized control plane traffic from internal networks.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"sc_7_9_a": {"name": "SC-7(9)(a)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_9_a","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": "SC-7(9) Restrict Threatening Outgoing Communications Traffic","SubSection": "Boundary Protection (SC-7)"}],"description": "Detect and deny outgoing communications traffic posing a threat to external systems.","checks_status": {"fail": 1,"pass": 5,"total": 13,"manual": 0}},"sc_7_9_b": {"name": "SC-7(9)(b)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_9_b","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": "SC-7(9) Restrict Threatening Outgoing Communications Traffic","SubSection": "Boundary Protection (SC-7)"}],"description": "Audit the identity of internal users associated with denied communications.","checks_status": {"fail": 5,"pass": 2,"total": 11,"manual": 0}},"si_1_1_c": {"name": "SI-1(1)(c)","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_1_1_c","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Policy And Procedures (SI-1)"}],"description": "Audit the use of the manual override capability.","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"si_1_a_2": {"name": "SI-1(a)(2)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_object_versioning": "FAIL","s3_bucket_secure_transport_policy": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_1_a_2","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Policy And Procedures (SI-1)"}],"description": "a. Develop, document, and disseminate to [Assignment: organization-defined personnel or roles]: 2. Procedures to facilitate the implementation of the system and information integrity policy and the associated system and information integrity controls;.","checks_status": {"fail": 5,"pass": 0,"total": 6,"manual": 0}},"si_3_8_a": {"name": "SI-3(8)(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_3_8_a","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": "SI-3(8) Detect Unauthorized Commands","SubSection": "Malicious Code Protection (SI-3)"}],"description": "Detect the following unauthorized operating system commands through the kernel application programming interface on [Assignment: organization-defined system hardware components]: [Assignment: organization-defined unauthorized operating system commands].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_3_8_b": {"name": "SI-3(8)(b)","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_3_8_b","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": "SI-3(8) Detect Unauthorized Commands","SubSection": "Malicious Code Protection (SI-3)"}],"description": "[Selection (one or more): issue a warning; audit the command execution; prevent the execution of the command].","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"si_3_c_2": {"name": "SI-3(c)(2)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_3_c_2","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Malicious Code Protection (SI-3)"}],"description": "c. Configure malicious code protection mechanisms to: 2. [Selection (one or more): block malicious code; quarantine malicious code; take [Assignment: organization-defined action]]; and send alert to [Assignment: organization-defined personnel or roles] in response to malicious code detection.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"si_4_4_a": {"name": "SI-4(4)(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_4_a","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": "SI-4(4) Inbound and Outbound Communications Traffic","SubSection": "System Monitoring (SI-4)"}],"description": "Determine criteria for unusual or unauthorized activities or conditions for inbound and outbound communications traffic.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_4_b": {"name": "SI-4(4)(b)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_4_b","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": "SI-4(4) Inbound and Outbound Communications Traffic","SubSection": "System Monitoring (SI-4)"}],"description": "Monitor inbound and outbound communications traffic [Assignment: organization-defined frequency] for [Assignment: organization-defined unusual or unauthorized activities or conditions].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_a_1": {"name": "SI-4(a)(1)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_a_1","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": "SI-4(a)","SubSection": "System Monitoring (SI-4)"}],"description": "a. Monitor the system to detect: 1. Attacks and indicators of potential attacks in accordance with the following monitoring objectives: [Assignment: organization-defined monitoring objectives]; and 2. Unauthorized local, network, and remote connections.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_a_2": {"name": "SI-4(a)(2)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_a_2","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": "SI-4(a)","SubSection": "System Monitoring (SI-4)"}],"description": "a. Monitor the system to detect: 2. Unauthorized local, network, and remote connections.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ac_17_4_a": {"name": "AC-17(4)(a)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_17_4_a","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-17(4) Privileged Commands And Access","SubSection": "Remote Access (AC-17)"}],"description": "Authorize the execution of privileged commands and access to security-relevant information via remote access only in a format that provides assessable evidence and for the following needs: [Assignment: organization-defined needs];","checks_status": {"fail": 3,"pass": 5,"total": 16,"manual": 0}},"ac_2_12_a": {"name": "AC-2(12)(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_12_a","Section": "Access Control (AC)","Service": "guarduty","SubGroup": "AC-2(12) Account Monitoring","SubSection": "Account Management (AC-2)"}],"description": "Monitor system accounts for [Assignment: organization-defined atypical usage].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ac_3_12_a": {"name": "AC-3(12)(a)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_12_a","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(12)Assert And Enforce Application Access","SubSection": "Access Enforcement (AC-3)"}],"description": "Require applications to assert, as part of the installation process, the access needed to the following system applications and functions: [Assignment: organization-defined system applications and functions].","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_12_b": {"name": "AC-3(12)(b)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_3_12_b","Section": "Access Control (AC)","Service": "guarduty","SubGroup": "AC-3(12) Assert And Enforce Application Access","SubSection": "Access Enforcement (AC-3)"}],"description": "Provide an enforcement mechanism to prevent unauthorized access;","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ac_3_15_a": {"name": "AC-3(15)(a)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_15_a","Section": "Access Control (AC)","Service": "guarduty","SubGroup": "AC-3(15) Discretionary And Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access control policy] over the set of covered subjects and objects specified in the policy.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_15_b": {"name": "AC-3(15)(b)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_15_b","Section": "Access Control (AC)","Service": "guarduty","SubGroup": "AC-3(15) Discretionary And Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined discretionary access control policy] over the set of covered subjects and objects specified in the policy.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ia_5_18_a": {"name": "IA-5(18)(a)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_18_a","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": "IA-5(18) Password Managers","SubSection": "Authenticator Management (IA-5)"}],"description": "Employ [Assignment: organization-defined password managers] to generate and manage passwords.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_18_b": {"name": "IA-5(18)(b)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_18_b","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": "IA-5(18) Password Managers","SubSection": "Authenticator Management (IA-5)"}],"description": "Protect the passwords using [Assignment: organization-defined controls].","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"pm_14_a_1": {"name": "PM-14(a)(1)","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pm_14_a_1","Section": "Program Management (PM)","Service": "aws","SubGroup": null,"SubSection": "Testing, Training, And Monitoring (PM-14)"}],"description": "a. Implement a process for ensuring that organizational plans for conducting security and privacy testing, training, and monitoring activities associated with organizational systems: 1. Are developed and maintained.","checks_status": {"fail": 8,"pass": 4,"total": 20,"manual": 0}},"ra_10_a_1": {"name": "RA-10(a)(1)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_10_a_1","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": "RA-10(a)","SubSection": "Threat Hunting (RA-10)"}],"description": "Establish and maintain a cyber threat hunting capability to: 1. Search for indicators of compromise in organizational systems; and 2. Detect, track, and disrupt threats that evade existings.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ra_10_a_2": {"name": "RA-10(a)(2)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_10_a_2","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": "RA-10(a)","SubSection": "Threat Hunting (RA-10)"}],"description": "a. Establish and maintain a cyber threat hunting capability to: 2. Detect, track, and disrupt threats that evade existings.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sa_15_a_4": {"name": "SA-15(a)(4)","checks": {"elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sa_15_a_4","Section": "System and Services Acquisition (SA)","Service": "aws","SubGroup": null,"SubSection": "Development Process, Standards, And Tools (SA-15)"}],"description": "a. Require the developer of the system, system component, or system service to follow a documented development process that: 4. Documents, manages, and ensures the integrity of changes to the process and/or tools used in development.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"sc_36_1_a": {"name": "SC-36(1)(a)","checks": {"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_36_1_a","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Distributed Processing And Storage (SC-36)"}],"description": "Employ polling techniques to identify potential faults, errors, or compromises to the following processing and storage components: [Assignment: organization-defined distributed processing and storage components].","checks_status": {"fail": 1,"pass": 0,"total": 5,"manual": 0}},"sc_7_24_b": {"name": "SC-7(24)(b)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_24_b","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": "SC-7(24) Personally Identifiable Information","SubSection": "Boundary Protection (SC-7)"}],"description": "For systems that process personally identifiable information: (b) Monitor for permitted processing at the external interfaces to the system and at key internal boundaries within the system.","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"si_10_1_c": {"name": "SI-10(1)(c)","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_10_1_c","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": "SI-10(1) Manual Override Capability","SubSection": "Information Input Validation (SI-10)"}],"description": "Audit the use of the manual override capability.","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"si_4_13_a": {"name": "SI-4(13)(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_13_a","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": "SI-4(13) Analyze Traffic And Event Patterns","SubSection": "System Monitoring (SI-4)"}],"description": "Analyze communications traffic and event patterns for the system.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ac_3_3_b_1": {"name": "AC-3(3)(b)(1)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_3_b_1","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(3) Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access policy] over the set of covered subjects and objects specified in the policy, and where the policy: (b) Specifies that a subject that has been granted access to information is constrained from doing any of the following; (1) Passing the information to unauthorized subjects or objects.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_3_b_2": {"name": "AC-3(3)(b)(2)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_3_b_2","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(3) Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access policy] over the set of covered subjects and objects specified in the policy, and where the policy: (b) Specifies that a subject that has been granted access to information is constrained from doing any of the following; (2) Granting its privileges to other subjects.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_3_b_3": {"name": "AC-3(3)(b)(3)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_3_b_3","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(3) Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access policy] over the set of covered subjects and objects specified in the policy, and where the policy: (b) Specifies that a subject that has been granted access to information is constrained from doing any of the following; (3) Changing one or more security attributes (specified by the policy) on subjects, objects, the system, or system components.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_3_b_4": {"name": "AC-3(3)(b)(4)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_3_b_4","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(3) Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access policy] over the set of covered subjects and objects specified in the policy, and where the policy: (b) Specifies that a subject that has been granted access to information is constrained from doing any of the following; (4) Choosing the security attributes and attribute values (specified by the policy) to be associated with newly created or modified objects.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_3_b_5": {"name": "AC-3(3)(b)(5)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_3_b_5","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(3) Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access policy] over the set of covered subjects and objects specified in the policy, and where the policy: (b) Specifies that a subject that has been granted access to information is constrained from doing any of the following; (5) Changing the rules governing access.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"cp_1_a_1_b": {"name": "CP-1(a)(1)(b)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_1_a_1_b","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": "CP-1(a)","SubSection": "Policy And Procedures (CP-1)"}],"description": "a. Develop, document, and disseminate to [Assignment: organization-defined personnel or roles]: 1. [Selection (one or more): Organization-level; Mission/business process-level; System-level] contingency planning policy that: (b) Is consistent with applicable laws, executive orders, directives, regulations, policies, standards, and guidelines.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}}},"requirements_passed": 86,"requirements_failed": 202,"requirements_manual": 0,"total_requirements": 288,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "c7fda251-1b8b-4668-be6e-6929da58d6af","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "rbi_cyber_security_framework_aws","framework": "RBI-Cyber-Security-Framework","version": "","description": "The Reserve Bank had prescribed a set of baseline cyber security controls for primary (Urban) cooperative banks (UCBs) in October 2018. On further examination, it has been decided to prescribe a comprehensive cyber security framework for the UCBs, as a graded approach, based on their digital depth and interconnectedness with the payment systems landscape, digital products offered by them and assessment of cyber security risk. The framework would mandate implementation of progressively stronger security measures based on the nature, variety and scale of digital product offerings of banks.","region": "eu-west-1","requirements": {"annex_i_6": {"name": "Annex I (6)","checks": {"ssm_managed_compliant_patching": "FAIL","guardduty_no_high_severity_findings": "FAIL","redshift_cluster_automatic_upgrades": null,"rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "annex_i_6","Section": null,"Service": "aws","SubGroup": null,"SubSection": null}],"description": "Put in place systems and processes to identify, track, manage and monitor the status of patches to servers, operating system and application software running at the systems used by the UCB officials (end-users). Implement and update antivirus protection for all servers and applicable end points preferably through a centralised system.","checks_status": {"fail": 2,"pass": 1,"total": 6,"manual": 0}},"annex_i_12": {"name": "Annex I (12)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "annex_i_12","Section": null,"Service": "aws","SubGroup": null,"SubSection": null}],"description": "Take periodic back up of the important data and store this data ā€˜off line’ (i.e., transferring important files to a storage device that can be detached from a computer/system after copying all the files).","checks_status": {"fail": 2,"pass": 1,"total": 5,"manual": 0}},"annex_i_1_1": {"name": "Annex I (1.1)","checks": {"ec2_instance_managed_by_ssm": "FAIL","organizations_account_part_of_organizations": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "annex_i_1_1","Section": null,"Service": "aws","SubGroup": null,"SubSection": null}],"description": "UCBs should maintain an up-to-date business IT Asset Inventory Register containing the following fields, as a minimum: a) Details of the IT Asset (viz., hardware/software/network devices, key personnel, services, etc.), b. Details of systems where customer data are stored, c. Associated business applications, if any, d. Criticality of the IT asset (For example, High/Medium/Low).","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"annex_i_1_3": {"name": "Annex I (1.3)","checks": {"elb_ssl_listeners": "FAIL","elbv2_ssl_listeners": "FAIL","ec2_instance_public_ip": "FAIL","backup_vaults_encrypted": "PASS","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"kms_cmk_rotation_enabled": null,"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","elbv2_insecure_ssl_ciphers": "PASS","rds_snapshots_public_access": "PASS","ssm_documents_set_as_public": "PASS","s3_bucket_default_encryption": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"redshift_cluster_public_access": null,"acm_certificates_expiration_check": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","vpc_subnet_no_public_ip_by_default": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"sns_topics_kms_encryption_at_rest_enabled": "FAIL","awslambda_function_not_publicly_accessible": "PASS","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_https_communications_enforced": null,"opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "annex_i_1_3","Section": null,"Service": "aws","SubGroup": null,"SubSection": null}],"description": "Appropriately manage and provide protection within and outside UCB/network, keeping in mind how the data/information is stored, transmitted, processed, accessed and put to use within/outside the UCB’s network, and level of risk they are exposed to depending on the sensitivity of the data/information.","checks_status": {"fail": 12,"pass": 15,"total": 40,"manual": 0}},"annex_i_5_1": {"name": "Annex I (5.1)","checks": {"elbv2_waf_acl_attached": "FAIL","apigateway_restapi_waf_acl_attached": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "annex_i_5_1","Section": null,"Service": "aws","SubGroup": null,"SubSection": null}],"description": "The firewall configurations should be set to the highest security level and evaluation of critical device (such as firewall, network switches, security devices, etc.) configurations should be done periodically.","checks_status": {"fail": 4,"pass": 1,"total": 5,"manual": 0}},"annex_i_7_1": {"name": "Annex I (7.1)","checks": {"iam_no_root_access_key": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "annex_i_7_1","Section": null,"Service": "iam","SubGroup": null,"SubSection": null}],"description": "Disallow administrative rights on end-user workstations/PCs/laptops and provide access rights on a ā€˜need to know’ and ā€˜need to do’ basis.","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"annex_i_7_2": {"name": "Annex I (7.2)","checks": {"iam_password_policy_reuse_24": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "annex_i_7_2","Section": null,"Service": "iam","SubGroup": null,"SubSection": null}],"description": "Passwords should be set as complex and lengthy and users should not use same passwords for all the applications/systems/devices.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"annex_i_7_3": {"name": "Annex I (7.3)","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "annex_i_7_3","Section": null,"Service": "vpc","SubGroup": null,"SubSection": null}],"description": "Remote Desktop Protocol (RDP) which allows others to access the computer remotely over a network or over the internet should be always disabled and should be enabled only with the approval of the authorised officer of the UCB. Logs for such remote access shall be enabled and monitored for suspicious activities.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"annex_i_7_4": {"name": "Annex I (7.4)","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","opensearch_service_domains_audit_logging_enabled": null,"opensearch_service_domains_cloudwatch_logging_enabled": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "annex_i_7_4","Section": null,"Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement appropriate (e.g. centralised) systems and controls to allow, manage, log and monitor privileged/super user/administrative access to critical systems (servers/databases, applications, network devices etc.)","checks_status": {"fail": 7,"pass": 3,"total": 15,"manual": 0}}},"requirements_passed": 3,"requirements_failed": 6,"requirements_manual": 0,"total_requirements": 9,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "c9352bc9-2107-40a5-8dc6-c67817863253","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "fedramp_moderate_revision_4_aws","framework": "FedRamp-Moderate-Revision-4","version": "","description": "The Federal Risk and Authorization Management Program (FedRAMP) was established in 2011. It provides a cost-effective, risk-based approach for the adoption and use of cloud services by the U.S. federal government. FedRAMP empowers federal agencies to use modern cloud technologies, with an emphasis on the security and protection of federal information.","region": "eu-west-1","requirements": {"ac-3": {"name": "Access Enforcement (AC-3)","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-3","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system enforces approved authorizations for logical access to information and system resources in accordance with applicable access control policies.","checks_status": {"fail": 1,"pass": 6,"total": 21,"manual": 0}},"ac-4": {"name": "Information Flow Enforcement (AC-4)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"acm_certificates_expiration_check": "PASS","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-4","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system enforces approved authorizations for controlling the flow of information within the system and between interconnected systems based on organization-defined information flow control policies.","checks_status": {"fail": 3,"pass": 7,"total": 16,"manual": 0}},"ac-6": {"name": "Least Privilege (AC-6)","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-6","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks in accordance with organizational missions and business functions.","checks_status": {"fail": 1,"pass": 6,"total": 20,"manual": 0}},"au-3": {"name": "Content of Audit Records (AU-3)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-3","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system generates audit records containing information that establishes what type of event occurred, when the event occurred, where the event occurred, the source of the event, the outcome of the event, and the identity of any individuals or subjects associated with the event.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au-9": {"name": "Protection of Audit Information (AU-9)","checks": {"cloudtrail_kms_encryption_enabled": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-9","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects audit information and audit tools from unauthorized access, modification, and deletion.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"cm-2": {"name": "Baseline Configuration (CM-2)","checks": {"ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"ec2_instance_managed_by_ssm": "FAIL","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"ssm_managed_compliant_patching": "FAIL","apigateway_restapi_waf_acl_attached": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm-2","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization develops, documents, and maintains under configuration control, a current baseline configuration of the information system.","checks_status": {"fail": 8,"pass": 6,"total": 22,"manual": 0}},"ia-2": {"name": "Identification and Authentication (Organizational users) (IA-2)","checks": {"iam_no_root_access_key": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia-2","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": null}],"description": "The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"ra-5": {"name": "Vulnerability Scanning (RA-5)","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ra-5","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": null,"SubSection": null}],"description": "Scan for system vulnerabilities. Share vulnerability information and security controls that eliminate vulnerabilities.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"sc-2": {"name": "Application Partitioning (SC-2)","checks": {"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc-2","Section": "System and Communications Protection (SC)","Service": "iam","SubGroup": null,"SubSection": null}],"description": "The information system separates user functionality (including user interface services) from information system management functionality.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"sc-4": {"name": "Information In Shared Resources (SC-4)","checks": {"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-4","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system prevents unauthorized and unintended information transfer via shared system resources.","checks_status": {"fail": 2,"pass": 5,"total": 14,"manual": 0}},"sc-5": {"name": "Denial Of Service Protection (SC-5)","checks": {"guardduty_is_enabled": "PASS","rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-5","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects against or limits the effects of the following types of denial of service attacks: [Assignment: organization-defined types of denial of service attacks or references to sources for such information] by employing [Assignment: organization-defined security safeguards].","checks_status": {"fail": 4,"pass": 1,"total": 6,"manual": 0}},"sc-7": {"name": "Boundary Protection (SC-7)","checks": {"elb_ssl_listeners": "FAIL","ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-7","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system: a. Monitors and controls communications at the external boundary of the system and at key internal boundaries within the system; b. Implements subnetworks for publicly accessible system components that are [Selection: physically; logically] separated from internal organizational networks; and c. Connects to external networks or information systems only through managed interfaces consisting of boundary protection devices arranged in accordance with an organizational security architecture.","checks_status": {"fail": 6,"pass": 6,"total": 21,"manual": 0}},"sc-8": {"name": "Transmission Integrity (SC-8)","checks": {"elb_ssl_listeners": "FAIL","elbv2_insecure_ssl_ciphers": "PASS","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-8","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects the confidentiality AND integrity of transmitted information.","checks_status": {"fail": 3,"pass": 1,"total": 5,"manual": 0}},"si-7": {"name": "Software, Firmware, and Information Integrity (SI-7)","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si-7","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization employs integrity verification tools to detect unauthorized changes to [Assignment: organization-defined software, firmware, and information].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"au-11": {"name": "Audit Record Retention (AU-11)","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-11","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization retains audit records for at least 90 days to provide support for after-the-fact investigations of security incidents and to meet regulatory and organizational information retention requirements.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cp-10": {"name": "Information System Recovery And Reconstitution (CP-10)","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp-10","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization provides for the recovery and reconstitution of the information system to a known state after a disruption, compromise, or failure.","checks_status": {"fail": 4,"pass": 1,"total": 9,"manual": 0}},"sa-10": {"name": "Developer Configuration Management (SA-10)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sa-10","Section": "System and Services Acquisition (SA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization requires the developer of the information system, system component, or information system service to: a. Perform configuration management during system, component, or service [Selection (one or more): design; development; implementation; operation]; b. Document, manage, and control the integrity of changes to [Assignment: organization-defined configuration items under configuration management]; c. Implement only organization-approved changes to the system, component, or service; d. Document approved changes to the system, component, or service and the potential security impacts of such changes; and e. Track security flaws and flaw resolution within the system, component, or service and report findings to [Assignment: organization-defined personnel].","checks_status": {"fail": 2,"pass": 2,"total": 4,"manual": 0}},"sc-12": {"name": "Cryptographic Key Establishment And Management (SC-12)","checks": {"kms_cmk_rotation_enabled": null,"acm_certificates_expiration_check": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc-12","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization establishes and manages cryptographic keys for required cryptography employed within the information system in accordance with [Assignment: organization-defined requirements for key generation, distribution, storage, access, and destruction].","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"sc-13": {"name": "Use of Cryptography (SC-13)","checks": {"s3_bucket_default_encryption": "PASS","sns_topics_kms_encryption_at_rest_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-13","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system implements FIPS-validated or NSA-approved cryptography in accordance with applicable federal laws, Executive Orders, directives, policies, regulations, and standards.","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"sc-23": {"name": "Session Authenticity (SC-23)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-23","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects the authenticity of communications sessions.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"sc-28": {"name": "Protection of Information at Rest (SC-28)","checks": {"ec2_ebs_volume_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-28","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects the confidentiality AND integrity of [Assignment: organization-defined information at rest].","checks_status": {"fail": 5,"pass": 2,"total": 13,"manual": 0}},"si-12": {"name": "Information Handling and Retention (SI-12)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si-12","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization handles and retains information within the information system and information output from the system in accordance with applicable federal laws, Executive Orders, directives, policies, regulations, standards, and operational requirements.","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"ac-2-1": {"name": "AC-2(1) Automated System Account Management","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac-2-1","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The organization employs automated mechanisms to support the management of information system accounts.","checks_status": {"fail": 0,"pass": 2,"total": 15,"manual": 0}},"ac-2-3": {"name": "AC-2-3","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac-2-3","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The information system automatically disables inactive accounts after 90 days for user accounts.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"ac-2-4": {"name": "AC-2(4) Automated Audit Actions","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-2-4","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The information system automatically audits account creation, modification, enabling, disabling, and removal actions, and notifies [Assignment: organization-defined personnel or roles].","checks_status": {"fail": 3,"pass": 3,"total": 14,"manual": 0}},"ac-2-f": {"name": "AC-2(f)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac-2-f","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The organization: f. Creates, enables, modifies, disables, and removes information system accounts in accordance with [Assignment: organization-defined procedures or conditions].","checks_status": {"fail": 0,"pass": 0,"total": 13,"manual": 0}},"ac-2-g": {"name": "AC-2(g)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","opensearch_service_domains_cloudwatch_logging_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-2-g","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The organization: g. Monitors the use of information system accounts.","checks_status": {"fail": 3,"pass": 4,"total": 12,"manual": 0}},"ac-2-j": {"name": "AC-2(j)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac-2-j","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The organization: j. Reviews accounts for compliance with account management requirements [Assignment: organization-defined frequency].","checks_status": {"fail": 0,"pass": 0,"total": 12,"manual": 0}},"ac-5-c": {"name": "AC-5(c)","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac-5-c","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Separation Of Duties (AC-5)"}],"description": "The organization: c. Defines information system access authorizations to support separation of duties.","checks_status": {"fail": 0,"pass": 0,"total": 8,"manual": 0}},"au-7-1": {"name": "AU-7(1) Automatic Processing","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-7-1","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Reduction And Report Generation (AU-7)"}],"description": "The information system provides the capability to process audit records for events of interest based on [Assignment: organization-defined audit fields within audit records].","checks_status": {"fail": 1,"pass": 0,"total": 5,"manual": 0}},"au-9-2": {"name": "AU-9(2) Audit Backup On Separate Physical Systems / Components","checks": {"s3_bucket_object_versioning": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-9-2","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Protection of Audit Information (AU-9)"}],"description": "The information system backs up audit records at least weekly onto a physically different system or system component than the system or component being audited.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cm-7-a": {"name": "CM-7(a)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm-7-a","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Least Functionality (CM-7)"}],"description": "The organization: a. Configures the information system to provide only essential capabilities.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm-8-1": {"name": "CM-8(1)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm-8-1","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Information System Component Inventory (CM-8)"}],"description": "The organization updates the inventory of information system components as an integral part of component installations, removals, and information system updates.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cp-9-b": {"name": "CP-9(b))","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp-9-b","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Information System Backup (CP-9)"}],"description": "The organization: b. Conducts backups of system-level information contained in the information system (daily incremental; weekly full).","checks_status": {"fail": 2,"pass": 1,"total": 7,"manual": 0}},"ia-2-1": {"name": "IA-2(1) Network Access To Privileged Accounts","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia-2-1","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "The information system implements multi-factor authentication for network access to privileged accounts.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ia-5-4": {"name": "IA-5(4) Automated Support For Password Strength Determination","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia-5-4","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "The organization employs automated tools to determine if password authenticators are sufficiently strong to satisfy [Assignment: organization-defined requirements].","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia-5-7": {"name": "IA-5(7) No Embedded Unencrypted Static Authenticators","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia-5-7","Section": "Identification and Authentication (IA)","Service": "codebuild","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "The organization ensures that unencrypted static authenticators are not embedded in applications or access scripts or stored on function keys.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ir-4-1": {"name": "IR-4(1) Automated Incident Handling Processes","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ir-4-1","Section": "Incident Response (IR)","Service": "aws","SubGroup": null,"SubSection": "Incident Handling (IR-4)"}],"description": "The organization employs automated mechanisms to support the incident handling process.","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"ir-6-1": {"name": "IR-6(1) Automated Reporting","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ir-6-1","Section": "Incident Response (IR)","Service": "aws","SubGroup": null,"SubSection": "Incident Reporting (IR-6)"}],"description": "The organization employs automated mechanisms to assist in the reporting of security incidents.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"ir-7-1": {"name": "IR-7(1) Automation Support For Availability Of Information / Support","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ir-7-1","Section": "Incident Response (IR)","Service": "aws","SubGroup": null,"SubSection": "Incident Response Assistance (IR-7)"}],"description": "The organization employs automated mechanisms to increase the availability of incident response-related information and support.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"sa-3-a": {"name": "SA-3(a)","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sa-3-a","Section": "System and Services Acquisition (SA)","Service": "aws","SubGroup": null,"SubSection": "System Development Life Cycle (SA-3)"}],"description": "The organization: a. Manages the information system using [Assignment: organization-defined system development life cycle] that incorporates information security considerations.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sc-7-3": {"name": "SC-7(3) Access Points","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-7-3","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "The organization limits the number of external network connections to the information system.","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"sc-8-1": {"name": "SC-8(1) Cryptographic Or Alternate Physical Protection","checks": {"elb_ssl_listeners": "FAIL","elbv2_insecure_ssl_ciphers": "PASS","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-8-1","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Transmission Integrity (SC-8)"}],"description": "The information system implements cryptographic mechanisms to [Selection (one or more): prevent unauthorized disclosure of information; detect changes to information] during transmission unless otherwise protected by [Assignment: organization-defined alternative physical safeguards].","checks_status": {"fail": 3,"pass": 1,"total": 5,"manual": 0}},"si-2-2": {"name": "Automated Flaw Remediation Status (SI-2(2))","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si-2-2","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Flaw Remediation (SI-2)"}],"description": "The organization employs automated mechanisms at least monthly to determine the state of information system components with regard to flaw remediation.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"si-4-1": {"name": "SI-4(1) System-Wide Intrusion Detection System","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si-4-1","Section": "System and Information Integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The organization connects and configures individual intrusion detection tools into an information system-wide intrusion detection system.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si-4-2": {"name": "SI-4(2) Automated Tools For Real-Time Analysis","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "si-4-2","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The organization employs automated tools to support near real-time analysis of events.","checks_status": {"fail": 0,"pass": 4,"total": 12,"manual": 0}},"si-4-4": {"name": "SI-4(4) Inbound and Outbound Communications Traffic","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "si-4-4","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The information system monitors inbound and outbound communications traffic continuously for unusual or unauthorized activities or conditions.","checks_status": {"fail": 0,"pass": 4,"total": 12,"manual": 0}},"si-4-5": {"name": "SI-4(5) System-Generated Alerts","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "si-4-5","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The information system alerts organization-defined personnel or roles when the following indications of compromise or potential compromise occur: [Assignment: organization-defined compromise indicators].","checks_status": {"fail": 0,"pass": 4,"total": 12,"manual": 0}},"si-7-1": {"name": "SI-7(1) Integrity Checks","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si-7-1","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Software, Firmware, and Information Integrity (SI-7)"}],"description": "The information system performs an integrity check of security relevant events at least monthly.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"ac-17-1": {"name": "AC-17(1) Automated Monitoring/Control","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-17-1","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Remote Access (AC-17)"}],"description": "The information system monitors and controls remote access methods.","checks_status": {"fail": 3,"pass": 8,"total": 19,"manual": 0}},"ac-17-2": {"name": "AC-17(2) Protection Of Confidentiality/Integrity Using Encryption","checks": {"elb_ssl_listeners": "FAIL","acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-17-2","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Remote Access (AC-17)"}],"description": "The information system implements cryptographic mechanisms to protect the confidentiality and integrity of remote access sessions.","checks_status": {"fail": 2,"pass": 1,"total": 3,"manual": 0}},"ac-21-b": {"name": "AC-21(b)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-21-b","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Information Sharing (AC-21)"}],"description": "The organization: b. Employs [Assignment: organization-defined automated mechanisms or manual processes] to assist users in making information sharing/collaboration decisions.","checks_status": {"fail": 3,"pass": 4,"total": 15,"manual": 0}},"ac-6-10": {"name": "AC-6(10) Prohibit Non-Privileged Users From Executing Privileged Functions","checks": {"iam_no_root_access_key": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac-6-10","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Least Privilege (AC-6)"}],"description": "The information system prevents non-privileged users from executing privileged functions to include disabling, circumventing, or altering implemented security safeguards/countermeasures.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"si-4-16": {"name": "SI-4(16) Correlate Monitoring Information","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "si-4-16","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The organization correlates information from monitoring tools employed throughout the information system.","checks_status": {"fail": 0,"pass": 3,"total": 7,"manual": 0}},"au-2-a-d": {"name": "AU-2(a)(d)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-2-a-d","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Events (AU-2)"}],"description": "The organization: a. Determines that the information system is capable of auditing the following events: Successful and unsuccessful account logon events, account management events, object access, policy change, privilege functions, process tracking, and system events. For Web applications: all administrator activity, authentication checks, authorization checks, data deletions, data access, data changes, and permission changes. d. Determines that the following events are to be audited within the information system: [organization-defined subset of the auditable events defined in AU-2 a to be audited continually for each identified event].","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au-6-1-3": {"name": "AU-6(1)(3)","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-6-1-3","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Review, Analysis And Reporting (AU-6)"}],"description": "(1) The organization employs automated mechanisms to integrate audit review, analysis, and reporting processes to support organizational processes for investigation and response to suspicious activities. (3) The organization analyzes and correlates audit records across different repositories to gain organization-wide situational awareness.","checks_status": {"fail": 7,"pass": 4,"total": 19,"manual": 0}},"ca-7-a-b": {"name": "CA-7(a)(b)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ca-7-a-b","Section": "Security Assessment And Authorization (CA)","Service": "aws","SubGroup": null,"SubSection": "Continuous Monitoring (CA-7)"}],"description": "The organization develops a continuous monitoring strategy and implements a continuous monitoring program that includes: a. Establishment of [Assignment: organization-defined metrics] to be monitored; b. Establishment of [Assignment: organization-defined frequencies] for monitoring and [Assignment: organization-defined frequencies] for assessments supporting such monitoring.","checks_status": {"fail": 1,"pass": 4,"total": 13,"manual": 0}},"cm-8-3-a": {"name": "CM-8(3)(a)","checks": {"guardduty_is_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm-8-3-a","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Information System Component Inventory (CM-8)"}],"description": "The organization: a. Employs automated mechanisms continuously, using automated mechanisms with a maximum five-minute delay in detection, to detect the presence of unauthorized hardware, software, and firmware components within the information system","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"ia-2-1-2": {"name": "IA-2(1)(2)","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia-2-1-2","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "IA-2(1) Network Access To Privileged Accounts"}],"description": "(1) The information system implements multifactor authentication for network access to privileged accounts. (2) The information system implements multifactor authentication for network access to non- privileged accounts.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ac-2-12-a": {"name": "AC-2(12)(a)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac-2-12-a","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The organization: a. Monitors information system accounts for [Assignment: organization-defined atypical use].","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"au-12-a-c": {"name": "AU-12(a)(c)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-12-a-c","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Generation (AU-12)"}],"description": "The information system: a. Provides audit record generation capability for the auditable events defined in AU-2 a. at all information system and network components where audit capability is deployed/available c. Generates audit records for the events defined in AU-2 d. with the content defined in AU-3.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"si-4-a-b-c": {"name": "SI-4(a)(b)(c)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_waf_acl_attached": "FAIL","ec2_instance_imdsv2_enabled": "PASS","apigateway_restapi_waf_acl_attached": "FAIL","guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si-4-a-b-c","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The organization: a. Monitors the information system to detect: 1. Attacks and indicators of potential attacks in accordance with [Assignment: organization- defined monitoring objectives]; and 2. Unauthorized local, network, and remote connections; b. Identifies unauthorized use of the information system through [Assignment: organization- defined techniques and methods]; c. Deploys monitoring devices: i. strategically within the information system to collect organization-determined essential information; and (ii) at ad hoc locations within the system to track specific types of transactions of interest to the organization.","checks_status": {"fail": 4,"pass": 3,"total": 11,"manual": 0}},"ia-5-1-a-d-e": {"name": "IA-5(1)(a)(d)(e)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia-5-1-a-d-e","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "IA-5(1) Password-Based Authentication"}],"description": "The information system, for password-based authentication: a. Enforces minimum password complexity of [Assignment: organization-defined requirements for case sensitivity, number of characters, mix of upper-case letters, lower-case letters, numbers, and special characters, including minimum requirements for each type]; d. Enforces password minimum and maximum lifetime restrictions of [Assignment: organization- defined numbers for lifetime minimum, lifetime maximum]; e. Prohibits password reuse for 24 generations","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 20,"requirements_failed": 43,"requirements_manual": 1,"total_requirements": 64,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "d7024b7f-64c1-4d70-8f9d-7844c9194c42","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "gdpr_aws","framework": "GDPR","version": "","description": "The General Data Protection Regulation (GDPR) is a new European privacy law that became enforceable on May 25, 2018. The GDPR replaces the EU Data Protection Directive, also known as Directive 95/46/EC. It's intended to harmonize data protection laws throughout the European Union (EU). It does this by applying a single data protection law that's binding throughout each EU member state.","region": "eu-west-1","requirements": {"article_25": {"name": "Article 25 Data protection by design and by default","checks": {"iam_root_mfa_enabled": null,"vpc_flow_logs_enabled": "FAIL","iam_no_root_access_key": null,"iam_support_role_created": null,"kms_cmk_rotation_enabled": null,"iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","config_recorder_all_regions_enabled": null,"iam_user_mfa_enabled_console_access": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","iam_password_policy_minimum_length_14": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_log_metric_filter_policy_changes": null,"iam_inline_policy_no_administrative_privileges": null,"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL","cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS","cloudwatch_log_metric_filter_authentication_failures": null,"iam_aws_attached_policy_no_administrative_privileges": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"iam_customer_attached_policy_no_administrative_privileges": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "article_25","Section": "Article 25 Data protection by design and by default","Service": "aws","SubGroup": null,"SubSection": null}],"description": "To obtain the latest version of the official guide, please visit https://gdpr-info.eu/art-25-gdpr/. Taking into account the state of the art, the cost of implementation and the nature, scope, context and purposes of processing as well as the risks of varying likelihood and severity for rights and freedoms of natural persons posed by the processing, the controller shall, both at the time of the determination of the means for processing and at the time of the processing itself, implement appropriate technical and organisational measures, such as pseudonymisation, which are designed to implement data-protection principles, such as data minimisation, in an effective manner and to integrate the necessary safeguards into the processing in order to meet the requirements of this Regulation and protect the rights of data subjects. The controller shall implement appropriate technical and organisational measures for ensuring that, by default, only personal data which are necessary for each specific purpose of the processing are processed. That obligation applies to the amount of personal data collected, the extent of their processing, the period of their storage and their accessibility. In particular, such measures shall ensure that by default personal data are not made accessible without the individual's intervention to an indefinite number of natural persons. An approved certification mechanism pursuant to Article 42 may be used as an element to demonstrate compliance with the requirements set out in paragraphs 1 and 2 of this Article.","checks_status": {"fail": 5,"pass": 2,"total": 42,"manual": 0}},"article_30": {"name": "Article 30 Records of processing activities","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","kms_cmk_rotation_enabled": null,"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","config_recorder_all_regions_enabled": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "article_30","Section": "Article 30 Records of processing activities","Service": "aws","SubGroup": null,"SubSection": null}],"description": " To obtain the latest version of the official guide, please visit https://www.privacy-regulation.eu/en/article-30-records-of-processing-activities-GDPR.htm. Each controller and, where applicable, the controller's representative, shall maintain a record of processing activities under its responsibility. That record shall contain all of the following information like the name and contact details of the controller and where applicable, the joint controller, the controller's representative and the data protection officer, the purposes of the processing etc. Each processor and where applicable, the processor's representative shall maintain a record of all categories of processing activities carried out on behalf of a controller, containing the name and contact details of the processor or processors and of each controller on behalf of which the processor is acting, and, where applicable of the controller's or the processor's representative, and the data protection officer, where applicable, transfers of personal data to a third country or an international organisation, including the identification of that third country or international organisation and, in the case of transfers referred to in the second subparagraph of Article 49(1), the documentation of suitable safeguards. The records referred to in paragraphs 1 and 2 shall be in writing, including in electronic form. The controller or the processor and, where applicable, the controller's or the processor's representative, shall make the record available to the supervisory authority on request. The obligations referred to in paragraphs 1 and 2 shall not apply to an enterprise or an organisation employing fewer than 250 persons unless the processing it carries out is likely to result in a risk to the rights and freedoms of data subjects, the processing is not occasional, or the processing includes special categories of data as referred to in Article 9(1) or personal data relating to criminal convictions and offences referred to in Article 10.","checks_status": {"fail": 5,"pass": 1,"total": 12,"manual": 0}},"article_32": {"name": "Article 32 Security of processing","checks": {"elb_ssl_listeners": "FAIL","ec2_ebs_volume_encryption": "PASS","rds_instance_backup_enabled": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"acm_certificates_expiration_check": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","redshift_cluster_automated_snapshot": null,"cloudfront_distributions_https_enabled": null,"cloudtrail_log_file_validation_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "article_32","Section": "Article 32 Security of processing","Service": "aws","SubGroup": null,"SubSection": null}],"description": " To obtain the latest version of the official guide, please visit https://gdpr-info.eu/art-32-gdpr/. Taking into account the state of the art, the costs of implementation and the nature, scope, context and purposes of processing as well as the risk of varying likelihood and severity for the rights and freedoms of natural persons, the controller and the processor shall implement appropriate technical and organisational measures to ensure a level of security appropriate to the risk, including inter alia as appropriate. In assessing the appropriate level of security account shall be taken in particular of the risks that are presented by processing, in particular from accidental or unlawful destruction, loss, alteration, unauthorised disclosure of, or access to personal data transmitted, stored or otherwise processed. Adherence to an approved code of conduct as referred to in Article 40 or an approved certification mechanism as referred to in Article 42 may be used as an element by which to demonstrate compliance with the requirements set out in paragraph 1 of this Article. The controller and processor shall take steps to ensure that any natural person acting under the authority of the controller or the processor who has access to personal data does not process them except on instructions from the controller, unless he or she is required to do so by Union or Member State law.","checks_status": {"fail": 9,"pass": 4,"total": 25,"manual": 0}}},"requirements_passed": 0,"requirements_failed": 3,"requirements_manual": 0,"total_requirements": 3,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "df010cc1-e468-42d1-8b7c-37d614adf364","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "aws_well_architected_framework_security_pillar_aws","framework": "AWS-Well-Architected-Framework-Security-Pillar","version": "","description": "Best Practices for AWS Well-Architected Framework Security Pillar. The focus of this framework is the security pillar of the AWS Well-Architected Framework. It provides guidance to help you apply best practices, current recommendations in the design, delivery, and maintenance of secure AWS workloads.","region": "eu-west-1","requirements": {"SEC01-BP01": {"name": "SEC01-BP01","checks": {"organizations_account_part_of_organizations": null},"status": "PASS","attributes": [{"Name": "SEC01-BP01 Separate workloads using accounts","Section": "Security foundations","SubSection": "AWS account management and separation","Description": "Establish common guardrails and isolation between environments (such as production, development, and test) and workloads through a multi-account strategy. Account-level separation is strongly recommended, as it provides a strong isolation boundary for security, billing, and access.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_multi_accounts.html#implementation-guidance.","WellArchitectedPracticeId": "sec_securely_operate_multi_accounts","WellArchitectedQuestionId": "securely-operate"}],"description": "Establish common guardrails and isolation between environments (such as production, development, and test) and workloads through a multi-account strategy. Account-level separation is strongly recommended, as it provides a strong isolation boundary for security, billing, and access.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"SEC01-BP02": {"name": "SEC01-BP02","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_root_hardware_mfa_enabled": null},"status": "PASS","attributes": [{"Name": "SEC01-BP02 Secure account root user and properties","Section": "Security foundations","SubSection": "AWS account management and separation","Description": "The root user is the most privileged user in an AWS account, with full administrative access to all resources within the account, and in some cases cannot be constrained by security policies. Deactivating programmatic access to the root user, establishing appropriate controls for the root user, and avoiding routine use of the root user helps reduce the risk of inadvertent exposure of the root credentials and subsequent compromise of the cloud environment.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_aws_account.html#implementation-guidance.","WellArchitectedPracticeId": "sec_securely_operate_aws_account","WellArchitectedQuestionId": "securely-operate"}],"description": "The root user is the most privileged user in an AWS account, with full administrative access to all resources within the account, and in some cases cannot be constrained by security policies. Deactivating programmatic access to the root user, establishing appropriate controls for the root user, and avoiding routine use of the root user helps reduce the risk of inadvertent exposure of the root credentials and subsequent compromise of the cloud environment.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"SEC01-BP03": {"name": "SEC01-BP03","checks": {},"status": "PASS","attributes": [{"Name": "SEC01-BP03 Identify and validate control objectives","Section": "Security foundations","SubSection": "Operating your workloads securely","Description": "Based on your compliance requirements and risks identified from your threat model, derive and validate the control objectives and controls that you need to apply to your workload. Ongoing validation of control objectives and controls help you measure the effectiveness of risk mitigation.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_control_objectives.html#implementation-guidance.","WellArchitectedPracticeId": "sec_securely_operate_control_objectives","WellArchitectedQuestionId": "securely-operate"}],"description": "Based on your compliance requirements and risks identified from your threat model, derive and validate the control objectives and controls that you need to apply to your workload. Ongoing validation of control objectives and controls help you measure the effectiveness of risk mitigation.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC01-BP04": {"name": "SEC01-BP04","checks": {},"status": "PASS","attributes": [{"Name": "SEC01-BP04 Keep up-to-date with security threats","Section": "Security foundations","SubSection": "Operating your workloads securely","Description": "To help you define and implement appropriate controls, recognize attack vectors by staying up to date with the latest security threats. Consume AWS Managed Services to make it easier to receive notification of unexpected or unusual behavior in your AWS accounts. Investigate using AWS Partner tools or third-party threat information feeds as part of your security information flow. The Common Vulnerabilities and Exposures (CVE) Listlist contains publicly disclosed cyber security vulnerabilities that you can use to stay up to date.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_updated_threats.html#implementation-guidance.","WellArchitectedPracticeId": "sec_securely_operate_updated_threats","WellArchitectedQuestionId": "securely-operate"}],"description": "To help you define and implement appropriate controls, recognize attack vectors by staying up to date with the latest security threats. Consume AWS Managed Services to make it easier to receive notification of unexpected or unusual behavior in your AWS accounts. Investigate using AWS Partner tools or third-party threat information feeds as part of your security information flow. The Common Vulnerabilities and Exposures (CVE) Listlist contains publicly disclosed cyber security vulnerabilities that you can use to stay up to date.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC01-BP05": {"name": "SEC01-BP05","checks": {},"status": "PASS","attributes": [{"Name": "SEC01-BP05 Keep up-to-date with security recommendations","Section": "Security foundations","SubSection": "Operating your workloads securely","Description": "Stay up-to-date with both AWS and industry security recommendations to evolve the security posture of your workload. AWS Security Bulletins contain important information about security and privacy notifications.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_updated_recommendations.html#implementation-guidance.","WellArchitectedPracticeId": "sec_securely_operate_updated_recommendations","WellArchitectedQuestionId": "securely-operate"}],"description": "Stay up-to-date with both AWS and industry security recommendations to evolve the security posture of your workload. AWS Security Bulletins contain important information about security and privacy notifications.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC01-BP06": {"name": "SEC01-BP06","checks": {"ec2_instance_managed_by_ssm": "FAIL","ecr_repositories_scan_images_on_push_enabled": "FAIL","ecr_repositories_scan_vulnerabilities_in_latest_image": null},"status": "FAIL","attributes": [{"Name": "SEC01-BP06 Automate testing and validation of security controls in pipelines","Section": "Security foundations","SubSection": "Operating your workloads securely","Description": "Establish secure baselines and templates for security mechanisms that are tested and validated as part of your build, pipelines, and processes. Use tools and automation to test and validate all security controls continuously. For example, scan items such as machine images and infrastructure-as-code templates for security vulnerabilities, irregularities, and drift from an established baseline at each stage. AWS CloudFormation Guard can help you verify that CloudFormation templates are safe, save you time, and reduce the risk of configuration error.Reducing the number of security misconfigurations introduced into a production environment is critical—the more quality control and reduction of defects you can perform in the build process, the better. Design continuous integration and continuous deployment (CI/CD) pipelines to test for security issues whenever possible. CI/CD pipelines offer the opportunity to enhance security at each stage of build and delivery. CI/CD security tooling must also be kept updated to mitigate evolving threats.Track changes to your workload configuration to help with compliance auditing, change management, and investigations that may apply to you. You can use AWS Config to record and evaluate your AWS and third-party resources. It allows you to continuously audit and assess the overall compliance with rules and conformance packs, which are collections of rules with remediation actions.Change tracking should include planned changes, which are part of your organization's change control process (sometimes referred to as MACD—Move, Add, Change, Delete), unplanned changes, and unexpected changes, such as incidents. Changes might occur on the infrastructure, but they might also be related to other categories, such as changes in code repositories, machine images and application inventory changes, process and policy changes, or documentation changes.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_test_validate_pipeline.html#implementation-guidance.","WellArchitectedPracticeId": "sec_securely_operate_test_validate_pipeline","WellArchitectedQuestionId": "securely-operate"}],"description": "Establish secure baselines and templates for security mechanisms that are tested and validated as part of your build, pipelines, and processes. Use tools and automation to test and validate all security controls continuously. For example, scan items such as machine images and infrastructure-as-code templates for security vulnerabilities, irregularities, and drift from an established baseline at each stage. AWS CloudFormation Guard can help you verify that CloudFormation templates are safe, save you time, and reduce the risk of configuration error.Reducing the number of security misconfigurations introduced into a production environment is critical—the more quality control and reduction of defects you can perform in the build process, the better. Design continuous integration and continuous deployment (CI/CD) pipelines to test for security issues whenever possible. CI/CD pipelines offer the opportunity to enhance security at each stage of build and delivery. CI/CD security tooling must also be kept updated to mitigate evolving threats.Track changes to your workload configuration to help with compliance auditing, change management, and investigations that may apply to you. You can use AWS Config to record and evaluate your AWS and third-party resources. It allows you to continuously audit and assess the overall compliance with rules and conformance packs, which are collections of rules with remediation actions.Change tracking should include planned changes, which are part of your organization's change control process (sometimes referred to as MACD—Move, Add, Change, Delete), unplanned changes, and unexpected changes, such as incidents. Changes might occur on the infrastructure, but they might also be related to other categories, such as changes in code repositories, machine images and application inventory changes, process and policy changes, or documentation changes.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"SEC01-BP07": {"name": "SEC01-BP07","checks": {"wellarchitected_workload_no_high_or_medium_risks": "FAIL"},"status": "FAIL","attributes": [{"Name": "SEC01-BP07 Identify threats and prioritize mitigations using a threat model","Section": "Security foundations","SubSection": "Operating your workloads securely","Description": "Perform threat modeling to identify and maintain an up-to-date register of potential threats and associated mitigations for your workload. Prioritize your threats and adapt your security control mitigations to prevent, detect, and respond. Revisit and maintain this in the context of your workload, and the evolving security landscape.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_threat_model.html#implementation-guidance.","WellArchitectedPracticeId": "sec_securely_operate_threat_model","WellArchitectedQuestionId": "securely-operate"}],"description": "Perform threat modeling to identify and maintain an up-to-date register of potential threats and associated mitigations for your workload. Prioritize your threats and adapt your security control mitigations to prevent, detect, and respond. Revisit and maintain this in the context of your workload, and the evolving security landscape.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"SEC01-BP08": {"name": "SEC01-BP08","checks": {},"status": "PASS","attributes": [{"Name": "SEC01-BP08 Evaluate and implement new security services and features regularly","Section": "Security foundations","SubSection": "Operating your workloads securely","Description": "Evaluate and implement security services and features from AWS and AWS Partners that allow you to evolve the security posture of your workload. The AWS Security Blog highlights new AWS services and features, implementation guides, and general security guidance. What's New with AWS? is a great way to stay up to date with all new AWS features, services, and announcements.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_implement_services_features.html#implementation-guidance.","WellArchitectedPracticeId": "sec_securely_operate_implement_services_features","WellArchitectedQuestionId": "securely-operate"}],"description": "Evaluate and implement security services and features from AWS and AWS Partners that allow you to evolve the security posture of your workload. The AWS Security Blog highlights new AWS services and features, implementation guides, and general security guidance. What's New with AWS? is a great way to stay up to date with all new AWS features, services, and announcements.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC02-BP01": {"name": "SEC02-BP01","checks": {"iam_avoid_root_usage": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_user_hardware_mfa_enabled": null,"iam_user_two_active_access_key": null,"iam_user_mfa_enabled_console_access": null,"iam_user_no_setup_initial_access_key": null,"iam_password_policy_minimum_length_14": null,"directoryservice_supported_mfa_radius_enabled": null,"directoryservice_radius_server_security_protocol": null,"sagemaker_notebook_instance_root_access_disabled": null,"opensearch_service_domains_use_cognito_authentication_for_kibana": null},"status": "PASS","attributes": [{"Name": "SEC02-BP01 Use strong sign-in mechanisms","Section": "Identity and access management","SubSection": "Identity management","Description": "Sign-ins (authentication using sign-in credentials) can present risks when not using mechanisms like multi-factor authentication (MFA), especially in situations where sign-in credentials have been inadvertently disclosed or are easily guessed. Use strong sign-in mechanisms to reduce these risks by requiring MFA and strong password policies.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_identities_enforce_mechanisms.html#implementation-guidance.","WellArchitectedPracticeId": "sec_identities_enforce_mechanisms","WellArchitectedQuestionId": "identities"}],"description": "Sign-ins (authentication using sign-in credentials) can present risks when not using mechanisms like multi-factor authentication (MFA), especially in situations where sign-in credentials have been inadvertently disclosed or are easily guessed. Use strong sign-in mechanisms to reduce these risks by requiring MFA and strong password policies.","checks_status": {"fail": 0,"pass": 0,"total": 15,"manual": 0}},"SEC02-BP02": {"name": "SEC02-BP02","checks": {"iam_rotate_access_key_90_days": null},"status": "PASS","attributes": [{"Name": "SEC02-BP02 Use temporary credentials","Section": "Identity and access management","SubSection": "Identity management","Description": "When doing any type of authentication, it’s best to use temporary credentials instead of long-term credentials to reduce or eliminate risks, such as credentials being inadvertently disclosed, shared, or stolen.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_identities_unique.html#implementation-guidance.","WellArchitectedPracticeId": "sec_identities_unique","WellArchitectedQuestionId": "identities"}],"description": "When doing any type of authentication, it’s best to use temporary credentials instead of long-term credentials to reduce or eliminate risks, such as credentials being inadvertently disclosed, shared, or stolen.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"SEC02-BP03": {"name": "SEC02-BP03","checks": {"ssm_document_secrets": "PASS","ec2_instance_secrets_user_data": "PASS","ec2_launch_template_no_secrets": "PASS","awslambda_function_no_secrets_in_code": "PASS","cloudformation_stack_outputs_find_secrets": "PASS","awslambda_function_no_secrets_in_variables": "PASS","ecs_task_definitions_no_environment_secrets": "PASS","autoscaling_find_secrets_ec2_launch_configuration": "PASS"},"status": "PASS","attributes": [{"Name": "SEC02-BP03 Store and use secrets securely","Section": "Identity and access management","SubSection": "Identity management","Description": "A workload requires an automated capability to prove its identity to databases, resources, and third-party services. This is accomplished using secret access credentials, such as API access keys, passwords, and OAuth tokens. Using a purpose-built service to store, manage, and rotate these credentials helps reduce the likelihood that those credentials become compromised.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_identities_secrets.html#implementation-guidance.","WellArchitectedPracticeId": "sec_identities_secrets","WellArchitectedQuestionId": "identities"}],"description": "A workload requires an automated capability to prove its identity to databases, resources, and third-party services. This is accomplished using secret access credentials, such as API access keys, passwords, and OAuth tokens. Using a purpose-built service to store, manage, and rotate these credentials helps reduce the likelihood that those credentials become compromised.","checks_status": {"fail": 0,"pass": 8,"total": 8,"manual": 0}},"SEC02-BP04": {"name": "SEC02-BP04","checks": {"iam_role_cross_service_confused_deputy_prevention": null},"status": "PASS","attributes": [{"Name": "SEC02-BP04 Rely on a centralized identity provider","Section": "Identity and access management","SubSection": "Identity management","Description": "For workforce identities, rely on an identity provider that enables you to manage identities in a centralized place. This makes it easier to manage access across multiple applications and services, because you are creating, managing, and revoking access from a single location. For example, if someone leaves your organization, you can revoke access for all applications and services (including AWS) from one location. This reduces the need for multiple credentials and provides an opportunity to integrate with existing human resources (HR) processes. For federation with individual AWS accounts, you can use centralized identities for AWS with a SAML 2.0-based provider with AWS Identity and Access Management. You can use any provider— whether hosted by you in AWS, external to AWS, or supplied by the AWS Partner—that is compatible with the SAML 2.0 protocol. You can use federation between your AWS account and your chosen provider to grant a user or application access to call AWS API operations by using a SAML assertion to get temporary security credentials. Web-based single sign-on is also supported, allowing users to sign in to the AWS Management Console from your sign in website. For federation to multiple accounts in your AWS Organizations, you can configure your identity source in AWS IAM Identity Center (successor to AWS Single Sign-On) (IAM Identity Center), and specify where your users and groups are stored. Once configured, your identity provider is your source of truth, and information can be synchronized using the System for Cross-domain Identity Management (SCIM) v2.0 protocol. You can then look up users or groups and grant them IAM Identity Center access to AWS accounts, cloud applications, or both. IAM Identity Center integrates with AWS Organizations, which enables you to configure your identity provider once and then grant access to existing and new accounts managed in your organization. IAM Identity Center provides you with a default store, which you can use to manage your users and groups. If you choose to use the IAM Identity Center store, create your users and groups and assign their level of access to your AWS accounts and applications, keeping in mind the best practice of least privilege. Alternatively, you can choose to Connect to Your External Identity Provider using SAML 2.0, or Connect to Your Microsoft AD Directory using AWS Directory Service. Once configured, you can sign into the AWS Management Console, or the AWS mobile app, by authenticating through your central identity provider. For managing end-users or consumers of your workloads, such as a mobile app, you can use Amazon Cognito. It provides authentication, authorization, and user management for your web and mobile apps. Your users can sign in directly with sign-in credentials, or through a third party, such as Amazon, Apple, Facebook, or Google.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_identities_identity_provider.html#implementation-guidance.","WellArchitectedPracticeId": "sec_identities_identity_provider","WellArchitectedQuestionId": "identities"}],"description": "For workforce identities, rely on an identity provider that enables you to manage identities in a centralized place. This makes it easier to manage access across multiple applications and services, because you are creating, managing, and revoking access from a single location. For example, if someone leaves your organization, you can revoke access for all applications and services (including AWS) from one location. This reduces the need for multiple credentials and provides an opportunity to integrate with existing human resources (HR) processes. For federation with individual AWS accounts, you can use centralized identities for AWS with a SAML 2.0-based provider with AWS Identity and Access Management. You can use any provider— whether hosted by you in AWS, external to AWS, or supplied by the AWS Partner—that is compatible with the SAML 2.0 protocol. You can use federation between your AWS account and your chosen provider to grant a user or application access to call AWS API operations by using a SAML assertion to get temporary security credentials. Web-based single sign-on is also supported, allowing users to sign in to the AWS Management Console from your sign in website. For federation to multiple accounts in your AWS Organizations, you can configure your identity source in AWS IAM Identity Center (successor to AWS Single Sign-On) (IAM Identity Center), and specify where your users and groups are stored. Once configured, your identity provider is your source of truth, and information can be synchronized using the System for Cross-domain Identity Management (SCIM) v2.0 protocol. You can then look up users or groups and grant them IAM Identity Center access to AWS accounts, cloud applications, or both. IAM Identity Center integrates with AWS Organizations, which enables you to configure your identity provider once and then grant access to existing and new accounts managed in your organization. IAM Identity Center provides you with a default store, which you can use to manage your users and groups. If you choose to use the IAM Identity Center store, create your users and groups and assign their level of access to your AWS accounts and applications, keeping in mind the best practice of least privilege. Alternatively, you can choose to Connect to Your External Identity Provider using SAML 2.0, or Connect to Your Microsoft AD Directory using AWS Directory Service. Once configured, you can sign into the AWS Management Console, or the AWS mobile app, by authenticating through your central identity provider. For managing end-users or consumers of your workloads, such as a mobile app, you can use Amazon Cognito. It provides authentication, authorization, and user management for your web and mobile apps. Your users can sign in directly with sign-in credentials, or through a third party, such as Amazon, Apple, Facebook, or Google.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"SEC02-BP05": {"name": "SEC02-BP05","checks": {"kms_cmk_rotation_enabled": null,"iam_rotate_access_key_90_days": null,"secretsmanager_automatic_rotation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Name": "SEC02-BP05 Audit and rotate credentials periodically","Section": "Identity and access management","SubSection": "Identity management","Description": "When you cannot rely on temporary credentials and require long-term credentials, audit credentials to ensure that the defined controls for example, multi-factor authentication (MFA), are enforced, rotated regularly, and have the appropriate access level. Periodic validation, preferably through an automated tool, is necessary to verify that the correct controls are enforced. For human identities, you should require users to change their passwords periodically and retire access keys in favor of temporary credentials. As you are moving from users to centralized identities, you can generate a credential report to audit your users. We also recommend that you enforce MFA settings in your identity provider. You can set up AWS Config Rules to monitor these settings. For machine identities, you should rely on temporary credentials using IAM roles. For situations where this is not possible, frequent auditing and rotating access keys is necessary.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_identities_audit.html#implementation-guidance.","WellArchitectedPracticeId": "sec_identities_audit","WellArchitectedQuestionId": "identities"}],"description": "When you cannot rely on temporary credentials and require long-term credentials, audit credentials to ensure that the defined controls for example, multi-factor authentication (MFA), are enforced, rotated regularly, and have the appropriate access level. Periodic validation, preferably through an automated tool, is necessary to verify that the correct controls are enforced. For human identities, you should require users to change their passwords periodically and retire access keys in favor of temporary credentials. As you are moving from users to centralized identities, you can generate a credential report to audit your users. We also recommend that you enforce MFA settings in your identity provider. You can set up AWS Config Rules to monitor these settings. For machine identities, you should rely on temporary credentials using IAM roles. For situations where this is not possible, frequent auditing and rotating access keys is necessary.","checks_status": {"fail": 1,"pass": 0,"total": 3,"manual": 0}},"SEC02-BP06": {"name": "SEC02-BP06","checks": {"iam_policy_allows_privilege_escalation": null,"iam_policy_attached_only_to_group_or_roles": null},"status": "PASS","attributes": [{"Name": "SEC02-BP06 Leverage user groups and attributes","Section": "Identity and access management","SubSection": "Identity management","Description": "As the number of users you manage grows, you will need to determine ways to organize them so that you can manage them at scale. Place users with common security requirements in groups defined by your identity provider, and put mechanisms in place to ensure that user attributes that may be used for access control (for example, department or location) are correct and updated. Use these groups and attributes to control access, rather than individual users. This allows you to manage access centrally by changing a user's group membership or attributes once with a permission set, rather than updating many individual policies when a user's access needs change. You can use AWS IAM Identity Center (successor to AWS Single Sign-On) (IAM Identity Center) to manage user groups and attributes. IAM Identity Center supports most commonly used attributes whether they are entered manually during user creation or automatically provisioned using a synchronization engine, such as defined in the System for Cross-Domain Identity Management (SCIM) specification.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_identities_groups_attributes.html#implementation-guidance.","WellArchitectedPracticeId": "sec_identities_groups_attributes","WellArchitectedQuestionId": "identities"}],"description": "As the number of users you manage grows, you will need to determine ways to organize them so that you can manage them at scale. Place users with common security requirements in groups defined by your identity provider, and put mechanisms in place to ensure that user attributes that may be used for access control (for example, department or location) are correct and updated. Use these groups and attributes to control access, rather than individual users. This allows you to manage access centrally by changing a user's group membership or attributes once with a permission set, rather than updating many individual policies when a user's access needs change. You can use AWS IAM Identity Center (successor to AWS Single Sign-On) (IAM Identity Center) to manage user groups and attributes. IAM Identity Center supports most commonly used attributes whether they are entered manually during user creation or automatically provisioned using a synchronization engine, such as defined in the System for Cross-Domain Identity Management (SCIM) specification.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"SEC03-BP01": {"name": "SEC03-BP01","checks": {"ec2_instance_imdsv2_enabled": "PASS","ec2_instance_profile_attached": "PASS","cloudwatch_cross_account_sharing_disabled": null},"status": "PASS","attributes": [{"Name": "SEC03-BP01 Define access requirements","Section": "Identity and access management","SubSection": "Permissions management","Description": "Each component or resource of your workload needs to be accessed by administrators, end users, or other components. Have a clear definition of who or what should have access to each component, choose the appropriate identity type and method of authentication and authorization.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_permissions_define.html#implementation-guidance.","WellArchitectedPracticeId": "sec_permissions_define","WellArchitectedQuestionId": "permissions"}],"description": "Each component or resource of your workload needs to be accessed by administrators, end users, or other components. Have a clear definition of who or what should have access to each component, choose the appropriate identity type and method of authentication and authorization.","checks_status": {"fail": 0,"pass": 2,"total": 3,"manual": 0}},"SEC03-BP02": {"name": "SEC03-BP02","checks": {"ec2_instance_profile_attached": "PASS","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"opensearch_service_domains_internal_user_database_enabled": null,"iam_customer_unattached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Name": "SEC03-BP02 Grant least privilege access","Section": "Identity and access management","SubSection": "Permissions management","Description": "Grant only the access that identities require by allowing access to specific actions on specific AWS resources under specific conditions. Rely on groups and identity attributes to dynamically set permissions at scale, rather than defining permissions for individual users. For example, you can allow a group of developers access to manage only resources for their project. This way, when a developer is removed from the group, access for the developer is revoked everywhere that group was used for access control, without requiring any changes to the access policies.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_permissions_least_privileges.html#implementation-guidance.","WellArchitectedPracticeId": "sec_permissions_least_privileges","WellArchitectedQuestionId": "permissions"}],"description": "Grant only the access that identities require by allowing access to specific actions on specific AWS resources under specific conditions. Rely on groups and identity attributes to dynamically set permissions at scale, rather than defining permissions for individual users. For example, you can allow a group of developers access to manage only resources for their project. This way, when a developer is removed from the group, access for the developer is revoked everywhere that group was used for access control, without requiring any changes to the access policies.","checks_status": {"fail": 0,"pass": 1,"total": 6,"manual": 0}},"SEC03-BP03": {"name": "SEC03-BP03","checks": {"account_maintain_current_contact_details": null,"account_security_contact_information_is_registered": null,"account_security_questions_are_registered_in_the_aws_account": null},"status": "PASS","attributes": [{"Name": "SEC03-BP03 Establish emergency access process","Section": "Identity and access management","SubSection": "Permissions management","Description": "A process that allows emergency access to your workload in the unlikely event of an automated process or pipeline issue. This will help you rely on least privilege access, but ensure users can obtain the right level of access when they require it. For example, establish a process for administrators to verify and approve their request, such as an emergency AWS cross-account role for access, or a specific process for administrators to follow to validate and approve an emergency request.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_permissions_emergency_process.html#implementation-guidance.","WellArchitectedPracticeId": "sec_permissions_emergency_process","WellArchitectedQuestionId": "permissions"}],"description": "A process that allows emergency access to your workload in the unlikely event of an automated process or pipeline issue. This will help you rely on least privilege access, but ensure users can obtain the right level of access when they require it. For example, establish a process for administrators to verify and approve their request, such as an emergency AWS cross-account role for access, or a specific process for administrators to follow to validate and approve an emergency request.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"SEC03-BP04": {"name": "SEC03-BP04","checks": {"iam_customer_attached_policy_no_administrative_privileges": null,"iam_customer_unattached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Name": "SEC03-BP04 Reduce permissions continuously","Section": "Identity and access management","SubSection": "Permissions management","Description": "As your teams determine what access is required, remove unneeded permissions and establish review processes to achieve least privilege permissions. Continually monitor and remove unused identities and permissions for both human and machine access.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_permissions_continuous_reduction.html#implementation-guidance.","WellArchitectedPracticeId": "sec_permissions_continuous_reduction","WellArchitectedQuestionId": "permissions"}],"description": "As your teams determine what access is required, remove unneeded permissions and establish review processes to achieve least privilege permissions. Continually monitor and remove unused identities and permissions for both human and machine access.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"SEC03-BP05": {"name": "SEC03-BP05","checks": {"organizations_account_part_of_organizations": null},"status": "PASS","attributes": [{"Name": "SEC03-BP05 Define permission guardrails for your organization","Section": "Identity and access management","SubSection": "Permissions management","Description": "Establish common controls that restrict access to all identities in your organization. For example, you can restrict access to specific AWS Regions, or prevent your operators from deleting common resources, such as an IAM role used for your central security team.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_permissions_define_guardrails.html#implementation-guidance.","WellArchitectedPracticeId": "sec_permissions_define_guardrails","WellArchitectedQuestionId": "permissions"}],"description": "Establish common controls that restrict access to all identities in your organization. For example, you can restrict access to specific AWS Regions, or prevent your operators from deleting common resources, such as an IAM role used for your central security team.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"SEC03-BP06": {"name": "SEC03-BP06","checks": {"ec2_elastic_ip_unassigned": "FAIL","elbv2_listeners_underneath": "PASS","codebuild_project_older_90_days": "FAIL","appstream_fleet_maximum_session_duration": null,"ecr_repositories_lifecycle_policy_enabled": "FAIL","appstream_fleet_session_disconnect_timeout": null,"appstream_fleet_session_idle_disconnect_timeout": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "FAIL","attributes": [{"Name": "SEC03-BP06 Manage access based on lifecycle","Section": "Identity and access management","SubSection": "Permissions management","Description": "Integrate access controls with operator and application lifecycle and your centralized federation provider. For example, remove a user's access when they leave the organization or change roles. As you manage workloads using separate accounts, there will be cases where you need to share resources between those accounts. We recommend that you share resources using AWS Resource Access Manager (AWS RAM). This service enables you to easily and securely share AWS resources within your AWS Organizations and Organizational Units. Using AWS RAM, access to shared resources is automatically granted or revoked as accounts are moved in and out of the Organization or Organization Unit with which they are shared. This helps ensure that resources are only shared with the accounts that you intend.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_permissions_lifecycle.html#implementation-guidance.","WellArchitectedPracticeId": "sec_permissions_lifecycle","WellArchitectedQuestionId": "permissions"}],"description": "Integrate access controls with operator and application lifecycle and your centralized federation provider. For example, remove a user's access when they leave the organization or change roles. As you manage workloads using separate accounts, there will be cases where you need to share resources between those accounts. We recommend that you share resources using AWS Resource Access Manager (AWS RAM). This service enables you to easily and securely share AWS resources within your AWS Organizations and Organizational Units. Using AWS RAM, access to shared resources is automatically granted or revoked as accounts are moved in and out of the Organization or Organization Unit with which they are shared. This helps ensure that resources are only shared with the accounts that you intend.","checks_status": {"fail": 4,"pass": 1,"total": 9,"manual": 0}},"SEC03-BP07": {"name": "SEC03-BP07","checks": {"ec2_ami_public": null,"elb_internet_facing": "FAIL","elbv2_internet_facing": "PASS","ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"apigateway_restapi_public": "FAIL","efs_not_publicly_accessible": "FAIL","rds_snapshots_public_access": "PASS","ssm_documents_set_as_public": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","emr_cluster_publicly_accesible": null,"redshift_cluster_public_access": null,"kms_key_not_publicly_accessible": null,"awslambda_function_url_cors_policy": null,"sns_topics_not_publicly_accessible": "PASS","sqs_queues_not_publicly_accessible": "PASS","eks_cluster_not_publicly_accessible": null,"glacier_vaults_policy_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"ecr_repositories_not_publicly_accessible": "PASS","emr_cluster_account_public_block_enabled": "PASS","awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","appstream_fleet_default_internet_access_disabled": null,"opensearch_service_domains_not_publicly_accessible": null,"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS","codeartifact_packages_external_public_publishing_disabled": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Name": "SEC03-BP07 Analyze public and cross-account access","Section": "Identity and access management","SubSection": "Permissions management","Description": "Continuously monitor findings that highlight public and cross-account access. Reduce public access and cross-account access to only resources that require this type of access.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_permissions_analyze_cross_account.html#implementation-guidance.","WellArchitectedPracticeId": "sec_permissions_analyze_cross_account","WellArchitectedQuestionId": "permissions"}],"description": "Continuously monitor findings that highlight public and cross-account access. Reduce public access and cross-account access to only resources that require this type of access.","checks_status": {"fail": 4,"pass": 13,"total": 35,"manual": 0}},"SEC03-BP08": {"name": "SEC03-BP08","checks": {"ssm_document_secrets": "PASS","awslambda_function_not_publicly_accessible": "PASS","codebuild_project_user_controlled_buildspec": "PASS","opensearch_service_domains_not_publicly_accessible": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "PASS","attributes": [{"Name": "SEC03-BP08 Share resources securely within your organization","Section": "Identity and access management","SubSection": "Permissions management","Description": "Govern the consumption of shared resources across accounts or within your AWS Organizations. Monitor shared resources and review shared resource access.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_permissions_share_securely.html#implementation-guidance.","WellArchitectedPracticeId": "sec_permissions_share_securely","WellArchitectedQuestionId": "permissions"}],"description": "Govern the consumption of shared resources across accounts or within your AWS Organizations. Monitor shared resources and review shared resource access.","checks_status": {"fail": 0,"pass": 3,"total": 5,"manual": 0}},"SEC04-BP01": {"name": "SEC04-BP01","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"apigatewayv2_api_access_logging_enabled": "FAIL","s3_bucket_server_access_logging_enabled": "FAIL","cloudfront_distributions_logging_enabled": null,"rds_instance_integration_cloudwatch_logs": "FAIL","acm_certificates_transparency_logs_enabled": "PASS","eks_control_plane_logging_all_types_enabled": null,"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL","opensearch_service_domains_audit_logging_enabled": null,"directoryservice_directory_log_forwarding_enabled": null,"opensearch_service_domains_cloudwatch_logging_enabled": null,"route53_public_hosted_zones_cloudwatch_logging_enabled": null,"awslambda_function_invoke_api_operations_cloudtrail_logging_enabled": "PASS"},"status": "FAIL","attributes": [{"Name": "SEC04-BP01 Configure service and application logging","Section": "Detection","SubSection": "Detection","Description": "Retain security event logs from services and applications. This is a fundamental principle of security for audit, investigations, and operational use cases, and a common security requirement driven by governance, risk, and compliance (GRC) standards, policies, and procedures.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_detect_investigate_events_app_service_logging.html#implementation-guidance.","WellArchitectedPracticeId": "sec_detect_investigate_events_app_service_logging","WellArchitectedQuestionId": "detect-investigate-events"}],"description": "Retain security event logs from services and applications. This is a fundamental principle of security for audit, investigations, and operational use cases, and a common security requirement driven by governance, risk, and compliance (GRC) standards, policies, and procedures.","checks_status": {"fail": 8,"pass": 3,"total": 21,"manual": 0}},"SEC04-BP02": {"name": "SEC04-BP02","checks": {"vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","config_recorder_all_regions_enabled": null},"status": "FAIL","attributes": [{"Name": "SEC04-BP02 Analyze logs, findings, and metrics centrally","Section": "Detection","SubSection": "Detection","Description": "Security operations teams rely on the collection of logs and the use of search tools to discover potential events of interest, which might indicate unauthorized activity or unintentional change. However, simply analyzing collected data and manually processing information is insufficient to keep up with the volume of information flowing from complex architectures. Analysis and reporting alone don't facilitate the assignment of the right resources to work an event in a timely fashion. A best practice for building a mature security operations team is to deeply integrate the flow of security events and findings into a notification and workflow system such as a ticketing system, a bug or issue system, or other security information and event management (SIEM) system. This takes the workflow out of email and static reports, and allows you to route, escalate, and manage events or findings. Many organizations are also integrating security alerts into their chat or collaboration, and developer productivity platforms. For organizations embarking on automation, an API-driven, low-latency ticketing system offers considerable flexibility when planning what to automate first. This best practice applies not only to security events generated from log messages depicting user activity or network events, but also from changes detected in the infrastructure itself. The ability to detect change, determine whether a change was appropriate, and then route that information to the correct remediation workflow is essential in maintaining and validating a secure architecture, in the context of changes where the nature of their undesirability is sufficiently subtle that their execution cannot currently be prevented with a combination of AWS Identity and Access Management (IAM) and AWS Organizations configuration. Amazon GuardDuty and AWS Security Hub provide aggregation, deduplication, and analysis mechanisms for log records that are also made available to you via other AWS services. GuardDuty ingests, aggregates, and analyzes information from sources such as AWS CloudTrail management and data events, VPC DNS logs, and VPC Flow Logs. Security Hub can ingest, aggregate, and analyze output from GuardDuty, AWS Config, Amazon Inspector, Amazon Macie, AWS Firewall Manager, and a significant number of third-party security products available in the AWS Marketplace, and if built accordingly, your own code. Both GuardDuty and Security Hub have an Administrator-Member model that can aggregate findings and insights across multiple accounts, and Security Hub is often used by customers who have an on- premises SIEM as an AWS-side log and alert preprocessor and aggregator from which they can then ingest Amazon EventBridge through a AWS Lambda-based processor and forwarder.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_detect_investigate_events_analyze_all.html#implementation-guidance.","WellArchitectedPracticeId": "sec_detect_investigate_events_analyze_all","WellArchitectedQuestionId": "detect-investigate-events"}],"description": "Security operations teams rely on the collection of logs and the use of search tools to discover potential events of interest, which might indicate unauthorized activity or unintentional change. However, simply analyzing collected data and manually processing information is insufficient to keep up with the volume of information flowing from complex architectures. Analysis and reporting alone don't facilitate the assignment of the right resources to work an event in a timely fashion. A best practice for building a mature security operations team is to deeply integrate the flow of security events and findings into a notification and workflow system such as a ticketing system, a bug or issue system, or other security information and event management (SIEM) system. This takes the workflow out of email and static reports, and allows you to route, escalate, and manage events or findings. Many organizations are also integrating security alerts into their chat or collaboration, and developer productivity platforms. For organizations embarking on automation, an API-driven, low-latency ticketing system offers considerable flexibility when planning what to automate first. This best practice applies not only to security events generated from log messages depicting user activity or network events, but also from changes detected in the infrastructure itself. The ability to detect change, determine whether a change was appropriate, and then route that information to the correct remediation workflow is essential in maintaining and validating a secure architecture, in the context of changes where the nature of their undesirability is sufficiently subtle that their execution cannot currently be prevented with a combination of AWS Identity and Access Management (IAM) and AWS Organizations configuration. Amazon GuardDuty and AWS Security Hub provide aggregation, deduplication, and analysis mechanisms for log records that are also made available to you via other AWS services. GuardDuty ingests, aggregates, and analyzes information from sources such as AWS CloudTrail management and data events, VPC DNS logs, and VPC Flow Logs. Security Hub can ingest, aggregate, and analyze output from GuardDuty, AWS Config, Amazon Inspector, Amazon Macie, AWS Firewall Manager, and a significant number of third-party security products available in the AWS Marketplace, and if built accordingly, your own code. Both GuardDuty and Security Hub have an Administrator-Member model that can aggregate findings and insights across multiple accounts, and Security Hub is often used by customers who have an on- premises SIEM as an AWS-side log and alert preprocessor and aggregator from which they can then ingest Amazon EventBridge through a AWS Lambda-based processor and forwarder.","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"SEC04-BP03": {"name": "SEC04-BP03","checks": {"elb_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS"},"status": "FAIL","attributes": [{"Name": "SEC04-BP03 Automate response to events","Section": "Detection","SubSection": "Detection","Description": "Using automation to investigate and remediate events reduces human effort and error, and enables you to scale investigation capabilities. Regular reviews will help you tune automation tools, and continuously iterate. In AWS, investigating events of interest and information on potentially unexpected changes into an automated workflow can be achieved using Amazon EventBridge. This service provides a scalable rules engine designed to broker both native AWS event formats (such as AWS CloudTrail events), as well as custom events you can generate from your application. Amazon GuardDuty also allows you to route events to a workflow system for those building incident response systems (AWS Step Functions), or to a central Security Account, or to a bucket for further analysis. Detecting change and routing this information to the correct workflow can also be accomplished using AWS Config Rules and Conformance Packs. AWS Config detects changes to in-scope services (though with higher latency than EventBridge) and generates events that can be parsed using AWS Config Rules for rollback, enforcement of compliance policy, and forwarding of information to systems, such as change management platforms and operational ticketing systems. As well as writing your own Lambda functions to respond to AWS Config events, you can also take advantage of the AWS Config Rules Development Kit, and a library of open source AWS Config Rules. Conformance packs are a collection of AWS Config Rules and remediation actions you deploy as a single entity authored as a YAML template. A sample conformance pack template is available for the Well-Architected Security Pillar.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_detect_investigate_events_auto_response.html#implementation-guidance.","WellArchitectedPracticeId": "sec_detect_investigate_events_auto_response","WellArchitectedQuestionId": "detect-investigate-events"}],"description": "Using automation to investigate and remediate events reduces human effort and error, and enables you to scale investigation capabilities. Regular reviews will help you tune automation tools, and continuously iterate. In AWS, investigating events of interest and information on potentially unexpected changes into an automated workflow can be achieved using Amazon EventBridge. This service provides a scalable rules engine designed to broker both native AWS event formats (such as AWS CloudTrail events), as well as custom events you can generate from your application. Amazon GuardDuty also allows you to route events to a workflow system for those building incident response systems (AWS Step Functions), or to a central Security Account, or to a bucket for further analysis. Detecting change and routing this information to the correct workflow can also be accomplished using AWS Config Rules and Conformance Packs. AWS Config detects changes to in-scope services (though with higher latency than EventBridge) and generates events that can be parsed using AWS Config Rules for rollback, enforcement of compliance policy, and forwarding of information to systems, such as change management platforms and operational ticketing systems. As well as writing your own Lambda functions to respond to AWS Config events, you can also take advantage of the AWS Config Rules Development Kit, and a library of open source AWS Config Rules. Conformance packs are a collection of AWS Config Rules and remediation actions you deploy as a single entity authored as a YAML template. A sample conformance pack template is available for the Well-Architected Security Pillar.","checks_status": {"fail": 2,"pass": 1,"total": 3,"manual": 0}},"SEC04-BP04": {"name": "SEC04-BP04","checks": {"macie_is_enabled": "PASS","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"directoryservice_directory_monitor_notifications": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Name": "SEC04-BP04 Implement actionable security events","Section": "Detection","SubSection": "Detection","Description": "Create alerts that are sent to and can be actioned by your team. Ensure that alerts include relevant information for the team to take action. For each detective mechanism you have, you should also have a process, in the form of a runbook or playbook, to investigate. For example, when you enable Amazon GuardDuty, it generates different findings. You should have a runbook entry for each finding type, for example, if a trojan is discovered, your runbook has simple instructions that instruct someone to investigate and remediate.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_detect_investigate_events_actionable_events.html#implementation-guidance.","WellArchitectedPracticeId": "sec_detect_investigate_events_actionable_events","WellArchitectedQuestionId": "detect-investigate-events"}],"description": "Create alerts that are sent to and can be actioned by your team. Ensure that alerts include relevant information for the team to take action. For each detective mechanism you have, you should also have a process, in the form of a runbook or playbook, to investigate. For example, when you enable Amazon GuardDuty, it generates different findings. You should have a runbook entry for each finding type, for example, if a trojan is discovered, your runbook has simple instructions that instruct someone to investigate and remediate.","checks_status": {"fail": 1,"pass": 3,"total": 20,"manual": 0}},"SEC05-BP01": {"name": "SEC05-BP01","checks": {"cloudfront_distributions_using_waf": null,"apigateway_restapi_waf_acl_attached": "FAIL","eks_cluster_not_publicly_accessible": null,"sagemaker_models_vpc_settings_configured": null,"vpc_endpoint_connections_trust_boundaries": "FAIL","awslambda_function_not_publicly_accessible": "PASS","sagemaker_models_network_isolation_enabled": null,"sagemaker_training_jobs_vpc_settings_configured": null,"sagemaker_training_jobs_network_isolation_enabled": null,"opensearch_service_domains_not_publicly_accessible": null,"sagemaker_notebook_instance_vpc_settings_configured": null,"vpc_endpoint_services_allowed_principals_trust_boundaries": null},"status": "FAIL","attributes": [{"Name": "SEC05-BP01 Create network layers","Section": "Infrastructure protection","SubSection": "Protecting networks","Description": "Group components that share reachability requirements into layers. For example, a database cluster in a virtual private cloud (VPC) with no need for internet access should be placed in subnets with no route to or from the internet. In a serverless workload operating without a VPC, similar layering and segmentation with microservices can achieve the same goal. Components such as Amazon Elastic Compute Cloud (Amazon EC2) instances, Amazon Relational Database Service (Amazon RDS) database clusters, and AWS Lambda functions that share reachability requirements can be segmented into layers formed by subnets. For example, an Amazon RDS database cluster in a VPC with no need for internet access should be placed in subnets with no route to or from the internet. This layered approach for the controls mitigates the impact of a single layer misconfiguration, which could allow unintended access. For Lambda, you can run your functions in your VPC to take advantage of VPC-based controls. For network connectivity that can include thousands of VPCs, AWS accounts, and on-premises networks, you should use AWS Transit Gateway. It acts as a hub that controls how traffic is routed among all the connected networks, which act like spokes. Traffic between an Amazon Virtual Private Cloud and AWS Transit Gateway remains on the AWS private network, which reduces external threat vectors such as distributed denial of service (DDoS) attacks and common exploits, such as SQL injection, cross-site scripting, cross-site request forgery, or abuse of broken authentication code. AWS Transit Gateway inter-region peering also encrypts inter-region traffic with no single point of failure or bandwidth bottleneck.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_network_protection_create_layers.html#implementation-guidance.","WellArchitectedPracticeId": "sec_network_protection_create_layers","WellArchitectedQuestionId": "network-protection"}],"description": "Group components that share reachability requirements into layers. For example, a database cluster in a virtual private cloud (VPC) with no need for internet access should be placed in subnets with no route to or from the internet. In a serverless workload operating without a VPC, similar layering and segmentation with microservices can achieve the same goal. Components such as Amazon Elastic Compute Cloud (Amazon EC2) instances, Amazon Relational Database Service (Amazon RDS) database clusters, and AWS Lambda functions that share reachability requirements can be segmented into layers formed by subnets. For example, an Amazon RDS database cluster in a VPC with no need for internet access should be placed in subnets with no route to or from the internet. This layered approach for the controls mitigates the impact of a single layer misconfiguration, which could allow unintended access. For Lambda, you can run your functions in your VPC to take advantage of VPC-based controls. For network connectivity that can include thousands of VPCs, AWS accounts, and on-premises networks, you should use AWS Transit Gateway. It acts as a hub that controls how traffic is routed among all the connected networks, which act like spokes. Traffic between an Amazon Virtual Private Cloud and AWS Transit Gateway remains on the AWS private network, which reduces external threat vectors such as distributed denial of service (DDoS) attacks and common exploits, such as SQL injection, cross-site scripting, cross-site request forgery, or abuse of broken authentication code. AWS Transit Gateway inter-region peering also encrypts inter-region traffic with no single point of failure or bandwidth bottleneck.","checks_status": {"fail": 2,"pass": 1,"total": 12,"manual": 0}},"SEC05-BP02": {"name": "SEC05-BP02","checks": {"ec2_ebs_public_snapshot": "PASS","s3_bucket_no_mfa_delete": "FAIL","s3_bucket_acl_prohibited": "FAIL","apigatewayv2_api_authorizers_enabled": "FAIL","apigateway_restapi_authorizers_enabled": "PASS","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Name": "SEC05-BP02 Control traffic at all layers","Section": "Infrastructure protection","SubSection": "Protecting networks","Description": "When architecting your network topology, you should examine the connectivity requirements of each component. For example, if a component requires internet accessibility (inbound and outbound), connectivity to VPCs, edge services, and external data centers. A VPC allows you to define your network topology that spans an AWS Region with a private IPv4 address range that you set, or an IPv6 address range AWS selects. You should apply multiple controls with a defense in depth approach for both inbound and outbound traffic, including the use of security groups (stateful inspection firewall), Network ACLs, subnets, and route tables. Within a VPC, you can create subnets in an Availability Zone. Each subnet can have an associated route table that defines routing rules for managing the paths that traffic takes within the subnet. You can define an internet routable subnet by having a route that goes to an internet or NAT gateway attached to the VPC, or through another VPC. When an instance, Amazon Relational Database Service(Amazon RDS) database, or other service is launched within a VPC, it has its own security group per network interface. This firewall is outside the operating system layer and can be used to define rules for allowed inbound and outbound traffic. You can also define relationships between security groups. For example, instances within a database tier security group only accept traffic from instances within the application tier, by reference to the security groups applied to the instances involved. Unless you are using non-TCP protocols, it shouldn't be necessary to have an Amazon Elastic Compute Cloud(Amazon EC2) instance directly accessible by the internet (even with ports restricted by security groups) without a load balancer, or CloudFront. This helps protect it from unintended access through an operating system or application issue. A subnet can also have a network ACL attached to it, which acts as a stateless firewall. You should configure the network ACL to narrow the scope of traffic allowed between layers, note that you need to define both inbound and outbound rules. Some AWS services require components to access the internet for making API calls, where AWS API endpoints are located. Other AWS services use VPC endpoints within your Amazon VPCs. Many AWS services, including Amazon S3 and Amazon DynamoDB, support VPC endpoints, and this technology has been generalized in AWS PrivateLink. We recommend you use this approach to access AWS services, third-party services, and your own services hosted in other VPCs securely. All network traffic on AWS PrivateLink stays on the global AWS backbone and never traverses the internet. Connectivity can only be initiated by the consumer of the service, and not by the provider of the service. Using AWS PrivateLink for external service access allows you to create air-gapped VPCs with no internet access and helps protect your VPCs from external threat vectors. Third-party services can use AWS PrivateLink to allow their customers to connect to the services from their VPCs over private IP addresses. For VPC assets that need to make outbound connections to the internet, these can be made outbound only (one-way) through an AWS managed NAT gateway, outbound only internet gateway, or web proxies that you create and manage.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_network_protection_layered.html#implementation-guidance.","WellArchitectedPracticeId": "sec_network_protection_layered","WellArchitectedQuestionId": "network-protection"}],"description": "When architecting your network topology, you should examine the connectivity requirements of each component. For example, if a component requires internet accessibility (inbound and outbound), connectivity to VPCs, edge services, and external data centers. A VPC allows you to define your network topology that spans an AWS Region with a private IPv4 address range that you set, or an IPv6 address range AWS selects. You should apply multiple controls with a defense in depth approach for both inbound and outbound traffic, including the use of security groups (stateful inspection firewall), Network ACLs, subnets, and route tables. Within a VPC, you can create subnets in an Availability Zone. Each subnet can have an associated route table that defines routing rules for managing the paths that traffic takes within the subnet. You can define an internet routable subnet by having a route that goes to an internet or NAT gateway attached to the VPC, or through another VPC. When an instance, Amazon Relational Database Service(Amazon RDS) database, or other service is launched within a VPC, it has its own security group per network interface. This firewall is outside the operating system layer and can be used to define rules for allowed inbound and outbound traffic. You can also define relationships between security groups. For example, instances within a database tier security group only accept traffic from instances within the application tier, by reference to the security groups applied to the instances involved. Unless you are using non-TCP protocols, it shouldn't be necessary to have an Amazon Elastic Compute Cloud(Amazon EC2) instance directly accessible by the internet (even with ports restricted by security groups) without a load balancer, or CloudFront. This helps protect it from unintended access through an operating system or application issue. A subnet can also have a network ACL attached to it, which acts as a stateless firewall. You should configure the network ACL to narrow the scope of traffic allowed between layers, note that you need to define both inbound and outbound rules. Some AWS services require components to access the internet for making API calls, where AWS API endpoints are located. Other AWS services use VPC endpoints within your Amazon VPCs. Many AWS services, including Amazon S3 and Amazon DynamoDB, support VPC endpoints, and this technology has been generalized in AWS PrivateLink. We recommend you use this approach to access AWS services, third-party services, and your own services hosted in other VPCs securely. All network traffic on AWS PrivateLink stays on the global AWS backbone and never traverses the internet. Connectivity can only be initiated by the consumer of the service, and not by the provider of the service. Using AWS PrivateLink for external service access allows you to create air-gapped VPCs with no internet access and helps protect your VPCs from external threat vectors. Third-party services can use AWS PrivateLink to allow their customers to connect to the services from their VPCs over private IP addresses. For VPC assets that need to make outbound connections to the internet, these can be made outbound only (one-way) through an AWS managed NAT gateway, outbound only internet gateway, or web proxies that you create and manage.","checks_status": {"fail": 4,"pass": 2,"total": 7,"manual": 0}},"SEC05-BP03": {"name": "SEC05-BP03","checks": {"elbv2_waf_acl_attached": "FAIL","ec2_securitygroup_not_used": "FAIL","elbv2_desync_mitigation_mode": "FAIL","ec2_securitygroup_from_launch_wizard": "FAIL","route53_domains_transferlock_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","route53_domains_privacy_protection_enabled": null,"ec2_securitygroup_with_many_ingress_egress_rules": "PASS","shield_advanced_protection_in_global_accelerators": null,"shield_advanced_protection_in_route53_hosted_zones": null,"shield_advanced_protection_in_associated_elastic_ips": null,"shield_advanced_protection_in_classic_load_balancers": null,"shield_advanced_protection_in_cloudfront_distributions": null,"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","shield_advanced_protection_in_internet_facing_load_balancers": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Name": "SEC05-BP03 Automate network protections","Section": "Infrastructure protection","SubSection": "Protecting networks","Description": "Automate protection mechanisms to provide a self-defending network based on threat intelligence and anomaly detection. For example, intrusion detection and prevention tools that can adapt to current threats and reduce their impact. A web application firewall is an example of where you can automate network protection, for example, by using the AWS WAF Security Automations solution (https://github.com/awslabs/aws-waf-security-automations) to automatically block requests originating from IP addresses associated with known threat actors.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_network_protection_auto_protect.html#implementation-guidance.","WellArchitectedPracticeId": "sec_network_protection_auto_protect","WellArchitectedQuestionId": "network-protection"}],"description": "Automate protection mechanisms to provide a self-defending network based on threat intelligence and anomaly detection. For example, intrusion detection and prevention tools that can adapt to current threats and reduce their impact. A web application firewall is an example of where you can automate network protection, for example, by using the AWS WAF Security Automations solution (https://github.com/awslabs/aws-waf-security-automations) to automatically block requests originating from IP addresses associated with known threat actors.","checks_status": {"fail": 8,"pass": 16,"total": 33,"manual": 0}},"SEC05-BP04": {"name": "SEC05-BP04","checks": {"guardduty_is_enabled": "PASS","vpc_flow_logs_enabled": "FAIL","apigateway_restapi_authorizers_enabled": "PASS"},"status": "FAIL","attributes": [{"Name": "SEC05-BP04 Implement inspection and protection","Section": "Infrastructure protection","SubSection": "Protecting networks","Description": "Inspect and filter your traffic at each layer. You can inspect your VPC configurations for potential unintended access using VPC Network Access Analyzer. You can specify your network access requirements and identify potential network paths that do not meet them. For components transacting over HTTP-based protocols, a web application firewall can help protect from common attacks. AWS WAF is a web application firewall that lets you monitor and block HTTP(s) requests that match your configurable rules that are forwarded to an Amazon API Gateway API, Amazon CloudFront, or an Application Load Balancer. To get started with AWS WAF, you can use AWS Managed Rules in combination with your own, or use existing partner integrations. For managing AWS WAF, AWS Shield Advanced protections, and Amazon VPC security groups across AWS Organizations, you can use AWS Firewall Manager. It allows you to centrally configure and manage firewall rules across your accounts and applications, making it easier to scale enforcement of common rules. It also enables you to rapidly respond to attacks, using AWS Shield Advanced, or solutions that can automatically block unwanted requests to your web applications. Firewall Manager also works with AWS Network Firewall. AWS Network Firewall is a managed service that uses a rules engine to give you fine-grained control over both stateful and stateless network traffic. It supports the Suricata compatible open source intrusion prevention system (IPS) specifications for rules to help protect your workload.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_network_protection_inspection.html#implementation-guidance.","WellArchitectedPracticeId": "sec_network_protection_inspection","WellArchitectedQuestionId": "network-protection"}],"description": "Inspect and filter your traffic at each layer. You can inspect your VPC configurations for potential unintended access using VPC Network Access Analyzer. You can specify your network access requirements and identify potential network paths that do not meet them. For components transacting over HTTP-based protocols, a web application firewall can help protect from common attacks. AWS WAF is a web application firewall that lets you monitor and block HTTP(s) requests that match your configurable rules that are forwarded to an Amazon API Gateway API, Amazon CloudFront, or an Application Load Balancer. To get started with AWS WAF, you can use AWS Managed Rules in combination with your own, or use existing partner integrations. For managing AWS WAF, AWS Shield Advanced protections, and Amazon VPC security groups across AWS Organizations, you can use AWS Firewall Manager. It allows you to centrally configure and manage firewall rules across your accounts and applications, making it easier to scale enforcement of common rules. It also enables you to rapidly respond to attacks, using AWS Shield Advanced, or solutions that can automatically block unwanted requests to your web applications. Firewall Manager also works with AWS Network Firewall. AWS Network Firewall is a managed service that uses a rules engine to give you fine-grained control over both stateful and stateless network traffic. It supports the Suricata compatible open source intrusion prevention system (IPS) specifications for rules to help protect your workload.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"SEC06-BP01": {"name": "SEC06-BP01","checks": {"ec2_instance_imdsv2_enabled": "PASS","ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"cloudtrail_log_file_validation_enabled": "FAIL","rds_instance_minor_version_upgrade_enabled": "PASS","ec2_instance_internet_facing_with_instance_profile": "FAIL","opensearch_service_domains_updated_to_the_latest_service_software_version": null},"status": "FAIL","attributes": [{"Name": "SEC06-BP01 Perform vulnerability management","Section": "Infrastructure protection","SubSection": "Protecting compute","Description": "Frequently scan and patch for vulnerabilities in your code, dependencies, and in your infrastructure to help protect against new threats. Starting with the configuration of your compute infrastructure, you can automate creating and updating resources using AWS CloudFormation. CloudFormation allows you to create templates written in YAML or JSON, either using AWS examples or by writing your own. This allows you to create secure-by-default infrastructure templates that you can verify with CloudFormation Guard, to save you time and reduce the risk of configuration error. You can build your infrastructure and deploy your applications using continuous delivery, for example with AWS CodePipeline, to automate the building, testing, and release. You are responsible for patch management for your AWS resources, including Amazon Elastic Compute Cloud(Amazon EC2) instances, Amazon Machine Images (AMIs), and many other compute resources. For Amazon EC2 instances, AWS Systems Manager Patch Manager automates the process of patching managed instances with both security related and other types of updates. You can use Patch Manager to apply patches for both operating systems and applications. (On Windows Server, application support is limited to updates for Microsoft applications.) You can use Patch Manager to install Service Packs on Windows instances and perform minor version upgrades on Linux instances. You can patch fleets of Amazon EC2 instances or your on-premises servers and virtual machines (VMs) by operating system type. This includes supported versions of Windows Server, Amazon Linux, Amazon Linux 2, CentOS, Debian Server, Oracle Linux, Red Hat Enterprise Linux (RHEL), SUSE Linux Enterprise Server (SLES), and Ubuntu Server. You can scan instances to see only a report of missing patches, or you can scan and automatically install all missing patches.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_network_protection_inspection.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_compute_vulnerability_management","WellArchitectedQuestionId": "protect-compute"}],"description": "Frequently scan and patch for vulnerabilities in your code, dependencies, and in your infrastructure to help protect against new threats. Starting with the configuration of your compute infrastructure, you can automate creating and updating resources using AWS CloudFormation. CloudFormation allows you to create templates written in YAML or JSON, either using AWS examples or by writing your own. This allows you to create secure-by-default infrastructure templates that you can verify with CloudFormation Guard, to save you time and reduce the risk of configuration error. You can build your infrastructure and deploy your applications using continuous delivery, for example with AWS CodePipeline, to automate the building, testing, and release. You are responsible for patch management for your AWS resources, including Amazon Elastic Compute Cloud(Amazon EC2) instances, Amazon Machine Images (AMIs), and many other compute resources. For Amazon EC2 instances, AWS Systems Manager Patch Manager automates the process of patching managed instances with both security related and other types of updates. You can use Patch Manager to apply patches for both operating systems and applications. (On Windows Server, application support is limited to updates for Microsoft applications.) You can use Patch Manager to install Service Packs on Windows instances and perform minor version upgrades on Linux instances. You can patch fleets of Amazon EC2 instances or your on-premises servers and virtual machines (VMs) by operating system type. This includes supported versions of Windows Server, Amazon Linux, Amazon Linux 2, CentOS, Debian Server, Oracle Linux, Red Hat Enterprise Linux (RHEL), SUSE Linux Enterprise Server (SLES), and Ubuntu Server. You can scan instances to see only a report of missing patches, or you can scan and automatically install all missing patches.","checks_status": {"fail": 3,"pass": 2,"total": 7,"manual": 0}},"SEC06-BP02": {"name": "SEC06-BP02","checks": {"awslambda_function_not_publicly_accessible": "PASS","ecr_repositories_scan_images_on_push_enabled": "FAIL"},"status": "FAIL","attributes": [{"Name": "SEC06-BP02 Reduce attack surface","Section": "Infrastructure protection","SubSection": "Protecting compute","Description": "Reduce your exposure to unintended access by hardening operating systems and minimizing the components, libraries, and externally consumable services in use. Start by reducing unused components, whether they are operating system packages or applications, for Amazon Elastic Compute Cloud (Amazon EC2)-based workloads, or external software modules in your code, for all workloads. You can find many hardening and security configuration guides for common operating systems and server software. For example, you can start with the Center for Internet Security and iterate.In Amazon EC2, you can create your own Amazon Machine Images (AMIs), which you have patched and hardened, to help you meet the specific security requirements for your organization. The patches and other security controls you apply on the AMI are effective at the point in time in which they were created—they are not dynamic unless you modify after launching, for example, with AWS Systems Manager.You can simplify the process of building secure AMIs with EC2 Image Builder. EC2 Image Builder significantly reduces the effort required to create and maintain golden images without writing and maintaining automation. When software updates become available, Image Builder automatically produces a new image without requiring users to manually initiate image builds. EC2 Image Builder allows you to easily validate the functionality and security of your images before using them in production with AWS-provided tests and your own tests. You can also apply AWS-provided security settings to further secure your images to meet internal security criteria. For example, you can produce images that conform to the Security Technical Implementation Guide (STIG) standard using AWS-provided templates.Using third-party static code analysis tools, you can identify common security issues such as unchecked function input bounds, as well as applicable common vulnerabilities and exposures (CVEs). You can use Amazon CodeGuru for supported languages. Dependency checking tools can also be used to determine whether libraries your code links against are the latest versions, are themselves free of CVEs, and have licensing conditions that meet your software policy requirements.Using Amazon Inspector, you can perform configuration assessments against your instances for known CVEs, assess against security benchmarks, and automate the notification of defects. Amazon Inspector runs on production instances or in a build pipeline, and it notifies developers and engineers when findings are present. You can access findings programmatically and direct your team to backlogs and bug-tracking systems. EC2 Image Builder can be used to maintain server images (AMIs) with automated patching, AWS-provided security policy enforcement, and other customizations. When using containers implement ECR Image Scanning in your build pipeline and on a regular basis against your image repository to look for CVEs in your containers.While Amazon Inspector and other tools are effective at identifying configurations and any CVEs that are present, other methods are required to test your workload at the application level. Fuzzing is a well-known method of finding bugs using automation to inject malformed data into input fields and other areas of your application.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_compute_reduce_surface.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_compute_reduce_surface","WellArchitectedQuestionId": "protect-compute"}],"description": "Reduce your exposure to unintended access by hardening operating systems and minimizing the components, libraries, and externally consumable services in use. Start by reducing unused components, whether they are operating system packages or applications, for Amazon Elastic Compute Cloud (Amazon EC2)-based workloads, or external software modules in your code, for all workloads. You can find many hardening and security configuration guides for common operating systems and server software. For example, you can start with the Center for Internet Security and iterate.In Amazon EC2, you can create your own Amazon Machine Images (AMIs), which you have patched and hardened, to help you meet the specific security requirements for your organization. The patches and other security controls you apply on the AMI are effective at the point in time in which they were created—they are not dynamic unless you modify after launching, for example, with AWS Systems Manager.You can simplify the process of building secure AMIs with EC2 Image Builder. EC2 Image Builder significantly reduces the effort required to create and maintain golden images without writing and maintaining automation. When software updates become available, Image Builder automatically produces a new image without requiring users to manually initiate image builds. EC2 Image Builder allows you to easily validate the functionality and security of your images before using them in production with AWS-provided tests and your own tests. You can also apply AWS-provided security settings to further secure your images to meet internal security criteria. For example, you can produce images that conform to the Security Technical Implementation Guide (STIG) standard using AWS-provided templates.Using third-party static code analysis tools, you can identify common security issues such as unchecked function input bounds, as well as applicable common vulnerabilities and exposures (CVEs). You can use Amazon CodeGuru for supported languages. Dependency checking tools can also be used to determine whether libraries your code links against are the latest versions, are themselves free of CVEs, and have licensing conditions that meet your software policy requirements.Using Amazon Inspector, you can perform configuration assessments against your instances for known CVEs, assess against security benchmarks, and automate the notification of defects. Amazon Inspector runs on production instances or in a build pipeline, and it notifies developers and engineers when findings are present. You can access findings programmatically and direct your team to backlogs and bug-tracking systems. EC2 Image Builder can be used to maintain server images (AMIs) with automated patching, AWS-provided security policy enforcement, and other customizations. When using containers implement ECR Image Scanning in your build pipeline and on a regular basis against your image repository to look for CVEs in your containers.While Amazon Inspector and other tools are effective at identifying configurations and any CVEs that are present, other methods are required to test your workload at the application level. Fuzzing is a well-known method of finding bugs using automation to inject malformed data into input fields and other areas of your application.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"SEC06-BP03": {"name": "SEC06-BP03","checks": {},"status": "PASS","attributes": [{"Name": "SEC06-BP03 Implement managed services","Section": "Infrastructure protection","SubSection": "Protecting compute","Description": "Implement services that manage resources, such as Amazon Relational Database Service (Amazon RDS), AWS Lambda, and Amazon Elastic Container Service (Amazon ECS), to reduce your security maintenance tasks as part of the shared responsibility model. For example, Amazon RDS helps you set up, operate, and scale a relational database, automates administration tasks such as hardware provisioning, database setup, patching, and backups. This means you have more free time to focus on securing your application in other ways described in the AWS Well-Architected Framework. Lambda lets you run code without provisioning or managing servers, so you only need to focus on the connectivity, invocation, and security at the code level–not the infrastructure or operating system.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_compute_implement_managed_services.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_compute_implement_managed_services","WellArchitectedQuestionId": "protect-compute"}],"description": "Implement services that manage resources, such as Amazon Relational Database Service (Amazon RDS), AWS Lambda, and Amazon Elastic Container Service (Amazon ECS), to reduce your security maintenance tasks as part of the shared responsibility model. For example, Amazon RDS helps you set up, operate, and scale a relational database, automates administration tasks such as hardware provisioning, database setup, patching, and backups. This means you have more free time to focus on securing your application in other ways described in the AWS Well-Architected Framework. Lambda lets you run code without provisioning or managing servers, so you only need to focus on the connectivity, invocation, and security at the code level–not the infrastructure or operating system.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC06-BP04": {"name": "SEC06-BP04","checks": {"ec2_instance_managed_by_ssm": "FAIL","ec2_instance_profile_attached": "PASS"},"status": "FAIL","attributes": [{"Name": "SEC06-BP04 Automate compute protection","Section": "Infrastructure protection","SubSection": "Protecting compute","Description": "Automate your protective compute mechanisms including vulnerability management, reduction in attack surface, and management of resources. The automation will help you invest time in securing other aspects of your workload, and reduce the risk of human error.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_compute_auto_protection.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_compute_auto_protection","WellArchitectedQuestionId": "protect-compute"}],"description": "Automate your protective compute mechanisms including vulnerability management, reduction in attack surface, and management of resources. The automation will help you invest time in securing other aspects of your workload, and reduce the risk of human error.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"SEC06-BP05": {"name": "SEC06-BP05","checks": {"ec2_instance_managed_by_ssm": "FAIL","ec2_instance_profile_attached": "PASS"},"status": "FAIL","attributes": [{"Name": "SEC06-BP05 Enable people to perform actions at a distance","Section": "Infrastructure protection","SubSection": "Protecting compute","Description": "Removing the ability for interactive access reduces the risk of human error, and the potential for manual configuration or management. For example, use a change management workflow to deploy Amazon Elastic Compute Cloud (Amazon EC2) instances using infrastructure-as-code, then manage Amazon EC2 instances using tools such as AWS Systems Manager instead of allowing direct access or through a bastion host. AWS Systems Manager can automate a variety of maintenance and deployment tasks, using features including automation workflows, documents (playbooks), and the run command. AWS CloudFormation stacks build from pipelines and can automate your infrastructure deployment and management tasks without using the AWS Management Console or APIs directly.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_compute_actions_distance.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_compute_actions_distance","WellArchitectedQuestionId": "protect-compute"}],"description": "Removing the ability for interactive access reduces the risk of human error, and the potential for manual configuration or management. For example, use a change management workflow to deploy Amazon Elastic Compute Cloud (Amazon EC2) instances using infrastructure-as-code, then manage Amazon EC2 instances using tools such as AWS Systems Manager instead of allowing direct access or through a bastion host. AWS Systems Manager can automate a variety of maintenance and deployment tasks, using features including automation workflows, documents (playbooks), and the run command. AWS CloudFormation stacks build from pipelines and can automate your infrastructure deployment and management tasks without using the AWS Management Console or APIs directly.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"SEC06-BP06": {"name": "SEC06-BP06","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Name": "SEC06-BP06 Validate software integrity","Section": "Infrastructure protection","SubSection": "Protecting compute","Description": "Implement mechanisms (for example, code signing) to validate that the software, code and libraries used in the workload are from trusted sources and have not been tampered with. For example, you should verify the code signing certificate of binaries and scripts to confirm the author, and ensure it has not been tampered with since created by the author. AWS Signer can help ensure the trust and integrity of your code by centrally managing the code- signing lifecycle, including signing certification and public and private keys. You can learn how to use advanced patterns and best practices for code signing with AWS Lambda. Additionally, a checksum of software that you download, compared to that of the checksum from the provider, can help ensure it has not been tampered with.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_compute_validate_software_integrity.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_compute_validate_software_integrity","WellArchitectedQuestionId": "protect-compute"}],"description": "Implement mechanisms (for example, code signing) to validate that the software, code and libraries used in the workload are from trusted sources and have not been tampered with. For example, you should verify the code signing certificate of binaries and scripts to confirm the author, and ensure it has not been tampered with since created by the author. AWS Signer can help ensure the trust and integrity of your code by centrally managing the code- signing lifecycle, including signing certification and public and private keys. You can learn how to use advanced patterns and best practices for code signing with AWS Lambda. Additionally, a checksum of software that you download, compared to that of the checksum from the provider, can help ensure it has not been tampered with.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"SEC07-BP01": {"name": "SEC07-BP01","checks": {},"status": "PASS","attributes": [{"Name": "SEC07-BP01 Identify the data within your workload","Section": "Data protection","SubSection": "Data classification","Description": "It’s critical to understand the type and classification of data your workload is processing, the associated business processes, where the data is stored, and who is the data owner. You should also have an understanding of the applicable legal and compliance requirements of your workload, and what data controls need to be enforced. Identifying data is the first step in the data classification journey.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_data_classification_identify_data.html#implementation-guidance.","WellArchitectedPracticeId": "sec_data_classification_identify_data","WellArchitectedQuestionId": "data-classification"}],"description": "It’s critical to understand the type and classification of data your workload is processing, the associated business processes, where the data is stored, and who is the data owner. You should also have an understanding of the applicable legal and compliance requirements of your workload, and what data controls need to be enforced. Identifying data is the first step in the data classification journey.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC07-BP02": {"name": "SEC07-BP02","checks": {},"status": "PASS","attributes": [{"Name": "SEC07-BP02 Define data protection controls","Section": "Data protection","SubSection": "Data classification","Description": "Protect data according to its classification level. For example, secure data classified as public by using relevant recommendations while protecting sensitive data with additional controls.By using resource tags, separate AWS accounts per sensitivity (and potentially also for each caveat, enclave, or community of interest), IAM policies, AWS Organizations SCPs, AWS Key Management Service (AWS KMS), and AWS CloudHSM, you can define and implement your policies for data classification and protection with encryption. For example, if you have a project with S3 buckets that contain highly critical data or Amazon Elastic Compute Cloud (Amazon EC2) instances that process confidential data, they can be tagged with a Project=ABC tag. Only your immediate team knows what the project code means, and it provides a way to use attribute-based access control. You can define levels of access to the AWS KMS encryption keys through key policies and grants to ensure that only appropriate services have access to the sensitive content through a secure mechanism. If you are making authorization decisions based on tags you should make sure that the permissions on the tags are defined appropriately using tag policies in AWS Organizations.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_data_classification_define_protection.html#implementation-guidance.","WellArchitectedPracticeId": "sec_data_classification_define_protection","WellArchitectedQuestionId": "data-classification"}],"description": "Protect data according to its classification level. For example, secure data classified as public by using relevant recommendations while protecting sensitive data with additional controls.By using resource tags, separate AWS accounts per sensitivity (and potentially also for each caveat, enclave, or community of interest), IAM policies, AWS Organizations SCPs, AWS Key Management Service (AWS KMS), and AWS CloudHSM, you can define and implement your policies for data classification and protection with encryption. For example, if you have a project with S3 buckets that contain highly critical data or Amazon Elastic Compute Cloud (Amazon EC2) instances that process confidential data, they can be tagged with a Project=ABC tag. Only your immediate team knows what the project code means, and it provides a way to use attribute-based access control. You can define levels of access to the AWS KMS encryption keys through key policies and grants to ensure that only appropriate services have access to the sensitive content through a secure mechanism. If you are making authorization decisions based on tags you should make sure that the permissions on the tags are defined appropriately using tag policies in AWS Organizations.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC07-BP03": {"name": "SEC07-BP03","checks": {},"status": "PASS","attributes": [{"Name": "SEC07-BP03 Automate identification and classification","Section": "Data protection","SubSection": "Data classification","Description": "Automating the identification and classification of data can help you implement the correct controls. Using automation for this instead of direct access from a person reduces the risk of human error and exposure. You should evaluate using a tool, such as Amazon Macie, that uses machine learning to automatically discover, classify, and protect sensitive data in AWS. Amazon Macie recognizes sensitive data, such as personally identifiable information (PII) or intellectual property, and provides you with dashboards and alerts that give visibility into how this data is being accessed or moved.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_data_classification_auto_classification.html#implementation-guidance.","WellArchitectedPracticeId": "sec_data_classification_auto_classification","WellArchitectedQuestionId": "data-classification"}],"description": "Automating the identification and classification of data can help you implement the correct controls. Using automation for this instead of direct access from a person reduces the risk of human error and exposure. You should evaluate using a tool, such as Amazon Macie, that uses machine learning to automatically discover, classify, and protect sensitive data in AWS. Amazon Macie recognizes sensitive data, such as personally identifiable information (PII) or intellectual property, and provides you with dashboards and alerts that give visibility into how this data is being accessed or moved.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC07-BP04": {"name": "SEC07-BP04","checks": {},"status": "PASS","attributes": [{"Name": "SEC07-BP04 Define data lifecycle management","Section": "Data protection","SubSection": "Data classification","Description": "Your defined lifecycle strategy should be based on sensitivity level as well as legal and organization requirements. Aspects including the duration for which you retain data, data destruction processes, data access management, data transformation, and data sharing should be considered. When choosing a data classification methodology, balance usability versus access. You should also accommodate the multiple levels of access and nuances for implementing a secure, but still usable, approach for each level. Always use a defense in depth approach and reduce human access to data and mechanisms for transforming, deleting, or copying data. For example, require users to strongly authenticate to an application, and give the application, rather than the users, the requisite access permission to perform action at a distance. In addition, ensure that users come from a trusted network path and require access to the decryption keys. Use tools, such as dashboards and automated reporting, to give users information from the data rather than giving them direct access to the data.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_data_classification_lifecycle_management.html#implementation-guidance.","WellArchitectedPracticeId": "sec_data_classification_lifecycle_management","WellArchitectedQuestionId": "data-classification"}],"description": "Your defined lifecycle strategy should be based on sensitivity level as well as legal and organization requirements. Aspects including the duration for which you retain data, data destruction processes, data access management, data transformation, and data sharing should be considered. When choosing a data classification methodology, balance usability versus access. You should also accommodate the multiple levels of access and nuances for implementing a secure, but still usable, approach for each level. Always use a defense in depth approach and reduce human access to data and mechanisms for transforming, deleting, or copying data. For example, require users to strongly authenticate to an application, and give the application, rather than the users, the requisite access permission to perform action at a distance. In addition, ensure that users come from a trusted network path and require access to the decryption keys. Use tools, such as dashboards and automated reporting, to give users information from the data rather than giving them direct access to the data.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC08-BP01": {"name": "SEC08-BP01","checks": {"kms_cmk_are_used": null},"status": "PASS","attributes": [{"Name": "SEC08-BP01 Implement secure key management","Section": "Data protection","SubSection": "Protecting data at rest","Description": "By defining an encryption approach that includes the storage, rotation, and access control of keys, you can help provide protection for your content against unauthorized users and against unnecessary exposure to authorized users. AWS Key Management Service (AWS KMS) helps you manage encryption keys and integrates with many AWS services. This service provides durable, secure, and redundant storage for your AWS KMS keys. You can define your key aliases as well as key-level policies. The policies help you define key administrators as well as key users. Additionally, AWS CloudHSM is a cloud-based hardware security module (HSM) that enables you to easily generate and use your own encryption keys in the AWS Cloud. It helps you meet corporate, contractual, and regulatory compliance requirements for data security by using FIPS 140-2 Level 3 validated HSMs.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_rest_key_mgmt.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_rest_key_mgmt","WellArchitectedQuestionId": "protect-data-rest"}],"description": "By defining an encryption approach that includes the storage, rotation, and access control of keys, you can help provide protection for your content against unauthorized users and against unnecessary exposure to authorized users. AWS Key Management Service (AWS KMS) helps you manage encryption keys and integrates with many AWS services. This service provides durable, secure, and redundant storage for your AWS KMS keys. You can define your key aliases as well as key-level policies. The policies help you define key administrators as well as key users. Additionally, AWS CloudHSM is a cloud-based hardware security module (HSM) that enables you to easily generate and use your own encryption keys in the AWS Cloud. It helps you meet corporate, contractual, and regulatory compliance requirements for data security by using FIPS 140-2 Level 3 validated HSMs.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"SEC08-BP02": {"name": "SEC08-BP02","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","ec2_ebs_snapshots_encrypted": "FAIL","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","cloudtrail_kms_encryption_enabled": "FAIL","workspaces_volume_encryption_enabled": null,"glue_database_connections_ssl_enabled": null,"sqs_queues_server_side_encryption_enabled": "PASS","dynamodb_tables_kms_cmk_encryption_enabled": null,"glue_etl_jobs_amazon_s3_encryption_enabled": "PASS","cloudwatch_log_group_kms_encryption_enabled": "FAIL","glue_etl_jobs_job_bookmark_encryption_enabled": "FAIL","glue_data_catalogs_metadata_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"glue_development_endpoints_s3_encryption_enabled": null,"glue_etl_jobs_cloudwatch_logs_encryption_enabled": "FAIL","eks_cluster_kms_cmk_encryption_in_secrets_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"sagemaker_training_jobs_intercontainer_encryption_enabled": null,"glue_data_catalogs_connection_passwords_encryption_enabled": "FAIL","glue_development_endpoints_job_bookmark_encryption_enabled": null,"sagemaker_training_jobs_volume_and_output_encryption_enabled": null,"glue_development_endpoints_cloudwatch_logs_encryption_enabled": null},"status": "FAIL","attributes": [{"Name": "SEC08-BP02 Enforce encryption at rest","Section": "Data protection","SubSection": "Protecting data at rest","Description": "You should ensure that the only way to store data is by using encryption. AWS Key Management Service (AWS KMS) integrates seamlessly with many AWS services to make it easier for you to encrypt all your data at rest. For example, in Amazon Simple Storage Service (Amazon S3), you can set default encryption on a bucket so that all new objects are automatically encrypted. Additionally, Amazon Elastic Compute Cloud (Amazon EC2) and Amazon S3 support the enforcement of encryption by setting default encryption. You can use AWS Config Rules to check automatically that you are using encryption, for example, for Amazon Elastic Block Store (Amazon EBS) volumes, Amazon Relational Database Service (Amazon RDS) instances, and Amazon S3 buckets.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_rest_encrypt.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_rest_encrypt","WellArchitectedQuestionId": "protect-data-rest"}],"description": "You should ensure that the only way to store data is by using encryption. AWS Key Management Service (AWS KMS) integrates seamlessly with many AWS services to make it easier for you to encrypt all your data at rest. For example, in Amazon Simple Storage Service (Amazon S3), you can set default encryption on a bucket so that all new objects are automatically encrypted. Additionally, Amazon Elastic Compute Cloud (Amazon EC2) and Amazon S3 support the enforcement of encryption by setting default encryption. You can use AWS Config Rules to check automatically that you are using encryption, for example, for Amazon Elastic Block Store (Amazon EBS) volumes, Amazon Relational Database Service (Amazon RDS) instances, and Amazon S3 buckets.","checks_status": {"fail": 9,"pass": 4,"total": 25,"manual": 0}},"SEC08-BP03": {"name": "SEC08-BP03","checks": {"s3_bucket_default_encryption": "PASS","sagemaker_notebook_instance_encryption_enabled": null},"status": "PASS","attributes": [{"Name": "SEC08-BP03 Automate data at rest protection","Section": "Data protection","SubSection": "Protecting data at rest","Description": "Use automated tools to validate and enforce data at rest controls continuously, for example, verify that there are only encrypted storage resources. You can automate validation that all EBS volumes are encrypted using AWS Config Rules. AWS Security Hub can also verify several different controls through automated checks against security standards. Additionally, your AWS Config Rules can automatically remediate noncompliant resources.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_rest_automate_protection.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_rest_automate_protection","WellArchitectedQuestionId": "protect-data-rest"}],"description": "Use automated tools to validate and enforce data at rest controls continuously, for example, verify that there are only encrypted storage resources. You can automate validation that all EBS volumes are encrypted using AWS Config Rules. AWS Security Hub can also verify several different controls through automated checks against security standards. Additionally, your AWS Config Rules can automatically remediate noncompliant resources.","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"SEC08-BP04": {"name": "SEC08-BP04","checks": {"s3_bucket_object_versioning": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","organizations_account_part_of_organizations": null},"status": "FAIL","attributes": [{"Name": "SEC08-BP04 Enforce access control","Section": "Data protection","SubSection": "Protecting data at rest","Description": "To help protect your data at rest, enforce access control using mechanisms, such as isolation and versioning, and apply the principle of least privilege. Prevent the granting of public access to your data.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_rest_access_control.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_rest_access_control","WellArchitectedQuestionId": "protect-data-rest"}],"description": "To help protect your data at rest, enforce access control using mechanisms, such as isolation and versioning, and apply the principle of least privilege. Prevent the granting of public access to your data.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"SEC08-BP05": {"name": "SEC08-BP05","checks": {},"status": "PASS","attributes": [{"Name": "SEC08-BP05 Use mechanisms to keep people away from data","Section": "Data protection","SubSection": "Protecting data at rest","Description": "Keep all users away from directly accessing sensitive data and systems under normal operational circumstances. For example, use a change management workflow to manage Amazon Elastic Compute Cloud (Amazon EC2) instances using tools instead of allowing direct access or a bastion host. This can be achieved using AWS Systems Manager Automation, which uses automation documents that contain steps you use to perform tasks. These documents can be stored in source control, be peer reviewed before running, and tested thoroughly to minimize risk compared to shell access. Business users could have a dashboard instead of direct access to a data store to run queries. Where CI/CD pipelines are not used, determine which controls and processes are required to adequately provide a normally disabled break-glass access mechanism.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_rest_use_people_away.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_rest_use_people_away","WellArchitectedQuestionId": "protect-data-rest"}],"description": "Keep all users away from directly accessing sensitive data and systems under normal operational circumstances. For example, use a change management workflow to manage Amazon Elastic Compute Cloud (Amazon EC2) instances using tools instead of allowing direct access or a bastion host. This can be achieved using AWS Systems Manager Automation, which uses automation documents that contain steps you use to perform tasks. These documents can be stored in source control, be peer reviewed before running, and tested thoroughly to minimize risk compared to shell access. Business users could have a dashboard instead of direct access to a data store to run queries. Where CI/CD pipelines are not used, determine which controls and processes are required to adequately provide a normally disabled break-glass access mechanism.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC09-BP01": {"name": "SEC09-BP01","checks": {"acm_certificates_expiration_check": "PASS","directoryservice_ldap_certificate_expiration": null},"status": "PASS","attributes": [{"Name": "SEC09-BP01 Implement secure key and certificate management","Section": "Data protection","SubSection": "Protecting data in transit","Description": "Store encryption keys and certificates securely and rotate them at appropriate time intervals with strict access control. The best way to accomplish this is to use a managed service, such as AWS Certificate Manager (ACM). It lets you easily provision, manage, and deploy public and private Transport Layer Security (TLS) certificates for use with AWS services and your internal connected resources. TLS certificates are used to secure network communications and establish the identity of websites over the internet as well as resources on private networks. ACM integrates with AWS resources, such as Elastic Load Balancers (ELBs), AWS distributions, and APIs on API Gateway, also handling automatic certificate renewals. If you use ACM to deploy a private root CA, both certificates and private keys can be provided by it for use in Amazon Elastic Compute Cloud (Amazon EC2) instances, containers, and so on.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_transit_key_cert_mgmt.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_transit_key_cert_mgmt","WellArchitectedQuestionId": "protect-data-transit"}],"description": "Store encryption keys and certificates securely and rotate them at appropriate time intervals with strict access control. The best way to accomplish this is to use a managed service, such as AWS Certificate Manager (ACM). It lets you easily provision, manage, and deploy public and private Transport Layer Security (TLS) certificates for use with AWS services and your internal connected resources. TLS certificates are used to secure network communications and establish the identity of websites over the internet as well as resources on private networks. ACM integrates with AWS resources, such as Elastic Load Balancers (ELBs), AWS distributions, and APIs on API Gateway, also handling automatic certificate renewals. If you use ACM to deploy a private root CA, both certificates and private keys can be provided by it for use in Amazon Elastic Compute Cloud (Amazon EC2) instances, containers, and so on.","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"SEC09-BP02": {"name": "SEC09-BP02","checks": {"elb_ssl_listeners": "FAIL","elbv2_ssl_listeners": "FAIL","elb_insecure_ssl_ciphers": "PASS","elbv2_insecure_ssl_ciphers": "PASS","s3_bucket_secure_transport_policy": "FAIL","cloudfront_distributions_https_enabled": null,"apigateway_restapi_client_certificate_enabled": "FAIL","cloudfront_distributions_field_level_encryption_enabled": null,"cloudfront_distributions_using_deprecated_ssl_protocols": null,"opensearch_service_domains_https_communications_enforced": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Name": "SEC09-BP02 Enforce encryption in transit","Section": "Data protection","SubSection": "Protecting data in transit","Description": "Enforce your defined encryption requirements based on appropriate standards and recommendations to help you meet your organizational, legal, and compliance requirements. AWS services provide HTTPS endpoints using TLS for communication, thus providing encryption in transit when communicating with the AWS APIs. Insecure protocols, such as HTTP, can be audited and blocked in a VPC through the use of security groups. HTTP requests can also be automatically redirected to HTTPS in Amazon CloudFront or on an Application Load Balancer. You have full control over your computing resources to implement encryption in transit across your services. Additionally, you can use VPN connectivity into your VPC from an external network to facilitate encryption of traffic. Third-party solutions are available in the AWS Marketplace, if you have special requirements.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_transit_encrypt.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_transit_encrypt","WellArchitectedQuestionId": "protect-data-transit"}],"description": "Enforce your defined encryption requirements based on appropriate standards and recommendations to help you meet your organizational, legal, and compliance requirements. AWS services provide HTTPS endpoints using TLS for communication, thus providing encryption in transit when communicating with the AWS APIs. Insecure protocols, such as HTTP, can be audited and blocked in a VPC through the use of security groups. HTTP requests can also be automatically redirected to HTTPS in Amazon CloudFront or on an Application Load Balancer. You have full control over your computing resources to implement encryption in transit across your services. Additionally, you can use VPN connectivity into your VPC from an external network to facilitate encryption of traffic. Third-party solutions are available in the AWS Marketplace, if you have special requirements.","checks_status": {"fail": 4,"pass": 2,"total": 11,"manual": 0}},"SEC09-BP03": {"name": "SEC09-BP03","checks": {},"status": "PASS","attributes": [{"Name": "SEC09-BP03 Automate detection of unintended data access","Section": "Data protection","SubSection": "Protecting data in transit","Description": "Use tools such as Amazon GuardDuty to automatically detect suspicious activity or attempts to move data outside of defined boundaries. For example, GuardDuty can detect Amazon Simple Storage Service (Amazon S3) read activity that is unusual with the Exfiltration:S3/AnomalousBehavior finding. In addition to GuardDuty, Amazon VPC Flow Logs, which capture network traffic information, can be used with Amazon EventBridge to trigger detection of abnormal connections–both successful and denied. Amazon S3 Access Analyzer can help assess what data is accessible to who in your Amazon S3 buckets.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_transit_auto_unintended_access.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_transit_auto_unintended_access","WellArchitectedQuestionId": "protect-data-transit"}],"description": "Use tools such as Amazon GuardDuty to automatically detect suspicious activity or attempts to move data outside of defined boundaries. For example, GuardDuty can detect Amazon Simple Storage Service (Amazon S3) read activity that is unusual with the Exfiltration:S3/AnomalousBehavior finding. In addition to GuardDuty, Amazon VPC Flow Logs, which capture network traffic information, can be used with Amazon EventBridge to trigger detection of abnormal connections–both successful and denied. Amazon S3 Access Analyzer can help assess what data is accessible to who in your Amazon S3 buckets.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC09-BP04": {"name": "SEC09-BP04","checks": {"vpc_flow_logs_enabled": "FAIL"},"status": "FAIL","attributes": [{"Name": "SEC09-BP04 Authenticate network communications","Section": "Data protection","SubSection": "Protecting data in transit","Description": "Verify the identity of communications by using protocols that support authentication, such as Transport Layer Security (TLS) or IPsec. Using network protocols that support authentication, allows for trust to be established between the parties. This adds to the encryption used in the protocol to reduce the risk of communications being altered or intercepted. Common protocols that implement authentication include Transport Layer Security (TLS), which is used in many AWS services, and IPsec, which is used in AWS Virtual Private Network (AWS VPN).","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_transit_authentication.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_transit_authentication","WellArchitectedQuestionId": "protect-data-transit"}],"description": "Verify the identity of communications by using protocols that support authentication, such as Transport Layer Security (TLS) or IPsec. Using network protocols that support authentication, allows for trust to be established between the parties. This adds to the encryption used in the protocol to reduce the risk of communications being altered or intercepted. Common protocols that implement authentication include Transport Layer Security (TLS), which is used in many AWS services, and IPsec, which is used in AWS Virtual Private Network (AWS VPN).","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"SEC10-BP01": {"name": "SEC10-BP01","checks": {"iam_support_role_created": null,"account_maintain_current_contact_details": null,"account_security_contact_information_is_registered": null,"account_security_questions_are_registered_in_the_aws_account": null},"status": "PASS","attributes": [{"Name": "SEC10-BP01 Identify key personnel and external resources","Section": "Incident response","SubSection": "Prepare","Description": "Identify internal and external personnel, resources, and legal obligations that would help your organization respond to an incident.When you define your approach to incident response in the cloud, in unison with other teams (such as your legal counsel, leadership, business stakeholders, AWS Support Services, and others), you must identify key personnel, stakeholders, and relevant contacts. To reduce dependency and decrease response time, make sure that your team, specialist security teams, and responders are educated about the services that you use and have opportunities to practice hands-on.We encourage you to identify external AWS security partners that can provide you with outside expertise and a different perspective to augment your response capabilities. Your trusted security partners can help you identify potential risks or threats that you might not be familiar with.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_incident_response_identify_personnel.html#implementation-guidance.","WellArchitectedPracticeId": "sec_incident_response_identify_personnel","WellArchitectedQuestionId": "incident-response"}],"description": "Identify internal and external personnel, resources, and legal obligations that would help your organization respond to an incident.When you define your approach to incident response in the cloud, in unison with other teams (such as your legal counsel, leadership, business stakeholders, AWS Support Services, and others), you must identify key personnel, stakeholders, and relevant contacts. To reduce dependency and decrease response time, make sure that your team, specialist security teams, and responders are educated about the services that you use and have opportunities to practice hands-on.We encourage you to identify external AWS security partners that can provide you with outside expertise and a different perspective to augment your response capabilities. Your trusted security partners can help you identify potential risks or threats that you might not be familiar with.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"SEC10-BP02": {"name": "SEC10-BP02","checks": {},"status": "PASS","attributes": [{"Name": "SEC10-BP02 Develop incident management plans","Section": "Incident response","SubSection": "Prepare","Description": "Create plans to help you respond to, communicate during, and recover from an incident. For example, you can start an incident response plan with the most likely scenarios for your workload and organization. Include how you would communicate and escalate both internally and externally.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_incident_response_develop_management_plans.html#implementation-guidance.","WellArchitectedPracticeId": "sec_incident_response_develop_management_plans","WellArchitectedQuestionId": "incident-response"}],"description": "Create plans to help you respond to, communicate during, and recover from an incident. For example, you can start an incident response plan with the most likely scenarios for your workload and organization. Include how you would communicate and escalate both internally and externally.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC10-BP03": {"name": "SEC10-BP03","checks": {},"status": "PASS","attributes": [{"Name": "SEC10-BP03 Prepare forensic capabilities","Section": "Incident response","SubSection": "Prepare","Description": "It's important for your incident responders to understand when and how the forensic investigation fits into your response plan. Your organization should define what evidence is collected and what tools are used in the process. Identify and prepare forensic investigation capabilities that are suitable, including external specialists, tools, and automation. A key decision that you should make upfront is if you will collect data from a live system. Some data, such as the contents of volatile memory or active network connections, will be lost if the system is powered off or rebooted.Your response team can combine tools, such as AWS Systems Manager, Amazon EventBridge, and AWS Lambda, to automatically run forensic tools within an operating system and VPC traffic mirroring to obtain a network packet capture, to gather non-persistent evidence. Conduct other activities, such as log analysis or analyzing disk images, in a dedicated security account with customized forensic workstations and tools accessible to your responders.Routinely ship relevant logs to a data store that provides high durability and integrity. Responders should have access to those logs. AWS offers several tools that can make log investigation easier, such as Amazon Athena, Amazon OpenSearch Service (OpenSearch Service), and Amazon CloudWatch Logs Insights. Additionally, preserve evidence securely using Amazon Simple Storage Service (Amazon S3) Object Lock. This service follows the WORM (write-once- read-many) model and prevents objects from being deleted or overwritten for a defined period. As forensic investigation techniques require specialist training, you might need to engage external specialists.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_incident_response_prepare_forensic.html#implementation-guidance.","WellArchitectedPracticeId": "sec_incident_response_prepare_forensic","WellArchitectedQuestionId": "incident-response"}],"description": "It's important for your incident responders to understand when and how the forensic investigation fits into your response plan. Your organization should define what evidence is collected and what tools are used in the process. Identify and prepare forensic investigation capabilities that are suitable, including external specialists, tools, and automation. A key decision that you should make upfront is if you will collect data from a live system. Some data, such as the contents of volatile memory or active network connections, will be lost if the system is powered off or rebooted.Your response team can combine tools, such as AWS Systems Manager, Amazon EventBridge, and AWS Lambda, to automatically run forensic tools within an operating system and VPC traffic mirroring to obtain a network packet capture, to gather non-persistent evidence. Conduct other activities, such as log analysis or analyzing disk images, in a dedicated security account with customized forensic workstations and tools accessible to your responders.Routinely ship relevant logs to a data store that provides high durability and integrity. Responders should have access to those logs. AWS offers several tools that can make log investigation easier, such as Amazon Athena, Amazon OpenSearch Service (OpenSearch Service), and Amazon CloudWatch Logs Insights. Additionally, preserve evidence securely using Amazon Simple Storage Service (Amazon S3) Object Lock. This service follows the WORM (write-once- read-many) model and prevents objects from being deleted or overwritten for a defined period. As forensic investigation techniques require specialist training, you might need to engage external specialists.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC10-BP04": {"name": "SEC10-BP04","checks": {},"status": "PASS","attributes": [{"Name": "SEC10-BP04 Automate containment capability","Section": "Incident response","SubSection": "Iterate","Description": "Automate containment and recovery of an incident to reduce response times and organizational impact.Once you create and practice the processes and tools from your playbooks, you can deconstruct the logic into a code-based solution, which can be used as a tool by many responders to automate the response and remove variance or guess-work by your responders. This can speed up the lifecycle of a response. The next goal is to enable this code to be fully automated by being invoked by the alerts or events themselves, rather than by a human responder, to create an event-driven response. These processes should also automatically add relevant data to your security systems. For example, an incident involving traffic from an unwanted IP address can automatically populate an AWS WAF block list or Network Firewall rule group to prevent further activity.With an event-driven response system, a detective mechanism triggers a responsive mechanism to automatically remediate the event. You can use event-driven response capabilities to reduce the time-to-value between detective mechanisms and responsive mechanisms. To create this event-driven architecture, you can use AWS Lambda, which is a serverless compute service that runs your code in response to events and automatically manages the underlying compute resources for you. For example, assume that you have an AWS account with the AWS CloudTrail service enabled. If CloudTrail is ever disabled (through the cloudtrail:StopLogging API call), you can use Amazon EventBridge to monitor for the specific cloudtrail:StopLogging event, and invoke a Lambda function to call cloudtrail:StartLogging to restart logging.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_incident_response_auto_contain.html#implementation-guidance.","WellArchitectedPracticeId": "sec_incident_response_auto_contain","WellArchitectedQuestionId": "incident-response"}],"description": "Automate containment and recovery of an incident to reduce response times and organizational impact.Once you create and practice the processes and tools from your playbooks, you can deconstruct the logic into a code-based solution, which can be used as a tool by many responders to automate the response and remove variance or guess-work by your responders. This can speed up the lifecycle of a response. The next goal is to enable this code to be fully automated by being invoked by the alerts or events themselves, rather than by a human responder, to create an event-driven response. These processes should also automatically add relevant data to your security systems. For example, an incident involving traffic from an unwanted IP address can automatically populate an AWS WAF block list or Network Firewall rule group to prevent further activity.With an event-driven response system, a detective mechanism triggers a responsive mechanism to automatically remediate the event. You can use event-driven response capabilities to reduce the time-to-value between detective mechanisms and responsive mechanisms. To create this event-driven architecture, you can use AWS Lambda, which is a serverless compute service that runs your code in response to events and automatically manages the underlying compute resources for you. For example, assume that you have an AWS account with the AWS CloudTrail service enabled. If CloudTrail is ever disabled (through the cloudtrail:StopLogging API call), you can use Amazon EventBridge to monitor for the specific cloudtrail:StopLogging event, and invoke a Lambda function to call cloudtrail:StartLogging to restart logging.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC10-BP05": {"name": "SEC10-BP05","checks": {},"status": "PASS","attributes": [{"Name": "SEC10-BP05 Pre-provision access","Section": "Incident response","SubSection": "Prepare","Description": "Verify that incident responders have the correct access pre-provisioned in AWS to reduce the time needed for investigation through to recovery.Common anti-patterns:Using the root account for incident response.Altering existing accounts.Manipulating IAM permissions directly when providing just-in-time privilege elevation.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_incident_response_pre_provision_access.html#implementation-guidance.","WellArchitectedPracticeId": "sec_incident_response_pre_provision_access","WellArchitectedQuestionId": "incident-response"}],"description": "Verify that incident responders have the correct access pre-provisioned in AWS to reduce the time needed for investigation through to recovery.Common anti-patterns:Using the root account for incident response.Altering existing accounts.Manipulating IAM permissions directly when providing just-in-time privilege elevation.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC10-BP06": {"name": "SEC10-BP06","checks": {},"status": "PASS","attributes": [{"Name": "SEC10-BP06 Pre-deploy tools","Section": "Incident response","SubSection": "Prepare","Description": "Ensure that security personnel have the right tools pre-deployed into AWS to reduce the time for investigation through to recovery.To automate security engineering and operations functions, you can use a comprehensive set of APIs and tools from AWS. You can fully automate identity management, network security, data protection, and monitoring capabilities and deliver them using popular software development methods that you already have in place. When you build security automation, your system can monitor, review, and initiate a response, rather than having people monitor your security position and manually react to events. An effective way to automatically provide searchable and relevant log data across AWS services to your incident responders is to enable Amazon Detective.If your incident response teams continue to respond to alerts in the same way, they risk alert fatigue. Over time, the team can become desensitized to alerts and can either make mistakes handling ordinary situations or miss unusual alerts. Automation helps avoid alert fatigue by using functions that process the repetitive and ordinary alerts, leaving humans to handle the sensitive and unique incidents. Integrating anomaly detection systems, such as Amazon GuardDuty, AWS CloudTrail Insights, and Amazon CloudWatch Anomaly Detection, can reduce the burden of common threshold-based alerts.You can improve manual processes by programmatically automating steps in the process. After you define the remediation pattern to an event, you can decompose that pattern into actionable logic, and write the code to perform that logic. Responders can then execute that code to remediate the issue. Over time, you can automate more and more steps, and ultimately automatically handle whole classes of common incidents.For tools that execute within the operating system of your Amazon Elastic Compute Cloud (Amazon EC2) instance, you should evaluate using the AWS Systems Manager Run Command, which enables you to remotely and securely administrate instances using an agent that you install on your Amazon EC2 instance operating system. It requires the Systems Manager Agent (SSM Agent), which is installed by default on many Amazon Machine Images (AMIs). Be aware, though, that once an instance has been compromised, no responses from tools or agents running on it should be considered trustworthy.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_incident_response_pre_deploy_tools.html#implementation-guidance.","WellArchitectedPracticeId": "sec_incident_response_pre_deploy_tools","WellArchitectedQuestionId": "incident-response"}],"description": "Ensure that security personnel have the right tools pre-deployed into AWS to reduce the time for investigation through to recovery.To automate security engineering and operations functions, you can use a comprehensive set of APIs and tools from AWS. You can fully automate identity management, network security, data protection, and monitoring capabilities and deliver them using popular software development methods that you already have in place. When you build security automation, your system can monitor, review, and initiate a response, rather than having people monitor your security position and manually react to events. An effective way to automatically provide searchable and relevant log data across AWS services to your incident responders is to enable Amazon Detective.If your incident response teams continue to respond to alerts in the same way, they risk alert fatigue. Over time, the team can become desensitized to alerts and can either make mistakes handling ordinary situations or miss unusual alerts. Automation helps avoid alert fatigue by using functions that process the repetitive and ordinary alerts, leaving humans to handle the sensitive and unique incidents. Integrating anomaly detection systems, such as Amazon GuardDuty, AWS CloudTrail Insights, and Amazon CloudWatch Anomaly Detection, can reduce the burden of common threshold-based alerts.You can improve manual processes by programmatically automating steps in the process. After you define the remediation pattern to an event, you can decompose that pattern into actionable logic, and write the code to perform that logic. Responders can then execute that code to remediate the issue. Over time, you can automate more and more steps, and ultimately automatically handle whole classes of common incidents.For tools that execute within the operating system of your Amazon Elastic Compute Cloud (Amazon EC2) instance, you should evaluate using the AWS Systems Manager Run Command, which enables you to remotely and securely administrate instances using an agent that you install on your Amazon EC2 instance operating system. It requires the Systems Manager Agent (SSM Agent), which is installed by default on many Amazon Machine Images (AMIs). Be aware, though, that once an instance has been compromised, no responses from tools or agents running on it should be considered trustworthy.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC10-BP07": {"name": "SEC10-BP07","checks": {},"status": "PASS","attributes": [{"Name": "SEC10-BP07 Run game days","Section": "Incident response","SubSection": "Simulate","Description": "Game days, also known as simulations or exercises, are internal events that provide a structured opportunity to practice your incident management plans and procedures during a realistic scenario. These events should exercise responders using the same tools and techniques that would be used in a real-world scenario - even mimicking real-world environments. Game days are fundamentally about being prepared and iteratively improving your response capabilities. Some of the reasons you might find value in performing game day activities include:Validating readinessDeveloping confidence – learning from simulations and training staffFollowing compliance or contractual obligationsGenerating artifacts for accreditationBeing agile – incremental improvementBecoming faster and improving toolsRefining communication and escalationDeveloping comfort with the rare and the unexpectedFor these reasons, the value derived from participating in a simulation activity increases an organization's effectiveness during stressful events. Developing a simulation activity that is both realistic and beneficial can be a difficult exercise. Although testing your procedures or automation that handles well-understood events has certain advantages, it is just as valuable to participate in creative Security Incident Response Simulations (SIRS) activities to test yourself against the unexpected and continuously improve.Create custom simulations tailored to your environment, team, and tools. Find an issue and design your simulation around it. This could be something like a leaked credential, a server communicating with unwanted systems, or a misconfiguration that results in unauthorized exposure. Identify engineers who are familiar with your organization to create the scenario and another group to participate. The scenario should be realistic and challenging enough to be valuable. It should include the opportunity to get hands on with logging, notifications, escalations, and executing runbooks or automation. During the simulation, your responders should exercise their technical and organizational skills, and leaders should be involved to build their incident management skills. At the end of the simulation, celebrate the efforts of the team and look for ways to iterate, repeat, and expand into further simulations.AWS has created Incident Response Runbook templates that you can use not only to prepare your response efforts, but also as a basis for a simulation. When planning, a simulation can be broken into five phases.Evidence gathering: In this phase, a team will get alerts through various means, such as an internal ticketing system, alerts from monitoring tooling, anonymous tips, or even public news. Teams then start to review infrastructure and application logs to determine the source of the compromise. This step should also involve internal escalations and incident leadership. Once identified, teams move on to containing the incidentContain the incident: Teams will have determined there has been an incident and established the source of the compromise. Teams now should take action to contain it, for example, by disabling compromised credentials, isolating a compute resource, or revoking a role's permission.Eradicate the incident: Now that they've contained the incident, teams will work towards mitigating any vulnerabilities in applications or infrastructure configurations that were susceptible to the compromise. This could include rotating all credentials used for a workload, modifying Access Control Lists (ACLs) or changing network configurations.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_incident_response_run_game_days.html#implementation-guidance.","WellArchitectedPracticeId": "sec_incident_response_run_game_days","WellArchitectedQuestionId": "incident-response"}],"description": "Game days, also known as simulations or exercises, are internal events that provide a structured opportunity to practice your incident management plans and procedures during a realistic scenario. These events should exercise responders using the same tools and techniques that would be used in a real-world scenario - even mimicking real-world environments. Game days are fundamentally about being prepared and iteratively improving your response capabilities. Some of the reasons you might find value in performing game day activities include:Validating readinessDeveloping confidence – learning from simulations and training staffFollowing compliance or contractual obligationsGenerating artifacts for accreditationBeing agile – incremental improvementBecoming faster and improving toolsRefining communication and escalationDeveloping comfort with the rare and the unexpectedFor these reasons, the value derived from participating in a simulation activity increases an organization's effectiveness during stressful events. Developing a simulation activity that is both realistic and beneficial can be a difficult exercise. Although testing your procedures or automation that handles well-understood events has certain advantages, it is just as valuable to participate in creative Security Incident Response Simulations (SIRS) activities to test yourself against the unexpected and continuously improve.Create custom simulations tailored to your environment, team, and tools. Find an issue and design your simulation around it. This could be something like a leaked credential, a server communicating with unwanted systems, or a misconfiguration that results in unauthorized exposure. Identify engineers who are familiar with your organization to create the scenario and another group to participate. The scenario should be realistic and challenging enough to be valuable. It should include the opportunity to get hands on with logging, notifications, escalations, and executing runbooks or automation. During the simulation, your responders should exercise their technical and organizational skills, and leaders should be involved to build their incident management skills. At the end of the simulation, celebrate the efforts of the team and look for ways to iterate, repeat, and expand into further simulations.AWS has created Incident Response Runbook templates that you can use not only to prepare your response efforts, but also as a basis for a simulation. When planning, a simulation can be broken into five phases.Evidence gathering: In this phase, a team will get alerts through various means, such as an internal ticketing system, alerts from monitoring tooling, anonymous tips, or even public news. Teams then start to review infrastructure and application logs to determine the source of the compromise. This step should also involve internal escalations and incident leadership. Once identified, teams move on to containing the incidentContain the incident: Teams will have determined there has been an incident and established the source of the compromise. Teams now should take action to contain it, for example, by disabling compromised credentials, isolating a compute resource, or revoking a role's permission.Eradicate the incident: Now that they've contained the incident, teams will work towards mitigating any vulnerabilities in applications or infrastructure configurations that were susceptible to the compromise. This could include rotating all credentials used for a workload, modifying Access Control Lists (ACLs) or changing network configurations.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC11-BP02": {"name": "SEC11-BP02","checks": {"ecr_repositories_scan_images_on_push_enabled": "FAIL","ecr_repositories_scan_vulnerabilities_in_latest_image": null},"status": "FAIL","attributes": [{"Name": "SEC11-BP02 Automate testing throughout the development and release lifecycle","Section": "Application Security","SubSection": null,"Description": "Automate the testing for security properties throughout the development and release lifecycle. Automation makes it easier to consistently and repeatably identify potential issues in software prior to release, which reduces the risk of security issues in the software being provided. The goal of automated testing is to provide a programmatic way of detecting potential issues early and often throughout the development lifecycle. When you automate regression testing, you can rerun functional and non-functional tests to verify that previously tested software still performs as expected after a change. When you define security unit tests to check for common misconfigurations, such as broken or missing authentication, you can identify and fix these issues early in the development process. Test automation uses purpose-built test cases for application validation, based on the application’s requirements and desired functionality. The result of the automated testing is based on comparing the generated test output to its respective expected output, which expedites the overall testing lifecycle. Testing methodologies such as regression testing and unit test suites are best suited for automation. Automating the testing of security properties allows builders to receive automated feedback without having to wait for a security review. Automated tests in the form of static or dynamic code analysis can increase code quality and help detect potential software issues early in the development lifecycle.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_appsec_automate_testing_throughout_lifecycle.html#implementation-guidance.","WellArchitectedPracticeId": "sec_appsec_automate_testing_throughout_lifecycle","WellArchitectedQuestionId": "application-security"}],"description": "Automate the testing for security properties throughout the development and release lifecycle. Automation makes it easier to consistently and repeatably identify potential issues in software prior to release, which reduces the risk of security issues in the software being provided. The goal of automated testing is to provide a programmatic way of detecting potential issues early and often throughout the development lifecycle. When you automate regression testing, you can rerun functional and non-functional tests to verify that previously tested software still performs as expected after a change. When you define security unit tests to check for common misconfigurations, such as broken or missing authentication, you can identify and fix these issues early in the development process. Test automation uses purpose-built test cases for application validation, based on the application’s requirements and desired functionality. The result of the automated testing is based on comparing the generated test output to its respective expected output, which expedites the overall testing lifecycle. Testing methodologies such as regression testing and unit test suites are best suited for automation. Automating the testing of security properties allows builders to receive automated feedback without having to wait for a security review. Automated tests in the form of static or dynamic code analysis can increase code quality and help detect potential software issues early in the development lifecycle.","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}}},"requirements_passed": 17,"requirements_failed": 23,"requirements_manual": 17,"total_requirements": 57,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "e079e750-59b8-4d29-9e57-1a10a0e63be4","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "aws_foundational_security_best_practices_aws","framework": "AWS-Foundational-Security-Best-Practices","version": "","description": "The AWS Foundational Security Best Practices standard is a set of controls that detect when your deployed accounts and resources deviate from security best practices.","region": "eu-west-1","requirements": {"s3": {"name": "Benchmark: S3","checks": {"s3_bucket_public_access": null,"s3_bucket_acl_prohibited": "FAIL","s3_bucket_object_versioning": "FAIL","s3_bucket_default_encryption": "PASS","s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS","s3_account_level_public_access_blocks": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "s3","Section": "S3","Service": "s3","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS S3 resources and options.","checks_status": {"fail": 4,"pass": 2,"total": 9,"manual": 0}},"acm": {"name": "ACM","checks": {"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "acm","Section": "Acm","Service": "acm","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring ACM resources.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"dms": {"name": "Benchmark: DMS","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "dms","Section": "DMS","Service": "dms","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS DMS resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ec2": {"name": "Benchmark: EC2","checks": {"vpc_flow_logs_enabled": "FAIL","ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","ec2_securitygroup_not_used": "FAIL","ec2_instance_imdsv2_enabled": "PASS","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ec2","Section": "EC2","Service": "ec2","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring EC2 resources and options.","checks_status": {"fail": 6,"pass": 4,"total": 10,"manual": 0}},"ecr": {"name": "Benchmark: Elastic Container Registry","checks": {"ecr_repositories_lifecycle_policy_enabled": "FAIL","ecr_repositories_scan_images_on_push_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ecr","Section": "ECR","Service": "ecr","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS ECR resources and options.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"ecs": {"name": "Benchmark: Elastic Container Service","checks": {"ecs_task_definitions_no_environment_secrets": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ecs","Section": "ECS","Service": "ecs","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring ECS resources and options.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"efs": {"name": "Benchmark: EFS","checks": {"efs_have_backup_enabled": "FAIL","efs_encryption_at_rest_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "efs","Section": "EFS","Service": "efs","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS EFS resources and options.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"eks": {"name": "Benchmark: EKS","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "eks","Section": "EKS","Service": "eks","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS EKS resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"elb": {"name": "Benchmark: ELB","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","elbv2_deletion_protection": "FAIL","elbv2_desync_mitigation_mode": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "elb","Section": "ELB","Service": "elb","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Elastic Load Balancer resources and options.","checks_status": {"fail": 4,"pass": 0,"total": 4,"manual": 0}},"emr": {"name": "Benchmark: EMR","checks": {"emr_cluster_master_nodes_no_public_ip": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "emr","Section": "EMR","Service": "emr","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring EMR resources.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"iam": {"name": "Benchmark: IAM","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "iam","Section": "IAM","Service": "iam","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS IAM resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 10,"manual": 0}},"kms": {"name": "Benchmark: KMS","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "kms","Section": "KMS","Service": "kms","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS KMS resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"rds": {"name": "Benchmark: RDS","checks": {"rds_instance_multi_az": "FAIL","rds_snapshots_public_access": "PASS","rds_instance_no_public_access": "PASS","rds_instance_storage_encrypted": "FAIL","rds_instance_deletion_protection": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "rds","Section": "RDS","Service": "rds","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS RDS resources and options.","checks_status": {"fail": 5,"pass": 3,"total": 10,"manual": 0}},"sns": {"name": "Benchmark: SNS","checks": {"sns_topics_kms_encryption_at_rest_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sns","Section": "SNS","Service": "sns","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS SNS resources and options.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sqs": {"name": "Benchmark: SQS","checks": {"sqs_queues_server_side_encryption_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sqs","Section": "SQS","Service": "sqs","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS SQS resources and options.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ssm": {"name": "Benchmark: SSM","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ssm","Section": "SSM","Service": "ssm","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Systems Manager resources and options.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"waf": {"name": "Benchmark: WAF","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "waf","Section": "WAF","Service": "waf","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS WAF resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"elbv2": {"name": "Benchmark: ELBv2","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "elbv2","Section": "ELBv2","Service": "elbv2","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Elastic Load Balancer resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"config": {"name": "Benchmark: Config","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "config","Section": "Config","Service": "config","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Config.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"lambda": {"name": "Benchmark: Lambda","checks": {"awslambda_function_url_public": null,"awslambda_function_using_supported_runtimes": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "lambda","Section": "Lambda","Service": "lambda","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Lambda resources and options.","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"account": {"name": "Account","checks": {"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "account","Section": "Account","Service": "account","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Account.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"kinesis": {"name": "Benchmark: Kinesis","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "kinesis","Section": "Kinesis","Service": "kinesis","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Kinesis resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"dynamodb": {"name": "Benchmark: DynamoDB","checks": {"dynamodb_tables_pitr_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "dynamodb","Section": "DynamoDB","Service": "dynamodb","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Dynamo DB resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"redshift": {"name": "Benchmark: Redshift","checks": {"redshift_cluster_public_access": null,"redshift_cluster_automated_snapshot": null,"redshift_cluster_automatic_upgrades": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "redshift","Section": "Redshift","Service": "redshift","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Redshift resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"codebuild": {"name": "Benchmark: CodeBuild","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "codebuild","Section": "CodeBuild","Service": "codebuild","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring CodeBuild resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"guardduty": {"name": "Benchmark: GuardDuty","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "guardduty","Section": "GuardDuty","Service": "guardduty","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS GuardDuty resources and options.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sagemaker": {"name": "Benchmark: SageMaker","checks": {"sagemaker_notebook_instance_root_access_disabled": null,"sagemaker_notebook_instance_vpc_settings_configured": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sagemaker","Section": "SageMaker","Service": "sagemaker","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Sagemaker resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"cloudfront": {"name": "Benchmark: CloudFront","checks": {"cloudfront_distributions_using_waf": null,"cloudfront_distributions_https_enabled": null,"cloudfront_distributions_logging_enabled": null,"cloudfront_distributions_field_level_encryption_enabled": null,"cloudfront_distributions_using_deprecated_ssl_protocols": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "cloudfront","Section": "CloudFront","Service": "cloudfront","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring CloudFront resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"cloudtrail": {"name": "Benchmark: CloudTrail","checks": {"cloudtrail_multi_region_enabled": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cloudtrail","Section": "CloudTrail","Service": "cloudtrail","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring CloudTrail resources and options.","checks_status": {"fail": 3,"pass": 1,"total": 4,"manual": 0}},"opensearch": {"name": "Benchmark: OpenSearch","checks": {"opensearch_service_domains_not_publicly_accessible": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "opensearch","Section": "OpenSearch","Service": "opensearch","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring OpenSearch resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"api-gateway": {"name": "API Gateway","checks": {"apigateway_restapi_logging_enabled": "PASS","apigateway_restapi_waf_acl_attached": "FAIL","apigatewayv2_api_authorizers_enabled": "FAIL","apigatewayv2_api_access_logging_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "api-gateway","Section": "API Gateway","Service": "apigateway","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring API Gateway resources.","checks_status": {"fail": 4,"pass": 1,"total": 5,"manual": 0}},"auto-scaling": {"name": "Benchmark: Auto Scaling","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "auto-scaling","Section": "Auto Scaling","Service": "autoscaling","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Auto Scaling resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"elasticsearch": {"name": "Benchmark: Elasticsearch","checks": {"opensearch_service_domains_audit_logging_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_https_communications_enforced": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "elasticsearch","Section": "ElasticSearch","Service": "elasticsearch","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Elasticsearch resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"cloudformation": {"name": "Benchmark: CloudFormation","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "cloudformation","Section": "CloudFormation","Service": "cloudformation","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring CloudFormation resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"secretsmanager": {"name": "Benchmark: Secrets Manager","checks": {"secretsmanager_automatic_rotation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "secretsmanager","Section": "Secrets Manager","Service": "secretsmanager","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Secrets Manager resources.","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"network-firewall": {"name": "Benchmark: Network Firewall","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "network-firewall","Section": "Network Firewall","Service": "network-firewall","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Network Firewall resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"elastic-beanstalk": {"name": "Benchmark: Elastic Beanstalk","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "elastic-beanstalk","Section": "Elastic Beanstalk","Service": "elasticbeanstalk","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Elastic Beanstalk resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}}},"requirements_passed": 14,"requirements_failed": 12,"requirements_manual": 11,"total_requirements": 37,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "e23a4728-558b-4a92-8e7d-f1473c21cc6e","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "ens_rd2022_aws","framework": "ENS","version": "RD2022","description": "The accreditation scheme of the ENS (National Security Scheme) has been developed by the Ministry of Finance and Public Administrations and the CCN (National Cryptological Center). This includes the basic principles and minimum requirements necessary for the adequate protection of information.","region": "eu-west-1","requirements": {"mp.s.1.aws.wm.1": {"name": "mp.s.1.aws.wm.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los servicios","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.s.1","DescripcionControl": "Se deberĆ” hacer uso del cifrado de la información contenida en los correos electrónicos."}],"description": "Protección del correo electrónico","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.s.1.aws.wm.2": {"name": "mp.s.1.aws.wm.2","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los servicios","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.s.1","DescripcionControl": "Habilitar el registro de eventos de Workmail en CloudWatch para realizar el seguimiento de mensajes con spam."}],"description": "Protección del correo electrónico","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.s.1.aws.wm.3": {"name": "mp.s.1.aws.wm.3","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los servicios","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.s.1","DescripcionControl": "En SES, se debe hacer uso de la opción que permite a los usuarios enviar correo electrónico cifrado con S/MIME"}],"description": "Protección del correo electrónico","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.s.4.aws.as.1": {"name": "mp.s.4.aws.as.1","checks": {"autoscaling_group_multiple_az": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los servicios","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.s.4","DescripcionControl": "Activar la solución AWS Auto Scaling para dotar a los sistemas de la capacidad suficiente para atender la carga prevista con holgura y desplegar tecnologĆ­as para la prevención de ataques conocidos."}],"description": "Protección frente a la denegación de servicio ","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"mp.s.2.aws.waf.1": {"name": "mp.s.2.aws.waf.1","checks": {"cloudfront_distributions_using_waf": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los servicios","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.s.2","DescripcionControl": "Todas las aplicaciones web distribuidas por el servicio de AWS CloudFront deben estar integradas con el servicio de firewall de aplicaciones web AWS WAF."}],"description": "Protección de servicios y aplicaciones web","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"mp.s.2.aws.waf.2": {"name": "mp.s.2.aws.waf.2","checks": {"apigateway_restapi_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los servicios","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.s.2","DescripcionControl": "Los API gateways deben tener un ACL WAF asociado."}],"description": "Protección de servicios y aplicaciones web","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.s.2.aws.waf.3": {"name": "mp.s.2.aws.waf.3","checks": {"elbv2_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los servicios","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.s.2","DescripcionControl": "Todos los balanceadores de aplicación deben estar integrados con el servicio de firewall de aplicación web para quedar protegidos ante ataques de la capa de aplicación"}],"description": "Protección de servicios y aplicaciones web","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.si.2.aws.es.1": {"name": "mp.si.2.aws.es.1","checks": {"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.si.2","DescripcionControl": "Aplicar cifrado sobre todos los dominios del servicio Amazon Elasticsearch Service (ES). En caso de usar este servicio, deberĆ” asegurarse la activación del cifrado en reposo."}],"description": "CriptografĆ­a","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"mp.si.2.aws.s3.1": {"name": "mp.si.2.aws.s3.1","checks": {"s3_bucket_default_encryption": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.si.2","DescripcionControl": "Aplicar cifrado sobre los distintos buckets de S3, de los cuales se debe asegurar que tengan activado el cifrado en reposo."}],"description": "CriptografĆ­a","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.pl.4.aws.sq.1": {"name": "op.pl.4.aws.sq.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.4","DescripcionControl": "La entidad usuaria deberĆ” llevar a cabo el estudio de capacidades a las que hace referencia la medida de seguridad, si bien (…) deberĆ” tener especialmente en cuenta: * Las cuotas de los servicios a utilizar."}],"description": "Necesidades de procesamiento","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.com.1.aws.cf.1": {"name": "mp.com.1.aws.cf.1","checks": {"cloudfront_distributions_https_enabled": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Asegurar que la distribución entre frontales CloudFront y sus orĆ­genes Ćŗnicamente emplee trĆ”fico HTTPs "}],"description": "PerĆ­metro seguro","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"mp.com.1.aws.s3.1": {"name": "mp.com.1.aws.s3.1","checks": {"s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Asegurar que los Buckets S3 de almacenamiento apliquen cifrado para la transferencia de datos empleando Secure Sockets Layer (SSL)"}],"description": "PerĆ­metro seguro","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.com.1.aws.sg.1": {"name": "mp.com.1.aws.sg.1","checks": {"ec2_securitygroup_from_launch_wizard": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Asegurar que el Security Group restrinja todo el trĆ”fico. Para ello, se deberĆ”n agregar las reglas del Security Group que se aplica por defecto cuando se crea una VPC."}],"description": "PerĆ­metro seguro","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"mp.com.1.aws.sg.2": {"name": "mp.com.1.aws.sg.2","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Evitar la existencia de Security Groups que dejen abierto todo el trĆ”fico entrante."}],"description": "PerĆ­metro seguro","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"mp.com.1.aws.sg.3": {"name": "mp.com.1.aws.sg.3","checks": {"ec2_securitygroup_not_used": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Evitar tener un repositorio de Security Groups que no estĆ©n siendo usados."}],"description": "PerĆ­metro seguro","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.com.3.aws.cf.1": {"name": "mp.com.3.aws.cf.1","checks": {"cloudfront_distributions_https_enabled": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["integridad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.3","DescripcionControl": "Asegurar que la distribución entre frontales CloudFront y sus orĆ­genes Ćŗnicamente emplee trĆ”fico HTTPS."}],"description": "Protección de la integridad y de la autenticidad","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"mp.com.3.aws.s3.1": {"name": "mp.com.3.aws.s3.1","checks": {"s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["integridad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.3","DescripcionControl": "Asegurar que los Buckets de almacenamiento S3 apliquen cifrado para la transferencia de datos empleando TLS."}],"description": "Protección de la integridad y de la autenticidad","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.com.4.aws.ws.1": {"name": "mp.com.4.aws.ws.1","checks": {"workspaces_vpc_2private_1public_subnets_nat": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "segregación de redes","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.4","DescripcionControl": "Se deberĆ”n abrir solo los puertos necesarios para el uso del servicio AWS WorkSpaces."}],"description": "Separación de flujos de información en la red","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"mp.si.2.aws.elb.1": {"name": "mp.si.2.aws.elb.1","checks": {"ec2_ebs_snapshots_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "recomendacion","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.si.2","DescripcionControl": "Se recomienda dejar activada la opción de cifrado por defecto para nuevos volĆŗmenes."}],"description": "CriptografĆ­a","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.si.2.aws.kms.1": {"name": "mp.si.2.aws.kms.1","checks": {"ec2_ebs_volume_encryption": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.si.2","DescripcionControl": "Aplicar cifrado sobre el almacenamiento de las instancias en todos sus volĆŗmenes de datos."}],"description": "CriptografĆ­a","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"mp.si.2.aws.rds.1": {"name": "mp.si.2.aws.rds.1","checks": {"rds_instance_storage_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.si.2","DescripcionControl": "Aplicar cifrado sobre las bases de datos AWS RDS."}],"description": "CriptografĆ­a","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.si.2.aws.sqs.1": {"name": "mp.si.2.aws.sqs.1","checks": {"sqs_queues_server_side_encryption_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.si.2","DescripcionControl": "Aplicar cifrado sobre las colas de mensajes de AWS (Amazon SQS)."}],"description": "CriptografĆ­a","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.exp.1.aws.re.1": {"name": "op.exp.1.aws.re.1","checks": {"resourceexplorer2_indexes_found": "PASS"},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.1","DescripcionControl": "Se recomienda el uso de AWS Resource Explorer para la exploración de los recursos como instancias RDB, buckets S3o tablas de Amazon DynamoDB."}],"description": "Inventario de activos","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.exp.5.aws.cm.1": {"name": "op.exp.5.aws.cm.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.5","DescripcionControl": "La entidad usuaria puede hacer uso de la utilidad AWS Change Manager para mantener un registro actualizado de las plantillas y peticiones de cambio en las que se incluya información en detalle sobre estos."}],"description": "Gestión de cambios","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.5.aws.ct.1": {"name": "op.exp.5.aws.ct.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.5","DescripcionControl": "Asegurar que CloudTrail estĆ© activo para todas las regiones."}],"description": "Gestión de cambios","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.exp.6.aws.gd.1": {"name": "op.exp.6.aws.gd.1","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.6","DescripcionControl": "Activar la protección contra software malintencionado de GuardDuty en todas las regiones."}],"description": "Protección frente a código daƱino","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.exp.7.aws.cf.1": {"name": "op.exp.7.aws.cf.1","checks": {"cloudfront_distributions_logging_enabled": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.7","DescripcionControl": "Habilitar los logs de acceso de CloudFront"}],"description": "Gestión de incidentes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.7.aws.gd.1": {"name": "op.exp.7.aws.gd.1","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.7","DescripcionControl": "Habilitar GuardDuty para la detección de incidentes de seguridad"}],"description": "Gestión de incidentes","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"op.exp.7.aws.sh.1": {"name": "op.exp.7.aws.sh.1","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.7","DescripcionControl": "Habilitar Security Hub"}],"description": "Gestión de incidentes","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.exp.8.aws.ct.1": {"name": "op.exp.8.aws.ct.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8","DescripcionControl": "Habilitar la herramienta CloudTrail en todas las regiones. Este serviio estĆ” habilitado por defecto cuando se crea una nueva cuenta, pero es posible deshabilitarlo."}],"description": "Registro de actividad","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.exp.8.aws.ct.2": {"name": "op.exp.8.aws.ct.2","checks": {"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8","DescripcionControl": "Establecer un filtro de mĆ©tricas desde AWS CloudWatch para detectar cambios en las configuraciones de CloudTrail"}],"description": "Registro de actividad","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.aws.ct.3": {"name": "op.exp.8.aws.ct.3","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8","DescripcionControl": "Habilitar la validación de archivos en todos los trails, evitando asĆ­ que estos se vean modificados o eliminados."}],"description": "Registro de actividad","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.aws.ct.4": {"name": "op.exp.8.aws.ct.4","checks": {"cloudtrail_s3_dataevents_write_enabled": null,"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8","DescripcionControl": "Habilitar la entrega continua de eventos de CloudTrail a un bucket S3 dedicado con el fin de unificar los archivos de registro."}],"description": "Registro de actividad","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"op.exp.8.aws.ct.5": {"name": "op.exp.8.aws.ct.5","checks": {"cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8","DescripcionControl": "Se deberĆ”n habilitar alertas para los siguientes eventos: * Llamadas no permitidas a la API, * Accesos no permitidos a la consola, * Todos los intentos de acceso sin el correcto uso de MFA, * Toda la actividad realizada sobre y por la cuenta root, * Cualquier cambio en las polĆ­ticas IAM"}],"description": "Registro de actividad","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"op.exp.8.aws.ct.6": {"name": "op.exp.8.aws.ct.6","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "medida","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8","DescripcionControl": "Activar el servicio de AWS CloudTrail para registrar la actividad de los usuarios relativa a la configuración de los servicios VPN Site-to-Site y AWS DirectConnect"}],"description": "Registro de actividad","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.exp.8.aws.cw.1": {"name": "op.exp.8.aws.cw.1","checks": {"cloudwatch_log_metric_filter_root_usage": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8","DescripcionControl": "Crear alertas utilizando herramientas como Amazon CloudWatch Events para anunciar el inicio de sesión y el uso de las credenciales de usuario root de la cuenta de administración"}],"description": "Registro de actividad","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.9.aws.ct.1": {"name": "op.exp.9.aws.ct.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.9","DescripcionControl": "Habilitar AWS Incident Manager y AWS CloudTrail en todas las regiones con el fin de recopilar información para generar contenido prescriptivo para la creación de informes exigidos por la medida de seguridad."}],"description": "Registro de la gestión de incidentes","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.ext.7.aws.am.1": {"name": "op.ext.7.aws.am.1","checks": {"account_maintain_current_contact_details": null,"account_security_contact_information_is_registered": null,"account_security_questions_are_registered_in_the_aws_account": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.7","DescripcionControl": "DeberĆ” proveerse la información relacionada con contactos alternativos (de facturación, operaciones y seguridad), con correos que no dependan de la misma persona. DeberĆ” comprobarse regularmente que estas cuentas funcionan correctamente y mantener listas de correo para asegurar la recepción de avisos por personal disponible en cada momento. AdemĆ”s, deberĆ”n establecerse preguntas de desafĆ­o de seguridad y respuestas para el caso de que sea necesario autenticarse como propiterio de la cuenta para ponerse en contacto con el soporte de AWS."}],"description": "Gestión de incidentes","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"op.mon.1.aws.ct.1": {"name": "op.mon.1.aws.ct.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.1","DescripcionControl": "Activar el servicio de eventos AWS CloudTrail para todas las regiones."}],"description": "Detección de intrusión","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.mon.1.aws.gd.1": {"name": "op.mon.1.aws.gd.1","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.1","DescripcionControl": "En ausencia de otras herramientas de terceros, habilitar Amazon GuarDuty para la detección de amenazas e intrusiones."}],"description": "Detección de intrusión","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.mon.1.aws.gd.2": {"name": "op.mon.1.aws.gd.2","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.1","DescripcionControl": "DeberĆ” habilitarse Amazon GuardDuty para todas las regiones tanto en la cuenta raĆ­z como en las cuentas miembro de un entorno multi-cuenta."}],"description": "Detección de intrusión","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.mon.1.aws.gd.3": {"name": "op.mon.1.aws.gd.3","checks": {"guardduty_centrally_managed": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.1","DescripcionControl": "Todas las cuentas miembro deberĆ”n estar aƱadidas para la supervisión bajo la cuenta raĆ­z."}],"description": "Detección de intrusión","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.mon.1.aws.gd.4": {"name": "op.mon.1.aws.gd.4","checks": {},"status": "PASS","attributes": [{"Tipo": "medida","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.mon.1","DescripcionControl": "La administración de Amazon GuardDuty quedarĆ” delegada exclusivamente a la cuenta de seguridad para garantizar una correcta asignación de los roles para este servicio."}],"description": "Detección de intrusión","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.mon.2.aws.sh.1": {"name": "op.mon.2.aws.sh.1","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.2","DescripcionControl": "Utilizar Security Hub para obtener una vista consolidada de los hallazgos de seguridad en los servicios de AWS habilitados."}],"description": "Sistema de mĆ©tricas","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.pl.4.aws.ec2.1": {"name": "op.pl.4.aws.ec2.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.4","DescripcionControl": "La entidad usuaria deberĆ” llevar a cabo el estudio de capacidades a las que hace referencia la medida de seguridad, si bien (…) deberĆ” tener especialmente en cuenta: * Las capacidades de procesamiento, almacenamiento y comunicaciones de las instancais desplegadas en AWS."}],"description": "Necesidades de procesamiento","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.com.1.aws.elb.1": {"name": "mp.com.1.aws.elb.1","checks": {"elb_ssl_listeners": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Habilitar TLS en los balanceadores de carga ELB "}],"description": "PerĆ­metro seguro","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.com.1.aws.elb.2": {"name": "mp.com.1.aws.elb.2","checks": {"elb_insecure_ssl_ciphers": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Evitar el uso de protocolos de cifrado inseguros para las polĆ­ticas de seguridad de ELB. Esto podrĆ­a dejar la conexión SSL entre balanceadores y clientes vulnerables a ser explotados. En particular deberĆ” evitarse el uso de TLS 1.0. "}],"description": "PerĆ­metro seguro","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"mp.com.1.aws.nfw.1": {"name": "mp.com.1.aws.nfw.1","checks": {"networkfirewall_in_all_vpc": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Filtrar todo el trĆ”fico entrante y saliente de la VPC a travĆ©s de Firewalls de red."}],"description": "PerĆ­metro seguro","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.com.1.aws.nfw.2": {"name": "mp.com.1.aws.nfw.2","checks": {"fms_policy_compliant": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Incidir en la utilización de AWS Firewall Manager para gestionar los firewalls de forma centralizada."}],"description": "PerĆ­metro seguro","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"mp.com.2.aws.vpn.1": {"name": "mp.com.2.aws.vpn.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.com.2","DescripcionControl": "Garantizar que las conexiones entre la VPC y la red local (remota) se canalizan a travĆ©s de VPN Site-to-Site o bien a travĆ©s de Direct Connect."}],"description": "Protección de la confidencialidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.com.2.aws.vpn.2": {"name": "mp.com.2.aws.vpn.2","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.com.2","DescripcionControl": "Garantizar que las conexiones entre la VPC y la red local (remota) se canalizan a travĆ©s de VPN Site-to-Site o bien a travĆ©s de Direct Connect."}],"description": "Protección de la confidencialidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.com.3.aws.elb.1": {"name": "mp.com.3.aws.elb.1","checks": {"elbv2_insecure_ssl_ciphers": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["integridad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.3","DescripcionControl": "Habilitar TLS en los balanceadores de carga ELB."}],"description": "Protección de la integridad y de la autenticidad","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"mp.com.3.aws.elb.2": {"name": "mp.com.3.aws.elb.2","checks": {"elbv2_insecure_ssl_ciphers": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["integridad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.3","DescripcionControl": "Evitar el uso de protocolos de cifrado inseguros en la conexión TLS entre clientes y balanceadores de carga. En particular, se deberĆ” evitar el uso de TLS 1.0."}],"description": "Protección de la integridad y de la autenticidad","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"mp.com.4.aws.vpc.1": {"name": "mp.com.4.aws.vpc.1","checks": {"vpc_subnet_separate_private_public": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.4","DescripcionControl": "Los flujos de información de red se deben separar a travĆ©s de la utilización de diferentes subnets."}],"description": "Separación de flujos de información en la red","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.com.4.aws.vpc.2": {"name": "mp.com.4.aws.vpc.2","checks": {"ec2_instance_internet_facing_with_instance_profile": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.4","DescripcionControl": "Evitar el uso de subnets con la opción de asignación automĆ”tica de IPs (auto-assign Public IP)."}],"description": "Separación de flujos de información en la red","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.si.2.aws.dydb.1": {"name": "mp.si.2.aws.dydb.1","checks": {"dynamodb_tables_kms_cmk_encryption_enabled": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.si.2","DescripcionControl": "Aplicar cifrado sobre las bases de datos DynamoDB, que deben implementar cifrado seguro mediante el uso de claves de cliente (KMS)."}],"description": "CriptografĆ­a","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.acc.1.aws.iam.1": {"name": "op.acc.1.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.1","DescripcionControl": "Utilizar los grupos y roles, en lugar de los usuarios individuales, para controlar el acceso. Esto permitirĆ” implementar un conjunto de permisos en lugar de actualizar muchas polĆ­ticas individuales cuando el acceso de un usuario necesita cambiar."}],"description": "Identificador Ćŗnico","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.1.aws.iam.2": {"name": "op.acc.1.aws.iam.2","checks": {"iam_check_saml_providers_sts": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.1","DescripcionControl": "Es muy recomendable la utilización de un proveedor de identidades que permita administrar las identidades en un lugar centralizado, en vez de utilizar IAM para ello."}],"description": "Proveedor de identidad centralizado","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.acc.1.aws.iam.3": {"name": "op.acc.1.aws.iam.3","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.1","DescripcionControl": "El usuario raĆ­z actĆŗa como usuario IAM de seguridad (usuario \"breakglass\"), dado que no se encuentra sincronizado con el proveedor de identidades externo, lo que permite la recuperación de emergencia del acceso a AWS en caso de imposibilidad de autenticar a los usuarios a travĆ©s del proveedor de identidades."}],"description": "Proveedor de identidad centralizado","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.1.aws.iam.4": {"name": "op.acc.1.aws.iam.4","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.1","DescripcionControl": "Utilizar identificadores Ćŗnicos para los usuarios del sistema."}],"description": "Identificador Ćŗnico","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.1.aws.iam.5": {"name": "op.acc.1.aws.iam.5","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.1","DescripcionControl": "Cada cuenta estarĆ” asociada a un identificador Ćŗnico."}],"description": "Identificador Ćŗnico","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.1.aws.iam.6": {"name": "op.acc.1.aws.iam.6","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.1","DescripcionControl": "Las cuentas deben ser inhabilitadas en los siguientes casos: cuando el usuario deja la organización; cuando el usuario cesa en la función para la cual se requerĆ­a la cuenta de usuario; o, cuando la persona que la autorizó, da orden en sentido contrario."}],"description": "Cuentas de usuario","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.1.aws.iam.7": {"name": "op.acc.1.aws.iam.7","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.1","DescripcionControl": "Las cuentas se retendrĆ”n durante el periodo necesario para atender a las necesidades de trazabilidad de los registros de actividad asociados a las mismas. A este periodo se le denominarĆ” periodo de retención."}],"description": "Cuentas de usuario","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.2.aws.iam.1": {"name": "op.acc.2.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.2","DescripcionControl": "Hacer uso de las polĆ­ticas IAM para la asignación de privilegios de acceso. DeberĆ”n administrarse permisos para controlar el acceso de las identidades de personas y mĆ”quinas y sus cargas de trabajo."}],"description": "Requisitos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.2.aws.iam.2": {"name": "op.acc.2.aws.iam.2","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.2","DescripcionControl": "DeberĆ” definirse una polĆ­tica IAM que conceda permiso al usuario o rol de IAM para utilizar los recursos y las acciones de la API especĆ­ficos que necesita"}],"description": "Requisitos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.2.aws.iam.3": {"name": "op.acc.2.aws.iam.3","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.2","DescripcionControl": "De acuerdo con las medidas del Esquema Nacional de seguridad los derechos de acceso de cada recurso, se establecerĆ”n segĆŗn las decisiones de la persona responsable del recurso, ateniĆ©ndose a la polĆ­tica y normativa de seguridad del sistema"}],"description": "Requisitos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.2.aws.iam.4": {"name": "op.acc.2.aws.iam.4","checks": {"iam_avoid_root_usage": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.2","DescripcionControl": "Se deberĆ” delegar en cuentas administradoras la administración de la organización, dejando la cuenta maestra sin uso y con las medidas de seguridad pertinentes."}],"description": "Requisitos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.acc.2.aws.vpn.1": {"name": "op.acc.2.aws.vpn.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.2","DescripcionControl": "DeberĆ” definirse una correcta polĆ­tica de permisos IAM para operaciones de Amazon WorkSpaces segĆŗn las recomendaciónes establecidas en la sección 3.1.1 Control de Acceso de la guĆ­a CCN STIC-887A GuĆ­a de configuración segura AWS."}],"description": "Requisitos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.2.aws.vpn.2": {"name": "op.acc.2.aws.vpn.2","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.2","DescripcionControl": "DeberĆ”n restringirse los permisos a usuarios para utilizar la acción ec2:DescribeVpnConnections. Esta acción permite a los usuarios ver la información de configuración de la gateway de cliente sobre las conexiones Site-to-Site VPN de su cuenta."}],"description": "Requisitos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.2.aws.vpn.3": {"name": "op.acc.2.aws.vpn.3","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.2","DescripcionControl": "La rotación de certificados de VPN deberĆ” asignarse siguiendo las recomendaciónes de segregación de funciones tal y como se explica en la sección 3.1.1."}],"description": "Requisitos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.3.aws.iam.1": {"name": "op.acc.3.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.3","DescripcionControl": "Enumerar los recursos especĆ­ficos a los que puede obtener acceso una función de trabajo."}],"description": "Segregación de funciones y tareas","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.3.aws.iam.2": {"name": "op.acc.3.aws.iam.2","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.3","DescripcionControl": "Emplear correctamente el uso de RBAC/ABAC para separar las funciones de desarrollo y operación."}],"description": "Segregación de funciones y tareas","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.3.aws.iam.3": {"name": "op.acc.3.aws.iam.3","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.3","DescripcionControl": "Emplear correctamente el uso de RBAC/ABAC para separar las funciones de autorización y control de uso."}],"description": "Segregación de funciones y tareas","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.3.aws.iam.4": {"name": "op.acc.3.aws.iam.4","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.3","DescripcionControl": "Las polĆ­ticas IAM deberĆ­an estar asociadas solo a grupos y a roles."}],"description": "Segregación de funciones y tareas","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.4.aws.iam.1": {"name": "op.acc.4.aws.iam.1","checks": {"awslambda_function_url_public": null,"awslambda_function_url_cors_policy": null,"sqs_queues_not_publicly_accessible": "PASS","organizations_scp_check_deny_regions": null,"s3_bucket_policy_public_write_access": "PASS","iam_policy_allows_privilege_escalation": null,"cloudwatch_cross_account_sharing_disabled": null,"awslambda_function_not_publicly_accessible": "PASS","organizations_account_part_of_organizations": null,"iam_inline_policy_no_administrative_privileges": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.4","DescripcionControl": "Las polĆ­ticas IAM deben permitir sólo los privilegios necesarios para cada rol. Se recomienda comenzar con el mĆ­nimo nivel de permisos e ir aƱadiendo permisos adicionales segĆŗn vaya surgiendo la necesidad en lugar de comenzar con permisos administrativos."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 3,"total": 13,"manual": 0}},"op.acc.4.aws.iam.2": {"name": "op.acc.4.aws.iam.2","checks": {"iam_policy_allows_privilege_escalation": null,"iam_inline_policy_no_administrative_privileges": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.4","DescripcionControl": "Evitar polĆ­ticas con comodines (wildcards) en su definición, que puedan otorgar privilegios administrativos completos."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"op.acc.4.aws.iam.3": {"name": "op.acc.4.aws.iam.3","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automatico","IdGrupoControl": "op.acc.4","DescripcionControl": "Para una correcta implementación de la estrategia de polĆ­ticas de acceso, se recomienda utilizar la herramienta Policy Simulator para probar y solucionar posibles problemas en la asignación de polĆ­ticas."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.acc.4.aws.iam.4": {"name": "op.acc.4.aws.iam.4","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.4","DescripcionControl": "Se puede utilizar Acces Analyzer para identificar recursos y cuentas, validar las polĆ­ticas contra las prĆ”cticas recomendadas y generar polĆ­ticas con base en la actividad de acceso de registros de CloudTrail."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.4.aws.iam.5": {"name": "op.acc.4.aws.iam.5","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.4","DescripcionControl": "En cuanto a los accesos a las instancias alojadas en AWS se recomienda emplear mecanismos para mantener a las personas alejadas de los datos. Es decir, limitar al mĆ”ximo el acceso directo a los datos por parte de los usuarios."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.4.aws.iam.6": {"name": "op.acc.4.aws.iam.6","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.4","DescripcionControl": "Con AWS Systems Manager Automation pueden utilizarse documentos de automatización y diseƱar flujos de trabajo para la administración de cambios o la ejecución de operaciones estĆ”ndar para administrar las instancias EC2 (p. ej., actualizar los sistemas operativos), en lugar de permitir el acceso directo. "}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.acc.4.aws.iam.7": {"name": "op.acc.4.aws.iam.7","checks": {"iam_avoid_root_usage": null,"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.4","DescripcionControl": "Se restringirĆ” todo acceso a las acciones especificadas para el usuario root de una cuenta."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"op.acc.4.aws.iam.8": {"name": "op.acc.4.aws.iam.8","checks": {"organizations_scp_check_deny_regions": null,"organizations_account_part_of_organizations": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.4","DescripcionControl": "Se restringirĆ” todo acceso a las acciones especificadas para el usuario root de una cuenta."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"op.acc.4.aws.iam.9": {"name": "op.acc.4.aws.iam.9","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.4","DescripcionControl": "Se configurarĆ”n diferentes permisos a las cuentas de usuario, limitando la utilización de la cuenta ā€œrootā€ para tareas especĆ­ficas que necesiten un nivel de privilegios elevado, esta configuración debe entenderse como un mecanismo para impedir que el trabajo directo con usuarios con privilegios de administrador repercuta negativamente en la seguridad, a acometer todas las acciones con el mĆ”ximo privilegio cuando este no es siempre requerido."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"op.acc.4.aws.sys.1": {"name": "op.acc.4.aws.sys.1","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.4","DescripcionControl": "Habilitar systems manager automation para evitar acceso remoto humano a tareas automatizables."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.acc.4.aws.vpn.1": {"name": "op.acc.4.aws.vpn.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.4","DescripcionControl": "Las configuraciones de las polĆ­ticas de las AWS VPN deben tener las redes especĆ­ficas con las que se va a establecer la conectividad y evitar polĆ­ticas genĆ©ricas basadas en routing donde se pierde el control granular de las redes permitidas en los SA de la VPN."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.4.aws.vpn.2": {"name": "op.acc.4.aws.vpn.2","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.4","DescripcionControl": "En configuraciones de AWS DirectConnect, deberĆ”n controlarse los AS y el routing que se lleva por BGP, de modo que se propague el mĆ­nimo de rutas y se asegure que no exista redistribución de rutas/redes privadas de entornos del cliente hacia el ISP."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.6.aws.iam.1": {"name": "op.acc.6.aws.iam.1","checks": {"iam_user_two_active_access_key": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6","DescripcionControl": "Evitar el uso permanente de mĆŗltiples claves de acceso para un mismo usuario IAM."}],"description": "Mecanismo de autenticación (usuarios de la organización)","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.acc.6.aws.iam.2": {"name": "op.acc.6.aws.iam.2","checks": {"iam_user_accesskey_unused": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6","DescripcionControl": "Las claves de acceso deberĆ”n rotarse cada 90 dĆ­as o menos."}],"description": "Mecanismo de autenticación (usuarios de la organización)","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"op.acc.6.aws.iam.3": {"name": "op.acc.6.aws.iam.3","checks": {"iam_user_accesskey_unused": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6","DescripcionControl": "DeberĆ” habilitarse el vencimiento de las credenciales de los usuarios. (Bien a travĆ©s de la polĆ­tica de contraseƱas de IAM o del proveedor de identidades federado)."}],"description": "Mecanismo de autenticación (usuarios de la organización)","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"op.acc.6.aws.iam.4": {"name": "op.acc.6.aws.iam.4","checks": {"iam_user_no_setup_initial_access_key": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6","DescripcionControl": "Se deberĆ” evitar la asignación por defecto de claves de acceso para todos los usuarios que tengan acceso a la consola. Para cumplir con este requisito, se recomienda revisar quĆ© usuarios se encuentran dados de alta en la cuenta de AWS y disponen de acceso a la consola de administración y evitar la asignación de claves de acceso cuando no son necesarias."}],"description": "Mecanismo de autenticación (usuarios de la organización)","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.cont.2.aws.az.1": {"name": "op.cont.2.aws.az.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "continuidad del servicio","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.cont.2","DescripcionControl": "(Organizativo) DeberĆ” implementarse correctamente la distribución de servicios segĆŗn regiones y zonas de disponibilidad para limitar al mĆ”ximo los riesgos asociados a una Ćŗnica ubicación."}],"description": "Plan de continuidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.1.aws.cfg.1": {"name": "op.exp.1.aws.cfg.1","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.1","DescripcionControl": "En lo referente al inventariado de activos, asegurar que AWS Config estĆ” habilitado en todas las regiones y utilizar la herramienta para obtener una vista de los recursos existentes en las cuentas de AWS."}],"description": "Inventario de activos","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.1.aws.cfg.2": {"name": "op.exp.1.aws.cfg.2","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "bajo","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.1","DescripcionControl": "Configurar una regla de Config Rules que alerte sobre el despliegue de recursos sin las etiquetas correspondientes asociadas."}],"description": "Inventario de activos","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.1.aws.sys.1": {"name": "op.exp.1.aws.sys.1","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.1","DescripcionControl": "En el Ć”mbito del software desplegado en las instancias de EC2, habilitar AWS System Manager Inventory para todo el entorno de EC2 en caso de no utilizar herramientas de terceros."}],"description": "Inventario de activos","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"op.exp.1.aws.sys.2": {"name": "op.exp.1.aws.sys.2","checks": {"organizations_tags_policies_enabled_and_attached": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.1","DescripcionControl": "Asignar metadatos personalizados a cada nodo administrado con información sobre el responsable del activo."}],"description": "Inventario de activos","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.1.aws.tag.1": {"name": "op.exp.1.aws.tag.1","checks": {"organizations_tags_policies_enabled_and_attached": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.1","DescripcionControl": "Para la correcta identificación del responsable, asociar etiquetas para todos los activos."}],"description": "Inventario de activos","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.3.aws.cfg.1": {"name": "op.exp.3.aws.cfg.1","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "bajo","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.3","DescripcionControl": "El cumplimiento de los requisitos se puede apoyar en la utilización de los servicios Config, Config Rules y Conformance Packs para identificar lĆ­neas base de configuración para evaluar si los recursos de AWS se ajustan a las prĆ”cticas autorizadas por la organización."}],"description": "Gestión de la configuración de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.4.aws.ami.1": {"name": "op.exp.4.aws.ami.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.4","DescripcionControl": "Una forma eficiente de garantizar la instalación de las versiones actualizadas y aprobadas del software de los sistemas es la utilización de Golden AMIs."}],"description": "Mantenimiento y actualizaciones de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.4.aws.sys.2": {"name": "op.exp.4.aws.sys.2","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.4","DescripcionControl": "Utilizar AWS Systems Manager Patch Manager para planificar y gestionar la aplicación de parches minimizando los riesgos asociados a tener instancias con software desactualizado y expuesto a vulnerabilidades conocidas."}],"description": "Mantenimiento y actualizaciones de seguridad","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"op.exp.5.aws.cal.1": {"name": "op.exp.5.aws.cal.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.5","DescripcionControl": "Utilizar AWS Change Calendar para establecer una ventana de tiempo (fecha y hora) en la que realizar los cambios y las pruebas de preproducción en equipos equivalentes a los de producción sin riesgo a que estas afecten a la continuidad del servicio prestado."}],"description": "Gestión de cambios","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.9.aws.img.1": {"name": "op.exp.9.aws.img.1","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssmincidents_enabled_with_plans": null},"status": "FAIL","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.9","DescripcionControl": "Habilitar AWS Incident Manager y AWS CloudTrail en todas las regiones con el fin de recopilar información para generar contenido prescriptivo para la creación de informes exigidos por la medida de seguridad."}],"description": "Registro de la gestión de incidentes","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"op.mon.3.aws.cwl.1": {"name": "op.mon.3.aws.cwl.1","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automatico","IdGrupoControl": "op.mon.3","DescripcionControl": "DeberĆ” asegurarse que todos los servicios que se utilicen en la arquitectura de la aplicación desplegada en AWS estĆ©n generando logs"}],"description": "Vigilancia","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.info.6.aws.iam.1": {"name": "mp.info.6.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de la información","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.info.6","DescripcionControl": "La organización puede hacer uso de roles y polĆ­ticas IAM para la definición y asignación de permisos en cuanto a controles de acceso de las copias de respaldo."}],"description": "Copias de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.info.6.aws.tag.1": {"name": "mp.info.6.aws.tag.1","checks": {"organizations_tags_policies_enabled_and_attached": null},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de la información","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.info.6","DescripcionControl": "Los planes de respaldo se pueden integrar con AWS Tags, acotando con base en las etiquetas de los recursos el alcance de cada proceso de copiado."}],"description": "Copias de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.acc.4.aws.iam.10": {"name": "op.acc.4.aws.iam.10","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.4","DescripcionControl": "Se evitarĆ” que los usuarios puedan deshabilitar o modificar servicios relacionados con el Ć”rea de seguridad como AWS Config o AWS CloudWatch."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.4.aws.iam.11": {"name": "op.acc.4.aws.iam.11","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.4","DescripcionControl": "DeberĆ” definirse una polĆ­tica de IAM que conceda permiso al usuario o rol de IAMpara utilizar exclusivamente los recursos y las acciones de WorkSpace que necesita."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.4.aws.iam.12": {"name": "op.acc.4.aws.iam.12","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.4","DescripcionControl": "Las polĆ­ticas IAM Ćŗnicamente deben poder asignarse por el usuario que tenga la función de control de accesos expresamente atribuida."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.4.aws.iam.13": {"name": "op.acc.4.aws.iam.13","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.4","DescripcionControl": "No utilizar el usuario raĆ­z salvo necesidad expresa."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.cont.3.aws.drs.1": {"name": "op.cont.3.aws.drs.1","checks": {"drs_job_exist": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "continuidad del servicio","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.cont.3","DescripcionControl": "La organización puede hacer uso del servicio AWS Elastic Disaster Recovery, programando y ejecutando pruebas no disruptivas (simulacros que no afectan ni al servidor de origen ni a la replicación de datos en curso) que prueben el correcto funcionamiento de las recuperaciones del plan de continuidad."}],"description": "Pruebas periódicas","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.10.aws.cmk.1": {"name": "op.exp.10.aws.cmk.1","checks": {"iam_policy_no_full_access_to_kms": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.10","DescripcionControl": "Los usuarios o roles con privilegios para la creación de claves deben ser diferentes a los que van a utilizar las claves para operaciones de cifrado."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.10.aws.cmk.2": {"name": "op.exp.10.aws.cmk.2","checks": {"iam_policy_no_full_access_to_kms": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.10","DescripcionControl": "Utilizar claves gestionadas por los clientes (CMK)."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.10.aws.cmk.3": {"name": "op.exp.10.aws.cmk.3","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.10","DescripcionControl": "Activar la rotación de las claves CMK."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.10.aws.cmk.4": {"name": "op.exp.10.aws.cmk.4","checks": {"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.10","DescripcionControl": "Para el archivo posterior a la explotación y destrucción de las claves se debe deshabilitar todas las claves CMK que no estĆ©n en uso."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.10.aws.cmk.5": {"name": "op.exp.10.aws.cmk.5","checks": {"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.10","DescripcionControl": "Eliminar las claves deshabilitadas que no estĆ©n en uso y no mantengan ningĆŗn objeto o recurso cifrado, completando el ciclo de vida de la clave."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.10.aws.cmk.6": {"name": "op.exp.10.aws.cmk.6","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.10","DescripcionControl": "Utilizar el principio de mĆ­nimos privilegios para las polĆ­ticas asociadas a claves."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.10.aws.cmk.7": {"name": "op.exp.10.aws.cmk.7","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.10","DescripcionControl": "Utilizar tags y alias para una mejor administración de las claves."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.10.aws.cmk.8": {"name": "op.exp.10.aws.cmk.8","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.10","DescripcionControl": "Utilizar las polĆ­ticas IAM y las concesiones de claves para el acceso a las mismas."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.10.aws.tag.1": {"name": "op.exp.10.aws.tag.1","checks": {"organizations_tags_policies_enabled_and_attached": null},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.10","DescripcionControl": "Se recomienda utilizar tags y alias para una mejor gestión y administración de las claves."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.mon.1.aws.flow.1": {"name": "op.mon.1.aws.flow.1","checks": {"vpc_flow_logs_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.1","DescripcionControl": "Activar el servicio VPC FlowLogs."}],"description": "Detección de intrusión","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.pl.2.aws.warch.1": {"name": "op.pl.2.aws.warch.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.2.r3","DescripcionControl": "Es recomendable que la entidad usuaria se apoye en el marco de trabajo AWS Well-Architected Framework"}],"description": "Validación de datos","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.pl.4.r1.aws.cw.1": {"name": "op.pl.4.r1.aws.cw.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.4.r1","DescripcionControl": "En caso de no disponer de herramientas de terceros, se deberĆ”n utilizar las herramientas de monitorización de la capaciad indicadas para monitorizar las capacidades de la infraestructura y el grado de consumo de los servicios en función de las cuotas disponibles. (CloudWatch)"}],"description": "Mejora continua de la gestión de la capacidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.pl.4.r1.aws.sq.1": {"name": "op.pl.4.r1.aws.sq.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.4.r1","DescripcionControl": "En caso de no disponer de herramientas de terceros, se deberĆ”n utilizar las herramientas de monitorización de la capaciad indicadas para monitorizar las capacidades de la infraestructura y el grado de consumo de los servicios en función de las cuotas disponibles. (Service Quotas)"}],"description": "Mejora continua de la gestión de la capacidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.pl.4.r1.aws.sq.2": {"name": "op.pl.4.r1.aws.sq.2","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.4.r1","DescripcionControl": "En cuanto a la monitorización sobre el grado de consumo, utilizar la solución nativa Quota Monitor."}],"description": "Previsión y actualización de la capacidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.pl.4.r1.aws.sq.3": {"name": "op.pl.4.r1.aws.sq.3","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.4.r1","DescripcionControl": "Visualizar las cuotas de servicio y configurar alarmas a travĆ©s de la integración de AWS Service Quotas con CloudWatch."}],"description": "Monitorización de la capacidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.info.6.aws.bcku.1": {"name": "mp.info.6.aws.bcku.1","checks": {"backup_plans_exist": "PASS","backup_vaults_exist": null,"backup_reportplans_exist": null},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de la información","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.info.6","DescripcionControl": "Para los procedimientos de respaldo de cualquiera de los dos entornos (local y nube) y siempre y cuando se utilicen recursos compatibles en el entorno local, la entidad puede hacer uso de AWS Backup, que permite elaboración de planes de respaldo y la definición de reglas de frecuencia, ciclo de vida, lugar de almacenamiento y etiquetado de las copias de seguridad."}],"description": "Copias de seguridad","checks_status": {"fail": 0,"pass": 1,"total": 3,"manual": 0}},"mp.si.2.r1.aws.kms.1": {"name": "mp.si.2.r1.aws.kms.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.si.2.r1","DescripcionControl": "Utilizar productos certificados conforme a op.pl.5, si bien AWS KMS es un producto certificado cuyo uso satisface la exigencia de este control."}],"description": "Productos certificados","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.si.2.r2.aws.ebs.1": {"name": "mp.si.2.r2.aws.ebs.1","checks": {"ec2_ebs_snapshots_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.si.2.r2","DescripcionControl": "Se deberĆ” asegurar el cifrado de las copias de seguridad (snapshots) de EBS."}],"description": "Copias de seguridad","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.sw.2.r1.aws.acb.1": {"name": "mp.sw.2.r1.aws.acb.1","checks": {"codebuild_project_older_90_days": "FAIL","codebuild_project_user_controlled_buildspec": "PASS"},"status": "FAIL","attributes": [{"Tipo": "recomendacion","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de la información","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.sw.2.r1","DescripcionControl": "Habilitar Amazon CodeBuild para el apoyo de la realización de pruebas en entornos aisaldos."}],"description": "Aceptación y puesta en servicio","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"op.exp.8.r1.aws.ct.2": {"name": "op.exp.8.r1.aws.ct.2","checks": {"cloudtrail_insights_exist": null,"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r1","DescripcionControl": "Configurar la herramienta CloudTrail de manera que realice el registro de eventos de administración, eventos de datos y eventos anómalos (insights)."}],"description": "Revisión de los registros","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"op.exp.8.r1.aws.ct.3": {"name": "op.exp.8.r1.aws.ct.3","checks": {"cloudtrail_insights_exist": null,"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r1","DescripcionControl": "Registrar los eventos de lectura y escritura de datos."}],"description": "Revisión de los registros","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"op.exp.8.r1.aws.ct.4": {"name": "op.exp.8.r1.aws.ct.4","checks": {"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r1","DescripcionControl": "Registrar los eventos de lectura y escritura de datos."}],"description": "Revisión de los registros","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"op.exp.8.r1.aws.ct.6": {"name": "op.exp.8.r1.aws.ct.6","checks": {"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r1","DescripcionControl": "Habilitar la entrega continua de eventos de CloudTrail a un bucket de Amazon S3"}],"description": "Revisión de los registros","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.r1.aws.ct.7": {"name": "op.exp.8.r1.aws.ct.7","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r1","DescripcionControl": "Integrar CloudTrail con el servicio CloudWatch Logs"}],"description": "Revisión de los registros","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.r1.aws.cw.1": {"name": "op.exp.8.r1.aws.cw.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.8.r1","DescripcionControl": "Utilizar el servicio AWS CloudWatch para centralizar y revisar los registros de todos los sistemas independientemente de su origen."}],"description": "Revisión de los registros","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.8.r3.aws.ct.1": {"name": "op.exp.8.r3.aws.ct.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.8.r3","DescripcionControl": "Ejecutar la acción PutRetentionPolicy de Amazon CloudWatch, permitiendo asĆ­ establecer la retención del grupo de registros especificado y configurar el nĆŗmero de dĆ­as durante los cuales se conservarĆ”n los eventos de registro en el grupo seleccionado de acuerdo con el documento de seguridad correspondiente. Paralelamente, se debe definir un periodo de retención para los datos almacenados en CloudTrail Lakes."}],"description": "Retención de registros","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.8.r3.aws.cw.1": {"name": "op.exp.8.r3.aws.cw.1","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r3","DescripcionControl": "Ejecutar la acción PutRetentionPolicy de Amazon CloudWatch, permitiendo asĆ­ establecer la retención del grupo de registros especificado y configurar el nĆŗmero de dĆ­as durante los cuales se conservarĆ”n los eventos de registro en el grupo seleccionado de acuerdo con el documento de seguridad correspondiente. Paralelamente, se debe definir un periodo de retención para los datos almacenados en CloudTrail Lakes."}],"description": "Retención de registros","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.r4.aws.ct.1": {"name": "op.exp.8.r4.aws.ct.1","checks": {"iam_policy_allows_privilege_escalation": null,"iam_policy_no_full_access_to_cloudtrail": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_role_cross_service_confused_deputy_prevention": null,"iam_customer_attached_policy_no_administrative_privileges": null,"iam_customer_unattached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r4","DescripcionControl": "Asignar correctamente las polĆ­ticas AWS IAM para el acceso y borrado de los registros y sus copias de seguridad haciendo uso del principio de mĆ­nimo privilegio."}],"description": "Control de acceso","checks_status": {"fail": 0,"pass": 0,"total": 7,"manual": 0}},"op.exp.8.r4.aws.ct.2": {"name": "op.exp.8.r4.aws.ct.2","checks": {"s3_bucket_public_access": null,"s3_bucket_policy_public_write_access": "PASS","cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r4","DescripcionControl": "Utilizar una polĆ­tica de bucket para restringir el acceso de forma pĆŗblica e imponer restricciones sobre cuĆ”les de los usuarios pueden eliminar objetos de Amazon S3."}],"description": "Control de acceso","checks_status": {"fail": 0,"pass": 2,"total": 3,"manual": 0}},"op.exp.8.r4.aws.ct.3": {"name": "op.exp.8.r4.aws.ct.3","checks": {"cloudtrail_bucket_requires_mfa_delete": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r4","DescripcionControl": "Activar el acceso por MFA al registro de actividad almacenado en los buckets de Amazon S3 dedicados para AWS CloudTrail."}],"description": "Control de acceso","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.r4.aws.ct.4": {"name": "op.exp.8.r4.aws.ct.4","checks": {"cloudtrail_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r4","DescripcionControl": "Configurar los archivos de logs de AWS CloudTrail para aprovechar el cifrado del lado del servidor (SSE – Server Side Encryption) y las claves maestras creadas por el cliente (CMK de KMS)."}],"description": "Control de acceso","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.r4.aws.ct.5": {"name": "op.exp.8.r4.aws.ct.5","checks": {"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r4","DescripcionControl": "El almacĆ©n de logs de CloudTrail no deberĆ­a ser accesible de forma pĆŗblica"}],"description": "Control de acceso","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.r4.aws.ct.6": {"name": "op.exp.8.r4.aws.ct.6","checks": {"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r4","DescripcionControl": "El almacĆ©n de logs de CloudTrail no deberĆ­a ser accesible de forma pĆŗblica(ACLs)"}],"description": "Control de acceso","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.exp.8.r4.aws.ct.7": {"name": "op.exp.8.r4.aws.ct.7","checks": {"cloudtrail_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r4","DescripcionControl": "Cifrado de los trails con KMS"}],"description": "Control de acceso","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.r4.aws.ct.8": {"name": "op.exp.8.r4.aws.ct.8","checks": {"iam_policy_allows_privilege_escalation": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_role_cross_service_confused_deputy_prevention": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r4","DescripcionControl": "Asignar correctamente las polĆ­ticas IAM para el acceso y borrado de los registros y sus copias de seguridad haciendo uso del principio de mĆ­nimo privilegio."}],"description": "Control de acceso","checks_status": {"fail": 0,"pass": 0,"total": 7,"manual": 0}},"op.mon.3.r1.aws.gd.1": {"name": "op.mon.3.r1.aws.gd.1","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.3.r1","DescripcionControl": "Activar GuardDuty y Security Hub o bien disponer de un SIEM externo a AWS"}],"description": "Correlación de eventos","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.mon.3.r1.aws.sh.1": {"name": "op.mon.3.r1.aws.sh.1","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.3.r1","DescripcionControl": "Activar GuardDuty y Security Hub o bien disponer de un SIEM externo a AWS"}],"description": "Correlación de eventos","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.mon.3.r2.aws.sh.1": {"name": "op.mon.3.r2.aws.sh.1","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.3.r2","DescripcionControl": "Utilizar las herramientas AWS Config y Security hub"}],"description": "AnĆ”lisis dinĆ”mico","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.mon.3.r3.aws.gd.1": {"name": "op.mon.3.r3.aws.gd.1","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.3.r3","DescripcionControl": "Activar GuardDuty (ya cubierto)"}],"description": "Ciberamenazas avanzadas","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.pl.4.r1.aws.sns.1": {"name": "op.pl.4.r1.aws.sns.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.4.r1","DescripcionControl": "Para la creación de alarmas en materia de capacidad de las instancias, se debe configurar un tema de SNS que permita el envĆ­o de mails automĆ”ticos a la dirección de correo seleccionada."}],"description": "Monitorización de la capacidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.pl.4.r1.aws.sns.2": {"name": "op.pl.4.r1.aws.sns.2","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.4.r1","DescripcionControl": "Configurar alarmas correspondientes a las diferentes capacidades (SNS) como uso de CPU, capacidad de almacenamiento o latencia."}],"description": "Monitorización de la capacidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.com.3.r1.aws.vpn.1": {"name": "mp.com.3.r1.aws.vpn.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["integridad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.com.3.r1","DescripcionControl": "Utilizar VPN Site-to-Site para conectar las VPCs con las redes locales o externas."}],"description": "Redes privadas virtuales","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.com.4.r1.aws.vpc.1": {"name": "mp.com.4.r1.aws.vpc.1","checks": {"vpc_different_regions": null,"vpc_subnet_separate_private_public": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.4.r1","DescripcionControl": "Implementar la segmentación a travĆ©s de la utilización de diferentes VPCs."}],"description": "Segmentación lógica avanzada","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"mp.com.4.r2.aws.vpc.1": {"name": "mp.com.4.r2.aws.vpc.1","checks": {"vpc_peering_routing_tables_with_least_privilege": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": ["mp.com.4.r3"],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.4.r2","DescripcionControl": "Implementar la segmentación a travĆ©s de la utilización de diferentes VPCs conectadas entre sĆ­ por VPN."}],"description": "Segmentación lógica avanzada","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"mp.com.4.r3.aws.vpc.1": {"name": "mp.com.4.r3.aws.vpc.1","checks": {"vpc_different_regions": null,"vpc_subnet_different_az": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad"],"Dependencias": ["mp.com.4.r2"],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.4.r3","DescripcionControl": "Implementar la segmentación a travĆ©s de diferentes VPCs situadas en diferentes ubicaciones."}],"description": "Segmentación fĆ­sica","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"mp.sw.2.r1.aws.cfgd.1": {"name": "mp.sw.2.r1.aws.cfgd.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de la información","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.sw.2.r2","DescripcionControl": "Habilitar CloudFormation Guard para el apoyo en las tareas de inspección de recursos no conformes implementados en el código fuente."}],"description": "Aceptación y puesta en servicio","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.1.r1.aws.iam.1": {"name": "op.acc.1.r1.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.1.r1","DescripcionControl": "Los identificadores de usuario deberĆ”n ser asignados en el proveedor de identidades (o en IAM) de modo que se permita singularizar a la persona asociada a cada identificador y cumplir con el resto de requisitos del refuerzo"}],"description": "Identificación de usuario","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.2.r1.aws.iam.1": {"name": "op.acc.2.r1.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.2.r1","DescripcionControl": "Evitar el uso de asunción de roles para cualquier cuenta."}],"description": "Privilegios de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.3.r1.aws.iam.1": {"name": "op.acc.3.r1.aws.iam.1","checks": {"iam_support_role_created": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.3.r1","DescripcionControl": "En caso de ser de aplicación, la segregación deberĆ” tener en cuenta la separación de las funciones de configuración y mantenimiento y de auditorĆ­a de cualquier otra."}],"description": "Segregación rigurosa","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.acc.3.r2.aws.iam.1": {"name": "op.acc.3.r2.aws.iam.1","checks": {"iam_securityaudit_role_created": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "opcional","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.3.r2","DescripcionControl": "Disponer de cuentas con privilegios de auditorĆ­a estrictamente controladas y personalizadas."}],"description": "Privilegios de auditorĆ­a","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.acc.3.r3.aws.iam.1": {"name": "op.acc.3.r3.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "opcional","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.3.r3","DescripcionControl": "Limitar el acceso a la información de seguridad del sistema a los administradores de seguridad utilizando los mecanismos de acceso imprescindibles (consola, interfaz web, acceso remoto etc.)."}],"description": "Acceso a la información de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.6.r1.aws.iam.1": {"name": "op.acc.6.r1.aws.iam.1","checks": {"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": ["op.acc.6.r2","op.acc.6.r4"],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6.r1","DescripcionControl": "Las contraseƱas de los usuarios deberĆ”n tener normas de complejidad mĆ­nima y robustez."}],"description": "ContraseƱas","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"op.acc.6.r2.aws.iam.1": {"name": "op.acc.6.r2.aws.iam.1","checks": {"iam_root_mfa_enabled": null,"iam_administrator_access_with_mfa": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": ["op.acc.6.r1","op.acc.6.r4"],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6.r2","DescripcionControl": "MFA deberĆ” estar habilitado para todas las cuentas que tengan contraseƱa para acceder a la consola, incluyendo el usuario root."}],"description": "ContraseƱa + otro factor de autenticación","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"op.acc.6.r2.aws.iam.2": {"name": "op.acc.6.r2.aws.iam.2","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.6.r2","DescripcionControl": "Se recomienda que la organización determine quĆ© llamadas a la API deben tambiĆ©n contar con seguridad reforzada a travĆ©s de un doble factor de autenticación."}],"description": "ContraseƱa + otro factor de autenticación","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.6.r3.aws.iam.1": {"name": "op.acc.6.r3.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.6.r3","DescripcionControl": "Utilizar el servicio AWS IAM Roles Anywhere para crear un ancla de confianza en la que se haga referencia al servicio AWS Certificate Manager Private CA o registrar sus propias autoridades de certificación (CA), permitiendo usar el certificado emitido por la misma para obtener credenciales temporales para el acceso al entorno AWS. Estos certificados deberĆ”n estar protegidos por un segundo factor."}],"description": "Certificados","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.6.r4.aws.iam.1": {"name": "op.acc.6.r4.aws.iam.1","checks": {"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": ["op.acc.6.r1","op.acc.6.r3"],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6.r4","DescripcionControl": "Habilitar los dispositivos MFA fĆ­sicos para todos los usuarios IAM mediante la consola, lĆ­nea de comandos o la propia API de IAM. Del mismo modo, el uso de estos certificados deberĆ” estar protegido por un segundo factor de tipo PIN o biomĆ©trico."}],"description": "Certificados en dispositvo fĆ­sico","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"op.acc.6.r5.aws.iam.1": {"name": "op.acc.6.r5.aws.iam.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6.r5","DescripcionControl": "Para registrar los intentos de acceso, se deberĆ” habilitar CloudTrail en todas las regiones y activar el registro de acceso de usuarios."}],"description": "Registro","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.acc.6.r5.aws.iam.2": {"name": "op.acc.6.r5.aws.iam.2","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.6.r5","DescripcionControl": "Habilitar la información de usuario sobre la fecha de Ćŗltimo uso de sus claves de acceso."}],"description": "Registro","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.6.r7.aws.iam.1": {"name": "op.acc.6.r7.aws.iam.1","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6.r7","DescripcionControl": "Activar la deshabilitación de las credenciales de los usuarios IAM que no hayan sido empleadas durante un periodo de tiempo (o bien, se deberĆ” establecer la deshabilitación en el proveedor de identidades)."}],"description": "Suspensión por no utilización","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"op.acc.6.r8.aws.iam.1": {"name": "op.acc.6.r8.aws.iam.1","checks": {"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6.r8","DescripcionControl": "Se deberĆ” emplear como mecanismo de autenticación o bien una contraseƱa mĆ”s otro factor de autenticación, o bien un certificado cualificado (con o sin soporte fĆ­sico) protegido por un doble factor de autenticación."}],"description": "Doble factor para acceso desde o a travĆ©s de zonas no controladas","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.acc.6.r9.aws.iam.1": {"name": "op.acc.6.r9.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.6.9","DescripcionControl": "DeberĆ” asegurarse que se estĆ” haciendo uso de HTTPS en todas las llamadas a API. Esto se puede lograr a travĆ©s de una polĆ­tica IAM que rechace el trĆ”fico que no sea HTTPS."}],"description": "Acceso remoto (todos los niveles)","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.6.r9.aws.iam.2": {"name": "op.acc.6.r9.aws.iam.2","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.6.9","DescripcionControl": "En caso de que las llamadas a las APIs no se produzcan de manera constante, se recomienda condicionar su realización a aquellas franjas horarias en las que sean necesarias. "}],"description": "Acceso remoto (todos los niveles)","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.1.r3.aws.tag.1": {"name": "op.exp.1.r3.aws.tag.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "opcional","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.1.r4","DescripcionControl": "Mantener actualizada una relación de los componentes software de terceros utilizados en el despliegue del sistema. Listado equivalente a lo requerido en mp.sw.1.r5."}],"description": "Lista de componentes software","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.3.r3.aws.cfg.1": {"name": "op.exp.3.r3.aws.cfg.1","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.3.r3","DescripcionControl": "La entidad usuaria puede consultar el histórico de configuraciones de recursos en AWS Config."}],"description": "Copias de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.3.r4.aws.cfg.2": {"name": "op.exp.3.r4.aws.cfg.2","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.3.r3","DescripcionControl": "Desplegar toda la infraestructura de AWS a travĆ©s de código con el servicio AWS CloudFormation."}],"description": "Copias de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.4.r2.aws.sys.1": {"name": "op.exp.4.r2.aws.sys.1","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.4.r2","DescripcionControl": "Utilizar la solución AWS Systems Manager Automation para automatizar las tareas de corrección en servicios de AWS como EC2 y RDS."}],"description": "Prevención de fallos","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.6.r1.aws.sys.1": {"name": "op.exp.6.r1.aws.sys.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.6.r1","DescripcionControl": "Automatizar las operaciones estĆ”ndar a llevar a cabo para la respuesta en caso de incidente a travĆ©s de AWS System Manager"}],"description": "Escaneo periódico","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.6.r3.aws.sys.1": {"name": "op.exp.6.r3.aws.sys.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.6.r3","DescripcionControl": "Hacer uso de AWS System Manager Inventory para definir, a nivel de software, una lista blanca de aplicaciones."}],"description": "Lista blanca","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.6.r4.aws.sys.1": {"name": "op.exp.6.r4.aws.sys.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.6.r4","DescripcionControl": "Automatizar tareas estĆ”ndar a travĆ©s de AWS System Manager"}],"description": "Capacidad de respuesta en caso de incidente","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.mon.3.r2.aws.cfg.1": {"name": "op.mon.3.r2.aws.cfg.1","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.3.r2","DescripcionControl": "Utilizar las herramientas AWS Config y Security hub"}],"description": "AnĆ”lisis dinĆ”mico","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.mon.3.r6.aws.cfg.1": {"name": "op.mon.3.r6.aws.cfg.1","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.3.r6","DescripcionControl": "Utilizar Config Rules y AWS Inspector"}],"description": "Inspecciones de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.4.r4.aws.insp.1": {"name": "op.exp.4.r4.aws.insp.1","checks": {"inspector2_is_enabled": "FAIL","inspector2_active_findings_exist": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "opcional","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.4.r4","DescripcionControl": "Desplegar a nivel de sistema una estrategia de monitorización continua de amenazas y vulnerabilidades detallando: indicadores crĆ­ticos de seguridad, polĆ­tica de aplicación de parches y criterios de revisión regular y excepcional de amenazas del sistema."}],"description": "Monitorización continua","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"op.mon.3.r2.aws.insp.1": {"name": "op.mon.3.r2.aws.insp.1","checks": {"inspector2_is_enabled": "FAIL","inspector2_active_findings_exist": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.3.r2","DescripcionControl": "Utilizar la herramienta Inspector para la detección de posibles vulneerabilidades de las instancias EC2, las funciones Lambda y las imĆ”genes de contenedor."}],"description": "AnĆ”lisis dinĆ”mico","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"op.mon.3.r6.aws.insp.1": {"name": "op.mon.3.r6.aws.insp.1","checks": {"inspector2_is_enabled": "FAIL","inspector2_active_findings_exist": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.3.r6","DescripcionControl": "Utilizar Config Rules y AWS Inspector."}],"description": "Inspecciones de seguridad","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"mp.info.6.r2.aws.bcku.1": {"name": "mp.info.6.r2.aws.bcku.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de la información","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.info.6.r2","DescripcionControl": "La organización puede hacer uso de la nube de AWS como ubicación diferente para el almacenamiento de la copia de seguridad separada del resto o, incluo, utilizar los servicios de ubicación para separar una copia de seguridad en una ubicación diferente dentro de la propia nube."}],"description": "Protección de las copias de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.1.r2.aws.sminv.1": {"name": "op.exp.1.r2.aws.sminv.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "opcional","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.1.r2","DescripcionControl": "Disponer de herramientas que permitan visualizar de forma continua el estado de todos los equipos en la red, en particular servidores y los dispositivos de red y comunicaciones."}],"description": "Identificación periódica de activos","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.s.4.r1.aws.shieldadv.1": {"name": "mp.s.4.r1.aws.shieldadv.1","checks": {"shield_advanced_protection_in_global_accelerators": null,"shield_advanced_protection_in_route53_hosted_zones": null,"shield_advanced_protection_in_associated_elastic_ips": null,"shield_advanced_protection_in_classic_load_balancers": null,"shield_advanced_protection_in_cloudfront_distributions": null,"shield_advanced_protection_in_internet_facing_load_balancers": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los servicios","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.s.4.r1","DescripcionControl": "Activar AWS Shield Advanced con el fin de disponer de una herramienta de prevención, detección y mitigación de ataques de denegación de servicio."}],"description": "Detección y reacción","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}}},"requirements_passed": 83,"requirements_failed": 37,"requirements_manual": 69,"total_requirements": 189,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "eeee198e-1eda-48dc-aeb6-eb28e98f8dde","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "kisa_isms_p_2023_korean_aws","framework": "KISA-ISMS-P","version": "2023-korean","description": "ISMS-P ģøģ¦ģ€ ķ•œźµ­ģøķ„°ė„·ģ§„ķ„ģ›(KISA)ģ“ ģ œģ •ķ•œ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계넼 기반으딜, ė…ė¦½ģ ģø ģ‹¬ģ‚¬źø°ź“€ģ“ źø°ģ—…ģ“ė‚˜ ģ”°ģ§ģ˜ ė³“ģ•ˆ ė° ź°œģøģ •ė³“ 볓호 ķ™œė™ģ“ ģøģ¦ źø°ģ¤€ģ„ ģ¶©ģ”±ķ•˜ėŠ”ģ§€ ķ‰ź°€ķ•œ 후 ģøģ¦ģ„ ė¶€ģ—¬ķ•˜ėŠ” ģ œė„ģž…ė‹ˆė‹¤. ģ“ė„¼ 통핓 źø°ģ—…ź³¼ źø°ź“€ģ€ ģ œź³µķ•˜ėŠ” ģ„œė¹„ģŠ¤ģ— ėŒ€ķ•œ ėŒ€ģ¤‘ģ˜ 신뢰넼 ė†’ģ“ź³ , 점점 ė³µģž”ķ•“ģ§€ėŠ” ģ‚¬ģ“ė²„ ģœ„ķ˜‘ģ— 효과적으딜 ėŒ€ģ‘ķ•  수 ģžˆģŠµė‹ˆė‹¤. ė˜ķ•œ, ISMS-PėŠ” ģ •ė³“ė³“ķ˜øģ™€ ź°œģøģ •ė³“ 볓호넼 ģ²“ź³„ģ ģœ¼ė”œ ģˆ˜ė¦½ķ•˜ź³  ģš“ģ˜ķ•  수 ģžˆėŠ” ķ¬ź“„ģ ģø ģ§€ģ¹Øģ„ ģ œź³µķ•©ė‹ˆė‹¤.","region": "eu-west-1","requirements": {"1.1.1": {"name": "ź²½ģ˜ģ§„ģ˜ ģ°øģ—¬","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.1.1 ź²½ģ˜ģ§„ģ˜ ģ°øģ—¬","Subdomain": "1.1. ꓀리첓계","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 볓고 첓계(ģ˜ģ‚¬ģ†Œķ†µź³„ķš 등)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģœ„ģ›ķšŒ ķšŒģ˜ė”","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 정책·지침(ź²½ģ˜ģ§„ ģŠ¹ģøė‚“ģ—­ ķ¬ķ•Ø)","ģ •ė³“ė³“ķ˜øź³„ķš ė° ė‚“ė¶€ ź“€ė¦¬ź³„ķš(ź²½ģ˜ģ§„ ģŠ¹ģøė‚“ģ—­ ķ¬ķ•Ø)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ”°ģ§ė„"],"AuditChecklist": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ź“€ė¦¬ģ²“ź³„ģ˜ 수립 ė° ģš“ģ˜ķ™œė™ ģ „ė°˜ģ— ź²½ģ˜ģ§„ģ˜ 참여가 ģ“ė£Øģ–“ģ§ˆ 수 ģžˆė„ė” 볓고 ė° ģ˜ģ‚¬ź²°ģ • ė“±ģ˜ ģ±…ģž„ź³¼ ģ—­ķ• ģ„ ė¬øģ„œķ™”ķ•˜ź³  ģžˆėŠ”ź°€?","ź²½ģ˜ģ§„ģ“ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ģ— ź“€ķ•œ ģ˜ģ‚¬ź²°ģ •ģ— 적극적으딜 참여할 수 ģžˆėŠ” 볓고, 검토 ė° ģŠ¹ģø 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…ģ„œģ— ė¶„źø°ė³„ė”œ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ˜„ķ™©ģ„ ź²½ģ˜ģ§„ģ—ź²Œ ė³“ź³ ķ•˜ė„ė” ėŖ…ģ‹œķ•˜ģ˜€ģœ¼ė‚˜, ģž„źø°ź°„ ꓀련 볓고넼 ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģ¤‘ģš” ģ •ė³“ė³“ķ˜ø ķ™œė™(ģœ„ķ—˜ķ‰ź°€, ģœ„ķ—˜ģˆ˜ģš©ģˆ˜ģ¤€ ź²°ģ •, ģ •ė³“ė³“ķ˜øėŒ€ģ±… ė° ģ“ķ–‰ź³„ķš 검토, ģ •ė³“ė³“ķ˜øėŒ€ģ±… ģ“ķ–‰ź²°ź³¼ 검토, ė³“ģ•ˆź°ģ‚¬ 등)ģ„ ģˆ˜ķ–‰ķ•˜ė©“ģ„œ ꓀련 ķ™œė™ź“€ė Ø 볓고, ģŠ¹ģø 등 ģ˜ģ‚¬ź²°ģ •ģ— ź²½ģ˜ģ§„ ė˜ėŠ” ź²½ģ˜ģ§„ģ˜ ź¶Œķ•œģ„ ģœ„ģž„ė°›ģ€ ģžź°€ ģ°øģ—¬ķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜ ꓀련 ģ¦ź±°ģžė£Œź°€ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ģµœź³ ź²½ģ˜ģžėŠ” ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ź“€ė¦¬ģ²“ź³„ģ˜ 수립과 ģš“ģ˜ķ™œė™ ģ „ė°˜ģ— ź²½ģ˜ģ§„ģ˜ 참여가 ģ“ė£Øģ–“ģ§ˆ 수 ģžˆė„ė” 볓고 ė° ģ˜ģ‚¬ź²°ģ • 첓계넼 ģˆ˜ė¦½ķ•˜ģ—¬ ģš“ģ˜ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.2": {"name": "ģµœź³ ģ±…ģž„ģžģ˜ 지정","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.1.2 ģµœź³ ģ±…ģž„ģžģ˜ 지정","Subdomain": "1.1. ꓀리첓계","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģž ģž„ėŖ…ź“€ė Ø ģžė£Œ(ģøģ‚¬ėŖ…ė ¹, ģøģ‚¬ģ¹“ė“œ 등)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ”°ģ§ė„","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 정책·지침","ģ§ė¬“źø°ģˆ ģ„œ(ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ˜ ģ—­ķ•  ė° ģ±…ģž„ģ— ź“€ķ•œ 사항)","ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ģ‹ ź³  ė‚“ģ—­","ė‚“ė¶€ ź“€ė¦¬ź³„ķš(ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģž 지정에 ź“€ķ•œ 사항)"],"AuditChecklist": ["ģµœź³ ź²½ģ˜ģžėŠ” ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ²˜ė¦¬ģ— ź“€ķ•œ 업묓넼 ģ“ź“„ķ•˜ģ—¬ ģ±…ģž„ģ§ˆ ģµœź³ ģ±…ģž„ģžė„¼ ź³µģ‹ģ ģœ¼ė”œ ģ§€ģ •ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžėŠ” ģ˜ˆģ‚°, ģøė „ 등 ģžģ›ģ„ 할당할 수 ģžˆėŠ” ģž„ģ›źø‰ģœ¼ė”œ ģ§€ģ •ķ•˜ź³  ģžˆģœ¼ė©°, ꓀련 법령에 따넸 ģžź²©ģš”ź±“ģ„ ģ¶©ģ”±ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ķ†µģ‹ ė§ė²•ģ— 따넸 ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž 지정 ė° ģ‹ ź³  ģ˜ė¬“ ėŒ€ģƒģžģž„ģ—ė„ ė¶ˆźµ¬ķ•˜ź³  ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģžė„¼ 지정 ė° ģ‹ ź³ ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ź°œģøģ •ė³“ ė³“ķ˜øģ™€ ź“€ė Øėœ ģ‹¤ģ§ˆģ ģø ź¶Œķ•œ ė° ģ§€ģœ„ė„¼ ė³“ģœ ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ ģøģ›ģ„ ź°œģøģ •ė³“ 볓호 ģ±…ģž„ģžė”œ ģ§€ģ •ķ•˜ź³  ģžˆģ–“, ź°œģøģ •ė³“ ģ²˜ė¦¬ģ— ź“€ķ•œ 업묓넼 ģ“ź“„ķ•“ģ„œ ģ±…ģž„ģ§ˆ 수 ģžˆė‹¤ź³  볓기 ģ–“ė ¤ģš“ 경우","사딀 3 : ģ”°ģ§ė„ģƒģ— ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžė„¼ ėŖ…ģ‹œķ•˜ź³  ģžˆģœ¼ė‚˜, ģøģ‚¬ė°œė ¹ ė“±ģ˜ ź³µģ‹ģ ģø ģ§€ģ •ģ ˆģ°Øė„¼ ź±°ģ¹˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ISMS ģøģ¦ ģ˜ė¬“ėŒ€ģƒģžģ“ė©“ģ„œ ģ „ė…„ė„ 말 기준 ģžģ‚°ģ“ģ•”ģ“ 5ģ²œģ–µ ģ›ģ„ ģ“ˆź³¼ķ•œ ģ •ė³“ķ†µģ‹ ģ„œė¹„ģŠ¤ ģ œź³µģžģ“ģ§€ė§Œ ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģžź°€ CIO넼 ź²øģ§ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“), 제31ģ”°(ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ˜ 지정)","ģ •ė³“ķ†µģ‹ ė§ė²• 제45ģ”°ģ˜3(ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģžģ˜ 지정 등)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ģµœź³ ź²½ģ˜ģžėŠ” ģ •ė³“ė³“ķ˜ø 업묓넼 ģ“ź“„ķ•˜ėŠ” ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģžģ™€ ź°œģøģ •ė³“ė³“ķ˜ø 업묓넼 ģ“ź“„ķ•˜ėŠ” ź°œģøģ •ė³“ė³“ķ˜ø ģ±…ģž„ģžė„¼ ģ˜ˆģ‚°Ā·ģøė „ 등 ģžģ›ģ„ 할당할 수 ģžˆėŠ” ģž„ģ›źø‰ģœ¼ė”œ ģ§€ģ •ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.3": {"name": "씰직 구성","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.1.3 씰직 구성","Subdomain": "1.1. ꓀리첓계","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģœ„ģ›ķšŒ ź·œģ •Ā·ķšŒģ˜ė”","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 실묓 ķ˜‘ģ˜ģ²“ ź·œģ •Ā·ķšŒģ˜ė”","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ”°ģ§ė„","ė‚“ė¶€ ź“€ė¦¬ź³„ķš","ģ§ė¬“źø°ģˆ ģ„œ"],"AuditChecklist": ["ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ˜ 업묓넼 ģ§€ģ›ķ•˜ź³  ģ”°ģ§ģ˜ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ģ„ ģ²“ź³„ģ ģœ¼ė”œ ģ“ķ–‰ķ•˜źø° ģœ„ķ•˜ģ—¬ ģ „ė¬øģ„±ģ„ ź°–ģ¶˜ ģ‹¤ė¬“ģ”°ģ§ģ„ źµ¬ģ„±ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","씰직 ģ „ė°˜ģ— 걸친 ģ¤‘ģš”ķ•œ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련사항에 ėŒ€ķ•˜ģ—¬ 검토, ģŠ¹ģø ė° ģ˜ģ‚¬ź²°ģ •ģ„ ķ•  수 ģžˆėŠ” ģœ„ģ›ķšŒė„¼ źµ¬ģ„±ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","전사적 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ģ„ ģœ„ķ•˜ģ—¬ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ė‹“ė‹¹ģž ė° ė¶€ģ„œė³„ ė‹“ė‹¹ģžė”œ źµ¬ģ„±ėœ 실묓 ķ˜‘ģ˜ģ²“ė„¼ źµ¬ģ„±ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģœ„ģ›ķšŒė„¼ źµ¬ģ„±ķ•˜ģ˜€ģœ¼ė‚˜, ģž„ģ› 등 ź²½ģ˜ģ§„ģ“ ķ¬ķ•Øė˜ģ–“ ģžˆģ§€ ģ•Šź³  실묓 ė¶€ģ„œģ˜ ģž„ģœ¼ė”œ źµ¬ģ„±ė˜ģ–“ ģžˆģ–“ ģ”°ģ§ģ˜ ģ¤‘ģš” 정볓 ė° ź°œģøģ •ė³“ ė³“ķ˜øģ— ź“€ķ•œ ģ‚¬ķ•­ģ„ ź²°ģ •ķ•  수 ģ—†ėŠ” 경우","사딀 2 : ė‚“ė¶€ 지침에 ė”°ė¼ ģ¤‘ģš” ģ •ė³“ģ²˜ė¦¬ ė¶€ģ„œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ ė¶€ģ„œģ˜ ģž„(ķŒ€ģž„źø‰)으딜 źµ¬ģ„±ėœ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 실묓 ķ˜‘ģ˜ģ²“ė„¼ źµ¬ģ„±ķ•˜ģ˜€ģœ¼ė‚˜, ģž„źø°ź°„ 욓영 ģ‹¤ģ ģ“ ģ—†ėŠ” 경우","사딀 3 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģœ„ģ›ķšŒė„¼ ź°œģµœķ•˜ģ˜€ģœ¼ė‚˜, ģ—°ź°„ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ź³„ķš ė° 교윔 ź³„ķš, ģ˜ˆģ‚° ė° ģøė „ 등 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜øģ— ź“€ķ•œ ģ£¼ģš” ģ‚¬ķ•­ģ“ 검토 ė° ģ˜ģ‚¬ź²°ģ •ģ“ ė˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ‹¬ģ˜Ā·ģ˜ź²°ģ„ ģœ„ķ•“ ģ •ė³“ė³“ķ˜øģœ„ģ›ķšŒė„¼ źµ¬ģ„±ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, 욓영 ė° ITė³“ģ•ˆ ꓀련 씰직만 ģ°øģ—¬ķ•˜ź³  ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ”°ģ§ģ€ ģ°øģ—¬ķ•˜ģ§€ ģ•Šź³  ģžˆģ–“ ź°œģøģ •ė³“ė³“ķ˜øģ— ź“€ķ•œ ģ‚¬ķ•­ģ„ ź²°ģ •ķ•  수 ģ—†ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ģµœź³ ź²½ģ˜ģžėŠ” ģ •ė³“ė³“ķ˜øģ™€ ź°œģøģ •ė³“ė³“ķ˜øģ˜ 효과적 źµ¬ķ˜„ģ„ ģœ„ķ•œ 실묓씰직, 씰직 ģ „ė°˜ģ˜ ģ •ė³“ė³“ķ˜øģ™€ ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ£¼ģš” ģ‚¬ķ•­ģ„ 검토 ė° ģ˜ź²°ķ•  수 ģžˆėŠ” ģœ„ģ›ķšŒ, 전사적 ė³“ķ˜øķ™œė™ģ„ ģœ„ķ•œ ė¶€ģ„œė³„ ģ •ė³“ė³“ķ˜øģ™€ ź°œģøģ •ė³“ė³“ķ˜ø ė‹“ė‹¹ģžė”œ źµ¬ģ„±ėœ ķ˜‘ģ˜ģ²“ė„¼ źµ¬ģ„±ķ•˜ģ—¬ ģš“ģ˜ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.4": {"name": "ė²”ģœ„ 설정","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.1.4 ė²”ģœ„ 설정","Subdomain": "1.1. ꓀리첓계","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ė²”ģœ„ ģ •ģ˜ģ„œ","ģ •ė³“ģžģ‚° ė° ź°œģøģ •ė³“ ėŖ©ė”","ė¬øģ„œ ėŖ©ė”","ģ„œė¹„ģŠ¤ ķė¦„ė„","ź°œģøģ •ė³“ ķė¦„ė„","전사 ģ”°ģ§ė„","ģ‹œģŠ¤ķ…œ ė° ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„"],"AuditChecklist": ["ģ”°ģ§ģ˜ 핵심 ģ„œė¹„ģŠ¤ ė° ź°œģøģ •ė³“ ģ²˜ė¦¬ģ— ģ˜ķ–„ģ„ 줄 수 ģžˆėŠ” ķ•µģ‹¬ģžģ‚°ģ„ ķ¬ķ•Øķ•˜ė„ė” ꓀리첓계 ė²”ģœ„ė„¼ ģ„¤ģ •ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ģ˜ėœ ė²”ģœ„ ė‚“ģ—ģ„œ ģ˜ˆģ™øģ‚¬ķ•­ģ“ ģžˆģ„ 경우 ėŖ…ķ™•ķ•œ ģ‚¬ģœ  ė° ź“€ė Øģž ķ˜‘ģ˜Ā·ģ±…ģž„ģž ģŠ¹ģø 등 ꓀련 근거넼 źø°ė”Ā·ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ė²”ģœ„ė„¼ ėŖ…ķ™•ķžˆ ķ™•ģøķ•  수 ģžˆė„ė” ź“€ė Øėœ ė‚“ģš©(ģ£¼ģš” ģ„œė¹„ģŠ¤ ė° 업묓 ķ˜„ķ™©, ģ •ė³“ģ‹œģŠ¤ķ…œ ėŖ©ė”, ė¬øģ„œėŖ©ė” 등)ģ“ ķ¬ķ•Øėœ ė¬øģ„œė„¼ ģž‘ģ„±ķ•˜ģ—¬ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ź°œė°œģ—…ė¬“ģ— ź“€ė Øķ•œ 개발 ė° ģ‹œķ—˜ ģ‹œģŠ¤ķ…œ, 외주업첓직원, PC, ķ…ŒģŠ¤ķŠøģš© 단말기 ė“±ģ“ ꓀리첓계 ė²”ģœ„ģ—ģ„œ ėˆ„ė½ėœ 경우","사딀 2 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ė²”ģœ„ė”œ ģ„¤ģ •ėœ ģ„œė¹„ģŠ¤ ė˜ėŠ” 사업에 ėŒ€ķ•˜ģ—¬ ģ¤‘ģš” ģ˜ģ‚¬ź²°ģ •ģž ģ—­ķ• ģ„ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ” ģž„ģ§ģ›, ģ‚¬ģ—…ė¶€ģ„œ ė“±ģ˜ 핵심 씰직(ģøė „)ģ„ ģøģ¦ė²”ģœ„ģ— ķ¬ķ•Øķ•˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ź°œė°œģ—…ė¬“ģ— ź“€ė Øķ•œ 개발 ė° ģ‹œķ—˜ ģ‹œģŠ¤ķ…œ, ź°œė°œģž PC, ķ…ŒģŠ¤ķŠøģš© 단말기, 개발씰직 ė“±ģ“ ꓀리첓계 ė²”ģœ„ģ—ģ„œ ėˆ„ė½ėœ 경우"],"RelatedRegulations": []}],"description": "ģ”°ģ§ģ˜ 핵심 ģ„œė¹„ģŠ¤ģ™€ ź°œģøģ •ė³“ 처리 ķ˜„ķ™© ė“±ģ„ ź³ ė ¤ķ•˜ģ—¬ ꓀리첓계 ė²”ģœ„ė„¼ ģ„¤ģ •ķ•˜ź³ , ź“€ė Øėœ ģ„œė¹„ģŠ¤ė„¼ ė¹„ė”Æķ•˜ģ—¬ ź°œģøģ •ė³“ 처리 업묓와 씰직, ģžģ‚°, 물리적 ģœ„ģ¹˜ ė“±ģ„ ė¬øģ„œķ™”ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.5": {"name": "ģ •ģ±… 수립","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.1.5 ģ •ģ±… 수립","Subdomain": "1.1. ꓀리첓계","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…Ā·ģ§€ģ¹ØĀ·ģ ˆģ°Øģ„œ(ģ œĀ·ź°œģ • ė‚“ģ—­ ķ¬ķ•Ø)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…Ā·ģ§€ģ¹Øģ ˆģ°Øģ„œ ģ œĀ·ź°œģ • ģ‹œ ģ“ķ•“ź“€ź³„ģž 검토 ķšŒģ˜ė”","ź°œģøģ •ė³“ ė‚“ė¶€ ź“€ė¦¬ź³„ķš","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 정책·지침 ģ œĀ·ź°œģ • 공지낓역(그룹웨얓, ģ‚¬ė‚“ź²Œģ‹œķŒ 등)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģœ„ģ›ķšŒ ķšŒģ˜ė”"],"AuditChecklist": ["ģ”°ģ§ģ“ ģˆ˜ķ–‰ķ•˜ėŠ” ėŖØė“  ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ģ˜ 근거넼 ķ¬ķ•Øķ•˜ėŠ” ģµœģƒģœ„ ģˆ˜ģ¤€ģ˜ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…ģ˜ ģ‹œķ–‰ģ„ ģœ„ķ•˜ģ—¬ ķ•„ģš”ķ•œ ģ„øė¶€ģ ģø 방법, 절차, 주기 ė“±ģ„ ź·œģ •ķ•œ 지침, 절차, 매뉓얼 ė“±ģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…Ā·ģ‹œķ–‰ė¬øģ„œģ˜ ģ œĀ·ź°œģ • ģ‹œ ģµœź³ ź²½ģ˜ģž ė˜ėŠ” ģµœź³ ź²½ģ˜ģžė”œė¶€ķ„° ź¶Œķ•œģ„ ģœ„ģž„ė°›ģ€ ģžģ˜ ģŠ¹ģøģ„ 받고 ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…Ā·ģ‹œķ–‰ė¬øģ„œģ˜ ģµœģ‹ ė³øģ„ ꓀련 ģž„ģ§ģ›ģ—ź²Œ ģ“ķ•“ķ•˜źø° ģ‰¬ģš“ ķ˜•ķƒœė”œ ģ œź³µķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ ź·œģ •ģ— ė”°ė„“ė©“ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…ģ„œ ģ œĀ·ź°œģ • ģ‹œģ—ėŠ” ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģœ„ģ›ķšŒģ˜ ģ˜ź²°ģ„ ź±°ģ¹˜ė„ė” ķ•˜ź³  ģžˆģœ¼ė‚˜, 최근 ģ •ģ±…ģ„œ ź°œģ • ģ‹œ ģœ„ģ›ķšŒģ— ģ•ˆź±“ģœ¼ė”œ ģƒģ •ķ•˜ģ§€ ģ•Šź³  ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ˜ ģŠ¹ģøģ„ 근거딜만 ź°œģ •ķ•œ 경우","사딀 2 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±… ė° ģ§€ģ¹Øģ„œź°€ ģµœź·¼ģ— ź°œģ •ė˜ģ—ˆģœ¼ė‚˜, 핓당 ģ‚¬ķ•­ģ“ ꓀련 ė¶€ģ„œ ė° ģž„ģ§ģ›ģ—ź²Œ ź³µģœ Ā·ģ „ė‹¬ė˜ģ§€ ģ•Šģ•„ ģ¼ė¶€ ė¶€ģ„œģ—ģ„œėŠ” źµ¬ė²„ģ „ģ˜ ģ§€ģ¹Øģ„œė„¼ źø°ģ¤€ģœ¼ė”œ 업묓넼 ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±… ė° ģ§€ģ¹Øģ„œė„¼ ė³“ģ•ˆė¶€ģ„œģ—ģ„œė§Œ ź“€ė¦¬ķ•˜ź³  ģžˆź³ , ģž„ģ§ģ›ģ“ ģ—“ėžŒķ•  수 ģžˆė„ė” ź²Œģ‹œķŒ, ė¬øģ„œ ė“±ģ˜ ė°©ė²•ģœ¼ė”œ ģ œź³µķ•˜ģ§€ ģ•ŠėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ģ •ė³“ė³“ķ˜øģ™€ ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±… ė° ģ‹œķ–‰ė¬øģ„œė„¼ ģˆ˜ė¦½Ā·ģž‘ģ„±ķ•˜ė©°, ģ“ė•Œ ģ”°ģ§ģ˜ ģ •ė³“ė³“ķ˜øģ™€ ź°œģøģ •ė³“ė³“ķ˜ø 방침 ė° ė°©ķ–„ģ„ ėŖ…ķ™•ķ•˜ź²Œ ģ œģ‹œķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ė˜ķ•œ ģ •ģ±…ź³¼ ģ‹œķ–‰ė¬øģ„œėŠ” ź²½ģ˜ģ§„ģ˜ ģŠ¹ģøģ„ 받고, ģž„ģ§ģ› ė° ź“€ė Øģžģ—ź²Œ ģ“ķ•“ķ•˜źø° ģ‰¬ģš“ ķ˜•ķƒœė”œ ģ „ė‹¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.6": {"name": "ģžģ› 할당","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.1.6 ģžģ› 할당","Subdomain": "1.1. ꓀리첓계","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ ģ—°ź°„ ģ¶”ģ§„ź³„ķšģ„œ(ģ˜ˆģ‚° ė° ģøė „ģš“ģ˜ź³„ķš)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ ź²°ź³¼ ė³“ź³ ģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķˆ¬ģž ė‚“ģ—­","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ”°ģ§ė„"],"AuditChecklist": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 분야별 ģ „ė¬øģ„±ģ„ ź°–ģ¶˜ ģøė „ģ„ ķ™•ė³“ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ź“€ė¦¬ģ²“ź³„ģ˜ 효과적 źµ¬ķ˜„ź³¼ ģ§€ģ†ģ  ģš“ģ˜ģ„ ģœ„ķ•˜ģ—¬ ķ•„ģš”ķ•œ ģžģ›ģ„ ķ‰ź°€ķ•˜ģ—¬ ķ•„ģš”ķ•œ ģ˜ˆģ‚°ź³¼ ģøė „ģ„ ģ§€ģ›ķ•˜ź³  ģžˆėŠ”ź°€?","ģ—°ė„ė³„ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 업묓 세부추진 ź³„ķšģ„ ģˆ˜ė¦½Ā·ģ‹œķ–‰ķ•˜ź³ , ź·ø 추진결과에 ėŒ€ķ•œ ģ‹¬ģ‚¬ė¶„ģ„Ā·ķ‰ź°€ė„¼ ģ‹¤ģ‹œķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ”°ģ§ģ„ źµ¬ģ„±ķ•˜ėŠ”ė°, 분야별 ģ „ė¬øģ„±ģ„ ź°–ģ¶˜ ģøė „ģ“ ģ•„ė‹Œ ģ •ė³“ė³“ķ˜ø ꓀련 ė˜ėŠ” IT ꓀련 ģ „ė¬øģ„±ģ“ ģ—†ėŠ” ģøģ›ģœ¼ė”œė§Œ ė³“ģ•ˆģøė „ģ„ źµ¬ģ„±ķ•œ 경우","사딀 2 : ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ źø°ģˆ ģ Ā·ź“€ė¦¬ģ  ė³“ķ˜øģ”°ģ¹˜ģ˜ ģš”ź±“ģ„ 갖추기 ģœ„ķ•œ ģµœģ†Œķ•œģ˜ ė³“ģ•ˆ ģ†”ė£Øģ…˜ ė„ģž…, ģ•ˆģ „ģ”°ģ¹˜ 적용 ė“±ģ„ ģœ„ķ•œ ė¹„ģš©ģ„ ģµœź³ ź²½ģ˜ģžź°€ ģ§€ģ›ķ•˜ģ§€ ģ•Šź³  ģžˆėŠ” 경우","사딀 3 : ģøģ¦ģ„ ģ·Øė“ķ•œ ģ“ķ›„ģ— ģøė „ź³¼ ģ˜ˆģ‚° ģ§€ģ›ģ„ ėŒ€ķ­ ģ¤„ģ“ź³  기씓 ģøė „ģ„ 다넸 ė¶€ģ„œė”œ ė°°ģ¹˜ķ•˜ź±°ė‚˜ ģ¼ė¶€ ģ˜ˆģ‚°ģ„ 다넸 ģš©ė„ė”œ ģ‚¬ģš©ķ•˜ėŠ” 경우"],"RelatedRegulations": []}],"description": "ģµœź³ ź²½ģ˜ģžėŠ” ģ •ė³“ė³“ķ˜øģ™€ ź°œģøģ •ė³“ė³“ķ˜ø 분야별 ģ „ė¬øģ„±ģ„ ź°–ģ¶˜ ģøė „ģ„ ķ™•ė³“ķ•˜ź³ , ź“€ė¦¬ģ²“ź³„ģ˜ 효과적 źµ¬ķ˜„ź³¼ ģ§€ģ†ģ  ģš“ģ˜ģ„ ģœ„ķ•œ ģ˜ˆģ‚° ė° ģžģ›ģ„ ķ• ė‹¹ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.2.1": {"name": "ģ •ė³“ģžģ‚° ģ‹ė³„","checks": {"macie_is_enabled": "PASS","resourceexplorer2_indexes_found": "PASS","config_recorder_all_regions_enabled": null,"organizations_account_part_of_organizations": null,"organizations_tags_policies_enabled_and_attached": null},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.2.1 ģ •ė³“ģžģ‚° ģ‹ė³„","Subdomain": "1.2. ģœ„ķ—˜ ꓀리","AuditEvidence": ["ģ •ė³“ģžģ‚° ė° ź°œģøģ •ė³“ ģžģ‚°ė¶„ė„˜ 기준","ģ •ė³“ģžģ‚° ė° ź°œģøģ •ė³“ ģžģ‚°ėŖ©ė”(ģžģ‚°ź“€ė¦¬ģ‹œģŠ¤ķ…œ 화멓)","ģ •ė³“ģžģ‚° ė° ź°œģøģ •ė³“ ė³“ģ•ˆė“±źø‰","ģžģ‚°ģ‹¤ģ‚¬ ė‚“ģ—­","ģœ„ķ—˜ė¶„ģ„ ė³“ź³ ģ„œ(ģžģ‚°ģ‹ė³„ ė‚“ģ—­)"],"AuditChecklist": ["ģ •ė³“ģžģ‚°ģ˜ ė¶„ė„˜źø°ģ¤€ģ„ ģˆ˜ė¦½ķ•˜ź³  ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ė²”ģœ„ ė‚“ģ˜ ėŖØė“  ģžģ‚°ģ„ ģ‹ė³„ķ•˜ģ—¬ ėŖ©ė”ģœ¼ė”œ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ‹ė³„ėœ ģ •ė³“ģžģ‚°ģ— ėŒ€ķ•˜ģ—¬ 법적 ģš”źµ¬ģ‚¬ķ•­ ė° 업묓에 ėÆøģ¹˜ėŠ” ģ˜ķ–„ ė“±ģ„ ź³ ė ¤ķ•˜ģ—¬ ģ¤‘ģš”ė„ė„¼ ź²°ģ •ķ•˜ź³  ė³“ģ•ˆė“±źø‰ģ„ ė¶€ģ—¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •źø°ģ ģœ¼ė”œ ģ •ė³“ģžģ‚° ķ˜„ķ™©ģ„ ģ”°ģ‚¬ķ•˜ģ—¬ ģ •ė³“ģžģ‚°ėŖ©ė”ģ„ ģµœģ‹ ģœ¼ė”œ ģœ ģ§€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ė²”ģœ„ ė‚“ģ˜ ģžģ‚° ėŖ©ė”ģ—ģ„œ ģ¤‘ģš”ģ •ė³“ ģ·Øźø‰ģž ė° ź°œģøģ •ė³“ ģ·Øźø‰ģž PC넼 ķ†µģ œķ•˜ėŠ” ė° ģ‚¬ģš©ė˜ėŠ” 출렄물 ė³“ģ•ˆ, ė¬øģ„œģ•”ķ˜øķ™”, USBė§¤ģ²“ģ œģ–“ ė“±ģ˜ 낓부정볓 ģœ ģ¶œķ†µģ œ ģ‹œģŠ¤ķ…œģ“ ėˆ„ė½ėœ 경우","사딀 2 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ė²”ģœ„ ė‚“ģ—ģ„œ 제3ģžė”œė¶€ķ„° ģ œź³µė°›ģ€ ź°œģøģ •ė³“ź°€ ģžˆģœ¼ė‚˜, 핓당 ź°œģøģ •ė³“ģ— ėŒ€ķ•œ ģžģ‚° ģ‹ė³„ģ“ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우","사딀 3 : ė‚“ė¶€ 지침에 ėŖ…ģ‹œėœ ģ •ė³“ģžģ‚° ė° ź°œģøģ •ė³“ ė³“ģ•ˆė“±źø‰ ė¶„ė„˜ 기준과 ģžģ‚°ź“€ė¦¬ ėŒ€ģž„ģ˜ ė¶„ė„˜ źø°ģ¤€ģ“ ģ¼ģ¹˜ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ģ˜Øķ”„ė ˆėÆøģŠ¤ ģžģ‚°ģ— ėŒ€ķ•“ģ„œėŠ” ģ‹ė³„ģ“ ģ“ė£Øģ–“ģ”Œģœ¼ė‚˜, 외부에 ģœ„ķƒķ•œ IT ģ„œė¹„ģŠ¤(ģ›¹ķ˜øģŠ¤ķŒ…, ģ„œė²„ķ˜øģŠ¤ķŒ…, ķ“ė¼ģš°ė“œ 등)에 ėŒ€ķ•œ ģžģ‚° ģ‹ė³„ģ“ ėˆ„ė½ėœ 경우(단, ģøģ¦ė²”ģœ„ ė‚“)","사딀 5 : ź³ ģœ ģ‹ė³„ģ •ė³“ 등 ź°œģøģ •ė³“ė„¼ ģ €ģž„ķ•˜ź³  ģžˆėŠ” ė°±ģ—…ģ„œė²„ģ˜ 기밀성 ė“±źø‰ģ„ (ķ•˜)딜 ģ‚°ģ •ķ•˜ėŠ” 등 ģ •ė³“ģžģ‚° ģ¤‘ģš”ė„ ķ‰ź°€ģ˜ 합리성 ė° ģ‹ ė¢°ģ„±ģ“ ėÆøķ”ķ•œ 경우"],"RelatedRegulations": []}],"description": "ģ”°ģ§ģ˜ ģ—…ė¬“ķŠ¹ģ„±ģ— ė”°ė¼ ģ •ė³“ģžģ‚° ė¶„ė„˜źø°ģ¤€ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ꓀리첓계 ė²”ģœ„ ė‚“ ėŖØė“  ģ •ė³“ģžģ‚°ģ„ ģ‹ė³„Ā·ė¶„ė„˜ķ•˜ź³ , ģ¤‘ģš”ė„ė„¼ ģ‚°ģ •ķ•œ 후 ź·ø ėŖ©ė”ģ„ ģµœģ‹ ģœ¼ė”œ ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 2,"total": 5,"manual": 0}},"1.2.2": {"name": "ķ˜„ķ™© ė° ķė¦„ė¶„ģ„","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.2.2 ķ˜„ķ™© ė° ķė¦„ė¶„ģ„","Subdomain": "1.2. ģœ„ķ—˜ ꓀리","AuditEvidence": ["ģ •ė³“ģ„œė¹„ģŠ¤ ķ˜„ķ™©ķ‘œ","ģ •ė³“ģ„œė¹„ģŠ¤ ģ—…ė¬“ķė¦„ķ‘œĀ·ģ—…ė¬“ķė¦„ė„","ź°œģøģ •ė³“ 처리 ķ˜„ķ™©ķ‘œ(ISMS-P ģøģ¦ģø 경우)","ź°œģøģ •ė³“ ķė¦„ķ‘œĀ·ķė¦„ė„(ISMS-P ģøģ¦ģø 경우)"],"AuditChecklist": ["꓀리첓계 ģ „ ģ˜ģ—­ģ— ėŒ€ķ•œ ģ •ė³“ģ„œė¹„ģŠ¤ ķ˜„ķ™©ģ„ ģ‹ė³„ķ•˜ź³  업묓 ģ ˆģ°Øģ™€ ķė¦„ģ„ ķŒŒģ•…ķ•˜ģ—¬ ė¬øģ„œķ™”ķ•˜ź³  ģžˆėŠ”ź°€?","꓀리첓계 ė²”ģœ„ ė‚“ ź°œģøģ •ė³“ 처리 ķ˜„ķ™©ģ„ ģ‹ė³„ķ•˜ź³  ź°œģøģ •ė³“ģ˜ ķė¦„ģ„ ķŒŒģ•…ķ•˜ģ—¬ ź°œģøģ •ė³“ ķė¦„ė„ ė“±ģœ¼ė”œ ė¬øģ„œķ™”ķ•˜ź³  ģžˆėŠ”ź°€?","ģ„œė¹„ģŠ¤ ė° 업묓, ģ •ė³“ģžģ‚° ė“±ģ˜ 변화에 따넸 ģ—…ė¬“ģ ˆģ°Ø ė° ź°œģøģ •ė³“ ķė¦„ģ„ 주기적으딜 ź²€ķ† ķ•˜ģ—¬ ķė¦„ė„ 등 ꓀련 ė¬øģ„œģ˜ ģµœģ‹ ģ„±ģ„ ģœ ģ§€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ꓀리첓계 ė²”ģœ„ ė‚“ ģ£¼ģš” ģ„œė¹„ģŠ¤ģ˜ 업묓 ģ ˆģ°ØĀ·ķė¦„ ė° ķ˜„ķ™©ģ— ė¬øģ„œķ™”ź°€ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우","사딀 2 : ź°œģøģ •ė³“ ķė¦„ė„ė„¼ ģž‘ģ„±ķ•˜ģ˜€ģœ¼ė‚˜, ģ‹¤ģ œ ź°œģøģ •ė³“ģ˜ ķė¦„ź³¼ ģƒģ“ķ•œ ė¶€ė¶„ģ“ ė‹¤ģˆ˜ ģ”“ģž¬ķ•˜ź±°ė‚˜ ģ¤‘ģš”ķ•œ ź°œģøģ •ė³“ ķė¦„ģ“ ėˆ„ė½ė˜ģ–“ ģžˆėŠ” 경우","사딀 3 : 최쓈 ź°œģøģ •ė³“ ķė¦„ė„ ģž‘ģ„± ģ“ķ›„ģ— ķ˜„ķ–‰ķ™”ź°€ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ•„ ė³€ķ™”ėœ ź°œģøģ •ė³“ ķė¦„ģ“ ķė¦„ė„ģ— ė°˜ģ˜ė˜ģ§€ ģ•Šź³  ģžˆėŠ” 경우"],"RelatedRegulations": []}],"description": "꓀리첓계 ģ „ ģ˜ģ—­ģ— ėŒ€ķ•œ ģ •ė³“ģ„œė¹„ģŠ¤ ė° ź°œģøģ •ė³“ 처리 ķ˜„ķ™©ģ„ ė¶„ģ„ķ•˜ź³  업묓 ģ ˆģ°Øģ™€ ķė¦„ģ„ ķŒŒģ•…ķ•˜ģ—¬ ė¬øģ„œķ™”ķ•˜ė©°, ģ“ė„¼ 주기적으딜 ź²€ķ† ķ•˜ģ—¬ ģµœģ‹ ģ„±ģ„ ģœ ģ§€ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.2.3": {"name": "ģœ„ķ—˜ ķ‰ź°€","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.2.3 ģœ„ķ—˜ ķ‰ź°€","Subdomain": "1.2. ģœ„ķ—˜ ꓀리","AuditEvidence": ["ģœ„ķ—˜ź“€ė¦¬ 지침","ģœ„ķ—˜ź“€ė¦¬ ė§¤ė‰“ģ–¼Ā·ź°€ģ“ė“œ","ģœ„ķ—˜ź“€ė¦¬ ź³„ķšģ„œ","ģœ„ķ—˜ķ‰ź°€ ź²°ź³¼ė³“ź³ ģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģœ„ģ›ķšŒ ķšŒģ˜ė”","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 실묓 ķ˜‘ģ˜ķšŒ ķšŒģ˜ė”","ģ •ė³“ģžģ‚° ė° ź°œģøģ •ė³“ģžģ‚° ėŖ©ė”","ģ •ė³“ģ„œė¹„ģŠ¤ ė° ź°œģøģ •ė³“ ķė¦„ķ‘œĀ·ķė¦„ė„"],"AuditChecklist": ["씰직 ė˜ėŠ” ģ„œė¹„ģŠ¤ģ˜ ķŠ¹ģ„±ģ— ė”°ė¼ ė‹¤ģ–‘ķ•œ ģø”ė©“ģ—ģ„œ ė°œģƒķ•  수 ģžˆėŠ” ģœ„ķ—˜ģ„ ģ‹ė³„ķ•˜ź³  ķ‰ź°€ķ•  수 ģžˆėŠ” ė°©ė²•ģ„ ģ •ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ģœ„ķ—˜ź“€ė¦¬ 방법 ė° 절차(ģˆ˜ķ–‰ģøė „, źø°ź°„, ėŒ€ģƒ, 방법, ģ˜ˆģ‚° 등)넼 źµ¬ģ²“ķ™”ķ•œ ģœ„ķ—˜ź“€ė¦¬ź³„ķšģ„ 매년 ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ģœ„ķ—˜ź“€ė¦¬ź³„ķšģ— ė”°ė¼ ģ—° 1회 ģ“ģƒ ģ •źø°ģ ģœ¼ė”œ ė˜ėŠ” ķ•„ģš”ķ•œ ģ‹œģ ģ— ģœ„ķ—˜ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ”°ģ§ģ—ģ„œ 수용 ź°€ėŠ„ķ•œ ėŖ©ķ‘œ ģœ„ķ—˜ģˆ˜ģ¤€ģ„ ģ •ķ•˜ź³ , ź·ø ģˆ˜ģ¤€ģ„ ģ“ˆź³¼ķ•˜ėŠ” ģœ„ķ—˜ģ„ ģ‹ė³„ķ•˜ź³  ģžˆėŠ”ź°€?","ģœ„ķ—˜ģ‹ė³„ ė° ķ‰ź°€ 결과넼 ź²½ģ˜ģ§„ģ—ź²Œ ė³“ź³ ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 수립된 ģœ„ķ—˜ź“€ė¦¬ź³„ķšģ„œģ— ģœ„ķ—˜ķ‰ź°€ źø°ź°„ ė° ģœ„ķ—˜ź“€ė¦¬ ėŒ€ģƒź³¼ ė°©ė²•ģ“ ģ •ģ˜ė˜ģ–“ ģžˆģœ¼ė‚˜, ģœ„ķ—˜ź“€ė¦¬ ģˆ˜ķ–‰ ģøė „ź³¼ ģ†Œģš” ģ˜ˆģ‚° 등 źµ¬ģ²“ģ ģø ģ‹¤ķ–‰ź³„ķšģ“ ėˆ„ė½ė˜ģ–“ ģžˆėŠ” 경우","사딀 2 : ģ „ė…„ė„ģ—ėŠ” ģœ„ķ—˜ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•˜ģ˜€ģœ¼ė‚˜, źøˆė…„ė„ģ—ėŠ” ģžģ‚° ė³€ź²½ģ“ ģ—†ģ—ˆė‹¤ėŠ” ģ‚¬ģœ ė”œ ģœ„ķ—˜ ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ģœ„ķ—˜ź“€ė¦¬ ź³„ķšģ— ė”°ė¼ ģœ„ķ—˜ ģ‹ė³„ ė° ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•˜ź³  ģžˆģœ¼ė‚˜, ė²”ģœ„ ė‚“ ģ¤‘ģš” ģ •ė³“ģžģ‚°ģ— ėŒ€ķ•œ ģœ„ķ—˜ ģ‹ė³„ ė° ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜, ģ •ė³“ė³“ķ˜ø ꓀련 법적 ģš”źµ¬ 사항 ģ¤€ģˆ˜ 여부에 따넸 ģœ„ķ—˜ģ„ ģ‹ė³„ ė° ķ‰ź°€ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ģœ„ķ—˜ź“€ė¦¬ ź³„ķšģ— ė”°ė¼ ģœ„ķ—˜ ģ‹ė³„ ė° ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•˜ź³  수용 ź°€ėŠ„ķ•œ ėŖ©ķ‘œ ģœ„ķ—˜ģˆ˜ģ¤€ģ„ ģ„¤ģ •ķ•˜ģ˜€ģœ¼ė‚˜, ꓀련 ģ‚¬ķ•­ģ„ ź²½ģ˜ģ§„(ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž 등)에 ė³“ź³ ķ•˜ģ—¬ ģŠ¹ģøė°›ģ§€ ģ•Šģ€ 경우","사딀 5 : ė‚“ė¶€ 지침에 ģ •ģ˜ķ•œ ģœ„ķ—˜ ķ‰ź°€ 방법과 ģ‹¤ģ œ ģˆ˜ķ–‰ķ•œ ģœ„ķ—˜ ķ‰ź°€ ė°©ė²•ģ“ ģƒģ“ķ•  경우","사딀 6 : ģ •ė³“ė³“ķ˜ø ꓀리첓계와 ź“€ė Øėœ ꓀리적·물리적 ģ˜ģ—­ģ˜ ģœ„ķ—˜ ģ‹ė³„ ė° ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šź³ , ė‹Øģˆœķžˆ 기술적 취약점진단 결과넼 ģœ„ķ—˜ ķ‰ź°€ 결과딜 ź°ˆģŒķ•˜ź³  ģžˆėŠ” 경우","사딀 7 : 수용 ź°€ėŠ„ķ•œ ėŖ©ķ‘œ ģœ„ķ—˜ģˆ˜ģ¤€(DoA)ģ„ ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ģ—†ģ“ ź³¼ė„ķ•˜ź²Œ ė†’ģ“ėŠ” 것으딜 결정함에 ė”°ė¼, ģ‹¤ģ§ˆģ ģœ¼ė”œ ėŒ€ģ‘ģ“ ķ•„ģš”ķ•œ ģ£¼ģš” ģœ„ķ—˜ė“¤ģ“ ģ”°ģ¹˜ź°€ ė¶ˆķ•„ģš”ķ•œ ģœ„ķ—˜(수용 ź°€ėŠ„ķ•œ ģœ„ķ—˜)으딜 ģ§€ģ •ėœ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ģ”°ģ§ģ˜ ėŒ€ė‚“ģ™ø ķ™˜ź²½ė¶„ģ„ģ„ ķ†µķ•˜ģ—¬ ģœ ķ˜•ė³„ ģœ„ķ˜‘ģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ź³  씰직에 ģ ķ•©ķ•œ ģœ„ķ—˜ ķ‰ź°€ ė°©ė²•ģ„ ģ„ ģ •ķ•˜ģ—¬ ꓀리첓계 ģ „ ģ˜ģ—­ģ— ėŒ€ķ•˜ģ—¬ ģ—° 1회 ģ“ģƒ ģœ„ķ—˜ģ„ ķ‰ź°€ķ•˜ė©°, ģˆ˜ģš©ķ•  수 ģžˆėŠ” ģœ„ķ—˜ģ€ ź²½ģ˜ģ§„ģ˜ ģŠ¹ģøģ„ 받아 ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.2.4": {"name": "ė³“ķ˜øėŒ€ģ±… ģ„ ģ •","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.2.4 ė³“ķ˜øėŒ€ģ±… ģ„ ģ •","Subdomain": "1.2. ģœ„ķ—˜ ꓀리","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ“ķ–‰ź³„ķšģ„œĀ·ģœ„ķ—˜ź“€ė¦¬ź³„ķšģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ėŒ€ģ±…ģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ė§ˆģŠ¤ķ„°ķ”Œėžœ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ“ķ–‰ź³„ķš ź²½ģ˜ģ§„ 볓고 ė° ģŠ¹ģø ė‚“ģ—­"],"AuditChecklist": ["ģ‹ė³„ėœ ģœ„ķ—˜ģ— ėŒ€ķ•œ 처리 ģ „ėžµ(ź°ģ†Œ, ķšŒķ”¼, ģ „ź°€, 수용 등)ģ„ ģˆ˜ė¦½ķ•˜ź³  ģœ„ķ—˜ģ²˜ė¦¬ė„¼ ģœ„ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģ„ ģ •ķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ķ˜øėŒ€ģ±…ģ˜ ģš°ģ„ ģˆœģœ„ė„¼ ź³ ė ¤ķ•˜ģ—¬ ģ¼ģ •, ė‹“ė‹¹ė¶€ģ„œ ė° ė‹“ė‹¹ģž, ģ˜ˆģ‚° ė“±ģ˜ ķ•­ėŖ©ģ„ ķ¬ķ•Øķ•œ ė³“ķ˜øėŒ€ģ±… ģ“ķ–‰ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ź³  ź²½ģ˜ģ§„ģ— ė³“ź³ ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ėŒ€ģ±…ģ— ėŒ€ķ•œ ģ“ķ–‰ź³„ķšģ€ ģˆ˜ė¦½ķ•˜ģ˜€ģœ¼ė‚˜, ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ—ź²Œ 볓고가 ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우","사딀 2 : ģœ„ķ—˜ź°ģ†Œź°€ ģš”źµ¬ė˜ėŠ” ģ¼ė¶€ ģœ„ķ—˜ģ˜ 씰치 ģ“ķ–‰ź³„ķšģ“ ėˆ„ė½ė˜ģ–“ ģžˆėŠ” 경우","사딀 3 : 법에 ė”°ė¼ ģ˜ė¬“ģ ģœ¼ė”œ ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•  사항, ė³“ģ•ˆ ģ·Øģ•½ģ„±ģ“ ė†’ģ€ ģœ„ķ—˜ ė“±ģ„ ė³„ė„ģ˜ 볓호씰치 ź³„ķš ģ—†ģ“ ģœ„ķ—˜ģˆ˜ģš©ģœ¼ė”œ ź²°ģ •ķ•˜ģ—¬ ģ”°ģ¹˜ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ģœ„ķ—˜ģˆ˜ģš©ģ— ėŒ€ķ•œ 근거와 ķƒ€ė‹¹ģ„±ģ“ ėÆøķ”ķ•˜ź³ , ģ‹œźø‰ģ„± ė° źµ¬ķ˜„ ģš©ģ“ģ„± ė“±ģ˜ ģø”ė©“ģ—ģ„œ ģ¦‰ģ‹œ ė˜ėŠ” 단기 ģ”°ģ¹˜ź°€ ź°€ėŠ„ķ•œ ģœ„ķ—˜ģš”ģøģ— ėŒ€ķ•“ģ„œė„ ķŠ¹ė³„ķ•œ ģ‚¬ģœ  ģ—†ģ“ ģž„źø° ģ”°ģ¹˜ź³„ķšģœ¼ė”œ ė¶„ė„˜ķ•œ 경우"],"RelatedRegulations": []}],"description": "ģœ„ķ—˜ ķ‰ź°€ 결과에 ė”°ė¼ ģ‹ė³„ėœ ģœ„ķ—˜ģ„ ģ²˜ė¦¬ķ•˜źø° ģœ„ķ•˜ģ—¬ 씰직에 ģ ķ•©ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģ„ ģ •ķ•˜ź³ , ė³“ķ˜øėŒ€ģ±…ģ˜ ģš°ģ„ ģˆœģœ„ģ™€ ģ¼ģ •Ā·ė‹“ė‹¹ģžĀ·ģ˜ˆģ‚° ė“±ģ„ ķ¬ķ•Øķ•œ ģ“ķ–‰ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ź²½ģ˜ģ§„ģ˜ ģŠ¹ģøģ„ 받아야 ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.3.1": {"name": "ė³“ķ˜øėŒ€ģ±… źµ¬ķ˜„","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.3.1 ė³“ķ˜øėŒ€ģ±… źµ¬ķ˜„","Subdomain": "1.3. ꓀리첓계 욓영","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ“ķ–‰ź³„ķšģ„œĀ·ģœ„ķ—˜ź“€ė¦¬ź³„ķšģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ėŒ€ģ±…ģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ“ķ–‰ź³„ķš ź²½ź³¼ė³“ź³ ģ„œ(ź²½ģ˜ģ§„ 볓고 ķ¬ķ•Ø)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ“ķ–‰ ģ™„ė£Œ ė³“ź³ ģ„œ(ź²½ģ˜ģ§„ 볓고 ķ¬ķ•Ø)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģš“ģ˜ėŖ…ģ„øģ„œ"],"AuditChecklist": ["ģ“ķ–‰ź³„ķšģ— ė”°ė¼ ė³“ķ˜øėŒ€ģ±…ģ„ 효과적으딜 źµ¬ķ˜„ķ•˜ź³  ģ“ķ–‰ź²°ź³¼ģ˜ 정확성 ė° ķšØź³¼ģ„± 여부넼 ź²½ģ˜ģ§„ģ“ ķ™•ģøķ•  수 ģžˆė„ė” ė³“ź³ ķ•˜ź³  ģžˆėŠ”ź°€?","꓀리첓계 ģøģ¦źø°ģ¤€ė³„ė”œ ė³“ķ˜øėŒ€ģ±… źµ¬ķ˜„ ė° 욓영 ķ˜„ķ™©ģ„ źø°ė”ķ•œ ģš“ģ˜ėŖ…ģ„øģ„œė„¼ 구첓적으딜 ģž‘ģ„±ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ėŒ€ģ±…ģ— ėŒ€ķ•œ ģ“ķ–‰ģ™„ė£Œ 결과넼 ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ—ź²Œ ė³“ź³ ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģœ„ķ—˜ģ”°ģ¹˜ ģ“ķ–‰ź²°ź³¼ė³“ź³ ģ„œėŠ” ʻ씰치 ģ™„ė£ŒŹ¼ė”œ ėŖ…ģ‹œė˜ģ–“ ģžˆģœ¼ė‚˜, ź“€ė Øėœ ģœ„ķ—˜ģ“ ģ—¬ģ „ķžˆ ģ”“ģž¬ķ•˜ź±°ė‚˜ ģ“ķ–‰ź²°ź³¼ģ˜ 정확성 ė° ķšØź³¼ģ„±ģ“ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ģ „ė…„ė„ ģ •ė³“ė³“ķ˜øėŒ€ģ±… ģ“ķ–‰ź³„ķšģ— ė”°ė¼ ģ¤‘Ā·ģž„źø°ė”œ ė¶„ė„˜ėœ ģœ„ķ—˜ė“¤ģ“ ķ•“ė‹¹ģ—°ė„ģ— źµ¬ķ˜„ģ“ 되고 ģžˆģ§€ ģ•Šź±°ė‚˜ ģ“ķ–‰ź²°ź³¼ė„¼ ź²½ģ˜ģ§„ģ“ 검토 ė° ķ™•ģøķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ģš“ģ˜ėŖ…ģ„øģ„œģ— ģž‘ģ„±ėœ 욓영 ķ˜„ķ™©ģ“ ģ‹¤ģ œģ™€ ģ¼ģ¹˜ķ•˜ģ§€ ģ•Šź³ , ģš“ėŖ…ėŖ…ģ„øģ„œģ— źø°ė”ė˜ģ–“ ģžˆėŠ” ꓀련 ė¬øģ„œ, ź²°ģž¬ ė‚“ģš©, ķšŒģ˜ė” ė“±ģ“ ģ”“ģž¬ķ•˜ģ§€ ģ•ŠėŠ” 경우","사딀 5 : ģ“ķ–‰ź³„ķš ģ‹œķ–‰ģ— ėŒ€ķ•œ 결과넼 ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ—ź²Œ ė³“ź³ ķ•˜ģ˜€ģœ¼ė‚˜, ģ¼ė¶€ ėÆøģ“ķ–‰ėœ 걓에 ėŒ€ķ•œ ģ‚¬ģœ  볓고 ė° ķ›„ģ† ģ”°ģ¹˜ź°€ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ģ„ ģ •ķ•œ ė³“ķ˜øėŒ€ģ±…ģ€ ģ“ķ–‰ź³„ķšģ— ė”°ė¼ 효과적으딜 źµ¬ķ˜„ķ•˜ź³ , ź²½ģ˜ģ§„ģ€ ģ“ķ–‰ź²°ź³¼ģ˜ 정확성과 ķšØź³¼ģ„± 여부넼 ķ™•ģøķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.3.2": {"name": "ė³“ķ˜øėŒ€ģ±… 공유","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.3.2 ė³“ķ˜øėŒ€ģ±… 공유","Subdomain": "1.3. ꓀리첓계 욓영","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ėŒ€ģ±…ė³„ ģš“ģ˜ė¶€ģ„œ ė˜ėŠ” ģ‹œķ–‰ė¶€ģ„œ ķ˜„ķ™©","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ ź“€ė¦¬ź³„ķš ė‚“ė¶€ź³µģœ  ģ¦ź±°ģžė£Œ(공지 ė‚“ģ—­, źµģœ”ģžė£Œ, 공유 ģžė£Œ 등)"],"AuditChecklist": ["źµ¬ķ˜„ėœ ė³“ķ˜øėŒ€ģ±…ģ„ 욓영 ė˜ėŠ” ģ‹œķ–‰ķ•  ė¶€ģ„œ ė° ė‹“ė‹¹ģžė„¼ ėŖ…ķ™•ķ•˜ź²Œ ķŒŒģ•…ķ•˜ź³  ģžˆėŠ”ź°€?","źµ¬ķ˜„ėœ ė³“ķ˜øėŒ€ģ±…ģ„ 욓영 ė˜ėŠ” ģ‹œķ–‰ķ•  ė¶€ģ„œ ė° ė‹“ė‹¹ģžģ—ź²Œ ꓀련 ė‚“ģš©ģ„ 공유 ė˜ėŠ” źµģœ”ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜øėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ģ—¬ źµ¬ķ˜„ķ•˜ź³  ģžˆģœ¼ė‚˜, ꓀련 ė‚“ģš©ģ„ ģ¶©ė¶„ķžˆ ź³µģœ Ā·źµģœ”ķ•˜ģ§€ ģ•Šģ•„ ģ‹¤ģ œ 욓영 ė˜ėŠ” ģˆ˜ķ–‰ ė¶€ģ„œ ė° ė‹“ė‹¹ģžź°€ 핓당 ė‚“ģš©ģ„ ģøģ§€ķ•˜ģ§€ ėŖ»ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": []}],"description": "ė³“ķ˜øėŒ€ģ±…ģ˜ ģ‹¤ģ œ 욓영 ė˜ėŠ” ģ‹œķ–‰ķ•  ė¶€ģ„œ ė° ė‹“ė‹¹ģžė„¼ ķŒŒģ•…ķ•˜ģ—¬ ꓀련 ė‚“ģš©ģ„ ź³µģœ ķ•˜ź³  źµģœ”ķ•˜ģ—¬ ģ§€ģ†ģ ģœ¼ė”œ ģš“ģ˜ė˜ė„ė” ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.3.3": {"name": "ģš“ģ˜ķ˜„ķ™© ꓀리","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.3.3 ģš“ģ˜ķ˜„ķ™© ꓀리","Subdomain": "1.3. ꓀리첓계 욓영","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ—°ź°„ź³„ķšģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģš“ģ˜ķ˜„ķ™©ķ‘œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ ģˆ˜ķ–‰ 여부 점검 ź²°ź³¼"],"AuditChecklist": ["꓀리첓계 ģš“ģ˜ģ„ ģœ„ķ•˜ģ—¬ 주기적 ė˜ėŠ” ģƒģ‹œģ ģœ¼ė”œ ģˆ˜ķ–‰ķ•˜ģ—¬ģ•¼ ķ•˜ėŠ” ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ģ„ ė¬øģ„œķ™”ķ•˜ģ—¬ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ź²½ģ˜ģ§„ģ€ 주기적으딜 ꓀리첓계 ģš“ģ˜ķ™œė™ģ˜ ķšØź³¼ģ„±ģ„ ķ™•ģøķ•˜ź³  ģ“ė„¼ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ģš“ģ˜ķ˜„ķ™© 중 주기적 ė˜ėŠ” ģƒģ‹œģ ģø ķ™œė™ģ“ ģš”źµ¬ė˜ėŠ” ķ™œė™ ķ˜„ķ™©ģ„ ė¬øģ„œķ™”ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ģš“ģ˜ķ˜„ķ™©ģ— ėŒ€ķ•œ ė¬øģ„œķ™”ėŠ” ģ“ė£Øģ–“ģ”Œģœ¼ė‚˜, 핓당 ģš“ģ˜ķ˜„ķ™©ģ— ėŒ€ķ•œ ģ£¼źø°ģ ģø 검토가 ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ•„ 월별 ė° 분기별 ķ™œė™ģ“ ģš”źµ¬ė˜ėŠ” ģ¼ė¶€ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ģ“ ėˆ„ė½ė˜ģ—ˆź³  ģ¼ė¶€ėŠ” ģ“ķ–‰ 여부넼 ķ™•ģøķ•  수 ģ—†ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제31ģ”°(ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ˜ 지정)","ģ •ė³“ķ†µģ‹ ė§ė²• 제45ģ”°ģ˜3(ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģžģ˜ 지정 등)"]}],"description": "ģ”°ģ§ģ“ ģˆ˜ė¦½ķ•œ ꓀리첓계에 ė”°ė¼ ģƒģ‹œģ  ė˜ėŠ” 주기적으딜 ģˆ˜ķ–‰ķ•˜ģ—¬ģ•¼ ķ•˜ėŠ” ģš“ģ˜ķ™œė™ ė° ģˆ˜ķ–‰ ė‚“ģ—­ģ€ ģ‹ė³„ ė° ģ¶”ģ ģ“ ź°€ėŠ„ķ•˜ė„ė” źø°ė”ķ•˜ģ—¬ ź“€ė¦¬ķ•˜ź³ , ź²½ģ˜ģ§„ģ€ 주기적으딜 ģš“ģ˜ķ™œė™ģ˜ ķšØź³¼ģ„±ģ„ ķ™•ģøķ•˜ģ—¬ ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.4.1": {"name": "법적 ģš”źµ¬ģ‚¬ķ•­ ģ¤€ģˆ˜ 검토","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.4.1 법적 ģš”źµ¬ģ‚¬ķ•­ ģ¤€ģˆ˜ 검토","Subdomain": "1.4. ꓀리첓계 점검 ė° ź°œģ„ ","AuditEvidence": ["법적 준거성 검토 ė‚“ģ—­","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 정책·지침 검토 ė° ź°œģ •ģ“ė „","정책·지침 ģ‹ źµ¬ėŒ€ģ”°ķ‘œ","법 ź°œģ •ģ‚¬ķ•­ ė‚“ė¶€ź³µģœ  ģžė£Œ","ź°œģøģ •ė³“ ģ†ķ•“ė°°ģƒ ģ±…ģž„ė³“ģž„ ģž…ģ¦ ģžė£Œ(ģ‚¬ģ“ė²„ė³“ķ—˜ ģ•½ģ •ģ„œ 등)","ģ •ė³“ė³“ķ˜ø ź³µģ‹œ ė‚“ģ—­"],"AuditChecklist": ["ģ”°ģ§ģ“ ģ¤€ģˆ˜ķ•˜ģ—¬ģ•¼ ķ•˜ėŠ” ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ķŒŒģ•…ķ•˜ģ—¬ ģµœģ‹ ģ„±ģ„ ģœ ģ§€ķ•˜ź³  ģžˆėŠ”ź°€?","법적 ģš”źµ¬ģ‚¬ķ•­ģ˜ ģ¤€ģˆ˜ 여부넼 ģ—° 1회 ģ“ģƒ ģ •źø°ģ ģœ¼ė”œ ź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ķ†µģ‹ ė§ė²• ė° ź°œģøģ •ė³“ ė³“ķ˜øė²•ģ“ 최근 ź°œģ •ė˜ģ—ˆģœ¼ė‚˜ ź°œģ •ģ‚¬ķ•­ģ“ 씰직에 ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ź²€ķ† ķ•˜ģ§€ ģ•Šģ•˜ģœ¼ė©°, ģ •ģ±…ģ„œĀ·ģ‹œķ–‰ė¬øģ„œ ė° 법적준거성 첓크리스트 ė“±ģ—ė„ 핓당 ė‚“ģš©ģ„ ė°˜ģ˜ķ•˜ģ§€ ģ•Šģ•„ ģ •ģ±…ģ„œĀ·ģ‹œķ–‰ė¬øģ„œ ė° 법적준거성 첓크리스트 ė“±ģ˜ ė‚“ģš©ģ“ 법령 ė‚“ģš©ź³¼ ģ¼ģ¹˜ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģ”°ģ§ģ—ģ„œ ģ¤€ģˆ˜ķ•˜ģ—¬ģ•¼ ķ•  ė²•ė„ ģ“ ź°œģ •ė˜ģ—ˆģœ¼ė‚˜, 핓당 법넠 준거성 검토넼 ģž„źø°ź°„ ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 3 : 법적 준거성 ģ¤€ģˆ˜ 여부에 ėŒ€ķ•œ 검토가 ģ ģ ˆķžˆ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ•„ ź°œģøģ •ė³“ ė³“ķ˜øė²• 등 ė²•ź·œ ģœ„ė°˜ ģ‚¬ķ•­ģ“ ė‹¤ģˆ˜ 발견된 경우","사딀 4 : ź°œģøģ •ė³“ ė³“ķ˜øė²•ģ— ė”°ė¼ ź°œģøģ •ė³“ ģ†ķ•“ė°°ģƒģ±…ģž„ ė³“ģž„ģ œė„ 적용 ėŒ€ģƒģ“ ė˜ģ—ˆģœ¼ė‚˜, ģ“ė„¼ ģøģ§€ķ•˜ģ§€ ėŖ»ķ•˜ģ—¬ ė³“ķ—˜ ź°€ģž…ģ“ė‚˜ ģ¤€ė¹„źøˆ ģ ė¦½ģ„ ķ•˜ģ§€ ģ•Šģ€ 경우 ė˜ėŠ” ė³“ķ—˜ ź°€ģž…ģ„ ķ•˜ģ˜€ģœ¼ė‚˜ ģ“ģš©ģž 수 ė° ė§¤ģ¶œģ•”ģ— 따넸 ģµœģ €ź°€ģž…źøˆģ•” źø°ģ¤€ģ„ ģ¤€ģˆ˜ķ•˜ģ§€ ėŖ»ķ•œ 경우","사딀 5 : ģ •ė³“ė³“ķ˜ø ź³µģ‹œ ģ˜ė¬“ėŒ€ģƒ ģ‚¬ģ—…ģžģ“ģ§€ė§Œ 법에 ģ •ķ•œ ģ‹œģ  낓에 ģ •ė³“ė³“ķ˜ø ź³µģ‹œź°€ ģ‹œķ–‰ė˜ģ§€ ģ•Šģ€ 경우","사딀 6 : ėŖØė°”ģ¼ģ•±ģ„ 통핓 ģœ„ģ¹˜ģ •ė³“ģ‚¬ģ—…ģžė”œė¶€ķ„° ģ“ģš©ģžģ˜ ź°œģøģœ„ģ¹˜ģ •ė³“ė„¼ 전솔받아 ģ„œė¹„ģŠ¤ģ— ģ“ģš©ķ•˜ź³  ģžˆģœ¼ė‚˜, ģœ„ģ¹˜źø°ė°˜ģ„œė¹„ģŠ¤ģ‚¬ģ—… 신고넼 ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 7 : 국낓에 ģ£¼ģ†Œ ė˜ėŠ” ģ˜ģ—…ģ†Œź°€ ģ—†ėŠ” ź°œģøģ •ė³“ģ²˜ė¦¬ģžė”œģ„œ ģ „ė…„ė„ 말 기준 직전 3ź°œģ›” ź°„ ź·ø ź°œģøģ •ė³“ź°€ ģ €ģž„Ā·ź“€ė¦¬ė˜ź³  ģžˆėŠ” źµ­ė‚“ ģ •ė³“ģ£¼ģ²“ģ˜ ģˆ˜ź°€ ģ¼ģ¼ķ‰ź·  100ė§ŒėŖ… ģ“ģƒģø ģžģ— ķ•“ė‹¹ė˜ģ–“ źµ­ė‚“ėŒ€ė¦¬ģø ģ§€ģ •ģ˜ė¬“ģ— ķ•“ė‹¹ėØģ—ė„ ė¶ˆźµ¬ķ•˜ź³ , źµ­ė‚“ėŒ€ė¦¬ģøģ„ ė¬øģ„œė”œ ģ§€ģ •ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ģ”°ģ§ģ“ ģ¤€ģˆ˜ķ•˜ģ—¬ģ•¼ ķ•  ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ 주기적으딜 ķŒŒģ•…ķ•˜ģ—¬ ź·œģ •ģ— ė°˜ģ˜ķ•˜ź³ , ģ¤€ģˆ˜ 여부넼 ģ§€ģ†ģ ģœ¼ė”œ ź²€ķ† ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.4.2": {"name": "꓀리첓계 점검","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.4.2 ꓀리첓계 점검","Subdomain": "1.4. ꓀리첓계 점검 ė° ź°œģ„ ","AuditEvidence": ["꓀리첓계 점검 ź³„ķšģ„œ(낓부점검 ź³„ķšģ„œ, 낓부감사 ź³„ķšģ„œ)","꓀리첓계 점검 ź²°ź³¼ė³“ź³ ģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģœ„ģ›ķšŒ ķšŒģ˜ė”"],"AuditChecklist": ["법적 ģš”źµ¬ģ‚¬ķ•­ ė° 수립된 정책에 ė”°ė¼ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계가 효과적으딜 ģš“ģ˜ė˜ėŠ”ģ§€ė„¼ ģ ź²€ķ•˜źø° ģœ„ķ•œ ꓀리첓계 점검기준, ė²”ģœ„, 주기, ģ ź²€ģøė „ ģžź²©ģš”ź±“ ė“±ģ„ ķ¬ķ•Øķ•œ ꓀리첓계 점검 ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","꓀리첓계 점검 ź³„ķšģ— ė”°ė¼ ė…ė¦½ģ„±, ź°ź“€ģ„± ė° ģ „ė¬øģ„±ģ“ ķ™•ė³“ėœ ģøė „ģ„ źµ¬ģ„±ķ•˜ģ—¬ ģ—° 1회 ģ“ģƒ ģ ź²€ģ„ ģˆ˜ķ–‰ķ•˜ź³  발견된 ė¬øģ œģ ģ„ ź²½ģ˜ģ§„ģ—ź²Œ ė³“ź³ ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ꓀리첓계 점검 ģøė „ģ— 점검 ėŒ€ģƒģœ¼ė”œ ģ‹ė³„ėœ ģ „ģ‚°ķŒ€ ģ§ģ›ģ“ ķ¬ķ•Øė˜ģ–“ ģ „ģ‚°ķŒ€ ꓀리 ģ˜ģ—­ģ— ėŒ€ķ•œ 점검에 ź“€ģ—¬ķ•˜ź³  ģžˆģ–“, ģ ź²€ģ˜ ė…ė¦½ģ„±ģ“ ķ›¼ģ†ėœ 경우","사딀 2 : źøˆė…„ė„ ꓀리첓계 ģ ź²€ģ„ ģ‹¤ģ‹œķ•˜ģ˜€ģœ¼ė‚˜, ģ ź²€ė²”ģœ„ź°€ ģ¼ė¶€ ģ˜ģ—­ģ— źµ­ķ•œė˜ģ–“ ģžˆģ–“ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ė²”ģœ„ė„¼ ģ¶©ģ”±ķ•˜ģ§€ ėŖ»ķ•œ 경우","사딀 3 : ꓀리첓계 ģ ź²€ķŒ€ģ“ ģœ„ķ—˜ķ‰ź°€ ė˜ėŠ” 취약점 점검 등 ꓀리첓계 구축 과정에 ģ°øģ—¬ķ•œ ė‚“ė¶€ 직원 ė° 외부 ģ»Øģ„¤ķ„“ķŠøė”œė§Œ źµ¬ģ„±ė˜ģ–“, ģ ź²€ģ˜ ė…ė¦½ģ„±ģ“ ķ™•ė³“ė˜ģ—ˆė‹¤ź³  ė³¼ 수 ģ—†ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "꓀리첓계가 ė‚“ė¶€ ģ •ģ±… ė° 법적 ģš”źµ¬ģ‚¬ķ•­ģ— ė”°ė¼ 효과적으딜 욓영되고 ģžˆėŠ”ģ§€ ė…ė¦½ģ„±ź³¼ ģ „ė¬øģ„±ģ“ ķ™•ė³“ėœ ģøė „ģ„ źµ¬ģ„±ķ•˜ģ—¬ ģ—° 1회 ģ“ģƒ ģ ź²€ķ•˜ź³ , 발견된 ė¬øģ œģ ģ„ ź²½ģ˜ģ§„ģ—ź²Œ ė³“ź³ ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.4.3": {"name": "꓀리첓계 ź°œģ„ ","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.4.3 ꓀리첓계 ź°œģ„ ","Subdomain": "1.4. ꓀리첓계 점검 ė° ź°œģ„ ","AuditEvidence": ["꓀리첓계 점검 ź²°ź³¼ė³“ź³ ģ„œ","꓀리첓계 점검 ģ”°ģ¹˜ź³„ķšģ„œĀ·ģ“ķ–‰ģ”°ģ¹˜ź²°ź³¼ģ„œ","ģž¬ė°œė°©ģ§€ ėŒ€ģ±…","ķšØź³¼ģ„± 츔정 ģ§€ķ‘œ ė° 츔정 ź²°ź³¼(ź²½ģ˜ģ§„ 볓고 ķ¬ķ•Ø)"],"AuditChecklist": ["법적 ģš”źµ¬ģ‚¬ķ•­ ģ¤€ģˆ˜ź²€ķ†  ė° ꓀리첓계 ģ ź²€ģ„ ķ†µķ•˜ģ—¬ ģ‹ė³„ėœ ź“€ė¦¬ģ²“ź³„ģƒģ˜ ė¬øģ œģ ģ— ėŒ€ķ•œ 근본 ģ›ģøģ„ ė¶„ģ„ķ•˜ģ—¬ ģž¬ė°œė°©ģ§€ ė° ź°œģ„  ėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģž¬ė°œė°©ģ§€ ė° ź°œģ„  ź²°ź³¼ģ˜ 정확성 ė° ķšØź³¼ģ„± 여부넼 ķ™•ģøķ•˜źø° ģœ„ķ•œ 기준과 절차넼 ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ģ ź²€ģ„ ķ†µķ•˜ģ—¬ 발견된 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 욓영상 ė¬øģ œģ ģ“ 매번 ė™ģ¼ķ•˜ź²Œ ė°˜ė³µė˜ģ–“ ė°œģƒė˜ėŠ” 경우","사딀 2 : ė‚“ė¶€ ź·œģ •ģ—ėŠ” 낓부점검 ģ‹œ 발견된 ė¬øģ œģ ģ— ėŒ€ķ•“ģ„œėŠ” ź·¼ė³øģ›ģøģ— ėŒ€ķ•œ ė¶„ģ„ ė° ģž¬ė°œė°©ģ§€ ėŒ€ģ±…ģ„ ģˆ˜ė¦½ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ģµœź·¼ģ— ģˆ˜ķ–‰ėœ ė‚“ė¶€ģ ź²€ģ—ģ„œėŠ” 발견된 ė¬øģ œģ ģ— ėŒ€ķ•˜ģ—¬ ź·¼ė³øģ›ģø ė¶„ģ„ ė° ģž¬ė°œė°©ģ§€ ėŒ€ģ±…ģ“ ģˆ˜ė¦½ė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ź“€ė¦¬ģ²“ź³„ģƒ ė¬øģ œģ ģ— ėŒ€ķ•œ ģž¬ė°œė°©ģ§€ ėŒ€ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ķ•µģ‹¬ģ„±ź³¼ģ§€ķ‘œė„¼ ė§ˆė Øķ•˜ģ—¬ 주기적으딜 ģø”ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, ź·ø 결과에 ėŒ€ķ•˜ģ—¬ ź²½ģ˜ģ§„ 볓고가 ģž„źø°ź°„ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우","사딀 4 : ꓀리첓계 점검 ģ‹œ 발견된 ė¬øģ œģ ģ— ėŒ€ķ•˜ģ—¬ ģ”°ģ¹˜ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜ 씰치 ģ™„ė£Œ 여부넼 ķ™•ģøķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "법적 ģš”źµ¬ģ‚¬ķ•­ ģ¤€ģˆ˜ź²€ķ†  ė° ꓀리첓계 ģ ź²€ģ„ ķ†µķ•˜ģ—¬ ģ‹ė³„ėœ ź“€ė¦¬ģ²“ź³„ģƒģ˜ ė¬øģ œģ ģ— ėŒ€ķ•œ ģ›ģøģ„ ė¶„ģ„ķ•˜ź³  ģž¬ė°œė°©ģ§€ ėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•˜ė©°, ź²½ģ˜ģ§„ģ€ ź°œģ„  ź²°ź³¼ģ˜ 정확성과 ķšØź³¼ģ„± 여부넼 ķ™•ģøķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.1.1": {"name": "ģ •ģ±…ģ˜ ģœ ģ§€ź“€ė¦¬","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.1.1 ģ •ģ±…ģ˜ ģœ ģ§€ź“€ė¦¬","Subdomain": "2.1. ģ •ģ±…, 씰직, ģžģ‚° ꓀리","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±… ė° ģ‹œķ–‰ė¬øģ„œ(지침, 절차, ź°€ģ“ė“œ, 매뉓얼 등)","정책·지침 정기·비정기 ķƒ€ė‹¹ģ„± 검토 ź²°ź³¼","정책·지침 ꓀련 ė¶€ģ„œģ™€ģ˜ 검토 ķšŒģ˜ė”, ķšŒėžŒė‚“ģš©","정책·지침 ģ œĀ·ź°œģ • ģ“ė „"],"AuditChecklist": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ •ģ±… ė° ģ‹œķ–‰ė¬øģ„œģ— ėŒ€ķ•œ ģ •źø°ģ ģø ķƒ€ė‹¹ģ„± 검토 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ”°ģ§ģ˜ ėŒ€ė‚“ģ™ø ķ™˜ź²½ģ— ģ¤‘ėŒ€ķ•œ 변화 ė°œģƒ ģ‹œ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ •ģ±… ė° ģ‹œķ–‰ė¬øģ„œģ— ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ź²€ķ† ķ•˜ź³  ķ•„ģš”ģ‹œ ģ œĀ·ź°œģ •ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ •ģ±… ė° ģ‹œķ–‰ė¬øģ„œģ˜ ģ œĀ·ź°œģ • ģ‹œ ģ“ķ•“ ź“€ź³„ģžģ˜ 검토넼 받고 ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ •ģ±… ė° ģ‹œķ–‰ė¬øģ„œģ˜ ģ œĀ·ź°œģ • 낓역에 ėŒ€ķ•˜ģ—¬ ģ“ė „ź“€ė¦¬ė„¼ ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ§€ģ¹Øģ„œģ™€ ģ ˆģ°Øģ„œ ź°„ ķŒØģŠ¤ģ›Œė“œ 설정 ź·œģ¹™ģ— ģ¼ź“€ģ„±ģ“ ģ—†ėŠ” 경우","사딀 2 : ģ •ė³“ė³“ķ˜ø ķ™œė™(ģ •ė³“ė³“ķ˜ø 교윔, ģ•”ķ˜øķ™”, 백업 등)ģ˜ ėŒ€ģƒ, 주기, ģˆ˜ģ¤€, 방법 ė“±ģ“ ꓀련 ė‚“ė¶€ ź·œģ •, 지침, ģ ˆģ°Øģ— ģ„œė”œ ė‹¤ė„“ź²Œ ėŖ…ģ‹œė˜ģ–“ ģ¼ź“€ģ„±ģ“ ģ—†ėŠ” 경우","사딀 3 : ė°ģ“ķ„°ė² ģ“ģŠ¤ģ— ėŒ€ķ•œ ģ ‘ź·¼ ė° ģž‘ģ—…ģ“ė „ģ„ 효과적으딜 źø°ė” ė° ź“€ė¦¬ķ•˜źø° ģœ„ķ•˜ģ—¬ ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ķ†µģ œ ģ†”ė£Øģ…˜ģ„ ģ‹ ź·œė”œ ė„ģž…ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, ė³“ģ•ˆģ‹œģŠ¤ķ…œ ė³“ģ•ˆ ꓀리지침 ė° ė°ģ“ķ„°ė² ģ“ģŠ¤ ė³“ģ•ˆ ꓀리지침 등 ė‚“ė¶€ ė³“ģ•ˆģ§€ģ¹Øģ— ģ ‘ź·¼ķ†µģ œ, ģž‘ģ—…ģ“ė „, ė”œź¹…, 검토 등에 ź“€ķ•œ ģ‚¬ķ•­ģ“ ė°˜ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…ģ“ ź°œģ •ė˜ģ—ˆģœ¼ė‚˜ ģ •ģ±… ģ‹œķ–‰ źø°ģ¤€ģ¼ģ“ ėŖ…ģ‹œė˜ģ–“ ģžˆģ§€ ģ•Šģœ¼ė©°, ꓀련 ģ •ģ±…ģ˜ ģž‘ģ„±ģ¼, ģž‘ģ„±ģž ė° ģŠ¹ģøģž ė“±ģ“ ėˆ„ė½ė˜ģ–“ ģžˆėŠ” 경우","사딀 5 : ź°œģøģ •ė³“ 볓호 ꓀련 법령, ź³ ģ‹œ 등에 ģ¤‘ėŒ€ķ•œ ė³€ź²½ģ‚¬ķ•­ģ“ ė°œģƒķ•˜ģ˜€ģœ¼ė‚˜, ģ“ėŸ¬ķ•œ ė³€ź²½ģ“ ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±… ė° ģ‹œķ–‰ė¬øģ„œģ— ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ź²€ķ† ķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜ ė³€ź²½ģ‚¬ķ•­ģ„ ė°˜ģ˜ķ•˜ģ—¬ ź°œģ •ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ •ģ±…ź³¼ ģ‹œķ–‰ė¬øģ„œėŠ” 법령 ė° 규제, ģƒģœ„ 씰직 ė° ꓀련 źø°ź“€ ģ •ģ±…ź³¼ģ˜ 연계성, ģ”°ģ§ģ˜ ėŒ€ė‚“ģ™ø ķ™˜ź²½ė³€ķ™” 등에 ė”°ė¼ 주기적으딜 ź²€ķ† ķ•˜ģ—¬ ķ•„ģš”ķ•œ 경우 ģ œĀ·ź°œģ •ķ•˜ź³  ź·ø ė‚“ģ—­ģ„ ģ“ė „ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.1.2": {"name": "ģ”°ģ§ģ˜ ģœ ģ§€ź“€ė¦¬","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.1.2 ģ”°ģ§ģ˜ ģœ ģ§€ź“€ė¦¬","Subdomain": "2.1. ģ •ģ±…, 씰직, ģžģ‚° ꓀리","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ”°ģ§ė„","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 씰직 ģ§ė¬“źø°ģˆ ģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 업묓 ė¶„ģž„ķ‘œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 정책·지침, ė‚“ė¶€ ź“€ė¦¬ź³„ķš","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ˜ģ‚¬ģ†Œķ†µ ź“€ė¦¬ź³„ķš","ģ˜ģ‚¬ģ†Œķ†µ ģˆ˜ķ–‰ ģ“ė „(월간볓고, 주간볓고, 낓부공지 등)","ģ˜ģ‚¬ģ†Œķ†µ 채널(ģ •ė³“ė³“ķ˜øķ¬ķ„ø, ź²Œģ‹œķŒ 등)"],"AuditChecklist": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ±…ģž„ģžģ™€ ė‹“ė‹¹ģžģ˜ ģ—­ķ•  ė° ģ±…ģž„ģ„ ėŖ…ķ™•ķžˆ ģ •ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ±…ģž„ģžģ™€ ė‹“ė‹¹ģžģ˜ ķ™œė™ģ„ ķ‰ź°€ķ•  수 ģžˆėŠ” 첓계넼 ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 씰직 ė° ģ”°ģ§ģ˜ 구성원 ź°„ 상호 ģ˜ģ‚¬ģ†Œķ†µķ•  수 ģžˆėŠ” 첓계 ė° 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ 지침 ė° ģ§ė¬“źø°ģˆ ģ„œģ— ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž, ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģž ė° ꓀련 ė‹“ė‹¹ģžģ˜ ģ—­ķ• ź³¼ ģ±…ģž„ģ„ ģ •ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ‹¤ģ œ ģš“ģ˜ķ˜„ķ™©ź³¼ ģ¼ģ¹˜ķ•˜ģ§€ ģ•ŠėŠ” 경우","사딀 2 : ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ꓀련 ė‹“ė‹¹ģžģ˜ ķ™œė™ģ„ 주기적으딜 ķ‰ź°€ķ•  수 ģžˆėŠ” ėŖ©ķ‘œ, 기준, ģ§€ķ‘œ ė“±ģ˜ 첓계가 ė§ˆė Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ė‚“ė¶€ ģ§€ģ¹Øģ—ėŠ” ė¶€ģ„œė³„ ģ •ė³“ė³“ķ˜ø ė‹“ė‹¹ģžėŠ” ģ •ė³“ė³“ķ˜øģ™€ ź“€ė Øėœ KPI넼 ģ„¤ģ •ķ•˜ģ—¬ ģøģ‚¬ķ‰ź°€ ģ‹œ ė°˜ģ˜ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ė¶€ģ„œė³„ ģ •ė³“ė³“ķ˜ø ė‹“ė‹¹ģžģ˜ KPI에 ģ •ė³“ė³“ķ˜øģ™€ ź“€ė Øėœ ģ‚¬ķ•­ģ“ ģ „ķ˜€ ė°˜ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžź°€ ģ§€ģ •ė˜ģ–“ ģžˆģœ¼ė‚˜, ꓀련 ė²•ė ¹ģ—ģ„œ ģš”źµ¬ķ•˜ėŠ” ģ—­ķ•  ė° ģ±…ģž„ģ“ ė‚“ė¶€ ģ§€ģ¹Øģ“ė‚˜ ģ§ė¬“źø°ģˆ ģ„œ 등에 구첓적으딜 ėŖ…ģ‹œė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“), 제31ģ”°(ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ˜ 지정)","ģ •ė³“ķ†µģ‹ ė§ė²• 제45ģ”°ģ˜3(ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģžģ˜ 지정 등)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ģ”°ģ§ģ˜ 각 źµ¬ģ„±ģ›ģ—ź²Œ ģ •ė³“ė³“ķ˜øģ™€ ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ—­ķ•  ė° ģ±…ģž„ģ„ ķ• ė‹¹ķ•˜ź³ , ź·ø ķ™œė™ģ„ ķ‰ź°€ķ•  수 ģžˆėŠ” 첓계와 씰직 ė° ģ”°ģ§ģ˜ 구성원 ź°„ 상호 ģ˜ģ‚¬ģ†Œķ†µķ•  수 ģžˆėŠ” 첓계넼 ģˆ˜ė¦½ķ•˜ģ—¬ ģš“ģ˜ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.1.3": {"name": "ģ •ė³“ģžģ‚° ꓀리","checks": {"macie_is_enabled": "PASS","resourceexplorer2_indexes_found": "PASS","config_recorder_all_regions_enabled": null,"account_maintain_current_contact_details": null,"organizations_account_part_of_organizations": null,"organizations_tags_policies_enabled_and_attached": null,"account_security_contact_information_is_registered": null,"account_security_questions_are_registered_in_the_aws_account": null,"account_maintain_different_contact_details_to_security_billing_and_operations": null},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.1.3 ģ •ė³“ģžģ‚° ꓀리","Subdomain": "2.1. ģ •ģ±…, 씰직, ģžģ‚° ꓀리","AuditEvidence": ["ģ •ė³“ģžģ‚° ėŖ©ė”(ģ±…ģž„ģž, ė‹“ė‹¹ģž 지정)","ģ •ė³“ģžģ‚° ģ·Øźø‰ 절차(ė¬øģ„œ, ģ •ė³“ģ‹œģŠ¤ķ…œ 등)","ģ •ė³“ģžģ‚° ꓀리 ģ‹œģŠ¤ķ…œ 화멓","ģ •ė³“ģžģ‚° ė³“ģ•ˆė“±źø‰ ķ‘œģ‹œ ė‚“ģ—­"],"AuditChecklist": ["ģ •ė³“ģžģ‚°ģ˜ ė³“ģ•ˆė“±źø‰ģ— 따넸 ģ·Øźø‰ģ ˆģ°Ø(ģƒģ„±Ā·ė„ģž…, ģ €ģž„, ģ“ģš©, 파기) ė° ė³“ķ˜øėŒ€ģ±…ģ„ ģ •ģ˜ķ•˜ź³  ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ‹ė³„ėœ ģ •ė³“ģžģ‚°ģ— ėŒ€ķ•˜ģ—¬ ģ±…ģž„ģž ė° ź“€ė¦¬ģžė„¼ ģ§€ģ •ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ 지침에 ė”°ė¼ ė¬øģ„œģ— ė³“ģ•ˆė“±źø‰ģ„ ķ‘œźø°ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ģ“ė„¼ ķ‘œģ‹œķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģ •ė³“ģžģ‚°ė³„ ė‹“ė‹¹ģž ė° ģ±…ģž„ģžė„¼ ģ‹ė³„ķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜, ģžģ‚°ėŖ©ė” ķ˜„ķ–‰ķ™”ź°€ ėÆøķ”ķ•˜ģ—¬ 퇓직, 전볓 등 ģøģ‚¬ģ“ė™ģ“ ė°œģƒķ•˜ģ—¬ ģ£¼ģš” ģ •ė³“ģžģ‚°ģ˜ ė‹“ė‹¹ģž ė° ģ±…ģž„ģžź°€ ė³€ź²½ė˜ģ—ˆģŒģ—ė„ ģ“ė„¼ ģ‹ė³„ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ģ‹ė³„ėœ ģ •ė³“ģžģ‚°ģ— ėŒ€ķ•œ ģ¤‘ģš”ė„ ķ‰ź°€ė„¼ ģ‹¤ģ‹œķ•˜ģ—¬ ė³“ģ•ˆė“±źø‰ģ„ ė¶€ģ—¬ķ•˜ź³  정볓 ģžģ‚°ėŖ©ė”ģ— źø°ė”ķ•˜ź³  ģžˆģœ¼ė‚˜, ė³“ģ•ˆė“±źø‰ģ— 따넸 ģ·Øźø‰ģ ˆģ°Øė„¼ ģ •ģ˜ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ģ •ė³“ģžģ‚°ģ˜ ģš©ė„ģ™€ ģ¤‘ģš”ė„ģ— 따넸 ģ·Øźø‰ 절차 ė° ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ , ģžģ‚°ė³„ ģ±…ģž„ģ†Œģž¬ė„¼ ėŖ…ķ™•ķžˆ ģ •ģ˜ķ•˜ģ—¬ ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 2,"total": 9,"manual": 0}},"2.2.1": {"name": "ģ£¼ģš” ģ§ė¬“ģž 지정 ė° ꓀리","checks": {"iam_support_role_created": null,"organizations_delegated_administrators": null,"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.2.1 ģ£¼ģš” ģ§ė¬“ģž 지정 ė° ꓀리","Subdomain": "2.2. ģøģ  ė³“ģ•ˆ","AuditEvidence": ["ģ£¼ģš” 직묓 기준","ģ£¼ģš”ģ§ė¬“ģž ėŖ©ė”","ź°œģøģ •ė³“ģ·Øźø‰ģž ėŖ©ė”","ģ¤‘ģš” ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ 계정 ė° ź¶Œķ•œ ꓀리 ėŒ€ģž„","ģ£¼ģš” ģ§ė¬“ģžģ— ėŒ€ķ•œ ꓀리 ķ˜„ķ™©(교윔 ź²°ź³¼, ė³“ģ•ˆģ„œģ•½ģ„œ 등)"],"AuditChecklist": ["ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ˜ ģ·Øźø‰, ģ£¼ģš” ģ‹œģŠ¤ķ…œ ģ ‘ź·¼ 등 ģ£¼ģš” ģ§ė¬“ģ˜ źø°ģ¤€ģ„ ėŖ…ķ™•ķžˆ ģ •ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ģ£¼ģš” 직묓넼 ģˆ˜ķ–‰ķ•˜ėŠ” ģž„ģ§ģ› ė° ģ™øė¶€ģžė„¼ ģ£¼ģš” ģ§ė¬“ģžė”œ ģ§€ģ •ķ•˜ź³  ź·ø ėŖ©ė”ģ„ ģµœģ‹ ģœ¼ė”œ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ—…ė¬“ģƒ ź°œģøģ •ė³“ė„¼ ģ·Øźø‰ķ•˜ėŠ” ģžė„¼ ź°œģøģ •ė³“ģ·Øźø‰ģžė”œ ģ§€ģ •ķ•˜ź³  ėŖ©ė”ģ„ ģµœģ‹ ģœ¼ė”œ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","업묓 ķ•„ģš”ģ„±ģ— ė”°ė¼ ģ£¼ģš” ģ§ė¬“ģž ė° ź°œģøģ •ė³“ģ·Øźø‰ģž ģ§€ģ •ģ„ ģµœģ†Œķ™”ķ•˜ėŠ” 등 ź“€ė¦¬ė°©ģ•ˆģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ£¼ģš” ģ§ė¬“ģž 명단(ź°œģøģ •ė³“ģ·Øźø‰ģž 명단, ė¹„ė°€ģ •ė³“ź“€ė¦¬ģž 명단 등)ģ„ ģž‘ģ„±ķ•˜ź³  ģžˆģœ¼ė‚˜, ėŒ€ėŸ‰ģ˜ ź°œģøģ •ė³“ 등 ģ¤‘ģš”ģ •ė³“ė„¼ ģ·Øźø‰ķ•˜ėŠ” ģ¼ė¶€ ģž„ģ§ģ›(DBA, DLP ź“€ė¦¬ģž 등)ģ„ 명단에 ėˆ„ė½ķ•œ 경우","사딀 2 : ģ£¼ģš” ģ§ė¬“ģž ė° ź°œģøģ •ė³“ģ·Øźø‰ģž ėŖ©ė”ģ„ ź“€ė¦¬ķ•˜ź³  ģžˆģœ¼ė‚˜, ķ‡“ģ‚¬ķ•œ ģž„ģ§ģ›ģ“ ķ¬ķ•Øė˜ģ–“ ģžˆź³  최근 ģ‹ ź·œ ģž…ģ‚¬ķ•œ ģøė „ģ“ ķ¬ķ•Øė˜ģ–“ ģžˆģ§€ ģ•ŠėŠ” 등 ķ˜„ķ–‰ķ™” ꓀리가 ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ė¶€ģ„œ ė‹Øģœ„ė”œ ź°œģøģ •ė³“ģ·Øźø‰ģž ź¶Œķ•œģ„ ģ¼ź“„ ė¶€ģ—¬ķ•˜ź³  ģžˆģ–“ ģ‹¤ģ œ ź°œģøģ •ė³“ė„¼ 취급할 ķ•„ģš”ź°€ ģ—†ėŠ” ģøģ›ź¹Œģ§€ ź³¼ė‹¤ķ•˜ź²Œ ź°œģøģ •ė³“ģ·Øźø‰ģžė”œ ģ§€ģ •ėœ 경우","사딀 4 : ė‚“ė¶€ ģ§€ģ¹Øģ—ėŠ” ģ£¼ģš” ģ§ė¬“ģž ź¶Œķ•œ 부여 ģ‹œģ—ėŠ” ė³“ģ•ˆķŒ€ģ˜ ģŠ¹ģøģ„ 받고 ģ£¼ģš” 직묓에 따넸 ė³“ģ•ˆģ„œģ•½ģ„œė„¼ ģž‘ģ„±ķ•˜ė„ė” ķ•˜ź³  ģžˆģœ¼ė‚˜, ė³“ģ•ˆķŒ€ ģŠ¹ģø ė° ė³“ģ•ˆģ„œģ•½ģ„œ ģž‘ģ„± ģ—†ģ“ ė“±ė”ėœ ģ£¼ģš” ģ§ė¬“ģžź°€ ė‹¤ģˆ˜ ģ”“ģž¬ķ•˜ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제28ģ”°(ź°œģøģ •ė³“ģ·Øźø‰ģžģ— ėŒ€ķ•œ ź°ė…), 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ˜ ģ·Øźø‰ģ“ė‚˜ ģ£¼ģš” ģ‹œģŠ¤ķ…œ ģ ‘ź·¼ 등 ģ£¼ģš” ģ§ė¬“ģ˜ 기준과 ź“€ė¦¬ė°©ģ•ˆģ„ ģˆ˜ė¦½ķ•˜ź³ , ģ£¼ģš” ģ§ė¬“ģžė„¼ ģµœģ†Œķ•œģœ¼ė”œ ģ§€ģ •ķ•˜ģ—¬ ź·ø ėŖ©ė”ģ„ ģµœģ‹ ģœ¼ė”œ ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"2.2.2": {"name": "직묓 분리","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.2.2 직묓 분리","Subdomain": "2.2. ģøģ  ė³“ģ•ˆ","AuditEvidence": ["직묓 분리 ꓀련 지침(ģøģ  ė³“ģ•ˆ 지침 등)","ģ§ė¬“źø°ģˆ ģ„œ(ģ‹œģŠ¤ķ…œ ģš“ģ˜Ā·ź“€ė¦¬, 개발·욓영 등)","직묓 미분리 ģ‹œ ė³“ģ™„ķ†µģ œ ķ˜„ķ™©"],"AuditChecklist": ["ź¶Œķ•œ ģ˜¤Ā·ė‚Øģš© ė“±ģœ¼ė”œ ģøķ•œ ģž ģž¬ģ ģø 피핓 ģ˜ˆė°©ģ„ ģœ„ķ•˜ģ—¬ 직묓 분리 źø°ģ¤€ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?","직묓 분리가 ģ–“ė ¤ģš“ 경우 ģ§ė¬“ģž ź°„ 상호 검토, ģƒģœ„ź“€ė¦¬ģž ģ •źø° ėŖØė‹ˆķ„°ė§ ė° 변경사항 ģŠ¹ģø, ģ±…ģž„ģ¶”ģ ģ„± 확볓 ė°©ģ•ˆ ė“±ģ˜ ė³“ģ™„ķ†µģ œė„¼ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ”°ģ§ģ˜ ź·œėŖØģ™€ ģøģ›ģ“ ė‹“ė‹¹ģžė³„ 직묓 분리가 ģ¶©ė¶„ķžˆ ź°€ėŠ„ķ•œ ģ”°ģ§ģž„ģ—ė„ 업묓 ķŽøģ˜ģ„±ė§Œģ„ ģ‚¬ģœ ė”œ ė‚“ė¶€ ź·œģ •ģœ¼ė”œ ģ •ķ•œ 직묓 분리 źø°ģ¤€ģ„ ģ¤€ģˆ˜ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ģ”°ģ§ģ˜ ķŠ¹ģ„±ģƒ ź²½ģ˜ģ§„ģ˜ ģŠ¹ģøģ„ ė°›ģ€ 후 개발과 욓영 직묓넼 ė³‘ķ–‰ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ§ė¬“ģž ź°„ 상호 검토, ģƒģœ„ź“€ė¦¬ģžģ˜ ģ£¼źø°ģ ģø ģ§ė¬“ģˆ˜ķ–‰ ėŖØė‹ˆķ„°ė§ ė° 변경 사항 ź²€ķ† Ā·ģŠ¹ģø, ģ§ė¬“ģžģ˜ ģ±…ģž„ģ¶”ģ ģ„± 확볓 ė“±ģ˜ ė³“ģ™„ķ†µģ œ ģ ˆģ°Øź°€ ė§ˆė Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ź¶Œķ•œ ģ˜¤Ā·ė‚Øģš© ė“±ģœ¼ė”œ ģøķ•œ ģž ģž¬ģ ģø 피핓 ģ˜ˆė°©ģ„ ģœ„ķ•˜ģ—¬ 직묓 분리 źø°ģ¤€ģ„ ģˆ˜ė¦½ķ•˜ź³  ģ ģš©ķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ė‹¤ė§Œ ė¶ˆź°€ķ”¼ķ•˜ź²Œ 직묓 분리가 ģ–“ė ¤ģš“ 경우 ė³„ė„ģ˜ ė³“ģ™„ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ģ—¬ ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.2.3": {"name": "ė³“ģ•ˆ ģ„œģ•½","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.2.3 ė³“ģ•ˆ ģ„œģ•½","Subdomain": "2.2. ģøģ  ė³“ģ•ˆ","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ„œģ•½ģ„œ(ģž„ģ§ģ›, ģ™øė¶€ģøė „)","ė¹„ė°€ģœ ģ§€ģ„œģ•½ģ„œ(ķ‡“ģ§ģž)"],"AuditChecklist": ["ģ‹ ź·œ ģøė „ ģ±„ģš© ģ‹œ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ±…ģž„ģ“ ėŖ…ģ‹œėœ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ„œģ•½ģ„œė„¼ 받고 ģžˆėŠ”ź°€?","ģž„ģ‹œģ§ģ›, ģ™øģ£¼ģš©ģ—­ģ§ģ› 등 ģ™øė¶€ģžģ—ź²Œ ģ •ė³“ģžģ‚°ģ— ėŒ€ķ•œ ģ ‘ź·¼ź¶Œķ•œģ„ 부여할 경우 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜øģ— ėŒ€ķ•œ ģ±…ģž„, ė¹„ė°€ģœ ģ§€ ģ˜ė¬“ ė“±ģ“ ėŖ…ģ‹œėœ ģ„œģ•½ģ„œė„¼ 받고 ģžˆėŠ”ź°€?","ģž„ģ§ģ› 퇓직 ģ‹œ ė³„ė„ģ˜ ė¹„ė°€ģœ ģ§€ģ— ź“€ė Øķ•œ ģ„œģ•½ģ„œė„¼ 받고 ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø, ź°œģøģ •ė³“ė³“ķ˜ø ė° ė¹„ė°€ģœ ģ§€ ģ„œģ•½ģ„œėŠ” ģ•ˆģ „ķ•˜ź²Œ ė³“ź“€ķ•˜ź³  ķ•„ģš”ģ‹œ ģ‰½ź²Œ 찾아볼 수 ģžˆė„ė” ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ‹ ź·œ ģž…ģ‚¬ģžģ— ėŒ€ķ•“ģ„œėŠ” ģž…ģ‚¬ ģ ˆģ°Øģƒģ— ė³“ģ•ˆģ„œģ•½ģ„œė„¼ ė°›ė„ė” ź·œģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, ģµœź·¼ģ— ģž…ģ‚¬ķ•œ ģ¼ė¶€ ģ§ģ›ģ˜ ė³“ģ•ˆģ„œģ•½ģ„œ ģž‘ģ„±ģ“ ėˆ„ė½ėœ 경우","사딀 2 : ģž„ģ§ģ›ģ— ėŒ€ķ•“ģ„œėŠ” ė³“ģ•ˆģ„œģ•½ģ„œė„¼ 받고 ģžˆģœ¼ė‚˜, ģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— 직접 ģ ‘ģ†ģ“ ź°€ėŠ„ķ•œ 외주 ģøė „ģ— ėŒ€ķ•“ģ„œėŠ” ė³“ģ•ˆģ„œģ•½ģ„œė„¼ 받지 ģ•Šģ€ 경우","사딀 3 : 제출된 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ„œģ•½ģ„œė„¼ ėŖØģ•„ ė†“ģ€ ė¬øģ„œģ² ģ“ ė¹„ģøź°€ģžź°€ ģ ‘ź·¼ ź°€ėŠ„ķ•œ 상태딜 사묓실 ģ±…ģƒģ— ė°©ģ¹˜ė˜ģ–“ ģžˆėŠ” 등 ꓀리가 ėÆøķ”ķ•œ 경우","사딀 4 : ź°œģøģ •ė³“ģ·Øźø‰ģžģ— ėŒ€ķ•˜ģ—¬ ė³“ģ•ˆģ„œģ•½ģ„œė§Œ 받고 ģžˆģœ¼ė‚˜, ė³“ģ•ˆģ„œģ•½ģ„œ 낓에 ė¹„ė°€ģœ ģ§€ģ— ėŒ€ķ•œ ė‚“ģš©ė§Œ ģžˆź³  ź°œģøģ •ė³“ė³“ķ˜øģ— ź“€ķ•œ ģ±…ģž„ ė° ė‚“ģš©ģ“ ķ¬ķ•Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ģ •ė³“ģžģ‚°ģ„ ģ·Øźø‰ķ•˜ź±°ė‚˜ ģ ‘ź·¼ź¶Œķ•œģ“ ė¶€ģ—¬ėœ ģž„ģ§ģ›Ā·ģž„ģ‹œģ§ģ›Ā·ģ™øė¶€ģž ė“±ģ“ ė‚“ė¶€ ģ •ģ±… ė°","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.2.4": {"name": "ģøģ‹ģ œź³  ė° źµģœ”ķ›ˆė Ø","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.2.4 ģøģ‹ģ œź³  ė° źµģœ”ķ›ˆė Ø","Subdomain": "2.2. ģøģ  ė³“ģ•ˆ","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 교윔 ź³„ķšģ„œ","교윔 ź²°ź³¼ė³“ź³ ģ„œ","공통, 직묓별 źµģœ”ģžė£Œ","źµģœ”ģ°øģ„ģž ėŖ©ė”"],"AuditChecklist": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø źµģœ”ģ˜ ģ‹œźø°, źø°ź°„, ėŒ€ģƒ, ė‚“ģš©, 방법 ė“±ģ˜ ė‚“ģš©ģ“ ķ¬ķ•Øėœ ģ—°ź°„ 교윔 ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ź³  ź²½ģ˜ģ§„ģ˜ ģŠ¹ģøģ„ 받고 ģžˆėŠ”ź°€?","꓀리첓계 ė²”ģœ„ ė‚“ ėŖØė“  ģž„ģ§ģ›ź³¼ ģ™øė¶€ģžė„¼ ėŒ€ģƒģœ¼ė”œ ģ—°ź°„ 교윔 ź³„ķšģ— ė”°ė¼ ģ—° 1회 ģ“ģƒ ģ •źø°ģ ģœ¼ė”œ źµģœ”ģ„ ģˆ˜ķ–‰ķ•˜ź³ , ꓀련 ė²•ź·œ ė° ź·œģ •ģ˜ ģ¤‘ėŒ€ķ•œ 변경 ģ‹œ ģ“ģ— ėŒ€ķ•œ ģ¶”ź°€źµģœ”ģ„ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģž„ģ§ģ› ģ±„ģš© ė° ģ™øė¶€ģž ģ‹ ź·œ 계약 ģ‹œ 업묓 ģ‹œģž‘ 전에 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø źµģœ”ģ„ ģ‹œķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","IT ė° ģ •ė³“ė³“ķ˜ø, ź°œģøģ •ė³“ė³“ķ˜ø 씰직 ė‚“ ģž„ģ§ģ›ģ€ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜øģ™€ ź“€ė Øķ•˜ģ—¬ 직묓별 전문성 제고넼 ģœ„ķ•œ ė³„ė„ģ˜ źµģœ”ģ„ 받고 ģžˆėŠ”ź°€?","źµģœ”ģ‹œķ–‰ģ— ėŒ€ķ•œ źø°ė”ģ„ 남기고 교윔 ķšØź³¼ģ™€ ģ ģ •ģ„±ģ„ ķ‰ź°€ķ•˜ģ—¬ ė‹¤ģŒ 교윔 ź³„ķšģ— ė°˜ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ „ė…„ė„ģ—ėŠ” ģ—°ź°„ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 교윔 ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ģ“ķ–‰ķ•˜ģ˜€ģœ¼ė‚˜, 당핓 ģ—°ė„ģ— ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ģ—†ģ“ ģ—°ź°„ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 교윔 ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģ—°ź°„ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 교윔 ź³„ķšģ— 교윔 주기와 ėŒ€ģƒģ€ ėŖ…ģ‹œķ•˜ź³  ģžˆģœ¼ė‚˜, ģ‹œķ–‰ ģ¼ģ •, ė‚“ģš© ė° 방법 ė“±ģ˜ ė‚“ģš©ģ“ ķ¬ķ•Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģ—°ź°„ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 교윔 ź³„ķšģ— ģ „ ģ§ģ›ģ„ ėŒ€ģƒģœ¼ė”œ ķ•˜ėŠ” ź°œģøģ •ė³“ė³“ķ˜ø ģøģ‹ źµģœ”ģ€ ģ¼ģ •ģ‹œź°„ ź³„ķšė˜ģ–“ ģžˆģœ¼ė‚˜, ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģž ė° ź°œģøģ •ė³“ė‹“ė‹¹ģž 등 ģ§ė¬“ė³„ė”œ ķ•„ģš”ķ•œ ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 교윔 ź³„ķšģ“ ķ¬ķ•Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 교윔 ź³„ķšģ„œ ė° ź²°ź³¼ ė³“ź³ ģ„œė„¼ ķ™•ģøķ•œ ź²°ź³¼, ģøģ¦ė²”ģœ„ ė‚“ģ˜ ģ •ė³“ģžģ‚° ė° 설비에 ģ ‘ź·¼ķ•˜ėŠ” ģ™øģ£¼ģš©ģ—­ģ—…ģ²“ 직원(전산실 ģ¶œģž… ģ²­ģ†Œģ›, 경비원, ģ™øģ£¼ź°œė°œģž 등)ģ„ 교윔 ėŒ€ģƒģ—ģ„œ ėˆ„ė½ķ•œ 경우","사딀 5 : 당핓 ģ—°ė„ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø źµģœ”ģ„ ģ‹¤ģ‹œķ•˜ģ˜€ģœ¼ė‚˜, źµģœ”ģ‹œķ–‰ ė° ķ‰ź°€ģ— ź“€ķ•œ źø°ė”(교윔 ģžė£Œ, ģ¶œģ„ė¶€, ķ‰ź°€ 설문지, ź²°ź³¼ė³“ź³ ģ„œ 등) ģ¼ė¶€ė„¼ 남기지 ģ•Šź³  ģžˆėŠ” 경우","사딀 6 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 교윔 ėÆøģ“ģˆ˜ģžė„¼ ķŒŒģ•…ķ•˜ģ§€ ģ•Šź³  ģžˆź±°ė‚˜, 핓당 ėÆøģ“ģˆ˜ģžģ— ėŒ€ķ•œ ģ¶”ź°€źµģœ” 방법(ģ „ė‹¬źµģœ”, ģ¶”ź°€źµģœ”, ģ˜Øė¼ģøźµģœ” 등)ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제26ģ”°(ģ—…ė¬“ģœ„ķƒģ— 따넸 ź°œģøģ •ė³“ģ˜ 처리 ģ œķ•œ), 제28ģ”°(ź°œģøģ •ė³“ ģ·Øźø‰ģžģ— ėŒ€ķ•œ ź°ė…), 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ģž„ģ§ģ› ė° ꓀련 ģ™øė¶€ģžź°€ ģ”°ģ§ģ˜ ꓀리첓계와 ģ •ģ±…ģ„ ģ“ķ•“ķ•˜ź³  직묓별 ģ „ė¬øģ„±ģ„ 확볓할 수 ģžˆė„ė” ģ—°ź°„ ģøģ‹ģ œź³  ķ™œė™ ė° źµģœ”ķ›ˆė Ø ź³„ķšģ„ ģˆ˜ė¦½Ā·ģš“ģ˜ķ•˜ź³ , ź·ø 결과에 따넸 ķšØź³¼ģ„±ģ„ ķ‰ź°€ķ•˜ģ—¬ ė‹¤ģŒ ź³„ķšģ— ė°˜ģ˜ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.2.5": {"name": "퇓직 ė° 직묓변경 ꓀리","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.2.5 퇓직 ė° 직묓변경 ꓀리","Subdomain": "2.2. ģøģ  ė³“ģ•ˆ","AuditEvidence": ["퇓직 ė° 직묓변경 ģ ˆģ°Øģ„œ","퇓직 ģ‹œ ģžģ‚°(계정) ė°˜ė‚©ź“€ė¦¬ėŒ€ģž„","ķ‡“ģ§ģž ė³“ģ•ˆģ ź²€ 첓크리스트 ė° 점검 ė‚“ģ—­"],"AuditChecklist": ["퇓직, 직묓변경, ė¶€ģ„œģ“ė™, 휓직 ė“±ģœ¼ė”œ ģøķ•œ ģøģ‚¬ė³€ź²½ ė‚“ģš©ģ“ ģøģ‚¬ė¶€ģ„œ, ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ė¶€ģ„œ, ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ģš“ģ˜ė¶€ģ„œ ź°„ 공유되고 ģžˆėŠ”ź°€?","씰직 ė‚“ ģøė „(ģž„ģ§ģ›, ģž„ģ‹œģ§ģ›, ģ™øģ£¼ģš©ģ—­ģ§ģ› 등)ģ˜ 퇓직 ė˜ėŠ” 직묓변경 ģ‹œ 지첓 ģ—†ėŠ” ģ •ė³“ģžģ‚° ė°˜ė‚©, ģ ‘ź·¼ź¶Œķ•œ ķšŒģˆ˜Ā·ģ”°ģ •, ź²°ź³¼ ķ™•ģø ė“±ģ˜ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 직묓 ė³€ė™ģ— ė”°ė¼ ź°œģøģ •ė³“ģ·Øźø‰ģžģ—ģ„œ ģ œģ™øėœ ģøė „ģ˜ 계정과 ź¶Œķ•œģ“ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— ź·øėŒ€ė”œ 남아 ģžˆėŠ” 경우","사딀 2 : ģµœź·¼ģ— ķ‡“ģ§ķ•œ ģ£¼ģš”ģ§ė¬“ģž ė° ź°œģøģ •ė³“ģ·Øźø‰ģžģ— ėŒ€ķ•˜ģ—¬ ģžģ‚°ė°˜ė‚©, ź¶Œķ•œ 회수 ė“±ģ˜ ķ‡“ģ§ģ ˆģ°Ø ģ“ķ–‰ źø°ė”ģ“ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ģž„ģ§ģ› 퇓직 ģ‹œ ģžģ‚°ė°˜ė‚© ź“€ė¦¬ėŠ” ģž˜ ģ“ķ–‰ķ•˜ź³  ģžˆģœ¼ė‚˜, ģøģ‚¬ź·œģ •ģ—ģ„œ ģ •ķ•œ ķ‡“ģ§ģž ė³“ģ•ˆģ ź²€ ė° ķ‡“ģ§ķ™•ģøģ„œė„¼ ģž‘ģ„±ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ź°œģøģ •ė³“ģ·Øźø‰ģž 퇓직 ģ‹œ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ģ ‘ź·¼ ź¶Œķ•œģ€ 지첓 ģ—†ģ“ ķšŒģˆ˜ė˜ģ—ˆģ§€ė§Œ, ģ¶œģž…ķ†µģ œ ģ‹œģŠ¤ķ…œ ė° VPN 등 ģ¼ė¶€ ģ‹œģŠ¤ķ…œģ˜ ģ ‘ź·¼ ź¶Œķ•œģ“ ķšŒģˆ˜ė˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ ź¶Œķ•œģ˜ ꓀리)"]}],"description": "퇓직 ė° 직묓변경 ģ‹œ ģøģ‚¬Ā·ģ •ė³“ė³“ķ˜øĀ·ź°œģøģ •ė³“ė³“ķ˜øĀ·IT 등 ꓀련 ė¶€ģ„œė³„ ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•  ģžģ‚°ė°˜ė‚©, 계정 ė° ģ ‘ź·¼ź¶Œķ•œ ķšŒģˆ˜Ā·ģ”°ģ •, ź²°ź³¼ķ™•ģø ė“±ģ˜ 절차넼 ģˆ˜ė¦½Ā·ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.2.6": {"name": "ė³“ģ•ˆ ģœ„ė°˜ ģ‹œ 씰치","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.2.6 ė³“ģ•ˆ ģœ„ė°˜ ģ‹œ 씰치","Subdomain": "2.2. ģøģ  ė³“ģ•ˆ","AuditEvidence": ["ģøģ‚¬ ź·œģ •(ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ź·œģ • ģœ„ė°˜ģ— 따넸 ģ²˜ė²Œź·œģ •)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 지침 ģœ„ė°˜ģž 징계 ė‚“ģ—­","사고 사딀(전사 공지, 교윔 ė‚“ģš©)"],"AuditChecklist": ["ģž„ģ§ģ› ė° ꓀련 ģ™øė¶€ģžź°€ 법령과 규제 ė° 낓부정책에 따넸 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ±…ģž„ź³¼ ģ˜ė¬“ė„¼ ģœ„ė°˜ķ•œ ź²½ģš°ģ— ėŒ€ķ•œ 처벌 ź·œģ •ģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ 볓호 ģœ„ė°˜ ģ‚¬ķ•­ģ“ 적발된 경우 ė‚“ė¶€ ģ ˆģ°Øģ— 따넸 씰치넼 ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ź·œģ • ģœ„ė°˜ģžģ— ėŒ€ķ•œ 처리 기준 ė° ģ ˆģ°Øź°€ ė‚“ė¶€ ź·œģ •ģ— ģ „ķ˜€ ķ¬ķ•Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ė³“ģ•ˆģ‹œģŠ¤ķ…œ(DLP, ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ģ œģ–“ģ‹œģŠ¤ķ…œ, ė‚“ė¶€ģ •ė³“ģœ ģ¶œķ†µģ œģ‹œģŠ¤ķ…œ 등)ģ„ ķ†µķ•˜ģ—¬ ģ •ģ±… ģœ„ė°˜ģ“ ķƒģ§€ėœ ź“€ė Øģžģ—ź²Œ 경고 ė©”ģ‹œģ§€ė„¼ ģ „ė‹¬ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•œ ģ†ŒėŖ… ė° 추가 씰사, 징계 ģ²˜ė¶„ 등 ė‚“ė¶€ ź·œģ •ģ— 따넸 ķ›„ģ† ģ”°ģ¹˜ź°€ ģ“ķ–‰ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ģž„ģ§ģ› ė° ꓀련 ģ™øė¶€ģžź°€ 법령, 규제 ė° ė‚“ė¶€ģ •ģ±…ģ„ ģœ„ė°˜ķ•œ 경우 ģ“ģ— 따넸 씰치 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.3.1": {"name": "ģ™øė¶€ģž ķ˜„ķ™© ꓀리","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.3.1 ģ™øė¶€ģž ķ˜„ķ™© ꓀리","Subdomain": "2.3. ģ™øė¶€ģž ė³“ģ•ˆ","AuditEvidence": ["외부 ģœ„ķƒ ė° 외부 ģ‹œģ„¤Ā·ģ„œė¹„ģŠ¤ ķ˜„ķ™©","외부 ģœ„ķƒ ź³„ģ•½ģ„œ","ģœ„ķ—˜ė¶„ģ„ ė³“ź³ ģ„œ ė° ė³“ķ˜øėŒ€ģ±…","ģœ„ķƒ ė³“ģ•ˆź“€ė¦¬ 지침, 첓크리스트 등"],"AuditChecklist": ["꓀리첓계 ė²”ģœ„ ė‚“ģ—ģ„œ ė°œģƒķ•˜ź³  ģžˆėŠ” 업묓 ģœ„ķƒ ė° 외부 ģ‹œģ„¤Ā·ģ„œė¹„ģŠ¤ģ˜ ģ“ģš© ķ˜„ķ™©ģ„ ģ‹ė³„ķ•˜ź³  ģžˆėŠ”ź°€?","업묓 ģœ„ķƒ ė° 외부 ģ‹œģ„¤Ā·ģ„œė¹„ģŠ¤ģ˜ ģ“ģš©ģ— 따넸 법적 ģš”źµ¬ģ‚¬ķ•­ź³¼ ģœ„ķ—˜ģ„ ķŒŒģ•…ķ•˜ź³  ģ ģ ˆķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ ź·œģ •ģ— ė”°ė¼ 외부 ģœ„ķƒ ė° 외부 ģ‹œģ„¤Ā·ģ„œė¹„ģŠ¤ ķ˜„ķ™©ģ„ ėŖ©ė”ģœ¼ė”œ ź“€ė¦¬ķ•˜ź³  ģžˆģœ¼ė‚˜, ėŖ‡ ź°œģ›” 전에 ė³€ź²½ėœ ģœ„ķƒģ—…ģ²“ź°€ ėŖ©ė”ģ— ė°˜ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 등 ķ˜„ķ–‰ķ™” ꓀리가 ėÆøķ”ķ•œ 경우","사딀 2 : ꓀리첓계 ė²”ģœ„ ė‚“ ģ¼ė¶€ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ„ 외부 ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ė”œ ģ“ģ „ķ•˜ģ˜€ģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•œ ģ‹ė³„ ė° ģœ„ķ—˜ķ‰ź°€ź°€ ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제26ģ”°(ģ—…ė¬“ģœ„ķƒģ— 따넸 ź°œģøģ •ė³“ģ˜ 처리 ģ œķ•œ)","ģ •ė³“ķ†µģ‹ ė§ė²• 제50ģ”°ģ˜3(ģ˜ė¦¬ėŖ©ģ ģ˜ ꓑ고성 정볓 ģ „ģ†”ģ˜ ģœ„ķƒ 등)"]}],"description": "ģ—…ė¬“ģ˜ ģ¼ė¶€(ź°œģøģ •ė³“ģ·Øźø‰, ģ •ė³“ė³“ķ˜ø, ģ •ė³“ģ‹œģŠ¤ķ…œ 욓영 ė˜ėŠ” 개발 등)넼 외부에 ģœ„ķƒķ•˜ź±°ė‚˜ ģ™øė¶€ģ˜ ģ‹œģ„¤ ė˜ėŠ” ģ„œė¹„ģŠ¤(ģ§‘ģ ģ •ė³“ķ†µģ‹ ģ‹œģ„¤, ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤, ģ• ķ”Œė¦¬ģ¼€ģ“ģ…˜ ģ„œė¹„ģŠ¤ 등)넼 ģ“ģš©ķ•˜ėŠ” 경우 ź·ø ķ˜„ķ™©ģ„ ģ‹ė³„ķ•˜ź³  법적 ģš”źµ¬ģ‚¬ķ•­ ė° 외부 ģ”°ģ§Ā·ģ„œė¹„ģŠ¤ė”œė¶€ķ„° ė°œģƒė˜ėŠ” ģœ„ķ—˜ģ„ ķŒŒģ•…ķ•˜ģ—¬ ģ ģ ˆķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.3.2": {"name": "ģ™øė¶€ģž 계약 ģ‹œ ė³“ģ•ˆ","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.3.2 ģ™øė¶€ģž 계약 ģ‹œ ė³“ģ•ˆ","Subdomain": "2.3. ģ™øė¶€ģž ė³“ģ•ˆ","AuditEvidence": ["ģœ„ķƒ ź³„ģ•½ģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ˜‘ģ•½ģ„œ(ģ•½ģ •ģ„œ, ė¶€ģ†ķ•©ģ˜ģ„œ)","ģœ„ķƒ ꓀련 ė‚“ė¶€ 지침","ģœ„ķƒģ—…ģ²“ ģ„ ģ • ꓀련 RFP(ģ œģ•ˆģš”ģ²­ģ„œ), ķ‰ź°€ķ‘œ"],"AuditChecklist": ["ģ¤‘ģš”ģ •ė³“ ė° ź°œģøģ •ė³“ ģ²˜ė¦¬ģ™€ ź“€ė Øėœ 외부 ģ„œė¹„ģŠ¤ ė° ģœ„ķƒ 업첓넼 ģ„ ģ •ķ•˜ėŠ” 경우 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ 볓호 ģ—­ėŸ‰ģ„ ź³ ė ¤ķ•˜ė„ė” 절차넼 ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","외부 ģ„œė¹„ģŠ¤ ģ“ģš© ė° 업묓 ģœ„ķƒģ— 따넸 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģš”źµ¬ģ‚¬ķ•­ģ„ ģ‹ė³„ķ•˜ź³  ģ“ė„¼ ź³„ģ•½ģ„œ ė˜ėŠ” ķ˜‘ģ •ģ„œģ— ėŖ…ģ‹œķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ź°œė°œģ„ ģœ„ķƒķ•˜ėŠ” 경우 개발 ģ‹œ ģ¤€ģˆ˜ķ•˜ģ—¬ģ•¼ ķ•  ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģš”źµ¬ģ‚¬ķ•­ģ„ ź³„ģ•½ģ„œģ— ėŖ…ģ‹œķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : IT 욓영, 개발 ė° ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ė„¼ ģœ„ķƒķ•˜ėŠ” ģ™øģ£¼ģš©ģ—­ģ—…ģ²“ģ— ėŒ€ķ•œ ģœ„ķƒź³„ģ•½ģ„œź°€ ģ”“ģž¬ķ•˜ģ§€ ģ•ŠėŠ” 경우","사딀 2 : ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ė„¼ ģœ„ķƒķ•˜ėŠ” ģ™øė¶€ģ—…ģ²“ģ™€ģ˜ ģœ„ķƒź³„ģ•½ģ„œģƒģ— ź°œģøģ •ė³“ ė³“ķ˜øė²• 등 ė²•ė ¹ģ—ģ„œ ģš”źµ¬ķ•˜ėŠ” ģ¼ė¶€ ķ•­ėŖ©(ź“€ė¦¬Ā·ź°ė…ģ— ź“€ķ•œ 사항 등)ģ“ ķ¬ķ•Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģøķ”„ė¼ 욓영과 ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ ģ¼ė¶€ė„¼ 외부업첓에 ģœ„ķƒķ•˜ź³  ģžˆģœ¼ė‚˜, ź³„ģ•½ģ„œ ė“±ģ—ėŠ” ģœ„ķƒģ—…ė¬“ģ˜ ķŠ¹ģ„±ģ— 따넸 ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ģ„ ģ‹ė³„Ā·ė°˜ģ˜ķ•˜ģ§€ ģ•Šź³  ė¹„ė°€ģœ ģ§€ ė° ģ†ķ•“ė°°ģƒģ— ź“€ķ•œ ģ¼ė°˜ ģ‚¬ķ•­ė§Œ ź·œģ •ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제26ģ”°(ģ—…ė¬“ģœ„ķƒģ— 따넸 ź°œģøģ •ė³“ģ˜ 처리 ģ œķ•œ)"]}],"description": "외부 ģ„œė¹„ģŠ¤ė„¼ ģ“ģš©ķ•˜ź±°ė‚˜ ģ™øė¶€ģžģ—ź²Œ 업묓넼 ģœ„ķƒķ•˜ėŠ” 경우 ģ“ģ— 따넸 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģš”źµ¬ģ‚¬ķ•­ģ„ ģ‹ė³„ķ•˜ź³ , ꓀련 ė‚“ģš©ģ„ ź³„ģ•½ģ„œ ė˜ėŠ” ķ˜‘ģ •ģ„œ 등에 ėŖ…ģ‹œķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.3.3": {"name": "ģ™øė¶€ģž ė³“ģ•ˆ ģ“ķ–‰ ꓀리","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.3.3 ģ™øė¶€ģž ė³“ģ•ˆ ģ“ķ–‰ ꓀리","Subdomain": "2.3. ģ™øė¶€ģž ė³“ģ•ˆ","AuditEvidence": ["ģ™øė¶€ģž ė° ģˆ˜ķƒģž ė³“ģ•ˆģ ź²€ ź²°ź³¼","ģ™øė¶€ģž ė° ģˆ˜ķƒģž 교윔 ė‚“ģ—­(교윔 ź²°ź³¼, ģ°øģ„ģž 명단, źµģœ”źµģž¬ 등)","ź°œģøģ •ė³“ ģœ„ķƒ ź³„ģ•½ģ„œ","ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ ģž¬ģœ„ķƒ ģ‹œ ģœ„ķƒģž ė™ģ˜ ģ¦ź±°ģžė£Œ"],"AuditChecklist": ["ģ™øė¶€ģžź°€ ź³„ģ•½ģ„œ, ķ˜‘ģ •ģ„œ, 낓부정책에 ėŖ…ģ‹œėœ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģš”źµ¬ģ‚¬ķ•­ģ„ ģ¤€ģˆ˜ķ•˜ź³  ģžˆėŠ”ģ§€ 주기적으딜 점검 ė˜ėŠ” 감사넼 ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ™øė¶€ģžģ— ėŒ€ķ•œ 점검 ė˜ėŠ” 감사 ģ‹œ 발견된 ė¬øģ œģ ģ— ėŒ€ķ•˜ģ—¬ ź°œģ„ ź³„ķšģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ė„¼ ģœ„ķƒė°›ģ€ ģˆ˜ķƒģžź°€ ꓀련 업묓넼 제3ģžģ—ź²Œ ģž¬ģœ„ķƒķ•˜ėŠ” 경우 ģœ„ķƒģžģ˜ ė™ģ˜ė„¼ ė°›ė„ė” ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķšŒģ‚¬ 낓에 ģƒģ£¼ķ•˜ģ—¬ IT 개발 ė° 욓영 업묓넼 ģˆ˜ķ–‰ķ•˜ėŠ” 외주업첓에 ėŒ€ķ•“ģ„œėŠ” ģ •źø°ģ ģœ¼ė”œ ė³“ģ•ˆģ ź²€ģ„ ģˆ˜ķ–‰ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ź°œģøģ •ė³“ ģˆ˜ķƒģžģ— ėŒ€ķ•˜ģ—¬ ė³“ģ•ˆźµģœ”ģ„ ģ‹¤ģ‹œķ•˜ė¼ėŠ” ź³µė¬øģ„ ė°œģ†”ķ•˜ź³  ģžˆģœ¼ė‚˜, 교윔 ģˆ˜ķ–‰ 여부넼 ķ™•ģøķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģˆ˜ķƒģžź°€ ģžģ²“ģ ģœ¼ė”œ ė³“ģ•ˆģ ź²€ģ„ ģˆ˜ķ–‰ķ•œ 후 ź·ø 결과넼 ķ†µģ§€ķ•˜ė„ė” ķ•˜ź³  ģžˆģœ¼ė‚˜, ģˆ˜ķƒģžź°€ ė³“ģ•ˆ ģ ź²€ģ„ ģ¶©ģ‹¤ķžˆ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ģ§€ 여부에 ėŒ€ķ•˜ģ—¬ ķ™•ģøķ•˜ėŠ” ģ ˆģ°Øź°€ ģ”“ģž¬ķ•˜ģ§€ ģ•Šģ•„ ė³“ģ•ˆģ ź²€ ź²°ź³¼ģ˜ ģ‹ ė¢°ģ„±ģ“ 매우 ė–Øģ–“ģ§€ėŠ” 경우","사딀 4 : ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ ģˆ˜ķƒģž 중 ģ¼ė¶€ź°€ ģœ„ķƒģžģ˜ ė™ģ˜ ģ—†ģ“ 핓당 업묓넼 제3ģžģ—ź²Œ ģž¬ģœ„ķƒķ•œ 경우","사딀 5 : 영리 ėŖ©ģ ģ˜ ꓑ고성 정볓전솔 업묓넼 ķƒ€ģøģ—ź²Œ ģœ„ķƒķ•˜ė©“ģ„œ ģˆ˜ķƒģžģ— ėŒ€ķ•œ ź“€ė¦¬Ā·ź°ė…ģ„ ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제26ģ”°(ģ—…ė¬“ģœ„ķƒģ— 따넸 ź°œģøģ •ė³“ģ˜ 처리 ģ œķ•œ)","ģ •ė³“ķ†µģ‹ ė§ė²• 제50ģ”°ģ˜3(ģ˜ė¦¬ėŖ©ģ ģ˜ ꓑ고성 정볓 ģ „ģ†”ģ˜ ģœ„ķƒ 등)"]}],"description": "ź³„ģ•½ģ„œ, ķ˜‘ģ •ģ„œ, 낓부정책에 ėŖ…ģ‹œėœ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģš”źµ¬ģ‚¬ķ•­ģ— ė”°ė¼ ģ™øė¶€ģžģ˜ ė³“ķ˜øėŒ€ģ±… ģ“ķ–‰ 여부넼 ģ£¼źø°ģ ģø 점검 ė˜ėŠ” 감사 등 ź“€ė¦¬Ā·ź°ė…ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.3.4": {"name": "ģ™øė¶€ģž 계약 변경 ė° 만료 ģ‹œ ė³“ģ•ˆ","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.3.4 ģ™øė¶€ģž 계약 변경 ė° 만료 ģ‹œ ė³“ģ•ˆ","Subdomain": "2.3. ģ™øė¶€ģž ė³“ģ•ˆ","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ„œģ•½ģ„œ","ė¹„ė°€ģœ ģ§€ ķ™•ģ•½ģ„œ","정볓 ė° ź°œģøģ •ė³“ 파기 ķ™•ģ•½ģ„œ","ģ™øė¶€ģž 계약 ģ¢…ė£Œģ™€ ź“€ė Øėœ ė‚“ė¶€ ģ •ģ±…, 지침"],"AuditChecklist": ["ģ™øė¶€ģž ź³„ģ•½ė§Œė£Œ, 업묓 ģ¢…ė£Œ, ė‹“ė‹¹ģž 변경 ģ‹œ ź³µģ‹ģ ģø ģ ˆģ°Øģ— 따넸 ģ •ė³“ģžģ‚° ė°˜ė‚©, ģ •ė³“ģ‹œģŠ¤ķ…œ 접근계정 ģ‚­ģ œ, ė¹„ė°€ģœ ģ§€ ķ™•ģ•½ģ„œ 징구 ė“±ģ“ ģ“ė£Øģ–“ģ§ˆ 수 ģžˆė„ė” ė³“ģ•ˆėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ™øė¶€ģž 계약 만료 ģ‹œ ģœ„ķƒ 업묓와 ź“€ė Øķ•˜ģ—¬ ģ™øė¶€ģžź°€ ģ¤‘ģš”ģ •ė³“ ė° ź°œģøģ •ė³“ė„¼ ė³“ģœ ķ•˜ź³  ģžˆėŠ”ģ§€ ķ™•ģøķ•˜ź³  ģ“ė„¼ ķšŒģˆ˜Ā·ķŒŒźø°ķ•  수 ģžˆė„ė” 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ¼ė¶€ ģ •ė³“ģ‹œģŠ¤ķ…œģ—ģ„œ 계약 만료된 ģ™øė¶€ģžģ˜ 계정 ė° ź¶Œķ•œģ“ ģ‚­ģ œė˜ģ§€ ģ•Šź³  ģ”“ģž¬ķ•˜ėŠ” 경우","사딀 2 : ģ™øģ£¼ģš©ģ—­ģ‚¬ģ—… ģˆ˜ķ–‰ź³¼ģ •ģ—ģ„œ ģ¼ė¶€ ģš©ģ—­ģ—…ģ²“ ė‹“ė‹¹ģžź°€ źµģ²“ė˜ź±°ė‚˜ 계약 만료딜 ķ‡“ģ§ķ•˜ģ˜€ģœ¼ė‚˜, ꓀련 ģøė „ė“¤ģ— ėŒ€ķ•œ 퇓사 ģ‹œ ė³“ģ•ˆģ„œģ•½ģ„œ 등 ė‚“ė¶€ ź·œģ •ģ— 따넸 ģ”°ģ¹˜ź°€ ģ“ķ–‰ė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ź°œģøģ •ė³“ 처리 ģœ„ķƒķ•œ 업첓와 계약 ģ¢…ė£Œ ģ“ķ›„ ė³“ģœ ķ•˜ź³  ģžˆėŠ” ź°œģøģ •ė³“ė„¼ ķŒŒźø°ķ•˜ģ˜€ėŠ”ģ§€ 여부넼 ķ™•ģøĀ·ģ ź²€ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제26ģ”°(ģ—…ė¬“ģœ„ķƒģ— 따넸 ź°œģøģ •ė³“ģ˜ 처리 ģ œķ•œ)","ģ •ė³“ķ†µģ‹ ė§ė²• 제50ģ”°ģ˜3(ģ˜ė¦¬ėŖ©ģ ģ˜ ꓑ고성 정볓 ģ „ģ†”ģ˜ ģœ„ķƒ 등)"]}],"description": "ģ™øė¶€ģž ź³„ģ•½ė§Œė£Œ, ģ—…ė¬“ģ¢…ė£Œ, ė‹“ė‹¹ģž 변경 ģ‹œģ—ėŠ” ģ œź³µķ•œ ģ •ė³“ģžģ‚° ė°˜ė‚©, ģ •ė³“ģ‹œģŠ¤ķ…œ 접근계정 ģ‚­ģ œ, ģ¤‘ģš”ģ •ė³“ 파기, 업묓 ģˆ˜ķ–‰ 중 ģ·Øė“ģ •ė³“ģ˜ ė¹„ė°€ģœ ģ§€ ķ™•ģ•½ģ„œ 징구 ė“±ģ˜ ė³“ķ˜øėŒ€ģ±…ģ„ ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.1": {"name": "ė³“ķ˜øźµ¬ģ—­ 지정","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.4.1 ė³“ķ˜øźµ¬ģ—­ 지정","Subdomain": "2.4. 물리 ė³“ģ•ˆ","AuditEvidence": ["물리적 ė³“ģ•ˆ 지침(ė³“ķ˜øźµ¬ģ—­ 지정 기준)","ė³“ķ˜øźµ¬ģ—­ 지정 ķ˜„ķ™©","ė³“ķ˜øźµ¬ģ—­ ķ‘œģ‹œ","ė³“ķ˜øźµ¬ģ—­ė³„ ė³“ķ˜øėŒ€ģ±… ķ˜„ķ™©"],"AuditChecklist": ["ė¬¼ė¦¬ģ Ā·ķ™˜ź²½ģ  ģœ„ķ˜‘ģœ¼ė”œė¶€ķ„° ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“, ė¬øģ„œ, ģ €ģž„ė§¤ģ²“, ģ£¼ģš” 설비 ė° ģ‹œģŠ¤ķ…œ ė“±ģ„ ė³“ķ˜øķ•˜źø° ģœ„ķ•˜ģ—¬ ķ†µģ œźµ¬ģ—­, ģ œķ•œźµ¬ģ—­, 접견구역 등 물리적 ė³“ķ˜øźµ¬ģ—­ ģ§€ģ •źø°ģ¤€ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","물리적 ė³“ķ˜øźµ¬ģ—­ 지정기준에 ė”°ė¼ ė³“ķ˜øźµ¬ģ—­ģ„ ģ§€ģ •ķ•˜ź³  구역별 ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ ė¬¼ė¦¬ė³“ģ•ˆ ģ§€ģ¹Øģ—ėŠ” ź°œģøģ •ė³“ ė³“ź“€ģ‹œģ„¤ ė° ģ‹œģŠ¤ķ…œ źµ¬ģ—­ģ„ ķ†µģ œźµ¬ģ—­ģœ¼ė”œ ģ§€ģ •ķ•œė‹¤ź³  ėŖ…ģ‹œė˜ģ–“ ģžˆģœ¼ė‚˜, 멤버십 ź°€ģž…ģ‹ ģ²­ ģ„œė„˜ź°€ ė³“ź“€ė˜ģ–“ ģžˆėŠ” ė¬øģ„œź³  등 ģ¼ė¶€ ėŒ€ģƒ źµ¬ģ—­ģ“ ķ†µģ œźµ¬ģ—­ģ—ģ„œ ėˆ„ė½ėœ 경우","사딀 2 : ė‚“ė¶€ ė¬¼ė¦¬ė³“ģ•ˆ 지침에 ķ†µģ œźµ¬ģ—­ģ— ėŒ€ķ•“ģ„œėŠ” ģ§€ģ •ėœ ģ–‘ģ‹ģ˜ ķ†µģ œźµ¬ģ—­ ķ‘œģ§€ķŒģ„ ģ„¤ģ¹˜ķ•˜ė„ė” ėŖ…ģ‹œķ•˜ź³  ģžˆģœ¼ė‚˜, ģ¼ė¶€ ķ†µģ œźµ¬ģ—­ģ— ķ‘œģ‹œķŒģ„ ģ„¤ģ¹˜ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제10ģ”°(물리적 ģ•ˆģ „ģ”°ģ¹˜)"]}],"description": "ė¬¼ė¦¬ģ Ā·ķ™˜ź²½ģ  ģœ„ķ˜‘ģœ¼ė”œė¶€ķ„° ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“, ė¬øģ„œ, ģ €ģž„ė§¤ģ²“, ģ£¼ģš” 설비 ė° ģ‹œģŠ¤ķ…œ ė“±ģ„ ė³“ķ˜øķ•˜źø° ģœ„ķ•˜ģ—¬ ķ†µģ œźµ¬ģ—­Ā·ģ œķ•œźµ¬ģ—­Ā·ģ ‘ź²¬źµ¬ģ—­ 등 물리적 ė³“ķ˜øźµ¬ģ—­ģ„ ģ§€ģ •ķ•˜ź³  구역별 ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.2": {"name": "ģ¶œģž…ķ†µģ œ","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.4.2 ģ¶œģž…ķ†µģ œ","Subdomain": "2.4. 물리 ė³“ģ•ˆ","AuditEvidence": ["ģ¶œģž… ź“€ė¦¬ėŒ€ģž„ ė° ģ¶œģž…ė”œź·ø","ģ¶œģž… ė“±ė” ģ‹ ģ²­ģ„œ ė° ģŠ¹ģø ė‚“ģ—­","ģ¶œģž…źø°ė” ź²€ķ† ģ„œ","ģ¶œģž…ķ†µģ œģ‹œģŠ¤ķ…œ ꓀리화멓(ģ¶œģž…ģž ė“±ė” ķ˜„ķ™© 등)"],"AuditChecklist": ["ė³“ķ˜øźµ¬ģ—­ģ€ ģ¶œģž…ģ ˆģ°Øģ— ė”°ė¼ ģ¶œģž…ģ“ ķ—ˆź°€ėœ ģžė§Œ ģ¶œģž…ķ•˜ė„ė” ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?","각 ė³“ķ˜øźµ¬ģ—­ģ— ėŒ€ķ•œ ė‚“Ā·ģ™øė¶€ģž ģ¶œģž…źø°ė”ģ„ ģ¼ģ •źø°ź°„ ė³“ģ”“ķ•˜ź³  ģ¶œģž…źø°ė” ė° ģ¶œģž…ź¶Œķ•œģ„ 주기적으딜 ź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķ†µģ œźµ¬ģ—­ģ„ ģ •ģ˜ķ•˜ģ—¬ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ģ¶œģž… ź°€ėŠ„ķ•œ ģž„ģ§ģ›ģ„ ź“€ė¦¬ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ¶œģž…źø°ė”ģ„ 주기적으딜 ź²€ķ† ķ•˜ģ§€ ģ•Šģ•„ 퇓직, ģ „ė°° 등에 따넸 ģž„źø° ėÆøģ¶œģž…ģžź°€ ė‹¤ģˆ˜ ģ”“ģž¬ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : 전산실, ė¬øģ„œź³  등 ķ†µģ œźµ¬ģ—­ģ— ģ¶œģž…ķ†µģ œ ģž„ģ¹˜ź°€ ģ„¤ģ¹˜ė˜ģ–“ ģžˆģœ¼ė‚˜, ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ė˜ėŠ” ģŠ¹ģø ģ—†ģ“ ģž„ģ‹œź°„ 개방 상태딜 ģœ ģ§€ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : ģ¼ė¶€ 외부 ķ˜‘ė „ģ—…ģ²“ ģ§ģ›ģ—ź²Œ ź³¼ė„ķ•˜ź²Œ ģ „ źµ¬ģ—­ģ„ ģƒģ‹œ ģ¶œģž…ķ•  수 ģžˆėŠ” ģ¶œģž…ģ¹“ė“œė„¼ ė¶€ģ—¬ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제10ģ”°(물리적 ģ•ˆģ „ģ”°ģ¹˜)"]}],"description": "ė³“ķ˜øźµ¬ģ—­ģ€ ģøź°€ėœ ģ‚¬ėžŒė§Œģ“ ģ¶œģž…ķ•˜ė„ė” ķ†µģ œķ•˜ź³  ģ±…ģž„ģ¶”ģ ģ„±ģ„ 확볓할 수 ģžˆė„ė” ģ¶œģž… ė° ģ ‘ź·¼ ģ“ė „ģ„ 주기적으딜 ź²€ķ† ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.3": {"name": "ģ •ė³“ģ‹œģŠ¤ķ…œ 볓호","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.4.3 ģ •ė³“ģ‹œģŠ¤ķ…œ 볓호","Subdomain": "2.4. 물리 ė³“ģ•ˆ","AuditEvidence": ["ģ •ė³“ģ²˜ė¦¬ģ‹œģ„¤ ė„ė©“","ģ •ė³“ģ‹œģŠ¤ķ…œ ė°°ģ¹˜ė„","ģžģ‚°ėŖ©ė”"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ¤‘ģš”ė„, ģš©ė„, ķŠ¹ģ„± ė“±ģ„ ź³ ė ¤ķ•˜ģ—¬ 배치 ģž„ģ†Œė„¼ ė¶„ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ‹¤ģ œ 물리적 ģœ„ģ¹˜ė„¼ ģ†ģ‰½ź²Œ ķ™•ģøķ•  수 ģžˆėŠ” ė°©ģ•ˆģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","ģ „ė „ ė° ķ†µģ‹ ģ¼€ģ“ėø”ģ„ ģ™øė¶€ė”œė¶€ķ„°ģ˜ 물리적 ģ†ģƒ ė° 전기적 ģ˜ķ–„ģœ¼ė”œė¶€ķ„° ģ•ˆģ „ķ•˜ź²Œ ė³“ķ˜øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ‹œģŠ¤ķ…œ ė°°ģ¹˜ė„ź°€ ģµœģ‹  ė³€ź²½ģ‚¬ķ•­ģ„ ė°˜ģ˜ķ•˜ģ—¬ ģ—…ė°ģ“ķŠøė˜ģ§€ ģ•Šģ•„ ģž„ģ• ź°€ ė°œģƒėœ ģ •ė³“ģ‹œģŠ¤ķ…œģ„ ģ‹ ģ†ķ•˜ź²Œ ķ™•ģøķ•  수 ģ—†ėŠ” 경우","사딀 2 : ģ„œė²„ģ‹¤ 바닄 ė˜ėŠ” ėž™ģ— ė§Žģ€ ģ¼€ģ“ėø”ģ“ ģ •ė¦¬ė˜ģ§€ ģ•Šź³  ė’¤ģ—‰ģ¼œ ģžˆģ–“ ģ „źø°ģ ģœ¼ė”œ ź°„ģ„­, ģ†ģƒ, ėˆ„ģˆ˜, ė¶€ģ£¼ģ˜ 등에 ģ˜ķ•œ ģž„ģ•  ė°œģƒģ“ ģš°ė ¤ė˜ėŠ” 경우"],"RelatedRegulations": []}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œģ€ ķ™˜ź²½ģ  ģœ„ķ˜‘ź³¼ ģœ ķ•“ģš”ģ†Œ, ė¹„ģøź°€ ģ ‘ź·¼ ź°€ėŠ„ģ„±ģ„ ź°ģ†Œģ‹œķ‚¬ 수 ģžˆė„ė” ģ¤‘ģš”ė„ģ™€ ķŠ¹ģ„±ģ„ ź³ ė ¤ķ•˜ģ—¬ ė°°ģ¹˜ķ•˜ź³ , 통신 ė° ģ „ė „ ģ¼€ģ“ėø”ģ“ ģ†ģƒģ„ ģž…ģ§€ ģ•Šė„ė” ė³“ķ˜øķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.4": {"name": "ė³“ķ˜øģ„¤ė¹„ 욓영","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.4.4 ė³“ķ˜øģ„¤ė¹„ 욓영","Subdomain": "2.4. 물리 ė³“ģ•ˆ","AuditEvidence": ["물리적 ė³“ģ•ˆ 지침(ė³“ķ˜øģ„¤ė¹„ ꓀련)","전산실 설비 ķ˜„ķ™© ė° ģ ź²€ķ‘œ","IDC ģœ„ķƒģš“ģ˜ ź³„ģ•½ģ„œ, SLA 등"],"AuditChecklist": ["각 ė³“ķ˜øźµ¬ģ—­ģ˜ ģ¤‘ģš”ė„ ė° ķŠ¹ģ„±ģ— ė”°ė¼ ķ™”ģž¬, ģˆ˜ķ•“, ģ „ė „ ģ“ģƒ 등 ģøģž¬ ė° ģžģ—°ģž¬ķ•“ 등에 ėŒ€ė¹„ķ•˜ģ—¬ ķ•„ģš”ķ•œ 설비넼 갖추고 욓영절차넼 ģˆ˜ė¦½ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","외부 ģ§‘ģ ģ •ė³“ķ†µģ‹ ģ‹œģ„¤(IDC)에 ģœ„ķƒ ģš“ģ˜ķ•˜ėŠ” 경우 물리적 ė³“ķ˜øģ— ķ•„ģš”ķ•œ ģš”źµ¬ģ‚¬ķ•­ģ„ ź³„ģ•½ģ„œģ— ė°˜ģ˜ķ•˜ź³  욓영상태넼 주기적으딜 ź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 본사 전산실 등 ģ¼ė¶€ ė³“ķ˜øźµ¬ģ—­ģ— ė‚“ė¶€ 지침에 ģ •ķ•œ ė³“ķ˜øģ„¤ė¹„ė„¼ 갖추고 ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : 전산실 낓에 UPS, ģ†Œķ™”ģ„¤ė¹„ ė“±ģ˜ ė³“ķ˜øģ„¤ė¹„ėŠ” 갖추고 ģžˆģœ¼ė‚˜, ꓀련 설비에 ėŒ€ķ•œ 욓영 ė° 점검 źø°ģ¤€ģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģš“ģ˜ģ§€ģ¹Øģ— ė”°ė¼ 전산실 낓에 ģ˜ØĀ·ģŠµė„ 씰절기넼 ģ„¤ģ¹˜ķ•˜ģ˜€ģœ¼ė‚˜, ģš©ėŸ‰ ė¶€ģ”±ģœ¼ė”œ ģøķ•˜ģ—¬ ķ‘œģ¤€ ģ˜ØĀ·ģŠµė„ė„¼ ģœ ģ§€ķ•˜ģ§€ ėŖ»ķ•˜ģ—¬ ģž„ģ• ė°œģƒ ź°€ėŠ„ģ„±ģ“ ė†’ģ€ 경우"],"RelatedRegulations": ["ģ •ė³“ķ†µģ‹ ė§ė²• 제46ģ”°(ģ§‘ģ ėœ ģ •ė³“ķ†µģ‹ ģ‹œģ„¤ģ˜ 볓호)","집적정볓 ķ†µģ‹ ģ‹œģ„¤ ė³“ķ˜øģ§€ģ¹Ø","ģ†Œė°©ģ‹œģ„¤ ģ„¤ģ¹˜ ė° ꓀리에 ź“€ķ•œ 법넠(ģ†Œė°©ģ‹œģ„¤ė²•) 제12ģ”°(ķŠ¹ģ •ģ†Œė°©ėŒ€ģƒė¬¼ģ— ģ„¤ģ¹˜ķ•˜ėŠ” ģ†Œė°©ģ‹œģ„¤ģ˜ ꓀리 등), 제16ģ”°(ķ”¼ė‚œģ‹œģ„¤, 방화구역 ė° ė°©ķ™”ģ‹œģ„¤ģ˜ ꓀리)"]}],"description": "ė³“ķ˜øźµ¬ģ—­ģ— ģœ„ģ¹˜ķ•œ ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ¤‘ģš”ė„ ė° ķŠ¹ģ„±ģ— ė”°ė¼ ģ˜ØĀ·ģŠµė„ 씰절, ķ™”ģž¬ź°ģ§€, ģ†Œķ™”ģ„¤ė¹„, ėˆ„ģˆ˜ź°ģ§€, UPS, ė¹„ģƒė°œģ „źø°, ģ“ģ¤‘ģ „ģ›ģ„  ė“±ģ˜ ė³“ķ˜øģ„¤ė¹„ė„¼ 갖추고 욓영절차넼 ģˆ˜ė¦½Ā·ģš“ģ˜ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.5": {"name": "ė³“ķ˜øźµ¬ģ—­ ė‚“ ģž‘ģ—…","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.4.5 ė³“ķ˜øźµ¬ģ—­ ė‚“ ģž‘ģ—…","Subdomain": "2.4. 물리 ė³“ģ•ˆ","AuditEvidence": ["ģž‘ģ—… ģ‹ ģ²­ģ„œ, ģž‘ģ—… ģ¼ģ§€","ķ†µģ œźµ¬ģ—­ ģ¶œģž… ėŒ€ģž„","ķ†µģ œźµ¬ģ—­ģ— ėŒ€ķ•œ ģ¶œģž…źø°ė” ė° ģž‘ģ—… źø°ė” 검토 ė‚“ģ—­"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ė„ģž…, ģœ ģ§€ė³“ģˆ˜ ė“±ģœ¼ė”œ ė³“ķ˜øźµ¬ģ—­ ė‚“ ģž‘ģ—…ģ“ ķ•„ģš”ķ•œ ź²½ģš°ģ— ėŒ€ķ•œ ź³µģ‹ģ ģø ģž‘ģ—…ģ‹ ģ²­ ė° ģˆ˜ķ–‰ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ķ˜øźµ¬ģ—­ ė‚“ ģž‘ģ—…ģ“ ķ†µģ œ ģ ˆģ°Øģ— ė”°ė¼ ģ ģ ˆķžˆ ģˆ˜ķ–‰ė˜ģ—ˆėŠ”ģ§€ 여부넼 ķ™•ģøķ•˜źø° ģœ„ķ•˜ģ—¬ ģž‘ģ—… źø°ė”ģ„ 주기적으딜 ź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 전산실 ģ¶œģž…ė”œź·øģ—ėŠ” 외부 ģœ ģ§€ė³“ģˆ˜ 업첓 ģ§ģ›ģ˜ ģ¶œģž…źø°ė”ģ“ 남아 ģžˆģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•œ ė³“ķ˜øźµ¬ģ—­ ģž‘ģ—… ģ‹ ģ²­ ė° ģŠ¹ģø ė‚“ģ—­ģ“ ģ”“ģž¬ķ•˜ģ§€ ģ•Šģ€ 경우(ė‚“ė¶€ ź·œģ •ģ— 따넸 ė³“ķ˜øźµ¬ģ—­ ģž‘ģ—… ģ‹ ģ²­ ģ—†ģ“ ė³“ķ˜øźµ¬ģ—­ ģ¶œģž… ė° ģž‘ģ—…ģ“ ģ“ė£Øģ–“ģ§€ź³  ģžˆėŠ” 경우)","사딀 2 : ė‚“ė¶€ ź·œģ •ģ—ėŠ” ė³“ķ˜øźµ¬ģ—­ ė‚“ ģž‘ģ—… źø°ė”ģ— ėŒ€ķ•˜ģ—¬ 분기별 1회 ģ“ģƒ ģ ź²€ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ķŠ¹ė³„ķ•œ ģ‚¬ģœ  ģ—†ģ“ ģž„źø°ź°„ ė™ģ•ˆ ė³“ķ˜øźµ¬ģ—­ ė‚“ ģž‘ģ—… źø°ė”ģ— ėŒ€ķ•œ ģ ź²€ģ“ ģ“ė£Øģ–“ģ§€ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ė³“ķ˜øźµ¬ģ—­ ė‚“ģ—ģ„œģ˜ ė¹„ģøź°€ķ–‰ģœ„ ė° ź¶Œķ•œ ģ˜¤Ā·ė‚Øģš© ė“±ģ„ ė°©ģ§€ķ•˜źø° ģœ„ķ•œ ģž‘ģ—… 절차넼 수립 ė°ģ“ķ–‰ķ•˜ź³ , ģž‘ģ—… źø°ė”ģ„ 주기적으딜 ź²€ķ† ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.6": {"name": "ė°˜ģ¶œģž… źø°źø° ķ†µģ œ","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.4.6 ė°˜ģ¶œģž… źø°źø° ķ†µģ œ","Subdomain": "2.4. 물리 ė³“ģ•ˆ","AuditEvidence": ["ė³“ķ˜øźµ¬ģ—­ ė‚“ ė°˜ģ¶œģž… ģ‹ ģ²­ģ„œ","ė°˜ģ¶œģž… ź“€ė¦¬ėŒ€ģž„","ė°˜ģ¶œģž… ģ“ė „ 검토 ź²°ź³¼"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œ, ėŖØė°”ģ¼ źø°źø°, ģ €ģž„ė§¤ģ²“ ė“±ģ„ ė³“ķ˜øźµ¬ģ—­ģ— ė°˜ģž…ķ•˜ź±°ė‚˜ ė°˜ģ¶œķ•˜ėŠ” 경우 ģ •ė³“ģœ ģ¶œ, ģ•…ģ„±ģ½”ė“œ 감염 등 ė³“ģ•ˆģ‚¬ź³  ģ˜ˆė°©ģ„ ģœ„ķ•œ ķ†µģ œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ė°˜ģ¶œģž… ķ†µģ œģ ˆģ°Øģ— 따넸 źø°ė”ģ„ ģœ ģ§€Ā·ź“€ė¦¬ķ•˜ź³ , 절차 ģ¤€ģˆ˜ 여부넼 ķ™•ģøķ•  수 ģžˆė„ė” ė°˜ģ¶œģž… ģ“ė „ģ„ 주기적으딜 ģ ź²€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ“ė™ģ»“ķ“ØķŒ…źø°źø° ė°˜ģ¶œģž…ģ— ėŒ€ķ•œ ķ†µģ œ 절차넼 ģˆ˜ė¦½ķ•˜ź³  ģžˆģœ¼ė‚˜, ķ†µģ œźµ¬ģ—­ ė‚“ ģ“ė™ģ»“ķ“ØķŒ…źø°źø° ė°˜ģž…ģ— ėŒ€ķ•œ ķ†µģ œė„¼ ķ•˜ź³  ģžˆģ§€ ģ•Šģ•„ ģ¶œģž…ģ“ ķ—ˆģš©ėœ ė‚“Ā·ģ™øė¶€ģøģ“ ģ“ė™ģ»“ķ“ØķŒ…źø°źø°ė„¼ ģ œģ•½ ģ—†ģ“ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : ė‚“ė¶€ 지침에 ė”°ė¼ ģ „ģ‚°ģž„ė¹„ ė°˜ģ¶œģž…ģ“ ģžˆėŠ” 경우 ģž‘ģ—…ź³„ķšģ„œģ— ė°˜ģ¶œģž… ė‚“ģš©ģ„ źø°ģž¬ķ•˜ź³  ꓀리 ģ±…ģž„ģžģ˜ ģ„œėŖ…ģ„ ė°›ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ģž‘ģ—…ź³„ķšģ„œģ˜ ė°˜ģ¶œģž… źø°ė”ģ— ź“€ė¦¬ģ±…ģž„ģžģ˜ ģ„œėŖ…ģ“ ė‹¤ģˆ˜ ėˆ„ė½ė˜ģ–“ ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제10ģ”°(물리적 ģ•ˆģ „ģ”°ģ¹˜)"]}],"description": "ė³“ķ˜øźµ¬ģ—­ ė‚“ ģ •ė³“ģ‹œģŠ¤ķ…œ, ėŖØė°”ģ¼ źø°źø°, ģ €ģž„ė§¤ģ²“ 등에 ėŒ€ķ•œ ė°˜ģ¶œģž… ķ†µģ œģ ˆģ°Øė„¼ 수립 ė°ģ“ķ–‰ķ•˜ź³  주기적으딜 ź²€ķ† ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.7": {"name": "ģ—…ė¬“ķ™˜ź²½ ė³“ģ•ˆ","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.4.7 ģ—…ė¬“ķ™˜ź²½ ė³“ģ•ˆ","Subdomain": "2.4. 물리 ė³“ģ•ˆ","AuditEvidence": ["사묓실 ė° ź³µģš©ź³µź°„ ė³“ģ•ˆģ ź²€ ė³“ź³ ģ„œ","사묓실 ė° ź³µģš©ź³µź°„ ė³“ģ•ˆģ ź²€ķ‘œ","ėÆøģ¤€ģˆ˜ģžģ— ėŒ€ķ•œ 씰치 사항(교윔, 상벌 등)","ģ¶œė „Ā·ė³µģ‚¬ė¬¼ 볓호씰치 ķ˜„ķ™©"],"AuditChecklist": ["ė¬øģ„œź³ , 공용 PC, 복합기, ķŒŒģ¼ģ„œė²„ 등 공용으딜 ģ‚¬ģš©ķ•˜ėŠ” ģ‹œģ„¤ ė° ģ‚¬ė¬“ģš© 기기에 ėŒ€ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ—…ė¬“ģš© PC, ģ±…ģƒ, ģ„œėž 등 ź°œģøģ—…ė¬“ ķ™˜ź²½ģ„ ķ†µķ•œ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ˜ ģœ Ā·ė…øģ¶œģ„ ė°©ģ§€ķ•˜źø° ģœ„ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ź°€ ķ¬ķ•Øėœ ģ¢…ģ“ ģøģ‡„ė¬¼ 등 ź°œģøģ •ė³“ģ˜ ģ¶œė „Ā·ė³µģ‚¬ė¬¼ģ„ ģ•ˆģ „ķ•˜ź²Œ ź“€ė¦¬ķ•˜źø° ģœ„ķ•“ ķ•„ģš”ķ•œ 볓호씰치넼 ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģø ė° ź³µģš©ģ—…ė¬“ ķ™˜ź²½ģ—ģ„œģ˜ ģ •ė³“ė³“ķ˜ø ģ¤€ģˆ˜ 여부넼 주기적으딜 ź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ„œ ė‚“ ź°œģøģ •ė³“ė³“ķ˜øė„¼ ģœ„ķ•œ ģƒķ™œė³“ģ•ˆ 점검(ķ“ė¦°ė°ģŠ¤ķ¬ 욓영 등)ģ„ ģ •źø°ģ ģœ¼ė”œ ģˆ˜ķ–‰ķ•˜ė„ė” ėŖ…ģ‹œķ•˜ź³  ģžˆģœ¼ė‚˜, ģ“ė„¼ ģ“ķ–‰ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : 멤버십 ź°€ģž…ģ‹ ģ²­ģ„œ 등 ź°œģøģ •ė³“ź°€ ķ¬ķ•Øėœ ģ„œė„˜ė„¼ ģž źøˆģž„ģ¹˜ź°€ ģ—†ėŠ” 사묓실 ė¬øģ„œķ•Øģ— ė³“ź“€ķ•œ 경우","사딀 3 : ģ§ģ›ė“¤ģ˜ 컓퓨터 ķ™”ė©“ė³“ķ˜øźø° ė° ķŒØģŠ¤ģ›Œė“œź°€ ģ„¤ģ •ė˜ģ–“ ģžˆģ§€ ģ•Šź³ , ķœ“ź°€ģž ģ±…ģƒ ģœ„ģ— ģ¤‘ģš”ė¬øģ„œź°€ ģž„źø°ź°„ ė°©ģ¹˜ė˜ģ–“ ģžˆėŠ” 경우","사딀 4 : ķšŒģ˜ģ‹¤ 등 공용 사묓 공간에 ģ„¤ģ¹˜ėœ 공용PC에 ėŒ€ķ•œ ė³“ķ˜øėŒ€ģ±…ģ“ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ•„ ź°œģøģ •ė³“ź°€ ķ¬ķ•Øėœ ķŒŒģ¼ģ“ ģ•”ķ˜øķ™”ė˜ģ§€ ģ•Šģ€ ģ±„ė”œ ģ €ģž„ė˜ģ–“ ģžˆź±°ė‚˜, ė³“ģ•ˆ ģ—…ė°ģ“ķŠø 미적용, 백신 ėÆøģ„¤ģ¹˜ 등 ģ·Øģ•½ķ•œ 상태딜 ģœ ģ§€ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제10ģ”°(물리적 ģ•ˆģ „ģ”°ģ¹˜), 제12ģ”°(ģ¶œė „Ā·ė³µģ‚¬ģ‹œ ģ•ˆģ „ģ”°ģ¹˜)"]}],"description": "공용으딜 ģ‚¬ģš©ķ•˜ėŠ” ģ‚¬ė¬“ģš© źø°źø°(ė¬øģ„œź³ , 공용 PC, 복합기, ķŒŒģ¼ģ„œė²„ 등) ė° ź°œģø ģ—…ė¬“ķ™˜ź²½(ģ—…ė¬“ģš© PC, ģ±…ģƒ 등)ģ„ ķ†µķ•˜ģ—¬ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ź°€ ė¹„ģøź°€ģžģ—ź²Œ ė…øģ¶œ ė˜ėŠ” ģœ ģ¶œė˜ģ§€ ģ•Šė„ė” ķ“ė¦°ė°ģŠ¤ķ¬, 정기점검 등 ģ—…ė¬“ķ™˜ź²½ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.5.1": {"name": "ģ‚¬ģš©ģž 계정 ꓀리","checks": {"iam_user_accesskey_unused": null,"iam_securityaudit_role_created": null,"iam_user_console_access_unused": null,"iam_policy_no_full_access_to_kms": null,"iam_role_administratoraccess_policy": null,"iam_user_administrator_access_policy": null,"organizations_scp_check_deny_regions": null,"iam_group_administrator_access_policy": null,"iam_policy_allows_privilege_escalation": null,"iam_inline_policy_no_full_access_to_kms": null,"iam_policy_no_full_access_to_cloudtrail": null,"iam_policy_attached_only_to_group_or_roles": null,"cognito_user_pool_self_registration_disabled": null,"iam_role_cross_account_readonlyaccess_policy": null,"iam_inline_policy_allows_privilege_escalation": null,"iam_inline_policy_no_administrative_privileges": null,"iam_inline_policy_no_full_access_to_cloudtrail": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_role_cross_service_confused_deputy_prevention": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"iam_customer_unattached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.5.1 ģ‚¬ģš©ģž 계정 ꓀리","Subdomain": "2.5. ģøģ¦ ė° ź¶Œķ•œź“€ė¦¬","AuditEvidence": ["ģ‚¬ģš©ģž 계정 ė° ź¶Œķ•œ ģ‹ ģ²­ģ„œ","ģ‚¬ģš©ģž 계정 ė° ź¶Œķ•œ ź“€ė¦¬ėŒ€ģž„ ė˜ėŠ” 화멓","ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œė³„ ģ ‘ź·¼ź¶Œķ•œ ė¶„ė„˜ķ‘œ","ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œė³„ ģ‚¬ģš©ģž, ź“€ė¦¬ģž, ź°œģøģ •ė³“ģ·Øźø‰ģž ėŖ©ė”"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œź³¼ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ— 접근할 수 ģžˆėŠ” ģ‚¬ģš©ģž 계정 ė° ģ ‘ź·¼ź¶Œķ•œģ˜ ė“±ė”Ā·ė³€ź²½Ā·ģ‚­ģ œģ— ź“€ķ•œ ź³µģ‹ģ ģø 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œź³¼ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ— 접근할 수 ģžˆėŠ” ģ‚¬ģš©ģž 계정 ė° ģ ‘ź·¼ź¶Œķ•œ ģƒģ„± ė° ė“±ė”Ā·ė³€ź²½ ģ‹œ 직묓별 ģ ‘ź·¼ź¶Œķ•œ ė¶„ė„˜ 첓계에 ė”°ė¼ ģ—…ė¬“ģƒ ķ•„ģš”ķ•œ ģµœģ†Œķ•œģ˜ ź¶Œķ•œė§Œģ„ ė¶€ģ—¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ‚¬ģš©ģžģ—ź²Œ 계정 ė° ģ ‘ź·¼ź¶Œķ•œģ„ ė¶€ģ—¬ķ•˜ėŠ” 경우 핓당 계정에 ėŒ€ķ•œ ė³“ģ•ˆģ±…ģž„ģ“ ė³øģøģ—ź²Œ ģžˆģŒģ„ ėŖ…ķ™•ķžˆ ģøģ‹ģ‹œķ‚¤ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ‚¬ģš©ģž ė° ź°œģøģ •ė³“ģ·Øźø‰ģžģ— ėŒ€ķ•œ ź³„ģ •Ā·ź¶Œķ•œģ— ėŒ€ķ•œ ģ‚¬ģš©ģž ė“±ė”, ķ•“ģ§€ ė° ģŠ¹ģøģ ˆģ°Ø ģ—†ģ“ 구두 ģš”ģ²­, ģ“ė©”ģ¼ ė“±ģœ¼ė”œ ģ²˜ė¦¬ķ•˜ģ—¬ ģ“ģ— ėŒ€ķ•œ ģŠ¹ģø ė° 처리 ģ“ė „ģ“ ķ™•ģøė˜ģ§€ ģ•ŠėŠ” 경우","사딀 2 : ź°œģøģ •ė³“ģ·Øźø‰ģžź°€ ķœ“ź°€, ģ¶œģž„, 공가 등에 따넸 업묓 ė°±ģ—…ģ„ ģ‚¬ģœ ė”œ ź³µģ‹ģ ģø 절차넼 ź±°ģ¹˜ģ§€ ģ•Šź³  ź°œģøģ •ė³“ģ·Øźø‰ģžė”œ ģ§€ģ •ė˜ģ§€ ģ•Šģ€ ģøģ›ģ—ź²Œ ź°œģøģ •ė³“ģ·Øźø‰ģž ź³„ģ •ģ„ ģ•Œė ¤ģ£¼ėŠ” 경우","사딀 3 : ģ •ė³“ģ‹œģŠ¤ķ…œ ė˜ėŠ” ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ģ‚¬ģš©ģžģ—ź²Œ ķ•„ģš” ģ“ģƒģ˜ ź³¼ė„ķ•œ ź¶Œķ•œģ„ ė¶€ģ—¬ķ•˜ģ—¬ ģ—…ė¬“ģƒ ė¶ˆķ•„ģš”ķ•œ 정볓 ė˜ėŠ” ź°œģøģ •ė³“ģ— ģ ‘ź·¼ģ“ ź°€ėŠ„ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ ź¶Œķ•œģ˜ ꓀리)"]}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œź³¼ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ— ėŒ€ķ•œ ė¹„ģøź°€ ģ ‘ź·¼ģ„ ķ†µģ œķ•˜ź³  업묓 목적에 따넸 ģ ‘ź·¼ź¶Œķ•œģ„ ģµœģ†Œķ•œģœ¼ė”œ 부여할 수 ģžˆė„ė” ģ‚¬ģš©ģž ė“±ė”Ā·ķ•“ģ§€ ė° ģ ‘ź·¼ź¶Œķ•œ ė¶€ģ—¬Ā·ė³€ź²½Ā·ė§ģ†Œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ , ģ‚¬ģš©ģž ė“±ė” ė° ź¶Œķ•œė¶€ģ—¬ ģ‹œ ģ‚¬ģš©ģžģ—ź²Œ ė³“ģ•ˆģ±…ģž„ģ“ ģžˆģŒģ„ ź·œģ •ķ™”ķ•˜ź³  ģøģ‹ģ‹œģ¼œģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 22,"manual": 0}},"2.5.2": {"name": "ģ‚¬ģš©ģž ģ‹ė³„","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.5.2 ģ‚¬ģš©ģž ģ‹ė³„","Subdomain": "2.5. ģøģ¦ ė° ź¶Œķ•œź“€ė¦¬","AuditEvidence": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ė”œź·øģø 화멓","ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ź“€ė¦¬ģž, ģ‚¬ģš©ģž, ź°œģøģ •ė³“ģ·Øźø‰ģž 계정 ėŖ©ė”","ģ˜ˆģ™ø ģ²˜ė¦¬ģ— ėŒ€ķ•œ ģŠ¹ģø ė‚“ģ—­"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ—ģ„œ ģ‚¬ģš©ģž ė° ź°œģøģ •ė³“ģ·Øźø‰ģžė„¼ ģœ ģ¼ķ•˜ź²Œ 구분할 수 ģžˆėŠ” ģ‹ė³„ģžė„¼ ķ• ė‹¹ķ•˜ź³  추츔 ź°€ėŠ„ķ•œ ģ‹ė³„ģžģ˜ ģ‚¬ģš©ģ„ ģ œķ•œķ•˜ź³  ģžˆėŠ”ź°€?","ė¶ˆź°€ķ”¼ķ•œ ģ‚¬ģœ ė”œ ė™ģ¼ķ•œ ģ‹ė³„ģžė„¼ ź³µģœ ķ•˜ģ—¬ ģ‚¬ģš©ķ•˜ėŠ” 경우 ź·ø ģ‚¬ģœ ģ™€ ķƒ€ė‹¹ģ„±ģ„ ź²€ķ† ķ•˜ź³  ė³“ģ™„ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ģ—¬ ģ±…ģž„ģžģ˜ ģŠ¹ģøģ„ 받고 ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ģ‹œģŠ¤ķ…œ(ģ„œė²„, ė„¤ķŠøģ›Œķ¬, ģ¹Øģž…ģ°Øė‹Øģ‹œģŠ¤ķ…œ, DBMS 등)ģ˜ 계정 ķ˜„ķ™©ģ„ ķ™•ģøķ•œ ź²°ź³¼, ģ œģ”°ģ‚¬ģ—ģ„œ ģ œź³µķ•˜ėŠ” źø°ė³ø ź“€ė¦¬ģž ź³„ģ •ģ„ 기술적으딜 변경 ź°€ėŠ„ķ•Øģ—ė„ ė¶ˆźµ¬ķ•˜ź³  ė³€ź²½ķ•˜ģ§€ ģ•Šź³  ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : ź°œė°œģžź°€ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ź³„ģ •ģ„ 공용으딜 ģ‚¬ģš©ķ•˜ź³  ģžˆģœ¼ė‚˜, ķƒ€ė‹¹ģ„± 검토 ė˜ėŠ” ģ±…ģž„ģžģ˜ ģŠ¹ģø ė“±ģ“ ģ—†ģ“ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : ģ™øė¶€ģ§ģ›ģ“ ģœ ģ§€ė³“ģˆ˜ķ•˜ź³  ģžˆėŠ” ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģš“ģ˜ź³„ģ •ģ„ ė³„ė„ģ˜ ģŠ¹ģø 절차 ģ—†ģ“ ź°œģø ź³„ģ •ģ²˜ėŸ¼ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ ź¶Œķ•œģ˜ ꓀리)"]}],"description": "ģ‚¬ģš©ģž ź³„ģ •ģ€ ģ‚¬ģš©ģžė³„ė”œ ģœ ģ¼ķ•˜ź²Œ 구분할 수 ģžˆė„ė” ģ‹ė³„ģžė„¼ ķ• ė‹¹ķ•˜ź³  추츔 ź°€ėŠ„ķ•œ ģ‹ė³„ģž ģ‚¬ģš©ģ„ ģ œķ•œķ•˜ģ—¬ģ•¼ ķ•˜ė©°, ė™ģ¼ķ•œ ģ‹ė³„ģžė„¼ ź³µģœ ķ•˜ģ—¬ ģ‚¬ģš©ķ•˜ėŠ” 경우 ź·ø ģ‚¬ģœ ģ™€ ķƒ€ė‹¹ģ„±ģ„ ź²€ķ† ķ•˜ģ—¬ ģ±…ģž„ģžģ˜ ģŠ¹ģø ė° ģ±…ģž„ģ¶”ģ ģ„± 확볓 등 ė³“ģ™„ėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.5.3": {"name": "ģ‚¬ģš©ģž ģøģ¦","checks": {"iam_root_mfa_enabled": null,"iam_user_accesskey_unused": null,"iam_check_saml_providers_sts": null,"cognito_user_pool_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_hardware_mfa_enabled": null,"iam_user_two_active_access_key": null,"iam_administrator_access_with_mfa": null,"iam_user_mfa_enabled_console_access": null,"iam_user_with_temporary_credentials": null,"apigatewayv2_api_authorizers_enabled": "FAIL","iam_user_no_setup_initial_access_key": null,"apigateway_restapi_authorizers_enabled": "PASS","rds_cluster_iam_authentication_enabled": "FAIL","rds_instance_iam_authentication_enabled": "FAIL","kafka_cluster_unrestricted_access_disabled": null,"cognito_identity_pool_guest_access_disabled": "FAIL","cognito_user_pool_advanced_security_enabled": null,"cognito_user_pool_self_registration_disabled": null,"directoryservice_supported_mfa_radius_enabled": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cognito_user_pool_client_token_revocation_enabled": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cognito_user_pool_client_prevent_user_existence_errors": null,"opensearch_service_domains_internal_user_database_enabled": null,"cognito_user_pool_blocks_potential_malicious_sign_in_attempts": null,"opensearch_service_domains_use_cognito_authentication_for_kibana": null,"cognito_user_pool_blocks_compromised_credentials_sign_in_attempts": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.5.3 ģ‚¬ģš©ģž ģøģ¦","Subdomain": "2.5. ģøģ¦ ė° ź¶Œķ•œź“€ė¦¬","AuditEvidence": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ė”œź·øģø 화멓","ė”œź·øģø 횟수 ģ œķ•œ 설정 화멓","ė”œź·øģø ģ‹¤ķŒØ ė©”ģ‹œģ§€ 화멓","외부 ģ ‘ģ† ģ‹œ 절차(ģ™øė¶€ģ ‘ģ† ģ‹ ģ²­ģ„œ, ģ™øė¶€ģ ‘ģ†ģž ķ˜„ķ™© 등)"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ģ ‘ź·¼ģ€ ģ‚¬ģš©ģž ģøģ¦, ė”œź·øģø 횟수 ģ œķ•œ, ė¶ˆė²• ė”œź·øģø ģ‹œė„ 경고 등 ģ•ˆģ „ķ•œ ģ‚¬ģš©ģž ģøģ¦ ģ ˆģ°Øģ— ė”°ė¼ ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ķ†µģ‹ ė§ģ„ ķ†µķ•˜ģ—¬ ģ™øė¶€ģ—ģ„œ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— ģ ‘ģ†ķ•˜ė ¤ėŠ” ź²½ģš°ģ—ėŠ” 법적 ģš”źµ¬ģ‚¬ķ•­ģ— ė”°ė¼ ģ•ˆģ „ķ•œ ģøģ¦ģˆ˜ė‹Ø ė˜ėŠ” ģ•ˆģ „ķ•œ ģ ‘ģ†ģˆ˜ė‹Øģ„ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ģ·Øźø‰ģžź°€ 공개된 외부 ģøķ„°ė„·ė§ģ„ ķ†µķ•˜ģ—¬ ģ“ģš©ģžģ˜ ź°œģøģ •ė³“ė„¼ ģ²˜ė¦¬ķ•˜ėŠ” ź°œģøģ •ė³“ģ²˜ė¦¬ ģ‹œģŠ¤ķ…œģ— ģ ‘ź·¼ ģ‹œ ģ•ˆģ „ķ•œ ģøģ¦ģˆ˜ė‹Øģ„ ģ ģš©ķ•˜ģ§€ ģ•Šź³  IDĀ·ė¹„ė°€ė²ˆķ˜ø ė°©ģ‹ģœ¼ė”œė§Œ ģøģ¦ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ė”œź·øģø ģ‹¤ķŒØ ģ‹œ 핓당 IDź°€ ģ”“ģž¬ķ•˜ģ§€ ģ•Šź±°ė‚˜ ė¹„ė°€ė²ˆķ˜øź°€ ķ‹€ė¦¼ģ„ ģžģ„øķžˆ ķ‘œģ‹œķ•“ 주고 ģžˆģœ¼ė©°, ė”œź·øģø ģ‹¤ķŒØķšŸģˆ˜ģ— ėŒ€ķ•œ ģ œķ•œģ“ ģ—†ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ ź¶Œķ•œģ˜ ꓀리), 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œź³¼ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ— ėŒ€ķ•œ ģ‚¬ģš©ģžģ˜ ģ ‘ź·¼ģ€ ģ•ˆģ „ķ•œ ģøģ¦ģ ˆģ°Øģ™€ ķ•„ģš”ģ— ė”°ė¼ ź°•ķ™”ėœ ģøģ¦ė°©ģ‹ģ„ ģ ģš©ķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ė˜ķ•œ ė”œź·øģø 횟수 ģ œķ•œ, ė¶ˆė²• ė”œź·øģø ģ‹œė„ 경고 등 ė¹„ģøź°€ģž ģ ‘ź·¼ ķ†µģ œė°©ģ•ˆģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 4,"pass": 1,"total": 29,"manual": 0}},"2.5.4": {"name": "ė¹„ė°€ė²ˆķ˜ø ꓀리","checks": {"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_password_policy_minimum_length_14": null,"cognito_user_pool_password_policy_number": null,"cognito_user_pool_password_policy_symbol": null,"cognito_user_pool_password_policy_lowercase": null,"cognito_user_pool_password_policy_uppercase": null,"cognito_user_pool_temporary_password_expiration": null,"cognito_user_pool_password_policy_minimum_length_14": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.5.4 ė¹„ė°€ė²ˆķ˜ø ꓀리","Subdomain": "2.5. ģøģ¦ ė° ź¶Œķ•œź“€ė¦¬","AuditEvidence": ["ģ›¹ķŽ˜ģ“ģ§€, ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ė¹„ė°€ė²ˆķ˜ø 설정 화멓","ė¹„ė°€ė²ˆķ˜ø ꓀리 ģ •ģ±… ė° 절차"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ģ•ˆģ „ķ•œ ģ‚¬ģš©ģž ė¹„ė°€ė²ˆķ˜ø ź“€ė¦¬ģ ˆģ°Ø ė° ģž‘ģ„±ź·œģ¹™ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","정볓주첓(ģ“ģš©ģž)ź°€ ģ•ˆģ „ķ•œ ė¹„ė°€ė²ˆķ˜øė„¼ ģ“ģš©ķ•  수 ģžˆė„ė” ė¹„ė°€ė²ˆķ˜ø ģž‘ģ„±ź·œģ¹™ģ„ 수립 ė° ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ģ·Øźø‰ģž ė˜ėŠ” ģ •ė³“ģ£¼ģ²“ģ˜ ģøģ¦ģˆ˜ė‹Øģ„ ģ•ˆģ „ķ•˜ź²Œ ģ ģš©ķ•˜ź³  ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ •ģ±…, 지침 ė“±ģ—ģ„œ ė¹„ė°€ė²ˆķ˜ø ģƒģ„±ź·œģ¹™ģ˜ źø°ģ¤€ģ„ ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ¼ė¶€ ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ—ģ„œ ė‚“ė¶€ 지침과 ģƒģ“ķ•œ ė¹„ė°€ė²ˆķ˜øė„¼ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : ė¹„ė°€ė²ˆķ˜ø ꓀련 ė‚“ė¶€ ź·œģ •ģ—ėŠ” ė¹„ė°€ė²ˆķ˜øė„¼ ģ“ˆźø°ķ™” ģ‹œ ģž„ģ‹œ ė¹„ė°€ė²ˆķ˜øė„¼ 부여받고 ź°•ģ œģ ģœ¼ė”œ ė³€ź²½ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ģ‹¤ģ œė”œėŠ” ģž„ģ‹œ ė¹„ė°€ė²ˆķ˜øė„¼ ź·øėŒ€ė”œ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : ė¹„ė°€ė²ˆķ˜ø ꓀련 ė‚“ė¶€ ź·œģ •ģ—ėŠ” ģ‚¬ģš©ģž ė° ź°œģøģ •ė³“ģ·Øźø‰ģžģ˜ ė¹„ė°€ė²ˆķ˜ø 변경주기넼 ģ •ķ•˜ź³  ģ“ķ–‰ķ•˜ė„ė” ķ•˜ź³  ģžˆģŒģ—ė„ ė¶ˆźµ¬ķ•˜ź³  ė³€ź²½ķ•˜ģ§€ ģ•Šź³  ź·øėŒ€ė”œ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ ź¶Œķ•œģ˜ ꓀리)"]}],"description": "법적 ģš”źµ¬ģ‚¬ķ•­, 외부 ģœ„ķ˜‘ģš”ģø ė“±ģ„ ź³ ė ¤ķ•˜ģ—¬ ģ •ė³“ģ‹œģŠ¤ķ…œ ģ‚¬ģš©ģž ė° ź³ ź°, ķšŒģ› 등 정볓주첓(ģ“ģš©ģž)ź°€ ģ‚¬ģš©ķ•˜ėŠ” ė¹„ė°€ė²ˆķ˜ø ź“€ė¦¬ģ ˆģ°Øė„¼ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 13,"manual": 0}},"2.5.5": {"name": "특수 계정 ė° ź¶Œķ•œ ꓀리","checks": {"iam_avoid_root_usage": null,"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_support_role_created": null,"rds_cluster_default_admin": "FAIL","rds_instance_default_admin": "FAIL","ec2_instance_profile_attached": "PASS","iam_root_hardware_mfa_enabled": null,"organizations_delegated_administrators": null,"cloudwatch_log_metric_filter_root_usage": null,"sagemaker_notebook_instance_root_access_disabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.5.5 특수 계정 ė° ź¶Œķ•œ ꓀리","Subdomain": "2.5. ģøģ¦ ė° ź¶Œķ•œź“€ė¦¬","AuditEvidence": ["ķŠ¹ģˆ˜ź¶Œķ•œ ꓀련 지침","ķŠ¹ģˆ˜ź¶Œķ•œ ģ‹ ģ²­Ā·ģŠ¹ģø ė‚“ģ—­","ķŠ¹ģˆ˜ź¶Œķ•œģž ėŖ©ė”","ķŠ¹ģˆ˜ź¶Œķ•œ 검토 ė‚“ģš©"],"AuditChecklist": ["ź“€ė¦¬ģž ź¶Œķ•œ 등 ķŠ¹ģˆ˜ź¶Œķ•œģ€ ģµœģ†Œķ•œģ˜ ģøģ›ģ—ź²Œė§Œ 부여될 수 ģžˆė„ė” ź³µģ‹ģ ģø ź¶Œķ•œ ģ‹ ģ²­ ė° ģŠ¹ģø 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","특수 ėŖ©ģ ģ„ ģœ„ķ•˜ģ—¬ ė¶€ģ—¬ķ•œ 계정 ė° ź¶Œķ•œģ„ ģ‹ė³„ķ•˜ź³  ė³„ė„ ėŖ©ė”ģœ¼ė”œ ź“€ė¦¬ķ•˜ėŠ” 등 ķ†µģ œģ ˆģ°Øė„¼ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ź“€ė¦¬ģž ė° ķŠ¹ģˆ˜ź¶Œķ•œ 부여 ė“±ģ˜ ģŠ¹ģø ģ“ė „ģ“ ģ‹œģŠ¤ķ…œģ“ė‚˜ ė¬øģ„œģƒģœ¼ė”œ ķ™•ģøģ“ ė˜ģ§€ ģ•Šź±°ė‚˜, ģŠ¹ģø ģ“ė „ź³¼ ķŠ¹ģˆ˜ź¶Œķ•œ ė‚“ģ—­ģ“ ģ„œė”œ ģ¼ģ¹˜ė˜ģ§€ ģ•ŠėŠ” 경우","사딀 2 : ė‚“ė¶€ ź·œģ •ģ—ėŠ” ź°œģøģ •ė³“ ź“€ė¦¬ģž ė° ķŠ¹ģˆ˜ź¶Œķ•œ ė³“ģœ ģžė„¼ ėŖ©ė”ģœ¼ė”œ ģž‘ģ„±Ā·ź“€ė¦¬ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜ ģ“ė„¼ ģž‘ģ„±Ā·ź“€ė¦¬ķ•˜ź³  ģžˆģ§€ ģ•Šź±°ė‚˜, ė³“ģ•ˆģ‹œģŠ¤ķ…œ ź“€ė¦¬ģž 등 ģ¼ė¶€ ķŠ¹ģˆ˜ź¶Œķ•œģ“ ģ‹ė³„Ā·ź“€ė¦¬ė˜ģ§€ ģ•ŠėŠ” 경우","사딀 3 : ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ģœ ģ§€ė³“ģˆ˜ė„¼ ģœ„ķ•˜ģ—¬ ė¶„źø° 1ķšŒģ— ė°©ė¬øķ•˜ėŠ” ģœ ģ§€ė³“ģˆ˜ģš© 특수 ź³„ģ •ģ“ ģ‚¬ģš©źø°ź°„ ģ œķ•œģ—†ģ“ ģƒģ‹œė”œ ķ™œģ„±ķ™”ė˜ģ–“ ģžˆėŠ” 경우","사딀 4 : ź“€ė¦¬ģž ė° ķŠ¹ģˆ˜ź¶Œķ•œģ˜ ģ‚¬ģš© 여부넼 ģ •źø°ģ ģœ¼ė”œ ź²€ķ† ķ•˜ģ§€ ģ•Šģ•„ ģ¼ė¶€ ķŠ¹ģˆ˜ź¶Œķ•œģžģ˜ 업묓가 ė³€ź²½ė˜ģ—ˆģŒģ—ė„ ė¶ˆźµ¬ķ•˜ź³  기씓 ź“€ė¦¬ģž ė° ķŠ¹ģˆ˜ź¶Œķ•œģ„ ź³„ģ† ė³“ģœ ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ ź¶Œķ•œģ˜ ꓀리)"]}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œ ꓀리, ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ ꓀리 등 특수 ėŖ©ģ ģ„ ģœ„ķ•˜ģ—¬ ģ‚¬ģš©ķ•˜ėŠ” 계정 ė° ź¶Œķ•œģ€ ģµœģ†Œķ•œģœ¼ė”œ ė¶€ģ—¬ķ•˜ź³  ė³„ė„ė”œ ģ‹ė³„ķ•˜ģ—¬ ķ†µģ œķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 2,"pass": 1,"total": 11,"manual": 0}},"2.5.6": {"name": "ģ ‘ź·¼ź¶Œķ•œ 검토","checks": {"accessanalyzer_enabled": "PASS","cloudtrail_insights_exist": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","accessanalyzer_enabled_without_findings": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_cross_account_sharing_disabled": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cloudtrail_multi_region_enabled_logging_management_events": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.5.6 ģ ‘ź·¼ź¶Œķ•œ 검토","Subdomain": "2.5. ģøģ¦ ė° ź¶Œķ•œź“€ė¦¬","AuditEvidence": ["ģ ‘ź·¼ź¶Œķ•œ 검토 기준 ė° 절차","ģ ‘ź·¼ź¶Œķ•œ 검토 ģ“ė „","ģ ‘ź·¼ź¶Œķ•œ 검토 ź²°ź³¼ė³“ź³ ģ„œ ė° ķ›„ģ†ģ”°ģ¹˜ ė‚“ģ—­"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œź³¼ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ— ėŒ€ķ•œ ģ‚¬ģš©ģž 계정 ė° ģ ‘ź·¼ź¶Œķ•œ ģƒģ„±Ā·ė“±ė”Ā·ė¶€ģ—¬ ė° ģ“ģš©Ā·ė³€ź²½Ā·ė§ģ†Œ ė“±ģ˜ ģ“ė „ģ„ 남기고 ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œź³¼ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ— ėŒ€ķ•œ ģ‚¬ģš©ģž 계정 ė° ģ ‘ź·¼ź¶Œķ•œģ˜ 적정성 검토 기준, 검토주첓, 검토방법, 주기 ė“±ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ 정기적 검토넼 ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ ‘ź·¼ź¶Œķ•œ 검토 ź²°ź³¼ ģ ‘ź·¼ź¶Œķ•œ 과다 부여, ź¶Œķ•œė¶€ģ—¬ 절차 ėÆøģ¤€ģˆ˜, ź¶Œķ•œ ģ˜¤Ā·ė‚Øģš© 등 ė¬øģ œģ ģ“ 발견된 경우 그에 따넸 씰치절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ ‘ź·¼ź¶Œķ•œ 검토와 ź“€ė Øėœ 방법, 점검주기, 볓고첓계, ģ˜¤Ā·ė‚Øģš© 기준 ė“±ģ“ ꓀련 지침에 구첓적으딜 ģ •ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ•„ ģ ‘ź·¼ź¶Œķ•œ 검토가 ģ •źø°ģ ģœ¼ė”œ ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ė‚“ė¶€ ģ •ģ±…, 지침 등에 ģž„źø° ėÆøģ‚¬ģš©ģž 계정에 ėŒ€ķ•œ ģž źøˆ(ė¹„ķ™œģ„±ķ™”) ė˜ėŠ” ģ‚­ģ œ ģ”°ģ¹˜ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, 6ź°œģ›” ģ“ģƒ ėÆøģ ‘ģ†ķ•œ ģ‚¬ģš©ģžģ˜ ź³„ģ •ģ“ ķ™œģ„±ķ™”ė˜ģ–“ ģžˆėŠ” 경우(ģ ‘ź·¼ź¶Œķ•œ 검토가 ģ¶©ģ‹¤ķžˆ ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ•„ 핓당 ź³„ģ •ģ“ ģ‹ė³„ė˜ģ§€ ģ•Šģ€ 경우)","사딀 3 : ģ ‘ź·¼ź¶Œķ•œ 검토 ģ‹œ ģ ‘ź·¼ź¶Œķ•œģ˜ 과다 부여 ė° ģ˜¤Ā·ė‚Øģš© ģ˜ģ‹¬ģ‚¬ė”€ź°€ ė°œź²¬ė˜ģ—ˆģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•œ ģƒģ„øģ”°ģ‚¬, 낓부볓고 ė“±ģ˜ ķ›„ģ†ģ”°ģ¹˜ź°€ ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ ź¶Œķ•œģ˜ ꓀리)"]}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œź³¼ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ— ģ ‘ź·¼ķ•˜ėŠ” ģ‚¬ģš©ģž ź³„ģ •ģ˜ ė“±ė”Ā·ģ“ģš©Ā·ģ‚­ģ œ ė° ģ ‘ź·¼ź¶Œķ•œģ˜ ė¶€ģ—¬Ā·ė³€ź²½Ā·ģ‚­ģ œ ģ“ė „ģ„ 남기고 주기적으딜 ź²€ķ† ķ•˜ģ—¬ 적정성 여부넼 ģ ź²€ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 2,"pass": 1,"total": 14,"manual": 0}},"2.6.1": {"name": "ė„¤ķŠøģ›Œķ¬ ģ ‘ź·¼","checks": {"ec2_ami_public": null,"elb_internet_facing": "FAIL","ec2_elastic_ip_shodan": null,"elbv2_internet_facing": "PASS","ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","kafka_cluster_is_public": null,"s3_bucket_acl_prohibited": "FAIL","apigateway_restapi_public": "FAIL","lightsail_database_public": null,"lightsail_instance_public": null,"ec2_securitygroup_not_used": "FAIL","elbv2_listeners_underneath": "PASS","networkfirewall_in_all_vpc": "FAIL","s3_bucket_public_write_acl": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","ssm_documents_set_as_public": "PASS","awslambda_function_url_public": null,"dms_instance_no_public_access": null,"rds_instance_no_public_access": "PASS","emr_cluster_publicly_accesible": null,"redshift_cluster_public_access": null,"neptune_cluster_public_snapshot": null,"eks_cluster_private_nodes_enabled": null,"awslambda_function_url_cors_policy": null,"documentdb_cluster_public_snapshot": null,"eks_cluster_network_policy_enabled": null,"neptune_cluster_uses_public_subnet": null,"sns_topics_not_publicly_accessible": "PASS","sqs_queues_not_publicly_accessible": "PASS","vpc_subnet_no_public_ip_by_default": "FAIL","vpc_subnet_separate_private_public": "FAIL","eks_cluster_not_publicly_accessible": null,"glacier_vaults_policy_public_access": null,"iam_user_mfa_enabled_console_access": null,"s3_access_point_public_access_block": "PASS","s3_bucket_level_public_access_block": "PASS","iam_user_administrator_access_policy": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"iam_group_administrator_access_policy": null,"s3_account_level_public_access_blocks": null,"apigateway_restapi_authorizers_enabled": "PASS","elasticache_cluster_uses_public_subnet": "PASS","rds_instance_iam_authentication_enabled": "FAIL","appstream_fleet_maximum_session_duration": null,"ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ecr_repositories_not_publicly_accessible": "PASS","emr_cluster_account_public_block_enabled": "PASS","sagemaker_models_vpc_settings_configured": null,"apigateway_restapi_public_with_authorizer": "FAIL","ec2_instance_port_ftp_exposed_to_internet": "PASS","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","vpc_endpoint_connections_trust_boundaries": "FAIL","appstream_fleet_session_disconnect_timeout": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_instance_port_cifs_exposed_to_internet": "PASS","ec2_instance_port_ldap_exposed_to_internet": "PASS","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","kafka_cluster_unrestricted_access_disabled": null,"sagemaker_models_network_isolation_enabled": null,"cognito_identity_pool_guest_access_disabled": "FAIL","ec2_instance_port_kafka_exposed_to_internet": "PASS","ec2_instance_port_mysql_exposed_to_internet": "PASS","ec2_instance_port_redis_exposed_to_internet": "PASS","workspaces_vpc_2private_1public_subnets_nat": null,"ec2_instance_port_oracle_exposed_to_internet": "PASS","ec2_instance_port_telnet_exposed_to_internet": "PASS","ec2_instance_port_mongodb_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_instance_port_kerberos_exposed_to_internet": "PASS","ec2_transitgateway_auto_accept_vpc_attachments": null,"appstream_fleet_session_idle_disconnect_timeout": null,"ec2_instance_port_cassandra_exposed_to_internet": "PASS","ec2_instance_port_memcached_exposed_to_internet": "PASS","ec2_instance_port_sqlserver_exposed_to_internet": "PASS","rds_instance_event_subscription_security_groups": "FAIL","sagemaker_training_jobs_vpc_settings_configured": null,"vpc_peering_routing_tables_with_least_privilege": "PASS","appstream_fleet_default_internet_access_disabled": null,"ec2_instance_port_postgresql_exposed_to_internet": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","cloudfront_distributions_geo_restrictions_enabled": null,"sagemaker_training_jobs_network_isolation_enabled": null,"opensearch_service_domains_not_publicly_accessible": null,"sagemaker_notebook_instance_vpc_settings_configured": null,"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","vpc_endpoint_services_allowed_principals_trust_boundaries": null,"ec2_instance_port_elasticsearch_kibana_exposed_to_internet": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","cognito_user_pool_blocks_potential_malicious_sign_in_attempts": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.6.1 ė„¤ķŠøģ›Œķ¬ ģ ‘ź·¼","Subdomain": "2.6. ģ ‘ź·¼ķ†µģ œ","AuditEvidence": ["ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„","IP ź“€ė¦¬ėŒ€ģž„","ģ •ė³“ģžģ‚° ėŖ©ė”","방화벽룰"],"AuditChecklist": ["ģ”°ģ§ģ˜ ė„¤ķŠøģ›Œķ¬ģ— 접근할 수 ģžˆėŠ” ėŖØė“  경딜넼 ģ‹ė³„ķ•˜ź³  ģ ‘ź·¼ķ†µģ œ 정책에 ė”°ė¼ ė‚“ė¶€ ė„¤ķŠøģ›Œķ¬ėŠ” ģøź°€ėœ ģ‚¬ģš©ģžė§Œģ“ 접근할 수 ģžˆė„ė” ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?","ģ„œė¹„ģŠ¤, ģ‚¬ģš©ģž 그룹, ģ •ė³“ģžģ‚°ģ˜ ģ¤‘ģš”ė„, 법적 ģš”źµ¬ģ‚¬ķ•­ģ— ė”°ė¼ ė„¤ķŠøģ›Œķ¬ ģ˜ģ—­ģ„ 물리적 ė˜ėŠ” ė…¼ė¦¬ģ ģœ¼ė”œ ė¶„ė¦¬ķ•˜ź³  각 ģ˜ģ—­ ź°„ ģ ‘ź·¼ķ†µģ œė„¼ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?","ė„¤ķŠøģ›Œķ¬ ėŒ€ģ—­ė³„ IPģ£¼ģ†Œ 부여 źø°ģ¤€ģ„ ė§ˆė Øķ•˜ź³  ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ„œė²„ 등 외부 ģ—°ź²°ģ“ ķ•„ģš”ķ•˜ģ§€ ģ•Šģ€ 경우 사설 IP딜 ķ• ė‹¹ķ•˜ėŠ” ė“±ģ˜ ėŒ€ģ±…ģ„ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?","물리적으딜 ė–Øģ–“ģ§„ IDC, 지사, ėŒ€ė¦¬ģ  ė“±ź³¼ģ˜ ė„¤ķŠøģ›Œķ¬ ģ—°ź²° ģ‹œ 전솔구간 ė³“ķ˜øėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„ģ™€ ģøķ„°ė·°ė„¼ ķ†µķ•˜ģ—¬ ķ™•ģøķ•œ ź²°ź³¼, 외부 ģ§€ģ ģ—ģ„œ ģ‚¬ģš©ķ•˜ėŠ” ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ ģ²˜ė¦¬ģ‹œģŠ¤ķ…œź³¼ IDC에 ģœ„ģ¹˜ķ•œ ģ„œė²„ ź°„ ģ—°ź²° ģ‹œ ģ¼ė°˜ ģøķ„°ė„· ķšŒģ„ ģ„ ķ†µķ•˜ģ—¬ ė°ģ“ķ„° ģ†”ģˆ˜ģ‹ ģ„ ģ²˜ė¦¬ķ•˜ź³  ģžˆģ–“ ė‚“ė¶€ ź·œģ •ģ— ėŖ…ģ‹œėœ VPNģ“ė‚˜ ģ „ģš©ė§ ė“±ģ„ ģ“ģš©ķ•œ ķ†µģ‹ ģ“ ģ“ė£Øģ–“ģ§€ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ė‚“ė¶€ė§ģ— ģœ„ģ¹˜ķ•œ ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ„œė²„ 등 ģ¼ė¶€ ģ¤‘ģš” ģ„œė²„ģ˜ IPģ£¼ģ†Œź°€ ė‚“ė¶€ ź·œģ •ź³¼ 달리 ź³µģø IP딜 ģ„¤ģ •ė˜ģ–“ ģžˆź³ , ė„¤ķŠøģ›Œķ¬ ģ ‘ź·¼ ģ°Øė‹Øģ“ ģ ģš©ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģ„œė²„ķŒœģ“ źµ¬ģ„±ė˜ģ–“ ģžˆģœ¼ė‚˜, ė„¤ķŠøģ›Œķ¬ ģ ‘ź·¼ģ œģ–“ 설정 ėÆøķ”ģœ¼ė”œ ė‚“ė¶€ė§ģ—ģ„œ ģ„œė²„ķŒœģœ¼ė”œģ˜ ģ ‘ź·¼ģ“ ź³¼ė„ķ•˜ź²Œ ķ—ˆģš©ė˜ģ–“ ģžˆėŠ” 경우","사딀 4 : ģ™øė¶€ģž(외부 ź°œė°œģž, ė°©ė¬øģž 등)ģ—ź²Œ ģ œź³µė˜ėŠ” ė„¤ķŠøģ›Œķ¬ė„¼ ė³„ė„ģ˜ ķ†µģ œ ģ—†ģ“ ė‚“ė¶€ 업묓 ė„¤ķŠøģ›Œķ¬ģ™€ ė¶„ė¦¬ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 5 : ė‚“ė¶€ ź·œģ •ź³¼ėŠ” 달리 MACģ£¼ģ†Œ ģøģ¦, ķ•„ģˆ˜ ė³“ģ•ˆ ģ†Œķ”„ķŠøģ›Øģ–“ ģ„¤ģ¹˜ ė“±ģ˜ ė³“ķ˜øėŒ€ģ±…ģ„ ģ ģš©ķ•˜ģ§€ ģ•Šģ€ 상태딜 ė„¤ķŠøģ›Œķ¬ ģ¼€ģ“ėø” ģ—°ź²°ė§Œģœ¼ė”œ 사낓 ė„¤ķŠøģ›Œķ¬ģ— ģ ‘ź·¼ ė° ģ“ģš©ķ•  수 ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "ė„¤ķŠøģ›Œķ¬ģ— ėŒ€ķ•œ ė¹„ģøź°€ ģ ‘ź·¼ģ„ ķ†µģ œķ•˜źø° ģœ„ķ•˜ģ—¬ IP꓀리, ė‹Øė§ģøģ¦ 등 ź“€ė¦¬ģ ˆģ°Øė„¼ 수립 ė°ģ“ķ–‰ķ•˜ź³ , 업묓목적 ė° ģ¤‘ģš”ė„ģ— ė”°ė¼ ė„¤ķŠøģ›Œķ¬ 분리(DMZ, ģ„œė²„ķŒœ, DB씓, 개발씓 등)와 ģ ‘ź·¼ķ†µģ œė„¼ ģ ģš©ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 17,"pass": 54,"total": 112,"manual": 0}},"2.6.2": {"name": "ģ •ė³“ģ‹œģŠ¤ķ…œ ģ ‘ź·¼","checks": {"ec2_elastic_ip_shodan": null,"ec2_instance_public_ip": "FAIL","ec2_elastic_ip_unassigned": "FAIL","lightsail_instance_public": null,"lightsail_static_ip_unused": null,"ec2_instance_managed_by_ssm": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_instance_port_ftp_exposed_to_internet": "PASS","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_instance_port_telnet_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","ec2_instance_internet_facing_with_instance_profile": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.6.2 ģ •ė³“ģ‹œģŠ¤ķ…œ ģ ‘ź·¼","Subdomain": "2.6. ģ ‘ź·¼ķ†µģ œ","AuditEvidence": ["ģ •ė³“ģ‹œģŠ¤ķ…œ 욓영첓제 계정 ėŖ©ė”","ģ„œė²„ ė³“ģ•ˆ 설정","ģ„œė²„ģ ‘ź·¼ģ œģ–“ ģ •ģ±…(SecureOS ꓀리화멓 등)","ģ„œė²„ ė° ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„","ģ •ė³“ģžģ‚° ėŖ©ė”"],"AuditChecklist": ["ģ„œė²„, ė„¤ķŠøģ›Œķ¬ģ‹œģŠ¤ķ…œ, ė³“ģ•ˆģ‹œģŠ¤ķ…œ 등 ģ •ė³“ģ‹œģŠ¤ķ…œė³„ 욓영첓제(OS)에 ģ ‘ź·¼ģ“ ķ—ˆģš©ė˜ėŠ” ģ‚¬ģš©ģž, ģ ‘ź·¼ ź°€ėŠ„ ģœ„ģ¹˜, ģ ‘ź·¼ ģˆ˜ė‹Ø ė“±ģ„ ģ •ģ˜ķ•˜ģ—¬ ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œģ— ģ ‘ģ† 후 ģ¼ģ •ģ‹œź°„ ģ—…ė¬“ģ²˜ė¦¬ė„¼ ķ•˜ģ§€ ģ•ŠėŠ” 경우 ģžė™ģœ¼ė”œ ģ‹œģŠ¤ķ…œ ģ ‘ģ†ģ“ ģ°Øė‹Øė˜ė„ė” ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ‚¬ģš©ėŖ©ģ ź³¼ ꓀계 ģ—†ėŠ” ģ„œė¹„ģŠ¤ė„¼ ģ œź±°ķ•˜ź³  ģžˆėŠ”ź°€?","ģ£¼ģš” ģ„œė¹„ģŠ¤ė„¼ ģ œź³µķ•˜ėŠ” ģ •ė³“ģ‹œģŠ¤ķ…œģ€ ė…ė¦½ėœ ģ„œė²„ė”œ ģš“ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ‚¬ė¬“ģ‹¤ģ—ģ„œ ģ„œė²„ź“€ė¦¬ģžź°€ IDC에 ģœ„ģ¹˜ķ•œ ģœˆė„ģš° ģ„œė²„ģ— ģ ‘ź·¼ ģ‹œ 터미널 ģ„œė¹„ģŠ¤ė„¼ ģ“ģš©ķ•˜ģ—¬ ģ ‘ź·¼ķ•˜ź³  ģžˆģœ¼ė‚˜, 터미널 ģ„œė¹„ģŠ¤ģ— ėŒ€ķ•œ ģ„øģ…˜ ķƒ€ģž„ģ•„ģ›ƒ ģ„¤ģ •ģ“ ė˜ģ–“ ģžˆģ§€ ģ•Šģ•„ ģž„ģ‹œź°„ ģ•„ė¬“ėŸ° ģž‘ģ—…ģ„ ķ•˜ģ§€ ģ•Šģ•„ė„ 핓당 ģ„øģ…˜ģ“ ģ°Øė‹Øė˜ģ§€ ģ•ŠėŠ” 경우","사딀 2 : ģ„œė²„ ź°„ ģ ‘ģ†ģ“ ģ ģ ˆķžˆ ģ œķ•œė˜ģ§€ ģ•Šģ•„ ķŠ¹ģ • ģ‚¬ģš©ģžź°€ ė³øģøģ—ź²Œ ģøź°€ėœ ģ„œė²„ģ— ģ ‘ģ†ķ•œ 후 핓당 ģ„œė²„ė„¼ ź²½ģœ ķ•˜ģ—¬ 다넸 ģøź°€ė°›ģ§€ ģ•Šģ€ ģ„œė²„ģ—ė„ ģ ‘ģ†ķ•  수 ģžˆėŠ” 경우","사딀 3 : ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ė˜ėŠ” 볓완 ėŒ€ģ±… ģ—†ģ“ ģ•ˆģ „ķ•˜ģ§€ ģ•Šģ€ ģ ‘ģ† ķ”„ė”œķ† ģ½œ(telnet, ftp 등)ģ„ ģ‚¬ģš©ķ•˜ģ—¬ ģ ‘ź·¼ķ•˜ź³  ģžˆģœ¼ė©°, ė¶ˆķ•„ģš”ķ•œ ģ„œė¹„ģŠ¤ ė° ķ¬ķŠøė„¼ ģ˜¤ķ”ˆķ•˜ź³  ģžˆėŠ” 경우","사딀 4 : ėŖØė“  ģ„œė²„ė”œģ˜ ģ ‘ź·¼ģ€ ģ„œė²„ģ ‘ź·¼ģ œģ–“ ģ‹œģŠ¤ķ…œģ„ ķ†µķ•˜ė„ė” ģ ‘ź·¼ķ†µģ œ ģ •ģ±…ģ„ 가져가고 ģžˆģœ¼ė‚˜, ģ„œė²„ģ ‘ź·¼ģ œģ–“ ģ‹œģŠ¤ķ…œģ„ ķ†µķ•˜ģ§€ ģ•Šź³  ģ„œė²„ģ— 접근할 수 ģžˆėŠ” 우회 ź²½ė”œź°€ ģ”“ģž¬ķ•˜ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "ģ„œė²„, ė„¤ķŠøģ›Œķ¬ģ‹œģŠ¤ķ…œ 등 ģ •ė³“ģ‹œģŠ¤ķ…œģ— ģ ‘ź·¼ģ„ ķ—ˆģš©ķ•˜ėŠ” ģ‚¬ģš©ģž, ģ ‘ź·¼ģ œķ•œ ė°©ģ‹, ģ•ˆģ „ķ•œ ģ ‘ź·¼ģˆ˜ė‹Ø ė“±ģ„ ģ •ģ˜ķ•˜ģ—¬ ķ†µģ œķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 8,"pass": 13,"total": 24,"manual": 0}},"2.6.3": {"name": "ģ‘ģš©ķ”„ė”œź·øėžØ ģ ‘ź·¼","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.6.3 ģ‘ģš©ķ”„ė”œź·øėžØ ģ ‘ź·¼","Subdomain": "2.6. ģ ‘ź·¼ķ†µģ œ","AuditEvidence": ["ģ‘ģš©ķ”„ė”œź·øėžØ ģ ‘ź·¼ź¶Œķ•œ ė¶„ė„˜ 첓계","ģ‘ģš©ķ”„ė”œź·øėžØ ź³„ģ •Ā·ź¶Œķ•œ ꓀리 화멓","ģ‘ģš©ķ”„ė”œź·øėžØ ģ‚¬ģš©ģžĀ·ź“€ė¦¬ģž 화멓(ź°œģøģ •ė³“ 씰회 등)","ģ‘ģš©ķ”„ė”œź·øėžØ ģ„øģ…˜ ķƒ€ģž„ ė° ė™ģ‹œģ ‘ģ† ķ—ˆģš© 여부 ė‚“ģ—­","ģ‘ģš©ķ”„ė”œź·øėžØ ź“€ė¦¬ģž ģ ‘ģ†ė”œź·ø ėŖØė‹ˆķ„°ė§ ė‚“ģ—­","ģ •ė³“ģžģ‚° ėŖ©ė”","ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ź°œģøģ •ė³“ 씰회, ź²€ģƒ‰ 화멓","ź°œģøģ •ė³“ ė§ˆģŠ¤ķ‚¹ ķ‘œģ¤€","ź°œģøģ •ė³“ ė§ˆģŠ¤ķ‚¹ 적용 화멓"],"AuditChecklist": ["ģ¤‘ģš”ģ •ė³“ ģ ‘ź·¼ģ„ ķ†µģ œķ•˜źø° ģœ„ķ•˜ģ—¬ ģ‚¬ģš©ģžģ˜ 업묓에 ė”°ė¼ ģ‘ģš©ķ”„ė”œź·øėžØ ģ ‘ź·¼ź¶Œķ•œģ„ 차등 ė¶€ģ—¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ¼ģ •ģ‹œź°„ ė™ģ•ˆ ģž…ė „ģ“ ģ—†ėŠ” ģ„øģ…˜ģ€ ģžė™ ģ°Øė‹Øķ•˜ź³ , ė™ģ¼ ģ‚¬ģš©ģžģ˜ ė™ģ‹œ ģ„øģ…˜ 수넼 ģ œķ•œķ•˜ź³  ģžˆėŠ”ź°€?","ź“€ė¦¬ģž ģ „ģš© ģ‘ģš©ķ”„ė”œź·øėžØ(ź“€ė¦¬ģž ģ›¹ķŽ˜ģ“ģ§€, ź“€ė¦¬ģ½˜ģ†” 등)ģ€ ė¹„ģøź°€ģžź°€ 접근할 수 ģ—†ė„ė” ģ ‘ź·¼ģ„ ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ˜ ķ‘œģ‹œģ œķ•œ ė³“ķ˜øģ”°ģ¹˜ģ˜ ģ¼ź“€ģ„±ģ„ 확볓할 수 ģžˆė„ė” ꓀련 źø°ģ¤€ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ˜ ė¶ˆķ•„ģš”ķ•œ ė…øģ¶œ(씰회, ķ™”ė©“ķ‘œģ‹œ, ģøģ‡„, ė‹¤ģš“ė”œė“œ 등)ģ„ ģµœģ†Œķ™”ķ•  수 ģžˆė„ė” ģ‘ģš©ķ”„ė”œź·øėžØģ„ źµ¬ķ˜„ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ‘ģš©ķ”„ė”œź·øėžØģ˜ ź°œģøģ •ė³“ ģ²˜ė¦¬ķ™”ė©“ 중 ģ¼ė¶€ ķ™”ė©“ģ˜ ź¶Œķ•œ ģ œģ–“ źø°ėŠ„ģ— ģ˜¤ė„˜ź°€ ģ”“ģž¬ķ•˜ģ—¬ ź°œģøģ •ė³“ ģ—“ėžŒ ź¶Œķ•œģ“ ģ—†ėŠ” ģ‚¬ģš©ģžģ—ź²Œė„ ź°œģøģ •ė³“ź°€ ė…øģ¶œė˜ź³  ģžˆėŠ” 경우","사딀 2 : ģ‘ģš©ķ”„ė”œź·øėžØģ˜ ź“€ė¦¬ģž ķŽ˜ģ“ģ§€ź°€ ģ™øė¶€ģøķ„°ė„·ģ— ģ˜¤ķ”ˆė˜ģ–“ ģžˆģœ¼ė©“ģ„œ ģ•ˆģ „ķ•œ ģøģ¦ģˆ˜ė‹Øģ“ ģ ģš©ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģ‘ģš©ķ”„ė”œź·øėžØģ— ėŒ€ķ•˜ģ—¬ ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ģ—†ģ“ ģ„øģ…˜ ķƒ€ģž„ģ•„ģ›ƒ ė˜ėŠ” ė™ģ¼ ģ‚¬ģš©ģž ź³„ģ •ģ˜ ė™ģ‹œ ģ ‘ģ†ģ„ ģ œķ•œķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ģ‘ģš©ķ”„ė”œź·øėžØģ„ ķ†µķ•˜ģ—¬ ź°œģøģ •ė³“ė„¼ ė‹¤ģš“ė”œė“œė°›ėŠ” 경우 핓당 ķŒŒģ¼ 낓에 ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø 등 ģ—…ė¬“ģƒ ė¶ˆķ•„ģš”ķ•œ 정볓가 ź³¼ė„ķ•˜ź²Œ ķ¬ķ•Øė˜ģ–“ ģžˆėŠ” 경우","사딀 5 : ģ‘ģš©ķ”„ė”œź·øėžØģ˜ ź°œģøģ •ė³“ ģ”°ķšŒķ™”ė©“ģ—ģ„œ like ź²€ģƒ‰ģ„ ź³¼ė„ķ•˜ź²Œ ķ—ˆģš©ķ•˜ź³  ģžˆģ–“, ėŖØė“  ģ‚¬ģš©ģžź°€ ė³øģøģ˜ 업묓 ė²”ģœ„ė„¼ ģ“ˆź³¼ķ•˜ģ—¬ ģ„±ģ”Øė§Œģœ¼ė”œė„ 전첓 ź³ ź° 정볓넼 ģ”°ķšŒķ•  수 ģžˆėŠ” 경우","사딀 6 : ź°œģøģ •ė³“ ķ‘œģ‹œģ œķ•œ 씰치 źø°ģ¤€ģ“ ė§ˆė Øė˜ģ–“ ģžˆģ§€ ģ•Šź±°ė‚˜ ģ“ė„¼ ģ¤€ģˆ˜ķ•˜ģ§€ ģ•ŠėŠ” ė“±ģ˜ ģ‚¬ģœ ė”œ ė™ģ¼ķ•œ ź°œģøģ •ė³“ 항목에 ėŒ€ķ•˜ģ—¬ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ķ™”ė©“ė³„ė”œ ģ„œė”œ 다넸 ė§ˆģŠ¤ķ‚¹ źø°ģ¤€ģ“ 적용된 경우","사딀 7 : ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ķ™”ė©“ģƒģ—ėŠ” ź°œģøģ •ė³“ź°€ ė§ˆģŠ¤ķ‚¹ė˜ģ–“ ķ‘œģ‹œė˜ģ–“ ģžˆģœ¼ė‚˜, ģ›¹ėøŒė¼ģš°ģ € ģ†ŒģŠ¤ė³“źø°ė„¼ ķ†µķ•˜ģ—¬ ė§ˆģŠ¤ķ‚¹ė˜ģ§€ ģ•Šģ€ 전첓 ź°œģøģ •ė³“ź°€ ė…øģ¶œė˜ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ź¶Œķ•œģ˜ ꓀리), 제6ģ”°(ģ ‘ź·¼ķ†µģ œ), 제12ģ”°(ģ¶œė „Ā·ė³µģ‚¬ģ‹œ ģ•ˆģ „ģ”°ģ¹˜)"]}],"description": "ģ‚¬ģš©ģžė³„ 업묓 ė° ģ ‘ź·¼ ģ •ė³“ģ˜ ģ¤‘ģš”ė„ 등에 ė”°ė¼ ģ‘ģš©ķ”„ė”œź·øėžØ ģ ‘ź·¼ź¶Œķ•œģ„ ģ œķ•œķ•˜ź³ , ė¶ˆķ•„ģš”ķ•œ 정볓 ė˜ėŠ” ģ¤‘ģš”ģ •ė³“ ė…øģ¶œģ„ ģµœģ†Œķ™”ķ•  수 ģžˆė„ė” źø°ģ¤€ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ģ ģš©ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.6.4": {"name": "ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼","checks": {"accessanalyzer_enabled": "PASS","lightsail_database_public": null,"rds_snapshots_public_access": "PASS","dms_instance_no_public_access": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"neptune_cluster_public_snapshot": null,"rds_instance_transport_encrypted": "FAIL","documentdb_cluster_public_snapshot": null,"neptune_cluster_uses_public_subnet": null,"vpc_subnet_separate_private_public": "FAIL","dynamodb_table_cross_account_access": null,"rds_cluster_iam_authentication_enabled": "FAIL","accessanalyzer_enabled_without_findings": "FAIL","rds_instance_iam_authentication_enabled": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","neptune_cluster_iam_authentication_enabled": null,"ec2_instance_port_mysql_exposed_to_internet": "PASS","ec2_instance_port_redis_exposed_to_internet": "PASS","ec2_instance_port_oracle_exposed_to_internet": "PASS","ec2_instance_port_mongodb_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_instance_port_cassandra_exposed_to_internet": "PASS","ec2_instance_port_sqlserver_exposed_to_internet": "PASS","opensearch_service_domains_not_publicly_accessible": null,"opensearch_service_domains_https_communications_enforced": null,"opensearch_service_domains_internal_user_database_enabled": null,"ec2_instance_port_elasticsearch_kibana_exposed_to_internet": "PASS","opensearch_service_domains_use_cognito_authentication_for_kibana": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.6.4 ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼","Subdomain": "2.6. ģ ‘ź·¼ķ†µģ œ","AuditEvidence": ["ė°ģ“ķ„°ė² ģ“ģŠ¤ ķ˜„ķ™©(ķ…Œģ“ėø”, 컬럼 등)","ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ģ†ģž ź³„ģ •Ā·ź¶Œķ•œ ėŖ©ė”","ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ģ œģ–“ ģ •ģ±…(ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ģ œģ–“ģ‹œģŠ¤ķ…œ ꓀리화멓 등)","ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„(ė°ģ“ķ„°ė² ģ“ģŠ¤ģ”“ 등)","ģ •ė³“ģžģ‚° ėŖ©ė”"],"AuditChecklist": ["ė°ģ“ķ„°ė² ģ“ģŠ¤ģ˜ ķ…Œģ“ėø” ėŖ©ė” 등 ģ €ģž„Ā·ź“€ė¦¬ė˜ź³  ģžˆėŠ” 정볓넼 ģ‹ė³„ķ•˜ź³  ģžˆėŠ”ź°€?","ė°ģ“ķ„°ė² ģ“ģŠ¤ ė‚“ 정볓에 ģ ‘ź·¼ģ“ ķ•„ģš”ķ•œ ģ‘ģš©ķ”„ė”œź·øėžØ, ģ •ė³“ģ‹œģŠ¤ķ…œ(ģ„œė²„) ė° ģ‚¬ģš©ģžė„¼ ėŖ…ķ™•ķžˆ ģ‹ė³„ķ•˜ź³  ģ ‘ź·¼ķ†µģ œ 정책에 ė”°ė¼ ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ėŒ€ėŸ‰ģ˜ ź°œģøģ •ė³“ė„¼ ė³“ź“€Ā·ģ²˜ė¦¬ķ•˜ź³  ģžˆėŠ” ė°ģ“ķ„°ė² ģ“ģŠ¤ė„¼ ģøķ„°ė„·ģ„ ķ†µķ•˜ģ—¬ ģ ‘ź·¼ ź°€ėŠ„ķ•œ 웹 ģ‘ģš©ķ”„ė”œź·øėžØź³¼ ė¶„ė¦¬ķ•˜ģ§€ ģ•Šź³  물리적으딜 ė™ģ¼ķ•œ ģ„œė²„ģ—ģ„œ ģš“ģ˜ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : ź°œė°œģž ė° ģš“ģ˜ģžė“¤ģ“ ģ‘ģ‘ ķ”„ė”œź·øėžØģ—ģ„œ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” ź³„ģ •ģ„ ź³µģœ ķ•˜ģ—¬ 욓영 ė°ģ“ķ„°ė² ģ“ģŠ¤ģ— ģ ‘ģ†ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : ė‚“ė¶€ ź·œģ •ģ—ėŠ” ė°ģ“ķ„°ė² ģ“ģŠ¤ģ˜ ģ ‘ģ†ź¶Œķ•œģ„ ģ˜¤ėøŒģ ķŠøė³„ė”œ ģ œķ•œķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ź¶Œķ•œģ„ ģš“ģ˜ģžģ—ź²Œ ģ¼ź“„ ė¶€ģ—¬ķ•˜ź³  ģžˆģ–“ ź°œģøģ •ė³“ ķ…Œģ“ėø”ģ— 접근할 ķ•„ģš”ź°€ ģ—†ėŠ” ģš“ģ˜ģžģ—ź²Œė„ ź³¼ė„ķ•˜ź²Œ ģ ‘ź·¼ ź¶Œķ•œģ“ ė¶€ģ—¬ėœ 경우","사딀 4 : ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ģ œģ–“ ģ†”ė£Øģ…˜ģ„ ė„ģž…ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ģ†ģžģ— ėŒ€ķ•œ IPģ£¼ģ†Œ ė“±ģ“ ģ ģ ˆķžˆ ģ œķ•œė˜ģ–“ ģžˆģ§€ ģ•Šģ•„ ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ģ œģ–“ ģ†”ė£Øģ…˜ģ„ ģš°ķšŒķ•˜ģ—¬ ė°ģ“ķ„°ė² ģ“ģŠ¤ģ— ģ ‘ģ†ķ•˜ź³  ģžˆėŠ” 경우","사딀 5 : ź°œģøģ •ė³“ė„¼ ģ €ģž„ķ•˜ź³  ģžˆėŠ” ė°ģ“ķ„°ė² ģ“ģŠ¤ģ˜ ķ…Œģ“ėø” ķ˜„ķ™©ģ“ ķŒŒģ•…ė˜ģ§€ ģ•Šģ•„, ģž„ģ‹œė”œ ģƒģ„±ėœ ķ…Œģ“ėø”ģ— ė¶ˆķ•„ģš”ķ•œ ź°œģøģ •ė³“ź°€ ķŒŒźø°ė˜ģ§€ ģ•Šź³  ėŒ€ėŸ‰ģœ¼ė”œ ģ €ģž„ė˜ģ–“ ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ź¶Œķ•œģ˜ ꓀리), 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "ķ…Œģ“ėø” ėŖ©ė” 등 ė°ģ“ķ„°ė² ģ“ģŠ¤ ė‚“ģ—ģ„œ ģ €ģž„Ā·ź“€ė¦¬ė˜ź³  ģžˆėŠ” 정볓넼 ģ‹ė³„ķ•˜ź³ , ģ •ė³“ģ˜ ģ¤‘ģš”ė„ģ™€ ģ‘ģš©ķ”„ė”œź·øėžØ ė° ģ‚¬ģš©ģž ģœ ķ˜• 등에 따넸 ģ ‘ź·¼ķ†µģ œ ģ •ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 6,"pass": 19,"total": 37,"manual": 0}},"2.6.5": {"name": "묓선 ė„¤ķŠøģ›Œķ¬ ģ ‘ź·¼","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.6.5 묓선 ė„¤ķŠøģ›Œķ¬ ģ ‘ź·¼","Subdomain": "2.6. ģ ‘ź·¼ķ†µģ œ","AuditEvidence": ["ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„","AP ė³“ģ•ˆ 설정 ė‚“ģ—­","ė¹„ģøź°€ 묓선 ė„¤ķŠøģ›Œķ¬ 점검 ģ“ė „","ė¬“ģ„ ė„¤ķŠøģ›Œķ¬ ģ‚¬ģš© ģ‹ ģ²­Ā·ģŠ¹ģø ģ“ė „"],"AuditChecklist": ["ė¬“ģ„ ė„¤ķŠøģ›Œķ¬ė„¼ ģ—…ė¬“ģ ģœ¼ė”œ ģ‚¬ģš©ķ•˜ėŠ” 경우 묓선 AP ė° ė„¤ķŠøģ›Œķ¬ 구간 ė³“ģ•ˆģ„ ģœ„ķ•˜ģ—¬ ģøģ¦, ģ†”ģˆ˜ģ‹  ė°ģ“ķ„° ģ•”ķ˜øķ™” 등 ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģøź°€ėœ ģž„ģ§ģ›ė§Œģ“ ė¬“ģ„ ė„¤ķŠøģ›Œķ¬ė„¼ ģ‚¬ģš©ķ•  수 ģžˆė„ė” ģ‚¬ģš© ģ‹ ģ²­ ė° ķ•“ģ§€ 절차넼 수립 ė° ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","AD Hoc ģ ‘ģ† ė° 씰직 ė‚“ ķ—ˆź°€ė°›ģ§€ ģ•Šģ€ 묓선 AP ķƒģ§€Ā·ģ°Øė‹Ø 등 ė¹„ģøź°€ėœ ė¬“ģ„ ė„¤ķŠøģ›Œķ¬ģ— ėŒ€ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ™øė¶€ģøģš© 묓선 ė„¤ķŠøģ›Œķ¬ģ™€ ė‚“ė¶€ 묓선 ė„¤ķŠøģ›Œķ¬ ģ˜ģ—­ėŒ€ź°€ ė™ģ¼ķ•˜ģ—¬ ģ™øė¶€ģøė„ ė¬“ģ„ ė„¤ķŠøģ›Œķ¬ė„¼ ķ†µķ•˜ģ—¬ ė³„ė„ģ˜ ķ†µģ œ ģ—†ģ“ ė‚“ė¶€ ė„¤ķŠøģ›Œķ¬ģ— ģ ‘ź·¼ģ“ ź°€ėŠ„ķ•œ 경우","사딀 2 : 묓선 AP 설정 ģ‹œ 정볓 ģ†”ģˆ˜ģ‹  ģ•”ķ˜øķ™” źø°ėŠ„ģ„ ģ„¤ģ •ķ•˜ģ˜€ģœ¼ė‚˜, ģ•ˆģ „ķ•˜ģ§€ ģ•Šģ€ ė°©ģ‹ģœ¼ė”œ ģ„¤ģ •ķ•œ 경우","사딀 3 : 업묓 목적으딜 ė‚“ė¶€ė§ģ— ģ—°ź²°ėœ 묓선AP에 ėŒ€ķ•˜ģ—¬ 묓선AP ź“€ė¦¬ģž ė¹„ė°€ė²ˆķ˜ø ė…øģ¶œ(ė””ķ“ķŠø ė¹„ė°€ė²ˆķ˜ø ģ‚¬ģš©), ģ ‘ź·¼ģ œģ–“ 미적용 등 ė³“ģ•ˆ ģ„¤ģ •ģ“ ėÆøķ”ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "묓선 ė„¤ķŠøģ›Œķ¬ė„¼ ģ‚¬ģš©ķ•˜ėŠ” 경우 ģ‚¬ģš©ģž ģøģ¦, ģ†”ģˆ˜ģ‹  ė°ģ“ķ„° ģ•”ķ˜øķ™”, AP ķ†µģ œ 등 묓선 ė„¤ķŠøģ›Œķ¬ ė³“ķ˜øėŒ€ģ±…ģ„ ģ ģš©ķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ė˜ķ•œ AD Hoc ģ ‘ģ†, ė¹„ģøź°€ AP ģ‚¬ģš© 등 ė¹„ģøź°€ 묓선 ė„¤ķŠøģ›Œķ¬ ģ ‘ģ†ģœ¼ė”œė¶€ķ„° ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.6.6": {"name": "원격접근 ķ†µģ œ","checks": {"vpc_flow_logs_enabled": "FAIL","networkfirewall_in_all_vpc": "FAIL","cognito_user_pool_mfa_enabled": null,"iam_user_console_access_unused": null,"vpc_subnet_no_public_ip_by_default": "FAIL","vpc_subnet_separate_private_public": "FAIL","iam_user_mfa_enabled_console_access": null,"workspaces_volume_encryption_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","appstream_fleet_maximum_session_duration": null,"ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","appstream_fleet_session_disconnect_timeout": null,"ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","cognito_identity_pool_guest_access_disabled": "FAIL","workspaces_vpc_2private_1public_subnets_nat": null,"cognito_user_pool_self_registration_disabled": null,"appstream_fleet_session_idle_disconnect_timeout": null,"appstream_fleet_default_internet_access_disabled": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"ec2_client_vpn_endpoint_connection_logging_enabled": null,"cloudwatch_log_metric_filter_authentication_failures": null,"ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.6.6 원격접근 ķ†µģ œ","Subdomain": "2.6. ģ ‘ź·¼ķ†µģ œ","AuditEvidence": ["VPN 등 ģ‚¬ģ™øģ ‘ģ† ģ‹ ģ²­ģ„œ","VPN 계정 ėŖ©ė”","VPN ģ ‘ź·¼ģ œģ–“ ģ •ģ±… 설정 ķ˜„ķ™©","IP ź“€ė¦¬ėŒ€ģž„","원격 ģ ‘ź·¼ģ œģ–“ 설정(ģ„œė²„ 설정, ė³“ģ•ˆģ‹œģŠ¤ķ…œ 설정 등)","ź“€ė¦¬ģš© 단말기 지정 ė° ꓀리 ķ˜„ķ™©","ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„"],"AuditChecklist": ["ģøķ„°ė„·ź³¼ ź°™ģ€ 외부 ė„¤ķŠøģ›Œķ¬ė„¼ ķ†µķ•œ ģ •ė³“ģ‹œģŠ¤ķ…œ ģ›ź²©ģš“ģ˜ģ€ ģ›ģ¹™ģ ģœ¼ė”œ źøˆģ§€ķ•˜ź³  ģž„ģ• ėŒ€ģ‘ 등 ė¶€ė“ģ“ķ•˜ź²Œ ķ—ˆģš©ķ•˜ėŠ” 경우 ė³“ģ™„ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","ė‚“ė¶€ ė„¤ķŠøģ›Œķ¬ė„¼ ķ†µķ•˜ģ—¬ ģ›ź²©ģœ¼ė”œ ģ •ė³“ģ‹œģŠ¤ķ…œģ„ ģš“ģ˜ķ•˜ėŠ” 경우 ķŠ¹ģ • 단말에 ķ•œķ•“ģ„œė§Œ ģ ‘ź·¼ģ„ ķ—ˆģš©ķ•˜ź³  ģžˆėŠ”ź°€?","ģž¬ķƒź·¼ė¬“, ģ›ź²©ķ˜‘ģ—…, ģŠ¤ė§ˆķŠøģ›Œķ¬ 등과 ź°™ģ€ 원격업묓 ģˆ˜ķ–‰ ģ‹œ ģ¤‘ģš”ģ •ė³“ 유출, 핓킹 등 침핓사고 ģ˜ˆė°©ģ„ ģœ„ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ꓀리, 욓영, 개발, ė³“ģ•ˆ ė“±ģ„ 목적으딜 ģ›ź²©ģœ¼ė”œ ź°œģøģ •ė³“ģ²˜ė¦¬ ģ‹œģŠ¤ķ…œģ— ģ ‘ģ†ķ•˜ėŠ” ė‹Øė§źø°ėŠ” ź“€ė¦¬ģš© ė‹Øė§źø°ė”œ ģ§€ģ •ķ•˜ź³  ģž„ģ˜ģ”°ģž‘ ė° 목적 외 ģ‚¬ģš© źøˆģ§€ 등 ģ•ˆģ „ģ”°ģ¹˜ė„¼ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ ź·œģ •ģ—ėŠ” ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ 원격 ģ ‘ź·¼ģ€ ģ›ģ¹™ģ ģœ¼ė”œ źøˆģ§€ķ•˜ź³  ė¶ˆź°€ķ”¼ķ•œ 경우 IP źø°ė°˜ģ˜ ģ ‘ź·¼ķ†µģ œė„¼ ķ†µķ•˜ģ—¬ ģŠ¹ģøėœ ģ‚¬ģš©ģžė§Œ 접근할 수 ģžˆė„ė” ėŖ…ģ‹œķ•˜ź³  ģžˆģœ¼ė‚˜, ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ 원격 ė°ģŠ¤ķ¬ķ†± ģ—°ź²°, SSH ģ ‘ģ†ģ“ IPģ£¼ģ†Œ ė“±ģœ¼ė”œ ģ œķ•œė˜ģ–“ ģžˆģ§€ ģ•Šģ•„ ėŖØė“  PCģ—ģ„œ 원격 ģ ‘ģ†ģ“ ź°€ėŠ„ķ•œ 경우","사딀 2 : ģ›ź²©ģš“ģ˜ź“€ė¦¬ė„¼ ģœ„ķ•˜ģ—¬ VPNģ„ źµ¬ģ¶•ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, VPN에 ėŒ€ķ•œ ģ‚¬ģš© ģŠ¹ģø ė˜ėŠ” ģ ‘ģ† źø°ź°„ ģ œķ•œ ģ—†ģ“ ģƒģ‹œ ķ—ˆģš©ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : 외부 ź·¼ė¬“ģžė„¼ ģœ„ķ•˜ģ—¬ ź°œģø 스마트 기기에 ģ—…ė¬“ģš© ėŖØė°”ģ¼ ģ•±ģ„ ģ„¤ģ¹˜ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ•…ģ„±ģ½”ė“œ, ė¶„ģ‹¤Ā·ė„ė‚œ 등에 ģ˜ķ•œ ź°œģøģ •ė³“ ģœ ģ¶œģ„ ė°©ģ§€ķ•˜źø° ģœ„ķ•œ ģ ģ ˆķ•œ ė³“ķ˜øėŒ€ģ±…(백신, ģ“ˆźø°ķ™”, ģ•”ķ˜øķ™” 등)ģ„ ģ ģš©ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : 외부 ģ ‘ģ†ģš© VPNģ—ģ„œ ģ‚¬ģš©ģžė³„ė”œ ģ›ź²©ģ ‘ź·¼ģ“ ź°€ėŠ„ķ•œ ė„¤ķŠøģ›Œķ¬ 구간 ė° ģ •ė³“ģ‹œģŠ¤ķ…œģ„ ģ œķ•œķ•˜ģ§€ ģ•Šģ•„ 원격접근 ģøģ¦ģ„ ė°›ģ€ ģ‚¬ģš©ģžź°€ 전첓 ė‚“ė¶€ė§ ė° ģ •ė³“ģ‹œģŠ¤ķ…œģ— ź³¼ė„ķ•˜ź²Œ ģ ‘ź·¼ģ“ ź°€ėŠ„ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "ė³“ķ˜øźµ¬ģ—­ ģ“ģ™ø ģž„ģ†Œģ—ģ„œģ˜ ģ •ė³“ģ‹œģŠ¤ķ…œ ꓀리 ė° ź°œģøģ •ė³“ ģ²˜ė¦¬ėŠ” ģ›ģ¹™ģ ģœ¼ė”œ źøˆģ§€ķ•˜ź³ , ģž¬ķƒź·¼ė¬“Ā·ģž„ģ• ėŒ€ģ‘Ā·ģ›ź²©ķ˜‘ģ—… 등 ė¶ˆź°€ķ”¼ķ•œ ģ‚¬ģœ ė”œ ģ›ź²©ģ ‘ź·¼ģ„ ķ—ˆģš©ķ•˜ėŠ” 경우 ģ±…ģž„ģž ģŠ¹ģø, ģ ‘ź·¼ 단말 지정, ģ ‘ź·¼ ķ—ˆģš©ė²”ģœ„ ė° źø°ź°„ 설정, ź°•ķ™”ėœ ģøģ¦, 구간 ģ•”ķ˜øķ™”, ģ ‘ģ†ė‹Øė§ ė³“ģ•ˆ(백신, 패치 등) 등 ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 8,"pass": 5,"total": 26,"manual": 0}},"2.6.7": {"name": "ģøķ„°ė„· ģ ‘ģ† ķ†µģ œ","checks": {"ec2_elastic_ip_shodan": null,"vpc_flow_logs_enabled": "FAIL","ec2_instance_public_ip": "FAIL","ec2_elastic_ip_unassigned": "FAIL","networkfirewall_in_all_vpc": "FAIL","vpc_subnet_no_public_ip_by_default": "FAIL","vpc_subnet_separate_private_public": "FAIL","workspaces_volume_encryption_enabled": null,"route53_dangling_ip_subdomain_takeover": null,"appstream_fleet_maximum_session_duration": null,"appstream_fleet_session_disconnect_timeout": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"workspaces_vpc_2private_1public_subnets_nat": null,"ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","appstream_fleet_session_idle_disconnect_timeout": null,"appstream_fleet_default_internet_access_disabled": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.6.7 ģøķ„°ė„· ģ ‘ģ† ķ†µģ œ","Subdomain": "2.6. ģ ‘ź·¼ķ†µģ œ","AuditEvidence": ["ė¹„ģ—…ė¬“ģ‚¬ģ“ķŠø(P2P 등) 차단정책(ė¹„ģ—…ė¬“ģ‚¬ģ“ķŠø ģ°Øė‹Øģ‹œģŠ¤ķ…œ ꓀리화멓 등)","ģøķ„°ė„· ģ ‘ģ†ė‚“ģ—­ ėŖØė‹ˆķ„°ė§ ģ“ė „","ģøķ„°ė„·ė§ ģ°Øė‹Øģ”°ģ¹˜ ėŒ€ģƒģž ėŖ©ė”","ė§ź°„ ģžė£Œ 전솔 절차 ė° ģ²˜ė¦¬ė‚“ģ—­(ģ‹ ģ²­Ā·ģŠ¹ģøė‚“ģ—­ 등)","ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„"],"AuditChecklist": ["ģ£¼ģš” 직묓 ģˆ˜ķ–‰ ė° ź°œģøģ •ė³“ ģ·Øźø‰ 단말기 등 ģ—…ė¬“ģš© PCģ˜ ģøķ„°ė„· ģ ‘ģ†ģ— ėŒ€ķ•œ ķ†µģ œģ •ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ£¼ģš” ģ •ė³“ģ‹œģŠ¤ķ…œ(DBģ„œė²„ 등)ģ—ģ„œ ė¶ˆķ•„ģš”ķ•œ 외부 ģøķ„°ė„· ģ ‘ģ†ģ„ ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?","꓀련 법령에 ė”°ė¼ ģøķ„°ė„·ė§ 차단 ģ˜ė¬“ź°€ ė¶€ź³¼ėœ 경우 ėŒ€ģƒģžė„¼ ģ‹ė³„ķ•˜ģ—¬ ģ•ˆģ „ķ•œ ė°©ģ‹ģœ¼ė”œ ģøķ„°ė„·ė§ 차단 씰치넼 ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ ė³“ķ˜øė²•ģ— ė”°ė¼ ģøķ„°ė„·ė§ 차단 씰치넼 ģ ģš©ķ•˜ģ˜€ģœ¼ė‚˜, ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ģ ‘ź·¼ź¶Œķ•œ 설정 ź°€ėŠ„ģž 등 ģ¼ė¶€ ģ˜ė¬“ėŒ€ģƒģžģ— ėŒ€ķ•˜ģ—¬ ģøķ„°ė„·ė§ 차단 씰치 ģ ģš©ģ“ ėˆ„ė½ėœ 경우","사딀 2 : ź°œģøģ •ė³“ ė³“ķ˜øė²•ģ— 따넸 ģøķ„°ė„·ė§ 차단 씰치 ģ˜ė¬“ėŒ€ģƒģœ¼ė”œģ„œ ģøķ„°ė„·ė§ 차단 씰치넼 ģ ģš©ķ•˜ģ˜€ģœ¼ė‚˜, 다넸 ģ„œė²„ė„¼ ź²½ģœ ķ•œ ģš°ķšŒģ ‘ģ†ģ“ ź°€ėŠ„ķ•˜ģ—¬ ģøķ„°ė„·ė§ 차단 ģ”°ģ¹˜ź°€ ģ ģš©ė˜ģ§€ ģ•Šģ€ ķ™˜ź²½ģ—ģ„œ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— ģ ‘ģ†ķ•˜ģ—¬ ź°œģøģ •ė³“ģ˜ ė‹¤ģš“ė”œė“œ, 파기 ė“±ģ“ ź°€ėŠ„ķ•œ 경우","사딀 3 : DMZ ė° ė‚“ė¶€ė§ģ— ģœ„ģ¹˜ķ•œ ģ¼ė¶€ ģ„œė²„ģ—ģ„œ ė¶ˆķ•„ģš”ķ•˜ź²Œ ģøķ„°ė„·ģœ¼ė”œģ˜ 직접 ģ ‘ģ†ģ“ ź°€ėŠ„ķ•œ 경우","사딀 4 : ģøķ„°ė„· PC와 ė‚“ė¶€ ģ—…ė¬“ģš© PC넼 물리적 ė§ė¶„ė¦¬ ė°©ģ‹ģœ¼ė”œ ģøķ„°ė„·ė§ 차단 씰치넼 ģ ģš©ķ•˜ź³  ė§ź°„ ģžė£Œģ „ģ†”ģ‹œģŠ¤ķ…œģ„ źµ¬ģ¶•Ā·ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, ģžė£Œ 전솔에 ėŒ€ķ•œ ģŠ¹ģø ģ ˆģ°Øź°€ ė¶€ģž¬ķ•˜ź³  ģžė£Œ 전솔 낓역에 ėŒ€ķ•œ 주기적 검토가 ģ“ė£Øģ–“ģ§€ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 5 : ė‚“ė¶€ ź·œģ •ģ—ėŠ” ź°œģøģ •ė³“ģ·Øźø‰ģžź°€ P2P ė° ģ›¹ķ•˜ė“œ ģ‚¬ģ“ķŠø ģ ‘ģ† ģ‹œ ģ±…ģž„ģž ģŠ¹ģøģ„ 거쳐 ķŠ¹ģ • źø°ź°„ ė™ģ•ˆė§Œ ķ—ˆģš©ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ģŠ¹ģøģ ˆģ°Øė„¼ ź±°ģ¹˜ģ§€ ģ•Šź³  ģ˜ˆģ™ø ģ ‘ģ†ģ“ ķ—ˆģš©ėœ 사딀가 ė‹¤ģˆ˜ ģ”“ģž¬ķ•˜ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "ģøķ„°ė„·ģ„ ķ†µķ•œ 정볓 유출, ģ•…ģ„±ģ½”ė“œ 감염, ė‚“ė¶€ė§ 침투 ė“±ģ„ ģ˜ˆė°©ķ•˜źø° ģœ„ķ•˜ģ—¬ ģ£¼ģš” ģ •ė³“ģ‹œģŠ¤ķ…œ, ģ£¼ģš” 직묓 ģˆ˜ķ–‰ ė° ź°œģøģ •ė³“ ģ·Øźø‰ 단말기 등에 ėŒ€ķ•œ ģøķ„°ė„· ģ ‘ģ† ė˜ėŠ” ģ„œė¹„ģŠ¤(P2P, ģ›¹ķ•˜ė“œ, 메신저 등)넼 ģ œķ•œķ•˜ėŠ” 등 ģøķ„°ė„· ģ ‘ģ† ķ†µģ œ ģ •ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 6,"pass": 1,"total": 19,"manual": 0}},"2.7.1": {"name": "ģ•”ķ˜øģ •ģ±… 적용","checks": {"elb_ssl_listeners": "FAIL","backup_vaults_exist": null,"elbv2_ssl_listeners": "FAIL","ssm_document_secrets": "PASS","backup_vaults_encrypted": "PASS","rds_snapshots_encrypted": "FAIL","elb_insecure_ssl_ciphers": "PASS","s3_bucket_kms_encryption": "FAIL","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","elbv2_insecure_ssl_ciphers": "PASS","athena_workgroup_encryption": null,"ec2_ebs_snapshots_encrypted": "FAIL","s3_bucket_default_encryption": "PASS","ec2_instance_secrets_user_data": "PASS","ec2_launch_template_no_secrets": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","rds_instance_transport_encrypted": "FAIL","cloudtrail_kms_encryption_enabled": "FAIL","neptune_cluster_storage_encrypted": null,"s3_bucket_secure_transport_policy": "FAIL","documentdb_cluster_storage_encrypted": null,"workspaces_volume_encryption_enabled": null,"awslambda_function_no_secrets_in_code": "PASS","glue_database_connections_ssl_enabled": null,"athena_workgroup_enforce_configuration": null,"cloudfront_distributions_https_enabled": null,"cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudformation_stack_outputs_find_secrets": "PASS","codebuild_project_no_secrets_in_variables": "PASS","kafka_cluster_encryption_at_rest_uses_cmk": null,"sns_subscription_not_using_http_endpoints": "PASS","sns_topics_kms_encryption_at_rest_enabled": "FAIL","sqs_queues_server_side_encryption_enabled": "PASS","awslambda_function_no_secrets_in_variables": "PASS","dynamodb_tables_kms_cmk_encryption_enabled": null,"glue_etl_jobs_amazon_s3_encryption_enabled": "PASS","acm_certificates_with_secure_key_algorithms": "PASS","cloudwatch_log_group_kms_encryption_enabled": "FAIL","ecs_task_definitions_no_environment_secrets": "PASS","kafka_cluster_in_transit_encryption_enabled": null,"storagegateway_fileshare_encryption_enabled": null,"apigateway_restapi_client_certificate_enabled": "FAIL","glue_etl_jobs_job_bookmark_encryption_enabled": "FAIL","glue_data_catalogs_metadata_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"kafka_cluster_mutual_tls_authentication_enabled": null,"directoryservice_radius_server_security_protocol": null,"glue_development_endpoints_s3_encryption_enabled": null,"glue_etl_jobs_cloudwatch_logs_encryption_enabled": "FAIL","autoscaling_find_secrets_ec2_launch_configuration": "PASS","eks_cluster_kms_cmk_encryption_in_secrets_enabled": null,"elasticache_redis_cluster_rest_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"cloudfront_distributions_field_level_encryption_enabled": null,"cloudfront_distributions_using_deprecated_ssl_protocols": null,"elasticache_redis_cluster_in_transit_encryption_enabled": null,"opensearch_service_domains_https_communications_enforced": null,"sagemaker_training_jobs_intercontainer_encryption_enabled": null,"glue_data_catalogs_connection_passwords_encryption_enabled": "FAIL","glue_development_endpoints_job_bookmark_encryption_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null,"sagemaker_training_jobs_volume_and_output_encryption_enabled": null,"glue_development_endpoints_cloudwatch_logs_encryption_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.7.1 ģ•”ķ˜øģ •ģ±… 적용","Subdomain": "2.7. ģ•”ķ˜øķ™” 적용","AuditEvidence": ["ģ•”ķ˜øķ†µģ œ ģ •ģ±…(ėŒ€ģƒ, ė°©ģ‹, ģ•Œź³ ė¦¬ģ¦˜ 등)","ģ•”ķ˜øķ™” ģ ģš©ķ˜„ķ™©(ģ €ģž„ ė° 전솔 ģ‹œ)","ģœ„ķ—˜ė„ ė¶„ģ„ ź²°ź³¼(ė‚“ė¶€ė§ģ—ģ„œ ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø ģ“ģ™øģ˜ ź³ ģœ ģ‹ė³„ģ •ė³“ ģ•”ķ˜øķ™” 미적용 ģ‹œ)","ģ•”ķ˜øķ™” ģ†”ė£Øģ…˜ ꓀리 화멓"],"AuditChecklist": ["ź°œģøģ •ė³“ ė° ģ£¼ģš”ģ •ė³“ģ˜ 볓호넼 ģœ„ķ•˜ģ—¬ 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ė°˜ģ˜ķ•œ ģ•”ķ˜øķ™” ėŒ€ģƒ, ģ•”ķ˜øź°•ė„, ģ•”ķ˜øģ‚¬ģš© ė“±ģ“ ķ¬ķ•Øėœ ģ•”ķ˜øģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ģ•”ķ˜øģ •ģ±…ģ— ė”°ė¼ ź°œģøģ •ė³“ ė° ģ£¼ģš”ģ •ė³“ģ˜ ģ €ģž„, 전솔, 전달 ģ‹œ ģ•”ķ˜øķ™”ė„¼ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ 정책·지침에 ģ•”ķ˜øķ†µģ œ ꓀련 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ź³ ė ¤ķ•œ ģ•”ķ˜øķ™” ėŒ€ģƒ, ģ•”ķ˜ø ź°•ė„, ģ €ģž„ ė° 전솔 ģ‹œ ģ•”ķ˜øķ™” 방법, ģ•”ķ˜øķ™” ꓀련 ė‹“ė‹¹ģžģ˜ ģ—­ķ•  ė° ģ±…ģž„ 등에 ź“€ķ•œ ģ‚¬ķ•­ģ“ ģ ģ ˆķžˆ ėŖ…ģ‹œė˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģ•”ķ˜øģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ė©“ģ„œ 핓당 źø°ģ—…ģ“ ģ ģš©ė°›ėŠ” ė²•ź·œė„¼ ģž˜ėŖ» ģ ģš©ķ•˜ģ—¬ ģ•”ķ˜øķ™” ꓀련 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ģ¤€ģˆ˜ķ•˜ģ§€ ėŖ»ķ•˜ź³  ģžˆėŠ” 경우(예넼 들얓, ģ“ģš©ģžģ˜ ź³„ģ¢Œė²ˆķ˜øė„¼ ģ €ģž„ķ•˜ė©“ģ„œ ģ•”ķ˜øķ™” 미적용)","사딀 3 : ź°œģøģ •ė³“ģ·Øźø‰ģž ė° ģ •ė³“ģ£¼ģ²“ģ˜ ė¹„ė°€ė²ˆķ˜øģ— ėŒ€ķ•˜ģ—¬ ģ¼ė°©ķ–„ ģ•”ķ˜øķ™”ė„¼ ģ ģš©ķ•˜ģ˜€ģœ¼ė‚˜, ģ•ˆģ „ķ•˜ģ§€ ģ•Šģ€ MD5 ģ•Œź³ ė¦¬ģ¦˜ģ„ ģ‚¬ģš©ķ•œ 경우","사딀 4 : ź°œģøģ •ė³“ģ²˜ė¦¬ģžź°€ ꓀련 ė²•ź·œ ė° ė‚“ė¶€ ź·œģ •ģ— ė”°ė¼ ģøķ„°ė„· 쇼핑몰에 ėŒ€ķ•˜ģ—¬ ė³“ģ•ˆģ„œė²„ė„¼ ģ ģš©ķ•˜ģ˜€ģœ¼ė‚˜, ķšŒģ›ģ •ė³“ 씰회 ė° 변경, ė¹„ė°€ė²ˆķ˜ø 찾기, ė¹„ė°€ė²ˆķ˜ø 변경 등 ģ“ģš©ģžģ˜ ź°œģøģ •ė³“ź°€ ģ „ģ†”ė˜ėŠ” ģ¼ė¶€ 구간에 ģ•”ķ˜øķ™” ģ”°ģ¹˜ź°€ ėˆ„ė½ėœ 경우","사딀 5 : ģ •ė³“ģ‹œģŠ¤ķ…œ ģ ‘ģ†ģš© ė¹„ė°€ė²ˆķ˜ø, ģøģ¦ķ‚¤ ź°’ ė“±ģ“ ģ‹œģŠ¤ķ…œ ģ„¤ģ •ķŒŒģ¼ ė° ģ†ŒģŠ¤ģ½”ė“œ 낓에 ķ‰ė¬øģœ¼ė”œ ģ €ģž„ė˜ģ–“ ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제24ģ”°ģ˜2(ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø ģ²˜ė¦¬ģ˜ ģ œķ•œ), 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제7ģ”°(ź°œģøģ •ė³“ģ˜ ģ•”ķ˜øķ™”)"]}],"description": "ź°œģøģ •ė³“ ė° ģ£¼ģš”ģ •ė³“ 볓호넼 ģœ„ķ•˜ģ—¬ 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ė°˜ģ˜ķ•œ ģ•”ķ˜øķ™” ėŒ€ģƒ, ģ•”ķ˜ø ź°•ė„, ģ•”ķ˜ø ģ‚¬ģš© ģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ź°œģøģ •ė³“ ė° ģ£¼ģš”ģ •ė³“ģ˜ ģ €ģž„Ā·ģ „ģ†”Ā·ģ „ė‹¬ ģ‹œ ģ•”ķ˜øķ™”ė„¼ ģ ģš©ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 18,"pass": 19,"total": 66,"manual": 0}},"2.7.2": {"name": "ģ•”ķ˜øķ‚¤ ꓀리","checks": {"kms_cmk_are_used": null,"kms_cmk_rotation_enabled": null,"kms_key_not_publicly_accessible": null,"kms_cmk_not_deleted_unintentionally": null,"rds_instance_certificate_expiration": "PASS","secretsmanager_automatic_rotation_enabled": "FAIL","acm_certificates_transparency_logs_enabled": "PASS","directoryservice_ldap_certificate_expiration": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.7.2 ģ•”ķ˜øķ‚¤ ꓀리","Subdomain": "2.7. ģ•”ķ˜øķ™” 적용","AuditEvidence": ["ģ•”ķ˜øķ‚¤ ꓀리정책","ģ•”ķ˜øķ‚¤ ź“€ė¦¬ėŒ€ģž„ ė° ź“€ė¦¬ģ‹œģŠ¤ķ…œ 화멓"],"AuditChecklist": ["ģ•”ķ˜øķ‚¤ ģƒģ„±, ģ“ģš©, 볓꓀, ė°°ķ¬, 변경, 복구, 파기 등에 ź“€ķ•œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ•”ķ˜øķ‚¤ėŠ” ķ•„ģš”ģ‹œ 복구가 ź°€ėŠ„ķ•˜ė„ė” ė³„ė„ģ˜ ģ•ˆģ „ķ•œ ģž„ģ†Œģ— ė³“ź“€ķ•˜ź³  ģ•”ķ˜øķ‚¤ ģ‚¬ģš©ģ— ź“€ķ•œ ģ ‘ź·¼ź¶Œķ•œģ„ ģµœģ†Œķ™”ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ•”ķ˜ø ģ •ģ±… 낓에 ģ•”ķ˜øķ‚¤ ꓀리와 ź“€ė Øėœ 절차, 방법 ė“±ģ“ ėŖ…ģ‹œė˜ģ–“ ģžˆģ§€ ģ•Šģ•„ ė‹“ė‹¹ģžė³„ė”œ ģ•”ķ˜øķ‚¤ ꓀리 ģˆ˜ģ¤€ ė° 방법 ģƒģ“ 등 ģ•”ķ˜øķ‚¤ ꓀리에 ģ·Øģ•½ģ‚¬ķ•­ģ“ ģ”“ģž¬ķ•˜ėŠ” 경우","사딀 2 : ė‚“ė¶€ ź·œģ •ģ— ģ¤‘ģš” 정볓넼 ģ•”ķ˜øķ™” ķ•  경우 ꓀련 ģ±…ģž„ģž ģŠ¹ģø ķ•˜ģ— ģ•”ķ˜øķ™” 키넼 ģƒģ„±ķ•˜ź³  ģ•”ķ˜øķ‚¤ ź“€ė¦¬ėŒ€ģž„ģ„ ģž‘ģ„±ķ•˜ė„ė” ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ•”ķ˜øķ‚¤ ź“€ė¦¬ėŒ€ģž„ģ— ģ¼ė¶€ ģ•”ķ˜øķ‚¤ź°€ ėˆ„ė½ė˜ģ–“ ģžˆź±°ė‚˜ ķ˜„ķ–‰ķ™”ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ź°œė°œģ‹œģŠ¤ķ…œģ— ģ ģš©ė˜ģ–“ ģžˆėŠ” ģ•”ķ˜øķ‚¤ģ™€ ģš“ģ˜ģ‹œģŠ¤ķ…œģ— 적용된 ģ•”ķ˜øķ‚¤ź°€ ė™ģ¼ķ•˜ģ—¬, ģ•”ķ˜øķ™”ėœ ģ‹¤ė°ģ“ķ„°ź°€ ź°œė°œģ‹œģŠ¤ķ…œģ„ 통핓 ģ‰½ź²Œ ė³µķ˜øķ™”ź°€ ź°€ėŠ„ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제7ģ”°(ź°œģøģ •ė³“ģ˜ ģ•”ķ˜øķ™”)"]}],"description": "ģ•”ķ˜øķ‚¤ģ˜ ģ•ˆģ „ķ•œ ģƒģ„±Ā·ģ“ģš©Ā·ė³“ź“€Ā·ė°°ķ¬Ā·ķŒŒźø°ė„¼ ģœ„ķ•œ ꓀리 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ , ķ•„ģš” ģ‹œ ė³µźµ¬ė°©ģ•ˆģ„ ė§ˆė Øķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 1,"pass": 2,"total": 9,"manual": 0}},"2.8.1": {"name": "ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ ģ •ģ˜","checks": {"macie_is_enabled": "PASS","securityhub_enabled": "PASS","fms_policy_compliant": null,"guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","accessanalyzer_enabled": "PASS","networkfirewall_in_all_vpc": "FAIL","guardduty_centrally_managed": "FAIL","wafv2_webacl_logging_enabled": "FAIL","config_recorder_all_regions_enabled": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","codebuild_project_no_secrets_in_variables": "PASS","codebuild_project_user_controlled_buildspec": "PASS","wellarchitected_workload_no_high_or_medium_risks": "FAIL","codebuild_project_source_repo_url_no_sensitive_credentials": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.8.1 ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ ģ •ģ˜","Subdomain": "2.8. ģ •ė³“ģ‹œģŠ¤ķ…œ ė„ģž… ė° 개발 ė³“ģ•ˆ","AuditEvidence": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ģøģˆ˜ 기준 ė° 절차","ģ •ė³“ģ‹œģŠ¤ķ…œ ė„ģž… RFP(ģ œģ•ˆģš”ģ²­ģ„œ) ė° źµ¬ė§¤ź³„ģ•½ģ„œ","개발 ģ‚°ģ¶œė¬¼(ģ‚¬ģ—…ģˆ˜ķ–‰ź³„ķšģ„œ, ģš”źµ¬ģ‚¬ķ•­ģ •ģ˜ģ„œ, ķ™”ė©“ģ„¤ź³„ģ„œ, ė³“ģ•ˆģ•„ķ‚¤ķ…ģ²˜ ģ„¤ź³„ģ„œ, ģ‹œķ—˜ź³„ķšģ„œ 등)","ģ‹œķģ–“ 코딩 ķ‘œģ¤€"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œģ„ ģ‹ ź·œė”œ ė„ģž…Ā·ź°œė°œ ė˜ėŠ” ė³€ź²½ķ•˜ėŠ” 경우 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģø”ė©“ģ˜ ķƒ€ė‹¹ģ„± 검토 ė° ģøģˆ˜ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œģ„ ģ‹ ź·œė”œ ė„ģž…Ā·ź°œė°œ ė˜ėŠ” ė³€ź²½ķ•˜ėŠ” 경우 법적 ģš”źµ¬ģ‚¬ķ•­, ģµœģ‹  취약점 ė“±ģ„ ķ¬ķ•Øķ•œ ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ģ„ ėŖ…ķ™•ķžˆ ģ •ģ˜ķ•˜ź³  설계 ė‹Øź³„ģ—ģ„œė¶€ķ„° ė°˜ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ•ˆģ „ķ•œ źµ¬ķ˜„ģ„ ģœ„ķ•œ 코딩 ķ‘œģ¤€ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ģ‹œģŠ¤ķ…œ ģøģˆ˜ ģ „ ė³“ģ•ˆģ„± ź²€ģ¦ 기준 ė° ģ ˆģ°Øź°€ ė§ˆė Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ģ‹ ź·œ ģ‹œģŠ¤ķ…œ ė„ģž… ģ‹œ 기씓 ģš“ģ˜ķ™˜ź²½ģ— ėŒ€ķ•œ ģ˜ķ–„ ė° ė³“ģ•ˆģ„±ģ„ ź²€ķ† ķ•˜ė„ė” ė‚“ė¶€ ź·œģ •ģ„ ė§ˆė Øķ•˜ź³  ģžˆģœ¼ė‚˜, 최근 ė„ģž…ķ•œ ģ¼ė¶€ ģ •ė³“ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•˜ģ—¬ ģøģˆ˜ ģ‹œ ė³“ģ•ˆģš”ź±“ģ— ėŒ€ķ•“ 세부 기준 ė° ź³„ķšģ“ ģˆ˜ė¦½ė˜ģ§€ ģ•Šģ•˜ģœ¼ė©°, ģ“ģ— ė”°ė¼ ģøģˆ˜ ģ‹œ ė³“ģ•ˆģ„±ź²€ķ† ź°€ ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : 개발 ꓀련 ė‚“ė¶€ 지침에 개발과 ź“€ė Øėœ ģ£¼ģš” ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­(ģøģ¦ ė° ģ•”ķ˜øķ™”, ė³“ģ•ˆė”œź·ø 등)ģ“ ģ •ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : Ź»ź°œė°œķ‘œģ¤€ģ •ģ˜ģ„œŹ¼ģ— ģ‚¬ģš©ģž ķŒØģŠ¤ģ›Œė“œė„¼ ģ•ˆģ „ķ•˜ģ§€ ģ•Šģ€ ģ•”ķ˜øķ™” ģ•Œź³ ė¦¬ģ¦˜(MD5, SHA1)으딜 ģ‚¬ģš©ķ•˜ė„ė” ė˜ģ–“ ģžˆģ–“ ꓀련 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ģ ģ ˆķžˆ ė°˜ģ˜ķ•˜ģ§€ ģ•ŠėŠ” 경우"],"RelatedRegulations": []}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ė„ģž…Ā·ź°œė°œĀ·ė³€ź²½ ģ‹œ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 법적 ģš”źµ¬ģ‚¬ķ•­, ģµœģ‹  ė³“ģ•ˆģ·Øģ•½ģ , ģ•ˆģ „ķ•œ 코딩방법 등 ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ģ„ ģ •ģ˜ķ•˜ź³  ģ ģš©ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 7,"pass": 7,"total": 16,"manual": 0}},"2.8.2": {"name": "ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ 검토 ė° ģ‹œķ—˜","checks": {"macie_is_enabled": "PASS","securityhub_enabled": "PASS","fms_policy_compliant": null,"guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","accessanalyzer_enabled": "PASS","networkfirewall_in_all_vpc": "FAIL","guardduty_centrally_managed": "FAIL","wafv2_webacl_logging_enabled": "FAIL","inspector2_active_findings_exist": "FAIL","config_recorder_all_regions_enabled": null,"guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","accessanalyzer_enabled_without_findings": "FAIL","codebuild_project_no_secrets_in_variables": "PASS","codebuild_project_user_controlled_buildspec": "PASS","wellarchitected_workload_no_high_or_medium_risks": "FAIL","codebuild_project_source_repo_url_no_sensitive_credentials": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.8.2 ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ 검토 ė° ģ‹œķ—˜","Subdomain": "2.8. ģ •ė³“ģ‹œģŠ¤ķ…œ ė„ģž… ė° 개발 ė³“ģ•ˆ","AuditEvidence": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ģøģˆ˜ ģ‹œķ—˜ ź²°ź³¼","ģš”źµ¬ģ‚¬ķ•­ 추적 매트릭스","ģ‹œķ—˜ ź³„ķšģ„œ, ģ‹œķ—˜ ź²°ź³¼ģ„œ","취약점 점검 ź²°ź³¼ģ„œ","ź°œģøģ •ė³“ ģ˜ķ–„ķ‰ź°€ģ„œ","ź°œģøģ •ė³“ ģ˜ķ–„ķ‰ź°€ ź°œģ„ ź³„ķš ģ“ķ–‰ģ ź²€ ķ™•ģøģ„œ"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ė„ģž…, 개발, 변경 ģ‹œ ė¶„ģ„ ė° 설계 ė‹Øź³„ģ—ģ„œ ģ •ģ˜ķ•œ ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ģ“ 효과적으딜 ģ ģš©ė˜ģ—ˆėŠ”ģ§€ė„¼ ķ™•ģøķ•˜źø° ģœ„ķ•œ ģ‹œķ—˜ģ„ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œģ“ ģ•ˆģ „ķ•œ 코딩 기준 등에 ė”°ė¼ ģ•ˆģ „ķ•˜ź²Œ ź°œė°œė˜ģ—ˆėŠ”ģ§€ė„¼ ķ™•ģøķ•˜źø° ģœ„ķ•œ 취약점 ģ ź²€ģ“ ģˆ˜ķ–‰ė˜ź³  ģžˆėŠ”ź°€?","ģ‹œķ—˜ ė° 취약점 점검 ź³¼ģ •ģ—ģ„œ 발견된 ė¬øģ œģ ģ“ ģ‹ ģ†ķ•˜ź²Œ ź°œģ„ ė  수 ģžˆė„ė” ź°œģ„ ź³„ķš 수립, ģ“ķ–‰ģ ź²€ ė“±ģ˜ 절차넼 ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ź³µź³µźø°ź“€ģ€ ꓀련 법령에 ė”°ė¼ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ģ‹ ź·œ 개발 ė° 변경 ģ‹œ ė¶„ģ„Ā·ģ„¤ź³„ ė‹Øź³„ģ—ģ„œ ģ˜ķ–„ķ‰ź°€źø°ź“€ģ„ ķ†µķ•˜ģ—¬ ģ˜ķ–„ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•˜ź³  ź·ø 결과넼 개발 ė° 변경 ģ‹œ ė°˜ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ģ‹œģŠ¤ķ…œ źµ¬ķ˜„ ģ“ķ›„ 개발 ꓀련 ė‚“ė¶€ 지침 ė° ė¬øģ„œģ— ģ •ģ˜ėœ ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ģ„ ģ‹œķ—˜ķ•˜ģ§€ ģ•Šź³  ģžˆėŠ” 경우","사딀 2 : ģ‘ģš©ķ”„ė”œź·øėžØ ķ…ŒģŠ¤ķŠø ģ‹œė‚˜ė¦¬ģ˜¤ ė° 기술적 취약점 점검항목에 ģž…ė „ź°’ ģœ ķšØģ„± 첓크 ė“±ģ˜ ģ¤‘ģš” 점검항목 ģ¼ė¶€ź°€ ėˆ„ė½ėœ 경우","사딀 3 : źµ¬ķ˜„ ė˜ėŠ” ģ‹œķ—˜ ź³¼ģ •ģ—ģ„œ ģ•Œė ¤ģ§„ 기술적 ģ·Øģ•½ģ ģ“ ģ”“ģž¬ķ•˜ėŠ”ģ§€ 여부넼 ģ ź²€ķ•˜ģ§€ ģ•Šź±°ė‚˜, ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ė˜ėŠ” ģŠ¹ģø ģ—†ģ“ ķ™•ģøėœ 취약점에 ėŒ€ķ•œ ź°œģ„ ģ”°ģ¹˜ė„¼ ģ“ķ–‰ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ź³µź³µźø°ź“€ģ“ 5만 ėŖ… ģ“ģƒ ģ •ė³“ģ£¼ģ²“ģ˜ ź³ ģœ ģ‹ė³„ģ •ė³“ė„¼ ģ²˜ė¦¬ķ•˜ėŠ” 등 ģ˜ķ–„ķ‰ź°€ ģ˜ė¬“ ėŒ€ģƒ ź°œģøģ •ė³“ ķŒŒģ¼ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ„ ģ‹ ź·œė”œ źµ¬ģ¶•ķ•˜ė©“ģ„œ ģ˜ķ–„ķ‰ź°€ė„¼ ģ‹¤ģ‹œķ•˜ģ§€ ģ•Šģ€ 경우","사딀 5 : ź³µź³µźø°ź“€ģ“ ģ˜ķ–„ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•œ 후 ģ˜ķ–„ķ‰ź°€źø°ź“€ģœ¼ė”œė¶€ķ„° ģ˜ķ–„ķ‰ź°€ģ„œė„¼ ė°›ģ€ ģ§€ 2ź°œģ›”ģ“ ģ§€ė‚¬ģŒģ—ė„ ė¶ˆźµ¬ķ•˜ź³  ģ˜ķ–„ķ‰ź°€ģ„œė„¼ ź°œģøģ •ė³“ ė³“ķ˜øģœ„ģ›ķšŒģ— ģ œģ¶œķ•˜ģ§€ ģ•Šģ€ 경우","사딀 6 : ģ‹ ź·œ ģ‹œģŠ¤ķ…œ ė„ģž… ģ‹œ 기씓 ģš“ģ˜ķ™˜ź²½ģ— ėŒ€ķ•œ ģ˜ķ–„ ė° ė³“ģ•ˆģ„±ģ„ 검토(취약점 점검 등)ķ•˜ė„ė” ė‚“ė¶€ ģ§€ģ¹Øģ„ ė§ˆė Øķ•˜ź³  ģžˆģœ¼ė‚˜, 최근 ė„ģž…ķ•œ ģ¼ė¶€ ģ •ė³“ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•˜ģ—¬ ģøģˆ˜ ģ‹œ 취약점 점검 등 ė³“ģ•ˆģ„±ź²€ķ† ź°€ ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제33ģ”°(ź°œģøģ •ė³“ ģ˜ķ–„ķ‰ź°€)","ź°œģøģ •ė³“ ģ˜ķ–„ķ‰ź°€ģ— ź“€ķ•œ ź³ ģ‹œ"]}],"description": "사전 ģ •ģ˜ėœ ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ģ— ė”°ė¼ ģ •ė³“ģ‹œģŠ¤ķ…œģ“ ė„ģž… ė˜ėŠ” źµ¬ķ˜„ė˜ģ—ˆėŠ”ģ§€ė„¼ ź²€ķ† ķ•˜źø° ģœ„ķ•˜ģ—¬ 법적 ģš”źµ¬ģ‚¬ķ•­ ģ¤€ģˆ˜, ģµœģ‹  ė³“ģ•ˆģ·Øģ•½ģ  점검, ģ•ˆģ „ķ•œ 코딩 źµ¬ķ˜„, ź°œģøģ •ė³“ ģ˜ķ–„ķ‰ź°€ ė“±ģ˜ 검토 기준과 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ , 발견된 ė¬øģ œģ ģ— ėŒ€ķ•œ ź°œģ„ ģ”°ģ¹˜ė„¼ ģˆ˜ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 10,"pass": 7,"total": 19,"manual": 0}},"2.8.3": {"name": "ģ‹œķ—˜ź³¼ 욓영 ķ™˜ź²½ 분리","checks": {"codebuild_project_user_controlled_buildspec": "PASS"},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.8.3 ģ‹œķ—˜ź³¼ 욓영 ķ™˜ź²½ 분리","Subdomain": "2.8. ģ •ė³“ģ‹œģŠ¤ķ…œ ė„ģž… ė° 개발 ė³“ģ•ˆ","AuditEvidence": ["ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„(ģ‹œķ—˜ķ™˜ź²½ 구성 ķ¬ķ•Ø)","욓영 ķ™˜ź²½ź³¼ ź°œė°œĀ·ģ‹œķ—˜ ķ™˜ź²½ ź°„ ģ ‘ź·¼ķ†µģ œ 적용 ķ˜„ķ™©"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ 개발 ė° ģ‹œķ—˜ ģ‹œģŠ¤ķ…œģ„ ģš“ģ˜ģ‹œģŠ¤ķ…œź³¼ ė¶„ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ė¶ˆź°€ķ”¼ķ•œ ģ‚¬ģœ ė”œ 개발과 ģš“ģ˜ķ™˜ź²½ģ˜ 분리가 ģ–“ė ¤ģš“ 경우 ģƒķ˜øź²€ķ† , ģƒźø‰ģž ėŖØė‹ˆķ„°ė§, 변경 ģŠ¹ģø, ģ±…ģž„ģ¶”ģ ģ„± 확볓 ė“±ģ˜ ė³“ģ•ˆėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ė˜ėŠ” ģŠ¹ģø ģ—†ģ“ ė³„ė„ģ˜ ź°œė°œķ™˜ź²½ģ„ źµ¬ģ„±ķ•˜ģ§€ ģ•Šź³  ģš“ģ˜ķ™˜ź²½ģ—ģ„œ 직접 ģ†ŒģŠ¤ģ½”ė“œ ė³€ź²½ģ„ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : ė¶ˆź°€ķ”¼ķ•˜ź²Œ ź°œė°œģ‹œģŠ¤ķ…œź³¼ ģš“ģ˜ģ‹œģŠ¤ķ…œģ„ ė¶„ė¦¬ķ•˜ģ§€ ģ•Šź³  욓영 중에 ģžˆģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•œ 상호 검토 ė‚“ģ—­, ėŖØė‹ˆķ„°ė§ ė‚“ģ—­ ė“±ģ“ ėˆ„ė½ė˜ģ–“ ģžˆėŠ” 경우","사딀 3 : ź°œė°œģ‹œģŠ¤ķ…œģ“ ė³„ė„ė”œ źµ¬ģ„±ė˜ģ–“ ģžˆģœ¼ė‚˜, ź°œė°œķ™˜ź²½ģœ¼ė”œė¶€ķ„° ģš“ģ˜ķ™˜ź²½ģœ¼ė”œģ˜ ģ ‘ź·¼ģ“ ķ†µģ œė˜ģ§€ ģ•Šģ•„ ź°œė°œģžė“¤ģ“ ź°œė°œģ‹œģŠ¤ķ…œģ„ ź²½ģœ ķ•˜ģ—¬ ė¶ˆķ•„ģš”ķ•˜ź²Œ ģš“ģ˜ģ‹œģŠ¤ķ…œ ģ ‘ź·¼ģ“ ź°€ėŠ„ķ•œ 경우"],"RelatedRegulations": []}],"description": "개발 ė° ģ‹œķ—˜ ģ‹œģŠ¤ķ…œģ€ ģš“ģ˜ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ė¹„ģøź°€ ģ ‘ź·¼ ė° ė³€ź²½ģ˜ ģœ„ķ—˜ģ„ ź°ģ†Œģ‹œķ‚¤źø° ģœ„ķ•˜ģ—¬ ģ›ģ¹™ģ ģœ¼ė”œ ė¶„ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.8.4": {"name": "ģ‹œķ—˜ ė°ģ“ķ„° ė³“ģ•ˆ","checks": {"codebuild_project_no_secrets_in_variables": "PASS"},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.8.4 ģ‹œķ—˜ ė°ģ“ķ„° ė³“ģ•ˆ","Subdomain": "2.8. ģ •ė³“ģ‹œģŠ¤ķ…œ ė„ģž… ė° 개발 ė³“ģ•ˆ","AuditEvidence": ["ģ‹œķ—˜ė°ģ“ķ„° ķ˜„ķ™©","ģ‹œķ—˜ė°ģ“ķ„° ģƒģ„± ź·œģ¹™","ģš“ģ˜ė°ģ“ķ„°ė„¼ ģ‹œķ—˜ķ™˜ź²½ģ— ģ‚¬ģš©ķ•œ 경우, ꓀련 ģŠ¹ģø ģ“ė „"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ 개발 ė° ģ‹œķ—˜ ź³¼ģ •ģ—ģ„œ ģ‹¤ģ œ 욓영 ė°ģ“ķ„°ģ˜ ģ‚¬ģš©ģ„ ģ œķ•œķ•˜ź³  ģžˆėŠ”ź°€?","ė¶ˆź°€ķ”¼ķ•˜ź²Œ ģš“ģ˜ė°ģ“ķ„°ė„¼ ģ‹œķ—˜ ķ™˜ź²½ģ—ģ„œ ģ‚¬ģš©ķ•  경우 ģ±…ģž„ģž ģŠ¹ģø, ģ ‘ź·¼ ė° ģœ ģ¶œėŖØė‹ˆķ„°ė§, ģ‹œķ—˜ 후 ė°ģ“ķ„° ģ‚­ģ œ ė“±ģ˜ ķ†µģ œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 개발 ģ„œė²„ģ—ģ„œ ģ‚¬ģš©ķ•  ģ‹œķ—˜ ė°ģ“ķ„° ģƒģ„±ģ— ėŒ€ķ•œ 구첓적 기준 ė° ģ ˆģ°Øź°€ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ė° ģ±…ģž„ģž ģŠ¹ģø ģ—†ģ“ 실 ģš“ģ˜ė°ģ“ķ„°ė„¼ ź°€ź³µķ•˜ģ§€ ģ•Šź³  ģ‹œķ—˜ ė°ģ“ķ„°ė”œ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : ė¶ˆź°€ķ”¼ķ•œ ģ‚¬ģœ ė”œ 사전 ģŠ¹ģøģ„ 받아 실 ģš“ģ˜ė°ģ“ķ„°ė„¼ ģ‹œķ—˜ ģš©ė„ė”œ ģ‚¬ģš©ķ•˜ė©“ģ„œ, ķ…ŒģŠ¤ķŠø ė°ģ“ķ„°ė² ģ“ģŠ¤ģ— ėŒ€ķ•˜ģ—¬ 욓영 ė°ģ“ķ„°ė² ģ“ģŠ¤ģ™€ ė™ģ¼ķ•œ ģˆ˜ģ¤€ģ˜ ģ ‘ź·¼ķ†µģ œė„¼ ģ ģš©ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : 실 ģš“ģ˜ė°ģ“ķ„°ė„¼ ķ…ŒģŠ¤ķŠø ģš©ė„ė”œ ģ‚¬ģš©ķ•œ 후 ķ…ŒģŠ¤ķŠøź°€ ģ™„ė£Œė˜ģ—ˆģŒģ—ė„ 실 ģš“ģ˜ė°ģ“ķ„°ė„¼ ķ…ŒģŠ¤ķŠø ė°ģ“ķ„°ė² ģ“ģŠ¤ģ—ģ„œ ģ‚­ģ œķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ģ‹œģŠ¤ķ…œ ģ‹œķ—˜ ź³¼ģ •ģ—ģ„œ ģš“ģ˜ė°ģ“ķ„°ģ˜ ģœ ģ¶œģ„ ģ˜ˆė°©ķ•˜źø° ģœ„ķ•˜ģ—¬ ģ‹œķ—˜ ė°ģ“ķ„°ģ˜ ģƒģ„±ź³¼ ģ“ģš© ė° ꓀리, 파기, 기술적 ė³“ķ˜øģ”°ģ¹˜ģ— ź“€ķ•œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.8.5": {"name": "ģ†ŒģŠ¤ ķ”„ė”œź·øėžØ ꓀리","checks": {"ecr_repositories_not_publicly_accessible": "PASS","codeartifact_packages_external_public_publishing_disabled": null},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.8.5 ģ†ŒģŠ¤ ķ”„ė”œź·øėžØ ꓀리","Subdomain": "2.8. ģ •ė³“ģ‹œģŠ¤ķ…œ ė„ģž… ė° 개발 ė³“ģ•ˆ","AuditEvidence": ["SVN 등 ķ˜•ģƒź“€ė¦¬ģ‹œģŠ¤ķ…œ 욓영 ķ˜„ķ™©(ģ ‘ź·¼ź¶Œķ•œģž ėŖ©ė” 등)","ģ†ŒģŠ¤ ķ”„ė”œź·øėžØ 변경 ģ“ė „"],"AuditChecklist": ["ė¹„ģøź°€ģžģ— ģ˜ķ•œ ģ†ŒģŠ¤ ķ”„ė”œź·øėžØ ģ ‘ź·¼ģ„ ķ†µģ œķ•˜źø° ģœ„ķ•œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ†ŒģŠ¤ ķ”„ė”œź·øėžØģ€ ģž„ģ•  등 ė¹„ģƒģ‹œė„¼ ėŒ€ė¹„ķ•˜ģ—¬ ģš“ģ˜ķ™˜ź²½ģ“ ģ•„ė‹Œ 곳에 ģ•ˆģ „ķ•˜ź²Œ ė³“ź“€ķ•˜ź³  ģžˆėŠ”ź°€?","ģ†ŒģŠ¤ ķ”„ė”œź·øėžØģ— ėŒ€ķ•œ ė³€ź²½ģ“ė „ģ„ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė³„ė„ģ˜ ģ†ŒģŠ¤ ķ”„ė”œź·øėžØ 백업 ė° ķ˜•ģƒź“€ė¦¬ģ‹œģŠ¤ķ…œģ“ źµ¬ģ¶•ė˜ģ–“ ģžˆģ§€ ģ•Šģœ¼ė©°, ģ“ģ „ ė²„ģ „ģ˜ ģ†ŒģŠ¤ ģ½”ė“œė„¼ 욓영 ģ„œė²„ ė˜ėŠ” ź°œė°œģž PC에 ģŠ¹ģø ė° ģ“ė „ź“€ė¦¬ ģ—†ģ“ ė³“ź“€ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : ķ˜•ģƒź“€ė¦¬ģ‹œģŠ¤ķ…œģ„ źµ¬ģ¶•ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜ ķ˜•ģƒź“€ė¦¬ģ‹œģŠ¤ķ…œ ė˜ėŠ” ķ˜•ģƒź“€ė¦¬ģ‹œģŠ¤ķ…œģ— ģ €ģž„ėœ ģ†ŒģŠ¤ģ½”ė“œģ— ėŒ€ķ•œ ģ ‘ź·¼ģ œķ•œ, ģ ‘ź·¼ ė° ė³€ź²½ģ“ė „ģ“ ģ ģ ˆķžˆ ź“€ė¦¬ė˜ģ§€ ģ•Šź³  ģžˆėŠ” 경우","사딀 3 : ė‚“ė¶€ ź·œģ •ģ—ėŠ” ķ˜•ģƒź“€ė¦¬ģ‹œģŠ¤ķ…œģ„ ķ†µķ•˜ģ—¬ ģ†ŒģŠ¤ ķ”„ė”œź·øėžØ 버전꓀리넼 ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ģµœģ‹  ė²„ģ „ģ˜ ģ†ŒģŠ¤ ķ”„ė”œź·øėžØģ€ ź°œė°œģž PCģ—ė§Œ ė³“ź“€ė˜ģ–“ ģžˆź³  ģ“ģ— ėŒ€ķ•œ ė³„ė„ģ˜ ė°±ģ—…ģ“ ģˆ˜ķ–‰ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ģ†ŒģŠ¤ ķ”„ė”œź·øėžØģ€ ģøź°€ėœ ģ‚¬ģš©ģžė§Œģ“ 접근할 수 ģžˆė„ė” ź“€ė¦¬ķ•˜ź³ , ģš“ģ˜ķ™˜ź²½ģ— ė³“ź“€ķ•˜ģ§€ ģ•ŠėŠ” ź²ƒģ„ ģ›ģ¹™ģœ¼ė”œ ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"2.8.6": {"name": "ģš“ģ˜ķ™˜ź²½ ģ“ź“€","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.8.6 ģš“ģ˜ķ™˜ź²½ ģ“ź“€","Subdomain": "2.8. ģ •ė³“ģ‹œģŠ¤ķ…œ ė„ģž… ė° 개발 ė³“ģ•ˆ","AuditEvidence": ["ģ“ź“€ 절차","ģ“ź“€ ė‚“ģ—­(ģ‹ ģ²­Ā·ģŠ¹ģø, ģ‹œķ—˜, ģ“ź“€ 등)"],"AuditChecklist": ["ģ‹ ź·œ ė„ģž…Ā·ź°œė°œ ė° ė³€ź²½ėœ ģ‹œģŠ¤ķ…œģ„ ģš“ģ˜ķ™˜ź²½ģœ¼ė”œ ģ•ˆģ „ķ•˜ź²Œ ģ“ź“€ķ•˜źø° ģœ„ķ•œ ķ†µģ œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģš“ģ˜ķ™˜ź²½ģœ¼ė”œ ģ“ź“€ ģ‹œ ė°œģƒķ•  수 ģžˆėŠ” ė¬øģ œģ— ėŒ€ķ•œ ėŒ€ģ‘ ė°©ģ•ˆģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","ģš“ģ˜ķ™˜ź²½ģ—ėŠ” ģ„œė¹„ģŠ¤ 실행에 ķ•„ģš”ķ•œ ķŒŒģ¼ė§Œģ„ ģ„¤ģ¹˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œė°œĀ·ė³€ź²½ģ“ ģ™„ė£Œėœ ģ†ŒģŠ¤ ķ”„ė”œź·øėžØģ„ ģš“ģ˜ķ™˜ź²½ģœ¼ė”œ ģ“ź“€ ģ‹œ ź²€ķ† Ā·ģŠ¹ģøķ•˜ėŠ” ģ ˆģ°Øź°€ ė§ˆė Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ģš“ģ˜ģ„œė²„ģ— ģ„œė¹„ģŠ¤ 실행에 ė¶ˆķ•„ģš”ķ•œ ķŒŒģ¼(ģ†ŒģŠ¤ģ½”ė“œ ė˜ėŠ” ė°°ķ¬ėŖØė“ˆ, 백업본, 개발 ꓀련 ė¬øģ„œ, 매뉓얼 등)ģ“ ģ”“ģž¬ķ•˜ėŠ” 경우","사딀 3 : ė‚“ė¶€ 지침에 ģš“ģ˜ķ™˜ź²½ ģ“ź“€ ģ‹œ ģ•ˆģ „ķ•œ ģ“ź“€Ā·ė³µźµ¬ė„¼ ģœ„ķ•˜ģ—¬ ė³€ź²½ģž‘ģ—… ģš”ģ²­ģ„œ ė° ź²°ź³¼ģ„œė„¼ ģž‘ģ„±ķ•˜ė„ė” ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, ꓀련 ė¬øģ„œź°€ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ė‚“ė¶€ ģ§€ģ¹Øģ—ėŠ” ėŖØė°”ģ¼ ģ•±ģ„ ģ•±ė§ˆģ¼“ģ— ė°°ķ¬ķ•˜ėŠ” 경우 ė‚“ė¶€ 검토 ė° ģŠ¹ģøģ„ ė°›ė„ė” ķ•˜ź³  ģžˆģœ¼ė‚˜, ź°œė°œģžź°€ 핓당 절차넼 ź±°ģ¹˜ģ§€ ģ•Šź³  ģž„ģ˜ė”œ ģ•±ė§ˆģ¼“ģ— ė°°ķ¬ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": []}],"description": "ģ‹ ź·œ ė„ģž…Ā·ź°œė°œ ė˜ėŠ” ė³€ź²½ėœ ģ‹œģŠ¤ķ…œģ„ ģš“ģ˜ķ™˜ź²½ģœ¼ė”œ ģ“ź“€ķ•  ė•ŒėŠ” ķ†µģ œėœ 절차넼 ė”°ė¼ģ•¼ ķ•˜ź³ , ģ‹¤ķ–‰ģ½”ė“œėŠ” ģ‹œķ—˜ ė° ģ‚¬ģš©ģž ģøģˆ˜ ģ ˆģ°Øģ— ė”°ė¼ ģ‹¤ķ–‰ė˜ģ–“ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.9.1": {"name": "변경꓀리","checks": {"codebuild_project_older_90_days": "FAIL","config_recorder_all_regions_enabled": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.9.1 변경꓀리","Subdomain": "2.9. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ģš“ģ˜ź“€ė¦¬","AuditEvidence": ["변경꓀리 절차","변경꓀리 ģˆ˜ķ–‰ ė‚“ģ—­(ģ‹ ģ²­Ā·ģŠ¹ģø, 변경 ė‚“ģ—­ 등)","변경에 따넸 ģ˜ķ–„ė¶„ģ„ ź²°ź³¼"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ꓀련 ģžģ‚°(ķ•˜ė“œģ›Øģ–“, 욓영첓제, 상용 ģ†Œķ”„ķŠøģ›Øģ–“ ķŒØķ‚¤ģ§€ 등) 변경에 ź“€ķ•œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œ ꓀련 ģžģ‚° ė³€ź²½ģ„ ģˆ˜ķ–‰ķ•˜źø° ģ „ ģ„±ėŠ„ ė° ė³“ģ•ˆģ— ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ė¶„ģ„ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 최근 DMZ 구간 ģ“ģ¤‘ķ™”ģ— 따넸 변경 ģž‘ģ—…ģ„ ģˆ˜ķ–‰ķ•˜ģ˜€ģœ¼ė‚˜, 변경 후 ė°œģƒķ•  수 ģžˆėŠ” ė³“ģ•ˆģœ„ķ—˜ģ„± ė° ģ„±ėŠ„ ķ‰ź°€ģ— ėŒ€ķ•œ ģˆ˜ķ–‰Ā·ģŠ¹ģø ģ¦ź±°ģžė£Œź°€ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우","사딀 2 : 최근 ė„¤ķŠøģ›Œķ¬ 변경 ģž‘ģ—…ģ„ ģˆ˜ķ–‰ķ•˜ģ˜€ģœ¼ė‚˜ ꓀련 검토 ė° 공지가 ģ¶©ė¶„ķžˆ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ•„ ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„ ė° ģ¼ė¶€ ģ ‘ź·¼ķ†µģ œģ‹œģŠ¤ķ…œ(ģ¹Øģž…ģ°Øė‹Øģ‹œģŠ¤ķ…œ, ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ģ œģ–“ģ‹œģŠ¤ķ…œ 등)ģ˜ ģ ‘ź·¼ķ†µģ œ 리스트(ACL)에 ģ ģ ˆķžˆ ė°˜ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ė³€ź²½ź“€ė¦¬ģ‹œģŠ¤ķ…œģ„ źµ¬ģ¶•ķ•˜ģ—¬ ģ •ė³“ģ‹œģŠ¤ķ…œ ģž…ź³  ė˜ėŠ” 변경 ģ‹œ ģ„±ėŠ„ ė° ė³“ģ•ˆģ— ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ė¶„ģ„ ė°ķ˜‘ģ˜ķ•˜ź³  ꓀련 ģ“ė „ģ„ ź“€ė¦¬ķ•˜ė„ė” ķ•˜ź³  ģžˆģœ¼ė‚˜, 핓당 ģ‹œģŠ¤ķ…œģ„ ķ†µķ•˜ģ§€ ģ•Šź³ ė„ ģ‹œģŠ¤ķ…œ ė³€ź²½ģ“ ź°€ėŠ„ķ•˜ė©°, ꓀련 ė³€ź²½ģ‚¬ķ•­ģ“ ģ ģ ˆķžˆ ź²€ķ† ė˜ģ§€ ģ•ŠėŠ” 경우"],"RelatedRegulations": []}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œ ꓀련 ģžģ‚°ģ˜ ėŖØė“  ė³€ź²½ė‚“ģ—­ģ„ ꓀리할 수 ģžˆė„ė” 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ , 변경 ģ „ ģ‹œģŠ¤ķ…œģ˜ ģ„±ėŠ„ ė° ė³“ģ•ˆģ— ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ė¶„ģ„ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 2,"pass": 0,"total": 14,"manual": 0}},"2.9.2": {"name": "ģ„±ėŠ„ ė° ģž„ģ• ź“€ė¦¬","checks": {"rds_cluster_multi_az": "FAIL","elb_is_in_multiple_az": "FAIL","rds_instance_multi_az": "FAIL","elbv2_is_in_multiple_az": "PASS","s3_bucket_no_mfa_delete": "FAIL","vpc_subnet_different_az": "PASS","neptune_cluster_multi_az": null,"elbv2_deletion_protection": "FAIL","autoscaling_group_multiple_az": null,"dms_instance_multi_az_enabled": null,"rds_cluster_backtrack_enabled": null,"cloudtrail_multi_region_enabled": "PASS","rds_cluster_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL","acm_certificates_expiration_check": "PASS","s3_bucket_cross_region_replication": "FAIL","trustedadvisor_errors_and_warnings": null,"config_recorder_all_regions_enabled": null,"kms_cmk_not_deleted_unintentionally": null,"neptune_cluster_deletion_protection": null,"networkfirewall_deletion_protection": null,"rds_instance_certificate_expiration": "PASS","route53_domains_transferlock_enabled": null,"cloudtrail_bucket_requires_mfa_delete": null,"elb_cross_zone_load_balancing_enabled": "PASS","documentdb_cluster_deletion_protection": null,"documentdb_cluster_cloudwatch_log_export": null,"ec2_instance_detailed_monitoring_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","iam_no_expired_server_certificates_stored": null,"kafka_cluster_enhanced_monitoring_enabled": null,"elasticache_redis_cluster_multi_az_enabled": null,"directoryservice_ldap_certificate_expiration": null,"cognito_user_pool_deletion_protection_enabled": null,"trustedadvisor_premium_support_plan_subscribed": null,"directoryservice_directory_monitor_notifications": null,"cloudformation_stacks_termination_protection_enabled": "FAIL","cloudtrail_multi_region_enabled_logging_management_events": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.9.2 ģ„±ėŠ„ ė° ģž„ģ• ź“€ė¦¬","Subdomain": "2.9. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ģš“ģ˜ź“€ė¦¬","AuditEvidence": ["ģ„±ėŠ„ ė° ģš©ėŸ‰ ėŖØė‹ˆķ„°ė§ 절차","ģ„±ėŠ„ ė° ģš©ėŸ‰ ėŖØė‹ˆķ„°ė§ ģ¦ź±°ģžė£Œ(낓부볓고 ź²°ź³¼ 등)","ģž„ģ• ėŒ€ģ‘ 절차","ģž„ģ• ģ”°ģ¹˜ė³“ź³ ģ„œ"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ź°€ģš©ģ„± ė³“ģž„ģ„ ģœ„ķ•˜ģ—¬ ģ„±ėŠ„ ė° ģš©ėŸ‰ģ„ ģ§€ģ†ģ ģœ¼ė”œ ėŖØė‹ˆķ„°ė§ķ•  수 ģžˆėŠ” 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œ ģ„±ėŠ„ ė° ģš©ėŸ‰ ģš”źµ¬ģ‚¬ķ•­(ģž„ź³„ģ¹˜)ģ„ ģ“ˆź³¼ķ•˜ėŠ” ź²½ģš°ģ— ėŒ€ķ•œ ėŒ€ģ‘ģ ˆģ°Øė„¼ 수립 ė° ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œ ģž„ģ• ė„¼ ģ¦‰ģ‹œ ģøģ§€ķ•˜ź³  ėŒ€ģ‘ķ•˜źø° ģœ„ķ•œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģž„ģ•  ė°œģƒ ģ‹œ ģ ˆģ°Øģ— ė”°ė¼ ģ”°ģ¹˜ķ•˜ź³  ģž„ģ• ģ”°ģ¹˜ė³“ź³ ģ„œ ė“±ģ„ ķ†µķ•˜ģ—¬ ģž„ģ• ģ”°ģ¹˜ė‚“ģ—­ģ„ źø°ė”ķ•˜ģ—¬ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ‹¬ź°ė„ź°€ ė†’ģ€ ģž„ģ• ģ˜ 경우 ģ›ģøė¶„ģ„ģ„ ķ†µķ•œ ģž¬ė°œė°©ģ§€ ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ„±ėŠ„ ė° ģš©ėŸ‰ ꓀리넼 ģœ„ķ•œ ėŒ€ģƒė³„ ģš”źµ¬ģ‚¬ķ•­(ģž„ź³„ģ¹˜ 등)ģ„ ģ •ģ˜ķ•˜ź³  ģžˆģ§€ ģ•Šź±°ė‚˜ ģ •źø° ģ ź²€ė³“ź³ ģ„œ 등에 źø°ė”ķ•˜ź³  ģžˆģ§€ ģ•Šģ•„ ķ˜„ķ™©ģ„ ķŒŒģ•…ķ•  수 ģ—†ėŠ” 경우","사딀 2 : ģ„±ėŠ„ ė˜ėŠ” ģš©ėŸ‰ źø°ģ¤€ģ„ ģ“ˆź³¼ķ•˜ģ˜€ģœ¼ė‚˜ ꓀련 검토 ė° ķ›„ģ†ģ”°ģ¹˜ė°©ģ•ˆ ģˆ˜ė¦½Ā·ģ“ķ–‰ģ“ ģ“ė£Øģ–“ģ§€ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģ „ģ‚°ģž„ė¹„ ģž„ģ• ėŒ€ģ‘ģ ˆģ°Øė„¼ ģˆ˜ė¦½ķ•˜ź³  ģžˆģœ¼ė‚˜ ė„¤ķŠøģ›Œķ¬ 구성 ė° 외주업첓 변경 ė“±ģ˜ 낓·외부 ķ™˜ź²½ė³€ķ™”ź°€ ģ ģ ˆķžˆ ė°˜ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ģž„ģ• ģ²˜ė¦¬ģ ˆģ°Øģ™€ ģž„ģ• ģœ ķ˜•ė³„ ģ”°ģ¹˜ė°©ė²• ź°„ ģ¼ź“€ģ„±ģ“ ģ—†ź±°ė‚˜ ģ˜ˆģƒģ†Œģš”ģ‹œź°„ 산정에 ėŒ€ķ•œ 근거가 ė¶€ģ”±ķ•˜ģ—¬ ģ‹ ģ†Ā·ģ •ķ™•ķ•˜ź³  ģ²“ź³„ģ ģø ėŒ€ģ‘ģ“ ģ–“ė ¤ģš“ 경우"],"RelatedRegulations": []}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ź°€ģš©ģ„± ė³“ģž„ģ„ ģœ„ķ•˜ģ—¬ ģ„±ėŠ„ ė° ģš©ėŸ‰ ģš”źµ¬ģ‚¬ķ•­ģ„ ģ •ģ˜ķ•˜ź³  ķ˜„ķ™©ģ„ ģ§€ģ†ģ ģœ¼ė”œ ėŖØė‹ˆķ„°ė§ķ•˜ģ—¬ģ•¼ ķ•˜ė©°, ģž„ģ•  ė°œģƒ ģ‹œ 효과적으딜 ėŒ€ģ‘ķ•˜źø° ģœ„ķ•œ ķƒģ§€Ā·źø°ė”Ā·ė¶„ģ„Ā·ė³µźµ¬Ā·ė³“ź³  ė“±ģ˜ 절차넼 ģˆ˜ė¦½Ā·ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 11,"pass": 6,"total": 39,"manual": 0}},"2.9.3": {"name": "백업 ė° 복구꓀리","checks": {"ec2_ami_public": null,"backup_plans_exist": "PASS","backup_vaults_exist": null,"backup_vaults_encrypted": "PASS","ec2_ebs_public_snapshot": "PASS","efs_have_backup_enabled": "FAIL","s3_bucket_public_access": null,"backup_reportplans_exist": null,"s3_bucket_kms_encryption": "FAIL","s3_bucket_public_list_acl": null,"s3_bucket_public_write_acl": null,"ec2_ebs_snapshots_encrypted": "FAIL","rds_instance_backup_enabled": "PASS","rds_snapshots_public_access": "PASS","s3_bucket_lifecycle_enabled": "FAIL","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"s3_bucket_default_encryption": "PASS","rds_cluster_backtrack_enabled": null,"neptune_cluster_backup_enabled": null,"ec2_ebs_volume_snapshots_exists": "FAIL","neptune_cluster_public_snapshot": null,"documentdb_cluster_backup_enabled": null,"documentdb_cluster_public_snapshot": null,"rds_cluster_copy_tags_to_snapshots": "FAIL","s3_bucket_cross_region_replication": "FAIL","rds_instance_copy_tags_to_snapshots": null,"redshift_cluster_automated_snapshot": null,"s3_access_point_public_access_block": "PASS","s3_bucket_policy_public_write_access": "PASS","lightsail_instance_automated_snapshots": null,"dlm_ebs_snapshot_lifecycle_policy_exists": "FAIL","elasticache_redis_cluster_backup_enabled": null,"ecr_repositories_lifecycle_policy_enabled": "FAIL","directoryservice_directory_snapshots_limit": null,"ec2_ebs_snapshot_account_block_public_access": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.9.3 백업 ė° 복구꓀리","Subdomain": "2.9. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ģš“ģ˜ź“€ė¦¬","AuditEvidence": ["백업 ė° 복구 절차","ė³µźµ¬ķ…ŒģŠ¤ķŠø ź²°ź³¼","ģ†Œģ‚°ė°±ģ—… ķ˜„ķ™©"],"AuditChecklist": ["백업 ėŒ€ģƒ, 주기, 방법, 절차 ė“±ģ“ ķ¬ķ•Øėœ 백업 ė° 복구절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ė°±ģ—…ėœ ģ •ė³“ģ˜ 완전성과 정확성, ė³µźµ¬ģ ˆģ°Øģ˜ ģ ģ ˆģ„±ģ„ ķ™•ģøķ•˜źø° ģœ„ķ•˜ģ—¬ ģ •źø°ģ ģœ¼ė”œė³µźµ¬ ķ…ŒģŠ¤ķŠøė„¼ ģ‹¤ģ‹œķ•˜ź³  ģžˆėŠ”ź°€?","ģ¤‘ģš”ģ •ė³“ź°€ ģ €ģž„ėœ ė°±ģ—…ė§¤ģ²“ģ˜ 경우 ģž¬ķ•“Ā·ģž¬ė‚œģ— ėŒ€ģ²˜ķ•  수 ģžˆė„ė” ė°±ģ—…ė§¤ģ²“ė„¼ė¬¼ė¦¬ģ ģœ¼ė”œ ė–Øģ–“ģ§„ ģž„ģ†Œģ— ģ†Œģ‚°ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 백업 ėŒ€ģƒ, 주기, 방법, 절차 ė“±ģ“ ķ¬ķ•Øėœ 백업 ė° 복구 ģ ˆģ°Øź°€ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ė°±ģ—…ģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆģœ¼ė‚˜ 법적 ģš”źµ¬ģ‚¬ķ•­ģ— ė”°ė¼ ģž„źø°ź°„(6ź°œģ›”, 3ė…„, 5ė…„ 등) ė³“ź“€ģ“ ķ•„ģš”ķ•œ 백업 ėŒ€ģƒ 정볓가 백업 정책에 ė”°ė¼ ė³“ź“€ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģƒģœ„ 지침 ė˜ėŠ” ė‚“ė¶€ 지침에 ė”°ė¼ ė³„ė„ė”œ ė°±ģ—…ķ•˜ģ—¬ ź“€ė¦¬ķ•˜ė„ė” ėŖ…ģ‹œėœ ģ¼ė¶€ ģ‹œģŠ¤ķ…œ(ė³“ģ•ˆģ‹œģŠ¤ķ…œ ģ •ģ±… ė° 딜그 등)에 ėŒ€ķ•œ ė°±ģ—…ģ“ ģ“ķ–‰ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ģƒģœ„ 지침 ė˜ėŠ” ė‚“ė¶€ ģ§€ģ¹Øģ—ėŠ” 주기적으딜 백업매첓에 ėŒ€ķ•œ 복구 ķ…ŒģŠ¤ķŠøė„¼ ģˆ˜ķ–‰ķ•˜ė„ė” ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜ ė³µźµ¬ķ…ŒģŠ¤ķŠøė„¼ ģž„źø°ź°„ ģ‹¤ģ‹œķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제11ģ”°(ģž¬ķ•“Ā·ģž¬ė‚œ ėŒ€ė¹„ ģ•ˆģ „ģ”°ģ¹˜)"]}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ź°€ģš©ģ„±ź³¼ ė°ģ“ķ„° ė¬“ź²°ģ„±ģ„ ģœ ģ§€ķ•˜źø° ģœ„ķ•˜ģ—¬ 백업 ėŒ€ģƒ, 주기, 방법, ė³“ź“€ģž„ģ†Œ, 볓꓀기간, ģ†Œģ‚° ė“±ģ˜ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ģ•„ģšøėŸ¬ 사고 ė°œģƒ ģ‹œ ģ ģ‹œģ— 복구할 수 ģžˆė„ė” ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 11,"pass": 8,"total": 37,"manual": 0}},"2.9.4": {"name": "딜그 ė° ģ ‘ģ†źø°ė” ꓀리","checks": {"macie_is_enabled": "PASS","elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","inspector2_is_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","ec2_ebs_public_snapshot": "PASS","eventbridge_bus_exposed": "PASS","rds_snapshots_encrypted": "FAIL","s3_bucket_public_access": null,"s3_bucket_kms_encryption": "FAIL","cloudtrail_insights_exist": null,"s3_bucket_public_list_acl": null,"s3_bucket_public_write_acl": null,"ec2_ebs_snapshots_encrypted": "FAIL","ec2_instance_managed_by_ssm": "FAIL","efs_not_publicly_accessible": "FAIL","guardduty_centrally_managed": "FAIL","rds_snapshots_public_access": "PASS","s3_bucket_default_encryption": "PASS","wafv2_webacl_logging_enabled": "FAIL","iam_securityaudit_role_created": null,"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","config_recorder_all_regions_enabled": null,"s3_access_point_public_access_block": "PASS","s3_bucket_level_public_access_block": "PASS","eventbridge_bus_cross_account_access": "FAIL","s3_bucket_policy_public_write_access": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"s3_account_level_public_access_blocks": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"apigatewayv2_api_access_logging_enabled": "FAIL","cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"s3_bucket_server_access_logging_enabled": "FAIL","cloudfront_distributions_logging_enabled": null,"documentdb_cluster_cloudwatch_log_export": null,"ec2_instance_detailed_monitoring_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_cross_account_sharing_disabled": null,"kafka_cluster_enhanced_monitoring_enabled": null,"acm_certificates_transparency_logs_enabled": "PASS","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","cloudwatch_log_metric_filter_policy_changes": null,"eks_control_plane_logging_all_types_enabled": null,"ec2_ebs_snapshot_account_block_public_access": null,"iam_inline_policy_no_full_access_to_cloudtrail": null,"trustedadvisor_premium_support_plan_subscribed": null,"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL","cloudwatch_log_metric_filter_sign_in_without_mfa": null,"directoryservice_directory_monitor_notifications": null,"eventbridge_schema_registry_cross_account_access": "FAIL","glue_etl_jobs_cloudwatch_logs_encryption_enabled": "FAIL","opensearch_service_domains_audit_logging_enabled": null,"directoryservice_directory_log_forwarding_enabled": null,"ec2_client_vpn_endpoint_connection_logging_enabled": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS","cloudwatch_log_metric_filter_authentication_failures": null,"opensearch_service_domains_cloudwatch_logging_enabled": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"route53_public_hosted_zones_cloudwatch_logging_enabled": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudtrail_multi_region_enabled_logging_management_events": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","glue_development_endpoints_cloudwatch_logs_encryption_enabled": null,"awslambda_function_invoke_api_operations_cloudtrail_logging_enabled": "PASS","cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.9.4 딜그 ė° ģ ‘ģ†źø°ė” ꓀리","Subdomain": "2.9. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ģš“ģ˜ź“€ė¦¬","AuditEvidence": ["ė”œź·øź“€ė¦¬ 절차","ė”œź·øźø°ė” ė‚“ģ—­","딜그 ģ €ģž„ģž„ģ¹˜ģ— ėŒ€ķ•œ ģ ‘ź·¼ķ†µģ œ ė‚“ģ—­","ź°œģøģ •ė³“ ģ ‘ģ†źø°ė” ė‚“ģ—­"],"AuditChecklist": ["ģ„œė²„, ģ‘ģš©ķ”„ė”œź·øėžØ, ė³“ģ•ˆģ‹œģŠ¤ķ…œ, ė„¤ķŠøģ›Œķ¬ģ‹œģŠ¤ķ…œ 등 ģ •ė³“ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ė”œź·øź“€ė¦¬ 절차넼 ģˆ˜ė¦½ķ•˜ź³  ģ“ģ— ė”°ė¼ ķ•„ģš”ķ•œ 딜그넼 ģƒģ„±ķ•˜ģ—¬ ė³“ź“€ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ė”œź·øźø°ė”ģ€ ģœ„Ā·ė³€ģ”° ė° ė„ė‚œ, ė¶„ģ‹¤ė˜ģ§€ ģ•Šė„ė” ģ•ˆģ „ķ•˜ź²Œ ė³“ź“€ķ•˜ź³  ė”œź·øźø°ė”ģ— ėŒ€ķ•œ ģ ‘ź·¼ź¶Œķ•œģ€ ģµœģ†Œķ™”ķ•˜ģ—¬ ė¶€ģ—¬ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ģ ‘ģ†źø°ė”ģ€ 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ģ¤€ģˆ˜ķ•  수 ģžˆė„ė” ķ•„ģš”ķ•œ ķ•­ėŖ©ģ„ 모두 ķ¬ķ•Øķ•˜ģ—¬ ģ¼ģ •źø°ź°„ ģ•ˆģ „ķ•˜ź²Œ ė³“ź“€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 딜그 źø°ė” ėŒ€ģƒ, 방법, 볓씓기간, 검토 주기, ė‹“ė‹¹ģž 등에 ėŒ€ķ•œ 세부 기준 ė° ģ ˆģ°Øź°€ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ė³“ģ•ˆ ģ“ė²¤ķŠø 딜그, ģ‘ģš©ķ”„ė”œź·øėžØ ė° ģ„œė¹„ģŠ¤ 딜그(ģœˆė„ģš° 2008 ģ„œė²„ ģ“ģƒ) 등 ģ¤‘ģš” ė”œź·øģ— ėŒ€ķ•œ ģµœėŒ€ 크기넼 ģ¶©ė¶„ķ•˜ź²Œ ģ„¤ģ •ķ•˜ģ§€ ģ•Šģ•„ ė‚“ė¶€ 기준에 ģ •ķ•œ źø°ź°„ ė™ģ•ˆ źø°ė”Ā·ė³“ź“€ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģ¤‘ģš” Linux/UNIX 계엓 ģ„œė²„ģ— ėŒ€ķ•œ 딜그 źø°ė”ģ„ ė³„ė„ė”œ ė°±ģ—…ķ•˜ź±°ė‚˜ ģ ģ ˆķžˆ ė³“ķ˜øķ•˜ģ§€ ģ•Šģ•„ ģ‚¬ģš©ģžģ˜ ėŖ…ė ¹ 실행 źø°ė” ė° ģ ‘ģ† ģ“ė „ ė“±ģ„ ģž„ģ˜ė”œ ģ‚­ģ œķ•  수 ģžˆėŠ” 경우","사딀 4 : ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— ģ ‘ģ†ķ•œ źø°ė”ģ„ ķ™•ģøķ•œ ź²°ź³¼ ģ ‘ģ†ģžģ˜ 계정, ģ ‘ģ† ģ¼ģ‹œ, ģ ‘ģ†ģž IPģ£¼ģ†Œ ģ •ė³“ėŠ” 남기고 ģžˆģœ¼ė‚˜, ģ²˜ė¦¬ķ•œ 정볓주첓 정볓 ė° ģˆ˜ķ–‰ģ—…ė¬“(씰회, 변경, ģ‚­ģ œ, ė‹¤ģš“ė”œė“œ 등)와 ź“€ė Øėœ 정볓넼 남기고 ģžˆģ§€ ģ•Šģ€ 경우","사딀 5 : 딜그 ģ„œė²„ģ˜ ģš©ėŸ‰ģ˜ ģ¶©ė¶„ķ•˜ģ§€ ģ•Šģ•„ģ„œ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ģ ‘ģ†źø°ė”ģ“ 2ź°œģ›” 밖에 남아 ģžˆģ§€ ģ•Šģ€ 경우","사딀 6 : ź°œģøģ •ė³“ģ²˜ė¦¬ģžź°€ 정볓주첓 10만 ėŖ…ģ˜ ź°œģøģ •ė³“ė„¼ ģ²˜ė¦¬ķ•˜ėŠ” ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ź°œģøģ •ė³“ģ·Øźø‰ģž ģ ‘ģ†źø°ė”ģ„ 1ė…„ź°„ė§Œ ė³“ź“€ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제8ģ”°(ģ ‘ģ†źø°ė”ģ˜ 볓꓀ ė° 점검)"]}],"description": "ģ„œė²„, ģ‘ģš©ķ”„ė”œź·øėžØ, ė³“ģ•ˆģ‹œģŠ¤ķ…œ, ė„¤ķŠøģ›Œķ¬ģ‹œģŠ¤ķ…œ 등 ģ •ė³“ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ģ‚¬ģš©ģž ģ ‘ģ†źø°ė”, ģ‹œģŠ¤ķ…œė”œź·ø, ź¶Œķ•œė¶€ģ—¬ ė‚“ģ—­ ė“±ģ˜ ė”œź·øģœ ķ˜•, 볓씓기간, 볓씓방법 ė“±ģ„ ģ •ķ•˜ź³  ģœ„Ā·ė³€ģ”°, ė„ė‚œ, ė¶„ģ‹¤ė˜ģ§€ ģ•Šė„ė” ģ•ˆģ „ķ•˜ź²Œ ė³“ģ”“Ā·ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 25,"pass": 15,"total": 81,"manual": 0}},"2.9.5": {"name": "딜그 ė° ģ ‘ģ†źø°ė” 점검","checks": {"cloudtrail_insights_exist": null,"inspector2_active_findings_exist": "FAIL","trustedadvisor_errors_and_warnings": null,"guardduty_no_high_severity_findings": "FAIL","accessanalyzer_enabled_without_findings": "FAIL","cloudtrail_threat_detection_enumeration": null,"cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_cross_account_sharing_disabled": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cognito_user_pool_client_prevent_user_existence_errors": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.9.5 딜그 ė° ģ ‘ģ†źø°ė” 점검","Subdomain": "2.9. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ģš“ģ˜ź“€ė¦¬","AuditEvidence": ["딜그 검토 ė° ėŖØė‹ˆķ„°ė§ 절차","딜그 검토 ė° ėŖØė‹ˆķ„°ė§ ź²°ź³¼(검토 ė‚“ģ—­, ė³“ź³ ģ„œ 등)","ź°œģøģ •ė³“ ģ ‘ģ†źø°ė” 점검 ė‚“ģ—­","ź°œģøģ •ė³“ ė‹¤ģš“ė”œė“œ ģ‹œ ģ‚¬ģœ  ķ™•ģø 기준 ė° ź²°ź³¼","ģ“ģƒģ§•ķ›„ 발견 ģ‹œ ėŒ€ģ‘ ģ¦ź±°ģžė£Œ"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ꓀련 오넘, ģ˜¤Ā·ė‚Øģš©(ė¹„ģøź°€ģ ‘ģ†, ź³¼ė‹¤ģ”°ķšŒ 등), ė¶€ģ •ķ–‰ģœ„ 등 ģ“ģƒģ§•ķ›„ė„¼ ģøģ§€ķ•  수 ģžˆė„ė” 딜그 검토 주기, ėŒ€ģƒ, 방법 ė“±ģ„ ķ¬ķ•Øķ•œ 딜그 검토 ė° ėŖØė‹ˆķ„°ė§ģ ˆģ°Øė„¼ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","딜그 검토 ė° ėŖØė‹ˆķ„°ė§ 결과넼 ģ±…ģž„ģžģ—ź²Œ ė³“ź³ ķ•˜ź³  ģ“ģƒģ§•ķ›„ 발견 ģ‹œ ģ ˆģ°Øģ— ė”°ė¼ ėŒ€ģ‘ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ģ ‘ģ†źø°ė”ģ€ ꓀련 ė²•ė ¹ģ—ģ„œ ģ •ķ•œ 주기에 ė”°ė¼ ģ •źø°ģ ģœ¼ė”œ ģ ź²€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ¤‘ģš” 정볓넼 ģ²˜ė¦¬ķ•˜ź³  ģžˆėŠ” ģ •ė³“ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ģ“ģƒģ ‘ģ†(ķœ“ģ¼ 새벽 ģ ‘ģ†, 우회경딜 ģ ‘ģ† 등) ė˜ėŠ” ģ“ģƒķ–‰ģœ„(ėŒ€ėŸ‰ ė°ģ“ķ„° 씰회 ė˜ėŠ” ģ†ŒėŸ‰ ė°ģ“ķ„°ģ˜ ģ§€ģ†ģ Ā·ģ—°ģ†ģ  씰회 등)에 ėŒ€ķ•œ ėŖØė‹ˆķ„°ė§ ė° ź²½ź³ Ā·ģ•Œė¦¼ ģ •ģ±…(기준)ģ“ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ė‚“ė¶€ 지침 ė˜ėŠ” ģ‹œģŠ¤ķ…œ 등에 ģ ‘ź·¼ ė° ģ‚¬ģš©ģ— ėŒ€ķ•œ ģ£¼źø°ģ ģø ģ ź²€Ā·ėŖØė‹ˆķ„°ė§ źø°ģ¤€ģ„ ė§ˆė Øķ•˜ź³  ģžˆģœ¼ė‚˜ ģ‹¤ģ œ ģ“ģƒģ ‘ģ† ė° ģ“ģƒķ–‰ģœ„ģ— ėŒ€ķ•œ 검토 ė‚“ģ—­ģ“ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ź°œģøģ •ė³“ģ²˜ė¦¬ģžź°€ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ģ ‘ģ†źø°ė” 점검 주기넼 ė¶„źø° 1회딜 ģ •ķ•˜ź³  ģžˆėŠ” 경우","사딀 4 : ź°œģøģ •ė³“ģ²˜ė¦¬ģžģ˜ ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ—ėŠ” 1,000ėŖ… ģ“ģƒģ˜ 정볓주첓에 ėŒ€ķ•œ ź°œģøģ •ė³“ė„¼ ė‹¤ģš“ė”œė“œķ•œ ź²½ģš°ģ—ėŠ” ģ‚¬ģœ ė„¼ ķ™•ģøķ•˜ė„ė” źø°ģ¤€ģ“ ģ±…ģ •ė˜ģ–“ ģžˆėŠ” ģƒķƒœģ—ģ„œ 1,000걓 ģ“ģƒģ˜ ź°œģøģ •ė³“ ė‹¤ģš“ė”œė“œź°€ ė°œģƒķ•˜ģ˜€ģœ¼ė‚˜ ź·ø ģ‚¬ģœ ė„¼ ķ™•ģøķ•˜ģ§€ ģ•Šź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제8ģ”°(ģ ‘ģ†źø°ė”ģ˜ 볓꓀ ė° 점검)"]}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ •ģƒģ ģø ģ‚¬ģš©ģ„ ė³“ģž„ķ•˜ź³  ģ‚¬ģš©ģž ģ˜¤Ā·ė‚Øģš©(ė¹„ģøź°€ģ ‘ģ†, ź³¼ė‹¤ģ”°ķšŒ 등)ģ„ ė°©ģ§€ķ•˜źø° ģœ„ķ•˜ģ—¬ ģ ‘ź·¼ ė° ģ‚¬ģš©ģ— ėŒ€ķ•œ 딜그 ź²€ķ† źø°ģ¤€ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ 주기적으딜 ģ ź²€ķ•˜ė©°, 문제 ė°œģƒ ģ‹œ ģ‚¬ķ›„ģ”°ģ¹˜ė„¼ ģ ģ‹œģ— ģˆ˜ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 6,"pass": 0,"total": 26,"manual": 0}},"2.9.6": {"name": "ģ‹œź°„ ė™źø°ķ™”","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.9.6 ģ‹œź°„ ė™źø°ķ™”","Subdomain": "2.9. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ģš“ģ˜ź“€ė¦¬","AuditEvidence": ["ģ‹œź°„ ė™źø°ķ™” 설정","ģ£¼ģš” ģ‹œģŠ¤ķ…œ ģ‹œź°„ ė™źø°ķ™” ģ¦ź±°ģžė£Œ"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ‹œź°„ģ„ ķ‘œģ¤€ģ‹œź°„ģœ¼ė”œ ė™źø°ķ™”ķ•˜ź³  ģžˆėŠ”ź°€?","ģ‹œź°„ ė™źø°ķ™”ź°€ ģ •ģƒģ ģœ¼ė”œ ģ“ė£Øģ–“ģ§€ź³  ģžˆėŠ”ģ§€ 주기적으딜 ģ ź²€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ¼ė¶€ ģ¤‘ģš” ģ‹œģŠ¤ķ…œ(ė³“ģ•ˆģ‹œģŠ¤ķ…œ, CCTV 등)ģ˜ ģ‹œź°ģ“ ķ‘œģ¤€ģ‹œģ™€ ė™źø°ķ™”ė˜ģ–“ ģžˆģ§€ ģ•Šģœ¼ė©°, ꓀련 ė™źø°ķ™” 여부에 ėŒ€ķ•œ 주기적 ģ ź²€ģ“ ģ“ķ–‰ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ė‚“ė¶€ NTP ģ„œė²„ģ™€ ģ‹œź°ģ„ ė™źø°ķ™”ķ•˜ė„ė” ģ„¤ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜ ģ¼ė¶€ ģ‹œģŠ¤ķ…œģ˜ ģ‹œź°ģ“ ė™źø°ķ™”ė˜ģ§€ ģ•Šź³  ģžˆź³ , ģ“ģ— ėŒ€ķ•œ ģ›ģøė¶„ģ„ ė° ėŒ€ģ‘ģ“ ģ“ė£Øģ–“ģ§€ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "딜그 ė° ģ ‘ģ†źø°ė”ģ˜ ģ •ķ™•ģ„±ģ„ ė³“ģž„ķ•˜ź³  신뢰성 ģžˆėŠ” ė”œź·øė¶„ģ„ģ„ ģœ„ķ•˜ģ—¬ ꓀련 ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ‹œź°ģ„ ķ‘œģ¤€ģ‹œź°ģœ¼ė”œ ė™źø°ķ™”ķ•˜ź³  주기적으딜 ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.9.7": {"name": "ģ •ė³“ģžģ‚°ģ˜ ģž¬ģ‚¬ģš© ė° ķźø°","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.9.7 ģ •ė³“ģžģ‚°ģ˜ ģž¬ģ‚¬ģš© ė° ķźø°","Subdomain": "2.9. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ģš“ģ˜ź“€ė¦¬","AuditEvidence": ["ģ •ė³“ģžģ‚° ķźø° ė° ģž¬ģ‚¬ģš© 절차","ģ €ģž„ė§¤ģ²“ ź“€ė¦¬ėŒ€ģž„","ģ •ė³“ģžģ‚° ė° ģ €ģž„ė§¤ģ²“ ķźø° ģ¦ź±°ģžė£Œ","ģ •ė³“ģžģ‚° ė° ģ €ģž„ė§¤ģ²“ ķźø° ꓀련 ģœ„ķƒź³„ģ•½ģ„œ"],"AuditChecklist": ["ģ •ė³“ģžģ‚°ģ˜ ģ•ˆģ „ķ•œ ģž¬ģ‚¬ģš© ė° ķźø°ģ— ėŒ€ķ•œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģžģ‚° ė° ģ €ģž„ė§¤ģ²“ė„¼ ģž¬ģ‚¬ģš© ė° ķźø°ķ•˜ėŠ” 경우 ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ė„¼ ė³µźµ¬ė˜ģ§€ ģ•ŠėŠ” ė°©ė²•ģœ¼ė”œ ģ²˜ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģžģ²“ģ ģœ¼ė”œ ģ •ė³“ģžģ‚° ė° ģ €ģž„ė§¤ģ²“ė„¼ ķźø°ķ•  경우 ź“€ė¦¬ėŒ€ģž„ģ„ ķ†µķ•˜ģ—¬ ķźø°ģ“ė „ģ„ 남기고 ķźø°ķ™•ģø ģ¦ģ ģ„ ķ•Øź»˜ ė³“ź“€ķ•˜ź³  ģžˆėŠ”ź°€?","외부업첓넼 ķ†µķ•˜ģ—¬ ģ •ė³“ģžģ‚° ė° ģ €ģž„ė§¤ģ²“ė„¼ ķźø°ķ•  경우 ķźø° 절차넼 ź³„ģ•½ģ„œģ— ėŖ…ģ‹œķ•˜ź³  ģ™„ģ „ķžˆ ķźø°ķ•˜ģ˜€ėŠ”ģ§€ 여부넼 ķ™•ģøķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œ, PC 등 ģœ ģ§€ė³“ģˆ˜, 수리 ź³¼ģ •ģ—ģ„œ ģ €ģž„ė§¤ģ²“ 교첓, 복구 등 ė°œģƒ ģ‹œ ģ €ģž„ė§¤ģ²“ ė‚“ 정볓넼 ė³“ķ˜øķ•˜źø° ģœ„ķ•œ ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ģ·Øźø‰ģž PC넼 ģž¬ģ‚¬ģš©ķ•  경우 ė°ģ“ķ„° ģ‚­ģ œķ”„ė”œź·øėžØģ„ ģ“ģš©ķ•˜ģ—¬ ģ™„ģ „ģ‚­ģ œ ķ•˜ė„ė” ģ •ģ±… ė° ģ ˆģ°Øź°€ ģˆ˜ė¦½ė˜ģ–“ ģžˆģœ¼ė‚˜, ģ‹¤ģ œė”œėŠ” ģ™„ģ „ģ‚­ģ œ 씰치 ģ—†ģ“ ģž¬ģ‚¬ģš©ķ•˜ź±°ė‚˜ źø°ė³ø ķ¬ė§·ė§Œ ķ•˜ź³  ģž¬ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 등 ꓀련 ģ ˆģ°Øź°€ ģ“ķ–‰ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : 외부업첓넼 ķ†µķ•˜ģ—¬ ģ €ģž„ė§¤ģ²“ė„¼ ķźø°ķ•˜ź³  ģžˆģœ¼ė‚˜, 계약 ė‚“ģš©ģƒ ģ•ˆģ „ķ•œ ķźø° 절차 ė° ė³“ķ˜øėŒ€ģ±…ģ— ėŒ€ķ•œ ė‚“ģš©ģ“ ėˆ„ė½ė˜ģ–“ ģžˆź³  ķźø° ģ“ķ–‰ ģ¦ź±°ģžė£Œ ķ™•ģø ė° 실사 ė“±ģ˜ ź“€ė¦¬Ā·ź°ė…ģ“ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우","사딀 3 : ķźø°ėœ HDDģ˜ ģ¼ė Øė²ˆķ˜øź°€ ģ•„ė‹Œ ģ‹œģŠ¤ķ…œėŖ…ģ„ źø°ė”ķ•˜ź±°ė‚˜ ķźø° ėŒ€ģž„ģ„ ģž‘ģ„±ķ•˜ģ§€ ģ•Šģ•„ ķźø° ģ“ė „ ė° 추적할 수 ģžˆėŠ” ģ¦ź±°ģžė£Œė„¼ ķ™•ģøķ•  수 ģ—†ėŠ” 경우","사딀 4 : ķšŒģˆ˜ķ•œ ķźø° ėŒ€ģƒ ķ•˜ė“œė””ģŠ¤ķ¬ź°€ ģ™„ģ „ģ‚­ģ œ ė˜ģ§€ ģ•Šģ€ 상태딜 ģž źøˆģž„ģ¹˜ź°€ ė˜ģ§€ ģ•Šģ€ ģž„ģ†Œģ— 방치되고 ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제21ģ”°(ź°œģøģ •ė³“ģ˜ 파기)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제13ģ”°(ź°œģøģ •ė³“ģ˜ 파기)"]}],"description": "ģ •ė³“ģžģ‚°ģ˜ ģž¬ģ‚¬ģš©ź³¼ ķźø° ź³¼ģ •ģ—ģ„œ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ź°€ ė³µźµ¬Ā·ģž¬ģƒė˜ģ§€ ģ•Šė„ė” ģ•ˆģ „ķ•œ ģž¬ģ‚¬ģš© ė° ķźø° 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.1": {"name": "ź°œģøģ •ė³“ ģˆ˜ģ§‘Ā·ģ“ģš©","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.1.1 ź°œģøģ •ė³“ ģˆ˜ģ§‘Ā·ģ“ģš©","Subdomain": "3.1. ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ‹œ 볓호씰치","AuditEvidence": ["ģ˜Øė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ķ™ˆķŽ˜ģ“ģ§€ ķšŒģ›ź°€ģž… 화멓, ėŖØė°”ģ¼ģ•± ķšŒģ›ź°€ģž… 화멓, ģ“ė²¤ķŠø ģ°øģ—¬ 등)","ģ˜¤ķ”„ė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ķšŒģ›ź°€ģž…ģ‹ ģ²­ģ„œ 등)","ź°œģøģ •ė³“ ģˆ˜ģ§‘ ė™ģ˜ źø°ė”(ķšŒģ› ė°ģ“ķ„°ė² ģ“ģŠ¤ 등)","ė²•ģ •ėŒ€ė¦¬ģø ė™ģ˜ źø°ė”","ź°œģøģ •ė³“ 처리방침"],"AuditChecklist": ["ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ėŠ” 경우 정볓주첓 ė™ģ˜, ė²•ė ¹ģƒ ģ˜ė¬“ģ¤€ģˆ˜, 계약 ģ²“ź²°Ā·ģ“ķ–‰ 등 적법 ģš”ź±“ģ— ė”°ė¼ ģˆ˜ģ§‘ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ź°œģøģ •ė³“ ģˆ˜ģ§‘ ė™ģ˜ė„¼ ė°›ėŠ” 경우 ė™ģ˜ė°©ė²• ė° ģ‹œģ ģ€ ģ ģ ˆķ•˜ź²Œ ė˜ģ–“ ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ź°œģøģ •ė³“ ģˆ˜ģ§‘ ė™ģ˜ė„¼ ė°›ėŠ” 경우 ꓀련 ė‚“ģš©ģ„ ėŖ…ķ™•ķ•˜ź²Œ ź³ ģ§€ķ•˜ź³  ė²•ė ¹ģ—ģ„œ ģ •ķ•œ ģ¤‘ģš”ķ•œ ė‚“ģš©ģ— ėŒ€ķ•“ ģ•Œģ•„ė³“źø° ģ‰½ź²Œ ķ‘œģ‹œķ•˜ź³  ģžˆėŠ”ź°€?","만 14세 미만 ģ•„ė™ģ˜ ź°œģøģ •ė³“ģ— ėŒ€ķ•“ ģˆ˜ģ§‘Ā·ģ“ģš©Ā·ģ œź³µ ė“±ģ˜ ė™ģ˜ė„¼ ė°›ėŠ” 경우 ė²•ģ •ėŒ€ė¦¬ģøģ—ź²Œ ķ•„ģš”ķ•œ 사항에 ėŒ€ķ•˜ģ—¬ ź³ ģ§€ķ•˜ź³  ė™ģ˜ė„¼ 받고 ģžˆėŠ”ź°€?","ė²•ģ •ėŒ€ė¦¬ģøģ˜ ė™ģ˜ė„¼ 받기 ģœ„ķ•˜ģ—¬ ķ•„ģš”ķ•œ ģµœģ†Œķ•œģ˜ ź°œģøģ •ė³“ė§Œģ„ ģˆ˜ģ§‘ķ•˜ź³  ģžˆģœ¼ė©°, ė²•ģ •ėŒ€ė¦¬ģøģ“ ģžź²© ģš”ź±“ģ„ 갖추고 ģžˆėŠ”ģ§€ ķ™•ģøķ•˜ėŠ” ģ ˆģ°Øģ™€ ė°©ė²•ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","만 14세 ėÆøė§Œģ˜ ģ•„ė™ģ—ź²Œ ź°œģøģ •ė³“ ģ²˜ė¦¬ģ™€ ź“€ė Øķ•œ 사항 ė“±ģ˜ ź³ ģ§€ ģ‹œ ģ“ķ•“ķ•˜źø° ģ‰¬ģš“ ģ–‘ģ‹ź³¼ ėŖ…ķ™•ķ•˜ź³  ģ•Œźø° ģ‰¬ģš“ ģ–øģ–“ė”œ ķ‘œķ˜„ķ•˜ź³  ģžˆėŠ”ź°€?","정볓주첓 ė° ė²•ģ •ėŒ€ė¦¬ģøģ—ź²Œ ė™ģ˜ė„¼ ė°›ģ€ źø°ė”ģ„ ė³“ź“€ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ ģ—†ģ“ ģ²˜ė¦¬ķ•  수 ģžˆėŠ” ź°œģøģ •ė³“ģ— ėŒ€ķ•“ģ„œėŠ” ź·ø ķ•­ėŖ©ź³¼ ģ²˜ė¦¬ģ˜ 법적 근거넼 ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ė„¼ 받아 ģ²˜ė¦¬ķ•˜ėŠ” ź°œģøģ •ė³“ģ™€ źµ¬ė¶„ķ•˜ģ—¬ ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ—ź³µź°œķ•˜ź±°ė‚˜ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ ģ—†ģ“ ź°œģøģ •ė³“ģ˜ ģ¶”ź°€ģ ģø ģ“ģš© ģ‹œ ė‹¹ģ“ˆ ģˆ˜ģ§‘ ėŖ©ģ ź³¼ģ˜ ꓀련성, 예츔 ź°€ėŠ„ģ„±, ģ“ģµ 침핓 여부, ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ ė“±ģ˜ 고려사항에 ėŒ€ķ•œ ķŒė‹Øźø°ģ¤€ģ„ 수립 ė° ģ“ķ–‰ķ•˜ź³ , ģ¶”ź°€ģ ģø ģ“ģš©ģ“ ģ§€ģ†ģ ģœ¼ė”œ ė°œģƒķ•˜ėŠ” 경우 고려사항에 ėŒ€ķ•œ ķŒė‹Øźø°ģ¤€ģ„ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź³µź°œķ•˜ź³  ģ“ė„¼ ģ ź²€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ ė³“ķ˜øė²•ģ„ ģ ģš©ė°›ėŠ” ź°œģøģ •ė³“ģ²˜ė¦¬ģžź°€ ź°œģøģ •ė³“ ģˆ˜ģ§‘ ė™ģ˜ ģ‹œ ź³ ģ§€ 사항에 Ź»ė™ģ˜ ź±°ė¶€ 권리 ė° ė™ģ˜ 거부에 따넸 ė¶ˆģ“ģµ ė‚“ģš©Ź¼ģ„ ėˆ„ė½ķ•œ 경우","사딀 2 : ź°œģøģ •ė³“ ģˆ˜ģ§‘ ė™ģ˜ ģ‹œ ģˆ˜ģ§‘ķ•˜ėŠ” ź°œģøģ •ė³“ ķ•­ėŖ©ģ„ 구첓적으딜 ėŖ…ģ‹œķ•˜ģ§€ ģ•Šź³  Ź»~ 등ʼ과 ź°™ģ“ ķ¬ź“„ģ ģœ¼ė”œ ģ•ˆė‚“ķ•˜ėŠ” 경우","사딀 3 : 쇼핑몰 ķ™ˆķŽ˜ģ“ģ§€ģ—ģ„œ ķšŒģ›ź°€ģž… ģ‹œ ķšŒģ›ź°€ģž…ģ— ķ•„ģš”ķ•œ ź°œģøģ •ė³“ 외에 추후 ė¬¼ķ’ˆ 구매 ģ‹œ ķ•„ģš”ķ•œ ź²°ģ œĀ·ė°°ģ†” 정볓넼 미리 ķ•„ģˆ˜ ķ•­ėŖ©ģœ¼ė”œ ģˆ˜ģ§‘ķ•˜ėŠ” 경우","사딀 4 : Q&A, ź²Œģ‹œķŒģ„ ķ†µķ•˜ģ—¬ ė¹„ķšŒģ›ģ˜ ź°œģøģ •ė³“(ģ“ė¦„, ģ“ė©”ģ¼, ķœ“ėŒ€ķ°ė²ˆķ˜ø)넼 ģˆ˜ģ§‘ķ•˜ė©“ģ„œ ź°œģøģ •ė³“ ģˆ˜ģ§‘ ė™ģ˜ 절차넼 ź±°ģ¹˜ģ§€ ģ•Šģ€ 경우","사딀 5 : 만 14세 미만 ģ•„ė™ģ˜ ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ė©“ģ„œ ė²•ģ •ėŒ€ė¦¬ģøģ˜ ė™ģ˜ė„¼ 받지 ģ•Šģ€ 경우","사딀 6 : 만 14세 미만 ģ•„ė™ģ— ėŒ€ķ•˜ģ—¬ ģ„œė¹„ģŠ¤ė„¼ ģ œź³µķ•˜ź³  ģžˆģ§€ ģ•Šģ§€ė§Œ, ķšŒģ›ź°€ģž… ė‹Øź³„ģ—ģ„œ ģž…ė „ė°›ėŠ” ģƒė…„ģ›”ģ¼ģ„ ķ†µķ•˜ģ—¬ ė‚˜ģ“ 첓크넼 ķ•˜ģ§€ ģ•Šģ•„ ė²•ģ •ėŒ€ė¦¬ģø ė™ģ˜ ģ—†ģ“ ź°€ģž…ėœ 만 14세 미만 ģ•„ė™ ķšŒģ›ģ“ ģ”“ģž¬ķ•œ 경우","사딀 7 : ė²•ģ •ėŒ€ė¦¬ģøģ˜ ģ§„ģœ„ 여부넼 ķ™•ģøķ•˜ėŠ” ģ ˆģ°Øź°€ ėÆøķ”ķ•˜ģ—¬ ėÆøģ„±ė…„ģž 등 ģ•„ė™ģ˜ ė²•ģ •ėŒ€ė¦¬ģøģœ¼ė”œ 볓기 ģ–“ė ¤ģš“ė°ė„ ė²•ģ •ėŒ€ė¦¬ģø ė™ģ˜ź°€ ź°€ėŠ„ķ•œ 경우","사딀 8 : 만 14세 미만 ģ•„ė™ģœ¼ė”œė¶€ķ„° ė²•ģ •ėŒ€ė¦¬ģø ė™ģ˜ė„¼ ė°›ėŠ” 목적으딜 ė²•ģ •ėŒ€ė¦¬ģøģ˜ ź°œģøģ •ė³“(ģ“ė¦„, ķœ“ėŒ€ķ°ė²ˆķ˜ø)넼 ģˆ˜ģ§‘ķ•œ ģ“ķ›„ ė²•ģ •ėŒ€ė¦¬ģøģ˜ ė™ģ˜ź°€ ģž„źø°ź°„ ķ™•ģøė˜ģ§€ ģ•Šģ•˜ģŒģ—ė„ ģ“ė„¼ ķŒŒźø°ķ•˜ģ§€ ģ•Šź³  ź³„ģ† ė³“ģœ ķ•˜ź³  ģžˆėŠ” 경우","사딀 9 : ė²•ģ •ėŒ€ė¦¬ģø ė™ģ˜ģ— ź·¼ź±°ķ•˜ģ—¬ 만 14세 미만 ģ•„ė™ģ˜ ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ģ˜€ģœ¼ė‚˜, ꓀련 źø°ė”ģ„ ė³“ģ”“ķ•˜ģ§€ ģ•Šģ•„ ė²•ģ •ėŒ€ė¦¬ģø ė™ģ˜ģ™€ ź“€ė Øėœ 사항(ė²•ģ •ėŒ€ė¦¬ģø ģ“ė¦„, ė™ģ˜ ģ¼ģ‹œ 등)ģ„ ķ™•ģøķ•  수 ģ—†ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제15ģ”°(ź°œģøģ •ė³“ģ˜ ģˆ˜ģ§‘Ā·ģ“ģš©), 제22ģ”°(ė™ģ˜ė„¼ ė°›ėŠ” 방법), 제22ģ”°ģ˜2(ģ•„ė™ģ˜ ź°œģøģ •ė³“ 볓호)","ź°œģøģ •ė³“ 처리 방법에 ź“€ķ•œ ź³ ģ‹œ"]}],"description": "ź°œģøģ •ė³“ėŠ” ģ ė²•ķ•˜ź³  ģ •ė‹¹ķ•˜ź²Œ ģˆ˜ģ§‘Ā·ģ“ģš©ķ•˜ģ—¬ģ•¼ ķ•˜ė©°, ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ė„¼ 근거딜 ģˆ˜ģ§‘ķ•˜ėŠ” ź²½ģš°ģ—ėŠ” ģ ė²•ķ•œ ė°©ė²•ģœ¼ė”œ ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ė„¼ 받아야 ķ•œė‹¤. ė˜ķ•œ 만 14세 미만 ģ•„ė™ģ˜ ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ėŠ” ź²½ģš°ģ—ėŠ” ź·ø ė²•ģ •ėŒ€ė¦¬ģøģ˜ ė™ģ˜ė„¼ 받아야 ķ•˜ė©° ė²•ģ •ėŒ€ė¦¬ģøģ“ ė™ģ˜ķ•˜ģ˜€ėŠ”ģ§€ė„¼ ķ™•ģøķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.2": {"name": "ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ œķ•œ","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.1.2 ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ œķ•œ","Subdomain": "3.1. ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ‹œ 볓호씰치","AuditEvidence": ["ģ˜Øė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ķ™ˆķŽ˜ģ“ģ§€ ķšŒģ›ź°€ģž… 화멓, ģ“ė²¤ķŠø ģ°øģ—¬ 화멓 등)","ģ˜¤ķ”„ė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(멤버십 ź°€ģž…ģ‹ ģ²­ģ„œ 등)","ź°œģøģ •ė³“ 처리방침"],"AuditChecklist": ["ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ėŠ” 경우 ź·ø 목적에 ķ•„ģš”ķ•œ ė²”ģœ„ģ—ģ„œ ģµœģ†Œķ•œģ˜ ģ •ė³“ė§Œģ„ ģˆ˜ģ§‘ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ė„¼ 받아 ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ėŠ” 경우 ķ•„ģš”ķ•œ ģµœģ†Œķ•œģ˜ 정볓 ģ™øģ˜ ź°œģøģ •ė³“ģˆ˜ģ§‘ģ—ėŠ” ė™ģ˜ķ•˜ģ§€ ģ•Šģ„ 수 ģžˆė‹¤ėŠ” ģ‚¬ģ‹¤ģ„ 구첓적으딜 ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?","정볓주첓가 ģˆ˜ģ§‘ 목적에 ķ•„ģš”ķ•œ ģµœģ†Œķ•œģ˜ 정볓 ģ“ģ™øģ˜ ź°œģøģ •ė³“ ģˆ˜ģ§‘ģ— ė™ģ˜ķ•˜ģ§€ģ•ŠėŠ”ė‹¤ėŠ” ģ“ģœ ė”œ ģ„œė¹„ģŠ¤ ė˜ėŠ” ģž¬ķ™”ģ˜ ģ œź³µģ„ ź±°ė¶€ķ•˜ģ§€ ģ•Šė„ė” ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź³„ģ•½ģ˜ 첓결 ė° ģ“ķ–‰ģ„ 근거딜 정볓주첓 ė™ģ˜ ģ—†ģ“ ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ė©“ģ„œ ź³„ģ•½ģ˜ 첓결 ė° ģ“ķ–‰ģ„ ģœ„ķ•“ ė°˜ė“œģ‹œ ķ•„ģš”ķ•˜ģ§€ ģ•Šģ€ ź°œģøģ •ė³“ ķ•­ėŖ©ź¹Œģ§€ ź³¼ė„ķ•˜ź²Œ ģˆ˜ģ§‘ķ•˜ėŠ” 경우","사딀 2 : ģ •ė³“ģ£¼ģ²“ė”œė¶€ķ„° ģ„ ķƒģ‚¬ķ•­ģ— ėŒ€ķ•œ ė™ģ˜ė„¼ ė°›ģœ¼ė©“ģ„œ 핓당 ź°œģøģ •ė³“ ģˆ˜ģ§‘ģ—ėŠ” ė™ģ˜ķ•˜ģ§€ ģ•„ė‹ˆķ•  수 ģžˆė‹¤ėŠ” ģ‚¬ģ‹¤ģ„ 구첓적으딜 ģ•Œė¦¬ģ§€ ģ•Šģ€ 경우","사딀 3 : ķšŒģ›ź°€ģž… ģ–‘ģ‹ģ—ģ„œ ķ•„ģˆ˜ģ™€ ģ„ ķƒ 정볓넼 źµ¬ė¶„ķ•˜ģ—¬ ė³„ė„ ė™ģ˜ė„¼ ė°›ė„ė” ė˜ģ–“ ģžˆģ—ˆģœ¼ė‚˜, ģ„ ķƒģ •ė³“ģ— ėŒ€ķ•˜ģ—¬ ė™ģ˜ķ•˜ģ§€ ģ•Šģ•„ė„ ķšŒģ›ź°€ģž…ģ“ ź°€ėŠ„ķ•Øģ„ 정볓주첓가 ģøģ§€ķ•  수 ģžˆė„ė” 구첓적으딜 ģ•Œė¦¬ģ§€ ģ•Šģ€ 경우(ź°œģøģ •ė³“ ģž…ė „ ģ–‘ģ‹ģ— ź°œģøģ •ė³“ ķ•­ėŖ©ė³„ė”œ ķ•„ģˆ˜, ģ„ ķƒ 여부가 ķ‘œģ‹œė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우 등)","사딀 4 : ķ™ˆķŽ˜ģ“ģ§€ ķšŒģ›ź°€ģž… ķ™”ė©“ģ—ģ„œ ģ„ ķƒģ‚¬ķ•­ģ— ėŒ€ķ•˜ģ—¬ ė™ģ˜ķ•˜ģ§€ ģ•Šź±°ė‚˜ ģ„ ķƒģ •ė³“ė„¼ ģž…ė „ķ•˜ģ§€ ģ•Šģœ¼ė©“ ė‹¤ģŒ ė‹Øź³„ė”œ ė„˜ģ–“ź°€ģ§€ ģ•Šź±°ė‚˜ ķšŒģ›ź°€ģž…ģ“ ģ°Øė‹Øė˜ėŠ” 경우","사딀 5 : ģ±„ģš© 계약 ģ‹œ ģ±„ģš© ģ˜ˆģ • 직묓와 직접 ź“€ė Øģ“ ģ—†ėŠ” 가씱사항 등 ź³¼ė„ķ•œ ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제16ģ”°(ź°œģøģ •ė³“ģ˜ ģˆ˜ģ§‘ģ œķ•œ), 제22ģ”°(ė™ģ˜ė„¼ ė°›ėŠ” 방법)"]}],"description": "ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ėŠ” 경우 처리 목적에 ķ•„ģš”ķ•œ ģµœģ†Œķ•œģ˜ ź°œģøģ •ė³“ė§Œģ„ ģˆ˜ģ§‘ķ•˜ģ—¬ģ•¼ ķ•˜ė©°, 정볓주첓가 ģ„ ķƒģ ģœ¼ė”œ ė™ģ˜ķ•  수 ģžˆėŠ” 사항 등에 ė™ģ˜ķ•˜ģ§€ ģ•„ė‹ˆķ•œė‹¤ėŠ” ģ“ģœ ė”œ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģž¬ķ™” ė˜ėŠ” ģ„œė¹„ģŠ¤ģ˜ ģ œź³µģ„ ź±°ė¶€ķ•˜ģ§€ ģ•Šģ•„ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.3": {"name": "ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø 처리 ģ œķ•œ","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.1.3 ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø 처리 ģ œķ•œ","Subdomain": "3.1. ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ķ™ˆķŽ˜ģ“ģ§€ ķšŒģ›ź°€ģž… 화멓, ģ“ė²¤ķŠø ģ°øģ—¬, 멤버십 ź°€ģž…ģ‹ ģ²­ģ„œ 등)","ģ˜Øė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ė³øģøķ™•ģø 등 ėŒ€ģ²“ź°€ģž…ģˆ˜ė‹Ø 제공 화멓)","ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øė„¼ ģ²˜ė¦¬ķ•˜ėŠ” 경우 ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø 처리 근거 ģ¦ź±°ģžė£Œ","ź°œģøģ •ė³“ 처리방침"],"AuditChecklist": ["ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øėŠ” ėŖ…ķ™•ķ•œ 법적 근거가 ģžˆėŠ” ź²½ģš°ģ—ė§Œ ģ²˜ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øģ˜ ģˆ˜ģ§‘ 근거가 ė˜ėŠ” ė²•ģ”°ķ•­ģ„ 구첓적으딜 ģ‹ė³„ķ•˜ź³  ģžˆėŠ”ź°€?","법적 근거에 ė”°ė¼ ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øė„¼ ģ²˜ė¦¬ķ•˜ėŠ” ź²½ģš°ģ—ė„ 정볓주첓가 ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ė„¼ ķ†µķ•˜ģ—¬ ķšŒģ›ģœ¼ė”œ ź°€ģž…ķ•˜ėŠ” ė‹Øź³„ģ—ģ„œėŠ” ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øė„¼ ģ‚¬ģš©ķ•˜ģ§€ ģ•„ė‹ˆķ•˜ź³ ė„ ķšŒģ›ģœ¼ė”œ ź°€ģž…ķ•  수 ģžˆėŠ” ė°©ė²•ģ„ ģ œź³µķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķ™ˆķŽ˜ģ“ģ§€ ź°€ģž…ź³¼ ź“€ė Øķ•˜ģ—¬ ģ‹¤ėŖ…ķ™•ģø 등 ė‹Øģˆœ ķšŒģ›ź“€ė¦¬ ėŖ©ģ ģ„ ģœ„ķ•˜ģ—¬ ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ģ— ź·¼ź±°ķ•˜ģ—¬ ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øė„¼ ģˆ˜ģ§‘ķ•œ 경우","사딀 2 : ģ •ė³“ģ£¼ģ²“ģ˜ ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øė„¼ ģ‹œķ–‰ź·œģ¹™ģ“ė‚˜ ģ§€ė°©ģžģ¹˜ė‹Øģ²“ģ˜ 씰딀에 ź·¼ź±°ķ•˜ģ—¬ ģˆ˜ģ§‘ķ•œ 경우","사딀 3 : ė¹„ė°€ė²ˆķ˜ø 분실 ģ‹œ ė³øģøķ™•ģø ė“±ģ˜ 목적으딜 ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø ė’¤ 6ģžė¦¬ė„¼ ģˆ˜ģ§‘ķ•˜ģ§€ė§Œ, ź“€ė Øėœ 법적 근거가 ģ—†ėŠ” 경우","사딀 4 : ģ±„ģš©ģ „ķ˜• ģ§„ķ–‰ė‹Øź³„ģ—ģ„œ 법적 근거 ģ—†ģ“ ģž…ģ‚¬ģ§€ģ›ģžģ˜ ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øė„¼ ģˆ˜ģ§‘ķ•œ 경우","사딀 5 : ģ½œģ„¼ķ„°ģ— ģƒķ’ˆ, ģ„œė¹„ģŠ¤ ꓀련 ė¬øģ˜ ģ‹œ ė³øģøķ™•ģøģ„ ģœ„ķ•˜ģ—¬ ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øė„¼ ģˆ˜ģ§‘ķ•œ 경우","사딀 6 : ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø ģˆ˜ģ§‘ģ˜ 법적 근거가 ģžˆė‹¤ėŠ” ģ‚¬ģœ ė”œ ķ™ˆķŽ˜ģ“ģ§€ ķšŒģ›ź°€ģž… ė‹Øź³„ģ—ģ„œ ėŒ€ģ²“ź°€ģž…ģˆ˜ė‹Øģ„ ģ œź³µķ•˜ģ§€ ģ•Šź³  ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øė„¼ ģž…ė „ė°›ėŠ” ė³øģøķ™•ģø ė° ķšŒģ›ź°€ģž… ė°©ė²•ė§Œģ„ ģ œź³µķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제24ģ”°ģ˜2(ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø ģ²˜ė¦¬ģ˜ ģ œķ•œ)","ģ •ė³“ķ†µģ‹ ė§ė²• 제23ģ”°ģ˜2(ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øģ˜ ģ‚¬ģš© ģ œķ•œ)"]}],"description": "ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øėŠ” 법적 근거가 ģžˆėŠ” 경우넼 ģ œģ™øķ•˜ź³ ėŠ” ģˆ˜ģ§‘Ā·ģ“ģš© 등 ģ²˜ė¦¬ķ•  수 ģ—†ģœ¼ė©°, ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øģ˜ ģ²˜ė¦¬ź°€ ķ—ˆģš©ėœ ź²½ģš°ė¼ ķ•˜ė”ė¼ė„ ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ ė“±ģ—ģ„œ ėŒ€ģ²“ģˆ˜ė‹Øģ„ ģ œź³µķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.4": {"name": "민감정볓 ė° ź³ ģœ ģ‹ė³„ģ •ė³“ģ˜ 처리 ģ œķ•œ","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.1.4 민감정볓 ė° ź³ ģœ ģ‹ė³„ģ •ė³“ģ˜ 처리 ģ œķ•œ","Subdomain": "3.1. ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ‹œ 볓호씰치","AuditEvidence": ["ģ˜Øė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ķ™ˆķŽ˜ģ“ģ§€ ķšŒģ›ź°€ģž… 화멓, ģ“ė²¤ķŠø ģ°øģ—¬ 등)","ģ˜¤ķ”„ė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ķšŒģ›ź°€ģž…ģ‹ ģ²­ģ„œ 등)","ź°œģøģ •ė³“ 처리방침"],"AuditChecklist": ["ėÆ¼ź°ģ •ė³“ėŠ” ģ •ė³“ģ£¼ģ²“ė”œė¶€ķ„° ė³„ė„ģ˜ ė™ģ˜ė„¼ ė°›ź±°ė‚˜ ꓀련 법령에 근거가 ģžˆėŠ” ź²½ģš°ģ—ė§Œģ²˜ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ź³ ģœ ģ‹ė³„ģ •ė³“(ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø ģ œģ™ø)ėŠ” ģ •ė³“ģ£¼ģ²“ė”œė¶€ķ„° ė³„ė„ģ˜ ė™ģ˜ė„¼ ė°›ź±°ė‚˜ ꓀련 법령에 źµ¬ģ²“ģ ģø 근거가 ģžˆėŠ” ź²½ģš°ģ—ė§Œ ģ²˜ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģž¬ķ™” ė˜ėŠ” ģ„œė¹„ģŠ¤ė„¼ ģ œź³µķ•˜ėŠ” ź³¼ģ •ģ—ģ„œ ź³µź°œė˜ėŠ” 정볓에 ģ •ė³“ģ£¼ģ²“ģ˜ 민감정볓가 ķ¬ķ•ØėØģœ¼ė”œģØ ģ‚¬ģƒķ™œ ģ¹Øķ•“ģ˜ ģœ„ķ—˜ģ„±ģ“ ģžˆė‹¤ź³  ķŒė‹Øķ•˜ėŠ” ė•Œģ—ėŠ” ģž¬ķ™” ė˜ėŠ” ģ„œė¹„ģŠ¤ģ˜ 제공 전에 ėÆ¼ź°ģ •ė³“ģ˜ 공개 ź°€ėŠ„ģ„± ė° ė¹„ź³µź°œė„¼ ģ„ ķƒķ•˜ėŠ” ė°©ė²•ģ„ 정볓주첓가 ģ•Œģ•„ė³“źø° ģ‰½ź²Œ ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģž„ģ• ģøģ— ėŒ€ķ•œ ģš”źøˆź°ė©“ 등 ķ˜œķƒ 부여넼 ģœ„ķ•˜ģ—¬ ģž„ģ•  여부 등 걓강에 ź“€ķ•œ 민감정볓넼 ģˆ˜ģ§‘ķ•˜ė©“ģ„œ 다넸 ź°œģøģ •ė³“ 항목에 ķ¬ķ•Øķ•˜ģ—¬ ģ¼ź“„ ė™ģ˜ė„¼ ė°›ģ€ 경우","사딀 2 : ķšŒģ›ź°€ģž… ģ‹œ ģ™øźµ­ģøģ— ķ•œķ•˜ģ—¬ ģ™øźµ­ģøė“±ė”ė²ˆķ˜øė„¼ ģˆ˜ģ§‘ķ•˜ė©“ģ„œ 다넸 ź°œģøģ •ė³“ 항목에 ķ¬ķ•Øķ•˜ģ—¬ ģ¼ź“„ ė™ģ˜ė„¼ ė°›ģ€ 경우","사딀 3 : 민감정볓 ė˜ėŠ” ź³ ģœ ģ‹ė³„ģ •ė³“ģ˜ ģˆ˜ģ§‘ģ— ėŒ€ķ•“ ė³„ė„ģ˜ ė™ģ˜ė„¼ ė°›ģœ¼ė©“ģ„œ ź³ ģ§€ķ•˜ģ—¬ģ•¼ ķ•  4가지 사항 중에 ģ¼ė¶€ė„¼ ėˆ„ė½ķ•˜ź±°ė‚˜ ģž˜ėŖ»ėœ ė‚“ģš©ģœ¼ė”œ ź³ ģ§€ķ•˜ėŠ” 경우(ė™ģ˜ ź±°ė¶€ 권리 ė° ė™ģ˜ 거부에 따넸 ė¶ˆģ“ģµ ģ‚¬ķ•­ģ„ ź³ ģ§€ķ•˜ģ§€ ģ•Šģ€ 경우 등)"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제23ģ”°(ėÆ¼ź°ģ •ė³“ģ˜ ģ²˜ė¦¬ģ œķ•œ), 제24ģ”°(ź³ ģœ ģ‹ė³„ģ •ė³“ģ˜ 처리 ģ œķ•œ)"]}],"description": "민감정볓와 ź³ ģœ ģ‹ė³„ģ •ė³“(ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø ģ œģ™ø)넼 ģ²˜ė¦¬ķ•˜źø° ģœ„ķ•“ģ„œėŠ” ė²•ė ¹ģ—ģ„œ 구첓적으딜 처리넼 ģš”źµ¬ķ•˜ź±°ė‚˜ ķ—ˆģš©ķ•˜ėŠ” 경우넼 ģ œģ™øķ•˜ź³ ėŠ” ģ •ė³“ģ£¼ģ²“ģ˜ ė³„ė„ ė™ģ˜ė„¼ 받아야 ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.5": {"name": "ź°œģøģ •ė³“ ź°„ģ ‘ģˆ˜ģ§‘","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.1.5 ź°œģøģ •ė³“ ź°„ģ ‘ģˆ˜ģ§‘","Subdomain": "3.1. ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ 제공 ꓀련 ź³„ģ•½ģ„œ(ģ œź³µķ•˜ėŠ” ģžģ™€ģ˜ 계약 사항)","ź°œģøģ •ė³“ ģˆ˜ģ§‘ģ¶œģ²˜ģ— ėŒ€ķ•œ 정볓주첓 통지 ė‚“ģ—­","ź°œģøģ •ė³“ 처리방침"],"AuditChecklist": ["정볓주첓 ģ“ģ™øģ˜ 제3ģžė”œė¶€ķ„° ź°œģøģ •ė³“ė„¼ ģ œź³µė°›ėŠ” 경우 ź°œģøģ •ė³“ ģˆ˜ģ§‘ģ— ėŒ€ķ•œ ė™ģ˜ķšė“ ģ±…ģž„ģ“ ź°œģøģ •ė³“ė„¼ ģ œź³µķ•˜ėŠ” ģžģ—ź²Œ ģžˆģŒģ„ ź³„ģ•½ģ„ ķ†µķ•˜ģ—¬ ėŖ…ģ‹œķ•˜ź³  ģžˆėŠ”ź°€?","공개된 매첓 ė° ģž„ģ†Œģ—ģ„œ ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ėŠ” 경우 ģ •ė³“ģ£¼ģ²“ģ˜ 공개 ėŖ©ģ Ā·ė²”ģœ„ ė° ģ‚¬ķšŒ ķ†µė…ģƒ ė™ģ˜ ģ˜ģ‚¬ź°€ ģžˆė‹¤ź³  ģøģ •ė˜ėŠ” ė²”ģœ„ ė‚“ģ—ģ„œė§Œ ģˆ˜ģ§‘Ā·ģ“ģš©ķ•˜ź³  ģžˆėŠ”ź°€?","ģ„œė¹„ģŠ¤ 계약 ģ“ķ–‰ģ„ ģœ„ķ•“ ķ•„ģš”ķ•œ ź²½ģš°ė”œģ„œ, ģ„œė¹„ģŠ¤ 제공 ź³¼ģ •ģ—ģ„œ ģžė™ģˆ˜ģ§‘ģž„ģ¹˜ 등에 ģ˜ķ•˜ģ—¬ ģˆ˜ģ§‘Ā·ģƒģ„±ķ•˜ėŠ” ź°œģøģ •ė³“ģ˜ ź²½ģš°ģ—ė„ ģµœģ†Œģˆ˜ģ§‘ ģ›ģ¹™ģ„ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?","정볓주첓 ģ“ģ™øė”œė¶€ķ„° ģˆ˜ģ§‘ķ•˜ėŠ” ź°œģøģ •ė³“ģ— ėŒ€ķ•“ ģ •ė³“ģ£¼ģ²“ģ˜ ģš”źµ¬ź°€ ģžˆėŠ” 경우 ģ¦‰ģ‹œ ķ•„ģš”ķ•œ ģ‚¬ķ•­ģ„ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?","정볓주첓 ģ“ģ™øė”œė¶€ķ„° ģˆ˜ģ§‘ķ•œ ź°œģøģ •ė³“ė„¼ ģ²˜ė¦¬ķ•˜ėŠ” 경우 ź°œģøģ •ė³“ģ˜ ģ¢…ė„˜Ā·ź·œėŖØ ė“±ģ“ 법적 ģš”ź±“ģ— ķ•“ė‹¹ķ•˜ėŠ” 경우 ķ•„ģš”ķ•œ ģ‚¬ķ•­ģ„ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģˆ˜ģ§‘ ģ¶œģ²˜ģ— ėŒ€ķ•“ ģ•Œė¦° źø°ė”ģ„ 핓당 ź°œģøģ •ė³“ģ˜ 파기 ģ‹œź¹Œģ§€ 볓꓀ ė° ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€, SNS에 공개된 ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ź³  ģžˆėŠ” ģƒķƒœģ—ģ„œ ģ •ė³“ģ£¼ģ²“ģ˜ ģˆ˜ģ§‘ 출처 ģš”źµ¬ģ— ėŒ€ķ•œ ģ²˜ė¦¬ģ ˆģ°Øź°€ ģ”“ģž¬ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ź°œģøģ •ė³“ ė³“ķ˜øė²• 제17씰제1ķ•­ģ œ1ķ˜øģ— ė”°ė¼ 다넸 ģ‚¬ģ—…ģžė”œė¶€ķ„° ź°œģøģ •ė³“ ģ œź³µė™ģ˜ė„¼ 근거딜 ź°œģøģ •ė³“ė„¼ ģ œź³µė°›ģ•˜ģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•˜ģ—¬ 핓당 ģ •ė³“ģ£¼ģ²“ģ—ź²Œ 3ź°œģ›” 낓에 ķ†µģ§€ķ•˜ģ§€ ģ•Šģ€ 경우(ė‹¤ė§Œ ģ œź³µė°›ģ€ ģžź°€ 5만 ėŖ… ģ“ģƒ ģ •ė³“ģ£¼ģ²“ģ˜ 민감정볓 ė˜ėŠ” ź³ ģœ ģ‹ė³„ģ •ė³“ė„¼ ģ²˜ė¦¬ķ•˜ź±°ė‚˜ 100만 ėŖ… ģ“ģƒ ģ •ė³“ģ£¼ģ²“ģ˜ ź°œģøģ •ė³“ė„¼ ģ²˜ė¦¬ķ•˜ėŠ” 경우)","사딀 3 : 법적 ģ˜ė¬“ ėŒ€ģƒģžģ— ķ•“ė‹¹ė˜ģ–“ ź°œģøģ •ė³“ ģˆ˜ģ§‘ 출처넼 ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ķ†µģ§€ķ•˜ė©“ģ„œ ź°œģøģ •ė³“ģ˜ 처리목적 ė˜ėŠ” ė™ģ˜ė„¼ ģ² ķšŒķ•  ź¶Œė¦¬ź°€ ģžˆė‹¤ėŠ” 사실 등 ķ•„ģˆ˜ ķ†µģ§€ģ‚¬ķ•­ģ„ ģ¼ė¶€ ėˆ„ė½ķ•œ 경우","사딀 4 : 법적 ģ˜ė¬“ ėŒ€ģƒģžģ— ķ•“ė‹¹ė˜ģ–“ ź°œģøģ •ė³“ ģˆ˜ģ§‘ 출처넼 ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ķ†µģ§€ķ•˜ģ˜€ģœ¼ė‚˜, ģˆ˜ģ§‘ 출처 통지에 ź“€ķ•œ źø°ė”ģ„ 핓당 ź°œģøģ •ė³“ģ˜ 파기 ģ‹œź¹Œģ§€ ė³“ź“€ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제16ģ”°(ź°œģøģ •ė³“ģ˜ ģˆ˜ģ§‘ ģ œķ•œ), 제19ģ”°(ź°œģøģ •ė³“ė„¼ ģ œź³µė°›ģ€ ģžģ˜ ģ“ģš©Ā·ģ œź³µ ģ œķ•œ), 제20ģ”°(정볓주첓 ģ“ģ™øė”œė¶€ķ„° ģˆ˜ģ§‘ķ•œ ź°œģøģ •ė³“ģ˜ ģˆ˜ģ§‘ 출처 등 통지)"]}],"description": "정볓주첓 ģ“ģ™øė”œė¶€ķ„° ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ź±°ė‚˜ 제3ģžė”œė¶€ķ„° ģ œź³µė°›ėŠ” ź²½ģš°ģ—ėŠ” 업묓에 ķ•„ģš”ķ•œ ģµœģ†Œķ•œģ˜ ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ź±°ė‚˜ ģ œź³µė°›ģ•„ģ•¼ ķ•˜ė©°, 법령에 ź·¼ź±°ķ•˜ź±°ė‚˜ ģ •ė³“ģ£¼ģ²“ģ˜ ģš”źµ¬ź°€ ģžˆģœ¼ė©“ ź°œģøģ •ė³“ģ˜ ģˆ˜ģ§‘ 출처, 처리목적, ģ²˜ė¦¬ģ •ģ§€ģ˜ ģš”źµ¬ź¶Œė¦¬ė„¼ ģ•Œė ¤ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.6": {"name": "ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģ„¤ģ¹˜Ā·ģš“ģ˜","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.1.6 ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģ„¤ģ¹˜Ā·ģš“ģ˜","Subdomain": "3.1. ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ‹œ 볓호씰치","AuditEvidence": ["ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° 욓영 ķ˜„ķ™©","ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģ•ˆė‚“ķŒ","ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģš“ģ˜Ā·ź“€ė¦¬ė°©ģ¹Ø","ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ꓀리화멓(ź³„ģ •Ā·ź¶Œķ•œ ė‚“ģ—­, ģ˜ģƒģ •ė³“ 볓씓기간 등)","ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° 욓영 ģˆ˜ķƒģžģ™€ģ˜ ź³„ģ•½ģ„œ ė° 점검 ģ“ė „"],"AuditChecklist": ["공개된 ģž„ģ†Œģ— ź³ ģ •ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ė„¼ ģ„¤ģ¹˜Ā·ģš“ģ˜ķ•  경우 법적 ķ—ˆģš© ģš”ź±“ģ— ķ•“ė‹¹ķ•˜ėŠ”ģ§€ė„¼ ź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?","공공기꓀ ė“±ģ“ 공개된 ģž„ģ†Œģ— ź³ ģ •ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ė„¼ ģ„¤ģ¹˜Ā·ģš“ģ˜ķ•˜ė ¤ėŠ” 경우 ź³µģ²­ķšŒĀ·ģ„¤ėŖ…ķšŒ 개최 ė“±ģ˜ 법령에 따넸 절차넼 거쳐 ꓀계 전문가 ė° ģ“ķ•“ź“€ź³„ģžģ˜ ģ˜ź²¬ģ„ ģˆ˜ė “ķ•˜ź³  ģžˆėŠ”ź°€?","ź³ ģ •ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģ„¤ģ¹˜Ā·ģš“ģ˜ ģ‹œ 정볓주첓가 ģ‰½ź²Œ ģøģ‹ķ•  수 ģžˆė„ė” ģ•ˆė‚“ķŒ ģ„¤ģ¹˜ 등 ķ•„ģš”ķ•œ 씰치넼 ķ•˜ź³  ģžˆėŠ”ź°€?","업묓넼 목적으딜 공개된 ģž„ģ†Œģ—ģ„œ ģ“ė™ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ė„¼ ģš“ģ˜ķ•˜ėŠ” 경우 법적 ķ—ˆģš© ģš”ź±“ģ— ķ•“ė‹¹ķ•˜ėŠ”ģ§€ė„¼ ź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?","업묓넼 목적으딜 공개된 ģž„ģ†Œģ—ģ„œ ģ“ė™ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ė”œ ģ‚¬ėžŒ ė˜ėŠ” ź·ø ģ‚¬ėžŒź³¼ ź“€ė Øėœ ģ‚¬ė¬¼ģ˜ ģ˜ģƒģ„ ģ“¬ģ˜ķ•˜ėŠ” 경우 ė¶ˆė¹›, ģ†Œė¦¬, ģ•ˆė‚“ķŒ ė“±ģ˜ ė°©ė²•ģœ¼ė”œ 쓬영 ģ‚¬ģ‹¤ģ„ ķ‘œģ‹œķ•˜ź³  ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?","ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ė° ģ˜ģƒģ •ė³“ģ˜ ģ•ˆģ „ķ•œ ꓀리넼 ģœ„ķ•œ ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģš“ģ˜Ā·ź“€ė¦¬ ė°©ģ¹Øģ„ ė§ˆė Øķ•˜ģ—¬ ģ‹œķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ˜ģƒģ •ė³“ģ˜ 볓꓀ źø°ź°„ģ„ ģ •ķ•˜ź³  ģžˆģœ¼ė©°, 볓꓀ źø°ź°„ 만료 ģ‹œ 지첓 ģ—†ģ“ ķŒŒźø°ķ•˜ź³  ģžˆėŠ”ź°€?","ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģ„¤ģ¹˜Ā·ģš“ģ˜ģ— ź“€ķ•œ 사묓넼 ģœ„ķƒķ•˜ėŠ” 경우 ꓀련 절차 ė° ģš”ź±“ģ— ė”°ė¼ ź³„ģ•½ģ„œģ— ė°˜ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģ•ˆė‚“ķŒģ˜ ź³ ģ§€ 문구가 ģ¼ė¶€ ėˆ„ė½ė˜ģ–“ 욓영되고 ģžˆź±°ė‚˜, ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° 욓영 ė° ꓀리 ė°©ģ¹Øģ„ ģˆ˜ė¦½Ā·ģš“ģ˜ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģš“ģ˜Ā·ź“€ė¦¬ ė°©ģ¹Øģ„ 수립 ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, 방침 ė‚“ģš©ź³¼ 달리 ė³“ź“€źø°ź°„ģ„ ģ¤€ģˆ˜ķ•˜ģ§€ ģ•Šź³  ģš“ģ˜ė˜ź±°ė‚˜, ģ˜ģƒģ •ė³“ 볓호넼 ģœ„ķ•œ ģ ‘ź·¼ķ†µģ œ ė° ė”œź¹… 등 방침에 źø°ģˆ ķ•œ ģ‚¬ķ•­ģ“ ģ¤€ģˆ˜ė˜ģ§€ ģ•ŠėŠ” 등 ꓀리가 ėÆøķ”ķ•œ 경우","사딀 3 : ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ģ˜ ģ„¤ģ¹˜Ā·ģš“ģ˜ 사묓넼 외부업첓에 ģœ„ķƒķ•˜ź³  ģžˆģœ¼ė‚˜, ģ˜ģƒģ •ė³“ģ˜ ꓀리 ķ˜„ķ™© 점검에 ź“€ķ•œ 사항, ģ†ķ•“ė°°ģƒ ģ±…ģž„ģ— ź“€ķ•œ 사항 등 ė²•ė ¹ģ—ģ„œ ģš”źµ¬ķ•˜ėŠ” ė‚“ģš©ģ„ ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° 업묓 ģœ„ķƒ ź³„ģ•½ģ„œģ— ėŖ…ģ‹œķ•˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ģ˜ ģ„¤ģ¹˜Ā·ģš“ģ˜ 사묓넼 외부업첓에 ģœ„ķƒķ•˜ź³  ģžˆģœ¼ė‚˜, ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģ•ˆė‚“ķŒģ— ģˆ˜ķƒģžģ˜ ėŖ…ģ¹­ź³¼ ģ—°ė½ģ²˜ė„¼ ėˆ„ė½ķ•˜ģ—¬ ź³ ģ§€ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제25ģ”°(ź³ ģ •ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ģ˜ ģ„¤ģ¹˜Ā·ģš“ģ˜ ģ œķ•œ), 제25ģ”°ģ˜2(ģ“ė™ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ģ˜ 욓영 ģ œķ•œ)"]}],"description": "ź³ ģ •ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ė„¼ 공개된 ģž„ģ†Œģ— ģ„¤ģ¹˜Ā·ģš“ģ˜ķ•˜ź±°ė‚˜ ģ“ė™ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ė„¼ 공개된 ģž„ģ†Œģ—ģ„œ 업묓넼 목적으딜 ģš“ģ˜ķ•˜ėŠ” 경우 ģ„¤ģ¹˜ 목적 ė° ģœ„ģ¹˜ģ— ė”°ė¼ 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ģ¤€ģˆ˜ķ•˜ź³ , ģ ģ ˆķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.7": {"name": "ė§ˆģ¼€ķŒ… ėŖ©ģ ģ˜ ź°œģøģ •ė³“ ģˆ˜ģ§‘Ā·ģ“ģš©","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.1.7 ė§ˆģ¼€ķŒ… ėŖ©ģ ģ˜ ź°œģøģ •ė³“ ģˆ˜ģ§‘Ā·ģ“ģš©","Subdomain": "3.1. ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ‹œ 볓호씰치","AuditEvidence": ["ģ˜Øė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ķ™ˆķŽ˜ģ“ģ§€ ķšŒģ›ź°€ģž… 화멓, ėŖØė°”ģ¼ģ•± ķšŒģ›ź°€ģž… 화멓, ģ“ė²¤ķŠø ģ°øģ—¬ 등)","ģ˜¤ķ”„ė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ķšŒģ›ź°€ģž…ģ‹ ģ²­ģ„œ 등)","ė§ˆģ¼€ķŒ… ė™ģ˜ źø°ė”","ꓑ고성 정볓전솔 ģˆ˜ģ‹ ė™ģ˜ źø°ė” ė° ģˆ˜ģ‹ ė™ģ˜ ģ˜ģ‚¬ķ™•ģø źø°ė”","ꓑ고성 정볓 ė°œģ†” ģ‹œģŠ¤ķ…œ ź“€ė¦¬ģž 화멓(ė©”ģ¼, SMS, 앱 ķ‘øģ‹œ 등)","ꓑ고성 정볓 ė°œģ†” 문구","ź°œģøģ •ė³“ 처리방침"],"AuditChecklist": ["ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģž¬ķ™”ė‚˜ ģ„œė¹„ģŠ¤ė„¼ ķ™ė³“ķ•˜ź±°ė‚˜ 판매넼 ź¶Œģœ ķ•˜źø° ģœ„ķ•˜ģ—¬ ź°œģøģ •ė³“ ģ²˜ė¦¬ģ— ėŒ€ķ•œ ė™ģ˜ė„¼ ė°›ėŠ” 경우 정볓주첓가 ģ“ė„¼ ėŖ…ķ™•ķ•˜ź²Œ ģøģ§€ķ•  수 ģžˆė„ė” ģ•Œė¦¬ź³  ė³„ė„ģ˜ ė™ģ˜ė„¼ 받고 ģžˆėŠ”ź°€?","ģ „ģžģ  전솔매첓넼 ģ“ģš©ķ•˜ģ—¬ ģ˜ė¦¬ėŖ©ģ ģ˜ ꓑ고성 정볓넼 ģ „ģ†”ķ•˜ėŠ” 경우 ģˆ˜ģ‹ ģžģ˜ ėŖ…ģ‹œģ ģø 사전 ė™ģ˜ė„¼ 받고 ģžˆģœ¼ė©°, 2ė…„ė§ˆė‹¤ ģ •źø°ģ ģœ¼ė”œ ģˆ˜ģ‹ ģžģ˜ ģˆ˜ģ‹ ė™ģ˜ 여부넼 ķ™•ģøķ•˜ź³  ģžˆėŠ”ź°€?","ģ „ģžģ  전솔매첓넼 ģ“ģš©ķ•œ ģ˜ė¦¬ėŖ©ģ ģ˜ ꓑ고성 정볓 전솔에 ėŒ€ķ•˜ģ—¬ ģˆ˜ģ‹ ģžź°€ ģˆ˜ģ‹ ź±°ė¶€ģ˜ģ‚¬ė„¼ ķ‘œģ‹œķ•˜ź±°ė‚˜ 사전 ė™ģ˜ė„¼ ģ² ķšŒķ•œ 경우 ģ˜ė¦¬ėŖ©ģ ģ˜ ꓑ고성 정볓 ģ „ģ†”ģ„ ģ¤‘ė‹Øķ•˜ė„ė” ķ•˜ź³  ģžˆėŠ”ź°€?","ģ˜ė¦¬ėŖ©ģ ģ˜ ꓑ고성 정볓넼 ģ „ģ†”ķ•˜ėŠ” 경우 ģ „ģ†”ģžģ˜ ėŖ…ģ¹­, ģˆ˜ģ‹ ź±°ė¶€ 방법 ė“±ģ„ 구첓적으딜 ė°ķžˆź³  ģžˆģœ¼ė©°, ģ•¼ź°„ģ‹œź°„ģ—ėŠ” ģ „ģ†”ķ•˜ģ§€ ģ•Šė„ė” ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : Ź»ķ™ė³“ ė° ė§ˆģ¼€ķŒ…Ź¼ 목적으딜 ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ė©“ģ„œ Ź»ė¶€ź°€ģ„œė¹„ģŠ¤ 제공ʼ, ʻ제휓 ģ„œė¹„ģŠ¤ 제공ʼ 등과 ź°™ģ“ ėŖ©ģ ģ„ ėŖØķ˜øķ•˜ź²Œ ģ•ˆė‚“ķ•˜ėŠ” 경우 ė˜ėŠ” 다넸 목적으딜 ģˆ˜ģ§‘ķ•˜ėŠ” ź°œģøģ •ė³“ģ™€ źµ¬ė¶„ķ•˜ģ§€ ģ•Šź³  ķ¬ź“„ ė™ģ˜ė„¼ ė°›ėŠ” 경우","사딀 2 : ėŖØė°”ģ¼ ģ•±ģ—ģ„œ ꓑ고성 정볓전솔(앱 ķ‘øģ‹œ)에 ėŒ€ķ•˜ģ—¬ ź±°ė¶€ ģ˜ģ‚¬ė„¼ ė°ķ˜”ģœ¼ė‚˜, ķ”„ė”œź·øėžØ 오넘 ė“±ģ˜ ģ“ģœ ė”œ ꓑ고성 앱 ķ‘øģ‹œź°€ ģ“ė£Øģ–“ģ§€ėŠ” 경우","사딀 3 : ģ˜Øė¼ģø ķšŒģ›ź°€ģž… ķ™”ė©“ģ—ģ„œ ė¬øģž, ģ“ė©”ģ¼ģ— ģ˜ķ•œ ꓑ고성 정볓 전솔에 ėŒ€ķ•˜ģ—¬ ė””ķ“ķŠøė”œ ģ²“ķ¬ė˜ģ–“ ģžˆėŠ” 경우","사딀 4 : ꓑ고성 정볓 ģˆ˜ģ‹ ė™ģ˜ 여부에 ėŒ€ķ•˜ģ—¬ 2ė…„ė§ˆė‹¤ ķ™•ģøķ•˜ģ§€ ģ•Šģ€ 경우","사딀 5 : ģ˜ė¦¬ėŖ©ģ ģ˜ ꓑ고성 정볓넼 ģ „ģžģš°ķŽøģœ¼ė”œ ģ „ģ†”ķ•˜ė©“ģ„œ ģ œėŖ©ģ“ ģ‹œģž‘ė˜ėŠ” 부분에 Ź»(ź“‘ź³ )ʼ ķ‘œģ‹œė„¼ ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제22ģ”°(ė™ģ˜ė„¼ ė°›ėŠ” 방법)","ģ •ė³“ķ†µģ‹ ė§ė²• 제50ģ”°(ꓑ고성 정볓 전솔 ģ œķ•œ)"]}],"description": "ģž¬ķ™”ė‚˜ ģ„œė¹„ģŠ¤ģ˜ ķ™ė³“, 판매 권유, ꓑ고성 정볓전솔 등 ė§ˆģ¼€ķŒ… 목적으딜 ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ ė°ģ“ģš©ķ•˜ėŠ” 경우 ź·ø ėŖ©ģ ģ„ 정볓주첓가 ėŖ…ķ™•ķ•˜ź²Œ ģøģ§€ķ•  수 ģžˆė„ė” ź³ ģ§€ķ•˜ź³  ė™ģ˜ė„¼ 받아야 ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.2.1": {"name": "ź°œģøģ •ė³“ ķ˜„ķ™©ź“€ė¦¬","checks": {"macie_is_enabled": "PASS","s3_bucket_lifecycle_enabled": "FAIL"},"status": "FAIL","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.2.1 ź°œģøģ •ė³“ ķ˜„ķ™©ź“€ė¦¬","Subdomain": "3.2. ź°œģøģ •ė³“ 볓유 ė° ģ“ģš© ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ ķ˜„ķ™©ķ‘œ","ź°œģøģ •ė³“ ķė¦„ķ‘œĀ·ķė¦„ė„","ź°œģøģ •ė³“ķŒŒģ¼ ė“±ė” ķ˜„ķ™©","ź°œģøģ •ė³“ķŒŒģ¼ ź“€ė¦¬ėŒ€ģž„","ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź“€ķ•œ ģ‚¬ķ•­ģ„ źø°ė”ķ•œ ź°œģøģ •ė³“ķŒŒģ¼","ļ½¢ģ”°ģ„øė²”ģ²˜ė²Œė²•ļ½£ģ— 따넸 ė²”ģ¹™ķ–‰ģœ„ 씰사 ė° 「꓀세법」에 따넸 ė²”ģ¹™ķ–‰ģœ„ 씰사에 ź“€ķ•œ ģ‚¬ķ•­ģ„ źø°ė”ķ•œ ź°œģøģ •ė³“ķŒŒģ¼","ģ¼ķšŒģ„±ģœ¼ė”œ ģš“ģ˜ė˜ėŠ” ķŒŒģ¼ 등 ģ§€ģ†ģ ģœ¼ė”œ ꓀리할 ķ•„ģš”ź°€ 낮다고 ģøģ •ė˜ģ–“ ėŒ€ķ†µė ¹ė ¹ģœ¼ė”œ ģ •ķ•˜ėŠ” ź°œģøģ •ė³“ķŒŒģ¼","ķšŒģ˜ ģ°øģ„ ģˆ˜ė‹¹ 지급, ģžė£ŒĀ·ė¬¼ķ’ˆģ˜ 솔부, źøˆģ „ģ˜ ģ •ģ‚° 등 ė‹Øģˆœ 업묓 ģˆ˜ķ–‰ģ„ ģœ„ķ•“ ģš“ģ˜ė˜ėŠ” ź°œģøģ •ė³“ķŒŒģ¼ė”œģ„œ ģ§€ģ†ģ  ꓀리 ķ•„ģš”ģ„±ģ“ ė‚®ģ€ ź°œģøģ •ė³“ķŒŒģ¼","ź³µģ¤‘ģœ„ģƒ 등 ź³µź³µģ˜ ģ•ˆģ „ź³¼ ģ•ˆė…•ģ„ ģœ„ķ•˜ģ—¬ źø“źø‰ķžˆ ķ•„ģš”ķ•œ ź²½ģš°ė”œģ„œ ģ¼ģ‹œģ ģœ¼ė”œ ģ²˜ė¦¬ė˜ėŠ” ź°œģøģ •ė³“ķŒŒģ¼","ź·ø 밖에 ģ¼ķšŒģ  업묓 ģ²˜ė¦¬ė§Œģ„ ģœ„ķ•“ ģˆ˜ģ§‘ėœ ź°œģøģ •ė³“ķŒŒģ¼ė”œģ„œ ģ €ģž„ė˜ź±°ė‚˜ źø°ė”ė˜ģ§€ ģ•ŠėŠ” ź°œģøģ •ė³“ķŒŒģ¼","다넸 법령에 ė”°ė¼ ė¹„ė°€ė”œ ė¶„ė„˜ėœ ź°œģøģ •ė³“ķŒŒģ¼","źµ­ź°€ģ•ˆģ „ė³“ģž„ź³¼ ź“€ė Øėœ 정볓 ė¶„ģ„ģ„ 목적으딜 ģˆ˜ģ§‘ ė˜ėŠ” 제공 ģš”ģ²­ė˜ėŠ” ź°œģøģ •ė³“ķŒŒģ¼","ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ė„¼ ķ†µķ•˜ģ—¬ ģ²˜ė¦¬ė˜ėŠ” ź°œģøģ˜ģƒģ •ė³“ķŒŒģ¼","ļ½¢źøˆģœµģ‹¤ėŖ…ź±°ėž˜ ė° ė¹„ė°€ė³“ģž„ģ— ź“€ķ•œ 법넠」에 따넸 źøˆģœµźø°ź“€ģ“ źøˆģœµģ—…ė¬“ ģ·Øźø‰ģ„ ģœ„ķ•˜ģ—¬ ė³“ģœ ķ•˜ėŠ” ź°œģøģ •ė³“ķŒŒģ¼"],"AuditChecklist": ["ģˆ˜ģ§‘Ā·ė³“ģœ ķ•˜ź³  ģžˆėŠ” ź°œģøģ •ė³“ģ˜ ķ•­ėŖ©, ė³“ģœ ėŸ‰, 처리 목적 ė° 방법, ė³“ģœ źø°ź°„ 등 ķ˜„ķ™©ģ„ ģ •źø°ģ ģœ¼ė”œ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ź³µź³µźø°ź“€ģ“ ź°œģøģ •ė³“ķŒŒģ¼ģ„ ģš“ģš©ķ•˜ź±°ė‚˜ ė³€ź²½ķ•˜ėŠ” 경우 ź“€ė Øėœ ģ‚¬ķ•­ģ„ ė²•ė„ ģ—ģ„œ ģ •ķ•œ ź“€ź³„źø°ź“€ģ˜ ģž„ģ—ź²Œ ė“±ė”ķ•˜ź³  ģžˆėŠ”ź°€?","ź³µź³µźø°ź“€ģ€ ź°œģøģ •ė³“ķŒŒģ¼ģ˜ 볓유 ķ˜„ķ™©ģ„ ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź³µź°œķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ķŒŒģ¼ģ„ ķ™ˆķŽ˜ģ“ģ§€ģ˜ ź°œģøģ •ė³“ķŒŒģ¼ ė“±ė” 메뉓넼 ķ†µķ•˜ģ—¬ ėŖ©ė”ģ„ ź“€ė¦¬ķ•˜ź³  ģžˆģœ¼ė‚˜, ź·ø 중 ģ¼ė¶€ ķ™ˆķŽ˜ģ“ģ§€ ģ„œė¹„ģŠ¤ģ™€ ź“€ė Øėœ ź°œģøģ •ė³“ķŒŒģ¼ģ˜ ė‚“ģš©ģ“ ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ėˆ„ė½ė˜ģ–“ ģžˆėŠ” 경우","사딀 2 : ģ‹ ź·œ ź°œģøģ •ė³“ķŒŒģ¼ģ„ źµ¬ģ¶•ķ•œ ģ§€ 2ź°œģ›”ģ“ ź²½ź³¼ķ•˜ģ˜€ģœ¼ė‚˜, 핓당 ź°œģøģ •ė³“ķŒŒģ¼ģ„ ź°œģøģ •ė³“ ė³“ķ˜øģœ„ģ›ķšŒģ— ė“±ė”ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ź°œģøģ •ė³“ ė³“ķ˜øģœ„ģ›ķšŒģ— ė“±ė”ė˜ģ–“ 공개된 ź°œģøģ •ė³“ķŒŒģ¼ģ˜ ė‚“ģš©(ģˆ˜ģ§‘ķ•˜ėŠ” ź°œģøģ •ė³“ģ˜ ķ•­ėŖ© 등)ģ“ ģ‹¤ģ œ ģ²˜ė¦¬ķ•˜ź³  ģžˆėŠ” ź°œģøģ •ė³“ķŒŒģ¼ ķ˜„ķ™©ź³¼ ģƒģ“ķ•œ 경우","사딀 4 : ź³µź³µźø°ź“€ģ“ ģž„ģ§ģ›ģ˜ ź°œģøģ •ė³“ķŒŒģ¼, 통계법에 ė”°ė¼ ģˆ˜ģ§‘ė˜ėŠ” ź°œģøģ •ė³“ķŒŒģ¼ģ— ėŒ€ķ•“ ź°œģøģ •ė³“ķŒŒģ¼ ė“±ė” ģ˜ˆģ™øģ‚¬ķ•­ģ— ķ•“ė‹¹ė˜ģ§€ ģ•ŠģŒģ—ė„ ė¶ˆźµ¬ķ•˜ź³  핓당 ź°œģøģ •ė³“ķŒŒģ¼ģ„ ź°œģøģ •ė³“ ė³“ķ˜øģœ„ģ›ķšŒģ— ė“±ė”ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제32ģ”°(ź°œģøģ •ė³“ķŒŒģ¼ģ˜ ė“±ė” ė° 공개)"]}],"description": "ģˆ˜ģ§‘Ā·ė³“ģœ ķ•˜ėŠ” ź°œģøģ •ė³“ģ˜ ķ•­ėŖ©, ė³“ģœ ėŸ‰, 처리 목적 ė° 방법, ė³“ģœ źø°ź°„ 등 ķ˜„ķ™©ģ„ ģ •źø°ģ ģœ¼ė”œ ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•˜ė©°, ź³µź³µźø°ź“€ģ˜ 경우 ģ“ė„¼ ė²•ė„ ģ—ģ„œ ģ •ķ•œ ź“€ź³„źø°ź“€ģ˜ ģž„ģ—ź²Œ ė“±ė”ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"3.2.2": {"name": "ź°œģøģ •ė³“ ķ’ˆģ§ˆė³“ģž„","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.2.2 ź°œģøģ •ė³“ ķ’ˆģ§ˆė³“ģž„","Subdomain": "3.2. ź°œģøģ •ė³“ 볓유 ė° ģ“ģš© ģ‹œ 볓호씰치","AuditEvidence": ["정볓주첓 ź°œģøģ •ė³“ ģˆ˜ģ •Ā·ė³€ź²½ ģ–‘ģ‹(ģ˜Øė¼ģø, ģ˜¤ķ”„ė¼ģø)","ź°œģøģ •ė³“ ģµœģ‹ ģ„± ģœ ģ§€ 절차"],"AuditChecklist": ["ź°œģøģ •ė³“ė„¼ ģµœģ‹ ģ˜ 상태딜 ģ •ķ™•ķ•˜ź²Œ ģœ ģ§€ķ•˜źø° ģœ„ķ•œ 절차 ė° ė°©ģ•ˆģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ ģžˆėŠ”ź°€?","정볓주첓가 ė³øģøģ˜ ź°œģøģ •ė³“ģ— ėŒ€ķ•˜ģ—¬ 정확성, 완전성 ė° ģµœģ‹ ģ„±ģ„ ģœ ģ§€ķ•  수 ģžˆėŠ” ė°©ė²•ģ„ ģ œź³µķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ė„¼ ķ†µķ•˜ģ—¬ ķšŒģ›ģ •ė³“ė„¼ 변경할 ė•ŒėŠ” ė³øģøķ™•ģø 절차넼 거치고 ģžˆģœ¼ė‚˜, ź³ ź°ģ„¼ķ„° ģƒė‹“ģ›ź³¼ģ˜ 통화넼 ķ†µķ•œ ķšŒģ› 정볓 변경 ģ‹œģ—ėŠ” ė³øģøķ™•ģø ģ ˆģ°Øź°€ ėÆøķ”ķ•˜ģ—¬ ķšŒģ›ģ •ė³“ģ˜ ė¶ˆė²•ģ ģø ė³€ź²½ģ“ ź°€ėŠ„ķ•œ 경우","사딀 2 : ģ˜Øė¼ģø ķšŒģ›ģ— ėŒ€ķ•“ģ„œėŠ” ź°œģøģ •ė³“ė„¼ 변경할 수 ģžˆėŠ” ė°©ė²•ģ„ ģ œź³µķ•˜ź³  ģžˆģœ¼ė‚˜, ģ˜¤ķ”„ė¼ģø ķšŒģ›ģ— ėŒ€ķ•“ģ„œėŠ” ź°œģøģ •ė³“ė„¼ 변경할 수 ģžˆėŠ” ė°©ė²•ģ„ ģ œź³µķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제3ģ”°(ź°œģøģ •ė³“ 볓호 원칙)"]}],"description": "ģˆ˜ģ§‘ėœ ź°œģøģ •ė³“ėŠ” 처리 목적에 ķ•„ģš”ķ•œ ė²”ģœ„ģ—ģ„œ ź°œģøģ •ė³“ģ˜ ģ •ķ™•ģ„±Ā·ģ™„ģ „ģ„±Ā·ģµœģ‹ ģ„±ģ“ ė³“ģž„ė˜ė„ė” ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ź“€ė¦¬ģ ˆģ°Øė„¼ ģ œź³µķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.2.3": {"name": "ģ“ģš©ģž 단말기 ģ ‘ź·¼ 볓호","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.2.3 ģ“ģš©ģž 단말기 ģ ‘ź·¼ 볓호","Subdomain": "3.2. ź°œģøģ •ė³“ 볓유 ė° ģ“ģš© ģ‹œ 볓호씰치","AuditEvidence": ["앱 ģ ‘ź·¼ź¶Œķ•œ ė™ģ˜ 화멓","앱 ģ ‘ź·¼ź¶Œķ•œ 설정 ķ˜„ķ™©"],"AuditChecklist": ["정볓주첓(ģ“ģš©ģž)ģ˜ ģ“ė™ķ†µģ‹ ė‹Øė§ģž„ģ¹˜ 낓에 ģ €ģž„ė˜ģ–“ ģžˆėŠ” 정볓 ė° ģ“ė™ķ†µģ‹ ė‹Øė§ģž„ģ¹˜ģ— ģ„¤ģ¹˜ėœ źø°ėŠ„ģ— ėŒ€ķ•˜ģ—¬ 접근할 수 ģžˆėŠ” ź¶Œķ•œģ“ ķ•„ģš”ķ•œ 경우 ėŖ…ķ™•ķ•˜ź²Œ ģøģ§€ķ•  수 ģžˆė„ė” ģ•Œė¦¬ź³  정볓주첓(ģ“ģš©ģž)ģ˜ ė™ģ˜ė„¼ 받고 ģžˆėŠ”ź°€?","ģ“ė™ķ†µģ‹ ė‹Øė§ģž„ģ¹˜ ė‚“ģ—ģ„œ 핓당 ģ„œė¹„ģŠ¤ė„¼ ģ œź³µķ•˜źø° ģœ„ķ•˜ģ—¬ ė°˜ė“œģ‹œ ķ•„ģš”ķ•œ ģ ‘ź·¼ź¶Œķ•œģ“ ģ•„ė‹Œ 경우, 정볓주첓(ģ“ģš©ģž)ź°€ ė™ģ˜ķ•˜ģ§€ ģ•Šģ•„ė„ ģ„œė¹„ģŠ¤ ģ œź³µģ„ ź±°ė¶€ķ•˜ģ§€ ģ•Šė„ė” ķ•˜ź³  ģžˆėŠ”ź°€?","ģ“ė™ķ†µģ‹ ė‹Øė§ģž„ģ¹˜ ė‚“ģ—ģ„œ 핓당 ģ ‘ź·¼ź¶Œķ•œģ— ėŒ€ķ•œ 정볓주첓(ģ“ģš©ģž)ģ˜ ė™ģ˜ ė° ģ² ķšŒė°©ė²•ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģŠ¤ė§ˆķŠøķ° ģ•±ģ—ģ„œ ģ„œė¹„ģŠ¤ģ— ė¶ˆķ•„ģš”ķ•Øģ—ė„ ė¶ˆźµ¬ķ•˜ź³  ģ£¼ģ†Œė”, 사진, ė¬øģž 등 ģŠ¤ė§ˆķŠøķ° ė‚“ ź°œģøģ •ė³“ ģ˜ģ—­ģ— 접근할 수 ģžˆėŠ” ź¶Œķ•œģ„ ź³¼ė„ķ•˜ź²Œ ģ„¤ģ •ķ•œ 경우","사딀 2 : ģ •ė³“ķ†µģ‹ ģ„œė¹„ģŠ¤ ģ œź³µģžģ˜ ģŠ¤ė§ˆķŠøķ° ģ•±ģ—ģ„œ ģŠ¤ė§ˆķŠøķ° 낓에 ģ €ģž„ė˜ģ–“ ģžˆėŠ” 정볓 ė° ģ„¤ģ¹˜ėœ źø°ėŠ„ģ— ģ ‘ź·¼ķ•˜ė©“ģ„œ ģ ‘ź·¼ź¶Œķ•œģ— ėŒ€ķ•œ ź³ ģ§€ ė° ė™ģ˜ė„¼ 받지 ģ•Šź³  ģžˆėŠ” 경우","사딀 3 : ģŠ¤ė§ˆķŠøķ° ģ•±ģ˜ ģ ‘ź·¼ź¶Œķ•œģ— ėŒ€ķ•œ ė™ģ˜ė„¼ ė°›ģœ¼ė©“ģ„œ ģ„ ķƒģ‚¬ķ•­ģ— ķ•“ė‹¹ķ•˜ėŠ” ź¶Œķ•œģ„ ķ•„ģˆ˜ź¶Œķ•œģœ¼ė”œ ź³ ģ§€ķ•˜ģ—¬ ė™ģ˜ė„¼ ė°›ėŠ” 경우","사딀 4 : ģ ‘ź·¼ź¶Œķ•œģ— ėŒ€ķ•œ ź°œė³„ė™ģ˜ź°€ ė¶ˆź°€ėŠ„ķ•œ ģ•ˆė“œė”œģ“ė“œ 6.0 미만 ė²„ģ „ģ„ ģ§€ģ›ķ•˜ėŠ” ģŠ¤ė§ˆķŠøķ° ģ•±ģ„ ė°°ķ¬ķ•˜ė©“ģ„œ ģ„ ķƒģ  ģ ‘ź·¼ź¶Œķ•œģ„ ķ•Øź»˜ ģ„¤ģ •ķ•˜ģ—¬, ģ„ ķƒģ  ģ ‘ź·¼ź¶Œķ•œģ— ėŒ€ķ•˜ģ—¬ 거부할 수 ģ—†ė„ė” ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ģ •ė³“ķ†µģ‹ ė§ė²• 제22ģ”°ģ˜2(ģ ‘ź·¼ź¶Œķ•œģ— ėŒ€ķ•œ ė™ģ˜)"]}],"description": "정볓주첓(ģ“ģš©ģž)ģ˜ ģ“ė™ķ†µģ‹ ė‹Øė§ģž„ģ¹˜ 낓에 ģ €ģž„ė˜ģ–“ ģžˆėŠ” 정볓 ė° ģ“ė™ķ†µģ‹ ė‹Øė§ģž„ģ¹˜ģ— ģ„¤ģ¹˜ėœ źø°ėŠ„ģ— ģ ‘ź·¼ģ“ ķ•„ģš”ķ•œ 경우 ģ“ė„¼ ėŖ…ķ™•ķ•˜ź²Œ ģøģ§€ķ•  수 ģžˆė„ė” ģ•Œė¦¬ź³  정볓주첓(ģ“ģš©ģž)ģ˜ ė™ģ˜ė„¼ 받아야 ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.2.4": {"name": "ź°œģøģ •ė³“ 목적 외 ģ“ģš© ė° 제공","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.2.4 ź°œģøģ •ė³“ 목적 외 ģ“ģš© ė° 제공","Subdomain": "3.2. ź°œģøģ •ė³“ 볓유 ė° ģ“ģš© ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ 목적 외 ģ“ģš© ė° 제3ģž 제공 ė‚“ģ—­(ģš”ģ²­ģ„œ 등 ꓀련 ģ¦ź±°ģžė£Œ ķ¬ķ•Ø)","ź°œģøģ •ė³“ 목적 외 ģ“ģš© ė° 제3ģž 제공 ėŒ€ģž„(ź³µź³µźø°ź“€ģø 경우)","ķ™ˆķŽ˜ģ“ģ§€ ė˜ėŠ” ꓀볓 ź²Œģž¬ ė‚“ģ—­(ź³µź³µźø°ź“€ģø 경우)","ģžė£Œ 제공 ģš”ģ²­ ėŒ€ģ‘ 지침","ģžė£Œ 제공 ģš”ģ²­ 공문 ė° ź°œģøģ •ė³“ ģ œź³µė‚“ģ—­, ėŒ€ģž„ 등"],"AuditChecklist": ["ź°œģøģ •ė³“ėŠ” 최쓈 ģˆ˜ģ§‘ ģ‹œ ģ •ė³“ģ£¼ģ²“ė”œė¶€ķ„° ė™ģ˜ė°›ģ€ 목적 ė˜ėŠ” 법령에 ź·¼ź±°ķ•œ ė²”ģœ„ ė‚“ģ—ģ„œė§Œ ģ“ģš©Ā·ģ œź³µķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ģ²˜ė¦¬ģžė”œė¶€ķ„° ź°œģøģ •ė³“ė„¼ ģ œź³µė°›ģ€ 경우 ģ œź³µė°›ģ€ ėŖ©ģ ģ˜ ė²”ģœ„ ė‚“ģ—ģ„œė§Œ ģ“ģš©Ā·ģ œź³µķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ 목적 ė˜ėŠ” ź°œģøģ •ė³“ģ²˜ė¦¬ģžė”œė¶€ķ„° ģ œź³µė°›ģ€ ėŖ©ģ ģ˜ ė²”ģœ„ė„¼ ģ“ˆź³¼ķ•˜ģ—¬ ģ“ģš©ķ•˜ź±°ė‚˜ ģ œź³µķ•˜ėŠ” 경우 ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ė³„ė„ģ˜ ė™ģ˜ė„¼ ė°›ź±°ė‚˜ 법적 근거가 ģžˆėŠ” 경우딜 ģ œķ•œķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ 목적 ģ™øģ˜ ģš©ė„ė”œ 제3ģžģ—ź²Œ ģ œź³µķ•˜ėŠ” 경우 ģ œź³µė°›ėŠ” ģžģ—ź²Œ ģ“ģš©ėŖ©ģ  ė° 방법 ė“±ģ„ ģ œķ•œķ•˜ź±°ė‚˜ ģ•ˆģ „ģ„± 확볓넼 ģœ„ķ•˜ģ—¬ ķ•„ģš”ķ•œ 씰치넼 ė§ˆė Øķ•˜ė„ė” ģš”ģ²­ķ•˜ź³  ģžˆėŠ”ź°€?","ź³µź³µźø°ź“€ģ“ ź°œģøģ •ė³“ė„¼ 목적 ģ™øģ˜ ģš©ė„ė”œ ģ“ģš©ķ•˜ź±°ė‚˜ 제3ģžģ—ź²Œ ģ œź³µķ•˜ėŠ” 경우 ź·ø ģ“ģš© ė˜ėŠ” ģ œź³µģ˜ 법적 근거, 목적 ė° ė²”ģœ„ 등에 ź“€ķ•˜ģ—¬ ķ•„ģš”ķ•œ ģ‚¬ķ•­ģ„ ꓀볓 ė˜ėŠ” ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ 등에 ź²Œģž¬ķ•˜ź³  ģžˆėŠ”ź°€?","공공기꓀ ė“±ģ“ ź°œģøģ •ė³“ė„¼ 목적 ģ™øģ˜ ģš©ė„ė”œ ģ“ģš©ķ•˜ź±°ė‚˜ 제3ģžģ—ź²Œ ģ œź³µķ•˜ėŠ” 경우 목적 외 ģ“ģš© ė° 제3ģž ģ œź³µėŒ€ģž„ģ— źø°ė”Ā·ź“€ė¦¬ķ•˜ėŠ” 등 절차넼 ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģƒķ’ˆė°°ģ†”ģ„ 목적으딜 ģˆ˜ģ§‘ķ•œ ź°œģøģ •ė³“ė„¼ 사전에 ė™ģ˜ 받지 ģ•Šģ€ ģžģ‚¬ ģƒķ’ˆģ˜ ķ†µģ‹ ķŒė§¤ ꓑ고에 ģ“ģš©ķ•œ 경우","사딀 2 : ź³ ź° ė§Œģ”±ė„ 씰사, ź²½ķ’ˆ 행사에 ģ‘ėŖØķ•˜źø° ģœ„ķ•˜ģ—¬ ģˆ˜ģ§‘ķ•œ ź°œģøģ •ė³“ė„¼ ģžģ‚¬ģ˜ ķ• ģøķŒė§¤ķ–‰ģ‚¬ ģ•ˆė‚“ģš© ź“‘ź³  ė°œģ†”ģ— ģ“ģš©ķ•œ 경우","사딀 3 : ź³µź³µźø°ź“€ģ“ 다넸 법넠에 ź·¼ź±°ķ•˜ģ—¬ ėÆ¼ģ›ģøģ˜ ź°œģøģ •ė³“ė„¼ 목적 ģ™øė”œ ķƒ€ 기꓀에 ģ œź³µķ•˜ė©“ģ„œ ꓀련 ģ‚¬ķ•­ģ„ ꓀볓 ė˜ėŠ” ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ģ— ź²Œģ‹œķ•˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ź³µź³µźø°ź“€ģ“ 범죄 ģˆ˜ģ‚¬ģ˜ 목적으딜 ź²½ģ°°ģ„œģ— ź°œģøģ •ė³“ė„¼ ģ œź³µķ•˜ė©“ģ„œ Ź»ź°œģøģ •ė³“ 목적 외 ģ“ģš© ė° 제3ģž 제공 ėŒ€ģž„Ź¼ģ— ꓀련 ģ‚¬ķ•­ģ„ źø°ė”ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제18ģ”°(ź°œģøģ •ė³“ģ˜ 목적 외 ģ“ģš©Ā·ģ œź³µ ģ œķ•œ), 제19ģ”°(ź°œģøģ •ė³“ė„¼ ģ œź³µė°›ģ€ ģžģ˜ ģ“ģš©Ā·ģ œź³µ ģ œķ•œ)"]}],"description": "ź°œģøģ •ė³“ėŠ” ģˆ˜ģ§‘ ģ‹œģ˜ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ź³ ģ§€Ā·ė™ģ˜ė„¼ ė°›ģ€ 목적 ė˜ėŠ” 법령에 ź·¼ź±°ķ•œ ė²”ģœ„ ė‚“ģ—ģ„œė§Œ ģ“ģš© ė˜ėŠ” ģ œź³µķ•˜ģ—¬ģ•¼ ķ•˜ė©°, ģ“ė„¼ ģ“ˆź³¼ķ•˜ģ—¬ ģ“ģš©Ā·ģ œź³µķ•˜ė ¤ėŠ” ė•Œģ—ėŠ” ģ •ė³“ģ£¼ģ²“ģ˜ 추가 ė™ģ˜ė„¼ ė°›ź±°ė‚˜ ꓀계 법령에 따넸 ģ ė²•ķ•œ ź²½ģš°ģøģ§€ ķ™•ģøķ•˜ź³  ģ ģ ˆķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.2.5": {"name": "가명정볓 처리","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.2.5 가명정볓 처리","Subdomain": "3.2. ź°œģøģ •ė³“ 볓유 ė° ģ“ģš© ģ‹œ 볓호씰치","AuditEvidence": ["ź°€ėŖ…ģ²˜ė¦¬Ā·ģµėŖ…ģ²˜ė¦¬ 적정성 ķ‰ź°€ 절차 ė° ź²°ź³¼","가명정볓 처리 źø°ė”","ź°œģøģ •ė³“ 처리방침(가명정볓 ģ“ģš©Ā·ģ œź³µģ— ź“€ķ•œ 사항) 등"],"AuditChecklist": ["가명정볓넼 ģ²˜ė¦¬ķ•˜ėŠ” 경우 목적 ģ œķ•œ, ź°€ėŖ…ģ²˜ė¦¬ 방법 ė° 기준, 적정성 검토, ģž¬ģ‹ė³„ źøˆģ§€ ė° ģž¬ģ‹ė³„ ė°œģƒ ģ‹œ ģ”°ģ¹˜ģ‚¬ķ•­ 등 가명정볓넼 ģ ģ •ķ•˜ź²Œ ģ²˜ė¦¬ķ•˜źø° ģœ„ķ•œ 절차넼 ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ ź°€ėŖ…ģ²˜ė¦¬ķ•˜ģ—¬ ģ“ģš©Ā·ģ œź³µ ģ‹œ 추가 ģ •ė³“ģ˜ ģ‚¬ģš©Ā·ź²°ķ•© ģ—†ģ“ėŠ” ź°œģøģ„ ģ•Œģ•„ė³¼ 수 ģ—†ė„ė” ģ ģ •ķ•œ ģˆ˜ģ¤€ģœ¼ė”œ ź°€ėŖ…ģ²˜ė¦¬ė„¼ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","다넸 ź°œģøģ •ė³“ģ²˜ė¦¬ģžģ™€ 가명정볓넼 ź²°ķ•©ķ•˜ėŠ” 경우 결합전문기꓀ ė˜ėŠ” ė°ģ“ķ„°ģ „ė¬øźø°ź“€ģ„ 통핓 ź²°ķ•©ķ•˜ź³  ģžˆėŠ”ź°€?","가명정볓넼 ģ²˜ė¦¬ķ•˜ėŠ” 경우 추가 정볓넼 ģ‚­ģ œ ė˜ėŠ” ė³„ė„ė”œ ė¶„ė¦¬ķ•˜ģ—¬ 볓꓀·꓀리, ꓀련 źø°ė”ģ˜ ģž‘ģ„±Ā·ė³“ź“€ 등 ģ•ˆģ „ģ„± 확볓에 ķ•„ģš”ķ•œ źø°ģˆ ģ Ā·ź“€ė¦¬ģ  ė° 물리적 씰치넼 ķ•˜ź³  ģžˆėŠ”ź°€?","가명정볓 처리목적 ė“±ģ„ ź³ ė ¤ķ•˜ģ—¬ ź°€ėŖ…ģ •ė³“ģ˜ 처리 źø°ź°„ģ„ ģ ģ •ķ•œ źø°ź°„ģœ¼ė”œ ģ •ķ•˜ź³  ģžˆģœ¼ė©°, 핓당 źø°ź°„ģ“ ź²½ź³¼ķ•œ 경우 지첓 ģ—†ģ“ ķŒŒźø°ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ ģµėŖ…ģ²˜ė¦¬ķ•˜ėŠ” 경우 ģ‹œź°„Ā·ė¹„ģš©Ā·źø°ģˆ  ė“±ģ„ ķ•©ė¦¬ģ ģœ¼ė”œ 고려할 ė•Œ 다넸 정볓넼 ģ‚¬ģš©ķ•˜ģ—¬ė„ ė” ģ“ģƒ ķŠ¹ģ • ź°œģøģ„ ģ•Œģ•„ė³¼ 수 ģ—†ė„ė” ģ ģ •ķ•œ ģˆ˜ģ¤€ģœ¼ė”œ ģµėŖ…ģ²˜ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķ†µź³„ģž‘ģ„± ė° 과학적 연구넼 ģœ„ķ•˜ģ—¬ 정볓주첓 ė™ģ˜ ģ—†ģ“ 가명정볓넼 ģ²˜ė¦¬ķ•˜ė©“ģ„œ 가명정볓 ģ²˜ė¦¬ģ— ź“€ķ•œ źø°ė”ģ„ 남기고 ģžˆģ§€ ģ•Šź±°ė‚˜, ė˜ėŠ” ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ꓀련 ģ‚¬ķ•­ģ„ ź³µź°œķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : 가명정볓와 ė™ģ¼ķ•œ ė°ģ“ķ„°ė² ģ“ģŠ¤ 낓에 추가 정볓넼 ė¶„ė¦¬ķ•˜ģ§€ ģ•Šź³  ė³“ź“€ķ•˜ź³  ģžˆź±°ė‚˜, ė˜ėŠ” 가명 정볓와 추가 정볓에 ėŒ€ķ•œ ģ ‘ź·¼ź¶Œķ•œģ“ ģ ģ ˆķžˆ ė¶„ė¦¬ė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ź°œģøģ •ė³“ė„¼ ź°€ėŖ…ģ²˜ė¦¬ķ•˜ģ—¬ ķ™œģš©ķ•˜ź³  ģžˆģœ¼ė‚˜ ģ ģ •ķ•œ ģˆ˜ģ¤€ģ˜ ź°€ėŖ…ģ²˜ė¦¬ź°€ ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ•„ 추가 ģ •ė³“ģ˜ ģ‚¬ģš© ģ—†ģ“ė„ 다넸 ģ •ė³“ģ™€ģ˜ ź²°ķ•© ė“±ģ„ ķ†µķ•˜ģ—¬ ķŠ¹ģ • ź°œģøģ„ ģ•Œģ•„ė³¼ 수 ģžˆėŠ” ź°€ėŠ„ģ„±ģ“ ģ”“ģž¬ķ•˜ėŠ” 경우","사딀 4 : ķ…ŒģŠ¤ķŠø ė°ģ“ķ„° ģƒģ„±, 외부 공개 ė“±ģ„ ģœ„ķ•˜ģ—¬ ź°œģøģ •ė³“ė„¼ ģµėŖ…ģ²˜ė¦¬ķ•˜ģ˜€ģœ¼ė‚˜, ķŠ¹ģ“ģ¹˜ ė“±ģœ¼ė”œ ģøķ•˜ģ—¬ ķŠ¹ģ • ź°œģøģ— ėŒ€ķ•œ ģ‹ė³„ź°€ėŠ„ģ„±ģ“ ģ”“ģž¬ķ•˜ėŠ” 등 ģµėŖ…ģ²˜ė¦¬ź°€ ģ ģ •ķ•˜ź²Œ ģˆ˜ķ–‰ė˜ģ—ˆė‹¤ź³  볓기 ģ–“ė ¤ģš“ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제2ģ”°(ģ •ģ˜), 제28ģ”°ģ˜2(ź°€ėŖ…ģ •ė³“ģ˜ 처리 등), 제28ģ”°ģ˜3(ź°€ėŖ…ģ •ė³“ģ˜ ź²°ķ•© ģ œķ•œ), 제28ģ”°ģ˜4(가명정볓에 ėŒ€ķ•œ ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“ 등), 제28ģ”°ģ˜5(가명정볓 처리 ģ‹œ źøˆģ§€ģ˜ė¬“ 등), 제28ģ”°ģ˜7(ģ ģš©ė²”ģœ„), 제58ģ”°ģ˜2(ģ ģš©ģ œģ™ø)"]}],"description": "가명정볓넼 ģ²˜ė¦¬ķ•˜ėŠ” 경우 ėŖ©ģ ģ œķ•œ, ź²°ķ•©ģ œķ•œ, ģ•ˆģ „ģ”°ģ¹˜, źøˆģ§€ģ˜ė¬“ 등 법적 ģš”ź±“ģ„ ģ¤€ģˆ˜ķ•˜ź³  적정 ģˆ˜ģ¤€ģ˜ ź°€ėŖ…ģ²˜ė¦¬ė„¼ ė³“ģž„ķ•  수 ģžˆė„ė” ź°€ėŖ…ģ²˜ė¦¬ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.3.1": {"name": "ź°œģøģ •ė³“ 제3ģž 제공","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.3.1 ź°œģøģ •ė³“ 제3ģž 제공","Subdomain": "3.3. ź°œģøģ •ė³“ 제공 ģ‹œ 볓호씰치","AuditEvidence": ["ģ˜Øė¼ģø ź°œģøģ •ė³“ 제3ģž 제공 ꓀련 ģ–‘ģ‹(ķ™ˆķŽ˜ģ“ģ§€ ķšŒģ›ź°€ģž… 화멓, ź°œģøģ •ė³“ 제3ģž 제공 ė™ģ˜ 화멓 등)","ģ˜¤ķ”„ė¼ģø ź°œģøģ •ė³“ 제3ģž 제공 ꓀련 ģ–‘ģ‹(ķšŒģ›ź°€ģž…ģ‹ ģ²­ģ„œ, ź°œģøģ •ė³“ 제3ģž 제공 ė™ģ˜ģ„œ 등)","제3ģž 제공 ė‚“ģ—­","ź°œģøģ •ė³“ 처리방침"],"AuditChecklist": ["ź°œģøģ •ė³“ė„¼ 제3ģžģ—ź²Œ ģ œź³µķ•˜ėŠ” 경우 정볓주첓 ė™ģ˜, ė²•ė ¹ģƒ ģ˜ė¬“ģ¤€ģˆ˜ 등 적법 ģš”ź±“ģ„ ėŖ…ķ™•ķžˆ ģ‹ė³„ķ•˜ź³  ģ“ė„¼ ģ¤€ģˆ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ź°œģøģ •ė³“ 제3ģž 제공 ė™ģ˜ė„¼ ė°›ėŠ” 경우 ꓀련 ģ‚¬ķ•­ģ„ ėŖ…ķ™•ķ•˜ź²Œ ź³ ģ§€ķ•˜ź³  다넸 ė™ģ˜ģ‚¬ķ•­ź³¼ źµ¬ė¶„ķ•˜ģ—¬ ģ ė²•ķ•˜ź²Œ ė™ģ˜ė„¼ 받고 ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ź°œģøģ •ė³“ 제3ģž 제공 ė™ģ˜ė„¼ ė°›ėŠ” 경우 ꓀련 ė‚“ģš©ģ„ ėŖ…ķ™•ķ•˜ź²Œ ź³ ģ§€ķ•˜ź³  ė²•ė ¹ģ—ģ„œ ģ •ķ•œ ģ¤‘ģš”ķ•œ ė‚“ģš©ģ— ėŒ€ķ•“ ėŖ…ķ™•ķžˆ ķ‘œģ‹œķ•˜ģ—¬ ģ•Œģ•„ė³“źø° ģ‰½ź²Œ ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ 제3ģžģ—ź²Œ ģ œź³µķ•˜ėŠ” 경우 제공 목적에 ė§žėŠ” ģµœģ†Œķ•œģ˜ ź°œģøģ •ė³“ ķ•­ėŖ©ģœ¼ė”œ ģ œķ•œķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ 제3ģžģ—ź²Œ ģ œź³µķ•˜ėŠ” 경우 ģ•ˆģ „ķ•œ ģ ˆģ°Øģ™€ ė°©ė²•ģ„ 통핓 ģ œź³µķ•˜ź³  제공 ė‚“ģ—­ģ„ źø°ė”ķ•˜ģ—¬ ė³“ź“€ķ•˜ź³  ģžˆėŠ”ź°€?","제3ģžģ—ź²Œ ź°œģøģ •ė³“ģ˜ ģ ‘ź·¼ģ„ ķ—ˆģš©ķ•˜ėŠ” 경우 ź°œģøģ •ė³“ė„¼ ģ•ˆģ „ķ•˜ź²Œ ė³“ķ˜øķ•˜źø° ģœ„ķ•œ ė³“ķ˜øģ ˆģ°Øģ— ė”°ė¼ ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ ģ—†ģ“ ź°œģøģ •ė³“ģ˜ ģ¶”ź°€ģ ģø 제공 ģ‹œ ė‹¹ģ“ˆ ģˆ˜ģ§‘ ėŖ©ģ ź³¼ģ˜ ꓀련성, ģ˜ˆģø”ź°€ėŠ„ģ„±, ģ“ģµ 침핓 여부, ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ ė“±ģ˜ 고려사항에 ėŒ€ķ•œ ķŒė‹Øźø°ģ¤€ģ„ 수립 ė° ģ“ķ–‰ķ•˜ź³ , ģ¶”ź°€ģ ģø ģ œź³µģ“ ģ§€ģ†ģ ģœ¼ė”œ ė°œģƒķ•˜ėŠ” 경우 고려사항에 ėŒ€ķ•œ ķŒė‹Øźø°ģ¤€ģ„ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź³µź°œķ•˜ź³  ģ“ė„¼ ģ ź²€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ģ²˜ė¦¬ģžź°€ ź°œģøģ •ė³“ 제3ģž 제공 ė™ģ˜ė„¼ ė°›ģ„ ė•Œ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ź³ ģ§€ķ•˜ėŠ” 사항 중에 ģ¼ė¶€ 사항(ė™ģ˜ ź±°ė¶€ź¶Œ, ģ œź³µķ•˜ėŠ” ķ•­ėŖ© 등)ģ„ ėˆ„ė½ķ•œ 경우","사딀 2 : ź°œģøģ •ė³“ė„¼ 제3ģžģ—ź²Œ ģ œź³µķ•˜ėŠ” ź³¼ģ •ģ—ģ„œ 제3ģž 제공 ė™ģ˜ 여부넼 ģ ģ ˆķžˆ ķ™•ģøķ•˜ģ§€ ėŖ»ķ•˜ģ—¬ ė™ģ˜ķ•˜ģ§€ ģ•Šģ€ ģ •ė³“ģ£¼ģ²“ģ˜ ź°œģøģ •ė³“ź°€ ķ•Øź»˜ 제공된 경우","사딀 3 : ź°œģøģ •ė³“ė„¼ 제공 ė™ģ˜ė„¼ ė°›ģ„ ė•Œ, ģ œź³µė°›ėŠ” ģžė„¼ ķŠ¹ģ •ķ•˜ģ§€ ģ•Šź³  Ź»~ 등ʼ과 ź°™ģ“ ķ¬ź“„ģ ģœ¼ė”œ ģ•ˆė‚“ķ•˜ź³  ė™ģ˜ė„¼ ė°›ģ€ 경우","사딀 4 : ķšŒģ› ź°€ģž… ė‹Øź³„ģ—ģ„œ ģ„ ķƒģ‚¬ķ•­ģœ¼ė”œ 제3ģž 제공 ė™ģ˜ė„¼ 받고 ģžˆģœ¼ė‚˜, 제3ģž ģ œź³µģ— ė™ģ˜ķ•˜ģ§€ ģ•Šģœ¼ė©“ ķšŒģ› ź°€ģž… ģ ˆģ°Øź°€ ė” ģ“ģƒ ģ§„ķ–‰ė˜ģ§€ ģ•Šė„ė” ė˜ģ–“ ģžˆėŠ” 경우","사딀 5 : ģ œź³µė°›ėŠ” ģžģ˜ ģ“ģš© 목적과 ꓀련 ģ—†ģ“ ģ§€ė‚˜ģ¹˜ź²Œ ė§Žģ€ ź°œģøģ •ė³“ė„¼ ģ œź³µķ•˜ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제17ģ”°(ź°œģøģ •ė³“ģ˜ 제공), 제22ģ”°(ė™ģ˜ė„¼ ė°›ėŠ” 방법)","ź°œģøģ •ė³“ 처리 방법에 ź“€ķ•œ ź³ ģ‹œ"]}],"description": "ź°œģøģ •ė³“ė„¼ 제3ģžģ—ź²Œ ģ œź³µķ•˜ėŠ” 경우 법적 근거에 ģ˜ķ•˜ź±°ė‚˜ ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ė„¼ 받아야 ķ•˜ė©°, 제3ģžģ—ź²Œ ź°œģøģ •ė³“ģ˜ ģ ‘ź·¼ģ„ ķ—ˆģš©ķ•˜ėŠ” 등 제공 ź³¼ģ •ģ—ģ„œ ź°œģøģ •ė³“ė„¼ ģ•ˆģ „ķ•˜ź²Œ ė³“ķ˜øķ•˜źø° ģœ„ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.3.2": {"name": "ź°œģøģ •ė³“ 처리 업묓 ģœ„ķƒ","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.3.2 ź°œģøģ •ė³“ 처리 업묓 ģœ„ķƒ","Subdomain": "3.3. ź°œģøģ •ė³“ 제공 ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ 처리방침(ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ ģœ„ķƒ ꓀련 공개 ė‚“ģ—­)","ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹","ź°œģøģ •ė³“ 처리 ģœ„ķƒ ź³„ģ•½ģ„œ","ģž¬ķ™” ė˜ėŠ” ģ„œė¹„ģŠ¤ ķ™ė³“Ā·ķŒė§¤ 권유 업묓 ģœ„ķƒ ꓀련 정볓주첓 통지 ė‚“ģ—­"],"AuditChecklist": ["ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ė„¼ 제3ģžģ—ź²Œ ģœ„ķƒ(ģž¬ģœ„ķƒ ķ¬ķ•Ø)ķ•˜ėŠ” 경우 ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ 등에 ģœ„ķƒķ•˜ėŠ” ģ—…ė¬“ģ˜ ė‚“ģš©ź³¼ ģˆ˜ķƒģžė„¼ ķ˜„ķ–‰ķ™”ķ•˜ģ—¬ ź³µź°œķ•˜ź³  ģžˆėŠ”ź°€?","ģž¬ķ™” ė˜ėŠ” ģ„œė¹„ģŠ¤ė„¼ ķ™ė³“ķ•˜ź±°ė‚˜ 판매넼 ź¶Œģœ ķ•˜ėŠ” 업묓넼 ģœ„ķƒķ•˜ėŠ” ź²½ģš°ģ—ėŠ” ģ„œė©“, ģ „ģžģš°ķŽø, ė¬øģžģ „ģ†” ė“±ģ˜ ė°©ė²•ģœ¼ė”œ ģœ„ķƒķ•˜ėŠ” ģ—…ė¬“ģ˜ ė‚“ģš©ź³¼ ģˆ˜ķƒģžė„¼ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķ™ˆķŽ˜ģ“ģ§€ ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ ģœ„ķƒ ģ‚¬ķ•­ģ„ ź³µź°œķ•˜ź³  ģžˆģœ¼ė‚˜, ģ¼ė¶€ ģˆ˜ķƒģžģ™€ ģœ„ķƒķ•˜ėŠ” ģ—…ė¬“ģ˜ ė‚“ģš©ģ“ ėˆ„ė½ėœ 경우","사딀 2 : ģž¬ķ™” ė˜ėŠ” ģ„œė¹„ģŠ¤ė„¼ ķ™ė³“ķ•˜ź±°ė‚˜ 판매넼 ź¶Œģœ ķ•˜ėŠ” 업묓넼 ģœ„ķƒķ•˜ė©“ģ„œ, ģœ„ķƒķ•˜ėŠ” ģ—…ė¬“ģ˜ ė‚“ģš©ź³¼ ģˆ˜ķƒģžė„¼ ģ„œė©“ė“±ģ˜ ė°©ė²•ģœ¼ė”œ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ģ§€ ģ•Šź³  ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź³µź°œķ•˜ėŠ” 것으딜 ź°ˆģŒķ•œ 경우","사딀 3 : 기씓 ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ ģˆ˜ķƒģžģ™€ģ˜ 계약 핓지에 ė”°ė¼ ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ ģˆ˜ķƒģžź°€ ė³€ź²½ė˜ģ—ˆģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•˜ģ—¬ ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— 지첓 ģ—†ģ“ ė°˜ģ˜ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ė„¼ ģœ„ķƒė°›ģ€ ģžź°€ 핓당 업묓넼 제3ģžģ—ź²Œ ģž¬ģœ„ķƒģ„ ķ•˜ź³  ģžˆģ§€ė§Œ, ģž¬ģœ„ķƒģ— ź“€ķ•œ ģ‚¬ķ•­ģ„ ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ 등에 ź³µź°œķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제26ģ”°(ģ—…ė¬“ģœ„ķƒģ— 따넸 ź°œģøģ •ė³“ģ˜ 처리 ģ œķ•œ)"]}],"description": "ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ė„¼ 제3ģžģ—ź²Œ ģœ„ķƒķ•˜ėŠ” 경우 ģœ„ķƒķ•˜ėŠ” ģ—…ė¬“ģ˜ ė‚“ģš©ź³¼ ģˆ˜ķƒģž 등 ź“€ė Øģ‚¬ķ•­ģ„ ź³µź°œķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ė˜ķ•œ ģž¬ķ™” ė˜ėŠ” ģ„œė¹„ģŠ¤ė„¼ ķ™ė³“ķ•˜ź±°ė‚˜ 판매넼 ź¶Œģœ ķ•˜ėŠ” 업묓넼 ģœ„ķƒķ•˜ėŠ” 경우 ģœ„ķƒķ•˜ėŠ” ģ—…ė¬“ģ˜ ė‚“ģš©ź³¼ ģˆ˜ķƒģžė„¼ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė ¤ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.3.3": {"name": "ģ˜ģ—…ģ˜ ģ–‘ė„ 등에 따넸 ź°œģøģ •ė³“ ģ“ģ „","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.3.3 ģ˜ģ—…ģ˜ ģ–‘ė„ 등에 따넸 ź°œģøģ •ė³“ ģ“ģ „","Subdomain": "3.3. ź°œģøģ •ė³“ 제공 ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ ģ“ģ „ ꓀련 정볓주첓 ź³ ģ§€ ė‚“ģ—­(ģ˜ģ—… ģ–‘ģˆ˜ė„ ģ‹œ)","ź°œģøģ •ė³“ 처리방침"],"AuditChecklist": ["ģ˜ģ—…ģ˜ ģ „ė¶€ ė˜ėŠ” ģ¼ė¶€ģ˜ ģ–‘ė„Ā·ķ•©ė³‘ ė“±ģœ¼ė”œ ź°œģøģ •ė³“ė„¼ 다넸 ģ‚¬ėžŒģ—ź²Œ ģ“ģ „ķ•˜ėŠ” 경우 ķ•„ģš”ķ•œ ģ‚¬ķ•­ģ„ 사전에 ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ ģ“ģ „ė°›ėŠ” ģžėŠ” 법적 통지 ģš”ź±“ģ— 핓당될 경우 ź°œģøģ •ė³“ė„¼ ģ“ģ „ė°›ģ€ 사실 등 ķ•„ģš”ķ•œ ģ‚¬ķ•­ģ„ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ 지첓 ģ—†ģ“ ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ ģ“ģ „ė°›ėŠ” ģžėŠ” ģ“ģ „ ė‹¹ģ‹œģ˜ ė³øėž˜ 목적으딜만 ź°œģøģ •ė³“ė„¼ ģ“ģš©ķ•˜ź±°ė‚˜ 제3ģžģ—ź²Œ ģ œź³µķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ģ²˜ė¦¬ģžź°€ ģ˜ģ—… ģ–‘ģˆ˜ė„¼ ķ†µķ•˜ģ—¬ ź°œģøģ •ė³“ė„¼ ģ“ģ „ė°›ģœ¼ė©“ģ„œ ģ–‘ė„ģžź°€ ź°œģøģ •ė³“ ģ“ģ „ ģ‚¬ģ‹¤ģ„ ģ•Œė¦¬ģ§€ ģ•Šģ•˜ģŒģ—ė„ ź°œģøģ •ė³“ ģ“ģ „ ģ‚¬ģ‹¤ģ„ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ģ§€ ģ•Šģ€ 경우","사딀 2 : ģ˜ģ—… ģ–‘ģˆ˜ė„ 등에 ģ˜ķ•˜ģ—¬ ź°œģøģ •ė³“ė„¼ ģ“ģ „ė°›ģœ¼ė©“ģ„œ 정볓주첓가 ģ“ģ „ģ„ ģ›ķ•˜ģ§€ ģ•Šģ€ 경우 ģ”°ģ¹˜ķ•  수 ģžˆėŠ” 방법과 절차넼 ė§ˆė Øķ•˜ģ§€ ģ•Šź±°ė‚˜, ģ“ė„¼ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제27ģ”°(ģ˜ģ—…ģ–‘ė„ 등에 따넸 ź°œģøģ •ė³“ģ˜ ģ“ģ „ ģ œķ•œ)"]}],"description": "ģ˜ģ—…ģ˜ ģ–‘ė„Ā·ķ•©ė³‘ ė“±ģœ¼ė”œ ź°œģøģ •ė³“ė„¼ ģ“ģ „ķ•˜ź±°ė‚˜ ģ“ģ „ė°›ėŠ” 경우 정볓주첓 통지 등 ģ ģ ˆķ•œ 볓호씰치넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.3.4": {"name": "ź°œģøģ •ė³“ źµ­ģ™øģ“ģ „","checks": {"s3_bucket_cross_region_replication": "FAIL"},"status": "FAIL","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.3.4 ź°œģøģ •ė³“ źµ­ģ™øģ“ģ „","Subdomain": "3.3. ź°œģøģ •ė³“ 제공 ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ 국외 ģ“ģ „ ꓀련 ė™ģ˜ ģ–‘ģ‹","ź°œģøģ •ė³“ 국외 ģ“ģ „ ꓀련 ź³„ģ•½ģ„œ","ź°œģøģ •ė³“ 처리방침","ź°œģøģ •ė³“ 국외 ģ²˜ė¦¬ģœ„ķƒĀ·ė³“ź“€ ꓀련 통지 ė˜ėŠ” 공개 ė‚“ģ—­"],"AuditChecklist": ["ź°œģøģ •ė³“ė„¼ źµ­ģ™øė”œ ģ“ģ „ķ•˜ėŠ” 경우 ģ •ė³“ģ£¼ģ²“ģ—ź²Œ 국외 ģ“ģ „ģ— ź“€ķ•œ ź³ ģ§€ ģ‚¬ķ•­ģ„ 모두 ģ•Œė¦¬ź³  ė³„ė„ ė™ģ˜ė„¼ ė°›ź±°ė‚˜, ģøģ¦ ė˜ėŠ” ģøģ • 등 적법 ģš”ź±“ģ„ ģ¤€ģˆ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ™€ģ˜ ź³„ģ•½ģ˜ 첓결 ė° ģ“ķ–‰ģ„ ģœ„ķ•œ ź°œģøģ •ė³“ģ˜ 국외 ģ²˜ė¦¬ģœ„ķƒĀ·ė³“ź“€ģ— ėŒ€ķ•“ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ėŠ” 경우 ķ•„ģš”ķ•œ ģ‚¬ķ•­ģ„ 모두 ķ¬ķ•Øķ•˜ģ—¬ ģ ģ ˆķ•œ ė°©ė²•ģœ¼ė”œ ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ 볓호 ꓀련 법령 ģ¤€ģˆ˜ ė° ź°œģøģ •ė³“ 볓호 등에 ź“€ķ•œ ģ‚¬ķ•­ģ„ ķ¬ķ•Øķ•˜ģ—¬ 국외 ģ“ģ „ģ— ź“€ķ•œ ź³„ģ•½ģ„ ģ²“ź²°ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ źµ­ģ™øė”œ ģ“ģ „ķ•˜ėŠ” 경우 ź°œģøģ •ė³“ 볓호넼 ģœ„ķ•˜ģ—¬ ķ•„ģš”ķ•œ 씰치넼 ģ·Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ė„¼ ģ²˜ė¦¬ķ•˜ėŠ” ź³¼ģ •ģ—ģ„œ 국외 ģ‚¬ģ—…ģžģ—ź²Œ ź°œģøģ •ė³“ 제3ģž ģ œź³µģ“ ė°œģƒķ•˜ģ˜€ģœ¼ė‚˜, ģøģ¦, ėŒ€ģƒźµ­ ģøģ • 등 ė™ģ˜ ģ˜ˆģ™ø ģš”ź±“ģ— ķ•“ė‹¹ė˜ģ§€ ģ•ŠģŒģ—ė„ ė¶ˆźµ¬ķ•˜ź³  ź°œģøģ •ė³“ 국외 ģ“ģ „ģ— ėŒ€ķ•œ ė³„ė„ ė™ģ˜ė„¼ 받지 ģ•Šģ€ 경우","사딀 2 : 국외 ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤(국외 리전)넼 ģ“ģš©ķ•˜ģ—¬ ź°œģøģ •ė³“ ģ²˜ė¦¬ģœ„ķƒ ė° ė³“ź“€ģ„ ķ•˜ė©“ģ„œ ģ“ģ „ė˜ėŠ” źµ­ź°€, ģ“ģ „ 방법 등 ꓀련 ģ‚¬ķ•­ģ„ ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź³µź°œķ•˜ź±°ė‚˜ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ģ§€ ģ•Šģ€ 경우","사딀 3 : ź°œģøģ •ė³“ 국외 ģ“ģ „ģ— ėŒ€ķ•œ ė™ģ˜ė„¼ ė°›ģœ¼ė©“ģ„œ ģ“ģ „ė°›ėŠ” ģžģ˜ ėŖ…ģ¹­(업첓명)만 ź³ ģ§€ķ•˜ź³  ģ“ģ „ė˜ėŠ” źµ­ź°€ 등에 ėŒ€ķ•˜ģ—¬ ģ•Œė¦¬ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제28ģ”°ģ˜8(ź°œģøģ •ė³“ģ˜ 국외 ģ“ģ „), 제28ģ”°ģ˜9(ź°œģøģ •ė³“ģ˜ 국외 ģ“ģ „ 중지 ėŖ…ė ¹), 제28ģ”°ģ˜10(ģƒķ˜øģ£¼ģ˜), 제28ģ”°ģ˜11(ģ¤€ģš©ź·œģ •)","ź°œģøģ •ė³“ 국외 ģ“ģ „ 욓영 등에 ź“€ķ•œ ź·œģ •"]}],"description": "ź°œģøģ •ė³“ė„¼ źµ­ģ™øė”œ ģ“ģ „ķ•˜ėŠ” 경우 국외 ģ“ģ „ģ— ėŒ€ķ•œ ė™ģ˜, ꓀련 사항에 ėŒ€ķ•œ 공개 등 ģ ģ ˆķ•œ 볓호씰치넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.4.1": {"name": "ź°œģøģ •ė³“ 파기","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.4.1 ź°œģøģ •ė³“ 파기","Subdomain": "3.4. ź°œģøģ •ė³“ 파기 ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ ė³“ģœ źø°ź°„ ė° 파기 ꓀련 ź·œģ •","ź°œģøģ •ė³“ 파기 ź²°ź³¼(ķšŒģ› ė°ģ“ķ„°ė² ģ“ģŠ¤ 등)","ź°œģøģ •ė³“ ķŒŒźø°ź“€ė¦¬ėŒ€ģž„"],"AuditChecklist": ["ź°œģøģ •ė³“ģ˜ ė³“ģœ źø°ź°„ ė° ķŒŒźø°ģ™€ ź“€ė Øėœ ė‚“ė¶€ ģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ģ˜ ģ²˜ė¦¬ėŖ©ģ ģ“ ė‹¬ģ„±ė˜ź±°ė‚˜ ė³“ģœ źø°ź°„ģ“ ź²½ź³¼ķ•œ 경우 지첓 ģ—†ģ“ 핓당 ź°œģøģ •ė³“ė„¼ ķŒŒźø°ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ ķŒŒźø°ķ•  ė•Œģ—ėŠ” ė³µźµ¬Ā·ģž¬ģƒė˜ģ§€ ģ•Šė„ė” ģ•ˆģ „ķ•œ ė°©ė²•ģœ¼ė”œ ķŒŒźø°ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ ķŒŒźø°ģ— ėŒ€ķ•œ źø°ė”ģ„ 남기고 ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķšŒģ› ķƒˆķ‡“ 등 ėŖ©ģ ģ“ ė‹¬ģ„±ė˜ź±°ė‚˜ ė³“ģœ źø°ź°„ģ“ 경과된 경우 ķšŒģ› ė°ģ“ķ„°ė² ģ“ģŠ¤ģ—ģ„œėŠ” 핓당 ź°œģøģ •ė³“ė„¼ ķŒŒźø°ķ•˜ģ˜€ģœ¼ė‚˜, CRMĀ·DW 등 ģ—°ź³„ėœ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— ė³µģ œė˜ģ–“ ģ €ģž„ė˜ģ–“ ģžˆėŠ” ź°œģøģ •ė³“ė„¼ ķŒŒźø°ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ķŠ¹ģ • źø°ź°„ ė™ģ•ˆ ģ“ė²¤ķŠøė„¼ ķ•˜ė©“ģ„œ ģˆ˜ģ§‘ėœ ź°œģøģ •ė³“ģ— ėŒ€ķ•˜ģ—¬ ģ“ė²¤ķŠøź°€ ģ¢…ė£Œėœ ģ“ķ›„ģ—ė„ 파기 źø°ģ¤€ģ“ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šź±°ė‚˜ ķŒŒźø°ź°€ ģ“ė£Øģ–“ģ§€ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģ½œģ„¼ķ„°ģ—ģ„œ ģˆ˜ģ§‘ė˜ėŠ” ėÆ¼ģ›ģ²˜ė¦¬ ꓀련 ź°œģøģ •ė³“(ģƒė‹“ģ“ė „, 녹취 등)넼 ģ „ģžģƒź±°ėž˜ė²•ģ„ 근거딜 3ė…„ź°„ ė³“ģ”“ķ•˜ź³  ģžˆģœ¼ė‚˜, 3ė…„ģ“ ź²½ź³¼ķ•œ ķ›„ģ—ė„ ķŒŒźø°ķ•˜ģ§€ ģ•Šź³  ė³“ź“€ķ•˜ź³  ģžˆėŠ” 경우","사딀 4 : ėø”ė”ģ²“ģø 등 기술적 ķŠ¹ģ„±ģœ¼ė”œ ģøķ•˜ģ—¬ ėŖ©ģ ģ“ ė‹¬ģ„±ėœ ź°œģøģ •ė³“ģ˜ 완전 ķŒŒźø°ź°€ ģ–“ė ¤ģ›Œ ģ™„ģ „ķŒŒźø° ėŒ€ģ‹  ģµėŖ…ģ²˜ė¦¬ė„¼ ķ•˜ģ˜€ģœ¼ė‚˜, ģµėŖ…ģ²˜ė¦¬ź°€ ģ ģ ˆķ•˜ź²Œ ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ•„ ģ¼ė¶€ ź°œģøģ •ė³“ģ˜ ģž¬ģ‹ė³„ 등 ė³µģ›ģ“ ź°€ėŠ„ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제21ģ”°(ź°œģøģ •ė³“ģ˜ 파기)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제13ģ”°(ź°œģøģ •ė³“ģ˜ 파기)"]}],"description": "ź°œģøģ •ė³“ģ˜ ė³“ģœ źø°ź°„ ė° 파기 ꓀련 ė‚“ė¶€ ģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ź°œģøģ •ė³“ģ˜ ė³“ģœ źø°ź°„ 경과, 처리목적 달성 등 파기 ģ‹œģ ģ“ ė„ė‹¬ķ•œ ė•Œģ—ėŠ” ķŒŒźø°ģ˜ ģ•ˆģ „ģ„± ė° ģ™„ģ „ģ„±ģ“ ė³“ģž„ė  수 ģžˆėŠ” ė°©ė²•ģœ¼ė”œ 지첓 ģ—†ģ“ ķŒŒźø°ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.4.2": {"name": "처리목적 달성 후 볓유 ģ‹œ 씰치","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.4.2 처리목적 달성 후 볓유 ģ‹œ 씰치","Subdomain": "3.4. ź°œģøģ •ė³“ 파기 ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ ė³“ģœ źø°ź°„ ė° 파기 ꓀련 ź·œģ •","분리 ė°ģ“ķ„°ė² ģ“ģŠ¤ ķ˜„ķ™©(ķ…Œģ“ėø” 구씰 등)","분리 ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ź¶Œķ•œ ķ˜„ķ™©"],"AuditChecklist": ["ź°œģøģ •ė³“ģ˜ ė³“ģœ źø°ź°„ 경과 ė˜ėŠ” 처리목적 달성 ķ›„ģ—ė„ ꓀련 법령 등에 ė”°ė¼ ķŒŒźø°ķ•˜ģ§€ ģ•Šź³  ė³“ģ”“ķ•˜ėŠ” 경우, ꓀련 법령에 따넸 ģµœģ†Œķ•œģ˜ źø°ź°„ģœ¼ė”œ ķ•œģ •ķ•˜ģ—¬ ģµœģ†Œķ•œģ˜ ģ •ė³“ė§Œģ„ ė³“ģ”“ķ•˜ė„ė” ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ģ˜ ė³“ģœ źø°ź°„ 경과 ė˜ėŠ” 처리목적 달성 ķ›„ģ—ė„ ꓀련 법령 등에 ė”°ė¼ ķŒŒźø°ķ•˜ģ§€ ģ•Šź³  ė³“ģ”“ķ•˜ėŠ” 경우 핓당 ź°œģøģ •ė³“ ė˜ėŠ” ź°œģøģ •ė³“ķŒŒģ¼ģ„ 다넸 ź°œģøģ •ė³“ģ™€ ė¶„ė¦¬ķ•˜ģ—¬ ģ €ģž„Ā·ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","분리 ė³“ź“€ķ•˜ź³  ģžˆėŠ” ź°œģøģ •ė³“ģ— ėŒ€ķ•˜ģ—¬ ė²•ė ¹ģ—ģ„œ ģ •ķ•œ 목적 ė²”ģœ„ ė‚“ģ—ģ„œė§Œ 처리 ź°€ėŠ„ķ•˜ė„ė” ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","분리 ė³“ź“€ķ•˜ź³  ģžˆėŠ” ź°œģøģ •ė³“ģ— ėŒ€ķ•˜ģ—¬ ģ ‘ź·¼ź¶Œķ•œģ„ ģµœģ†Œķ•œģ˜ ģøģ›ģœ¼ė”œ ģ œķ•œķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķƒˆķ‡“ķšŒģ› 정볓넼 ķŒŒźø°ķ•˜ģ§€ ģ•Šź³  ģ „ģžģƒź±°ėž˜ė²•ģ— ė”°ė¼ ģ¼ģ •źø°ź°„ ė³“ź“€ķ•˜ė©“ģ„œ Flagź°’ė§Œ ė³€ź²½ķ•˜ģ—¬ 다넸 ķšŒģ›ģ •ė³“ģ™€ ė™ģ¼ķ•œ ķ…Œģ“ėø”ģ— ė³“ź“€ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : ģ „ģžģƒź±°ėž˜ė²•ģ— 따넸 ģ†Œė¹„ģž 불만 ė° ė¶„ģŸģ²˜ė¦¬ģ— ź“€ķ•œ źø°ė”ģ— ėŒ€ķ•“ ꓀련 법적 ģš”ź±“ģ„ ģž˜ėŖ» ģ ģš©ķ•˜ģ—¬ 3ė…„ģ“ ģ•„ė‹Œ 5ė…„ź°„ ė³“ģ”“ķ•˜ė„ė” ģ •ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : 분리 ė°ģ“ķ„°ė² ģ“ģŠ¤ė„¼ źµ¬ģ„±ķ•˜ģ˜€ģœ¼ė‚˜ ģ ‘ź·¼ź¶Œķ•œģ„ ė³„ė„ė”œ ģ„¤ģ •ķ•˜ģ§€ ģ•Šģ•„ ģ—…ė¬“ģƒ ģ ‘ź·¼ģ“ ė¶ˆķ•„ģš”ķ•œ ģøģ›ė„ 분리 ė°ģ“ķ„°ė² ģ“ģŠ¤ģ— ģžģœ ė”­ź²Œ ģ ‘ź·¼ģ“ ź°€ėŠ„ķ•œ 경우","사딀 4 : ķƒˆķ‡“ķšŒģ› 정볓넼 ķŒŒźø°ķ•˜ģ§€ ģ•Šź³  ģ „ģžģƒź±°ėž˜ė²•ģ— ė”°ė¼ 계약 ė˜ėŠ” ģ²­ģ•½ģ² ķšŒ, ėŒ€źøˆź²°ģ œ ė° ģž¬ķ™” 공급에 ź“€ķ•œ źø°ė”ģ„ ė¶„ė¦¬ķ•˜ģ—¬ ė³“ģ”“ķ•˜ģ˜€ģœ¼ė‚˜, ģ „ģžģƒź±°ėž˜ė²•ģ— 따넸 ė³“ģ”“ģ˜ė¬“ź°€ ģ—†ėŠ” ģ„ ķƒģ •ė³“ź¹Œģ§€ ź³¼ė„ķ•˜ź²Œ ė³“ģ”“ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제21ģ”°(ź°œģøģ •ė³“ģ˜ 파기)"]}],"description": "ź°œģøģ •ė³“ģ˜ ė³“ģœ źø°ź°„ 경과 ė˜ėŠ” 처리목적 달성 ķ›„ģ—ė„ ꓀련 법령 등에 ė”°ė¼ ķŒŒźø°ķ•˜ģ§€ ģ•Šź³  ė³“ģ”“ķ•˜ėŠ” ź²½ģš°ģ—ėŠ” 핓당 목적에 ķ•„ģš”ķ•œ ģµœģ†Œķ•œģ˜ ķ•­ėŖ©ģœ¼ė”œ ģ œķ•œķ•˜ź³  다넸 ź°œģøģ •ė³“ģ™€ ė¶„ė¦¬ķ•˜ģ—¬ ģ €ģž„Ā·ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.5.1": {"name": "ź°œģøģ •ė³“ 처리방침 공개","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.5.1 ź°œģøģ •ė³“ 처리방침 공개","Subdomain": "3.5. 정볓주첓 권리볓호","AuditEvidence": ["ź°œģøģ •ė³“ 처리방침","ź°œģøģ •ė³“ 처리방침 ź°œģ • ꓀련 공지 ė‚“ģ—­(ź²Œģ‹œķŒ 등)"],"AuditChecklist": ["ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ„ ė²•ė ¹ģ—ģ„œ ģš”źµ¬ķ•˜ėŠ” ė‚“ģš©ģ„ 모두 ķ¬ķ•Øķ•˜ģ—¬ ģ•Œźø° ģ‰¬ģš“ ģš©ģ–“ė”œ źµ¬ģ²“ģ ģ“ź³  ėŖ…ķ™•ķ•˜ź²Œ ģž‘ģ„±ķ•˜ģ˜€ėŠ”ź°€?","ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ„ 정볓주첓가 ģ‰½ź²Œ ķ™•ģøķ•  수 ģžˆė„ė” ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ 등에 ģ§€ģ†ģ ģœ¼ė”œ ķ˜„ķ–‰ķ™”ķ•˜ģ—¬ ź³µź°œķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ“ ė³€ź²½ė˜ėŠ” 경우 ģ‚¬ģœ  ė° 변경 ė‚“ģš©ģ„ 지첓 ģ—†ģ“ ź³µģ§€ķ•˜ź³  정볓주첓가 ģ–øģ œė“ ģ§€ ė³€ź²½ėœ ģ‚¬ķ•­ģ„ ģ‰½ź²Œ ģ•Œģ•„ ė³¼ 수 ģžˆė„ė” ģ”°ģ¹˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź³µź°œė˜ģ–“ ģžˆėŠ” ź°œģøģ •ė³“ ģˆ˜ģ§‘, 제3ģž 제공 ė‚“ģ—­ģ“ ģ‹¤ģ œ ģˆ˜ģ§‘ ė° ģ œź³µķ•˜ėŠ” ė‚“ģ—­ź³¼ 다넸 경우","사딀 2 : ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ˜ 변경, ģˆ˜ķƒģž 변경 등 ź°œģøģ •ė³“ 처리방침 공개 ė‚“ģš© 중에 ė³€ź²½ģ‚¬ķ•­ģ“ ė°œģƒķ•˜ģ˜€ģŒģ—ė„ ģ“ė„¼ ė°˜ģ˜ķ•˜ģ—¬ ė³€ź²½ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ“ ź³µź°œėŠ” ė˜ģ–“ ģžˆģœ¼ė‚˜, ėŖ…ģ¹­ģ“ Ź»ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹ØŹ¼ģ“ ģ•„ė‹ˆė¼ Ź»ź°œģøģ •ė³“ ė³“ķ˜øģ •ģ±…Ź¼ģœ¼ė”œ ė˜ģ–“ ģžˆź³  źø€ģž 크기, ģƒ‰ģƒ ė“±ģ„ ķ™œģš©ķ•˜ģ—¬ 정볓주첓가 ģ‰½ź²Œ ģ°¾ģ„ 수 ģžˆė„ė” ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ“ ėŖ‡ 차딀 ź°œģ •ė˜ģ—ˆģœ¼ė‚˜, ģ˜ˆģ „ģ— ģž‘ģ„±ėœ ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ˜ ė‚“ģš©ģ„ ķ™•ģøķ•  수 ģžˆė„ė” ź³µź°œė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 5 : ģ „ģžģƒź±°ėž˜ė²•, ģƒė²• 등 다넸 법령에 ė”°ė¼ ź°œģøģ •ė³“ė„¼ ķŒŒźø°ķ•˜ģ§€ ģ•„ė‹ˆķ•˜ź³  ģ¼ģ •źø°ź°„ ė³“ź“€ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ“ģ— 따넸 볓씓근거와 ė³“ģ”“ķ•˜ėŠ” ź°œģøģ •ė³“ ķ•­ėŖ©ģ„ ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź³µź°œķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제30ģ”°(ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ˜ 수립 ė° 공개), 제30ģ”°ģ˜2(ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ˜ ķ‰ź°€ ė° ź°œģ„ ź¶Œź³ )"]}],"description": "ź°œģøģ •ė³“ģ˜ 처리 목적 등 ķ•„ģš”ķ•œ ģ‚¬ķ•­ģ„ 모두 ķ¬ķ•Øķ•˜ģ—¬ 정볓주첓가 ģ•Œźø° ģ‰½ė„ė” ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ„ ģˆ˜ė¦½ķ•˜ź³ , ģ“ė„¼ 정볓주첓가 ģ–øģ œė“ ģ§€ ģ‰½ź²Œ ķ™•ģøķ•  수 ģžˆė„ė” ģ ģ ˆķ•œ 방법에 ė”°ė¼ ź³µź°œķ•˜ź³  ģ§€ģ†ģ ģœ¼ė”œ ķ˜„ķ–‰ķ™”ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.5.2": {"name": "정볓주첓 ź¶Œė¦¬ė³“ģž„","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.5.2 정볓주첓 ź¶Œė¦¬ė³“ģž„","Subdomain": "3.5. 정볓주첓 권리볓호","AuditEvidence": ["ź°œģøģ •ė³“ 처리방침","ź°œģøģ •ė³“ ģ—“ėžŒė“±ģš”źµ¬ 처리 절차, ꓀련 ģ–‘ģ‹","ź°œģøģ •ė³“ ģ—“ėžŒė“±ģš”źµ¬ ģ‹œ 씰치 ė‚“ģ—­","ķšŒģ› ķƒˆķ‡“ ė° ė™ģ˜ 철회 절차"],"AuditChecklist": ["정볓주첓 ė˜ėŠ” ź·ø ėŒ€ė¦¬ģøģ“ ź°œģøģ •ė³“ģ— ėŒ€ķ•œ ģ—“ėžŒ, ģ •ģ •Ā·ģ‚­ģ œ, ģ²˜ė¦¬ģ •ģ§€ ė° ė™ģ˜ 철회 등(ģ“ķ•˜ 'ģ—“ėžŒė“±ģš”źµ¬'ė¼ 함)ģ„ ź°œģøģ •ė³“ ģˆ˜ģ§‘ė°©ė²•Ā·ģ ˆģ°Øė³“ė‹¤ 얓렵지 ģ•„ė‹ˆķ•˜ė„ė” 권리 행사 ė°©ė²•ė° 절차넼 ė§ˆė Øķ•˜ģ—¬ ź³µź°œķ•˜ź³  ģžˆėŠ”ź°€?","정볓주첓 ė˜ėŠ” ź·ø ėŒ€ė¦¬ģøģ“ ź°œģøģ •ė³“ ģ—“ėžŒė“±ģš”źµ¬ė„¼ ķ•˜ėŠ” 경우 źø°ź°„ 낓에 ģ—“ėžŒė“±ģš”źµ¬ģ— 따넸 ķ•„ģš”ķ•œ 씰치넼 ķ•˜ź³  ģžˆėŠ”ź°€?","정볓주첓 ė˜ėŠ” ź·ø ėŒ€ė¦¬ģøģ“ ź°œģøģ •ė³“ ģˆ˜ģ§‘Ā·ģ“ģš©Ā·ģ œź³µ ė“±ģ˜ ė™ģ˜ė„¼ ģ² ķšŒķ•˜ėŠ” 경우 지첓 ģ—†ģ“ ģˆ˜ģ§‘ėœ ź°œģøģ •ė³“ė„¼ ķŒŒźø°ķ•˜ėŠ” 등 ķ•„ģš”ķ•œ 씰치넼 ģ·Øķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ˜ ģ—“ėžŒė“±ģš”źµ¬ģ— ėŒ€ķ•œ ģ”°ģ¹˜ģ— ė¶ˆė³µģ“ ģžˆėŠ” 경우 ģ“ģ˜ė„¼ ģ œźø°ķ•  수 ģžˆė„ė” ķ•„ģš”ķ•œ 절차넼 ė§ˆė Øķ•˜ģ—¬ ģ•ˆė‚“ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ˜ ģ—“ėžŒė“±ģš”źµ¬ ė° 처리 결과에 ėŒ€ķ•˜ģ—¬ źø°ė”ģ„ 남기고 ģžˆėŠ”ź°€?","ģ •ė³“ķ†µģ‹ ė§ģ—ģ„œ ģ‚¬ģƒķ™œ 침핓 ė˜ėŠ” ėŖ…ģ˜ˆķ›¼ģ† 등 ķƒ€ģøģ˜ 권리넼 ģ¹Øķ•“ķ•œ 경우 침핓넼 ė°›ģ€ ģžź°€ ģ •ė³“ķ†µģ‹ ģ„œė¹„ģŠ¤ ģ œź³µģžģ—ź²Œ ģ •ė³“ģ˜ ģ‚­ģ œ ģš”ģ²­ ė“±ģ„ ķ•  수 ģžˆėŠ” 절차넼 ė§ˆė Øķ•˜ģ—¬ ģ‹œķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ģ˜ ģ—“ėžŒ, ģ •ģ •Ā·ģ‚­ģ œ, ģ²˜ė¦¬ģ •ģ§€ ģš”źµ¬ ė°©ė²•ģ„ 정볓주첓가 ģ•Œ 수 ģžˆė„ė” ź³µź°œķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ź°œģøģ •ė³“ģ˜ ģ—“ėžŒ ģš”źµ¬ģ— ėŒ€ķ•˜ģ—¬ ģ •ė‹¹ķ•œ ģ‚¬ģœ ģ˜ 통지 ģ—†ģ“ ģ—“ėžŒ ģš”źµ¬ė„¼ ģ ‘ģˆ˜ė°›ģ€ ė‚ ė”œė¶€ķ„° 10ģ¼ģ„ ģ“ˆź³¼ķ•˜ģ—¬ ķšŒģ‹ ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : ź°œģøģ •ė³“ģ˜ ģ—“ėžŒ 민원에 ėŒ€ķ•œ 처리 ė‚“ģ—­ źø°ė” ė° ė³“ź“€ģ“ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우","사딀 4 : 정볓주첓 ė‹¹ģ‚¬ģž ė˜ėŠ” ģ •ė‹¹ķ•œ ėŒ€ė¦¬ģøģ“ ė§žėŠ”ģ§€ģ— ėŒ€ķ•œ ķ™•ģø 절차 ģ—†ģ“ ģ—“ėžŒ 통지가 ģ“ė£Øģ–“ģ§€ėŠ” 경우","사딀 5 : ź°œģøģ •ė³“ģ˜ ģ •ģ •Ā·ģ‚­ģ œ ģš”źµ¬ģ— ėŒ€ķ•˜ģ—¬ ģ •ģ •Ā·ģ‚­ģ œ ģš”źµ¬ė„¼ ģ ‘ģˆ˜ė°›ģ€ ė‚ ė”œė¶€ķ„° 10ģ¼ģ„ ģ“ˆź³¼ķ•˜ģ—¬ ķšŒģ‹ ķ•˜ėŠ” 경우","사딀 6 : ķšŒģ› ź°€ģž… ģ‹œģ—ėŠ” ģ˜Øė¼ģøģ„ ķ†µķ•˜ģ—¬ ģ‰½ź²Œ ķšŒģ› ź°€ģž…ģ“ ź°€ėŠ„ķ•˜ģ˜€ģœ¼ė‚˜, ķšŒģ› ķƒˆķ‡“ ģ‹œģ—ėŠ” ģ‹ ė¶„ģ¦ 등 추가 ģ„œė„˜ė„¼ ģ œģ¶œķ•˜ź²Œ ķ•˜ź±°ė‚˜ ģ˜¤ķ”„ė¼ģø ė°©ė¬øģ„ ķ†µķ•“ģ„œė§Œ ź°€ėŠ„ķ•˜ė„ė” ķ•˜ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제34ģ”°ģ˜2(ė…øģ¶œėœ ź°œģøģ •ė³“ģ˜ ģ‚­ģ œĀ·ģ°Øė‹Ø), 제35ģ”°(ź°œģøģ •ė³“ģ˜ ģ—“ėžŒ), 제35ģ”°ģ˜2(ź°œģøģ •ė³“ģ˜ 전솔 ģš”źµ¬), 제36ģ”°(ź°œģøģ •ė³“ģ˜ ģ •ģ •Ā·ģ‚­ģ œ), 제37ģ”°(ź°œģøģ •ė³“ģ˜ ģ²˜ė¦¬ģ •ģ§€ 등), 제37ģ”°ģ˜2(ģžė™ķ™”ėœ 결정에 ėŒ€ķ•œ ģ •ė³“ģ£¼ģ²“ģ˜ 권리 등), 제38ģ”°(ź¶Œė¦¬ķ–‰ģ‚¬ģ˜ 방법 ė° 절차)","ģ •ė³“ķ†µģ‹ ė§ė²• 제44ģ”°(ģ •ė³“ķ†µģ‹ ė§ģ—ģ„œģ˜ 권리볓호), 제44ģ”°ģ˜2(ģ •ė³“ģ˜ ģ‚­ģ œģš”ģ²­ 등), 제44ģ”°ģ˜3(ģž„ģ˜ģ˜ ģž„ģ‹œģ”°ģ¹˜)"]}],"description": "정볓주첓가 ź°œģøģ •ė³“ģ˜ ģ—“ėžŒ, ģ •ģ •Ā·ģ‚­ģ œ, ģ²˜ė¦¬ģ •ģ§€, ģ“ģ˜ģ œźø°, ė™ģ˜ģ² ķšŒ 등 ģš”źµ¬ė„¼ ģˆ˜ģ§‘ ė°©ė²•Ā·ģ ˆģ°Øė³“ė‹¤ ģ‰½ź²Œ ķ•  수 ģžˆė„ė” ź¶Œė¦¬ķ–‰ģ‚¬ 방법 ė° 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ , ģ •ė³“ģ£¼ģ²“ģ˜ ģš”źµ¬ė„¼ ė°›ģ€ 경우 지첓 ģ—†ģ“ ģ²˜ė¦¬ķ•˜ź³  ꓀련 źø°ė”ģ„ 남겨야 ķ•œė‹¤. ė˜ķ•œ ģ •ė³“ģ£¼ģ²“ģ˜ ģ‚¬ģƒķ™œ 침핓, ėŖ…ģ˜ˆķ›¼ģ† 등 ķƒ€ģøģ˜ 권리넼 ģ¹Øķ•“ķ•˜ėŠ” 정볓가 ģœ ķ†µė˜ģ§€ ģ•Šė„ė” ģ‚­ģ œģš”ģ²­, ģž„ģ‹œģ”°ģ¹˜ ė“±ģ˜ źø°ģ¤€ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.5.3": {"name": "정볓주첓에 ėŒ€ķ•œ 통지","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.5.3 정볓주첓에 ėŒ€ķ•œ 통지","Subdomain": "3.5. 정볓주첓 권리볓호","AuditEvidence": ["ź°œģøģ •ė³“ ģ“ģš©Ā·ģ œź³µ ė‚“ģ—­ 통지 źø°ė”","ź°œģøģ •ė³“ ģ“ģš©Ā·ģ œź³µ ė‚“ģ—­ 통지 ģ–‘ģ‹ ė° 문구"],"AuditChecklist": ["법적 ģ˜ė¬“ ėŒ€ģƒģžģ— ķ•“ė‹¹ķ•˜ėŠ” 경우 ź°œģøģ •ė³“ ģ“ģš©Ā·ģ œź³µ ė‚“ģ—­ ė˜ėŠ” ź·ø ė‚“ģ—­ģ„ ķ™•ģøķ•  수 ģžˆėŠ” ģ •ė³“ģ‹œģŠ¤ķ…œģ— ģ ‘ģ†ķ•˜ėŠ” ė°©ė²•ģ„ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ 주기적으딜 ķ†µģ§€ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ ģ“ģš©Ā·ģ œź³µ ė‚“ģ—­ 통지 ķ•­ėŖ©ģ€ 법적 ģš”źµ¬ķ•­ėŖ©ģ„ 모두 ķ¬ķ•Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ „ė…„ė„ 말 기준 직전 3ź°œģ›” ź°„ ģ¼ģ¼ ķ‰ź·  ģ €ģž„Ā·ź“€ė¦¬ķ•˜ź³  ģžˆėŠ” ź°œģøģ •ė³“ź°€ 100ė§ŒėŖ… ģ“ģƒģœ¼ė”œģ„œ ź°œģøģ •ė³“ ģ“ģš©ģ œź³µ ė‚“ģ—­ 통지 ģ˜ė¬“ ėŒ€ģƒģžģ— 핓당 ėØģ—ė„ ė¶ˆźµ¬ķ•˜ź³  źøˆė…„ė„ģ— ź°œģøģ •ė³“ ģ“ģš© ė°ė‚“ģ—­ģ„ ķ†µģ§€ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ź°œģøģ •ė³“ ģ“ģš©Ā·ģ œź³µ ė‚“ģ—­ģ„ ź°œė³„ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ§ģ ‘ģ ģœ¼ė”œ ķ†µģ§€ķ•˜ėŠ” ėŒ€ģ‹  ķ™ˆķŽ˜ģ“ģ§€ģ—ģ„œ ė‹Øģˆœ ķŒģ—…ģ°½ģ“ė‚˜ ė³„ė„ ź³µģ§€ģ‚¬ķ•­ģœ¼ė”œ ģ•ˆė‚“ė§Œ ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제20ģ”°ģ˜2(ź°œģøģ •ė³“ ģ“ģš©Ā·ģ œź³µ ė‚“ģ—­ģ˜ 통지)"]}],"description": "ź°œģøģ •ė³“ģ˜ ģ“ģš©Ā·ģ œź³µ ė‚“ģ—­ 등 ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ķ†µģ§€ķ•˜ģ—¬ģ•¼ ķ•  ģ‚¬ķ•­ģ„ ķŒŒģ•…ķ•˜ģ—¬ ź·ø ė‚“ģš©ģ„ 주기적으딜 ķ†µģ§€ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.10.1": {"name": "ė³“ģ•ˆģ‹œģŠ¤ķ…œ 욓영","checks": {"kms_cmk_are_used": null,"macie_is_enabled": "PASS","securityhub_enabled": "PASS","fms_policy_compliant": null,"guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","elbv2_waf_acl_attached": "FAIL","kms_cmk_rotation_enabled": null,"ec2_securitygroup_not_used": "FAIL","guardduty_centrally_managed": "FAIL","wafv2_webacl_logging_enabled": "FAIL","ssm_managed_compliant_patching": "FAIL","kms_key_not_publicly_accessible": null,"ssmincidents_enabled_with_plans": null,"inspector2_active_findings_exist": "FAIL","cloudfront_distributions_using_waf": null,"cognito_user_pool_waf_acl_attached": null,"trustedadvisor_errors_and_warnings": null,"apigateway_restapi_waf_acl_attached": "FAIL","config_recorder_all_regions_enabled": null,"guardduty_no_high_severity_findings": "FAIL","ec2_securitygroup_from_launch_wizard": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","organizations_delegated_administrators": null,"ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_instance_port_ftp_exposed_to_internet": "PASS","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","secretsmanager_automatic_rotation_enabled": "FAIL","ec2_instance_port_cifs_exposed_to_internet": "PASS","ec2_instance_port_ldap_exposed_to_internet": "PASS","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_instance_port_kafka_exposed_to_internet": "PASS","ec2_instance_port_mysql_exposed_to_internet": "PASS","ec2_instance_port_redis_exposed_to_internet": "PASS","ec2_instance_port_oracle_exposed_to_internet": "PASS","ec2_instance_port_telnet_exposed_to_internet": "PASS","ec2_instance_port_mongodb_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_instance_port_kerberos_exposed_to_internet": "PASS","ec2_instance_port_cassandra_exposed_to_internet": "PASS","ec2_instance_port_memcached_exposed_to_internet": "PASS","ec2_instance_port_sqlserver_exposed_to_internet": "PASS","cloudwatch_log_metric_filter_sign_in_without_mfa": null,"ec2_instance_port_postgresql_exposed_to_internet": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","shield_advanced_protection_in_global_accelerators": null,"ec2_instance_internet_facing_with_instance_profile": "FAIL","shield_advanced_protection_in_route53_hosted_zones": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_authentication_failures": null,"shield_advanced_protection_in_associated_elastic_ips": null,"shield_advanced_protection_in_classic_load_balancers": null,"shield_advanced_protection_in_cloudfront_distributions": null,"ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","ec2_instance_port_elasticsearch_kibana_exposed_to_internet": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","shield_advanced_protection_in_internet_facing_load_balancers": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.1 ė³“ģ•ˆģ‹œģŠ¤ķ…œ 욓영","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["ė³“ģ•ˆģ‹œģŠ¤ķ…œ 구성","ė„¤ķŠøģ›Œķ¬ 구성","ė³“ģ•ˆģ‹œģŠ¤ķ…œ 욓영절차","방화벽 ģ •ģ±…","방화벽 ģ •ģ±… 설정·변경 ģš”ģ²­ģ„œ","ė³“ģ•ˆģ‹œģŠ¤ķ…œ ģ˜ˆģ™øģž ėŖ©ė”","ė³“ģ•ˆģ‹œģŠ¤ķ…œė³„ ꓀리 화멓(방화벽, IPS, ģ„œė²„ģ ‘ź·¼ģ œģ–“, DLP, DRM 등)","ė³“ģ•ˆģ‹œģŠ¤ķ…œ ģ •ģ±… 검토 ģ“ė „"],"AuditChecklist": ["ģ”°ģ§ģ—ģ„œ ģš“ģ˜ķ•˜ź³  ģžˆėŠ” ė³“ģ•ˆģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ 욓영절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ģ•ˆģ‹œģŠ¤ķ…œ ź“€ė¦¬ģž 등 ģ ‘ź·¼ģ“ ķ—ˆģš©ėœ ģøģ›ģ„ ģµœģ†Œķ™”ķ•˜ź³  ė¹„ģøź°€ģžģ˜ ģ ‘ź·¼ģ„ ģ—„ź²©ķ•˜ź²Œ ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ģ•ˆģ‹œģŠ¤ķ…œė³„ė”œ ģ •ģ±…ģ˜ ģ‹ ź·œ ė“±ė”, 변경, ģ‚­ģ œ ė“±ģ„ ģœ„ķ•œ ź³µģ‹ģ ģø 절차넼 수립 ė° ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ģ•ˆģ‹œģŠ¤ķ…œģ˜ ģ˜ˆģ™ø ģ •ģ±… ė“±ė”ģ— ėŒ€ķ•˜ģ—¬ ģ ˆģ°Øģ— ė”°ė¼ ź“€ė¦¬ķ•˜ź³  ģžˆģœ¼ė©°, ģ˜ˆģ™ø ģ •ģ±… ģ‚¬ģš©ģžģ— ėŒ€ķ•˜ģ—¬ ģµœģ†Œķ•œģ˜ ź¶Œķ•œģœ¼ė”œ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ģ•ˆģ‹œģŠ¤ķ…œģ— ģ„¤ģ •ėœ ģ •ģ±…ģ˜ ķƒ€ė‹¹ģ„± 여부넼 주기적으딜 ź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ė¶ˆė²•ģ ģø ģ ‘ź·¼ ė° ź°œģøģ •ė³“ 유출 방지넼 ģœ„ķ•˜ģ—¬ ꓀련 ė²•ė ¹ģ—ģ„œ ģ •ķ•œ źø°ėŠ„ģ„ ģˆ˜ķ–‰ķ•˜ėŠ” ė³“ģ•ˆģ‹œģŠ¤ķ…œģ„ ģ„¤ģ¹˜ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ¹Øģž…ģ°Øė‹Øģ‹œģŠ¤ķ…œ ė³“ģ•ˆģ •ģ±…ģ— ėŒ€ķ•œ ģ •źø° 검토가 ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ•„ ė¶ˆķ•„ģš”ķ•˜ź±°ė‚˜ ź³¼ė„ķ•˜ź²Œ ķ—ˆģš©ėœ ģ •ģ±…ģ“ ė‹¤ģˆ˜ ģ”“ģž¬ķ•˜ėŠ” 경우","사딀 2 : ė³“ģ•ˆģ‹œģŠ¤ķ…œ ė³“ģ•ˆģ •ģ±…ģ˜ ģ‹ ģ²­, 변경, ģ‚­ģ œ, 주기적 검토에 ėŒ€ķ•œ 절차 ė° źø°ģ¤€ģ“ ģ—†ź±°ė‚˜, ģ ˆģ°ØėŠ” ģžˆģœ¼ė‚˜ ģ“ė„¼ ģ¤€ģˆ˜ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ė³“ģ•ˆģ‹œģŠ¤ķ…œģ˜ ź“€ė¦¬ģž 지정 ė° ź¶Œķ•œ 부여 ķ˜„ķ™©ģ— ėŒ€ķ•œ ź“€ė¦¬ź°ė…ģ“ ģ ģ ˆķžˆ ģ“ķ–‰ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ė‚“ė¶€ ģ§€ģ¹Øģ—ėŠ” ģ •ė³“ė³“ķ˜øė‹“ė‹¹ģžź°€ ė³“ģ•ˆģ‹œģŠ¤ķ…œģ˜ ė³“ģ•ˆģ •ģ±… 변경 ģ“ė „ģ„ źø°ė”Ā·ė³“ź“€ķ•˜ė„ė” ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ •ģ±…ź“€ė¦¬ėŒ€ģž„ģ„ 주기적으딜 ģž‘ģ„±ķ•˜ģ§€ ģ•Šź³  ģžˆź±°ė‚˜ ģ •ģ±…ź“€ė¦¬ėŒ€ģž„ģ— źø°ė”ėœ ė³“ģ•ˆģ •ģ±…ź³¼ ģ‹¤ģ œ 욓영 ģ¤‘ģø ģ‹œģŠ¤ķ…œģ˜ ė³“ģ•ˆģ •ģ±…ģ“ ģƒģ“ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "ė³“ģ•ˆģ‹œģŠ¤ķ…œ ģœ ķ˜•ė³„ė”œ ź“€ė¦¬ģž 지정, ģµœģ‹  ģ •ģ±… ģ—…ė°ģ“ķŠø, 룰셋 변경, ģ“ė²¤ķŠø ėŖØė‹ˆķ„°ė§ ė“±ģ˜ 욓영절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ė³“ģ•ˆģ‹œģŠ¤ķ…œė³„ ģ •ģ±…ģ ģš© ķ˜„ķ™©ģ„ ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 16,"pass": 39,"total": 75,"manual": 0}},"2.10.2": {"name": "ķ“ė¼ģš°ė“œ ė³“ģ•ˆ","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.2 ķ“ė¼ģš°ė“œ ė³“ģ•ˆ","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ꓀련 ź³„ģ•½ģ„œ ė° SLA","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ģœ„ķ—˜ė¶„ģ„ ź²°ź³¼","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ė³“ģ•ˆķ†µģ œ ģ •ģ±…","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ź“€ė¦¬ģž ź¶Œķ•œ 부여 ķ˜„ķ™©","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ źµ¬ģ„±ė„","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ė³“ģ•ˆģ„¤ģ • ķ˜„ķ™©","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ė³“ģ•ˆģ„¤ģ • 적정성 검토 ģ“ė „"],"AuditChecklist": ["ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ģ œź³µģžģ™€ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜øģ— ėŒ€ķ•œ ģ±…ģž„ź³¼ ģ—­ķ• ģ„ ėŖ…ķ™•ķžˆģ •ģ˜ķ•˜ź³  ģ“ė„¼ ź³„ģ•½ģ„œ(SLA 등)에 ė°˜ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ģ“ģš© ģ‹œ ģ„œė¹„ģŠ¤ ģœ ķ˜•ģ— 따넸 ė³“ģ•ˆģœ„ķ—˜ģ„ ķ‰ź°€ķ•˜ģ—¬ ė¹„ģøź°€ ģ ‘ź·¼,ģ„¤ģ •ģ˜¤ė„˜ ė“±ģ„ 방지할 수 ģžˆė„ė” ė³“ģ•ˆ 구성 ė° 설정 기준, ė³“ģ•ˆģ„¤ģ • 변경 ė° ģŠ¹ģø 절차, ģ•ˆģ „ķ•œ ģ ‘ģ†ė°©ė²•, ź¶Œķ•œ 첓계 등 ė³“ģ•ˆ ķ†µģ œ ģ •ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ź“€ė¦¬ģž ź¶Œķ•œģ€ 역할에 ė”°ė¼ ģµœģ†Œķ™”ķ•˜ģ—¬ ė¶€ģ—¬ķ•˜ź³  ź“€ė¦¬ģž ź¶Œķ•œģ— ėŒ€ķ•œė¹„ģøź°€ ģ ‘ź·¼, ź¶Œķ•œ ģ˜¤Ā·ė‚Øģš© ė“±ģ„ 방지할 수 ģžˆė„ė” ź°•ķ™”ėœ ģøģ¦, ģ•”ķ˜øķ™”, ģ ‘ź·¼ķ†µģ œ, ź°ģ‚¬źø°ė” 등 ė³“ķ˜øėŒ€ģ±…ģ„ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ģ˜ ė³“ģ•ˆ 설정 변경, 욓영 ķ˜„ķ™© ė“±ģ„ ėŖØė‹ˆķ„°ė§ķ•˜ź³  ź·ø ģ ģ ˆģ„±ģ„ ģ •źø°ģ ģœ¼ė”œź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ź³„ģ•½ģ„œ 낓에 ė³“ģ•ˆģ— ėŒ€ķ•œ ģ±…ģž„ ė° ģ—­ķ•  등에 ėŒ€ķ•œ ģ‚¬ķ•­ģ“ ķ¬ķ•Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ģ˜ ė³“ģ•ˆģ„¤ģ •ģ„ 변경할 수 ģžˆėŠ” ź¶Œķ•œģ“ ģ—…ė¬“ģƒ ė°˜ė“œģ‹œ ķ•„ģš”ķ•˜ģ§€ ģ•Šģ€ ģ§ģ›ė“¤ģ—ź²Œ ź³¼ė„ķ•˜ź²Œ ė¶€ģ—¬ė˜ģ–“ ģžˆėŠ” 경우","사딀 3 : ė‚“ė¶€ ģ§€ģ¹Øģ—ėŠ” ķ“ė¼ģš°ė“œ ė‚“ 사설 ė„¤ķŠøģ›Œķ¬ģ˜ ģ ‘ź·¼ķ†µģ œ 룰(Rule) 변경 ģ‹œ ė³“ģ•ˆģ±…ģž„ģž ģŠ¹ģøģ„ ė°›ė„ė” ķ•˜ź³  ģžˆģœ¼ė‚˜, ģŠ¹ģøģ ˆģ°Øė„¼ ź±°ģ¹˜ģ§€ ģ•Šź³  ė“±ė”Ā·ė³€ź²½ėœ ģ ‘ź·¼ģ œģ–“ ė£°ģ“ ė‹¤ģˆ˜ 발견된 경우","사딀 4 : ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ģ˜ ė³“ģ•ˆģ„¤ģ • 오넘딜 ė‚“ė¶€ 딜그 ķŒŒģ¼ģ“ ģøķ„°ė„·ģ„ ķ†µķ•˜ģ—¬ ź³µź°œė˜ģ–“ ģžˆėŠ” 경우"],"RelatedRegulations": []}],"description": "ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ģ“ģš© ģ‹œ ģ„œė¹„ģŠ¤ ģœ ķ˜•(SaaS, PaaS, IaaS 등)에 따넸 ė¹„ģøź°€ ģ ‘ź·¼, 설정 오넘 등에 ė”°ė¼ ģ¤‘ģš”ģ •ė³“ģ™€ ź°œģøģ •ė³“ź°€ ģœ Ā·ė…øģ¶œė˜ģ§€ ģ•Šė„ė” ź“€ė¦¬ģž ģ ‘ź·¼ ė° ė³“ģ•ˆ 설정 등에 ėŒ€ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.10.3": {"name": "ź³µź°œģ„œė²„ ė³“ģ•ˆ","checks": {"elb_ssl_listeners": "FAIL","elbv2_ssl_listeners": "FAIL","ssm_document_secrets": "PASS","elbv2_waf_acl_attached": "FAIL","elb_insecure_ssl_ciphers": "PASS","apigateway_restapi_public": "FAIL","lightsail_database_public": null,"lightsail_instance_public": null,"elbv2_insecure_ssl_ciphers": "PASS","lightsail_static_ip_unused": null,"networkfirewall_in_all_vpc": "FAIL","ec2_instance_imdsv2_enabled": "PASS","elbv2_desync_mitigation_mode": "FAIL","awslambda_function_inside_vpc": "FAIL","awslambda_function_url_public": null,"ec2_instance_secrets_user_data": "PASS","ec2_launch_template_no_secrets": "PASS","ssm_managed_compliant_patching": "FAIL","inspector2_active_findings_exist": "FAIL","acm_certificates_expiration_check": "PASS","awslambda_function_url_cors_policy": null,"cloudfront_distributions_using_waf": null,"vpc_subnet_separate_private_public": "FAIL","apigateway_restapi_waf_acl_attached": "FAIL","apigatewayv2_api_authorizers_enabled": "FAIL","awslambda_function_no_secrets_in_code": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","apigateway_restapi_authorizers_enabled": "PASS","cloudfront_distributions_https_enabled": null,"ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","apigateway_restapi_public_with_authorizer": "FAIL","ec2_instance_port_ftp_exposed_to_internet": "PASS","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","awslambda_function_no_secrets_in_variables": "PASS","awslambda_function_not_publicly_accessible": "PASS","ec2_instance_port_cifs_exposed_to_internet": "PASS","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","route53_domains_privacy_protection_enabled": null,"ec2_instance_port_kafka_exposed_to_internet": "PASS","ec2_instance_port_mysql_exposed_to_internet": "PASS","ec2_instance_port_redis_exposed_to_internet": "PASS","ec2_instance_port_oracle_exposed_to_internet": "PASS","ec2_instance_port_telnet_exposed_to_internet": "PASS","apigateway_restapi_client_certificate_enabled": "FAIL","ec2_instance_port_mongodb_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_instance_port_kerberos_exposed_to_internet": "PASS","ec2_instance_port_cassandra_exposed_to_internet": "PASS","ec2_instance_port_memcached_exposed_to_internet": "PASS","ec2_instance_port_sqlserver_exposed_to_internet": "PASS","kafka_cluster_mutual_tls_authentication_enabled": null,"ec2_instance_port_postgresql_exposed_to_internet": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","autoscaling_find_secrets_ec2_launch_configuration": "PASS","ec2_instance_internet_facing_with_instance_profile": "FAIL","cloudfront_distributions_using_deprecated_ssl_protocols": null,"ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","ec2_instance_port_elasticsearch_kibana_exposed_to_internet": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.3 ź³µź°œģ„œė²„ ė³“ģ•ˆ","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„","ģ›¹ģ‚¬ģ“ķŠø ģ •ė³“ź³µź°œ 절차 ė° ė‚“ģ—­(ģ‹ ģ²­Ā·ģŠ¹ģøĀ·ź²Œģ‹œ ģ“ė „ 등)","ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ ė…øģ¶œ 여부 점검 ģ“ė „"],"AuditChecklist": ["ź³µź°œģ„œė²„ė„¼ ģš“ģ˜ķ•˜ėŠ” 경우 ģ“ģ— ėŒ€ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ź³µź°œģ„œė²„ėŠ” ė‚“ė¶€ ė„¤ķŠøģ›Œķ¬ģ™€ ė¶„ė¦¬ėœ DMZ ģ˜ģ—­ģ— ģ„¤ģ¹˜ķ•˜ź³  ģ¹Øģž…ģ°Øė‹Øģ‹œģŠ¤ķ…œ 등 ė³“ģ•ˆģ‹œģŠ¤ķ…œģ„ ķ†µķ•˜ģ—¬ ė³“ķ˜øķ•˜ź³  ģžˆėŠ”ź°€?","ź³µź°œģ„œė²„ģ— ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ė„¼ ź²Œģ‹œķ•˜ź±°ė‚˜ ģ €ģž„ķ•˜ģ—¬ģ•¼ ķ•  경우 ģ±…ģž„ģž ģŠ¹ģø 등 ķ—ˆź°€ ė° ź²Œģ‹œģ ˆģ°Øė„¼ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ”°ģ§ģ˜ ģ¤‘ģš”ģ •ė³“ź°€ ģ›¹ģ‚¬ģ“ķŠø ė° ģ›¹ģ„œė²„ė„¼ ķ†µķ•˜ģ—¬ ė…øģ¶œė˜ź³  ģžˆėŠ”ģ§€ 여부넼 주기적으딜 ķ™•ģøķ•˜ģ—¬ ģ¤‘ģš”ģ •ė³“ ė…øģ¶œģ„ ģøģ§€ķ•œ 경우 ģ“ė„¼ ģ¦‰ģ‹œ ģ°Øė‹Øķ•˜ėŠ” ė“±ģ˜ 씰치넼 ģ·Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģøķ„°ė„·ģ— 공개된 ģ›¹ģ‚¬ģ“ķŠøģ˜ ģ·Øģ•½ģ ģœ¼ė”œ ģøķ•˜ģ—¬ 구글 ź²€ģƒ‰ģ„ ķ†µķ•˜ģ—¬ ģ—“ėžŒ ź¶Œķ•œģ“ ģ—†ėŠ” ķƒ€ģøģ˜ ź°œģøģ •ė³“ģ— 접근할 수 ģžˆėŠ” 경우","사딀 2 : ģ›¹ģ‚¬ģ“ķŠøģ— ź°œģøģ •ė³“ė„¼ ź²Œģ‹œķ•˜ėŠ” 경우 ģŠ¹ģø 절차넼 ź±°ģ¹˜ė„ė” ė‚“ė¶€ ź·œģ •ģ“ ė§ˆė Øė˜ģ–“ ģžˆģœ¼ė‚˜, ģ“ė„¼ ģ¤€ģˆ˜ķ•˜ģ§€ ģ•Šź³  ź°œģøģ •ė³“ź°€ ź²Œģ‹œėœ 사딀가 ė‹¤ģˆ˜ ģ”“ģž¬ķ•œ 경우","사딀 3 : ź²Œģ‹œķŒ ė“±ģ˜ 웹 ģ‘ģš©ķ”„ė”œź·øėžØģ—ģ„œ ķƒ€ģøģ“ ģž‘ģ„±ķ•œ źø€ģ„ ģž„ģ˜ė”œ ģˆ˜ģ •Ā·ģ‚­ģ œķ•˜ź±°ė‚˜ ė¹„ė°€ė²ˆķ˜øė”œ 볓호된 źø€ģ„ ģ—“ėžŒķ•  수 ģžˆėŠ” 경우"],"RelatedRegulations": []}],"description": "외부 ė„¤ķŠøģ›Œķ¬ģ— ź³µź°œė˜ėŠ” ģ„œė²„ģ˜ 경우 ė‚“ė¶€ ė„¤ķŠøģ›Œķ¬ģ™€ ė¶„ė¦¬ķ•˜ź³  취약점 점검, ģ ‘ź·¼ķ†µģ œ, ģøģ¦, 정볓 ģˆ˜ģ§‘Ā·ģ €ģž„Ā·ź³µź°œ 절차 등 ź°•ķ™”ėœ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 19,"pass": 47,"total": 76,"manual": 0}},"2.10.4": {"name": "ģ „ģžź±°ėž˜ ė° ķ•€ķ…Œķ¬ ė³“ģ•ˆ","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.4 ģ „ģžź±°ėž˜ ė° ķ•€ķ…Œķ¬ ė³“ģ•ˆ","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["ģ „ģžź±°ėž˜ ė° ķ•€ķ…Œķ¬ ģ„œė¹„ģŠ¤ ė³“ķ˜øėŒ€ģ±…","ź²°ģ œģ‹œģŠ¤ķ…œ 연계 ģ‹œ ė³“ģ•ˆģ„± 검토 ź²°ź³¼"],"AuditChecklist": ["ģ „ģžź±°ėž˜ ė° ķ•€ķ…Œķ¬ ģ„œė¹„ģŠ¤ė„¼ ģ œź³µķ•˜ėŠ” 경우 ź±°ėž˜ģ˜ ģ•ˆģ „ģ„±ź³¼ 신뢰성 확볓넼 ģœ„ķ•œė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ „ģžź±°ėž˜ ė° ķ•€ķ…Œķ¬ ģ„œė¹„ģŠ¤ ģ œź³µģ„ ģœ„ķ•˜ģ—¬ ź²°ģ œģ‹œģŠ¤ķ…œ 등 외부 ģ‹œģŠ¤ķ…œź³¼ ģ—°ź³„ķ•˜ėŠ” 경우 ģ†”ģˆ˜ģ‹ ė˜ėŠ” ꓀련 ģ •ė³“ģ˜ 볓호넼 ģœ„ķ•œ ėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģ•ˆģ „ģ„±ģ„ ģ ź²€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ „ģžź²°ģ œėŒ€ķ–‰ģ—…ģ²“ģ™€ ģœ„ķƒ ź³„ģ•½ģ„ ė§ŗź³  연계넼 ķ•˜ģ˜€ģœ¼ė‚˜, ģ ģ ˆķ•œ ģøģ¦ ė° ģ ‘ź·¼ģ œķ•œ ģ—†ģ“ ķŠ¹ģ • URLģ„ ķ†µķ•˜ģ—¬ 결제 ꓀련 정볓가 모두 ķ‰ė¬øģœ¼ė”œ ģ „ģ†”ė˜ėŠ” 경우","사딀 2 : ģ „ģžź²°ģ œėŒ€ķ–‰ģ—…ģ²“ģ™€ 외부 연계 ģ‹œģŠ¤ķ…œģ“ ģ „ģš©ė§ģœ¼ė”œ ģ—°ź²°ė˜ģ–“ ģžˆģœ¼ė‚˜, 핓당 연계 ģ‹œģŠ¤ķ…œģ—ģ„œ ė‚“ė¶€ 업묓 ģ‹œģŠ¤ķ…œģœ¼ė”œģ˜ ģ ‘ź·¼ģ“ ģ¹Øģž…ģ°Øė‹Øģ‹œģŠ¤ķ…œ ė“±ģœ¼ė”œ ģ ģ ˆķžˆ ķ†µģ œė˜ģ§€ ģ•Šź³  ģžˆėŠ” 경우","사딀 3 : ė‚“ė¶€ ģ§€ģ¹Øģ—ėŠ” 외부 ķ•€ķ…Œķ¬ ģ„œė¹„ģŠ¤ 연계 ģ‹œ ģ •ė³“ė³“ķ˜øķŒ€ģ˜ ė³“ģ•ˆģ„± 검토넼 ė°›ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ģµœź·¼ģ— ģ‹ ź·œ ķ•€ķ…Œķ¬ ģ„œė¹„ģŠ¤ė„¼ ģ—°ź³„ķ•˜ė©“ģ„œ ģ¼ģ •ģƒ ģ“ģœ ė”œ ė³“ģ•ˆģ„± 검토넼 ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ģ „ģžź±°ėž˜ ė° ķ•€ķ…Œķ¬ ģ„œė¹„ģŠ¤ 제공 ģ‹œ ģ •ė³“ģœ ģ¶œģ“ė‚˜ ė°ģ“ķ„° ģ”°ģž‘Ā·ģ‚¬źø° ė“±ģ˜ 침핓사고 ģ˜ˆė°©ģ„ ģœ„ķ•˜ģ—¬ ģøģ¦Ā·ģ•”ķ˜øķ™” ė“±ģ˜ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³ , ź²°ģ œģ‹œģŠ¤ķ…œ 등 외부 ģ‹œģŠ¤ķ…œź³¼ 연계할 경우 ģ•ˆģ „ģ„±ģ„ ģ ź²€ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.10.5": {"name": "정볓전솔 ė³“ģ•ˆ","checks": {"elb_ssl_listeners": "FAIL","elbv2_ssl_listeners": "FAIL","elb_insecure_ssl_ciphers": "PASS","elbv2_insecure_ssl_ciphers": "PASS","rds_instance_transport_encrypted": "FAIL","s3_bucket_secure_transport_policy": "FAIL","glue_database_connections_ssl_enabled": null,"cloudfront_distributions_https_enabled": null,"sns_subscription_not_using_http_endpoints": "PASS","kafka_cluster_in_transit_encryption_enabled": null,"apigateway_restapi_client_certificate_enabled": "FAIL","kafka_cluster_mutual_tls_authentication_enabled": null,"directoryservice_radius_server_security_protocol": null,"cloudfront_distributions_using_deprecated_ssl_protocols": null,"elasticache_redis_cluster_in_transit_encryption_enabled": null,"opensearch_service_domains_https_communications_enforced": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.5 정볓전솔 ė³“ģ•ˆ","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["정볓전솔 ķ˜‘ģ•½ģ„œ ė˜ėŠ” ź³„ģ•½ģ„œ","정볓전솔 źø°ģˆ ķ‘œģ¤€","정볓전솔 ꓀련 źµ¬ģ„±ė„, ģøķ„°ķŽ˜ģ“ģŠ¤ ģ •ģ˜ģ„œ"],"AuditChecklist": ["외부 씰직에 ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ė„¼ 전솔할 경우 ģ•ˆģ „ķ•œ 전솔 ģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ģ—…ė¬“ģƒ 씰직 ź°„ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ė„¼ ģƒķ˜øźµķ™˜ķ•˜ėŠ” 경우 ģ•ˆģ „ķ•œ ģ „ģ†”ģ„ ģœ„ķ•œ ķ˜‘ģ•½ģ²“ź²° 등 ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ėŒ€ģ™ø 기꓀과 연계 ģ‹œ ģ „ģš©ė§ ė˜ėŠ” VPNģ„ ģ ģš©ķ•˜ź³  ģ¤‘ź³„ģ„œė²„ģ™€ ģøģ¦ģ„œ 적용 ė“±ģ„ ķ†µķ•˜ģ—¬ ģ•ˆģ „ķ•˜ź²Œ 정볓넼 ģ „ģ†”ķ•˜ź³  ģžˆģœ¼ė‚˜, 외부 기꓀별 연계 ģ‹œźø°, ė°©ģ‹, ė‹“ė‹¹ģž ė° ģ±…ģž„ģž, 연계 정볓, 법적 근거 등에 ėŒ€ķ•œ ķ˜„ķ™©ź“€ė¦¬ź°€ ģ ģ ˆķžˆ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šź³  ģžˆėŠ” 경우","사딀 2 : ģ¤‘ź³„ź³¼ģ •ģ—ģ„œģ˜ ģ•”ķ˜ø ķ•“ģ œ 구간 ė˜ėŠ” ģ·Øģ•½ķ•œ ģ•”ķ˜øķ™” ģ•Œź³ ė¦¬ģ¦˜(DES, 3DES) ģ‚¬ģš© 등에 ėŒ€ķ•œ ė³“ģ•ˆģ„± 검토, ė³“ģ•ˆķ‘œģ¤€ ė° ģ”°ģ¹˜ė°©ģ•ˆ 수립 등에 ėŒ€ķ•œ ķ˜‘ģ˜ź°€ ģ“ķ–‰ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "다넸 씰직에 ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ė„¼ 전솔할 경우 ģ•ˆģ „ķ•œ 전솔 ģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  씰직 ź°„ ķ•©ģ˜ė„¼ ķ†µķ•˜ģ—¬ ꓀리 ģ±…ģž„, 전솔방법, ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ 볓호넼 ģœ„ķ•œ 기술적 볓호씰치 ė“±ģ„ ķ˜‘ģ•½ķ•˜ź³  ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 5,"pass": 3,"total": 17,"manual": 0}},"2.10.6": {"name": "ģ—…ė¬“ģš© 단말기기 ė³“ģ•ˆ","checks": {"workspaces_volume_encryption_enabled": null,"appstream_fleet_maximum_session_duration": null,"appstream_fleet_session_disconnect_timeout": null,"workspaces_vpc_2private_1public_subnets_nat": null,"appstream_fleet_session_idle_disconnect_timeout": null,"appstream_fleet_default_internet_access_disabled": null},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.6 ģ—…ė¬“ģš© 단말기기 ė³“ģ•ˆ","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["ģ—…ė¬“ģš© 단말기 ė³“ģ•ˆķ†µģ œ 지침 ė° 절차","ģ—…ė¬“ģš© 단말기 ė“±ė”ķ˜„ķ™©","ģ—…ė¬“ģš© 단말기 ė³“ģ•ˆģ„¤ģ •","ģ—…ė¬“ģš© 단말기 źø°źø°ģøģ¦ ė° ģŠ¹ģø ģ“ė „","ģ—…ė¬“ģš© 단말기 ė³“ģ•ˆģ ź²€ ķ˜„ķ™©"],"AuditChecklist": ["PC, ė…øķŠøė¶, ź°€ģƒPC, ķƒœėø”ė¦æ 등 업묓에 ģ‚¬ģš©ė˜ėŠ” 단말기에 ėŒ€ķ•˜ģ—¬ źø°źø°ģøģ¦, ģŠ¹ģø, ģ ‘ź·¼ė²”ģœ„ 설정, źø°źø° ė³“ģ•ˆģ„¤ģ • ė“±ģ˜ ė³“ģ•ˆ ķ†µģ œ ģ •ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ—…ė¬“ģš© 단말기넼 ķ†µķ•˜ģ—¬ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ź°€ ģœ ģ¶œė˜ėŠ” ź²ƒģ„ ė°©ģ§€ķ•˜źø° ģœ„ķ•˜ģ—¬ ģžė£Œź³µģœ ķ”„ė”œź·øėžØ ģ‚¬ģš© źøˆģ§€, ź³µģœ ģ„¤ģ • ģ œķ•œ, ė¬“ģ„ ė§ ģ“ģš© ķ†µģ œ ė“±ģ˜ ģ •ģ±…ģ„ 수립 ė° ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ—…ė¬“ģš© ėŖØė°”ģ¼ źø°źø°ģ˜ 분실, ė„ė‚œ ė“±ģœ¼ė”œ ģøķ•œ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ˜ ģœ Ā·ė…øģ¶œģ„ ė°©ģ§€ķ•˜źø° ģœ„ķ•˜ģ—¬ ė³“ģ•ˆėŒ€ģ±…ģ„ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?","ģ—…ė¬“ģš© 단말기기에 ėŒ€ķ•œ ģ ‘ź·¼ķ†µģ œ ėŒ€ģ±…ģ˜ ģ ģ ˆģ„±ģ— ėŒ€ķ•˜ģ—¬ 주기적으딜 ģ ź²€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ—…ė¬“ģ ģø 목적으딜 ė…øķŠøė¶, ķƒœėø”ė¦æPC 등 ėŖØė°”ģ¼ 기기넼 ģ‚¬ģš©ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ—…ė¬“ģš© ėŖØė°”ģ¼ 기기에 ėŒ€ķ•œ ķ—ˆģš© 기준, ģ‚¬ģš© ė²”ģœ„, ģŠ¹ģø 절차, ģøģ¦ 방법 등에 ėŒ€ķ•œ ģ •ģ±…ģ“ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ėŖØė°”ģ¼ źø°źø° ė³“ģ•ˆź“€ė¦¬ ģ§€ģ¹Øģ—ģ„œėŠ” ėŖØė°”ģ¼ źø°źø°ģ˜ ģ—…ė¬“ģš© ģ‚¬ģš©ģ„ ģ›ģ¹™ģ ģœ¼ė”œ źøˆģ§€ķ•˜ź³  ķ•„ģš”ģ‹œ ģŠ¹ģø 절차넼 ķ†µķ•˜ģ—¬ ģ œķ•œėœ źø°ź°„ ė™ģ•ˆ ķ—ˆź°€ėœ ėŖØė°”ģ¼ 기기만 ģ‚¬ģš©ķ•˜ė„ė” ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, ķ—ˆź°€ėœ ėŖØė°”ģ¼ źø°źø°ź°€ ģ‹ė³„Ā·ź“€ė¦¬ė˜ģ§€ ģ•Šź³  ģŠ¹ģøė˜ģ§€ ģ•Šģ€ ėŖØė°”ģ¼ źø°źø°ģ—ģ„œė„ ė‚“ė¶€ ģ •ė³“ģ‹œģŠ¤ķ…œ ģ ‘ģ†ģ“ ź°€ėŠ„ķ•œ 경우","사딀 3 : ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ģ— ģ“ģš©ė˜ėŠ” ėŖØė°”ģ¼ 기기에 ėŒ€ķ•˜ģ—¬ ė¹„ė°€ė²ˆķ˜ø 설정 등 ė„ė‚œĀ·ė¶„ģ‹¤ģ— ėŒ€ķ•œ ė³“ķ˜øėŒ€ģ±…ģ“ ģ ģš©ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ė‚“ė¶€ ź·œģ •ģ—ģ„œėŠ” ģ—…ė¬“ģš© ė‹Øė§źø°ģ˜ ź³µģœ ķ“ė” ģ‚¬ģš©ģ„ źøˆģ§€ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•œ ģ£¼źø°ģ ģø ģ ź²€ģ“ ģ“ė£Øģ–“ģ§€ź³  ģžˆģ§€ ģ•Šģ•„ ė‹¤ģˆ˜ģ˜ ģ—…ė¬“ģš© ė‹Øė§źø°ģ—ģ„œ ź³¼ė„ķ•˜ź²Œ ź³µģœ ķ“ė”ė„¼ ģ„¤ģ •ķ•˜ģ—¬ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "PC, ėŖØė°”ģ¼ źø°źø° 등 단말기기넼 업묓 목적으딜 ė„¤ķŠøģ›Œķ¬ģ— ģ—°ź²°ķ•  경우 źø°źø° ģøģ¦ ė° ģŠ¹ģø, ģ ‘ź·¼ ė²”ģœ„, źø°źø° ė³“ģ•ˆģ„¤ģ • ė“±ģ˜ ģ ‘ź·¼ķ†µģ œ ėŒ€ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  주기적으딜 ģ ź²€ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"2.10.7": {"name": "ė³“ģ”°ģ €ģž„ė§¤ģ²“ ꓀리","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.7 ė³“ģ”°ģ €ģž„ė§¤ģ²“ ꓀리","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["ė³“ģ”°ģ €ģž„ė§¤ģ²“(USB, CD 등) 차단 ģ •ģ±…","ė³“ģ”°ģ €ģž„ė§¤ģ²“ ź“€ė¦¬ėŒ€ģž„","ė³“ģ”°ģ €ģž„ė§¤ģ²“ ģ‹¤ķƒœģ ź²€ ģ“ė „"],"AuditChecklist": ["ģ™øģž„ķ•˜ė“œ, USB메모리, CD 등 ė³“ģ”°ģ €ģž„ė§¤ģ²“ ģ·Øźø‰(ģ‚¬ģš©), 볓꓀, ķźø°, ģž¬ģ‚¬ģš©ģ— ėŒ€ķ•œ ģ •ģ±… ė° 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ģ”°ģ €ģž„ė§¤ģ²“ ė³“ģœ ķ˜„ķ™©, ģ‚¬ģš© ė° ź“€ė¦¬ģ‹¤ķƒœė„¼ 주기적으딜 ģ ź²€ķ•˜ź³  ģžˆėŠ”ź°€?","ģ£¼ģš” ģ •ė³“ģ‹œģŠ¤ķ…œģ“ ģœ„ģ¹˜ķ•œ ķ†µģ œźµ¬ģ—­, ģ¤‘ģš” ģ œķ•œźµ¬ģ—­ ė“±ģ—ģ„œ ė³“ģ”°ģ €ģž„ė§¤ģ²“ ģ‚¬ģš©ģ„ ģ œķ•œķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ģ”°ģ €ģž„ė§¤ģ²“ė„¼ ķ†µķ•œ ģ•…ģ„±ģ½”ė“œ 감염 ė° ģ¤‘ģš”ģ •ė³“ 유출 방지넼 ģœ„ķ•œ ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ ė˜ėŠ” ģ¤‘ģš”ģ •ė³“ź°€ ķ¬ķ•Øėœ ė³“ģ”°ģ €ģž„ė§¤ģ²“ė„¼ ģž źøˆģž„ģ¹˜ź°€ ģžˆėŠ” ģ•ˆģ „ķ•œ ģž„ģ†Œģ— ė³“ź“€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķ†µģ œźµ¬ģ—­ģø ģ„œė²„ģ‹¤ģ—ģ„œģ˜ ė³“ģ”°ģ €ģž„ė§¤ģ²“ ģ‚¬ģš©ģ„ ģ œķ•œķ•˜ėŠ” ģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ˜ˆģ™ø ģŠ¹ģø 절차넼 ģ¤€ģˆ˜ķ•˜ģ§€ ģ•Šź³  ė³“ģ”°ģ €ģž„ė§¤ģ²“ė„¼ ģ‚¬ģš©ķ•œ ģ“ė „ģ“ ė‹¤ģˆ˜ ķ™•ģøė˜ģ—ˆģœ¼ė©°, ė³“ģ”°ģ €ģž„ė§¤ģ²“ ź“€ė¦¬ģ‹¤ķƒœģ— ėŒ€ķ•œ 주기적 ģ ź²€ģ“ ģ‹¤ģ‹œė˜ģ§€ ģ•Šģ•„ ė³“ģ”°ģ €ģž„ė§¤ģ²“ ź“€ė¦¬ėŒ€ģž„ģ˜ ķ˜„ķ–‰ķ™”ź°€ ėÆøķ”ķ•œ 경우","사딀 2 : ź°œģøģ •ė³“ź°€ ķ¬ķ•Øėœ ė³“ģ”°ģ €ģž„ė§¤ģ²“ė„¼ ģž źøˆģž„ģ¹˜ź°€ ģžˆėŠ” ģ•ˆģ „ķ•œ ģž„ģ†Œģ— ė³“ź“€ķ•˜ģ§€ ģ•Šź³  사묓실 ģ„œėž 등에 ė°©ģ¹˜ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : ė³“ģ”°ģ €ģž„ė§¤ģ²“ ķ†µģ œ ģ†”ė£Øģ…˜ģ„ ė„ģž…Ā·ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ¼ė¶€ ģ‚¬ģš©ģžģ— ėŒ€ķ•˜ģ—¬ ģ ģ ˆķ•œ ģŠ¹ģø 절차 ģ—†ģ“ ģ˜ˆģ™øģ²˜ė¦¬ė˜ģ–“ ģ“°źø° ė“±ģ“ ķ—ˆģš©ėœ 경우","사딀 4 : 전산실에 ģœ„ģ¹˜ķ•œ ģ¼ė¶€ 공용 PC ė° ģ „ģ‚°ģž„ė¹„ģ—ģ„œ ģ¼ė°˜ USB메모리에 ėŒ€ķ•œ ģ“°źø°ź°€ ź°€ėŠ„ķ•œ ģƒķ™©ģ“ė‚˜ 매첓 ė°˜ģž… ė° ģ‚¬ģš© ģ œķ•œ, ģ‚¬ģš©ģ“ė „ źø°ė” ė° 검토 등 ķ†µģ œź°€ 적용되고 ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제10ģ”°(물리적 ģ•ˆģ „ģ”°ģ¹˜)"]}],"description": "ė³“ģ”°ģ €ģž„ė§¤ģ²“ė„¼ ķ†µķ•˜ģ—¬ ź°œģøģ •ė³“ ė˜ėŠ” ģ¤‘ģš”ģ •ė³“ģ˜ ģœ ģ¶œģ“ ė°œģƒķ•˜ź±°ė‚˜ ģ•…ģ„±ģ½”ė“œź°€ ź°ģ—¼ė˜ģ§€ ģ•Šė„ė” ꓀리 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ , ź°œģøģ •ė³“ ė˜ėŠ” ģ¤‘ģš”ģ •ė³“ź°€ ķ¬ķ•Øėœ ė³“ģ”°ģ €ģž„ ė§¤ģ²“ėŠ” ģ•ˆģ „ķ•œ ģž„ģ†Œģ— ė³“ź“€ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.10.8": {"name": "ķŒØģ¹˜ź“€ė¦¬","checks": {"ssm_managed_compliant_patching": "FAIL","kafka_cluster_uses_latest_version": null,"ec2_instance_account_imdsv2_enabled": null,"redshift_cluster_automatic_upgrades": null,"eks_cluster_uses_a_supported_version": null,"ec2_instance_older_than_specific_days": "FAIL","rds_instance_deprecated_engine_version": "PASS","rds_cluster_minor_version_upgrade_enabled": "PASS","dms_instance_minor_version_upgrade_enabled": null,"rds_instance_minor_version_upgrade_enabled": "PASS","awslambda_function_using_supported_runtimes": "FAIL","elasticache_redis_cluster_auto_minor_version_upgrades": null,"cloudfront_distributions_using_deprecated_ssl_protocols": null,"opensearch_service_domains_updated_to_the_latest_service_software_version": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.8 ķŒØģ¹˜ź“€ė¦¬","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["패치 적용 ꓀리 ģ •ģ±…Ā·ģ ˆģ°Ø","ģ‹œģŠ¤ķ…œė³„ 패치 적용 ķ˜„ķ™©","패치 적용 ꓀련 ģ˜ķ–„ė„ ė¶„ģ„ ź²°ź³¼"],"AuditChecklist": ["ģ„œė²„, ė„¤ķŠøģ›Œķ¬ģ‹œģŠ¤ķ…œ, ė³“ģ•ˆģ‹œģŠ¤ķ…œ, PC 등 ģžģ‚°ė³„ ķŠ¹ģ„± ė° ģ¤‘ģš”ė„ģ— ė”°ė¼ 욓영첓제(OS)와 ģ†Œķ”„ķŠøģ›Øģ–“ģ˜ ķŒØģ¹˜ź“€ė¦¬ ģ •ģ±… ė° 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ£¼ģš” ģ„œė²„, ė„¤ķŠøģ›Œķ¬ģ‹œģŠ¤ķ…œ, ė³“ģ•ˆģ‹œģŠ¤ķ…œ ė“±ģ˜ 경우 ģ„¤ģ¹˜ėœ OS, ģ†Œķ”„ķŠøģ›Øģ–“ 패치 적용 ķ˜„ķ™©ģ„ 주기적으딜 ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ„œė¹„ģŠ¤ ģ˜ķ–„ė„ 등에 ė”°ė¼ ģ·Øģ•½ģ ģ„ ģ”°ģ¹˜ķ•˜źø° ģœ„ķ•œ ģµœģ‹ ģ˜ 패치 ģ ģš©ģ“ ģ–“ė ¤ģš“ 경우 ė³“ģ™„ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","ģ£¼ģš” ģ„œė²„, ė„¤ķŠøģ›Œķ¬ģ‹œģŠ¤ķ…œ, ė³“ģ•ˆģ‹œģŠ¤ķ…œ ė“±ģ˜ 경우 공개 ģøķ„°ė„· ģ ‘ģ†ģ„ ķ†µķ•œ 패치넼 ģ œķ•œķ•˜ź³  ģžˆėŠ”ź°€?","ķŒØģ¹˜ź“€ė¦¬ģ‹œģŠ¤ķ…œģ„ ķ™œģš©ķ•˜ėŠ” 경우 ģ ‘ź·¼ķ†µģ œ 등 ģ¶©ė¶„ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ¼ė¶€ ģ‹œģŠ¤ķ…œģ—ģ„œ ķƒ€ė‹¹ķ•œ ģ‚¬ģœ ė‚˜ ģ±…ģž„ģž ģŠ¹ģø ģ—†ģ“ OSķŒØģ¹˜ź°€ ģž„źø°ź°„ 적용되고 ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ģ¼ė¶€ ģ‹œģŠ¤ķ…œģ— ģ„œė¹„ģŠ¤ ģ§€ģ›ģ“ ģ¢…ė£Œ(EOS)된 OSė²„ģ „ģ„ ģ‚¬ģš© ģ¤‘ģ“ė‚˜, ģ“ģ— 따넸 ėŒ€ģ‘ź³„ķšģ“ė‚˜ ė³“ģ™„ėŒ€ģ±…ģ“ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : 상용 ģ†Œķ”„ķŠøģ›Øģ–“ ė° OS에 ėŒ€ķ•“ģ„œėŠ” ģµœģ‹  ķŒØģ¹˜ź°€ 적용되고 ģžˆģœ¼ė‚˜, ģ˜¤ķ”ˆģ†ŒģŠ¤ ķ”„ė”œź·øėžØ(openssl, openssh, Apache 등)에 ėŒ€ķ•“ģ„œėŠ” ģµœģ‹  패치넼 ķ™•ģøķ•˜ź³  ģ ģš©ķ•˜ėŠ” 절차 ė° ė‹“ė‹¹ģžź°€ ģ§€ģ •ė˜ģ–“ ģžˆģ§€ ģ•Šģ•„ ģµœģ‹  ė³“ģ•ˆķŒØģ¹˜ź°€ 적용되고 ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제9ģ”°(ģ•…ģ„±ķ”„ė”œź·øėžØ 등 ė°©ģ§€)"]}],"description": "ģ†Œķ”„ķŠøģ›Øģ–“, 욓영첓제, ė³“ģ•ˆģ‹œģŠ¤ķ…œ ė“±ģ˜ ģ·Øģ•½ģ ģœ¼ė”œ ģøķ•œ 침핓사고넼 ģ˜ˆė°©ķ•˜źø° ģœ„ķ•˜ģ—¬ ģµœģ‹  패치넼 ģ ģš©ķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ė‹¤ė§Œ ģ„œė¹„ģŠ¤ ģ˜ķ–„ģ„ ź²€ķ† ķ•˜ģ—¬ ģµœģ‹  패치 ģ ģš©ģ“ ģ–“ė ¤ģšø 경우 ė³„ė„ģ˜ ė³“ģ™„ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ģ—¬ ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 3,"pass": 3,"total": 14,"manual": 0}},"2.10.9": {"name": "ģ•…ģ„±ģ½”ė“œ ķ†µģ œ","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.9 ģ•…ģ„±ģ½”ė“œ ķ†µģ œ","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["ģ•…ģ„±ķ”„ė”œź·øėžØ ėŒ€ģ‘ ģ§€ģ¹ØĀ·ģ ˆģ°ØĀ·ė§¤ė‰“ģ–¼","ė°±ģ‹ ķ”„ė”œź·øėžØ ģ„¤ģ¹˜ ķ˜„ķ™©","ė°±ģ‹ ķ”„ė”œź·øėžØ 설정 화멓","ģ•…ģ„±ķ”„ė”œź·øėžØ ėŒ€ģ‘ ģ“ė „(ėŒ€ģ‘ ė³“ź³ ģ„œ 등)"],"AuditChecklist": ["ė°”ģ“ėŸ¬ģŠ¤, ģ›œ, ķŠøė”œģ“ėŖ©ė§ˆ, ėžœģ„¬ģ›Øģ–“ ė“±ģ˜ ģ•…ģ„±ģ½”ė“œė”œė¶€ķ„° ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ģ—…ė¬“ģš©ė‹Øė§źø° ė“±ģ„ ė³“ķ˜øķ•˜źø° ģœ„ķ•˜ģ—¬ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","백신 ģ†Œķ”„ķŠøģ›Øģ–“ 등 ė³“ģ•ˆķ”„ė”œź·øėžØģ„ ķ†µķ•˜ģ—¬ ģµœģ‹  ģ•…ģ„±ģ½”ė“œ ģ˜ˆė°©Ā·ķƒģ§€ ķ™œė™ģ„ ģ§€ģ†ģ ģœ¼ė”œ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","백신 ģ†Œķ”„ķŠøģ›Øģ–“ 등 ė³“ģ•ˆķ”„ė”œź·øėžØģ€ ģµœģ‹ ģ˜ 상태딜 ģœ ģ§€ķ•˜ź³  ķ•„ģš”ģ‹œ źø“źø‰ ė³“ģ•ˆ ģ—…ė°ģ“ķŠøė„¼ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ•…ģ„±ģ½”ė“œ 감염 발견 ģ‹œ ģ•…ģ„±ģ½”ė“œ 확산 ė° 피핓 ģµœģ†Œķ™” ė“±ģ˜ ėŒ€ģ‘ģ ˆģ°Øė„¼ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ¼ė¶€ PC ė° ģ„œė²„ģ— ė°±ģ‹ ģ“ ģ„¤ģ¹˜ė˜ģ–“ ģžˆģ§€ ģ•Šź±°ė‚˜, 백신 ģ—”ģ§„ģ“ ģž„źø°ź°„ ģµœģ‹  ė²„ģ „ģœ¼ė”œ ģ—…ė°ģ“ķŠøė˜ģ§€ ģ•Šģ€ 경우","사딀 2 : 백신 ķ”„ė”œź·øėžØģ˜ ķ™˜ź²½ģ„¤ģ •(ģ‹¤ģ‹œź°„ 검사, ģ˜ˆģ•½ź²€ģ‚¬, ģ—…ė°ģ“ķŠø 설정 등)ģ„ ģ“ģš©ģžź°€ ģž„ģ˜ė”œ 변경할 수 ģžˆģŒģ—ė„ 그에 따넸 추가 ė³“ķ˜øėŒ€ģ±…ģ“ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : 백신 ģ¤‘ģ•™ź“€ė¦¬ģ‹œģŠ¤ķ…œģ— ģ ‘ź·¼ķ†µģ œ 등 ė³“ķ˜øėŒ€ģ±…ģ“ ėÆøė¹„ķ•˜ģ—¬ ģ¤‘ģ•™ź“€ė¦¬ģ‹œģŠ¤ķ…œģ„ ķ†µķ•œ ģ¹Øķ•“ģ‚¬ź³ ė°œģƒ ź°€ėŠ„ģ„±ģ“ ģžˆėŠ” 경우 ė˜ėŠ” 백신 ķŒØķ„“ģ— ėŒ€ķ•œ 묓결성 ź²€ģ¦ģ„ ķ•˜ģ§€ ģ•Šģ•„ ģ•…ģ˜ģ ģø ģ‚¬ģš©ģžģ— ģ˜ķ•œ ģ•…ģ„±ģ½”ė“œ ģ „ķŒŒ ź°€ėŠ„ģ„±ģ“ ģžˆėŠ” 경우","사딀 4 : ģ¼ė¶€ ė‚“ė¶€ė§ PC ė° ģ„œė²„ģ—ģ„œ ė‹¤ģˆ˜ģ˜ ģ•…ģ„±ģ½”ė“œ ź°ģ—¼ģ“ė „ģ“ ķ™•ģøė˜ģ—ˆģœ¼ė‚˜, 감염 ķ˜„ķ™©, 감염 경딜 ė° ģ›ģø ė¶„ģ„, 그에 따넸 ģ”°ģ¹˜ė‚“ģ—­ ė“±ģ“ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제9ģ”°(ģ•…ģ„±ķ”„ė”œź·øėžØ 등 ė°©ģ§€)"]}],"description": "ė°”ģ“ėŸ¬ģŠ¤Ā·ģ›œĀ·ķŠøė”œģ“ėŖ©ė§ˆĀ·ėžœģ„¬ģ›Øģ–“ ė“±ģ˜ ģ•…ģ„±ģ½”ė“œė”œė¶€ķ„° ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“, ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ģ—…ė¬“ģš© 단말기 ė“±ģ„ ė³“ķ˜øķ•˜źø° ģœ„ķ•˜ģ—¬ ģ•…ģ„±ģ½”ė“œ ģ˜ˆė°©Ā·ķƒģ§€Ā·ėŒ€ģ‘ ė“±ģ˜ ė³“ķ˜øėŒ€ģ±…ģ„ 수립 ė° ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.11.1": {"name": "사고 예방 ė° ėŒ€ģ‘ģ²“ź³„ 구축","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.11.1 사고 예방 ė° ėŒ€ģ‘ģ²“ź³„ 구축","Subdomain": "2.11. 사고 예방 ė° ėŒ€ģ‘","AuditEvidence": ["침핓사고 ėŒ€ģ‘ ģ§€ģ¹ØĀ·ģ ˆģ°ØĀ·ė§¤ė‰“ģ–¼","침핓사고 ėŒ€ģ‘ ģ”°ģ§ė„ ė° ė¹„ģƒģ—°ė½ė§","ė³“ģ•ˆź“€ģ œģ„œė¹„ģŠ¤ ź³„ģ•½ģ„œ(SLA 등)"],"AuditChecklist": ["침핓사고 ė° ź°œģøģ •ė³“ ģœ ģ¶œģ‚¬ź³ ė„¼ ģ˜ˆė°©ķ•˜ź³  사고 ė°œģƒ ģ‹œ ģ‹ ģ†ķ•˜ź³  효과적으딜 ėŒ€ģ‘ķ•˜źø° ģœ„ķ•œ 첓계와 절차넼 ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ģ•ˆź“€ģ œģ„œė¹„ģŠ¤ 등 외부 źø°ź“€ģ„ ķ†µķ•˜ģ—¬ 침핓사고 ėŒ€ģ‘ģ²“ź³„ė„¼ źµ¬ģ¶•Ā·ģš“ģ˜ķ•˜ėŠ” 경우 침핓사고 ėŒ€ģ‘ģ ˆģ°Øģ˜ ģ„øė¶€ģ‚¬ķ•­ģ„ ź³„ģ•½ģ„œģ— ė°˜ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ģ¹Øķ•“ģ‚¬ź³ ģ˜ ėŖØė‹ˆķ„°ė§, ėŒ€ģ‘ ė° 처리넼 ģœ„ķ•˜ģ—¬ 외부전문가, 전문업첓, 전문기꓀ ė“±ź³¼ģ˜ ķ˜‘ģ”°ģ²“ź³„ė„¼ ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 침핓사고에 ėŒ€ė¹„ķ•œ 침핓사고 ėŒ€ģ‘ 씰직 ė° ėŒ€ģ‘ 절차넼 ėŖ…ķ™•ķžˆ ģ •ģ˜ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ė‚“ė¶€ 지침 ė° ģ ˆģ°Øģ— 침핓사고 단계별(사고 ģ „, ģøģ§€, 처리, 복구, 볓고 등) ėŒ€ģ‘ 절차넼 ģˆ˜ė¦½ķ•˜ģ—¬ ėŖ…ģ‹œķ•˜ź³  ģžˆģœ¼ė‚˜, 침핓사고 ė°œģƒ ģ‹œ 사고 ģœ ķ˜• ė° ģ‹¬ź°ė„ģ— 따넸 신고·통지 절차, ėŒ€ģ‘ ė° 복구 ģ ˆģ°Øģ˜ ģ¼ė¶€ ė˜ėŠ” 전부넼 ģˆ˜ė¦½ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : 침핓사고 ėŒ€ģ‘ ģ”°ģ§ė„ ė° ė¹„ģƒģ—°ė½ė§ ė“±ģ„ ķ˜„ķ–‰ķ™”ķ•˜ģ§€ ģ•Šź³  ģžˆź±°ė‚˜, ė‹“ė‹¹ģžė³„ ģ—­ķ• ź³¼ ģ±…ģž„ģ“ ėŖ…ķ™•ķžˆ ģ •ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : 침핓사고 신고·통지 ė° ėŒ€ģ‘ ķ˜‘ģ”°ė„¼ ģœ„ķ•œ ėŒ€ģ™øźø°ź“€ ģ—°ė½ģ²˜ģ— 기꓀명, ķ™ˆķŽ˜ģ“ģ§€, ģ—°ė½ģ²˜ ė“±ģ“ ģž˜ėŖ» ėŖ…ģ‹œė˜ģ–“ ģžˆź±°ė‚˜, ģ¼ė¶€ źø°ź“€ ꓀련 정볓가 ėˆ„ė½ ė˜ėŠ” ķ˜„ķ–‰ķ™”ė˜ģ§€ ģ•Šģ€ 경우","사딀 5 : 외부 ė³“ģ•ˆź“€ģ œ 전문업첓 등 ģœ ź“€źø°ź“€ģ— 침핓사고 ķƒģ§€ ė° ėŒ€ģ‘ģ„ ģœ„ķƒķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, 침핓사고 ėŒ€ģ‘ģ— ėŒ€ķ•œ 상호 ź°„ ꓀련 ģ—­ķ•  ė° ģ±…ģž„ ė²”ģœ„ź°€ ź³„ģ•½ģ„œė‚˜ SLA에 ėŖ…ķ™•ķ•˜ź²Œ ģ •ģ˜ė˜ģ§€ ģ•Šģ€ 경우","사딀 6 : 침핓사고 ėŒ€ģ‘ģ ˆģ°Øė„¼ ģˆ˜ė¦½ķ•˜ģ˜€ģœ¼ė‚˜, ź°œģøģ •ė³“ 침핓 ģ‹ ź³  기준, ģ‹œģ  ė“±ģ“ 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ģ¤€ģˆ˜ķ•˜ģ§€ ėŖ»ķ•˜ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제34ģ”°(ź°œģøģ •ė³“ģ˜ 유출 ė“±ģ˜ 통지·신고)","ģ •ė³“ķ†µģ‹ ė§ė²• 제48ģ”°ģ˜3(ģ¹Øķ•“ģ‚¬ź³ ģ˜ ģ‹ ź³  등), 제48ģ”°ģ˜4(ģ¹Øķ•“ģ‚¬ź³ ģ˜ ģ›ģøė¶„ģ„ 등)"]}],"description": "침핓사고 ė° ź°œģøģ •ė³“ 유출 ė“±ģ„ ģ˜ˆė°©ķ•˜ź³  사고 ė°œģƒ ģ‹œ ģ‹ ģ†ķ•˜ź³  효과적으딜 ėŒ€ģ‘ķ•  수 ģžˆė„ė” 낓·외부 ģ¹Øķ•“ģ‹œė„ģ˜ ķƒģ§€Ā·ėŒ€ģ‘Ā·ė¶„ģ„ ė° 공유넼 ģœ„ķ•œ 첓계와 절차넼 ģˆ˜ė¦½ķ•˜ź³ , ꓀련 외부기꓀ ė° 전문가들과 ķ˜‘ģ”°ģ²“ź³„ė„¼ źµ¬ģ¶•ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.11.2": {"name": "취약점 점검 ė° 씰치","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ssm_document_secrets": "PASS","inspector2_is_enabled": "FAIL","ec2_instance_imdsv2_enabled": "PASS","guardduty_centrally_managed": "FAIL","ec2_instance_secrets_user_data": "PASS","ec2_launch_template_no_secrets": "PASS","inspector2_active_findings_exist": "FAIL","trustedadvisor_errors_and_warnings": null,"guardduty_no_high_severity_findings": "FAIL","awslambda_function_no_secrets_in_code": "PASS","cloudwatch_log_group_no_secrets_in_logs": "FAIL","ecr_registry_scan_images_on_push_enabled": "PASS","cloudformation_stack_outputs_find_secrets": "PASS","codebuild_project_no_secrets_in_variables": "PASS","awslambda_function_no_secrets_in_variables": "PASS","ecs_task_definitions_no_environment_secrets": "PASS","ecr_repositories_scan_images_on_push_enabled": "FAIL","trustedadvisor_premium_support_plan_subscribed": null,"autoscaling_find_secrets_ec2_launch_configuration": "PASS","ecr_repositories_scan_vulnerabilities_in_latest_image": null,"codebuild_project_source_repo_url_no_sensitive_credentials": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.11.2 취약점 점검 ė° 씰치","Subdomain": "2.11. 사고 예방 ė° ėŒ€ģ‘","AuditEvidence": ["취약점 점검 ź³„ķšģ„œ","취약점 점검 ź²°ź³¼ė³“ź³ ģ„œ(웹, ėŖØė°”ģ¼ 앱, ģ„œė²„, ė„¤ķŠøģ›Œķ¬ģ‹œģŠ¤ķ…œ, ė³“ģ•ˆģ‹œģŠ¤ķ…œ, DBMS 등)","취약점 점검 ģ“ė „","취약점 ģ”°ģ¹˜ź³„ķšģ„œ","취약점 ģ”°ģ¹˜ģ™„ė£Œė³“ź³ ģ„œ","ėŖØģ˜ķ•“ķ‚¹ ź³„ķšģ„œĀ·ź²°ź³¼ė³“ź³ ģ„œ"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œ 취약점 점검 절차넼 ģˆ˜ė¦½ķ•˜ź³ , ģ •źø°ģ ģœ¼ė”œ ģ ź²€ģ„ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","발견된 취약점에 ėŒ€ķ•œ 씰치넼 ģˆ˜ķ–‰ķ•˜ź³ , ź·ø 결과넼 ģ±…ģž„ģžģ—ź²Œ ė³“ź³ ķ•˜ź³  ģžˆėŠ”ź°€?","ģµœģ‹  ė³“ģ•ˆģ·Øģ•½ģ  ė°œģƒ 여부넼 ģ§€ģ†ģ ģœ¼ė”œ ķŒŒģ•…ķ•˜ź³ , ģ •ė³“ģ‹œģŠ¤ķ…œģ— ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ė¶„ģ„ķ•˜ģ—¬ ģ”°ģ¹˜ķ•˜ź³  ģžˆėŠ”ź°€?","취약점 점검 ģ“ė „ģ„ źø°ė”ź“€ė¦¬ķ•˜ģ—¬ ģ „ė…„ė„ģ— ė„ģ¶œėœ ģ·Øģ•½ģ ģ“ ģž¬ė°œģƒķ•˜ėŠ” ė“±ģ˜ ė¬øģ œģ ģ— ėŒ€ķ•˜ģ—¬ ė³“ķ˜øėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ ź·œģ •ģ— ģ—° 1회 ģ“ģƒ ģ£¼ģš” ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ 기술적 취약점 ģ ź²€ģ„ ķ•˜ė„ė” ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ£¼ģš” ģ‹œģŠ¤ķ…œ 중 ģ¼ė¶€ź°€ 취약점 점검 ėŒ€ģƒģ—ģ„œ ėˆ„ė½ėœ 경우","사딀 2 : 취약점 ģ ź²€ģ—ģ„œ 발견된 취약점에 ėŒ€ķ•œ ė³“ģ™„ģ”°ģ¹˜ė„¼ ģ“ķ–‰ķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜, 단기간 낓에 ģ”°ģ¹˜ķ•  수 ģ—†ėŠ” 취약점에 ėŒ€ķ•œ ķƒ€ė‹¹ģ„± 검토 ė° ģŠ¹ģø ģ“ė „ģ“ ģ—†ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검), 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ·Øģ•½ģ ģ“ ė…øģ¶œė˜ģ–“ ģžˆėŠ”ģ§€ė„¼ ķ™•ģøķ•˜źø° ģœ„ķ•˜ģ—¬ ģ •źø°ģ ģœ¼ė”œ 취약점 ģ ź²€ģ„ ģˆ˜ķ–‰ķ•˜ź³ , 발견된 취약점에 ėŒ€ķ•“ģ„œėŠ” ģ‹ ģ†ķ•˜ź²Œ ģ”°ģ¹˜ķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ė˜ķ•œ ģµœģ‹  ė³“ģ•ˆģ·Øģ•½ģ ģ˜ ė°œģƒ 여부넼 ģ§€ģ†ģ ģœ¼ė”œ ķŒŒģ•…ķ•˜ź³ , ģ •ė³“ģ‹œģŠ¤ķ…œģ— ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ė¶„ģ„ķ•˜ģ—¬ ģ”°ģ¹˜ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 6,"pass": 14,"total": 23,"manual": 0}},"2.11.3": {"name": "ģ“ģƒķ–‰ģœ„ ė¶„ģ„ ė° ėŖØė‹ˆķ„°ė§","checks": {"securityhub_enabled": "PASS","fms_policy_compliant": null,"vpc_flow_logs_enabled": "FAIL","cloudtrail_insights_exist": null,"networkfirewall_in_all_vpc": "FAIL","trustedadvisor_errors_and_warnings": null,"guardduty_no_high_severity_findings": "FAIL","cloudtrail_threat_detection_enumeration": null,"cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_cross_account_sharing_disabled": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cognito_user_pool_client_prevent_user_existence_errors": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.11.3 ģ“ģƒķ–‰ģœ„ ė¶„ģ„ ė° ėŖØė‹ˆķ„°ė§","Subdomain": "2.11. 사고 예방 ė° ėŒ€ģ‘","AuditEvidence": ["ģ“ģƒķ–‰ģœ„ ė¶„ģ„ ė° ėŖØė‹ˆķ„°ė§ ķ˜„ķ™©","ģ“ģƒķ–‰ģœ„ 발견 ģ‹œ ėŒ€ģ‘ ģ¦ź±°ģžė£Œ"],"AuditChecklist": ["낓·외부에 ģ˜ķ•œ ģ¹Øķ•“ģ‹œė„, ź°œģøģ •ė³“ģœ ģ¶œ ģ‹œė„, ė¶€ģ •ķ–‰ģœ„ 등 ģ“ģƒķ–‰ģœ„ė„¼ ķƒģ§€ķ•  수 ģžˆė„ė” ģ£¼ģš” ģ •ė³“ģ‹œģŠ¤ķ…œ, ģ‘ģš©ķ”„ė”œź·øėžØ, ė„¤ķŠøģ›Œķ¬, ė³“ģ•ˆģ‹œģŠ¤ķ…œ ė“±ģ—ģ„œ ė°œģƒķ•œ ė„¤ķŠøģ›Œķ¬ ķŠøėž˜ķ”½,ė°ģ“ķ„° ķė¦„, ģ“ė²¤ķŠø 딜그 ė“±ģ„ ģˆ˜ģ§‘ķ•˜ģ—¬ ė¶„ģ„ ė° ėŖØė‹ˆķ„°ė§ķ•˜ź³  ģžˆėŠ”ź°€?","ģ¹Øķ•“ģ‹œė„, ź°œģøģ •ė³“ģœ ģ¶œģ‹œė„, ė¶€ģ •ķ–‰ģœ„ ė“±ģ˜ 여부넼 ķŒė‹Øķ•˜źø° ģœ„ķ•œ 기준 ė° ģž„ź³„ģ¹˜ė„¼ ģ •ģ˜ķ•˜ź³  ģ“ģ— ė”°ė¼ ģ“ģƒķ–‰ģœ„ģ˜ ķŒė‹Ø ė° 씰사 등 ķ›„ģ† ģ”°ģ¹˜ź°€ ģ ģ‹œģ— ģ“ė£Øģ–“ģ§€ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ™øė¶€ė”œė¶€ķ„°ģ˜ ģ„œė²„, ė„¤ķŠøģ›Œķ¬, ė°ģ“ķ„°ė² ģ“ģŠ¤, ė³“ģ•ˆģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ 침핓 ģ‹œė„ė„¼ ģøģ§€ķ•  수 ģžˆė„ė” ķ•˜ėŠ” ģƒģ‹œ ė˜ėŠ” 정기적 ėŖØė‹ˆķ„°ė§ 첓계 ė° 절차넼 ė§ˆė Øķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : 외부 ė³“ģ•ˆź“€ģ œ 전문업첓 등 외부 기꓀에 ģ¹Øķ•“ģ‹œė„ ėŖØė‹ˆķ„°ė§ 업묓넼 ģœ„ķƒķ•˜ź³  ģžˆģœ¼ė‚˜, ģœ„ķƒģ—…ģ²“ź°€ ģ œź³µķ•œ ꓀련 ė³“ź³ ģ„œė„¼ ź²€ķ† ķ•œ ģ“ė „ģ“ ķ™•ģøė˜ģ§€ ģ•Šź±°ė‚˜, ģœ„ķƒ ėŒ€ģƒģ—ģ„œ ģ œģ™øėœ ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ģžģ²“ ėŖØė‹ˆķ„°ė§ 첓계넼 갖추고 ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ė‚“ė¶€ģ ģœ¼ė”œ ģ •ģ˜ķ•œ ģž„ź³„ģ¹˜ė„¼ ģ“ˆź³¼ķ•˜ėŠ” ģ“ģƒ ķŠøėž˜ķ”½ģ“ ģ§€ģ†ģ ģœ¼ė”œ 발견되고 ģžˆģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•œ ėŒ€ģ‘ģ”°ģ¹˜ź°€ ģ“ė£Øģ–“ģ§€ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "낓·외부에 ģ˜ķ•œ ģ¹Øķ•“ģ‹œė„, ź°œģøģ •ė³“ģœ ģ¶œ ģ‹œė„, ė¶€ģ •ķ–‰ģœ„ ė“±ģ„ ģ‹ ģ†ķ•˜ź²Œ ķƒģ§€Ā·ėŒ€ģ‘ķ•  수 ģžˆė„ė” ė„¤ķŠøģ›Œķ¬ ė° ė°ģ“ķ„° ķė¦„ ė“±ģ„ ģˆ˜ģ§‘ķ•˜ģ—¬ ė¶„ģ„ķ•˜ė©°, ėŖØė‹ˆķ„°ė§ ė° 점검 결과에 따넸 ģ‚¬ķ›„ģ”°ģ¹˜ėŠ” ģ ģ‹œģ— ģ“ė£Øģ–“ģ øģ•¼ ķ•œė‹¤.","checks_status": {"fail": 6,"pass": 1,"total": 28,"manual": 0}},"2.11.4": {"name": "사고 ėŒ€ģ‘ ķ›ˆė Ø ė° ź°œģ„ ","checks": {"ssmincidents_enabled_with_plans": null},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.11.4 사고 ėŒ€ģ‘ ķ›ˆė Ø ė° ź°œģ„ ","Subdomain": "2.11. 사고 예방 ė° ėŒ€ģ‘","AuditEvidence": ["침핓사고 ė° ź°œģøģ •ė³“ ģœ ģ¶œģ‚¬ź³  ėŒ€ģ‘ ėŖØģ˜ķ›ˆė Ø ź³„ķšģ„œ","침핓사고 ė° ź°œģøģ •ė³“ ģœ ģ¶œģ‚¬ź³  ėŒ€ģ‘ ėŖØģ˜ķ›ˆė Ø ź²°ź³¼ģ„œ","침핓사고 ėŒ€ģ‘ 절차"],"AuditChecklist": ["침핓사고 ė° ź°œģøģ •ė³“ ģœ ģ¶œģ‚¬ź³  ėŒ€ģ‘ ģ ˆģ°Øģ— ź“€ķ•œ ėŖØģ˜ķ›ˆė Øź³„ķšģ„ ģˆ˜ė¦½ķ•˜ź³  ģ“ģ— ė”°ė¼ ģ—° 1회 ģ“ģƒ 주기적으딜 ķ›ˆė Øģ„ ģ‹¤ģ‹œķ•˜ź³  ģžˆėŠ”ź°€?","침핓사고 ė° ź°œģøģ •ė³“ ģœ ģ¶œģ‚¬ź³  ķ›ˆė Ø 결과넼 ė°˜ģ˜ķ•˜ģ—¬ 침핓사고 ė° ź°œģøģ •ė³“ ģœ ģ¶œģ‚¬ź³  ėŒ€ģ‘ģ²“ź³„ė„¼ ź°œģ„ ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 침핓사고 ėŖØģ˜ķ›ˆė Øģ„ ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜ ꓀련 ź³„ķšģ„œ ė° ź²°ź³¼ė³“ź³ ģ„œź°€ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģ—°ź°„ 침핓사고 ėŖØģ˜ķ›ˆė Ø ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ģ˜€ģœ¼ė‚˜ ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ė˜ėŠ” ģŠ¹ģø ģ—†ģ“ 핓당 źø°ź°„ 낓에 ģ‹¤ģ‹œķ•˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ėŖØģ˜ķ›ˆė Øģ„ ź³„ķšķ•˜ģ—¬ ģ‹¤ģ‹œķ•˜ģ˜€ģœ¼ė‚˜, ꓀련 ė‚“ė¶€ 지침에 ģ •ķ•œ 절차 ė° ģ„œģ‹ģ— ė”°ė¼ ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "침핓사고 ė° ź°œģøģ •ė³“ ģœ ģ¶œģ‚¬ź³  ėŒ€ģ‘ 절차넼 ģž„ģ§ģ›ź³¼ ģ“ķ•“ź“€ź³„ģžź°€ ģˆ™ģ§€ķ•˜ė„ė” ģ‹œė‚˜ė¦¬ģ˜¤ģ— 따넸 ėŖØģ˜ķ›ˆė Øģ„ ģ—° 1회 ģ“ģƒ ģ‹¤ģ‹œķ•˜ź³  ķ›ˆė Øź²°ź³¼ė„¼ ė°˜ģ˜ķ•˜ģ—¬ ėŒ€ģ‘ģ²“ź³„ė„¼ ź°œģ„ ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"2.11.5": {"name": "사고 ėŒ€ģ‘ ė° 복구","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.11.5 사고 ėŒ€ģ‘ ė° 복구","Subdomain": "2.11. 사고 예방 ė° ėŒ€ģ‘","AuditEvidence": ["침핓사고 ėŒ€ģ‘ 절차","침핓사고 ėŒ€ģ‘ė³“ź³ ģ„œ","침핓사고 ź“€ė¦¬ėŒ€ģž„","ź°œģøģ •ė³“ ģœ ģ¶œģ‹ ź³ ģ„œ","ė¹„ģƒģ—°ė½ė§"],"AuditChecklist": ["침핓사고 ė° ź°œģøģ •ė³“ ģœ ģ¶œģ˜ 징후 ė˜ėŠ” ė°œģƒģ„ ģøģ§€ķ•œ 경우 ģ •ģ˜ėœ 침핓사고 ėŒ€ģ‘ģ ˆģ°Øģ— ė”°ė¼ ģ‹ ģ†ķ•˜ź²Œ ėŒ€ģ‘ ė° 볓고가 ģ“ė£Øģ–“ģ§€ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ 침핓사고 ė°œģƒ ģ‹œ ꓀련 법령에 ė”°ė¼ 정볓주첓 통지 ė° ꓀계기꓀ ģ‹ ź³  절차넼 ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","침핓사고가 ģ¢…ź²°ėœ 후 ģ‚¬ź³ ģ˜ ģ›ģøģ„ ė¶„ģ„ķ•˜ģ—¬ ź·ø 결과넼 ė³“ź³ ķ•˜ź³  ꓀련 씰직 ė°ģøė „ź³¼ ź³µģœ ķ•˜ź³  ģžˆėŠ”ź°€?","침핓사고 ė¶„ģ„ģ„ ķ†µķ•˜ģ—¬ ģ–»ģ€ 정볓넼 ķ™œģš©ķ•˜ģ—¬ ģœ ģ‚¬ 사고가 ģž¬ė°œķ•˜ģ§€ ģ•Šė„ė” ėŒ€ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ķ•„ģš”ķ•œ 경우 침핓사고 ėŒ€ģ‘ģ ˆģ°Ø ė“±ģ„ ė³€ź²½ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ 침핓사고 ėŒ€ģ‘ģ§€ģ¹Øģ—ėŠ” 침핓사고 ė°œģƒ ģ‹œ ė‚“ė¶€ ģ •ė³“ė³“ķ˜øģœ„ģ›ķšŒ ė° ģ“ķ•“ź“€ź³„ ė¶€ģ„œģ—ź²Œ ė³“ź³ ķ•˜ė„ė” ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, 침핓사고 ė°œģƒ ģ‹œ 닓당 ė¶€ģ„œģ—ģ„œ ģžģ²“ģ ģœ¼ė”œ ėŒ€ģ‘ 씰치 후 ģ •ė³“ė³“ķ˜øģœ„ģ›ķšŒ ė° ģ“ķ•“ź“€ź³„ ė¶€ģ„œģ— ė³“ź³ ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : 최근 DDoS 공격으딜 ģ˜ģ‹¬ė˜ėŠ” ģ¹Øķ•“ģ‚¬ź³ ė”œ ģøķ•˜ģ—¬ ģ„œė¹„ģŠ¤ ģ¼ė¶€ź°€ ģ¤‘ė‹Øėœ 사딀가 ģžˆģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•œ ģ›ģøė¶„ģ„ ė° ģž¬ė°œė°©ģ§€ ėŒ€ģ±…ģ“ ģˆ˜ė¦½ė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : 외부 핓킹에 ģ˜ķ•“ ź°œģøģ •ė³“ ģœ ģ¶œģ‚¬ź³ ź°€ ė°œģƒķ•˜ģ˜€ģœ¼ė‚˜, 유출된 ź°œģøģ •ė³“ ź±“ģˆ˜ź°€ ģ†ŒėŸ‰ģ“ė¼ėŠ” ģ“ģœ ė”œ 72ģ‹œź°„ ģ“ė‚“ģ— 통지 ė° ģ‹ ź³ ź°€ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우","사딀 4 : ė‹“ė‹¹ģžģ˜ ģ‹¤ģˆ˜ģ— ģ˜ķ•“ ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ ź²Œģ‹œķŒģ„ 통핓 1ģ²œėŖ… ģ“ģƒ 정볓주첓에 ėŒ€ķ•œ ź°œģøģ •ė³“ ģœ ģ¶œģ“ ė°œģƒķ•˜ģ˜€ģœ¼ė‚˜, 핓당 정볓주첓에 ėŒ€ķ•œ 유출 통지가 ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제34ģ”°(ź°œģøģ •ė³“ģ˜ 유출 ė“±ģ˜ 통지·신고)","ģ •ė³“ķ†µģ‹ ė§ė²• 제48ģ”°ģ˜3(ģ¹Øķ•“ģ‚¬ź³ ģ˜ ģ‹ ź³  등), 제48ģ”°ģ˜4(ģ¹Øķ•“ģ‚¬ź³ ģ˜ ģ›ģøė¶„ģ„ 등)"]}],"description": "침핓사고 ė° ź°œģøģ •ė³“ 유출 ģ§•ķ›„ė‚˜ ė°œģƒģ„ ģøģ§€ķ•œ ė•Œģ—ėŠ” 법적 통지 ė° ģ‹ ź³  ģ˜ė¬“ė„¼ ģ¤€ģˆ˜ķ•˜ģ—¬ģ•¼ ķ•˜ė©°, ģ ˆģ°Øģ— ė”°ė¼ ģ‹ ģ†ķ•˜ź²Œ ėŒ€ģ‘ ė° ė³µźµ¬ķ•˜ź³  ģ‚¬ź³ ė¶„ģ„ 후 ģž¬ė°œė°©ģ§€ ėŒ€ģ±…ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ėŒ€ģ‘ģ²“ź³„ģ— ė°˜ģ˜ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.12.1": {"name": "ģž¬ķ•“Ā·ģž¬ė‚œ ėŒ€ė¹„ ģ•ˆģ „ģ”°ģ¹˜","checks": {"drs_job_exist": "FAIL","backup_plans_exist": "PASS","rds_cluster_multi_az": "FAIL","elb_is_in_multiple_az": "FAIL","rds_instance_multi_az": "FAIL","s3_bucket_object_lock": "FAIL","vpc_different_regions": null,"efs_have_backup_enabled": "FAIL","elbv2_is_in_multiple_az": "PASS","vpc_subnet_different_az": "PASS","backup_reportplans_exist": null,"neptune_cluster_multi_az": null,"elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_lifecycle_enabled": "FAIL","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"autoscaling_group_multiple_az": null,"dms_instance_multi_az_enabled": null,"ec2_ebs_volume_snapshots_exists": "FAIL","rds_cluster_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL","documentdb_cluster_backup_enabled": null,"s3_bucket_cross_region_replication": "FAIL","kms_cmk_not_deleted_unintentionally": null,"neptune_cluster_deletion_protection": null,"redshift_cluster_automated_snapshot": null,"elb_cross_zone_load_balancing_enabled": "PASS","lightsail_instance_automated_snapshots": null,"dlm_ebs_snapshot_lifecycle_policy_exists": "FAIL","documentdb_cluster_cloudwatch_log_export": null,"elasticache_redis_cluster_backup_enabled": null,"elasticache_redis_cluster_multi_az_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.12.1 ģž¬ķ•“Ā·ģž¬ė‚œ ėŒ€ė¹„ ģ•ˆģ „ģ”°ģ¹˜","Subdomain": "2.12. ģž¬ķ•“ 복구","AuditEvidence": ["IT ģž¬ķ•“ 복구 ģ§€ģ¹ØĀ·ģ ˆģ°Ø","IT ģž¬ķ•“ 복구 ź³„ķš(RTO, RPO ģ •ģ˜ ķ¬ķ•Ø)","ė¹„ģƒģ—°ė½ė§","ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ģœ„źø°ėŒ€ģ‘ 매뉓얼"],"AuditChecklist": ["ģ”°ģ§ģ˜ 핵심 ģ„œė¹„ģŠ¤(업묓) ģ—°ģ†ģ„±ģ„ ģœ„ķ˜‘ķ•  수 ģžˆėŠ” IT ģž¬ķ•“ ģœ ķ˜•ģ„ ģ‹ė³„ķ•˜ź³ , ģœ ķ˜•ė³„ ķ”¼ķ•“ź·œėŖØ ė° 업묓에 ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ė¶„ģ„ķ•˜ģ—¬ 핵심 IT ģ„œė¹„ģŠ¤(업묓) ė° ģ‹œģŠ¤ķ…œģ„ģ‹ė³„ķ•˜ź³  ģžˆėŠ”ź°€?","핵심 IT ģ„œė¹„ģŠ¤ ė° ģ‹œģŠ¤ķ…œģ˜ ģ¤‘ģš”ė„ ė° ķŠ¹ģ„±ģ— 따넸 복구 ėŖ©ķ‘œģ‹œź°„, 복구 ėŖ©ķ‘œģ‹œģ ģ„ ģ •ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ģž¬ķ•“Ā·ģž¬ė‚œ ė°œģƒ ģ‹œģ—ė„ 핵심 ģ„œė¹„ģŠ¤ ė° ģ‹œģŠ¤ķ…œģ˜ ģ—°ģ†ģ„±ģ„ ė³“ģž„ķ•  수 ģžˆė„ė” 복구 ģ „ėžµ ė° ėŒ€ģ±…, ė¹„ģƒģ‹œ 복구 씰직, ė¹„ģƒģ—°ė½ģ²“ź³„, 복구 절차 등 ģž¬ķ•“ 복구 ź³„ķšģ„ 수립 ė° ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : IT ģž¬ķ•“ 복구 ģ ˆģ°Øģ„œ 낓에 IT ģž¬ķ•“ 복구 씰직 ė° ģ—­ķ•  ģ •ģ˜, ė¹„ģƒģ—°ė½ģ²“ź³„, 복구 절차 ė° 방법 등 ģ¤‘ģš”ķ•œ ė‚“ģš©ģ“ ėˆ„ė½ė˜ģ–“ ģžˆėŠ” 경우","사딀 2 : ė¹„ģƒģ‚¬ķƒœ ė°œģƒ ģ‹œ ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ—°ģ†ģ„± 확볓 ė° 피핓 ģµœģ†Œķ™”ė„¼ ģœ„ķ•˜ģ—¬ 백업센터넼 źµ¬ģ¶•ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, ꓀련 정책에 백업센터넼 ķ™œģš©ķ•œ ģž¬ķ•“ 복구 절차 ė“±ģ“ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ•„ ģž¬ķ•“ 복구 ģ‹œķ—˜ ė° 복구가 효과적으딜 ģ§„ķ–‰ė˜źø° ģ–“ė ¤ģš“ 경우","사딀 3 : ģ„œė¹„ģŠ¤ 욓영과 ź“€ė Øėœ ģ¼ė¶€ ģ¤‘ģš” ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ 복구 ėŖ©ķ‘œģ‹œź°„ģ“ ģ •ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģœ¼ė©°, ģ“ģ— ėŒ€ķ•œ ģ ģ ˆķ•œ 복구 ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ģž¬ķ•“ 복구 ꓀련 ģ§€ģ¹Øģ„œ 등에 IT ģ„œė¹„ģŠ¤ ė˜ėŠ” ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ 복구 ģš°ģ„ ģˆœģœ„, 복구 ėŖ©ķ‘œģ‹œź°„, 복구 ėŖ©ķ‘œģ‹œģ  ė“±ģ“ ģ •ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 5 : ķ˜„ģ‹¤ģ  ėŒ€ģ±… ģ—†ģ“ 복구 ėŖ©ķ‘œģ‹œź°„ģ„ ź³¼ė„ ė˜ėŠ” ź³¼ģ†Œķ•˜ź²Œ ģ„¤ģ •ķ•˜ź³  ģžˆź±°ė‚˜, 복구 ėŖ©ķ‘œģ‹œģ ź³¼ 백업정책(ėŒ€ģƒ, 주기 등)ģ“ ģ ģ ˆķžˆ ģ—°ź³„ė˜ģ§€ ģ•Šģ•„ 복구 ķšØź³¼ģ„±ģ„ ė³“ģž„ķ•  수 ģ—†ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제11ģ”°(ģž¬ķ•“Ā·ģž¬ė‚œ ėŒ€ė¹„ ģ•ˆģ „ģ”°ģ¹˜)"]}],"description": "ģžģ—°ģž¬ķ•“, 통신·전렄 ģž„ģ• , 핓킹 등 ģ”°ģ§ģ˜ 핵심 ģ„œė¹„ģŠ¤ ė° ģ‹œģŠ¤ķ…œģ˜ 욓영 ģ—°ģ†ģ„±ģ„ ģœ„ķ˜‘ķ•  수 ģžˆėŠ” ģž¬ķ•“ ģœ ķ˜•ģ„ ģ‹ė³„ķ•˜ź³ , ģœ ķ˜•ė³„ 예상 ķ”¼ķ•“ź·œėŖØ ė° ģ˜ķ–„ģ„ ė¶„ģ„ķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ė˜ķ•œ 복구 ėŖ©ķ‘œģ‹œź°„, 복구 ėŖ©ķ‘œģ‹œģ ģ„ ģ •ģ˜ķ•˜ź³  복구 ģ „ėžµ ė° ėŒ€ģ±…, ė¹„ģƒģ‹œ 복구 씰직, ė¹„ģƒģ—°ė½ģ²“ź³„, 복구 절차 등 ģž¬ķ•“ 복구첓계넼 źµ¬ģ¶•ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 14,"pass": 5,"total": 33,"manual": 0}},"2.12.2": {"name": "ģž¬ķ•“ 복구 ģ‹œķ—˜ ė° ź°œģ„ ","checks": {"drs_job_exist": "FAIL","backup_plans_exist": "PASS","rds_cluster_multi_az": "FAIL","elb_is_in_multiple_az": "FAIL","rds_instance_multi_az": "FAIL","s3_bucket_object_lock": "FAIL","vpc_different_regions": null,"efs_have_backup_enabled": "FAIL","elbv2_is_in_multiple_az": "PASS","vpc_subnet_different_az": "PASS","backup_reportplans_exist": null,"neptune_cluster_multi_az": null,"elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_lifecycle_enabled": "FAIL","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"autoscaling_group_multiple_az": null,"dms_instance_multi_az_enabled": null,"ec2_ebs_volume_snapshots_exists": "FAIL","rds_cluster_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL","documentdb_cluster_backup_enabled": null,"s3_bucket_cross_region_replication": "FAIL","kms_cmk_not_deleted_unintentionally": null,"neptune_cluster_deletion_protection": null,"redshift_cluster_automated_snapshot": null,"elb_cross_zone_load_balancing_enabled": "PASS","lightsail_instance_automated_snapshots": null,"dlm_ebs_snapshot_lifecycle_policy_exists": "FAIL","documentdb_cluster_cloudwatch_log_export": null,"elasticache_redis_cluster_backup_enabled": null,"elasticache_redis_cluster_multi_az_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.12.2 ģž¬ķ•“ 복구 ģ‹œķ—˜ ė° ź°œģ„ ","Subdomain": "2.12. ģž¬ķ•“ 복구","AuditEvidence": ["IT ģž¬ķ•“ 복구 ģ ˆģ°Øģ„œ","IT ģž¬ķ•“ 복구 ģ‹œķ—˜ ź³„ķšģ„œ","IT ģž¬ķ•“ 복구 ģ‹œķ—˜ ź²°ź³¼ģ„œ"],"AuditChecklist": ["수립된 IT ģž¬ķ•“ ė³µźµ¬ģ²“ź³„ģ˜ ģ‹¤ķšØģ„±ģ„ ķŒė‹Øķ•˜źø° ģœ„ķ•˜ģ—¬ ģž¬ķ•“ 복구 ģ‹œķ—˜ź³„ķšģ„ 수립 ė° ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ‹œķ—˜ź²°ź³¼, ģ •ė³“ģ‹œģŠ¤ķ…œ ķ™˜ź²½ė³€ķ™”, 법넠 등에 따넸 변화넼 ė°˜ģ˜ķ•  수 ģžˆė„ė” ė³µźµ¬ģ „ėžµ ė° ėŒ€ģ±…ģ„ ģ •źø°ģ ģœ¼ė”œ ź²€ķ† Ā·ė³“ģ™„ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģž¬ķ•“ 복구 ķ›ˆė Øģ„ ź³„ķšĀ·ģ‹œķ–‰ķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜ ꓀련 ź³„ķšģ„œ ė° ź²°ź³¼ė³“ź³ ģ„œź°€ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģž¬ķ•“ 복구 ķ›ˆė Ø ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ģ˜€ģœ¼ė‚˜, ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ė˜ėŠ” ģŠ¹ģø ģ—†ģ“ ź³„ķšėŒ€ė”œ ģ‹¤ģ‹œķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜ ꓀련 결과볓고가 ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ģž¬ķ•“ 복구 ķ›ˆė Øģ„ ź³„ķšķ•˜ģ—¬ ģ‹¤ģ‹œķ•˜ģ˜€ģœ¼ė‚˜, ė‚“ė¶€ ꓀련 지침에 ģ •ķ•œ 절차 ė° ģ„œģ‹ģ— ė”°ė¼ ģ“ķ–‰ė˜ģ§€ ģ•Šģ•„ ģˆ˜ė¦½ķ•œ ģž¬ķ•“ 복구 ģ ˆģ°Øģ˜ 적정성 ė° ķšØź³¼ģ„±ģ„ ķ‰ź°€ķ•˜źø° ģœ„ķ•œ ķ›ˆė Øģœ¼ė”œ 볓기 ģ–“ė ¤ģš“ 경우"],"RelatedRegulations": []}],"description": "ģž¬ķ•“ 복구 ģ „ėžµ ė° ėŒ€ģ±…ģ˜ ģ ģ •ģ„±ģ„ ģ •źø°ģ ģœ¼ė”œ ģ‹œķ—˜ķ•˜ģ—¬ ģ‹œķ—˜ź²°ź³¼, ģ •ė³“ģ‹œģŠ¤ķ…œ ķ™˜ź²½ė³€ķ™”, ė²•ź·œ 등에 따넸 변화넼 ė°˜ģ˜ķ•˜ģ—¬ ė³µźµ¬ģ „ėžµ ė° ėŒ€ģ±…ģ„ ė³“ģ™„ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 14,"pass": 5,"total": 33,"manual": 0}}},"requirements_passed": 10,"requirements_failed": 27,"requirements_manual": 64,"total_requirements": 101,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "f9e5248f-1b1d-4256-b2a1-3b571315c190","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "cis_1.4_aws","framework": "CIS","version": "1.4","description": "The CIS Benchmark for CIS Amazon Web Services Foundations Benchmark, v1.4.0, Level 1 and 2 provides prescriptive guidance for configuring security options for a subset of Amazon Web Services. It has an emphasis on foundational, testable, and architecture agnostic settings","region": "eu-west-1","requirements": {"1.1": {"name": "1.1","checks": {"account_maintain_current_contact_details": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/manage-account-payment.html#contact-info","Description": "Ensure contact email and telephone details for AWS accounts are current and map to more than one individual in your organization.An AWS account supports a number of contact details, and AWS will use these to contact the account owner if activity judged to be in breach of Acceptable Use Policy or indicative of likely security compromise is observed by the AWS Abuse team. Contact details should not be for a single individual, as circumstances may arise where that individual is unavailable. Email contact details should point to a mail alias which forwards email to multiple individuals within the organization; where feasible, phone contact details should point to a PABX hunt group or other call-forwarding system.","DefaultValue": null,"AuditProcedure": "This activity can only be performed via the AWS Console, with a user who has permission to read and write Billing information (aws-portal:\\*Billing )1. Sign in to the AWS Management Console and open the `Billing and Cost Management` console at https://console.aws.amazon.com/billing/home#/. 2. On the navigation bar, choose your account name, and then choose `My Account`. 3. On the `Account Settings` page, review and verify the current details. 4. Under `Contact Information`, review and verify the current details.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "If an AWS account is observed to be behaving in a prohibited or suspicious manner, AWS will attempt to contact the account owner by email and phone using the contact details listed. If this is unsuccessful and the account behavior needs urgent mitigation, proactive measures may be taken, including throttling of traffic between the account exhibiting suspicious behavior and the AWS API endpoints and the Internet. This will result in impaired service to and from the account in question, so it is in both the customers' and AWS' best interests that prompt contact can be established. This is best achieved by setting AWS account contact details to point to resources which have multiple individuals as recipients, such as email aliases and PABX hunt groups.","RemediationProcedure": "This activity can only be performed via the AWS Console, with a user who has permission to read and write Billing information (aws-portal:\\*Billing ).1. Sign in to the AWS Management Console and open the `Billing and Cost Management` console at https://console.aws.amazon.com/billing/home#/. 2. On the navigation bar, choose your account name, and then choose `My Account`. 3. On the `Account Settings` page, next to `Account Settings`, choose `Edit`. 4. Next to the field that you need to update, choose `Edit`. 5. After you have entered your changes, choose `Save changes`. 6. After you have made your changes, choose `Done`. 7. To edit your contact information, under `Contact Information`, choose `Edit`. 8. For the fields that you want to change, type your updated information, and then choose `Update`.","AdditionalInformation": ""}],"description": "Maintain current contact details","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.2": {"name": "1.2","checks": {"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "","Description": "AWS provides customers with the option of specifying the contact information for account's security team. It is recommended that this information be provided.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if security contact information is present:**From Console:**1. Click on your account name at the top right corner of the console 2. From the drop-down menu Click `My Account`3. Scroll down to the `Alternate Contacts` section 4. Ensure contact information is specified in the `Security` section","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Specifying security-specific contact information will help ensure that security advisories sent by AWS reach the team in your organization that is best equipped to respond to them.","RemediationProcedure": "Perform the following to establish security contact information:**From Console:**1. Click on your account name at the top right corner of the console. 2. From the drop-down menu Click `My Account`3. Scroll down to the `Alternate Contacts` section 4. Enter contact information in the `Security` section**Note:** Consider specifying an internal email distribution list to ensure emails are regularly monitored by more than one individual.","AdditionalInformation": ""}],"description": "Ensure security contact information is registered","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.3": {"name": "1.3","checks": {"account_security_questions_are_registered_in_the_aws_account": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "","Description": "The AWS support portal allows account owners to establish security questions that can be used to authenticate individuals calling AWS customer service for support. It is recommended that security questions be established.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS account as the 'root' user 2. On the top right you will see the __ 3. Click on the __ 4. From the drop-down menu Click `My Account`5. In the `Configure Security Challenge Questions` section on the `Personal Information` page, configure three security challenge questions. 6. Click `Save questions` .","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "When creating a new AWS account, a default super user is automatically created. This account is referred to as the 'root user' or 'root' account. It is recommended that the use of this account be limited and highly controlled. During events in which the 'root' password is no longer accessible or the MFA token associated with 'root' is lost/destroyed it is possible, through authentication using secret questions and associated answers, to recover 'root' user login access.","RemediationProcedure": "**From Console:**1. Login to the AWS Account as the 'root' user 2. Click on the __ from the top right of the console 3. From the drop-down menu Click _My Account_ 4. Scroll down to the `Configure Security Questions` section 5. Click on `Edit`6. Click on each `Question` - From the drop-down select an appropriate question- Click on the `Answer` section- Enter an appropriate answer - Follow process for all 3 questions 7. Click `Update` when complete 8. Save Questions and Answers and place in a secure physical location","AdditionalInformation": ""}],"description": "Ensure security questions are registered in the AWS account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.4": {"name": "1.4","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "http://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html:http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html:http://docs.aws.amazon.com/IAM/latest/APIReference/API_GetAccountSummary.html:https://aws.amazon.com/blogs/security/an-easier-way-to-determine-the-presence-of-aws-account-access-keys/","Description": "The 'root' user account is the most privileged user in an AWS account. AWS Access Keys provide programmatic access to a given AWS account. It is recommended that all access keys associated with the 'root' user account be removed.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has access keys:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on `Credential Report`5. This will download a `.csv` file which contains credential usage for all IAM users within an AWS Account - open this file 6. For the `` user, ensure the `access_key_1_active` and `access_key_2_active` fields are set to `FALSE` .**From Command Line:**Run the following command: ```aws iam get-account-summary | grep \"AccountAccessKeysPresent\"``` If no 'root' access keys exist the output will show \"AccountAccessKeysPresent\": 0,. If the output shows a \"1\" than 'root' keys exist, refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Removing access keys associated with the 'root' user account limits vectors by which the account can be compromised. Additionally, removing the 'root' access keys encourages the creation and use of role based accounts that are least privileged.","RemediationProcedure": "Perform the following to delete or disable active 'root' user access keys**From Console:**1. Sign in to the AWS Management Console as 'root' and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. Click on __ at the top right and select `My Security Credentials` from the drop down list 3. On the pop out screen Click on `Continue to Security Credentials`4. Click on `Access Keys` _(Access Key ID and Secret Access Key)_ 5. Under the `Status` column if there are any Keys which are Active- Click on `Make Inactive` - (Temporarily disable Key - may be needed again)- Click `Delete` - (Deleted keys cannot be recovered)","AdditionalInformation": "IAM User account \"root\" for us-gov cloud regions is not enabled by default. However, on request to AWS support enables 'root' access only through access-keys (CLI, API methods) for us-gov cloud region."}],"description": "Ensure no 'root' user account access key exists","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.5": {"name": "1.5","checks": {"iam_root_mfa_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#id_root-user_manage_mfa:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html#enable-virt-mfa-for-root","Description": "The 'root' user account is the most privileged user in an AWS account. Multi-factor Authentication (MFA) adds an extra layer of protection on top of a username and password. With MFA enabled, when a user signs in to an AWS website, they will be prompted for their username and password as well as for an authentication code from their AWS MFA device.**Note:** When virtual MFA is used for 'root' accounts, it is recommended that the device used is NOT a personal device, but rather a dedicated mobile device (tablet or phone) that is managed to be kept charged and secured independent of any individual personal devices. (\"non-personal virtual MFA\") This lessens the risks of losing access to the MFA due to device loss, device trade-in or if the individual owning the device is no longer employed at the company.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has MFA setup:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on `Credential Report`5. This will download a `.csv` file which contains credential usage for all IAM users within an AWS Account - open this file 6. For the `` user, ensure the `mfa_active` field is set to `TRUE` .**From Command Line:**1. Run the following command: ```aws iam get-account-summary | grep \"AccountMFAEnabled\" ``` 2. Ensure the AccountMFAEnabled property is set to 1","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling MFA provides increased security for console access as it requires the authenticating principal to possess a device that emits a time-sensitive key and have knowledge of a credential.","RemediationProcedure": "Perform the following to establish MFA for the 'root' user account:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). Note: to manage MFA devices for the 'root' AWS account, you must use your 'root' account credentials to sign in to AWS. You cannot manage MFA devices for the 'root' account using other credentials.2. Choose `Dashboard` , and under `Security Status` , expand `Activate MFA` on your root account. 3. Choose `Activate MFA`4. In the wizard, choose `A virtual MFA` device and then choose `Next Step` . 5. IAM generates and displays configuration information for the virtual MFA device, including a QR code graphic. The graphic is a representation of the 'secret configuration key' that is available for manual entry on devices that do not support QR codes. 6. Open your virtual MFA application. (For a list of apps that you can use for hosting virtual MFA devices, see [Virtual MFA Applications](http://aws.amazon.com/iam/details/mfa/#Virtual_MFA_Applications).) If the virtual MFA application supports multiple accounts (multiple virtual MFA devices), choose the option to create a new account (a new virtual MFA device). 7. Determine whether the MFA app supports QR codes, and then do one of the following: - Use the app to scan the QR code. For example, you might choose the camera icon or choose an option similar to Scan code, and then use the device's camera to scan the code.- In the Manage MFA Device wizard, choose Show secret key for manual configuration, and then type the secret configuration key into your MFA application.When you are finished, the virtual MFA device starts generating one-time passwords.In the Manage MFA Device wizard, in the Authentication Code 1 box, type the one-time password that currently appears in the virtual MFA device. Wait up to 30 seconds for the device to generate a new one-time password. Then type the second one-time password into the Authentication Code 2 box. Choose Assign Virtual MFA.","AdditionalInformation": "IAM User account \"root\" for us-gov cloud regions does not have console access. This recommendation is not applicable for us-gov cloud regions."}],"description": "Ensure MFA is enabled for the 'root' user account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.6": {"name": "1.6","checks": {"iam_root_hardware_mfa_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_physical.html#enable-hw-mfa-for-root","Description": "The 'root' user account is the most privileged user in an AWS account. MFA adds an extra layer of protection on top of a user name and password. With MFA enabled, when a user signs in to an AWS website, they will be prompted for their user name and password as well as for an authentication code from their AWS MFA device. For Level 2, it is recommended that the 'root' user account be protected with a hardware MFA.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has a hardware MFA setup:1. Run the following command to determine if the 'root' account has MFA setup: ```aws iam get-account-summary | grep \"AccountMFAEnabled\" ```The `AccountMFAEnabled` property is set to `1` will ensure that the 'root' user account has MFA (Virtual or Hardware) Enabled. If `AccountMFAEnabled` property is set to `0` the account is not compliant with this recommendation.2. If `AccountMFAEnabled` property is set to `1`, determine 'root' account has Hardware MFA enabled. Run the following command to list all virtual MFA devices: ```aws iam list-virtual-mfa-devices``` If the output contains one MFA with the following Serial Number, it means the MFA is virtual, not hardware and the account is not compliant with this recommendation: `\"SerialNumber\": \"arn:aws:iam::__:mfa/root-account-mfa-device\"`","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "A hardware MFA has a smaller attack surface than a virtual MFA. For example, a hardware MFA does not suffer the attack surface introduced by the mobile smartphone on which a virtual MFA resides.**Note**: Using hardware MFA for many, many AWS accounts may create a logistical device management issue. If this is the case, consider implementing this Level 2 recommendation selectively to the highest security AWS accounts and the Level 1 recommendation applied to the remaining accounts.","RemediationProcedure": "Perform the following to establish a hardware MFA for the 'root' user account:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). Note: to manage MFA devices for the AWS 'root' user account, you must use your 'root' account credentials to sign in to AWS. You cannot manage MFA devices for the 'root' account using other credentials. 2. Choose `Dashboard` , and under `Security Status` , expand `Activate MFA` on your root account. 3. Choose `Activate MFA`4. In the wizard, choose `A hardware MFA` device and then choose `Next Step` . 5. In the `Serial Number` box, enter the serial number that is found on the back of the MFA device. 6. In the `Authentication Code 1` box, enter the six-digit number displayed by the MFA device. You might need to press the button on the front of the device to display the number. 7. Wait 30 seconds while the device refreshes the code, and then enter the next six-digit number into the `Authentication Code 2` box. You might need to press the button on the front of the device again to display the second number. 8. Choose `Next Step` . The MFA device is now associated with the AWS account. The next time you use your AWS account credentials to sign in, you must type a code from the hardware MFA device.Remediation for this recommendation is not available through AWS CLI.","AdditionalInformation": "IAM User account 'root' for us-gov cloud regions does not have console access. This control is not applicable for us-gov cloud regions."}],"description": "Ensure hardware MFA is enabled for the 'root' user account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.7": {"name": "1.7","checks": {"iam_avoid_root_usage": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html:https://docs.aws.amazon.com/general/latest/gr/aws_tasks-that-require-root.html","Description": "With the creation of an AWS account, a 'root user' is created that cannot be disabled or deleted. That user has unrestricted access to and control over all resources in the AWS account. It is highly recommended that the use of this account be avoided for everyday tasks.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console at `https://console.aws.amazon.com/iam/` 2. In the left pane, click `Credential Report` 3. Click on `Download Report` 4. Open of Save the file locally 5. Locate the `` under the user column 6. Review `password_last_used, access_key_1_last_used_date, access_key_2_last_used_date` to determine when the 'root user' was last used.**From Command Line:**Run the following CLI commands to provide a credential report for determining the last time the 'root user' was used: ``` aws iam generate-credential-report ``` ``` aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,5,11,16 | grep -B1 '' ```Review `password_last_used`, `access_key_1_last_used_date`, `access_key_2_last_used_date` to determine when the _root user_ was last used.**Note:** There are a few conditions under which the use of the 'root' user account is required. Please see the reference links for all of the tasks that require use of the 'root' user.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "The 'root user' has unrestricted access to and control over all account resources. Use of it is inconsistent with the principles of least privilege and separation of duties, and can lead to unnecessary harm due to error or account compromise.","RemediationProcedure": "If you find that the 'root' user account is being used for daily activity to include administrative tasks that do not require the 'root' user:1. Change the 'root' user password. 2. Deactivate or delete any access keys associate with the 'root' user.**Remember, anyone who has 'root' user credentials for your AWS account has unrestricted access to and control of all the resources in your account, including billing information.","AdditionalInformation": "The 'root' user for us-gov cloud regions is not enabled by default. However, on request to AWS support, they can enable the 'root' user and grant access only through access-keys (CLI, API methods) for us-gov cloud region. If the 'root' user for us-gov cloud regions is enabled, this recommendation is applicable.Monitoring usage of the 'root' user can be accomplished by implementing recommendation 3.3 Ensure a log metric filter and alarm exist for usage of the 'root' user."}],"description": "Eliminate use of the 'root' user for administrative and daily tasks","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.8": {"name": "1.8","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy","Description": "Password policies are, in part, used to enforce password complexity requirements. IAM password policies can be used to ensure password are at least a given length. It is recommended that the password policy require a minimum password length 14.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure the password policy is configured as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Ensure \"Minimum password length\" is set to 14 or greater.**From Command Line:** ``` aws iam get-account-password-policy ``` Ensure the output of the above command includes \"MinimumPasswordLength\": 14 (or higher)","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Setting a password complexity policy increases account resiliency against brute force login attempts.","RemediationProcedure": "Perform the following to set the password policy as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Set \"Minimum password length\" to `14` or greater. 5. Click \"Apply password policy\"**From Command Line:** ```aws iam update-account-password-policy --minimum-password-length 14 ``` Note: All commands starting with \"aws iam update-account-password-policy\" can be combined into a single command.","AdditionalInformation": ""}],"description": "Ensure IAM password policy requires minimum length of 14 or greater","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.9": {"name": "1.9","checks": {"iam_password_policy_reuse_24": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy","Description": "IAM password policies can prevent the reuse of a given password by the same user. It is recommended that the password policy prevent the reuse of passwords.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure the password policy is configured as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Ensure \"Prevent password reuse\" is checked 5. Ensure \"Number of passwords to remember\" is set to 24**From Command Line:** ``` aws iam get-account-password-policy``` Ensure the output of the above command includes \"PasswordReusePrevention\": 24","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Preventing password reuse increases account resiliency against brute force login attempts.","RemediationProcedure": "Perform the following to set the password policy as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Check \"Prevent password reuse\" 5. Set \"Number of passwords to remember\" is set to `24` **From Command Line:** ```aws iam update-account-password-policy --password-reuse-prevention 24 ``` Note: All commands starting with \"aws iam update-account-password-policy\" can be combined into a single command.","AdditionalInformation": ""}],"description": "Ensure IAM password policy prevents password reuse","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.1": {"name": "3.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-management-events:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-management-and-data-events-with-cloudtrail.html?icmpid=docs_cloudtrail_console#logging-management-events:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-supported-services.html#cloud-trail-supported-services-data-events","Description": "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. CloudTrail provides a history of AWS API calls for an account, including API calls made via the Management Console, SDKs, command line tools, and higher-level AWS services (such as CloudFormation).","DefaultValue": null,"AuditProcedure": "Perform the following to determine if CloudTrail is enabled for all regions:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane- You will be presented with a list of trails across all regions 3. Ensure at least one Trail has `All` specified in the `Region` column 4. Click on a trail via the link in the _Name_ column 5. Ensure `Logging` is set to `ON`6. Ensure `Apply trail to all regions` is set to `Yes` 7. In section `Management Events` ensure `Read/Write Events` set to `ALL`**From Command Line:** ```aws cloudtrail describe-trails ``` Ensure `IsMultiRegionTrail` is set to `true```` aws cloudtrail get-trail-status --name  ``` Ensure `IsLogging` is set to `true` ``` aws cloudtrail get-event-selectors --trail-name  ``` Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`","ImpactStatement": "S3 lifecycle features can be used to manage the accumulation and management of logs over time. See the following AWS resource for more information on these features:1. https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html","AssessmentStatus": "Automated","RationaleStatement": "The AWS API call history produced by CloudTrail enables security analysis, resource change tracking, and compliance auditing. Additionally, - ensuring that a multi-regions trail exists will ensure that unexpected activity occurring in otherwise unused regions is detected- ensuring that a multi-regions trail exists will ensure that `Global Service Logging` is enabled for a trail by default to capture recording of events generated onAWS global services- for a multi-regions trail, ensuring that management events configured for all type of Read/Writes ensures recording of management operations that are performed on all resources in an AWS account","RemediationProcedure": "Perform the following to enable global (Multi-region) CloudTrail logging:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on _Trails_ on the left navigation pane 3. Click `Get Started Now` , if presented- Click `Add new trail` - Enter a trail name in the `Trail name` box- Set the `Apply trail to all regions` option to `Yes` - Specify an S3 bucket name in the `S3 bucket` box- Click `Create`4. If 1 or more trails already exist, select the target trail to enable for global logging 5. Click the edit icon (pencil) next to `Apply trail to all regions` , Click `Yes` and Click `Save`. 6. Click the edit icon (pencil) next to `Management Events` click `All` for setting `Read/Write Events` and Click `Save`.**From Command Line:** ``` aws cloudtrail create-trail --name  --bucket-name  --is-multi-region-trailaws cloudtrail update-trail --name  --is-multi-region-trail ```Note: Creating CloudTrail via CLI without providing any overriding options configures `Management Events` to set `All` type of `Read/Writes` by default.","AdditionalInformation": ""}],"description": "Ensure CloudTrail is enabled in all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3.2": {"name": "3.2","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-file-validation-enabling.html","Description": "CloudTrail log file validation creates a digitally signed digest file containing a hash of each log that CloudTrail writes to S3. These digest files can be used to determine whether a log file was changed, deleted, or unchanged after CloudTrail delivered the log. It is recommended that file validation be enabled on all CloudTrails.","DefaultValue": null,"AuditProcedure": "Perform the following on each trail to determine if log file validation is enabled:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane 3. For Every Trail: - Click on a trail via the link in the _Name_ column - Under the `General details` section, ensure `Log file validation` is set to `Enabled` **From Command Line:** ``` aws cloudtrail describe-trails ``` Ensure `LogFileValidationEnabled` is set to `true` for each trail","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling log file validation will provide additional integrity checking of CloudTrail logs.","RemediationProcedure": "Perform the following to enable log file validation on a given trail:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane 3. Click on target trail 4. Within the `General details` section click `edit` 5. Under the `Advanced settings` section 6. Check the enable box under `Log file validation`7. Click `Save changes` **From Command Line:** ``` aws cloudtrail update-trail --name  --enable-log-file-validation ``` Note that periodic validation of logs using these digests can be performed by running the following command: ``` aws cloudtrail validate-logs --trail-arn  --start-time  --end-time  ```","AdditionalInformation": ""}],"description": "Ensure CloudTrail log file validation is enabled","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.3": {"name": "3.3","checks": {"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html","Description": "CloudTrail logs a record of every API call made in your AWS account. These logs file are stored in an S3 bucket. It is recommended that the bucket policy or access control list (ACL) applied to the S3 bucket that CloudTrail logs to prevent public access to the CloudTrail logs.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if any public access is granted to an S3 bucket via an ACL or S3 bucket policy:**From Console:**1. Go to the Amazon CloudTrail console at [https://console.aws.amazon.com/cloudtrail/home](https://console.aws.amazon.com/cloudtrail/home) 2. In the `API activity history` pane on the left, click `Trails`3. In the `Trails` pane, note the bucket names in the `S3 bucket` column 4. Go to Amazon S3 console at [https://console.aws.amazon.com/s3/home](https://console.aws.amazon.com/s3/home) 5. For each bucket noted in step 3, right-click on the bucket and click `Properties`6. In the `Properties` pane, click the `Permissions` tab. 7. The tab shows a list of grants, one row per grant, in the bucket ACL. Each row identifies the grantee and the permissions granted. 8. Ensure no rows exists that have the `Grantee` set to `Everyone` or the `Grantee` set to `Any Authenticated User.`9. If the `Edit bucket policy` button is present, click it to review the bucket policy. 10. Ensure the policy does not contain a `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ```aws cloudtrail describe-trails --query 'trailList[*].S3BucketName' ``` 2. Ensure the `AllUsers` principal is not granted privileges to that `` : ```aws s3api get-bucket-acl --bucket  --query 'Grants[?Grantee.URI== `https://acs.amazonaws.com/groups/global/AllUsers` ]' ``` 3. Ensure the `AuthenticatedUsers` principal is not granted privileges to that ``: ```aws s3api get-bucket-acl --bucket  --query 'Grants[?Grantee.URI== `https://acs.amazonaws.com/groups/global/Authenticated Users` ]' ``` 4. Get the S3 Bucket Policy ```aws s3api get-bucket-policy --bucket ``` 5. Ensure the policy does not contain a `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}**Note:** Principal set to \"\\*\" or {\"AWS\" : \"\\*\"} allows anonymous access.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Allowing public access to CloudTrail log content may aid an adversary in identifying weaknesses in the affected account's use or configuration.","RemediationProcedure": "Perform the following to remove any public access that has been granted to the bucket via an ACL or S3 bucket policy:1. Go to Amazon S3 console at [https://console.aws.amazon.com/s3/home](https://console.aws.amazon.com/s3/home) 2. Right-click on the bucket and click Properties 3. In the `Properties` pane, click the `Permissions` tab. 4. The tab shows a list of grants, one row per grant, in the bucket ACL. Each row identifies the grantee and the permissions granted. 5. Select the row that grants permission to `Everyone` or `Any Authenticated User`6. Uncheck all the permissions granted to `Everyone` or `Any Authenticated User` (click `x` to delete the row). 7. Click `Save` to save the ACL. 8. If the `Edit bucket policy` button is present, click it. 9. Remove any `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}.","AdditionalInformation": ""}],"description": "Ensure the S3 bucket used to store CloudTrail logs is not publicly accessible","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3.4": {"name": "3.4","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-user-guide.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/how-cloudtrail-works.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-aws-service-specific-topics.html","Description": "AWS CloudTrail is a web service that records AWS API calls made in a given AWS account. 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. CloudTrail uses Amazon S3 for log file storage and delivery, so log files are stored durably. In addition to capturing CloudTrail logs within a specified S3 bucket for long term analysis, realtime analysis can be performed by configuring CloudTrail to send logs to CloudWatch Logs. For a trail that is enabled in all regions in an account, CloudTrail sends log files from all those regions to a CloudWatch Logs log group. It is recommended that CloudTrail logs be sent to CloudWatch Logs.Note: The intent of this recommendation is to ensure AWS account activity is being captured, monitored, and appropriately alarmed on. CloudWatch Logs is a native way to accomplish this using AWS services but does not preclude the use of an alternate solution.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure CloudTrail is configured as prescribed:**From Console:**1. Login to the CloudTrail console at `https://console.aws.amazon.com/cloudtrail/` 2. Under `Trails` , click on the CloudTrail you wish to evaluate 3. Under the `CloudWatch Logs` section. 4. Ensure a `CloudWatch Logs` log group is configured and listed. 5. Under `General details` confirm `Last log file delivered` has a recent (~one day old) timestamp.**From Command Line:**1. Run the following command to get a listing of existing trails: ```aws cloudtrail describe-trails ``` 2. Ensure `CloudWatchLogsLogGroupArn` is not empty and note the value of the `Name` property. 3. Using the noted value of the `Name` property, run the following command: ```aws cloudtrail get-trail-status --name  ``` 4. Ensure the `LatestcloudwatchLogdDeliveryTime` property is set to a recent (~one day old) timestamp.If the `CloudWatch Logs` log group is not setup and the delivery time is not recent refer to the remediation below.","ImpactStatement": "Note: By default, CloudWatch Logs will store Logs indefinitely unless a specific retention period is defined for the log group. When choosing the number of days to retain, keep in mind the average days it takes an organization to realize they have been breached is 210 days (at the time of this writing). Since additional time is required to research a breach, a minimum 365 day retention policy allows time for detection and research. You may also wish to archive the logs to a cheaper storage service rather than simply deleting them. See the following AWS resource to manage CloudWatch Logs retention periods:1. https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/SettingLogRetention.html","AssessmentStatus": "Automated","RationaleStatement": "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.","RemediationProcedure": "Perform the following to establish the prescribed state:**From Console:**1. Login to the CloudTrail console at `https://console.aws.amazon.com/cloudtrail/` 2. Select the `Trail` the needs to be updated. 3. Scroll down to `CloudWatch Logs` 4. Click `Edit` 5. Under `CloudWatch Logs` click the box `Enabled` 6. Under `Log Group` pick new or select an existing log group 7. Edit the `Log group name` to match the CloudTrail or pick the existing CloudWatch Group. 8. Under `IAM Role` pick new or select an existing. 9. Edit the `Role name` to match the CloudTrail or pick the existing IAM Role. 10. Click `Save changes.**From Command Line:** ``` aws cloudtrail update-trail --name  --cloudwatch-logs-log-group-arn  --cloudwatch-logs-role-arn  ```","AdditionalInformation": ""}],"description": "Ensure CloudTrail trails are integrated with CloudWatch Logs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.5": {"name": "3.5","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/cli/latest/reference/configservice/describe-configuration-recorder-status.html","Description": "AWS Config is a web service that performs configuration management of supported AWS resources within your account and delivers log files to you. The recorded information includes the configuration item (AWS resource), relationships between configuration items (AWS resources), any configuration changes between resources. It is recommended AWS Config be enabled in all regions.","DefaultValue": null,"AuditProcedure": "Process to evaluate AWS Config configuration per region**From Console:**1. Sign in to the AWS Management Console and open the AWS Config console at [https://console.aws.amazon.com/config/](https://console.aws.amazon.com/config/). 2. On the top right of the console select target Region. 3. If presented with Setup AWS Config - follow remediation procedure: 4. On the Resource inventory page, Click on edit (the gear icon). The Set Up AWS Config page appears. 5. Ensure 1 or both check-boxes under \"All Resources\" is checked.- Include global resources related to IAM resources - which needs to be enabled in 1 region only 6. Ensure the correct S3 bucket has been defined. 7. Ensure the correct SNS topic has been defined. 8. Repeat steps 2 to 7 for each region.**From Command Line:**1. Run this command to show all AWS Config recorders and their properties: ``` aws configservice describe-configuration-recorders ``` 2. Evaluate the output to ensure that there's at least one recorder for which `recordingGroup` object includes `\"allSupported\": true` AND `\"includeGlobalResourceTypes\": true`Note: There is one more parameter \"ResourceTypes\" in recordingGroup object. We don't need to check the same as whenever we set \"allSupported\": true, AWS enforces resource types to be empty (\"ResourceTypes\":[])Sample Output:``` {\"ConfigurationRecorders\": [{\"recordingGroup\": {\"allSupported\": true,\"resourceTypes\": [],\"includeGlobalResourceTypes\": true},\"roleARN\": \"arn:aws:iam:::role/service-role/\",\"name\": \"default\"}] } ```3. Run this command to show the status for all AWS Config recorders: ``` aws configservice describe-configuration-recorder-status ``` 4. In the output, find recorders with `name` key matching the recorders that met criteria in step 2. Ensure that at least one of them includes `\"recording\": true` and `\"lastStatus\": \"SUCCESS\"`","ImpactStatement": "It is recommended AWS Config be enabled in all regions.","AssessmentStatus": "Automated","RationaleStatement": "The AWS configuration item history captured by AWS Config enables security analysis, resource change tracking, and compliance auditing.","RemediationProcedure": "To implement AWS Config configuration:**From Console:**1. Select the region you want to focus on in the top right of the console 2. Click `Services`3. Click `Config`4. Define which resources you want to record in the selected region 5. Choose to include global resources (IAM resources) 6. Specify an S3 bucket in the same account or in another managed AWS account 7. Create an SNS Topic from the same AWS account or another managed AWS account**From Command Line:**1. Ensure there is an appropriate S3 bucket, SNS topic, and IAM role per the [AWS Config Service prerequisites](http://docs.aws.amazon.com/config/latest/developerguide/gs-cli-prereq.html). 2. Run this command to set up the configuration recorder ``` aws configservice subscribe --s3-bucket my-config-bucket --sns-topic arn:aws:sns:us-east-1:012345678912:my-config-notice --iam-role arn:aws:iam::012345678912:role/myConfigRole ``` 3. Run this command to start the configuration recorder: ``` start-configuration-recorder --configuration-recorder-name  ```","AdditionalInformation": ""}],"description": "Ensure AWS Config is enabled in all regions","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.6": {"name": "3.6","checks": {"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerLogs.html","Description": "S3 Bucket Access Logging generates a log that contains access records for each request made to your S3 bucket. An access log record contains details about the request, such as the request type, the resources specified in the request worked, and the time and date the request was processed. It is recommended that bucket access logging be enabled on the CloudTrail S3 bucket.","DefaultValue": null,"AuditProcedure": "Perform the following ensure the CloudTrail S3 bucket has access logging is enabled:**From Console:**1. Go to the Amazon CloudTrail console at [https://console.aws.amazon.com/cloudtrail/home](https://console.aws.amazon.com/cloudtrail/home) 2. In the API activity history pane on the left, click Trails 3. In the Trails pane, note the bucket names in the S3 bucket column 4. Sign in to the AWS Management Console and open the S3 console at [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3). 5. Under `All Buckets` click on a target S3 bucket 6. Click on `Properties` in the top right of the console 7. Under `Bucket:` _ `` _ click on `Logging`8. Ensure `Enabled` is checked.**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ```aws cloudtrail describe-trails --query 'trailList[*].S3BucketName'``` 2. Ensure Bucket Logging is enabled: ``` aws s3api get-bucket-logging --bucket  ``` Ensure command does not returns empty output.Sample Output for a bucket with logging enabled:``` {\"LoggingEnabled\": {\"TargetPrefix\": \"\",\"TargetBucket\": \"\"} } ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "By enabling S3 bucket logging on target S3 buckets, it is possible to capture all events which may affect objects within any target buckets. Configuring logs to be placed in a separate bucket allows access to log information which can be useful in security and incident response workflows.","RemediationProcedure": "Perform the following to enable S3 bucket logging:**From Console:**1. Sign in to the AWS Management Console and open the S3 console at [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3). 2. Under `All Buckets` click on the target S3 bucket 3. Click on `Properties` in the top right of the console 4. Under `Bucket:`  click on `Logging`5. Configure bucket logging- Click on the `Enabled` checkbox- Select Target Bucket from list- Enter a Target Prefix 6. Click `Save`.**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ``` aws cloudtrail describe-trails --region  --query trailList[*].S3BucketName ``` 2. Copy and add target bucket name at ``, Prefix for logfile at `` and optionally add an email address in the following template and save it as ``: ``` {\"LoggingEnabled\": {\"TargetBucket\": \"\",\"TargetPrefix\": \"\",\"TargetGrants\": [{\"Grantee\": {\"Type\": \"AmazonCustomerByEmail\",\"EmailAddress\": \"\"},\"Permission\": \"FULL_CONTROL\"}]}} ``` 3. Run the `put-bucket-logging` command with bucket name and `` as input, for more information refer at [put-bucket-logging](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-logging.html): ``` aws s3api put-bucket-logging --bucket  --bucket-logging-status file:// ```","AdditionalInformation": ""}],"description": "Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.7": {"name": "3.7","checks": {"cloudtrail_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/encrypting-cloudtrail-log-files-with-aws-kms.html:https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html","Description": "AWS CloudTrail is a web service that records AWS API calls for an account and makes those logs available to users and resources in accordance with IAM policies. AWS Key Management Service (KMS) is a managed service that helps create and control the encryption keys used to encrypt account data, and uses Hardware Security Modules (HSMs) to protect the security of encryption keys. CloudTrail logs can be configured to leverage server side encryption (SSE) and KMS customer created master keys (CMK) to further protect CloudTrail logs. It is recommended that CloudTrail be configured to use SSE-KMS.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if CloudTrail is configured to use SSE-KMS:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. In the left navigation pane, choose `Trails` . 3. Select a Trail 4. Under the `S3` section, ensure `Encrypt log files` is set to `Yes` and a KMS key ID is specified in the `KSM Key Id` field.**From Command Line:**1. Run the following command: ```aws cloudtrail describe-trails``` 2. For each trail listed, SSE-KMS is enabled if the trail has a `KmsKeyId` property defined.","ImpactStatement": "Customer created keys incur an additional cost. See https://aws.amazon.com/kms/pricing/ for more information.","AssessmentStatus": "Automated","RationaleStatement": "Configuring CloudTrail to use SSE-KMS provides additional confidentiality controls on log data as a given user must have S3 read permission on the corresponding log bucket and must be granted decrypt permission by the CMK policy.","RemediationProcedure": "Perform the following to configure CloudTrail to use SSE-KMS:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. In the left navigation pane, choose `Trails` . 3. Click on a Trail 4. Under the `S3` section click on the edit button (pencil icon) 5. Click `Advanced`6. Select an existing CMK from the `KMS key Id` drop-down menu- Note: Ensure the CMK is located in the same region as the S3 bucket- Note: You will need to apply a KMS Key policy on the selected CMK in order for CloudTrail as a service to encrypt and decrypt log files using the CMK provided. Steps are provided [here](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/create-kms-key-policy-for-cloudtrail.html) for editing the selected CMK Key policy 7. Click `Save`8. You will see a notification message stating that you need to have decrypt permissions on the specified KMS key to decrypt log files. 9. Click `Yes` **From Command Line:** ``` aws cloudtrail update-trail --name  --kms-id  aws kms put-key-policy --key-id  --policy  ```","AdditionalInformation": "3 statements which need to be added to the CMK policy:1\\. Enable Cloudtrail to describe CMK properties ``` 
{\"Sid\": \"Allow CloudTrail access\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\"Action\": \"kms:DescribeKey\",\"Resource\": \"*\" } ``` 2\\. Granting encrypt permissions ``` 
{\"Sid\": \"Allow CloudTrail to encrypt logs\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\"Action\": \"kms:GenerateDataKey*\",\"Resource\": \"*\",\"Condition\": {\"StringLike\": {\"kms:EncryptionContext:aws:cloudtrail:arn\": [\"arn:aws:cloudtrail:*:aws-account-id:trail/*\"]}} } ``` 3\\. Granting decrypt permissions ``` 
{\"Sid\": \"Enable CloudTrail log decrypt permissions\",\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"arn:aws:iam::aws-account-id:user/username\"},\"Action\": \"kms:Decrypt\",\"Resource\": \"*\",\"Condition\": {\"Null\": {\"kms:EncryptionContext:aws:cloudtrail:arn\": \"false\"}} } ```"}],"description": "Ensure CloudTrail logs are encrypted at rest using KMS CMKs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.8": {"name": "3.8","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://aws.amazon.com/kms/pricing/:https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final","Description": "AWS Key Management Service (KMS) allows customers to rotate the backing key which is key material stored within the KMS which is tied to the key ID of the Customer Created customer master key (CMK). It is the backing key that is used to perform cryptographic operations such as encryption and decryption. Automated key rotation currently retains all prior backing keys so that decryption of encrypted data can take place transparently. It is recommended that CMK key rotation be enabled for symmetric keys. Key rotation can not be enabled for any asymmetric CMK.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam](https://console.aws.amazon.com/iam). 2. In the left navigation pane, choose `Customer managed keys` 3. Select a customer managed CMK where `Key spec = SYMMETRIC_DEFAULT` 4. Underneath the `General configuration` panel open the tab `Key rotation` 5. Ensure that the checkbox `Automatically rotate this KMS key every year.` is activated 6. Repeat steps 3 - 5 for all customer managed CMKs where \"Key spec = SYMMETRIC_DEFAULT\"**From Command Line:**1. Run the following command to get a list of all keys and their associated `KeyIds````aws kms list-keys ``` 2. For each key, note the KeyId and run the following command ``` describe-key --key-id  ``` 3. If the response contains \"KeySpec = SYMMETRIC_DEFAULT\" run the following command ```aws kms get-key-rotation-status --key-id  ``` 4. Ensure `KeyRotationEnabled` is set to `true` 5. Repeat steps 2 - 4 for all remaining CMKs","ImpactStatement": "Creation, management, and storage of CMKs may require additional time from and administrator.","AssessmentStatus": "Automated","RationaleStatement": "Rotating encryption keys helps reduce the potential impact of a compromised key as data encrypted with a new key cannot be accessed with a previous key that may have been exposed. Keys should be rotated every year, or upon event that would result in the compromise of that key.","RemediationProcedure": "**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam](https://console.aws.amazon.com/iam). 2. In the left navigation pane, choose `Customer managed keys` . 3. Select a customer managed CMK where `Key spec = SYMMETRIC_DEFAULT` 4. Underneath the \"General configuration\" panel open the tab \"Key rotation\" 5. Check the \"Automatically rotate this KMS key every year.\" checkbox**From Command Line:**1. Run the following command to enable key rotation: ```aws kms enable-key-rotation --key-id  ```","AdditionalInformation": ""}],"description": "Ensure rotation for customer created symmetric CMKs is enabled","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.9": {"name": "3.9","checks": {"vpc_flow_logs_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/flow-logs.html","Description": "VPC Flow Logs is a feature that enables you to capture information about the IP traffic going to and from network interfaces in your VPC. After you've created a flow log, you can view and retrieve its data in Amazon CloudWatch Logs. It is recommended that VPC Flow Logs be enabled for packet \"Rejects\" for VPCs.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if VPC Flow logs are enabled:**From Console:**1. Sign into the management console 2. Select `Services` then `VPC`3. In the left navigation pane, select `Your VPCs`4. Select a VPC 5. In the right pane, select the `Flow Logs` tab. 6. Ensure a Log Flow exists that has `Active` in the `Status` column.**From Command Line:**1. Run `describe-vpcs` command (OSX/Linux/UNIX) to list the VPC networks available in the current AWS region: ``` aws ec2 describe-vpcs --region  --query Vpcs[].VpcId ``` 2. The command output returns the `VpcId` available in the selected region. 3. Run `describe-flow-logs` command (OSX/Linux/UNIX) using the VPC ID to determine if the selected virtual network has the Flow Logs feature enabled: ``` aws ec2 describe-flow-logs --filter \"Name=resource-id,Values=\" ``` 4. If there are no Flow Logs created for the selected VPC, the command output will return an `empty list []`. 5. Repeat step 3 for other VPCs available in the same region. 6. Change the region by updating `--region` and repeat steps 1 - 5 for all the VPCs.","ImpactStatement": "By default, CloudWatch Logs will store Logs indefinitely unless a specific retention period is defined for the log group. When choosing the number of days to retain, keep in mind the average days it takes an organization to realize they have been breached is 210 days (at the time of this writing). Since additional time is required to research a breach, a minimum 365 day retention policy allows time for detection and research. You may also wish to archive the logs to a cheaper storage service rather than simply deleting them. See the following AWS resource to manage CloudWatch Logs retention periods:1. https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/SettingLogRetention.html","AssessmentStatus": "Automated","RationaleStatement": "VPC Flow Logs provide visibility into network traffic that traverses the VPC and can be used to detect anomalous traffic or insight during security workflows.","RemediationProcedure": "Perform the following to determine if VPC Flow logs is enabled:**From Console:**1. Sign into the management console 2. Select `Services` then `VPC`3. In the left navigation pane, select `Your VPCs`4. Select a VPC 5. In the right pane, select the `Flow Logs` tab. 6. If no Flow Log exists, click `Create Flow Log`7. For Filter, select `Reject` 8. Enter in a `Role` and `Destination Log Group`9. Click `Create Log Flow`10. Click on `CloudWatch Logs Group` **Note:** Setting the filter to \"Reject\" will dramatically reduce the logging data accumulation for this recommendation and provide sufficient information for the purposes of breach detection, research and remediation. However, during periods of least privilege security group engineering, setting this the filter to \"All\" can be very helpful in discovering existing traffic flows required for proper operation of an already running environment.**From Command Line:**1. Create a policy document and name it as `role_policy_document.json` and paste the following content: ``` {\"Version\": \"2012-10-17\",\"Statement\": [{\"Sid\": \"test\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"ec2.amazonaws.com\"},\"Action\": \"sts:AssumeRole\"}] } ``` 2. Create another policy document and name it as `iam_policy.json` and paste the following content: ``` {\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Action\":[\"logs:CreateLogGroup\",\"logs:CreateLogStream\",\"logs:DescribeLogGroups\",\"logs:DescribeLogStreams\",\"logs:PutLogEvents\",\"logs:GetLogEvents\",\"logs:FilterLogEvents\"],\"Resource\": \"*\"}] } ``` 3. Run the below command to create an IAM role: ``` aws iam create-role --role-name  --assume-role-policy-document file://role_policy_document.json``` 4. Run the below command to create an IAM policy: ``` aws iam create-policy --policy-name  --policy-document file://iam-policy.json ``` 5. Run `attach-group-policy` command using the IAM policy ARN returned at the previous step to attach the policy to the IAM role (if the command succeeds, no output is returned): ``` aws iam attach-group-policy --policy-arn arn:aws:iam:::policy/ --group-name  ``` 6. Run `describe-vpcs` to get the VpcId available in the selected region: ``` aws ec2 describe-vpcs --region  ``` 7. The command output should return the VPC Id available in the selected region. 8. Run `create-flow-logs` to create a flow log for the vpc: ``` aws ec2 create-flow-logs --resource-type VPC --resource-ids  --traffic-type REJECT --log-group-name  --deliver-logs-permission-arn  ``` 9. Repeat step 8 for other vpcs available in the selected region. 10. Change the region by updating --region and repeat remediation procedure for other vpcs.","AdditionalInformation": ""}],"description": "Ensure VPC flow logging is enabled in all VPCs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"4.1": {"name": "4.1","checks": {"cloudwatch_log_metric_filter_unauthorized_api_calls": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://aws.amazon.com/sns/:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for unauthorized API calls.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with \"Name\":` note ``- From value associated with \"CloudWatchLogsLogGroupArn\" note Example: for CloudWatchLogsLogGroupArn that looks like arn:aws:logs:::log-group:NewGroup:*,  would be NewGroup- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name <\"Name\" as shown in describe-trails>`Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this `` that you captured in step 1:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.errorCode = *UnauthorizedOperation) || ($.errorCode = AccessDenied*) || ($.sourceIPAddress!=delivery.logs.amazonaws.com) || ($.eventName!=HeadBucket) }\", ```4. Note the \"filterName\" `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query \"MetricAlarms[?MetricName == `unauthorized_api_calls_metric`]\" ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "This alert may be triggered by normal read-only console activities that attempt to opportunistically gather optional information, but gracefully fail if they don't have permissions.If an excessive number of alerts are being generated then an organization may wish to consider adding read access to the limited IAM user permissions simply to quiet the alerts.In some cases doing this may allow the users to actually view some areas of the system - any additional access given should be reviewed for alignment with the original limited IAM user intent.","AssessmentStatus": "Automated","RationaleStatement": "Monitoring unauthorized API calls will help reveal application errors and may reduce time to detect malicious activity.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for unauthorized API calls and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name \"cloudtrail_log_group_name\" --filter-name \"\" --metric-transformations metricName=unauthorized_api_calls_metric,metricNamespace=CISBenchmark,metricValue=1 --filter-pattern \"{ ($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\") || ($.sourceIPAddress!=\"delivery.logs.amazonaws.com\") || ($.eventName!=\"HeadBucket\") }\" ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms. **Note**: Capture the TopicArn displayed when creating the SNS Topic in Step 2.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name \"unauthorized_api_calls_alarm\" --metric-name \"unauthorized_api_calls_metric\" --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace \"CISBenchmark\" --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for unauthorized API calls","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.2": {"name": "4.2","checks": {"cloudwatch_log_metric_filter_sign_in_without_mfa": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/viewing_metrics_with_cloudwatch.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for console logins that are not protected by multi-factor authentication (MFA).","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all `CloudTrails`:``` aws cloudtrail describe-trails ```- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region `CloudTrail` is active``` aws cloudtrail get-trail-status --name  ```Ensure in the output that `IsLogging` is set to `TRUE`- Ensure identified Multi-region 'Cloudtrail' captures all Management Events``` aws cloudtrail get-event-selectors --trail-name  ```Ensure in the output there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }\" ```Or (To reduce false positives incase Single Sign-On (SSO) is used in organization):``` \"filterPattern\": \"{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\") }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring for single-factor console logins will increase visibility into accounts that are not protected by MFA.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Management Console sign-in without MFA and the `` taken from audit step 1.Use Command: ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }' ```Or (To reduce false positives incase Single Sign-On (SSO) is used in organization):``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\") }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored -Filter pattern set to `{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\"}` reduces false alarms raised when user logs in via SSO account."}],"description": "Ensure a log metric filter and alarm exist for Management Console sign-in without MFA","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.3": {"name": "4.3","checks": {"cloudwatch_log_metric_filter_root_usage": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for 'root' login attempts.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails:`aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring for 'root' account logins will provide visibility into the use of a fully privileged account and an opportunity to reduce the use of it.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for 'Root' account usage and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name `` --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "**Configuring log metric filter and alarm on Multi-region (global) CloudTrail**- ensures that activities from all regions (used as well as unused) are monitored- ensures that activities on all supported global services are monitored- ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for usage of 'root' account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.4": {"name": "4.4","checks": {"cloudwatch_log_metric_filter_policy_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established changes made to Identity and Access Management (IAM) policies.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails:`aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to IAM policies will help ensure authentication and authorization controls remain intact.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for IAM policy changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name `` --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for IAM policy changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.5": {"name": "4.5","checks": {"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for detecting changes to CloudTrail's configurations.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to CloudTrail's configuration will help ensure sustained visibility to activities performed in the AWS account.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for cloudtrail configuration changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for CloudTrail configuration changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.6": {"name": "4.6","checks": {"cloudwatch_log_metric_filter_authentication_failures": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for failed console authentication attempts.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring failed console logins may decrease lead time to detect an attempt to brute force a credential, which may provide an indicator, such as source IP, that can be used in other event correlation.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS management Console Login Failures and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }' ``` **Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for AWS Management Console authentication failures","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.7": {"name": "4.7","checks": {"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for customer created CMKs which have changed state to disabled or scheduled deletion.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Data encrypted with disabled or deleted keys will no longer be accessible.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for disabled or scheduled for deletion CMK's and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }' ``` **Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.8": {"name": "4.8","checks": {"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for changes to S3 bucket policies.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to S3 bucket policies may reduce time to detect and correct permissive policies on sensitive S3 buckets.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for S3 bucket policy changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for S3 bucket policy changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.9": {"name": "4.9","checks": {"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for detecting changes to CloudTrail's configurations.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to AWS Config configuration will help ensure sustained visibility of configuration items within the AWS account.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Configuration changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for AWS Config configuration changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"5.1": {"name": "5.1","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html:https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Security.html#VPC_Security_Comparison","Description": "The Network Access Control List (NACL) function provide stateless filtering of ingress and egress network traffic to AWS resources. It is recommended that no NACL allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "**From Console:**Perform the following to determine if the account is configured as prescribed: 1. Login to the AWS Management Console at https://console.aws.amazon.com/vpc/home 2. In the left pane, click `Network ACLs` 3. For each network ACL, perform the following:- Select the network ACL- Click the `Inbound Rules` tab- Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `0.0.0.0/0` and shows `ALLOW`**Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "**From Console:**Perform the following: 1. Login to the AWS Management Console at https://console.aws.amazon.com/vpc/home 2. In the left pane, click `Network ACLs` 3. For each network ACL to remediate, perform the following:- Select the network ACL- Click the `Inbound Rules` tab- Click `Edit inbound rules`- Either A) update the Source field to a range other than 0.0.0.0/0, or, B) Click `Delete` to remove the offending inbound rule- Click `Save`","AdditionalInformation": ""}],"description": "Ensure no Network ACLs allow ingress from 0.0.0.0/0 to remote server administration ports","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"5.2": {"name": "5.2","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#deleting-security-group-rule","Description": "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `0.0.0.0/0` **Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports.","ImpactStatement": "When updating an existing environment, ensure that administrators have access to remote server administration ports through another mechanism before removing access by deleting the 0.0.0.0/0 inbound rule.","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "Perform the following to implement the prescribed state:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Click the `Edit inbound rules` button 4. Identify the rules to be edited or removed 5. Either A) update the Source field to a range other than 0.0.0.0/0, or, B) Click `Delete` to remove the offending inbound rule 6. Click `Save rules`","AdditionalInformation": ""}],"description": "Ensure no security groups allow ingress from 0.0.0.0/0 to remote server administration ports","checks_status": {"fail": 0,"pass": 3,"total": 3,"manual": 0}},"5.3": {"name": "5.3","checks": {"ec2_securitygroup_default_restrict_traffic": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#default-security-group","Description": "A VPC comes with a default security group whose initial settings deny all inbound traffic, allow all outbound traffic, and allow all traffic between instances assigned to the security group. If you don't specify a security group when you launch an instance, the instance is automatically assigned to this default security group. Security groups provide stateful filtering of ingress/egress network traffic to AWS resources. It is recommended that the default security group restrict all traffic.The default VPC in every region should have its default security group updated to comply. Any newly created VPCs will automatically contain a default security group that will need remediation to comply with this recommendation.**NOTE:** When implementing this recommendation, VPC flow logging is invaluable in determining the least privilege port access required by systems to work properly because it can log all packet acceptances and rejections occurring under the current security groups. This dramatically reduces the primary barrier to least privilege engineering - discovering the minimum ports required by systems in the environment. Even if the VPC flow logging recommendation in this benchmark is not adopted as a permanent security measure, it should be used during any period of discovery and engineering for least privileged security groups.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:Security Group State1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. For each default security group, perform the following: 1. Select the `default` security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exist 4. Click the `Outbound Rules` tab 5. Ensure no rules existSecurity Group Members1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all default groups in all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. Copy the id of the default security group. 5. Change to the EC2 Management Console at https://console.aws.amazon.com/ec2/v2/home 6. In the filter column type 'Security Group ID : < security group id from #4 >'","ImpactStatement": "Implementing this recommendation in an existing VPC containing operating resources requires extremely careful migration planning as the default security groups are likely to be enabling many ports that are unknown. Enabling VPC flow logging (of accepts) in an existing environment that is known to be breach free will reveal the current pattern of ports being used for each instance to communicate successfully.","AssessmentStatus": "Automated","RationaleStatement": "Configuring all VPC default security groups to restrict all traffic will encourage least privilege security group development and mindful placement of AWS resources into security groups which will in-turn reduce the exposure of those resources.","RemediationProcedure": "Security Group MembersPerform the following to implement the prescribed state:1. Identify AWS resources that exist within the default security group 2. Create a set of least privilege security groups for those resources 3. Place the resources in those security groups 4. Remove the resources noted in #1 from the default security groupSecurity Group State1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. For each default security group, perform the following: 1. Select the `default` security group 2. Click the `Inbound Rules` tab 3. Remove any inbound rules 4. Click the `Outbound Rules` tab 5. Remove any Outbound rulesRecommended:IAM groups allow you to edit the \"name\" field. After remediating default groups rules for all VPCs in all regions, edit this field to add text similar to \"DO NOT USE. DO NOT ADD RULES\"","AdditionalInformation": ""}],"description": "Ensure the default security group of every VPC restricts all traffic","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"5.4": {"name": "5.4","checks": {"vpc_peering_routing_tables_with_least_privilege": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "5. Networking","References": "https://docs.aws.amazon.com/AmazonVPC/latest/PeeringGuide/peering-configurations-partial-access.html:https://docs.aws.amazon.com/cli/latest/reference/ec2/create-vpc-peering-connection.html","Description": "Once a VPC peering connection is established, routing tables must be updated to establish any connections between the peered VPCs. These routes can be as specific as desired - even peering a VPC to only a single host on the other side of the connection.","DefaultValue": null,"AuditProcedure": "Review routing tables of peered VPCs for whether they route all subnets of each VPC and whether that is necessary to accomplish the intended purposes for peering the VPCs.**From Command Line:**1. List all the route tables from a VPC and check if \"GatewayId\" is pointing to a __ (e.g. pcx-1a2b3c4d) and if \"DestinationCidrBlock\" is as specific as desired. ``` aws ec2 describe-route-tables --filter \"Name=vpc-id,Values=\" --query \"RouteTables[*].{RouteTableId:RouteTableId, VpcId:VpcId, Routes:Routes, AssociatedSubnets:Associations[*].SubnetId}\" ```","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Being highly selective in peering routing tables is a very effective way of minimizing the impact of breach as resources outside of these routes are inaccessible to the peered VPC.","RemediationProcedure": "Remove and add route table entries to ensure that the least number of subnets or hosts as is required to accomplish the purpose for peering are routable.**From Command Line:**1. For each __ containing routes non compliant with your routing policy (which grants more than desired \"least access\"), delete the non compliant route: ``` aws ec2 delete-route --route-table-id  --destination-cidr-block  ```2. Create a new compliant route: ``` aws ec2 create-route --route-table-id  --destination-cidr-block  --vpc-peering-connection-id  ```","AdditionalInformation": "If an organization has AWS transit gateway implemented in their VPC architecture they should look to apply the recommendation above for \"least access\" routing architecture at the AWS transit gateway level in combination with what must be implemented at the standard VPC route table. More specifically, to route traffic between two or more VPCs via a transit gateway VPCs must have an attachment to a transit gateway route table as well as a route, therefore to avoid routing traffic between VPCs an attachment to the transit gateway route table should only be added where there is an intention to route traffic between the VPCs. As transit gateways are able to host multiple route tables it is possible to group VPCs by attaching them to a common route table."}],"description": "Ensure routing tables for VPC peering are \"least access\"","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.10": {"name": "1.10","checks": {"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://tools.ietf.org/html/rfc6238:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#enable-mfa-for-privileged-users:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html:https://blogs.aws.amazon.com/security/post/Tx2SJJYE082KBUK/How-to-Delegate-Management-of-Multi-Factor-Authentication-to-AWS-IAM-Users","Description": "Multi-Factor Authentication (MFA) adds an extra layer of authentication assurance beyond traditional credentials. With MFA enabled, when a user signs in to the AWS Console, they will be prompted for their user name and password as well as for an authentication code from their physical or virtual MFA token. It is recommended that MFA be enabled for all accounts that have a console password.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if a MFA device is enabled for all IAM users having a console password:**From Console:**1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the left pane, select `Users`3. If the `MFA` or `Password age` columns are not visible in the table, click the gear icon at the upper right corner of the table and ensure a checkmark is next to both, then click `Close`. 4. Ensure that for each user where the `Password age` column shows a password age, the `MFA` column shows `Virtual`, `U2F Security Key`, or `Hardware`.**From Command Line:**1. Run the following command (OSX/Linux/UNIX) to generate a list of all IAM users along with their password and MFA status: ```aws iam generate-credential-report ``` ```aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,8``` 2. The output of this command will produce a table similar to the following: ```user,password_enabled,mfa_activeelise,false,falsebrandon,true,truerakesh,false,falsehelene,false,falseparas,true,trueanitha,false,false``` 3. For any column having `password_enabled` set to `true` , ensure `mfa_active` is also set to `true.`","ImpactStatement": "AWS will soon end support for SMS multi-factor authentication (MFA). New customers are not allowed to use this feature. We recommend that existing customers switch to one of the following alternative methods of MFA.","AssessmentStatus": "Automated","RationaleStatement": "Enabling MFA provides increased security for console access as it requires the authenticating principal to possess a device that displays a time-sensitive key and have knowledge of a credential.","RemediationProcedure": "Perform the following to enable MFA:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at 'https://console.aws.amazon.com/iam/' 2. In the left pane, select `Users`. 3. In the `User Name` list, choose the name of the intended MFA user. 4. Choose the `Security Credentials` tab, and then choose `Manage MFA Device`. 5. In the `Manage MFA Device wizard`, choose `Virtual MFA` device, and then choose `Continue`. IAM generates and displays configuration information for the virtual MFA device, including a QR code graphic. The graphic is a representation of the 'secret configuration key' that is available for manual entry on devices that do not support QR codes.6. Open your virtual MFA application. (For a list of apps that you can use for hosting virtual MFA devices, see Virtual MFA Applications at https://aws.amazon.com/iam/details/mfa/#Virtual_MFA_Applications). If the virtual MFA application supports multiple accounts (multiple virtual MFA devices), choose the option to create a new account (a new virtual MFA device). 7. Determine whether the MFA app supports QR codes, and then do one of the following: - Use the app to scan the QR code. For example, you might choose the camera icon or choose an option similar to Scan code, and then use the device's camera to scan the code.- In the Manage MFA Device wizard, choose Show secret key for manual configuration, and then type the secret configuration key into your MFA application. When you are finished, the virtual MFA device starts generating one-time passwords.8. In the `Manage MFA Device wizard`, in the `MFA Code 1 box`, type the `one-time password` that currently appears in the virtual MFA device. Wait up to 30 seconds for the device to generate a new one-time password. Then type the second `one-time password` into the `MFA Code 2 box`.9. Click `Assign MFA`.","AdditionalInformation": "**Forced IAM User Self-Service Remediation**Amazon has published a pattern that forces users to self-service setup MFA before they have access to their complete permissions set. Until they complete this step, they cannot access their full permissions. This pattern can be used on new AWS accounts. It can also be used on existing accounts - it is recommended users are given instructions and a grace period to accomplish MFA enrollment before active enforcement on existing AWS accounts."}],"description": "Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.11": {"name": "1.11","checks": {"iam_user_no_setup_initial_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/cli/latest/reference/iam/delete-access-key.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html","Description": "AWS console defaults to no check boxes selected when creating a new IAM user. When cerating the IAM User credentials you have to determine what type of access they require. Programmatic access: The IAM user might need to make API calls, use the AWS CLI, or use the Tools for Windows PowerShell. In that case, create an access key (access key ID and a secret access key) for that user. AWS Management Console access: If the user needs to access the AWS Management Console, create a password for the user.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if access keys were created upon user creation and are being used and rotated as prescribed:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on a User where column `Password age` and `Access key age` is not set to `None` 5. Click on `Security credentials` Tab 6. Compare the user 'Creation time` to the Access Key `Created` date. 6. For any that match, the key was created during initial user setup.- Keys that were created at the same time as the user profile and do not have a last used date should be deleted. Refer to the remediation below.**From Command Line:**1. Run the following command (OSX/Linux/UNIX) to generate a list of all IAM users along with their access keys utilization: ```aws iam generate-credential-report ``` ```aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,9,11,14,16 ``` 2. The output of this command will produce a table similar to the following: ``` user,password_enabled,access_key_1_active,access_key_1_last_used_date,access_key_2_active,access_key_2_last_used_dateelise,false,true,2015-04-16T15:14:00+00:00,false,N/Abrandon,true,true,N/A,false,N/Arakesh,false,false,N/A,false,N/Ahelene,false,true,2015-11-18T17:47:00+00:00,false,N/Aparas,true,true,2016-08-28T12:04:00+00:00,true,2016-03-04T10:11:00+00:00anitha,true,true,2016-06-08T11:43:00+00:00,true,N/A``` 3. For any user having `password_enabled` set to `true` AND `access_key_last_used_date` set to `N/A` refer to the remediation below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Requiring the additional steps be taken by the user for programmatic access after their profile has been created will give a stronger indication of intent that access keys are [a] necessary for their work and [b] once the access key is established on an account that the keys may be in use somewhere in the organization.**Note**: Even if it is known the user will need access keys, require them to create the keys themselves or put in a support ticket to have them created as a separate step from user creation.","RemediationProcedure": "Perform the following to delete access keys that do not pass the audit:**From Console:**1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. As an Administrator - Click on the X `(Delete)` for keys that were created at the same time as the user profile but have not been used. 7. As an IAM User- Click on the X `(Delete)` for keys that were created at the same time as the user profile but have not been used.**From Command Line:** ``` aws iam delete-access-key --access-key-id  --user-name  ```","AdditionalInformation": "Credential report does not appear to contain \"Key Creation Date\""}],"description": "Do not setup access keys during initial user setup for all IAM users that have a console password","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.12": {"name": "1.12","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#remove-credentials:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_admin-change-user.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "AWS IAM users can access AWS resources using different types of credentials, such as passwords or access keys. It is recommended that all credentials that have been unused in 45 or greater days be deactivated or removed.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if unused credentials exist:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM` 4. Click on `Users` 5. Click the `Settings` (gear) icon. 6. Select `Console last sign-in`, `Access key last used`, and `Access Key Id` 7. Click on `Close`8. Check and ensure that `Console last sign-in` is less than 45 days ago.**Note** - `Never` means the user has never logged in.9. Check and ensure that `Access key age` is less than 45 days and that `Access key last used` does not say `None`If the user hasn't signed into the Console in the last 45 days or Access keys are over 45 days old refer to the remediation.**From Command Line:****Download Credential Report:**1. Run the following commands: ```aws iam generate-credential-report aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,5,6,9,10,11,14,15,16 | grep -v '^' ```**Ensure unused credentials do not exist:**2. For each user having `password_enabled` set to `TRUE` , ensure `password_last_used_date` is less than `45` days ago.- When `password_enabled` is set to `TRUE` and `password_last_used` is set to `No_Information` , ensure `password_last_changed` is less than 45 days ago.3. For each user having an `access_key_1_active` or `access_key_2_active` to `TRUE` , ensure the corresponding `access_key_n_last_used_date` is less than `45` days ago.- When a user having an `access_key_x_active` (where x is 1 or 2) to `TRUE` and corresponding access_key_x_last_used_date is set to `N/A', ensure `access_key_x_last_rotated` is less than 45 days ago.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Disabling or removing unnecessary credentials will reduce the window of opportunity for credentials associated with a compromised or abandoned account to be used.","RemediationProcedure": "**From Console:**Perform the following to manage Unused Password (IAM user console access)1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. Select user whose `Console last sign-in` is greater than 45 days 7. Click `Security credentials` 8. In section `Sign-in credentials`, `Console password` click `Manage`9. Under Console Access select `Disable` 10.Click `Apply`Perform the following to deactivate Access Keys:1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. Select any access keys that are over 45 days old and that have been used and - Click on `Make Inactive` 7. Select any access keys that are over 45 days old and that have not been used and - Click the X to `Delete`","AdditionalInformation": " is excluded in the audit since the root account should not be used for day to day business and would likely be unused for more than 45 days."}],"description": "Ensure credentials unused for 45 days or greater are disabled","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1.13": {"name": "1.13","checks": {"iam_user_two_active_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "Access keys are long-term credentials for an IAM user or the AWS account 'root' user. You can use access keys to sign programmatic requests to the AWS CLI or AWS API (directly or using the AWS SDK)","DefaultValue": null,"AuditProcedure": "**From Console:**1. Sign in to the AWS Management Console and navigate to IAM dashboard at `https://console.aws.amazon.com/iam/`. 2. In the left navigation panel, choose `Users`. 3. Click on the IAM user name that you want to examine. 4. On the IAM user configuration page, select `Security Credentials` tab. 5. Under `Access Keys` section, in the Status column, check the current status for each access key associated with the IAM user. If the selected IAM user has more than one access key activated then the users access configuration does not adhere to security best practices and the risk of accidental exposures increases. - Repeat steps no. 3 – 5 for each IAM user in your AWS account.**From Command Line:**1. Run `list-users` command to list all IAM users within your account: ``` aws iam list-users --query \"Users[*].UserName\" ``` The command output should return an array that contains all your IAM user names.2. Run `list-access-keys` command using the IAM user name list to return the current status of each access key associated with the selected IAM user: ``` aws iam list-access-keys --user-name  ``` The command output should expose the metadata `(\"Username\", \"AccessKeyId\", \"Status\", \"CreateDate\")` for each access key on that user account.3. Check the `Status` property value for each key returned to determine each keys current state. If the `Status` property value for more than one IAM access key is set to `Active`, the user access configuration does not adhere to this recommendation, refer to the remediation below.- Repeat steps no. 2 and 3 for each IAM user in your AWS account.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Access keys are long-term credentials for an IAM user or the AWS account 'root' user. You can use access keys to sign programmatic requests to the AWS CLI or AWS API. One of the best ways to protect your account is to not allow users to have multiple access keys.","RemediationProcedure": "**From Console:**1. Sign in to the AWS Management Console and navigate to IAM dashboard at `https://console.aws.amazon.com/iam/`. 2. In the left navigation panel, choose `Users`. 3. Click on the IAM user name that you want to examine. 4. On the IAM user configuration page, select `Security Credentials` tab. 5. In `Access Keys` section, choose one access key that is less than 90 days old. This should be the only active key used by this IAM user to access AWS resources programmatically. Test your application(s) to make sure that the chosen access key is working. 6. In the same `Access Keys` section, identify your non-operational access keys (other than the chosen one) and deactivate it by clicking the `Make Inactive` link. 7. If you receive the `Change Key Status` confirmation box, click `Deactivate` to switch off the selected key. 8. Repeat steps no. 3 – 7 for each IAM user in your AWS account.**From Command Line:**1. Using the IAM user and access key information provided in the `Audit CLI`, choose one access key that is less than 90 days old. This should be the only active key used by this IAM user to access AWS resources programmatically. Test your application(s) to make sure that the chosen access key is working.2. Run the `update-access-key` command below using the IAM user name and the non-operational access key IDs to deactivate the unnecessary key(s). Refer to the Audit section to identify the unnecessary access key ID for the selected IAM user**Note** - the command does not return any output: ``` aws iam update-access-key --access-key-id  --status Inactive --user-name  ``` 3. To confirm that the selected access key pair has been successfully `deactivated` run the `list-access-keys` audit command again for that IAM User: ``` aws iam list-access-keys --user-name  ``` - The command output should expose the metadata for each access key associated with the IAM user. If the non-operational key pair(s) `Status` is set to `Inactive`, the key has been successfully deactivated and the IAM user access configuration adheres now to this recommendation.4. Repeat steps no. 1 – 3 for each IAM user in your AWS account.","AdditionalInformation": ""}],"description": "Ensure there is only one active access key available for any single IAM user","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.14": {"name": "1.14","checks": {"iam_rotate_access_key_90_days": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#rotate-credentials:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html:https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "Access keys consist of an access key ID and secret access key, which are used to sign programmatic requests that you make to AWS. AWS users need their own access keys to make programmatic calls to AWS from the AWS Command Line Interface (AWS CLI), Tools for Windows PowerShell, the AWS SDKs, or direct HTTP calls using the APIs for individual AWS services. It is recommended that all access keys be regularly rotated.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if access keys are rotated as prescribed:**From Console:**1. Go to Management Console (https://console.aws.amazon.com/iam) 2. Click on `Users` 3. Click `setting` icon 4. Select `Console last sign-in` 5. Click `Close` 6. Ensure that `Access key age` is less than 90 days ago. note) `None` in the `Access key age` means the user has not used the access key.**From Command Line:**``` aws iam generate-credential-report aws iam get-credential-report --query 'Content' --output text | base64 -d ``` The `access_key_1_last_rotated` field in this file notes The date and time, in ISO 8601 date-time format, when the user's access key was created or last changed. If the user does not have an active access key, the value in this field is N/A (not applicable).","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Rotating access keys will reduce the window of opportunity for an access key that is associated with a compromised or terminated account to be used.Access keys should be rotated to ensure that data cannot be accessed with an old key which might have been lost, cracked, or stolen.","RemediationProcedure": "Perform the following to rotate access keys:**From Console:**1. Go to Management Console (https://console.aws.amazon.com/iam) 2. Click on `Users` 3. Click on `Security Credentials`4. As an Administrator - Click on `Make Inactive` for keys that have not been rotated in `90` Days 5. As an IAM User- Click on `Make Inactive` or `Delete` for keys which have not been rotated or used in `90` Days 6. Click on `Create Access Key`7. Update programmatic call with new Access Key credentials**From Command Line:**1. While the first access key is still active, create a second access key, which is active by default. Run the following command: ``` aws iam create-access-key ```At this point, the user has two active access keys.2. Update all applications and tools to use the new access key. 3. Determine whether the first access key is still in use by using this command: ``` aws iam get-access-key-last-used ``` 4. One approach is to wait several days and then check the old access key for any use before proceeding.Even if step Step 3 indicates no use of the old key, it is recommended that you do not immediately delete the first access key. Instead, change the state of the first access key to Inactive using this command: ``` aws iam update-access-key ``` 5. Use only the new access key to confirm that your applications are working. Any applications and tools that still use the original access key will stop working at this point because they no longer have access to AWS resources. If you find such an application or tool, you can switch its state back to Active to reenable the first access key. Then return to step Step 2 and update this application to use the new key.6. After you wait some period of time to ensure that all applications and tools have been updated, you can delete the first access key with this command: ``` aws iam delete-access-key ```","AdditionalInformation": ""}],"description": "Ensure access keys are rotated every 90 days or less","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.15": {"name": "1.15","checks": {"iam_policy_attached_only_to_group_or_roles": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html","Description": "IAM users are granted access to services, functions, and data through IAM policies. There are three ways to define policies for a user: 1) Edit the user policy directly, aka an inline, or user, policy; 2) attach a policy directly to a user; 3) add the user to an IAM group that has an attached policy. Only the third implementation is recommended.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if an inline policy is set or a policy is directly attached to users:1. Run the following to get a list of IAM users: ```aws iam list-users --query 'Users[*].UserName' --output text``` 2. For each user returned, run the following command to determine if any policies are attached to them: ```aws iam list-attached-user-policies --user-name aws iam list-user-policies --user-name ``` 3. If any policies are returned, the user has an inline policy or direct policy attachment.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Assigning IAM policy only through groups unifies permissions management to a single, flexible layer consistent with organizational functional roles. By unifying permissions management, the likelihood of excessive permissions is reduced.","RemediationProcedure": "Perform the following to create an IAM group and assign a policy to it:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click `Groups` and then click `Create New Group` . 3. In the `Group Name` box, type the name of the group and then click `Next Step` . 4. In the list of policies, select the check box for each policy that you want to apply to all members of the group. Then click `Next Step` . 5. Click `Create Group` Perform the following to add a user to a given group:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click `Groups`3. Select the group to add a user to 4. Click `Add Users To Group`5. Select the users to be added to the group 6. Click `Add Users` Perform the following to remove a direct association between a user and policy:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the left navigation pane, click on Users 3. For each user:- Select the user- Click on the `Permissions` tab- Expand `Permissions policies` - Click `X` for each policy; then click Detach or Remove (depending on policy type)","AdditionalInformation": ""}],"description": "Ensure IAM Users Receive Permissions Only Through Groups","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.16": {"name": "1.16","checks": {"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html:https://docs.aws.amazon.com/cli/latest/reference/iam/index.html#cli-aws-iam","Description": "IAM policies are the means by which privileges are granted to users, groups, or roles. It is recommended and considered a standard security advice to grant _least privilege_ -that is, granting only the permissions required to perform a task. Determine what users need to do and then craft policies for them that let the users perform _only_ those tasks, instead of allowing full administrative privileges.","DefaultValue": null,"AuditProcedure": "Perform the following to determine what policies are created:**From Command Line:**1. Run the following to get a list of IAM policies: ```aws iam list-policies --only-attached --output text ``` 2. For each policy returned, run the following command to determine if any policies is allowing full administrative privileges on the account: ```aws iam get-policy-version --policy-arn  --version-id  ``` 3. In output ensure policy should not have any Statement block with `\"Effect\": \"Allow\"` and `Action` set to `\"*\"` and `Resource` set to `\"*\"`","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "It's more secure to start with a minimum set of permissions and grant additional permissions as necessary, rather than starting with permissions that are too lenient and then trying to tighten them later.Providing full administrative privileges instead of restricting to the minimum set of permissions that the user is required to do exposes the resources to potentially unwanted actions.IAM policies that have a statement with \"Effect\": \"Allow\" with \"Action\": \"\\*\" over \"Resource\": \"\\*\" should be removed.","RemediationProcedure": "**From Console:**Perform the following to detach the policy that has full administrative privileges:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click Policies and then search for the policy name found in the audit step. 3. Select the policy that needs to be deleted. 4. In the policy action menu, select first `Detach`5. Select all Users, Groups, Roles that have this policy attached 6. Click `Detach Policy`7. In the policy action menu, select `Detach` **From Command Line:**Perform the following to detach the policy that has full administrative privileges as found in the audit step:1. Lists all IAM users, groups, and roles that the specified managed policy is attached to.```aws iam list-entities-for-policy --policy-arn  ``` 2. Detach the policy from all IAM Users: ```aws iam detach-user-policy --user-name  --policy-arn  ``` 3. Detach the policy from all IAM Groups: ```aws iam detach-group-policy --group-name  --policy-arn  ``` 4. Detach the policy from all IAM Roles: ```aws iam detach-role-policy --role-name  --policy-arn  ```","AdditionalInformation": ""}],"description": "Ensure IAM policies that allow full \"*:*\" administrative privileges are not attached","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1.17": {"name": "1.17","checks": {"iam_support_role_created": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html:https://aws.amazon.com/premiumsupport/pricing/:https://docs.aws.amazon.com/cli/latest/reference/iam/list-policies.html:https://docs.aws.amazon.com/cli/latest/reference/iam/attach-role-policy.html:https://docs.aws.amazon.com/cli/latest/reference/iam/list-entities-for-policy.html","Description": "AWS provides a support center that can be used for incident notification and response, as well as technical support and customer services. Create an IAM Role to allow authorized users to manage incidents with AWS Support.","DefaultValue": null,"AuditProcedure": "**From Command Line:**1. List IAM policies, filter for the 'AWSSupportAccess' managed policy, and note the \"Arn\" element value: ``` aws iam list-policies --query \"Policies[?PolicyName == 'AWSSupportAccess']\" ``` 2. Check if the 'AWSSupportAccess' policy is attached to any role:``` aws iam list-entities-for-policy --policy-arn arn:aws:iam::aws:policy/AWSSupportAccess ```3. In Output, Ensure `PolicyRoles` does not return empty. 'Example: Example: PolicyRoles: [ ]'If it returns empty refer to the remediation below.","ImpactStatement": "All AWS Support plans include an unlimited number of account and billing support cases, with no long-term contracts. Support billing calculations are performed on a per-account basis for all plans. Enterprise Support plan customers have the option to include multiple enabled accounts in an aggregated monthly billing calculation. Monthly charges for the Business and Enterprise support plans are based on each month's AWS usage charges, subject to a monthly minimum, billed in advance.","AssessmentStatus": "Automated","RationaleStatement": "By implementing least privilege for access control, an IAM Role will require an appropriate IAM Policy to allow Support Center Access in order to manage Incidents with AWS Support.","RemediationProcedure": "**From Command Line:**1. Create an IAM role for managing incidents with AWS:- Create a trust relationship policy document that allows  to manage AWS incidents, and save it locally as /tmp/TrustPolicy.json: ```{\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"\"},\"Action\": \"sts:AssumeRole\"}]} ``` 2. Create the IAM role using the above trust policy: ``` aws iam create-role --role-name  --assume-role-policy-document file:///tmp/TrustPolicy.json ``` 3. Attach 'AWSSupportAccess' managed policy to the created IAM role: ``` aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AWSSupportAccess --role-name  ```","AdditionalInformation": "AWSSupportAccess policy is a global AWS resource. It has same ARN as `arn:aws:iam::aws:policy/AWSSupportAccess` for every account."}],"description": "Ensure a support role has been created to manage incidents with AWS Support","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.18": {"name": "1.18","checks": {"ec2_instance_profile_attached": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html","Description": "AWS access from within AWS instances can be done by either encoding AWS keys into AWS API calls or by assigning the instance to a role which has an appropriate permissions policy for the required access. \"AWS Access\" means accessing the APIs of AWS in order to access AWS resources or manage AWS account resources.","DefaultValue": null,"AuditProcedure": "Where an instance is associated with a Role:For instances that are known to perform AWS actions, ensure that they belong to an instance role that has the necessary permissions:1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Open the EC2 Dashboard and choose \"Instances\" 3. Click the EC2 instance that performs AWS actions, in the lower pane details find \"IAM Role\" 4. If the Role is blank, the instance is not assigned to one. 5. If the Role is filled in, it does not mean the instance might not \\*also\\* have credentials encoded on it for some activities.Where an Instance Contains Embedded Credentials:- On the instance that is known to perform AWS actions, audit all scripts and environment variables to ensure that none of them contain AWS credentials.Where an Instance Application Contains Embedded Credentials:- Applications that run on an instance may also have credentials embedded. This is a bad practice, but even worse if the source code is stored in a public code repository such as github. When an application contains credentials can be determined by eliminating all other sources of credentials and if the application can still access AWS resources - it likely contains embedded credentials. Another method is to examine all source code and configuration files of the application.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "AWS IAM roles reduce the risks associated with sharing and rotating credentials that can be used outside of AWS itself. If credentials are compromised, they can be used from outside of the AWS account they give access to. In contrast, in order to leverage role permissions an attacker would need to gain and maintain access to a specific instance to use the privileges associated with it.Additionally, if credentials are encoded into compiled applications or other hard to change mechanisms, then they are even more unlikely to be properly rotated due to service disruption risks. As time goes on, credentials that cannot be rotated are more likely to be known by an increasing number of individuals who no longer work for the organization owning the credentials.","RemediationProcedure": "IAM roles can only be associated at the launch of an instance. To remediate an instance to add it to a role you must create a new instance.If the instance has no external dependencies on its current private ip or public addresses are elastic IPs:1. In AWS IAM create a new role. Assign a permissions policy if needed permissions are already known. 2. In the AWS console launch a new instance with identical settings to the existing instance, and ensure that the newly created role is selected. 3. Shutdown both the existing instance and the new instance. 4. Detach disks from both instances. 5. Attach the existing instance disks to the new instance. 6. Boot the new instance and you should have the same machine, but with the associated role.**Note:** if your environment has dependencies on a dynamically assigned PRIVATE IP address you can create an AMI from the existing instance, destroy the old one and then when launching from the AMI, manually assign the previous private IP address.**Note: **if your environment has dependencies on a dynamically assigned PUBLIC IP address there is not a way ensure the address is retained and assign an instance role. Dependencies on dynamically assigned public IP addresses are a bad practice and, if possible, you may wish to rebuild the instance with a new elastic IP address and make the investment to remediate affected systems while assigning the system to a role.","AdditionalInformation": ""}],"description": "Ensure IAM instance roles are used for AWS resource access from instances","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.19": {"name": "1.19","checks": {"iam_no_expired_server_certificates_stored": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_server-certs.html:https://docs.aws.amazon.com/cli/latest/reference/iam/delete-server-certificate.html","Description": "To enable HTTPS connections to your website or application in AWS, you need an SSL/TLS server certificate. You can use ACM or IAM to store and deploy server certificates.Use IAM as a certificate manager only when you must support HTTPS connections in a region that is not supported by ACM. IAM securely encrypts your private keys and stores the encrypted version in IAM SSL certificate storage. IAM supports deploying server certificates in all regions, but you must obtain your certificate from an external provider for use with AWS. You cannot upload an ACM certificate to IAM. Additionally, you cannot manage your certificates from the IAM Console.","DefaultValue": null,"AuditProcedure": "**From Console:**Getting the certificates expiration information via AWS Management Console is not currently supported.To request information about the SSL/TLS certificates stored in IAM via the AWS API use the Command Line Interface (CLI).**From Command Line:**Run list-server-certificates command to list all the IAM-stored server certificates:``` aws iam list-server-certificates ```The command output should return an array that contains all the SSL/TLS certificates currently stored in IAM and their metadata (name, ID, expiration date, etc):``` {\"ServerCertificateMetadataList\": [{\"ServerCertificateId\": \"EHDGFRW7EJFYTE88D\",\"ServerCertificateName\": \"MyServerCertificate\",\"Expiration\": \"2018-07-10T23:59:59Z\",\"Path\": \"/\",\"Arn\": \"arn:aws:iam::012345678910:server-certificate/MySSLCertificate\",\"UploadDate\": \"2018-06-10T11:56:08Z\"}] } ```Verify the `ServerCertificateName` and `Expiration` parameter value (expiration date) for each SSL/TLS certificate returned by the list-server-certificates command and determine if there are any expired server certificates currently stored in AWS IAM. If so, use the AWS API to remove them.If this command returns: ``` { { \"ServerCertificateMetadataList\": [] } ``` This means that there are no expired certificates, It DOES NOT mean that no certificates exist.","ImpactStatement": "Deleting the certificate could have implications for your application if you are using an expired server certificate with Elastic Load Balancing, CloudFront, etc. One has to make configurations at respective services to ensure there is no interruption in application functionality.","AssessmentStatus": "Automated","RationaleStatement": "Removing expired SSL/TLS certificates eliminates the risk that an invalid certificate will be deployed accidentally to a resource such as AWS Elastic Load Balancer (ELB), which can damage the credibility of the application/website behind the ELB. As a best practice, it is recommended to delete expired certificates.","RemediationProcedure": "**From Console:**Removing expired certificates via AWS Management Console is not currently supported. To delete SSL/TLS certificates stored in IAM via the AWS API use the Command Line Interface (CLI).**From Command Line:**To delete Expired Certificate run following command by replacing  with the name of the certificate to delete:``` aws iam delete-server-certificate --server-certificate-name  ```When the preceding command is successful, it does not return any output.","AdditionalInformation": ""}],"description": "Ensure that all the expired SSL/TLS certificates stored in AWS IAM are removed","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.20": {"name": "1.20","checks": {"accessanalyzer_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-getting-started.html:https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/get-analyzer.html:https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/create-analyzer.html","Description": "Enable IAM Access analyzer for IAM policies about all resources in each region.IAM Access Analyzer is a technology introduced at AWS reinvent 2019. After the Analyzer is enabled in IAM, scan results are displayed on the console showing the accessible resources. Scans show resources that other accounts and federated users can access, such as KMS keys and IAM roles. So the results allow you to determine if an unintended user is allowed, making it easier for administrators to monitor least privileges access. Access Analyzer analyzes only policies that are applied to resources in the same AWS Region.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Open the IAM console at `https://console.aws.amazon.com/iam/` 2. Choose `Access analyzer` 3. Click 'Analyzers' 4. Ensure that at least one analyzer is present 5. Ensure that the `STATUS` is set to `Active` 6. Repeat these step for each active region**From Command Line:**1. Run the following command: ``` aws accessanalyzer list-analyzers | grep status ``` 2. Ensure that at least one Analyzer the `status` is set to `ACTIVE`3. Repeat the steps above for each active region.If an Access analyzer is not listed for each region or the status is not set to active refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "AWS IAM Access Analyzer helps you identify the resources in your organization and accounts, such as Amazon S3 buckets or IAM roles, that are shared with an external entity. This lets you identify unintended access to your resources and data. Access Analyzer identifies resources that are shared with external principals by using logic-based reasoning to analyze the resource-based policies in your AWS environment. IAM Access Analyzer continuously monitors all policies for S3 bucket, IAM roles, KMS(Key Management Service) keys, AWS Lambda functions, and Amazon SQS(Simple Queue Service) queues.","RemediationProcedure": "**From Console:**Perform the following to enable IAM Access analyzer for IAM policies:1. Open the IAM console at `https://console.aws.amazon.com/iam/.` 2. Choose `Access analyzer`. 3. Choose `Create analyzer`. 4. On the `Create analyzer` page, confirm that the `Region` displayed is the Region where you want to enable Access Analyzer. 5. Enter a name for the analyzer. `Optional as it will generate a name for you automatically`. 6. Add any tags that you want to apply to the analyzer. `Optional`.7. Choose `Create Analyzer`. 8. Repeat these step for each active region**From Command Line:**Run the following command: ``` aws accessanalyzer create-analyzer --analyzer-name  --type  ``` Repeat this command above for each active region.**Note:** The IAM Access Analyzer is successfully configured only when the account you use has the necessary permissions.","AdditionalInformation": ""}],"description": "Ensure that IAM Access analyzer is enabled for all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.21": {"name": "1.21","checks": {"iam_check_saml_providers_sts": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "","Description": "In multi-account environments, IAM user centralization facilitates greater user control. User access beyond the initial account is then provided via role assumption. Centralization of users can be accomplished through federation with an external identity provider or through the use of AWS Organizations.","DefaultValue": null,"AuditProcedure": "For multi-account AWS environments with an external identity provider... 1. Determine the master account for identity federation or IAM user management 2. Login to that account through the AWS Management Console 3. Click `Services`4. Click `IAM`5. Click `Identity providers` 6. Verify the configurationThen..., determine all accounts that should not have local users present. For each account...1. Determine all accounts that should not have local users present 2. Log into the AWS Management Console 3. Switch role into each identified account 4. Click `Services`5. Click `IAM`6. Click `Users` 7. Confirm that no IAM users representing individuals are presentFor multi-account AWS environments implementing AWS Organizations without an external identity provider... 1. Determine all accounts that should not have local users present 2. Log into the AWS Management Console 3. Switch role into each identified account 4. Click `Services`5. Click `IAM`6. Click `Users` 7. Confirm that no IAM users representing individuals are present","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Centralizing IAM user management to a single identity store reduces complexity and thus the likelihood of access management errors.","RemediationProcedure": "The remediation procedure will vary based on the individual organization's implementation of identity federation and/or AWS Organizations with the acceptance criteria that no non-service IAM users, and non-root accounts, are present outside the account providing centralized IAM user management.","AdditionalInformation": ""}],"description": "Ensure IAM users are managed centrally via identity federation or AWS Organizations for multi-account environments","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.10": {"name": "3.10","checks": {"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-cloudtrail-events.html","Description": "S3 object-level API operations such as GetObject, DeleteObject, and PutObject are called data events. By default, CloudTrail trails don't log data events and so it is recommended to enable Object-level logging for S3 buckets.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to CloudTrail dashboard at `https://console.aws.amazon.com/cloudtrail/` 2. In the left panel, click `Trails` and then click on the CloudTrail Name that you want to examine. 3. Review `General details` 4. Confirm that `Multi-region trail` is set to `Yes` 5. Scroll down to `Data events` 6. Confirm that it reads: Data events: S3 Bucket Name: All current and future S3 buckets Read: Enabled Write: Enabled 7. Repeat steps 2 to 6 to verify that Multi-region trail and Data events logging of S3 buckets in CloudTrail. If the CloudTrails do not have multi-region and data events configured for S3 refer to the remediation below.**From Command Line:**1. Run `list-trails` command to list the names of all Amazon CloudTrail trails currently available in all AWS regions: ``` aws cloudtrail list-trails ``` 2. The command output will be a list of all the trail names to include. \"TrailARN\": \"arn:aws:cloudtrail:::trail/\", \"Name\": \"\", \"HomeRegion\": \"\" 3. Next run 'get-trail- command to determine Multi-region. ``` aws cloudtrail get-trail --name  --region  ``` 4. The command output should include: \"IsMultiRegionTrail\": true, 5. Next run `get-event-selectors` command using the `Name` of the trail and the `region` returned in step 2 to determine if Data events logging feature is enabled within the selected CloudTrail trail for all S3 buckets: ``` aws cloudtrail get-event-selectors --region  --trail-name  --query EventSelectors[*].DataResources[] ``` 6. The command output should be an array that contains the configuration of the AWS resource(S3 bucket) defined for the Data events selector. \"Type\": \"AWS::S3::Object\",\"Values\": [\"arn:aws:s3\" 7. If the `get-event-selectors` command returns an empty array '[]', the Data events are not included in the selected AWS Cloudtrail trail logging configuration, therefore the S3 object-level API operations performed within your AWS account are not recorded. 8. Repeat steps 1 to 5 for auditing each CloudTrail to determine if Data events for S3 are covered. If Multi-region is not set to true and the Data events does not show S3 defined as shown refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling object-level logging will help you meet data compliance requirements within your organization, perform comprehensive security analysis, monitor specific patterns of user behavior in your AWS account or take immediate actions on any object-level API activity within your S3 Buckets using Amazon CloudWatch Events.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. Click on the `Object-level` logging setting, enter the CloudTrail name for the recording activity. You can choose an existing Cloudtrail or create a new one by navigating to the Cloudtrail console link `https://console.aws.amazon.com/cloudtrail/` 5. Once the Cloudtrail is selected, check the `Write` event checkbox, so that `object-level` logging for Write events is enabled. 6. Repeat steps 2 to 5 to enable object-level logging of write events for other S3 buckets.**From Command Line:**1. To enable `object-level` data events logging for S3 buckets within your AWS account, run `put-event-selectors` command using the name of the trail that you want to reconfigure as identifier: ``` aws cloudtrail put-event-selectors --region  --trail-name  --event-selectors '[{ \"ReadWriteType\": \"WriteOnly\", \"IncludeManagementEvents\":true, \"DataResources\": [{ \"Type\": \"AWS::S3::Object\", \"Values\": [\"arn:aws:s3:::/\"] }] }]' ``` 2. The command output will be `object-level` event trail configuration. 3. If you want to enable it for all buckets at once then change Values parameter to `[\"arn:aws:s3\"]` in command given above. 4. Repeat step 1 for each s3 bucket to update `object-level` logging of write events. 5. Change the AWS region by updating the `--region` command parameter and perform the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that Object-level logging for write events is enabled for S3 bucket","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.11": {"name": "3.11","checks": {"cloudtrail_s3_dataevents_read_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-cloudtrail-events.html","Description": "S3 object-level API operations such as GetObject, DeleteObject, and PutObject are called data events. By default, CloudTrail trails don't log data events and so it is recommended to enable Object-level logging for S3 buckets.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. If the current status for `Object-level` logging is set to `Disabled`, then object-level logging of read events for the selected s3 bucket is not set. 5. If the current status for `Object-level` logging is set to `Enabled`, but the Read event check-box is unchecked, then object-level logging of read events for the selected s3 bucket is not set. 6. Repeat steps 2 to 5 to verify `object-level` logging for `read` events of your other S3 buckets.**From Command Line:** 1. Run `describe-trails` command to list the names of all Amazon CloudTrail trails currently available in the selected AWS region: ``` aws cloudtrail describe-trails --region  --output table --query trailList[*].Name ``` 2. The command output will be table of the requested trail names. 3. Run `get-event-selectors` command using the name of the trail returned at the previous step and custom query filters to determine if Data events logging feature is enabled within the selected CloudTrail trail configuration for s3 bucket resources: ``` aws cloudtrail get-event-selectors --region  --trail-name  --query EventSelectors[*].DataResources[] ``` 4. The command output should be an array that contains the configuration of the AWS resource(S3 bucket) defined for the Data events selector. 5. If the `get-event-selectors` command returns an empty array, the Data events are not included into the selected AWS Cloudtrail trail logging configuration, therefore the S3 object-level API operations performed within your AWS account are not recorded. 6. Repeat steps 1 to 5 for auditing each s3 bucket to identify other trails that are missing the capability to log Data events. 7. Change the AWS region by updating the `--region` command parameter and perform the audit process for other regions.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling object-level logging will help you meet data compliance requirements within your organization, perform comprehensive security analysis, monitor specific patterns of user behavior in your AWS account or take immediate actions on any object-level API activity using Amazon CloudWatch Events.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. Click on the `Object-level` logging setting, enter the CloudTrail name for the recording activity. You can choose an existing Cloudtrail or create a new one by navigating to the Cloudtrail console link `https://console.aws.amazon.com/cloudtrail/` 5. Once the Cloudtrail is selected, check the Read event checkbox, so that `object-level` logging for `Read` events is enabled. 6. Repeat steps 2 to 5 to enable `object-level` logging of read events for other S3 buckets.**From Command Line:** 1. To enable `object-level` data events logging for S3 buckets within your AWS account, run `put-event-selectors` command using the name of the trail that you want to reconfigure as identifier: ``` aws cloudtrail put-event-selectors --region  --trail-name  --event-selectors '[{ \"ReadWriteType\": \"ReadOnly\", \"IncludeManagementEvents\":true, \"DataResources\": [{ \"Type\": \"AWS::S3::Object\", \"Values\": [\"arn:aws:s3:::/\"] }] }]' ``` 2. The command output will be `object-level` event trail configuration. 3. If you want to enable it for all buckets at ones then change Values parameter to `[\"arn:aws:s3\"]` in command given above. 4. Repeat step 1 for each s3 bucket to update `object-level` logging of read events. 5. Change the AWS region by updating the `--region` command parameter and perform the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that Object-level logging for read events is enabled for S3 bucket","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.10": {"name": "4.10","checks": {"cloudwatch_log_metric_filter_security_group_changes": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Security Groups are a stateful packet filter that controls ingress and egress traffic within a VPC. It is recommended that a metric filter and alarm be established for detecting changes to Security Groups.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query \"MetricAlarms[?MetricName== '']\" ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to security group will help ensure that resources and services are not unintentionally exposed.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for security groups changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name \"\" --filter-name \"\" --metric-transformations metricName= \"\" ,metricNamespace=\"CISBenchmark\",metricValue=1 --filter-pattern \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\" ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name \"\" ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn \"\" --protocol  --notification-endpoint \"\" ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name \"\" --metric-name \"\" --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace \"CISBenchmark\" --alarm-actions \"\" ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for security group changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.11": {"name": "4.11","checks": {"cloudwatch_changes_to_network_acls_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. NACLs are used as a stateless packet filter to control ingress and egress traffic for subnets within a VPC. It is recommended that a metric filter and alarm be established for changes made to NACLs.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to NACLs will help ensure that AWS resources and services are not unintentionally exposed.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for NACL changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL)","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.12": {"name": "4.12","checks": {"cloudwatch_changes_to_network_gateways_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Network gateways are required to send/receive traffic to a destination outside of a VPC. It is recommended that a metric filter and alarm be established for changes to network gateways.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to network gateways will help ensure that all ingress/egress traffic traverses the VPC border via a controlled path.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for network gateways changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for changes to network gateways","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.13": {"name": "4.13","checks": {"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Routing tables are used to route network traffic between subnets and to network gateways. It is recommended that a metric filter and alarm be established for changes to route tables.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to route tables will help ensure that all VPC traffic flows through an expected path.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for route table changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for route table changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.14": {"name": "4.14","checks": {"cloudwatch_changes_to_vpcs_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is possible to have more than 1 VPC within an account, in addition it is also possible to create a peer connection between 2 VPCs enabling network traffic to route between VPCs. It is recommended that a metric filter and alarm be established for changes made to VPCs.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to VPC will help ensure VPC traffic flow is not getting impacted.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for VPC changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for VPC changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.15": {"name": "4.15","checks": {"cloudwatch_log_metric_filter_aws_organizations_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/organizations/latest/userguide/orgs_security_incident-response.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for AWS Organizations changes made in the master AWS Account.","DefaultValue": null,"AuditProcedure": "1. Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured: - Identify the log group name configured for use with active multi-region CloudTrail: - List all CloudTrails:``` aws cloudtrail describe-trails ``` - Identify Multi region Cloudtrails, Trails with `\"IsMultiRegionTrail\"` set to true - From value associated with CloudWatchLogsLogGroupArn note **Example:** for CloudWatchLogsLogGroupArn that looks like arn:aws:logs:::log-group:NewGroup:*,  would be NewGroup- Ensure Identified Multi region CloudTrail is active: ``` aws cloudtrail get-trail-status --name  ``` Ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events: ``` aws cloudtrail get-event-selectors --trail-name  ``` - Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to true and `ReadWriteType` set to `All`.2. Get a list of all associated metric filters for this : ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdatePolicy\") || ($.eventName = \"UpdateOrganizationalUnit\")) }\" ``` 4. Note the `` value associated with the filterPattern found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4: ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the AlarmActions value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic: ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. Example of valid \"SubscriptionArn\":``` \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring AWS Organizations changes can help you prevent any unwanted, accidental or intentional modifications that may lead to unauthorized access or other security breaches. This monitoring technique helps you to ensure that any unexpected changes performed within your AWS Organizations can be investigated and any unwanted changes can be rolled back.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Organizations changes and the `` taken from audit step 1: ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdatePolicy\") || ($.eventName = \"UpdateOrganizationalUnit\")) }' ``` **Note:** You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify: ``` aws sns create-topic --name  ``` **Note:** you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2: ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note:** you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2: ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": ""}],"description": "Ensure a log metric filter and alarm exists for AWS Organizations changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"2.1.1": {"name": "2.1.1","checks": {"s3_bucket_default_encryption": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/default-bucket-encryption.html:https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html#bucket-encryption-related-resources","Description": "Amazon S3 provides a variety of no, or low, cost encryption options to protect data at rest.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select a Bucket. 3. Click on 'Properties'. 4. Verify that `Default Encryption` is enabled, and displays either `AES-256`, `AWS-KMS`, `SSE-KMS` or `SSE-S3`. 5. Repeat for all the buckets in your AWS account.**From Command Line:**1. Run command to list buckets ``` aws s3 ls ``` 2. For each bucket, run``` aws s3api get-bucket-encryption --bucket  ``` 3. Verify that either``` \"SSEAlgorithm\": \"AES256\" ```or``` \"SSEAlgorithm\": \"aws:kms\"```is displayed.","ImpactStatement": "Amazon S3 buckets with default bucket encryption using SSE-KMS cannot be used as destination buckets for Amazon S3 server access logging. Only SSE-S3 default encryption is supported for server access log destination buckets.","AssessmentStatus": "Automated","RationaleStatement": "Encrypting data at rest reduces the likelihood that it is unintentionally exposed and can nullify the impact of disclosure if the encryption remains unbroken.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select a Bucket. 3. Click on 'Properties'. 4. Click edit on `Default Encryption`. 5. Select either `AES-256`, `AWS-KMS`, `SSE-KMS` or `SSE-S3`. 6. Click `Save` 7. Repeat for all the buckets in your AWS account lacking encryption.**From Command Line:**Run either``` aws s3api put-bucket-encryption --bucket  --server-side-encryption-configuration '{\"Rules\": [{\"ApplyServerSideEncryptionByDefault\": {\"SSEAlgorithm\": \"AES256\"}}]}' ```or``` aws s3api put-bucket-encryption --bucket  --server-side-encryption-configuration '{\"Rules\": [{\"ApplyServerSideEncryptionByDefault\": {\"SSEAlgorithm\": \"aws:kms\",\"KMSMasterKeyID\": \"aws/s3\"}}]}' ```**Note:** the KMSMasterKeyID can be set to the master key of your choosing; aws/s3 is an AWS preconfigured default.","AdditionalInformation": "S3 bucket encryption only applies to objects as they are placed in the bucket. Enabling S3 bucket encryption does **not** encrypt objects previously stored within the bucket."}],"description": "Ensure all S3 buckets employ encryption-at-rest","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.2": {"name": "2.1.2","checks": {"s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-policy-for-config-rule/:https://aws.amazon.com/blogs/security/how-to-use-bucket-policies-and-apply-defense-in-depth-to-help-secure-your-amazon-s3-data/:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-bucket-policy.html","Description": "At the Amazon S3 bucket level, you can configure permissions through a bucket policy making the objects accessible only through HTTPS.","DefaultValue": null,"AuditProcedure": "To allow access to HTTPS you can use a condition that checks for the key `\"aws:SecureTransport: true\"`. This means that the request is sent through HTTPS but that HTTP can still be used. So to make sure you do not allow HTTP access confirm that there is a bucket policy that explicitly denies access for HTTP requests and that it contains the key \"aws:SecureTransport\": \"false\".**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/ 2. Select the Check box next to the Bucket. 3. Click on 'Permissions', then Click on `Bucket Policy`. 4. Ensure that a policy is listed that matches: ``` '{\"Sid\": ,\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}' ``` `` and `` will be specific to your account5. Repeat for all the buckets in your AWS account.**From Command Line:**1. List all of the S3 Buckets``` aws s3 ls ``` 2. Using the list of buckets run this command on each of them: ``` aws s3api get-bucket-policy --bucket  | grep aws:SecureTransport ``` 3. Confirm that `aws:SecureTransport` is set to false `aws:SecureTransport:false` 4. Confirm that the policy line has Effect set to Deny 'Effect:Deny'","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "By default, Amazon S3 allows both HTTP and HTTPS requests. To achieve only allowing access to Amazon S3 objects through HTTPS you also have to explicitly deny access to HTTP requests. Bucket policies that allow HTTPS requests without explicitly denying HTTP requests will not comply with this recommendation.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/ 2. Select the Check box next to the Bucket. 3. Click on 'Permissions'. 4. Click 'Bucket Policy' 5. Add this to the existing policy filling in the required information ``` {\"Sid\": \",\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}}} ``` 6. Save 7. Repeat for all the buckets in your AWS account that contain sensitive data.**From Console** using AWS Policy Generator:1. Repeat steps 1-4 above. 2. Click on `Policy Generator` at the bottom of the Bucket Policy Editor 3. Select Policy Type `S3 Bucket Policy` 4. Add Statements - `Effect` = Deny - `Principal` = * - `AWS Service` = Amazon S3 - `Actions` = * - `Amazon Resource Name` =  5. Generate Policy 6. Copy the text and add it to the Bucket Policy.**From Command Line:**1. Export the bucket policy to a json file. ``` aws s3api get-bucket-policy --bucket  --query Policy --output text > policy.json ```2. Modify the policy.json file by adding in this statement: ``` {\"Sid\": \",\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}}} ``` 3. Apply this modified policy back to the S3 bucket: ``` aws s3api put-bucket-policy --bucket  --policy file://policy.json ```","AdditionalInformation": ""}],"description": "Ensure S3 Bucket Policy is set to deny HTTP requests","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.1.3": {"name": "2.1.3","checks": {"s3_bucket_no_mfa_delete": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html#MultiFactorAuthenticationDelete:https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMFADelete.html:https://aws.amazon.com/blogs/security/securing-access-to-aws-using-mfa-part-3/:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_lost-or-broken.html","Description": "Once MFA Delete is enabled on your sensitive and classified S3 bucket it requires the user to have two forms of authentication.","DefaultValue": null,"AuditProcedure": "Perform the steps below to confirm MFA delete is configured on an S3 Bucket**From Console:**1. Login to the S3 console at `https://console.aws.amazon.com/s3/`2. Click the `Check` box next to the Bucket name you want to confirm3. In the window under `Properties`4. Confirm that Versioning is `Enabled`5. Confirm that MFA Delete is `Enabled`**From Command Line:**1. Run the `get-bucket-versioning` ``` aws s3api get-bucket-versioning --bucket my-bucket ```Output example: ```  EnabledEnabled ```If the Console or the CLI output does not show Versioning and MFA Delete `enabled` refer to the remediation below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Adding MFA delete to an S3 bucket, requires additional authentication when you change the version state of your bucket or you delete and object version adding another layer of security in the event your security credentials are compromised or unauthorized access is granted.","RemediationProcedure": "Perform the steps below to enable MFA delete on an S3 bucket.Note: -You cannot enable MFA Delete using the AWS Management Console. You must use the AWS CLI or API. -You must use your 'root' account to enable MFA Delete on S3 buckets.**From Command line:**1. Run the s3api put-bucket-versioning command``` aws s3api put-bucket-versioning --profile my-root-profile --bucket Bucket_Name --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa ā€œarn:aws:iam::aws_account_id:mfa/root-account-mfa-device passcodeā€ ```","AdditionalInformation": ""}],"description": "Ensure MFA Delete is enabled on S3 buckets","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.1.4": {"name": "2.1.4","checks": {"macie_is_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://aws.amazon.com/macie/getting-started/:https://docs.aws.amazon.com/workspaces/latest/adminguide/data-protection.html:https://docs.aws.amazon.com/macie/latest/user/data-classification.html","Description": "Amazon S3 buckets can contain sensitive data, that for security purposes should be discovered, monitored, classified and protected. Macie along with other 3rd party tools can automatically provide an inventory of Amazon S3 buckets.","DefaultValue": null,"AuditProcedure": "Perform the following steps to determine if Macie is running:**From Console:** 1. Login to the Macie console at https://console.aws.amazon.com/macie/ 2. In the left hand pane click on By job under findings. 3. Confirm that you have a Job setup for your S3 BucketsWhen you log into the Macie console if you aren't taken to the summary page and you don't have a job setup and running then refer to the remediation procedure below.If you are using a 3rd Party tool to manage and protect your s3 data you meet this recommendation.","ImpactStatement": "There is a cost associated with using Amazon Macie. There is also typically a cost associated with 3rd Party tools that perform similar processes and protection.","AssessmentStatus": "Manual","RationaleStatement": "Using a Cloud service or 3rd Party software to continuously monitor and automate the process of data discovery and classification for S3 buckets using machine learning and pattern matching is a strong defense in protecting that information.Amazon Macie is a fully managed data security and data privacy service that uses machine learning and pattern matching to discover and protect your sensitive data in AWS.","RemediationProcedure": "Perform the steps below to enable and configure Amazon Macie**From Console:**1. Log on to the Macie console at `https://console.aws.amazon.com/macie/`2. Click `Get started`.3. Click `Enable Macie`.Setup a repository for sensitive data discovery results1. In the Left pane, under Settings, click `Discovery results`.2. Make sure `Create bucket` is selected.3. Create a bucket, enter a name for the bucket. The name must be unique across all S3 buckets. In addition, the name must start with a lowercase letter or a number.4. Click on `Advanced`.5. Block all public access, make sure `Yes` is selected.6. KMS encryption, specify the AWS KMS key that you want to use to encrypt the results. The key must be a symmetric, customer master key (CMK) that's in the same Region as the S3 bucket.7. Click on `Save`Create a job to discover sensitive data1. In the left pane, click `S3 buckets`. Macie displays a list of all the S3 buckets for your account.2. Select the `check box` for each bucket that you want Macie to analyze as part of the job3. Click `Create job`.3. Click `Quick create`.4. For the Name and description step, enter a name and, optionally, a description of the job.5. Then click `Next`.6. For the Review and create step, click `Submit`.Review your findings1. In the left pane, click `Findings`.2. To view the details of a specific finding, choose any field other than the check box for the finding.If you are using a 3rd Party tool to manage and protect your s3 data, follow the Vendor documentation for implementing and configuring that tool.","AdditionalInformation": ""}],"description": "Ensure all data in Amazon S3 has been discovered, classified and secured when required.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.5": {"name": "2.1.5","checks": {"s3_bucket_level_public_access_block": "PASS","s3_account_level_public_access_blocks": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/block-public-access-account.html","Description": "Amazon S3 provides `Block public access (bucket settings)` and `Block public access (account settings)` to help you manage public access to Amazon S3 resources. By default, S3 buckets and objects are created with public access disabled. However, an IAM principal with sufficient S3 permissions can enable public access at the bucket and/or object level. While enabled, `Block public access (bucket settings)` prevents an individual bucket, and its contained objects, from becoming publicly accessible. Similarly, `Block public access (account settings)` prevents all buckets, and contained objects, from becoming publicly accessible across the entire account.","DefaultValue": null,"AuditProcedure": "**If utilizing Block Public Access (bucket settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select the Check box next to the Bucket. 3. Click on 'Edit public access settings'. 4. Ensure that block public access settings are set appropriately for this bucket 5. Repeat for all the buckets in your AWS account.**From Command Line:**1. List all of the S3 Buckets ``` aws s3 ls ``` 2. Find the public access setting on that bucket ``` aws s3api get-public-access-block --bucket  ``` Output if Block Public access is enabled:``` {\"PublicAccessBlockConfiguration\": {\"BlockPublicAcls\": true,\"IgnorePublicAcls\": true,\"BlockPublicPolicy\": true,\"RestrictPublicBuckets\": true} } ```If the output reads `false` for the separate configuration settings then proceed to the remediation.**If utilizing Block Public Access (account settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Choose `Block public access (account settings)` 3. Ensure that block public access settings are set appropriately for your AWS account.**From Command Line:**To check Public access settings for this account status, run the following command, `aws s3control get-public-access-block --account-id  --region `Output if Block Public access is enabled:``` {\"PublicAccessBlockConfiguration\": {\"IgnorePublicAcls\": true, \"BlockPublicPolicy\": true, \"BlockPublicAcls\": true, \"RestrictPublicBuckets\": true} } ```If the output reads `false` for the separate configuration settings then proceed to the remediation.","ImpactStatement": "When you apply Block Public Access settings to an account, the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously, but they eventually propagate to all Regions.","AssessmentStatus": "Automated","RationaleStatement": "Amazon S3 `Block public access (bucket settings)` prevents the accidental or malicious public exposure of data contained within the respective bucket(s). Amazon S3 `Block public access (account settings)` prevents the accidental or malicious public exposure of data contained within all buckets of the respective AWS account.Whether blocking public access to all or some buckets is an organizational decision that should be based on data sensitivity, least privilege, and use case.","RemediationProcedure": "**If utilizing Block Public Access (bucket settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select the Check box next to the Bucket. 3. Click on 'Edit public access settings'. 4. Click 'Block all public access' 5. Repeat for all the buckets in your AWS account that contain sensitive data.**From Command Line:**1. List all of the S3 Buckets ``` aws s3 ls ``` 2. Set the Block Public Access to true on that bucket ``` aws s3api put-public-access-block --bucket  --public-access-block-configuration \"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true\" ```**If utilizing Block Public Access (account settings)****From Console:**If the output reads `true` for the separate configuration settings then it is set on the account.1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Choose `Block Public Access (account settings)` 3. Choose `Edit` to change the block public access settings for all the buckets in your AWS account 4. Choose the settings you want to change, and then choose `Save`. For details about each setting, pause on the `i` icons. 5. When you're asked for confirmation, enter `confirm`. Then Click `Confirm` to save your changes.**From Command Line:**To set Block Public access settings for this account, run the following command: ``` aws s3control put-public-access-block --public-access-block-configuration BlockPublicAcls=true, IgnorePublicAcls=true, BlockPublicPolicy=true, RestrictPublicBuckets=true --account-id  ```","AdditionalInformation": ""}],"description": "Ensure that S3 Buckets are configured with 'Block public access (bucket settings)'","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"2.2.1": {"name": "2.2.1","checks": {"ec2_ebs_volume_encryption": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.2. Elastic Compute Cloud (EC2)","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html:https://aws.amazon.com/blogs/aws/new-opt-in-to-default-encryption-for-new-ebs-volumes/","Description": "Elastic Compute Cloud (EC2) supports encryption at rest when using the Elastic Block Store (EBS) service. While disabled by default, forcing encryption at EBS volume creation is supported.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under `Account attributes`, click `EBS encryption`. 3. Verify `Always encrypt new EBS volumes` displays `Enabled`. 4. Review every region in-use.**Note:** EBS volume encryption is configured per region.**From Command Line:**1. Run``` aws --region  ec2 get-ebs-encryption-by-default ``` 2. Verify that `\"EbsEncryptionByDefault\": true` is displayed. 3. Review every region in-use.**Note:** EBS volume encryption is configured per region.","ImpactStatement": "Losing access or removing the KMS key in use by the EBS volumes will result in no longer being able to access the volumes.","AssessmentStatus": "Automated","RationaleStatement": "Encrypting data at rest reduces the likelihood that it is unintentionally exposed and can nullify the impact of disclosure if the encryption remains unbroken.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under `Account attributes`, click `EBS encryption`. 3. Click `Manage`. 4. Click the `Enable` checkbox. 5. Click `Update EBS encryption` 6. Repeat for every region requiring the change.**Note:** EBS volume encryption is configured per region.**From Command Line:**1. Run``` aws --region  ec2 enable-ebs-encryption-by-default ``` 2. Verify that `\"EbsEncryptionByDefault\": true` is displayed. 3. Repeat every region requiring the change.**Note:** EBS volume encryption is configured per region.","AdditionalInformation": "Default EBS volume encryption only applies to newly created EBS volumes. Existing EBS volumes are **not** converted automatically."}],"description": "Ensure EBS Volume Encryption is Enabled in all Regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.3.1": {"name": "2.3.1","checks": {"rds_instance_storage_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Encryption.html:https://aws.amazon.com/blogs/database/selecting-the-right-encryption-options-for-amazon-rds-and-amazon-aurora-database-engines/#:~:text=With%20RDS%2Dencrypted%20resources%2C%20data,transparent%20to%20your%20database%20engine.:https://aws.amazon.com/rds/features/security/","Description": "Amazon RDS encrypted DB instances use the industry standard AES-256 encryption algorithm to encrypt your data on the server that hosts your Amazon RDS DB instances. After your data is encrypted, Amazon RDS handles authentication of access and decryption of your data transparently with a minimal impact on performance.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and open the RDS dashboard at https://console.aws.amazon.com/rds/ 2. In the navigation pane, under RDS dashboard, click `Databases`. 3. Select the RDS Instance that you want to examine 4. Click `Instance Name` to see details, then click on `Configuration` tab. 5. Under Configuration Details section, In Storage pane search for the `Encryption Enabled` Status. 6. If the current status is set to `Disabled`, Encryption is not enabled for the selected RDS Instance database instance. 7. Repeat steps 3 to 7 to verify encryption status of other RDS Instance in same region. 8. Change region from the top of the navigation bar and repeat audit for other regions.**From Command Line:**1. Run `describe-db-instances` command to list all RDS Instance database names, available in the selected AWS region, Output will return each Instance database identifier-name.``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. Run again `describe-db-instances` command using the RDS Instance identifier returned earlier, to determine if the selected database instance is encrypted, The command output should return the encryption status `True` Or `False`. ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].StorageEncrypted' ``` 3. If the StorageEncrypted parameter value is `False`, Encryption is not enabled for the selected RDS database instance. 4. Repeat steps 1 to 3 for auditing each RDS Instance and change Region to verify for other regions","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Databases are likely to hold sensitive and critical data, it is highly recommended to implement encryption in order to protect your data from unauthorized access or disclosure. With RDS encryption enabled, the data stored on the instance's underlying storage, the automated backups, read replicas, and snapshots, are all encrypted.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and open the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases` 3. Select the Database instance that needs to be encrypted. 4. Click on `Actions` button placed at the top right and select `Take Snapshot`. 5. On the Take Snapshot page, enter a database name of which you want to take a snapshot in the `Snapshot Name` field and click on `Take Snapshot`. 6. Select the newly created snapshot and click on the `Action` button placed at the top right and select `Copy snapshot` from the Action menu. 7. On the Make Copy of DB Snapshot page, perform the following:- In the New DB Snapshot Identifier field, Enter a name for the `new snapshot`. - Check `Copy Tags`, New snapshot must have the same tags as the source snapshot. - Select `Yes` from the `Enable Encryption` dropdown list to enable encryption, You can choose to use the AWS default encryption key or custom key from Master Key dropdown list.8. Click `Copy Snapshot` to create an encrypted copy of the selected instance snapshot. 9. Select the new Snapshot Encrypted Copy and click on the `Action` button placed at the top right and select `Restore Snapshot` button from the Action menu, This will restore the encrypted snapshot to a new database instance. 10. On the Restore DB Instance page, enter a unique name for the new database instance in the DB Instance Identifier field. 11. Review the instance configuration details and click `Restore DB Instance`. 12. As the new instance provisioning process is completed can update application configuration to refer to the endpoint of the new Encrypted database instance Once the database endpoint is changed at the application level, can remove the unencrypted instance.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names available in the selected AWS region, The command output should return the database instance identifier. ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. Run `create-db-snapshot` command to create a snapshot for the selected database instance, The command output will return the `new snapshot` with name DB Snapshot Name. ``` aws rds create-db-snapshot --region  --db-snapshot-identifier  --db-instance-identifier  ``` 3. Now run `list-aliases` command to list the KMS keys aliases available in a specified region, The command output should return each `key alias currently available`. For our RDS encryption activation process, locate the ID of the AWS default KMS key. ``` aws kms list-aliases --region  ``` 4. Run `copy-db-snapshot` command using the default KMS key ID for RDS instances returned earlier to create an encrypted copy of the database instance snapshot, The command output will return the `encrypted instance snapshot configuration`. ``` aws rds copy-db-snapshot --region  --source-db-snapshot-identifier  --target-db-snapshot-identifier  --copy-tags --kms-key-id  ``` 5. Run `restore-db-instance-from-db-snapshot` command to restore the encrypted snapshot created at the previous step to a new database instance, If successful, the command output should return the new encrypted database instance configuration. ``` aws rds restore-db-instance-from-db-snapshot --region  --db-instance-identifier  --db-snapshot-identifier  ``` 6. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region, Output will return database instance identifier name Select encrypted database name that we just created DB-Name-Encrypted. ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 7. Run again `describe-db-instances` command using the RDS instance identifier returned earlier, to determine if the selected database instance is encrypted, The command output should return the encryption status `True`. ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].StorageEncrypted' ```","AdditionalInformation": ""}],"description": "Ensure that encryption is enabled for RDS Instances","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 48,"requirements_failed": 10,"requirements_manual": 0,"total_requirements": 58,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "fb07e872-c61f-4749-96d2-da2b68993ae5","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "gxp_21_cfr_part_11_aws","framework": "GxP-21-CFR-Part-11","version": "","description": "GxP refers to the regulations and guidelines that are applicable to life sciences organizations that make food and medical products. Medical products that fall under this include medicines, medical devices, and medical software applications. The overall intent of GxP requirements is to ensure that food and medical products are safe for consumers. It's also to ensure the integrity of data that's used to make product-related safety decisions.","region": "eu-west-1","requirements": {"11.30": {"name": "11.30 Controls for open systems","checks": {"elb_ssl_listeners": "FAIL","kms_cmk_rotation_enabled": null,"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","elbv2_insecure_ssl_ciphers": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.30","Section": "11.30 Controls for open systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use open systems to create, modify, maintain, or transmit electronic records shall employ procedures and controls designed to ensure the authenticity, integrity, and, as appropriate, the confidentiality of electronic records from the point of their creation to the point of their receipt. Such procedures and controls shall include those identified in 11.10, as appropriate, and additional measures such as document encryption and use of appropriate digital signature standards to ensure, as necessary under the circumstances, record authenticity, integrity, and confidentiality.","checks_status": {"fail": 9,"pass": 4,"total": 21,"manual": 0}},"11.200": {"name": "11.200 Electronic signature components and controls","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "11.200","Section": "11.200 Electronic signature components and controls","Service": "aws","SubGroup": null,"SubSection": null}],"description": "(a) Electronic signatures that are not based upon biometrics shall: (1) Employ at least two distinct identification components such as an identification code and password. (i) When an individual executes a series of signings during a single, continuous period of controlled system access, the first signing shall be executed using all electronic signature components; subsequent signings shall be executed using at least one electronic signature component that is only executable by, and designed to be used only by, the individual. (ii) When an individual executes one or more signings not performed during a single, continuous period of controlled system access, each signing shall be executed using all of the electronic signature components. (2) Be used only by their genuine owners; and (3) Be administered and executed to ensure that attempted use of an individual's electronic signature by anyone other than its genuine owner requires collaboration of two or more individuals.","checks_status": {"fail": 0,"pass": 0,"total": 12,"manual": 0}},"11.10-a": {"name": "11.10(a)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","ec2_instance_managed_by_ssm": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"ssm_managed_compliant_patching": "FAIL","rds_instance_deletion_protection": "FAIL","redshift_cluster_automated_snapshot": null,"ec2_instance_older_than_specific_days": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.10-a","Section": "11.10 Controls for closed systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use closed systems to create, modify, maintain, or transmit electronic records shall employ procedures and controls designed to ensure the authenticity, integrity, and, when appropriate, the confidentiality of electronic records, and to ensure that the signer cannot readily repudiate the signed record as not genuine. Such procedures and controls shall include the following: (a) Validation of systems to ensure accuracy, reliability, consistent intended performance, and the ability to discern invalid or altered records.","checks_status": {"fail": 8,"pass": 1,"total": 13,"manual": 0}},"11.10-c": {"name": "11.10(c)","checks": {"s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","s3_bucket_object_versioning": "FAIL","s3_bucket_default_encryption": "PASS","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"redshift_cluster_public_access": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS","sagemaker_notebook_instance_encryption_enabled": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.10-c","Section": "11.10 Controls for closed systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use closed systems to create, modify, maintain, or transmit electronic records shall employ procedures and controls designed to ensure the authenticity, integrity, and, when appropriate, the confidentiality of electronic records, and to ensure that the signer cannot readily repudiate the signed record as not genuine. Such procedures and controls shall include the following: (c) Protection of records to enable their accurate and ready retrieval throughout the records retention period.","checks_status": {"fail": 5,"pass": 3,"total": 14,"manual": 0}},"11.10-d": {"name": "11.10(d)","checks": {"iam_root_mfa_enabled": null,"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"ec2_instance_profile_attached": "PASS","iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"iam_user_mfa_enabled_console_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"iam_password_policy_minimum_length_14": null,"s3_account_level_public_access_blocks": null,"secretsmanager_automatic_rotation_enabled": "FAIL","awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.10-d","Section": "11.10 Controls for closed systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use closed systems to create, modify, maintain, or transmit electronic records shall employ procedures and controls designed to ensure the authenticity, integrity, and, when appropriate, the confidentiality of electronic records, and to ensure that the signer cannot readily repudiate the signed record as not genuine. Such procedures and controls shall include the following: (d) Limiting system access to authorized individuals.","checks_status": {"fail": 4,"pass": 8,"total": 38,"manual": 0}},"11.10-e": {"name": "11.10(e)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","opensearch_service_domains_cloudwatch_logging_enabled": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.10-d","Section": "11.10 Controls for closed systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use closed systems to create, modify, maintain, or transmit electronic records shall employ procedures and controls designed to ensure the authenticity, integrity, and, when appropriate, the confidentiality of electronic records, and to ensure that the signer cannot readily repudiate the signed record as not genuine. Such procedures and controls shall include the following: (e) Use of secure, computer-generated, time-stamped audit trails to independently record the date and time of operator entries and actions that create, modify, or delete electronic records. Record changes shall not obscure previously recorded information. Such audit trail documentation shall be retained for a period at least as long as that required for the subject electronic records and shall be available for agency review and copying.","checks_status": {"fail": 7,"pass": 2,"total": 14,"manual": 0}},"11.10-g": {"name": "11.10(g)","checks": {"iam_root_mfa_enabled": null,"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"ec2_ebs_volume_encryption": "PASS","iam_user_accesskey_unused": null,"ec2_ebs_default_encryption": "PASS","iam_password_policy_number": null,"iam_password_policy_symbol": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"ec2_instance_profile_attached": "PASS","iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"rds_instance_no_public_access": "PASS","efs_encryption_at_rest_enabled": "FAIL","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"iam_user_mfa_enabled_console_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"iam_password_policy_minimum_length_14": null,"s3_account_level_public_access_blocks": null,"secretsmanager_automatic_rotation_enabled": "FAIL","awslambda_function_not_publicly_accessible": "PASS","dynamodb_tables_kms_cmk_encryption_enabled": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"iam_customer_attached_policy_no_administrative_privileges": null,"opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.10-g","Section": "11.10 Controls for closed systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use closed systems to create, modify, maintain, or transmit electronic records shall employ procedures and controls designed to ensure the authenticity, integrity, and, when appropriate, the confidentiality of electronic records, and to ensure that the signer cannot readily repudiate the signed record as not genuine. Such procedures and controls shall include the following: (g) Use of authority checks to ensure that only authorized individuals can use the system, electronically sign a record, access the operation or computer system input or output device, alter a record, or perform the operation at hand.","checks_status": {"fail": 5,"pass": 10,"total": 44,"manual": 0}},"11.10-h": {"name": "11.10(h)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.10-h","Section": "11.10 Controls for closed systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use closed systems to create, modify, maintain, or transmit electronic records shall employ procedures and controls designed to ensure the authenticity, integrity, and, when appropriate, the confidentiality of electronic records, and to ensure that the signer cannot readily repudiate the signed record as not genuine. Such procedures and controls shall include the following: (h) Use of device (e.g., terminal) checks to determine, as appropriate, the validity of the source of data input or operational instruction.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"11.10-k": {"name": "11.10(k)","checks": {"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"cloudtrail_multi_region_enabled": "PASS","s3_bucket_policy_public_write_access": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.10-k","Section": "11.10 Controls for closed systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use closed systems to create, modify, maintain, or transmit electronic records shall employ procedures and controls designed to ensure the authenticity, integrity, and, when appropriate, the confidentiality of electronic records, and to ensure that the signer cannot readily repudiate the signed record as not genuine. Such procedures and controls shall include the following: (k) Use of appropriate controls over systems documentation including: (1) Adequate controls over the distribution of, access to, and use of documentation for system operation and maintenance. (2) Revision and change control procedures to maintain an audit trail that documents time-sequenced development and modification of systems documentation.","checks_status": {"fail": 5,"pass": 5,"total": 17,"manual": 0}},"11.300-b": {"name": "11.300(b)","checks": {"iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.300-b","Section": "11.300 Controls for identification codes/passwords","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use electronic signatures based upon use of identification codes in combination with passwords shall employ controls to ensure their security and integrity. Such controls shall include: (b) Ensuring that identification code and password issuances are periodically checked, recalled, or revised (e.g., to cover such events as password aging).","checks_status": {"fail": 1,"pass": 0,"total": 10,"manual": 0}},"11.300-d": {"name": "11.300(d)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.300-d","Section": "11.300 Controls for identification codes/passwords","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use electronic signatures based upon use of identification codes in combination with passwords shall employ controls to ensure their security and integrity. Such controls shall include: (d) Use of transaction safeguards to prevent unauthorized use of passwords and/or identification codes, and to detect and report in an immediate and urgent manner any attempts at their unauthorized use to the system security unit, and, as appropriate, to organizational management.","checks_status": {"fail": 1,"pass": 3,"total": 4,"manual": 0}}},"requirements_passed": 1,"requirements_failed": 10,"requirements_manual": 0,"total_requirements": 11,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}}]
+[{"model": "api.complianceoverview","pk": "07d0c342-abcb-4d91-b865-88f9c96adbfc","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "cisa_aws","framework": "CISA","version": "","description": "Cybersecurity & Infrastructure Security Agency's (CISA) Cyber Essentials is a guide for leaders of small businesses as well as leaders of small and local government agencies to develop an actionable understanding of where to start implementing organizational cybersecurity practices.","region": "eu-west-1","requirements": {"your-data-1": {"name": "Your Data-1","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"sagemaker_training_jobs_volume_and_output_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-data-1","Section": "your data","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Learn how your data is protected.","checks_status": {"fail": 4,"pass": 3,"total": 13,"manual": 0}},"your-data-2": {"name": "Your Data-2","checks": {"elb_ssl_listeners": "FAIL","elb_logging_enabled": "FAIL","elbv2_ssl_listeners": "FAIL","vpc_flow_logs_enabled": "FAIL","ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","efs_have_backup_enabled": "FAIL","s3_bucket_public_access": null,"s3_bucket_acl_prohibited": "FAIL","ec2_ebs_volume_encryption": "PASS","rds_snapshots_public_access": "PASS","s3_bucket_default_encryption": "PASS","rds_instance_no_public_access": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"redshift_cluster_public_access": null,"cloudtrail_multi_region_enabled": "PASS","acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_logging_enabled": "PASS","s3_bucket_policy_public_write_access": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","awslambda_function_not_publicly_accessible": "PASS","dynamodb_tables_kms_cmk_encryption_enabled": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_cloudwatch_logging_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_training_jobs_volume_and_output_encryption_enabled": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-data-2","Section": "your data","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Learn what is happening on your network, manage network and perimeter components, host and device components, data-at-rest and in-transit, and user behavior activities.","checks_status": {"fail": 18,"pass": 11,"total": 49,"manual": 0}},"your-data-3": {"name": "Your Data-3","checks": {"elbv2_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-data-3","Section": "your data","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Domain name system protection.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"your-data-4": {"name": "Your Data-4","checks": {"efs_have_backup_enabled": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL","redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-data-4","Section": "your data","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establish regular automated backups and redundancies of key systems.","checks_status": {"fail": 4,"pass": 1,"total": 8,"manual": 0}},"your-data-5": {"name": "Your Data-5","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "your-data-5","Section": "your data","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Leverage protections for backups, including physical security, encryption and offline copies.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"your-systems-1": {"name": "Your Systems-1","checks": {"ec2_elastic_ip_unassigned": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-systems-1","Section": "your systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Learn what is on your network. Maintain inventories of hardware and software assets to know what is in play and at-risk from attack.","checks_status": {"fail": 4,"pass": 0,"total": 4,"manual": 0}},"your-systems-2": {"name": "Your Systems-2","checks": {"ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-systems-2","Section": "your systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Leverage automatic updates for all operating systems and third-party software.","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"your-systems-3": {"name": "Your Systems-3","checks": {"elb_ssl_listeners": "FAIL","elb_logging_enabled": "FAIL","elbv2_ssl_listeners": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_root_mfa_enabled": null,"rds_instance_multi_az": "FAIL","ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","efs_have_backup_enabled": "FAIL","s3_bucket_public_access": null,"kms_cmk_rotation_enabled": null,"ec2_ebs_volume_encryption": "PASS","elbv2_deletion_protection": "FAIL","iam_user_accesskey_unused": null,"ec2_ebs_default_encryption": "PASS","iam_password_policy_number": null,"iam_password_policy_symbol": null,"rds_instance_backup_enabled": "PASS","rds_snapshots_public_access": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"s3_bucket_default_encryption": "PASS","iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"rds_instance_no_public_access": "PASS","efs_encryption_at_rest_enabled": "FAIL","iam_user_console_access_unused": null,"rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"redshift_cluster_public_access": null,"cloudtrail_multi_region_enabled": "PASS","rds_instance_deletion_protection": "FAIL","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_logging_enabled": "PASS","apigateway_restapi_waf_acl_attached": "FAIL","iam_user_mfa_enabled_console_access": null,"redshift_cluster_automated_snapshot": null,"s3_bucket_policy_public_write_access": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"emr_cluster_master_nodes_no_public_ip": null,"iam_password_policy_minimum_length_14": null,"s3_account_level_public_access_blocks": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","secretsmanager_automatic_rotation_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","vpc_endpoint_connections_trust_boundaries": "FAIL","awslambda_function_not_publicly_accessible": "PASS","dynamodb_tables_kms_cmk_encryption_enabled": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL","codebuild_project_user_controlled_buildspec": "PASS","apigateway_restapi_client_certificate_enabled": "FAIL","iam_inline_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_aws_attached_policy_no_administrative_privileges": null,"opensearch_service_domains_cloudwatch_logging_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"iam_customer_attached_policy_no_administrative_privileges": null,"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_training_jobs_volume_and_output_encryption_enabled": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-systems-3","Section": "your systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement security configurations for all hardware and software assets.","checks_status": {"fail": 25,"pass": 16,"total": 84,"manual": 0}},"your-surroundings-1": {"name": "Your Surroundings-1","checks": {"vpc_flow_logs_enabled": "FAIL","ec2_elastic_ip_unassigned": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-surroundings-1","Section": "your surroundings","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Learn who is on your network. Maintain inventories of network connections (user accounts, vendors, business partners, etc.).","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"your-surroundings-2": {"name": "Your Surroundings-2","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "your-surroundings-2","Section": "your surroundings","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Leverage multi-factor authentication for all users, starting with privileged, administrative and remote access users.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"your-surroundings-3": {"name": "Your Surroundings-3","checks": {"elbv2_ssl_listeners": "FAIL","iam_no_root_access_key": null,"iam_inline_policy_no_administrative_privileges": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "your-surroundings-3","Section": "your surroundings","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Grant access and admin permissions based on need-to-know and least privilege.","checks_status": {"fail": 1,"pass": 0,"total": 6,"manual": 0}},"your-surroundings-4": {"name": "Your Surroundings-4","checks": {"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "your-surroundings-4","Section": "your surroundings","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Leverage unique passwords for all user accounts.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"your-crisis-response-2": {"name": "Your Crisis Response-2","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "your-crisis-response-2","Section": "your crisis response","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Lead development of an internal reporting structure to detect, communicate and contain attacks.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"booting-up-thing-to-do-first-1": {"name": "YBooting Up: Things to Do First-1","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "booting-up-thing-to-do-first-1","Section": "booting up thing to do first","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Lead development of an internal reporting structure to detect, communicate and contain attacks.","checks_status": {"fail": 2,"pass": 1,"total": 7,"manual": 0}},"booting-up-thing-to-do-first-2": {"name": "YBooting Up: Things to Do First-2","checks": {"iam_root_mfa_enabled": null,"iam_user_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "booting-up-thing-to-do-first-2","Section": "booting up thing to do first","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Require multi-factor authentication (MFA) for accessing your systems whenever possible. MFA should be required of all users, but start with privileged, administrative, and remote access users.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"booting-up-thing-to-do-first-3": {"name": "YBooting Up: Things to Do First-3","checks": {"ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "booting-up-thing-to-do-first-1","Section": "booting up thing to do first","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Enable automatic updates whenever possible. Replace unsupported operating systems, applications and hardware. Test and deploy patches quickly.","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}}},"requirements_passed": 4,"requirements_failed": 11,"requirements_manual": 1,"total_requirements": 16,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "089cf697-547a-4a34-a811-e7a19b78b9fd","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "aws_foundational_technical_review_aws","framework": "AWS-Foundational-Technical-Review","version": "","description": "The AWS Foundational Technical Review (FTR) assesses an AWS Partner's solution against a specific set of Amazon Web Services (AWS) best practices around security, performance, and operational processes that are most critical for customer success. Passing the FTR is required to qualify AWS Software Partners for AWS Partner Network (APN) programs such as AWS Competency and AWS Service Ready but any AWS Partner who offers a technology solution may request a FTR review through AWS Partner Central.","region": "eu-west-1","requirements": {"S3-001": {"name": "Review all Amazon S3 buckets to determine appropriate access levels","checks": {"s3_bucket_object_lock": "FAIL","s3_bucket_public_access": null,"s3_bucket_acl_prohibited": "FAIL","s3_bucket_kms_encryption": "FAIL","s3_bucket_public_list_acl": null,"s3_bucket_public_write_acl": null,"s3_bucket_default_encryption": "PASS","s3_bucket_secure_transport_policy": "FAIL","s3_bucket_level_public_access_block": "PASS","s3_bucket_policy_public_write_access": "PASS","s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "You must ensure that buckets that require public access have been reviewed to determine if public read or write access is needed and if appropriate controls are in place to control public access. When assigning access permissions, follow the principle of least privilege, an AWS best practice. For more information, refer to overview of managing access.","checks_status": {"fail": 5,"pass": 3,"total": 11,"manual": 0}},"ARC-001": {"name": "Use root user only by exception","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "The root user has unlimited access to your account and its resources, and using it only by exception helps protect your AWS resources. The AWS root user must not be used for everyday tasks, even administrative ones. Instead, adhere to the best practice of using the root user only to create your first AWS Identity and Access Management (IAM) user. Then securely lock away the root user credentials and use them to perform only a few accounts and service management tasks. To view the tasks that require you to sign in as the root user, see AWS Tasks That Require Root User. FTR does not require you to actively monitor root usage.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ARC-003": {"name": "Enable multi-factor authentication (MFA) on the root user for all AWS accounts","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Enabling MFA provides an additional layer of protection against unauthorized access to your account. To configure MFA for the root user, follow the instructions for enabling either a virtual MFA or hardware MFA device. If you are using AWS Organizations to create new accounts, the initial password for the root user is set to a random value that is never exposed to you. If you do not recover the password for the root user of these accounts, you do not need to enable MFA on them. For any accounts where you do have access to the root user’s password, you must enable MFA","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"ARC-004": {"name": "Remove access keys for the root user","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Programmatic access to AWS APIs should never use the root user. It is best not to generate static an access key for the root user. If one already exists, you should transition any processes using that key to use temporary access keys from an AWS Identity and Access Management (IAM) role, or, if necessary, static access keys from an IAM user.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ARC-005": {"name": "Develop incident management plans","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "An incident management plan is critical to respond, mitigate, and recover from the potential impact of security incidents. An incident management plan is a structured process for identifying, remediating, and responding in a timely matter to security incidents. An effective incident management plan must be continually iterated upon, remaining current with your cloud operations goal. For more information on developing incident management plan please see Develop incident management plans.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"BAR-001": {"name": "Configure automatic data backups","checks": {"backup_plans_exist": "PASS","backup_vaults_exist": null,"backup_vaults_encrypted": "PASS","efs_have_backup_enabled": "FAIL","backup_reportplans_exist": null,"rds_instance_backup_enabled": "PASS"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "You must perform regular backups to a durable storage service. Backups ensure that you have the ability to recover from administrative, logical, or physical error scenarios. Configure backups to be taken automatically based on a periodic schedule, or by changes in the dataset. RDS instances, EBS volumes, DynamoDB tables, and S3 objects can all be configured for automatic backup. AWS Backup, AWS Marketplace solutions or third-party solutions can also be used. If objects in S3 bucket are write-once-read-many (WORM), compensating controls such as object lock can be used meet this requirement. If it is customers’ responsibility to backup their data, it must be clearly stated in the documentation and the Partner must provide clear instructions on how to backup the data.","checks_status": {"fail": 1,"pass": 3,"total": 6,"manual": 0}},"BAR-002": {"name": "Periodically recover data to verify the integrity of your backup process","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "To confirm that your backup process meets your recovery time objectives (RTO) and recovery point objectives (RPO), run a recovery test on a regular schedule and after making significant changes to your cloud environment. For more information, refer to Getting Started - Backup and Restore with AWS.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"CAA-001": {"name": "Use cross-account roles to access customer AWS accounts","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Cross-account roles reduce the amount of sensitive information AWS Partners need to store for their customers.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"CAA-002": {"name": "Use an external ID with cross-account roles to access customer accounts","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "An external ID allows the user that is assuming the role to assert the circumstances in which they are operating. It also provides a way for the account owner to permit the role to be assumed only under specific circumstances. The primary function of the external ID is to address and prevent the confused deputy problem.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"CAA-003": {"name": "Deprecate any historical use of customer-provided IAM credentials","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "If your application provides legacy support for the use of static IAM credentials for cross-account access, the application's user interface and customer documentation must make it clear that this method is deprecated. Existing customers should be encouraged to switch to cross-account role based-access, and collection of credentials should be disabled for new customers.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"CAA-004": {"name": "Use a value you generate (not something provided by the customer) for the external ID","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "When configuring cross-account access using IAM roles, you must use a value you generate for the external ID, instead of one provided by the customer, to ensure the integrity of the cross-account role configuration. A partner-generated external ID ensures that malicious parties cannot impersonate a customer's configuration and enforces uniqueness and format consistency across all customers. If you are not generating an external ID today we recommend implementing a process that generates a random unique value (such as a Universally Unique Identifier) for the external ID that a customer uses to set up a cross-account role.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"CAA-005": {"name": "Ensure that all external IDs are unique.","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "The external IDs used must be unique across all customers. Re-using external IDs for different customers does not solve the confused deputy problem and runs the risk of customer A being able to view data of customer B by using the role ARN and the external ID of customer B. To resolve this, we recommend implementing a process that ensures a random unique value, such as a Universally Unique Identifier, is generated for the external ID that a customer would use to setup a cross account role.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"CAA-006": {"name": "Provide read-only access to external ID to customers","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Customers must not be able to set or influence external IDs. When the external ID is editable, it is possible for one customer to impersonate the configuration of another. For example, when the external ID is editable, customer A can create a cross account role setup using customer B’s role ARN and external ID, granting customer A access to customer B’s data. Remediation of this item involves making the external ID a view-only field, ensuring that the external ID cannot be changed to impersonate the setup of another customer.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"CAA-007": {"name": "Provide guidance or an automated setup mechanism (for example, an AWS CloudFormation template) for creating cross-account roles with the minimum required privileges","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "The policy created for cross-account access in customer accounts must follow the principle of least privilege. The AWS Partner must provide a role-policy document or an automated setup mechanism (for example, an AWS CloudFormation template) for the customers to use to ensure that the roles are created with minimum required privileges. For more information, refer to the AWS Partner Network (APN) blog posts.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"IAM-001": {"name": "Enable multi-factor authentication (MFA) for all Human Identities with AWS access","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_hardware_mfa_enabled": null,"iam_administrator_access_with_mfa": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "You must require any human identities to authenticate using MFA before accessing your AWS accounts. Typically, this means enabling MFA within your corporate identity provider. If you have existing legacy IAM users you must enable MFA for console access for those principals as well. Enabling MFA for IAM users provides an additional layer of security. With MFA, users have a device that generates a unique authentication code (a one-time password, or OTP). Users must provide both their normal credentials (user name and password) and the OTP. The MFA device can either be a special piece of hardware, or it can be a virtual device (for example, it can run in an app on a smartphone). Please note that machine identities do not require MFA.","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"IAM-002": {"name": "Monitor and secure static AWS Identity and Access Management (IAM) credentials","checks": {"guardduty_is_enabled": "PASS","iam_user_accesskey_unused": null,"iam_rotate_access_key_90_days": null,"guardduty_no_high_severity_findings": "FAIL","iam_user_with_temporary_credentials": null},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Use temporary IAM credentials retrieved by assuming a role whenever possible. In cases where it is infeasible to use IAM roles, implement the following controls to reduce the risk these credentials are misused: Rotate IAM access keys regularly (recommended at least every 90 days). Maintain an inventory of all static keys and where they are used and remove unused access keys. Implement monitoring of AWS CloudTrail logs to detect anomalous activity or other potential misuse (e.g. using AWS GuardDuty.) Define a runbook or SOP for revoking credentials in the event you detect misuse.","checks_status": {"fail": 1,"pass": 1,"total": 5,"manual": 0}},"IAM-003": {"name": "Use strong password policy","checks": {"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_password_policy_minimum_length_14": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Enforce a strong password policy, and educate users to avoid common or re-used passwords. For IAM users, you can create a password policy for your account on the Account Settings page of the IAM console. You can use the password policy to define password requirements, such as minimum length and whether it requires non-alphabetic characters, and so on. For more information, see Setting an Account Password Policy for IAM users.","checks_status": {"fail": 0,"pass": 0,"total": 7,"manual": 0}},"IAM-004": {"name": "Create individual identities (no shared credentials) for anyone who needs AWS access","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Create individual entities and give unique security credentials and permissions to each user accessing your account. With individual entities and no shared credentials, you can audit the activity of each user.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"IAM-005": {"name": "Use IAM roles and its temporary security credentials to provide access to third parties.","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Do not provision IAM users and share those credentials with people outside of your organization. Any external services that need to make AWS API calls against your account (for example, a monitoring solution that accesses your account's AWS CloudWatch metrics) must use a cross-account role. For more information, refer to Providing access to AWS accounts owned by third parties.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"IAM-006": {"name": "Grant least privilege access","checks": {"iam_policy_attached_only_to_group_or_roles": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "You must follow the standard security advice of granting least privilege. Grant only the access that identities require by allowing access to specific actions on specific AWS resources under specific conditions. Rely on groups and identity attributes to dynamically set permissions at scale, rather than defining permissions for individual users. For example, you can allow a group of developers access to manage only resources for their project. This way, when a developer is removed from the group, access for the developer is revoked everywhere that group was used for access control, without requiring any changes to the access policies.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"IAM-007": {"name": "Manage access based on life cycle","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Integrate access controls with operator and application lifecycle and your centralized federation provider and IAM. For example, remove a user’s access when they leave the organization or change roles.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"IAM-008": {"name": "Audit identities quarterly","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Auditing the identities that are configured in your identity provider and IAM helps ensure that only authorized identities have access to your workload. For example, remove people that leave the organization, and remove cross-account roles that are no longer required. Have a process in place to periodically audit permissions to the services accessed by an IAM entity. This helps you identify the policies you needto modify to remove any unused permissions. For more information, see Refining permissions in AWS using last accessed information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"IAM-009": {"name": "Do not embed credentials in application code","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Ensure that all credentials used by your applications (for example, IAM access keys and database passwords) are never included in your application's source code or committed to source control in any way.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"RES-001": {"name": "Define a Recovery Point Objective (RPO)","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "To confirm that your backup process meets your recovery time objectives (RTO) and recovery point objectives (RPO), run a recovery test on a regular schedule and after making significant changes to your cloud environment. For more information, refer to Getting Started - Backup and Restore with AWS.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"RES-002": {"name": "Establish a Recovery Time Objective (RTO)","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Define an RTO that meets your organization’s needs and expectations. RTO is the maximum acceptable delay your organization will accept between the interruption and restoration of service.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"RES-004": {"name": "Resiliency Testing","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Test resiliency to ensure that RTO and RPO are met, both periodically (minimum every 12 months) and after major updates. The resiliency test must include accidental data loss, instance failures, and Availability Zone (AZ) failures. At least one resilience test that meets RTO and RPO requirements must be completed prior to FTR approval. You can use AWS Resilience Hub to test and verify your workloads to see if it meets its resilience target. AWS Resilience Hub works with AWS Fault Injection Service (AWS FIS) , a chaos engineering service, to provide fault-injection simulations of real-world failures to validate the application recovers within the resilience targets you defined. AWS Resilience Hub also provides API operations for you to integrate its resilience assessment and testing into your CI/CD pipelines for ongoing resilience validation. Including resilience validation in CI/CD pipelines helps make sure that changes to the workload’s underlying infrastructure don't compromise resilience.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"RES-005": {"name": "Communicate customer responsibilities for resilience","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Clearly define your customers’ responsibility for backup, recovery, and availability. At a minimum, your product documentation or customer agreements should cover the following: Responsibility the customer has for backing up the data stored in your solution. Instructions for backing up data or configuring optional features in your product for data protection, if applicable. Options customers have for configuring the availability of your product.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"RES-006": {"name": "Architect your product to meet availability targets and uptime service level agreements (SLAs)","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "If you publish or privately agree to availability targets or uptime SLAs, ensure that your architecture and operational processes are designed to support them. Additionally, provide clear guidance to customers on any configuration required to achieve the targets or SLAs.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"RES-007": {"name": "Define a customer communication plan for outages","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Establish a plan for communicating information about system outages to your customers both during and after incidents. Your communication should not include any data that was provided by AWS under a non-disclosure agreement (NDA).","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SUP-001": {"name": "Subscribe to the AWS Business Support tier (or higher) for all production AWS accounts or have an action plan to handle issues which require help from AWS Support","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Partner-hosted FTR requirements","Service": null,"SubGroup": null,"SubSection": null}],"description": "It is recommended that you subscribe to the AWS Business Support tier or higher (including AWS Partner-Led Support) for all of your AWS production accounts. For more information, refer to Compare AWS Support Plans. If you don't have premium support, you must have an action plan to handle issues which require help from AWS Support. AWS Support provides a mix of tools and technology, people, and programs designed to proactively help you optimize performance, lower costs, and innovate faster. AWS Business Support provides additional benefits including access to AWS Trusted Advisor and AWS Personal Health Dashboard and faster response times.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ACOM-001": {"name": "Configure AWS account contacts","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "If an account is not managed by AWS Organizations, alternate account contacts help AWS get in contact with the appropriate personnel if needed. Configure the account’s alternate contacts to point to a group rather than an individual. For example, create separate email distribution lists for billing, operations, and security and configure these as Billing, Security, and Operations contacts in each active AWS account. This ensures that multiple people will receive AWS notifications and be able to respond, even if someone is on vacation, changes roles, or leaves the company.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ACOM-002": {"name": "Set account contact information including the root user email address to email addresses and phone numbers owned by your company","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Using company owned email addresses and phone numbers for contact information enables you to access them even if the individuals whom they belong to are no longer with your organization","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"HOST-001": {"name": "Confirm your hosting model","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Partner-hosted FTR requirements","Service": null,"SubGroup": null,"SubSection": null}],"description": "To use this FTR checklist you must host all critical application components on AWS. You may use external providers for edge services such as content delivery networks (CDNs) or domain name system (DNS), or corporate identity providers. If you are using any edge services outside AWS, please specify them in the self-assessment.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"IAM-0010": {"name": "Store secrets securely.","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Encrypt all secrets in transit and at rest, define fine-grained access controls that only allow access to specific identities, and log access to secrets in an audit log. We recommend you use a purpose-built secret management service such as AWS Secrets Manager, AWS Systems Manager Parameter Store, or an AWS Partner solution, but internally developed solutions that meet these requirements are also acceptable.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"IAM-0011": {"name": "Encrypt all end user/customer credentials and hash passwords at rest.","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "If you are storing end user/customer credentials in a database that you manage, encrypt credentials at rest and hash passwords. As an alternative, AWS recommends using a user-identity synchronization service, such as Amazon Cognito or an equivalent AWS Partner solution.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"IAM-0012": {"name": "Use temporary credentials","checks": {"iam_root_mfa_enabled": null,"iam_user_accesskey_unused": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_hardware_mfa_enabled": null,"iam_administrator_access_with_mfa": null,"iam_role_administratoraccess_policy": null,"iam_user_mfa_enabled_console_access": null,"iam_user_with_temporary_credentials": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_role_cross_account_readonlyaccess_policy": null,"iam_role_cross_service_confused_deputy_prevention": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Use temporary security credentials to access AWS resources. For machine identities within AWS (for example, Amazon Elastic Compute Cloud (Amazon EC2) instances or AWS Lambda functions), always use IAM roles to acquire temporary security credentials. For machine identities running outside of AWS, use IAM Roles Anywhere or securely store static AWS access keys that are only used to assume an IAM role.For human identities, use AWS IAM Identity Center or other identity federation solutions where possible. If you must use static AWS access keys for human users, require MFA for all access, including the AWS Management Console, and AWS Command Line Interface (AWS CLI).","checks_status": {"fail": 0,"pass": 0,"total": 13,"manual": 0}},"RCVP-001": {"name": "Establish a process to ensure that all required compliance standards are met","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "If you advertise that your product meets specific compliance standards, you must have an internal process for ensuring compliance. Examples of compliance standards include Payment Card Industry Data Security Standard (PCI DSS) PCI DSS, Federal Risk and Authorization Management Program (FedRAMP)FedRAMP, and U.S. Health Insurance Portability and Accountability Act (HIPAA)HIPAA. Applicable compliance standards are determined by various factors, such as what types of data the solution stores or transmits and which geographic regions the solution supports.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SDAT-001": {"name": "Identify sensitive data (for example, Personally Identifiable Information (PII) and Protected Health Information (PHI))","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Data classification enables you to determine which data needs to be protected and how. Based on the workload and the data it processes, identify the data that is not common public knowledge.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SDAT-002": {"name": "Encrypt all sensitive data at rest","checks": {"athena_workgroup_encryption": null,"efs_encryption_at_rest_enabled": "FAIL","cloudtrail_kms_encryption_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Encryption maintains the confidentiality of sensitive data even when it gets stolen or the network through which it is transmitted becomes compromised.","checks_status": {"fail": 3,"pass": 0,"total": 7,"manual": 0}},"SDAT-003": {"name": "Only use protocols with encryption when transmitting sensitive data outside of your VPC","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Encryption maintains data confidentiality even when the network through which it is transmitted becomes compromised.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"WAFR-001": {"name": "Conduct periodic architecture reviews (minimum once every year)","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Partner-hosted FTR requirements","Service": null,"SubGroup": null,"SubSection": null}],"description": "Conduct periodic architecture reviews of your production workload (at least once per year) using a documented architectural standard that includes AWS-specific best practices. If you have an internally defined standard for your AWS workloads, we recommend you use it for these reviews. If you do not have an internal standard, we recommend you use the AWS Well-Architected Framework.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"WAFR-002": {"name": "Review the AWS Shared Responsibility Models for Security and Resiliency","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Partner-hosted FTR requirements","Service": null,"SubGroup": null,"SubSection": null}],"description": "Review the AWS Shared Responsibility Model for Security and the AWS Shared Responsibility Model for Resiliency. Ensure that your product’s architecture and operational processes address the customer responsibilities defined in these models. We recommend you to use AWS Resilience Hub to ensure your workload resiliency posture meets your targets and to provide you with operational procedures you may use to address the customer responsibilities.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"NETSEC-001": {"name": "Implement the least permissive rules for all Amazon EC2 security groups","checks": {"ec2_ami_public": null,"ec2_instance_public_ip": "FAIL","ec2_securitygroup_not_used": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "All Amazon EC2 security groups should restrict access to the greatest degree possible. At a minimum, do the following: Ensure that no security groups allow ingress from 0.0.0.0/0 to port 22 or 3389 (CIS 5.2) Ensure that the default security group of every VPC restricts all traffic (CIS 5.3/Security Control EC2.2)","checks_status": {"fail": 3,"pass": 16,"total": 20,"manual": 0}},"NETSEC-002": {"name": "Restrict resources in public subnets","checks": {"vpc_subnet_no_public_ip_by_default": "FAIL","vpc_subnet_separate_private_public": "FAIL","vpc_endpoint_connections_trust_boundaries": "FAIL","workspaces_vpc_2private_1public_subnets_nat": null,"vpc_endpoint_services_allowed_principals_trust_boundaries": null},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Do not place resources in public subnets of your VPC unless they must receive network traffic from public sources. Public subnets are subnets associated with a route table that has a route to an internet gateway.","checks_status": {"fail": 3,"pass": 0,"total": 5,"manual": 0}},"SECOPS-001": {"name": "Perform vulnerability management","checks": {"inspector2_is_enabled": "FAIL","inspector2_active_findings_exist": "FAIL","guardduty_no_high_severity_findings": "FAIL","accessanalyzer_enabled_without_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Architectural and Operational Controls","Service": null,"SubGroup": null,"SubSection": null}],"description": "Define a mechanism and frequency to scan and patch for vulnerabilities in your dependencies, and in your operating systems to help protect against new threats. Scan and patch your dependencies, and your operating systems on a defined schedule. Software vulnerability management is essential to keeping your system secure from threat actors. Embedding vulnerability assessments early into your continuous integration/continuous delivery (CI/CD) pipeline allows you to prioritize remediation of any security vulnerabilities detected. The solution you need to achieve this varies according to the AWS services that you are consuming. To check for vulnerabilities in software running in Amazon EC2 instances, you can add Amazon Inspector to your pipeline to cause your build to fail if Inspector detects vulnerabilities. You can also use open source products such as OWASP Dependency-Check, Snyk, OpenVAS, package managers and AWS Partner tools for vulnerability management.","checks_status": {"fail": 4,"pass": 0,"total": 4,"manual": 0}}},"requirements_passed": 6,"requirements_failed": 7,"requirements_manual": 32,"total_requirements": 45,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "1491ce35-3d2b-4cf6-a56d-b18b391d5623","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "nist_800_171_revision_2_aws","framework": "NIST-800-171-Revision-2","version": "","description": "The cybersecurity controls within NIST 800-171 safeguard CUI in the IT networks of government contractors and subcontractors. It defines the practices and procedures that government contractors must adhere to when their networks process or store CUI. NIST 800-171 only applies to those parts of a contractor’s network where CUI is present.","region": "eu-west-1","requirements": {"3_1_1": {"name": "3.1.1 Limit system access to authorized users, processes acting on behalf of authorized users, and devices (including other systems)","checks": {"iam_root_mfa_enabled": null,"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"ec2_instance_profile_attached": "PASS","iam_root_hardware_mfa_enabled": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"eks_cluster_not_publicly_accessible": null,"iam_user_mfa_enabled_console_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_1_1","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Access control policies (e.g., identity or role-based policies, control matrices, and cryptography) control access between active entities or subjects (i.e., users or processes acting on behalf of users) and passive entities or objects (e.g., devices, files, records, and domains) in systems. Access enforcement mechanisms can be employed at the application and service level to provide increased information security. Other systems include systems internal and external to the organization. This requirement focuses on account management for systems and applications. The definition of and enforcement of access authorizations, other than those determined by account type (e.g., privileged verses non-privileged) are addressed in requirement 3.1.2.","checks_status": {"fail": 3,"pass": 7,"total": 28,"manual": 0}},"3_1_2": {"name": "3.1.2 Limit system access to the types of transactions and functions that authorized users are permitted to execute","checks": {"iam_root_mfa_enabled": null,"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"ec2_instance_profile_attached": "PASS","iam_root_hardware_mfa_enabled": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"eks_cluster_not_publicly_accessible": null,"iam_user_mfa_enabled_console_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_1_2","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Organizations may choose to define access privileges or other attributes by account, by type of account, or a combination of both. System account types include individual, shared, group, system, anonymous, guest, emergency, developer, manufacturer, vendor, and temporary. Other attributes required for authorizing access include restrictions on time-of-day, day-of-week, and point-oforigin. In defining other account attributes, organizations consider system-related requirements (e.g., system upgrades scheduled maintenance,) and mission or business requirements, (e.g., time zone differences, customer requirements, remote access to support travel requirements).","checks_status": {"fail": 3,"pass": 7,"total": 28,"manual": 0}},"3_1_3": {"name": "3.1.3 Control the flow of CUI in accordance with approved authorizations","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"eks_cluster_not_publicly_accessible": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_1_3","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Information flow control regulates where information can travel within a system and between systems (versus who can access the information) and without explicit regard to subsequent accesses to that information. Flow control restrictions include the following: keeping exportcontrolled information from being transmitted in the clear to the Internet; blocking outside traffic that claims to be from within the organization; restricting requests to the Internet that are not from the internal web proxy server; and limiting information transfers between organizations based on data structures and content. Organizations commonly use information flow control policies and enforcement mechanisms to control the flow of information between designated sources and destinations (e.g., networks, individuals, and devices) within systems and between interconnected systems. Flow control is based on characteristics of the information or the information path. Enforcement occurs in boundary protection devices (e.g., gateways, routers, guards, encrypted tunnels, firewalls) that employ rule sets or establish configuration settings that restrict system services, provide a packetfiltering capability based on header information, or message-filtering capability based on message content (e.g., implementing key word searches or using document characteristics). Organizations also consider the trustworthiness of filtering and inspection mechanisms (i.e., hardware, firmware, and software components) that are critical to information flow enforcement. Transferring information between systems representing different security domains with different security policies introduces risk that such transfers violate one or more domain security policies. In such situations, information owners or stewards provide guidance at designated policy enforcement points between interconnected systems. Organizations consider mandating specific architectural solutions when required to enforce specific security policies. Enforcement includes: prohibiting information transfers between interconnected systems (i.e., allowing access only); employing hardware mechanisms to enforce one-way information flows; and implementing trustworthy regrading mechanisms to reassign security attributes and security labels.","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"3_1_4": {"name": "3.1.4 Separate the duties of individuals to reduce the risk of malevolent activity without collusion","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_1_4","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Separation of duties addresses the potential for abuse of authorized privileges and helps to reduce the risk of malevolent activity without collusion. Separation of duties includes dividing mission functions and system support functions among different individuals or roles; conducting system support functions with different individuals (e.g., configuration management, quality assurance and testing, system management, programming, and network security); and ensuring that security personnel administering access control functions do not also administer audit functions. Because separation of duty violations can span systems and application domains, organizations consider the entirety of organizational systems and system components when developing policy on separation of duties.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"3_1_5": {"name": "3.1.5 Employ the principle of least privilege, including for specific security functions and privileged accounts","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_1_5","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Organizations employ the principle of least privilege for specific duties and authorized accesses for users and processes. The principle of least privilege is applied with the goal of authorized privileges no higher than necessary to accomplish required organizational missions or business functions. Organizations consider the creation of additional processes, roles, and system accounts as necessary, to achieve least privilege. Organizations also apply least privilege to the development, implementation, and operation of organizational systems. Security functions include establishing system accounts, setting events to be logged, setting intrusion detection parameters, and configuring access authorizations (i.e., permissions, privileges). Privileged accounts, including super user accounts, are typically described as system administrator for various types of commercial off-the-shelf operating systems. Restricting privileged accounts to specific personnel or roles prevents day-to-day users from having access to privileged information or functions. Organizations may differentiate in the application of this requirement between allowed privileges for local accounts and for domain accounts provided organizations retain the ability to control system configurations for key security parameters and as otherwise necessary to sufficiently mitigate risk.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"3_1_6": {"name": "3.1.6 Use non-privileged accounts or roles when accessing nonsecurity functions","checks": {"iam_no_root_access_key": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_1_6","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "This requirement limits exposure when operating from within privileged accounts or roles. The inclusion of roles addresses situations where organizations implement access control policies such as role-based access control and where a change of role provides the same degree of assurance in the change of access authorizations for the user and all processes acting on behalf of the user as would be provided by a change between a privileged and non-privileged account.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"3_1_7": {"name": "3.1.7 Prevent non-privileged users from executing privileged functions and capture the execution of such functions in audit logs","checks": {"iam_no_root_access_key": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_1_7","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Privileged functions include establishing system accounts, performing system integrity checks, conducting patching operations, or administering cryptographic key management activities. Nonprivileged users are individuals that do not possess appropriate authorizations. Circumventing intrusion detection and prevention mechanisms or malicious code protection mechanisms are examples of privileged functions that require protection from non-privileged users. Note that this requirement represents a condition to be achieved by the definition of authorized privileges in 3.1.2. Misuse of privileged functions, either intentionally or unintentionally by authorized users, or by unauthorized external entities that have compromised system accounts, is a serious and ongoing concern and can have significant adverse impacts on organizations. Logging the use of privileged functions is one way to detect such misuse, and in doing so, help mitigate the risk from insider threats and the advanced persistent threat.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"3_3_1": {"name": "3.3.1 Create and retain system audit logs and records to the extent needed to enable the monitoring, analysis, investigation, and reporting of unlawful or unauthorized system activity","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_3_1","Section": "3.3 Audit and Accountability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "An event is any observable occurrence in a system, which includes unlawful or unauthorized system activity. Organizations identify event types for which a logging functionality is needed as those events which are significant and relevant to the security of systems and the environments in which those systems operate to meet specific and ongoing auditing needs. Event types can include password changes, failed logons or failed accesses related to systems, administrative privilege usage, or third-party credential usage. In determining event types that require logging, organizations consider the monitoring and auditing appropriate for each of the CUI security requirements. Monitoring and auditing requirements can be balanced with other system needs. For example, organizations may determine that systems must have the capability to log every file access both successful and unsuccessful, but not activate that capability except for specific circumstances due to the potential burden on system performance. Audit records can be generated at various levels of abstraction, including at the packet level as information traverses the network. Selecting the appropriate level of abstraction is a critical aspect of an audit logging capability and can facilitate the identification of root causes to problems. Organizations consider in the definition of event types, the logging necessary to cover related events such as the steps in distributed, transaction-based processes (e.g., processes that are distributed across multiple organizations) and actions that occur in service-oriented or cloudbased architectures. Audit record content that may be necessary to satisfy this requirement includes time stamps, source and destination addresses, user or process identifiers, event descriptions, success or fail indications, filenames involved, and access control or flow control rules invoked. Event outcomes can include indicators of event success or failure and event-specific results (e.g., the security state of the system after the event occurred). Detailed information that organizations may consider in audit records includes full text recording of privileged commands or the individual identities of group account users. Organizations consider limiting the additional audit log information to only that information explicitly needed for specific audit requirements. This facilitates the use of audit trails and audit logs by not including information that could potentially be misleading or could make it more difficult to locate information of interest. Audit logs are reviewed and analyzed as often as needed to provide important information to organizations to facilitate risk-based decision making.","checks_status": {"fail": 7,"pass": 4,"total": 14,"manual": 0}},"3_3_2": {"name": "3.3.2 Ensure that the actions of individual system users can be uniquely traced to those users, so they can be held accountable for their actions","checks": {"guardduty_is_enabled": "PASS","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_3_2","Section": "3.3 Audit and Accountability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "This requirement ensures that the contents of the audit record include the information needed to link the audit event to the actions of an individual to the extent feasible. Organizations consider logging for traceability including results from monitoring of account usage, remote access, wireless connectivity, mobile device connection, communications at system boundaries, configuration settings, physical access, nonlocal maintenance, use of maintenance tools, temperature and humidity, equipment delivery and removal, system component inventory, use of mobile code, and use of Voice over Internet Protocol (VoIP).","checks_status": {"fail": 3,"pass": 3,"total": 9,"manual": 0}},"3_3_3": {"name": "3.3.3 Review and update logged events","checks": {"vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_3_3","Section": "3.3 Audit and Accountability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The intent of this requirement is to periodically re-evaluate which logged events will continue to be included in the list of events to be logged. The event types that are logged by organizations may change over time. Reviewing and updating the set of logged event types periodically is necessary to ensure that the current set remains necessary and sufficient.","checks_status": {"fail": 4,"pass": 2,"total": 9,"manual": 0}},"3_3_4": {"name": "3.3.4 Alert in the event of an audit logging process failure","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_3_4","Section": "3.3 Audit and Accountability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Audit logging process failures include software and hardware errors, failures in the audit record capturing mechanisms, and audit record storage capacity being reached or exceeded. This requirement applies to each audit record data storage repository (i.e., distinct system component where audit records are stored), the total audit record storage capacity of organizations (i.e., all audit record data storage repositories combined), or both.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"3_3_5": {"name": "3.3.5 Correlate audit record review, analysis, and reporting processes for investigation and response to indications of unlawful, unauthorized, suspicious, or unusual activity","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_3_5","Section": "3.3 Audit and Accountability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Correlating audit record review, analysis, and reporting processes helps to ensure that they do not operate independently, but rather collectively. Regarding the assessment of a given organizational system, the requirement is agnostic as to whether this correlation is applied at the system level or at the organization level across all systems.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"3_3_8": {"name": "3.3.8 Protect audit information and audit logging tools from unauthorized access, modification, and deletion","checks": {"s3_bucket_public_access": null,"s3_bucket_object_versioning": "FAIL","s3_bucket_default_encryption": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_policy_public_write_access": "PASS","s3_account_level_public_access_blocks": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_3_8","Section": "3.3 Audit and Accountability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Audit information includes all information (e.g., audit records, audit log settings, and audit reports) needed to successfully audit system activity. Audit logging tools are those programs and devices used to conduct audit and logging activities. This requirement focuses on the technical protection of audit information and limits the ability to access and execute audit logging tools to authorized individuals. Physical protection of audit information is addressed by media protection and physical and environmental protection requirements.","checks_status": {"fail": 4,"pass": 2,"total": 8,"manual": 0}},"3_4_1": {"name": "3.4.1 Establish and maintain baseline configurations and inventories of organizational systems (including hardware, software, firmware, and documentation) throughout the respective system development life cycles","checks": {"ec2_elastic_ip_unassigned": "FAIL","elbv2_deletion_protection": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","cloudtrail_multi_region_enabled": "PASS","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_4_1","Section": "3.4 Configuration Management","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Baseline configurations are documented, formally reviewed, and agreed-upon specifications for systems or configuration items within those systems. Baseline configurations serve as a basis for future builds, releases, and changes to systems. Baseline configurations include information about system components (e.g., standard software packages installed on workstations, notebook computers, servers, network components, or mobile devices; current version numbers and update and patch information on operating systems and applications; and configuration settings and parameters), network topology, and the logical placement of those components within the system architecture. Baseline configurations of systems also reflect the current enterprise architecture. Maintaining effective baseline configurations requires creating new baselines as organizational systems change over time. Baseline configuration maintenance includes reviewing and updating the baseline configuration when changes are made based on security risks and deviations from the established baseline configuration Organizations can implement centralized system component inventories that include components from multiple organizational systems. In such situations, organizations ensure that the resulting inventories include system-specific information required for proper component accountability (e.g., system association, system owner). Information deemed necessary for effective accountability of system components includes hardware inventory specifications, software license information, software version numbers, component owners, and for networked components or devices, machine names and network addresses. Inventory specifications include manufacturer, device type, model, serial number, and physical location.","checks_status": {"fail": 6,"pass": 1,"total": 7,"manual": 0}},"3_4_2": {"name": "3.4.2 Establish and enforce security configuration settings for information technology products employed in organizational systems","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_4_2","Section": "3.4 Configuration Management","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Configuration settings are the set of parameters that can be changed in hardware, software, or firmware components of the system that affect the security posture or functionality of the system. Information technology products for which security-related configuration settings can be defined include mainframe computers, servers, workstations, input and output devices (e.g., scanners, copiers, and printers), network components (e.g., firewalls, routers, gateways, voice and data switches, wireless access points, network appliances, sensors), operating systems, middleware, and applications. Security parameters are those parameters impacting the security state of systems including the parameters required to satisfy other security requirements. Security parameters include: registry settings; account, file, directory permission settings; and settings for functions, ports, protocols, and remote connections. Organizations establish organization-wide configuration settings and subsequently derive specific configuration settings for systems. The established settings become part of the systems configuration baseline. Common secure configurations (also referred to as security configuration checklists, lockdown and hardening guides, security reference guides, security technical implementation guides) provide recognized, standardized, and established benchmarks that stipulate secure configuration settings for specific information technology platforms/products and instructions for configuring those system components to meet operational requirements. Common secure configurations can be developed by a variety of organizations including information technology product developers, manufacturers, vendors, consortia, academia, industry, federal agencies, and other organizations in the public and private sectors.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"3_4_6": {"name": "3.4.6 Employ the principle of least functionality by configuring organizational systems to provide only essential capabilities","checks": {"iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"ec2_instance_managed_by_ssm": "FAIL","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"redshift_cluster_public_access": null,"ssm_managed_compliant_patching": "FAIL","s3_bucket_policy_public_write_access": "PASS","s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_4_6","Section": "3.4 Configuration Management","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Systems can provide a wide variety of functions and services. Some of the functions and services routinely provided by default, may not be necessary to support essential organizational missions, functions, or operations. It is sometimes convenient to provide multiple services from single system components. However, doing so increases risk over limiting the services provided by any one component. Where feasible, organizations limit component functionality to a single function per component. Organizations review functions and services provided by systems or components of systems, to determine which functions and services are candidates for elimination. Organizations disable unused or unnecessary physical and logical ports and protocols to prevent unauthorized connection of devices, transfer of information, and tunneling. Organizations can utilize network scanning tools, intrusion detection and prevention systems, and end-point protections such as firewalls and host-based intrusion detection systems to identify and prevent the use of prohibited functions, ports, protocols, and services.","checks_status": {"fail": 3,"pass": 3,"total": 15,"manual": 0}},"3_4_7": {"name": "3.4.7 Restrict, disable, or prevent the use of nonessential programs, functions, ports, protocols, and services","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_4_7","Section": "3.4 Configuration Management","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Restricting the use of nonessential software (programs) includes restricting the roles allowed to approve program execution; prohibiting auto-execute; program blacklisting and whitelisting; or restricting the number of program instances executed at the same time. The organization makes a security-based determination which functions, ports, protocols, and/or services are restricted. Bluetooth, File Transfer Protocol (FTP), and peer-to-peer networking are examples of protocols organizations consider preventing the use of, restricting, or disabling.","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"3_4_9": {"name": "3.4.9 Control and monitor user-installed software","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_4_9","Section": "3.4 Configuration Management","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Users can install software in organizational systems if provided the necessary privileges. To maintain control over the software installed, organizations identify permitted and prohibited actions regarding software installation through policies. Permitted software installations include updates and security patches to existing software and applications from organization-approved 'app stores.' Prohibited software installations may include software with unknown or suspect pedigrees or software that organizations consider potentially malicious. The policies organizations select governing user-installed software may be organization-developed or provided by some external entity. Policy enforcement methods include procedural methods, automated methods, or both.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"3_5_2": {"name": "3.5.2 Authenticate (or verify) the identities of users, processes, or devices, as a prerequisite to allowing access to organizational systems","checks": {"iam_root_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_5_2","Section": "3.5 Identification and Authentication","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Individual authenticators include the following: passwords, key cards, cryptographic devices, and one-time password devices. Initial authenticator content is the actual content of the authenticator, for example, the initial password. In contrast, the requirements about authenticator content include the minimum password length. Developers ship system components with factory default authentication credentials to allow for initial installation and configuration. Default authentication credentials are often well known, easily discoverable, and present a significant security risk. Systems support authenticator management by organization-defined settings and restrictions for various authenticator characteristics including minimum password length, validation time window for time synchronous one-time tokens, and number of allowed rejections during the verification stage of biometric authentication. Authenticator management includes issuing and revoking, when no longer needed, authenticators for temporary access such as that required for remote maintenance. Device authenticators include certificates and passwords.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"3_5_3": {"name": "3.5.3 Use multifactor authentication for local and network access to privileged accounts and for network access to non-privileged accounts","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_5_3","Section": "3.5 Identification and Authentication","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Multifactor authentication requires the use of two or more different factors to authenticate. The factors are defined as something you know (e.g., password, personal identification number [PIN]); something you have (e.g., cryptographic identification device, token); or something you are (e.g., biometric). Multifactor authentication solutions that feature physical authenticators include hardware authenticators providing time-based or challenge-response authenticators and smart cards. In addition to authenticating users at the system level (i.e., at logon), organizations may also employ authentication mechanisms at the application level, when necessary, to provide increased information security. Access to organizational systems is defined as local access or network access. Local access is any access to organizational systems by users (or processes acting on behalf of users) where such access is obtained by direct connections without the use of networks. Network access is access to systems by users (or processes acting on behalf of users) where such access is obtained through network connections (i.e., nonlocal accesses). Remote access is a type of network access that involves communication through external networks. The use of encrypted virtual private networks for connections between organization-controlled and non-organization controlled endpoints may be treated as internal networks with regard to protecting the confidentiality of information.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"3_5_5": {"name": "3.5.5 Prevent reuse of identifiers for a defined period","checks": {"iam_password_policy_reuse_24": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_5_5","Section": "3.5 Identification and Authentication","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Identifiers are provided for users, processes acting on behalf of users, or devices (3.5.1). Preventing reuse of identifiers implies preventing the assignment of previously used individual, group, role, or device identifiers to different individuals, groups, roles, or devices.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"3_5_6": {"name": "3.5.6 Disable identifiers after a defined period of inactivity","checks": {"iam_user_accesskey_unused": null,"iam_password_policy_reuse_24": null,"iam_user_console_access_unused": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_5_6","Section": "3.5 Identification and Authentication","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Inactive identifiers pose a risk to organizational information because attackers may exploit an inactive identifier to gain undetected access to organizational devices. The owners of the inactive accounts may not notice if unauthorized access to the account has been obtained.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"3_5_7": {"name": "3.5.7 Enforce a minimum password complexity and change of characters when new passwords are created","checks": {"iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_5_7","Section": "3.5 Identification and Authentication","Service": "aws","SubGroup": null,"SubSection": null}],"description": "This requirement applies to single-factor authentication of individuals using passwords as individual or group authenticators, and in a similar manner, when passwords are used as part of multifactor authenticators. The number of changed characters refers to the number of changes required with respect to the total number of positions in the current password. To mitigate certain brute force attacks against passwords, organizations may also consider salting passwords.","checks_status": {"fail": 0,"pass": 0,"total": 9,"manual": 0}},"3_5_8": {"name": "3.5.8 Prohibit password reuse for a specified number of generations","checks": {"iam_user_accesskey_unused": null,"iam_password_policy_reuse_24": null,"iam_user_console_access_unused": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_5_8","Section": "3.5 Identification and Authentication","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Password lifetime restrictions do not apply to temporary passwords.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"3_6_1": {"name": "3.6.1 Establish an operational incident-handling capability for organizational systems that includes preparation, detection, analysis, containment, recovery, and user response activities","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_6_1","Section": "3.6 Incident Response","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Organizations recognize that incident handling capability is dependent on the capabilities of organizational systems and the mission/business processes being supported by those systems. Organizations consider incident handling as part of the definition, design, and development of mission/business processes and systems. Incident-related information can be obtained from a variety of sources including audit monitoring, network monitoring, physical access monitoring, user and administrator reports, and reported supply chain events. Effective incident handling capability includes coordination among many organizational entities including mission/business owners, system owners, authorizing officials, human resources offices, physical and personnel security offices, legal departments, operations personnel, procurement offices, and the risk executive. As part of user response activities, incident response training is provided by organizations and is linked directly to the assigned roles and responsibilities of organizational personnel to ensure that the appropriate content and level of detail is included in such training. For example, regular users may only need to know who to call or how to recognize an incident on the system; system administrators may require additional training on how to handle or remediate incidents; and incident responders may receive more specific training on forensics, reporting, system recovery, and restoration. Incident response training includes user training in the identification/reporting of suspicious activities from external and internal sources. User response activities also includes incident response assistance which may consist of help desk support, assistance groups, and access to forensics services or consumer redress services, when required.","checks_status": {"fail": 6,"pass": 4,"total": 14,"manual": 0}},"3_6_2": {"name": "3.6.2 Track, document, and report incidents to designated officials and/or authorities both internal and external to the organization","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_6_2","Section": "3.6 Incident Response","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Tracking and documenting system security incidents includes maintaining records about each incident, the status of the incident, and other pertinent information necessary for forensics, evaluating incident details, trends, and handling. Incident information can be obtained from a variety of sources including incident reports, incident response teams, audit monitoring, network monitoring, physical access monitoring, and user/administrator reports. Reporting incidents addresses specific incident reporting requirements within an organization and the formal incident reporting requirements for the organization. Suspected security incidents may also be reported and include the receipt of suspicious email communications that can potentially contain malicious code. The types of security incidents reported, the content and timeliness of the reports, and the designated reporting authorities reflect applicable laws, Executive Orders, directives, regulations, and policies.","checks_status": {"fail": 6,"pass": 4,"total": 14,"manual": 0}},"3_11_2": {"name": "3.11.2 Scan for vulnerabilities in organizational systems and applications periodically and when new vulnerabilities affecting those systems and applications are identified","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_11_2","Section": "3.11 Risk Assessment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Organizations determine the required vulnerability scanning for all system components, ensuring that potential sources of vulnerabilities such as networked printers, scanners, and copiers are not overlooked. The vulnerabilities to be scanned are readily updated as new vulnerabilities are discovered, announced, and scanning methods developed. This process ensures that potential vulnerabilities in the system are identified and addressed as quickly as possible. Vulnerability analyses for custom software applications may require additional approaches such as static analysis, dynamic analysis, binary analysis, or a hybrid of the three approaches. Organizations can employ these analysis approaches in source code reviews and in a variety of tools (e.g., static analysis tools, web-based application scanners, binary analyzers) and in source code reviews. Vulnerability scanning includes: scanning for patch levels; scanning for functions, ports, protocols, and services that should not be accessible to users or devices; and scanning for improperly configured or incorrectly operating information flow control mechanisms. To facilitate interoperability, organizations consider using products that are Security Content Automated Protocol (SCAP)-validated, scanning tools that express vulnerabilities in the Common Vulnerabilities and Exposures (CVE) naming convention, and that employ the Open Vulnerability Assessment Language (OVAL) to determine the presence of system vulnerabilities. Sources for vulnerability information include the Common Weakness Enumeration (CWE) listing and the National Vulnerability Database (NVD). Security assessments, such as red team exercises, provide additional sources of potential vulnerabilities for which to scan. Organizations also consider using scanning tools that express vulnerability impact by the Common Vulnerability Scoring System (CVSS). In certain situations, the nature of the vulnerability scanning may be more intrusive or the system component that is the subject of the scanning may contain highly sensitive information. Privileged access authorization to selected system components facilitates thorough vulnerability scanning and protects the sensitive nature of such scanning.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"3_11_3": {"name": "3.11.3 Remediate vulnerabilities in accordance with risk assessments","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_11_3","Section": "3.11 Risk Assessment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Vulnerabilities discovered, for example, via the scanning conducted in response to 3.11.2, are remediated with consideration of the related assessment of risk. The consideration of risk influences the prioritization of remediation efforts and the level of effort to be expended in the remediation for specific vulnerabilities.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"3_12_4": {"name": "3.12.4 Develop, document, and periodically update system security plans that describe system boundaries, system environments of operation, how security requirements are implemented, and the relationships with or connections to other systems","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_12_4","Section": "3.12 Assessment, Authorization, and Monitoring","Service": "aws","SubGroup": null,"SubSection": null}],"description": "System security plans relate security requirements to a set of security controls. System security plans also describe, at a high level, how the security controls meet those security requirements, but do not provide detailed, technical descriptions of the design or implementation of the controls. System security plans contain sufficient information to enable a design and implementation that is unambiguously compliant with the intent of the plans and subsequent determinations of risk if the plan is implemented as intended. Security plans need not be single documents; the plans can be a collection of various documents including documents that already exist. Effective security plans make extensive use of references to policies, procedures, and additional documents (e.g., design and implementation specifications) where more detailed information can be obtained. This reduces the documentation requirements associated with security programs and maintains security-related information in other established management/operational areas related to enterprise architecture, system development life cycle, systems engineering, and acquisition. Federal agencies may consider the submitted system security plans and plans of action as critical inputs to an overall risk management decision to process, store, or transmit CUI on a system hosted by a nonfederal organization and whether it is advisable to pursue an agreement or contract with the nonfederal organization.","checks_status": {"fail": 2,"pass": 3,"total": 9,"manual": 0}},"3_13_1": {"name": "3.13.1 Monitor, control, and protect communications (i.e., information transmitted or received by organizational systems) at the external boundaries and key internal boundaries of organizational systems","checks": {"elb_ssl_listeners": "FAIL","elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","elbv2_waf_acl_attached": "FAIL","rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"cloudtrail_multi_region_enabled": "PASS","acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_logging_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_13_1","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Communications can be monitored, controlled, and protected at boundary components and by restricting or prohibiting interfaces in organizational systems. Boundary components include gateways, routers, firewalls, guards, network-based malicious code analysis and virtualization systems, or encrypted tunnels implemented within a system security architecture (e.g., routers protecting firewalls or application gateways residing on protected subnetworks). Restricting or prohibiting interfaces in organizational systems includes restricting external web communications traffic to designated web servers within managed interfaces and prohibiting external traffic that appears to be spoofing internal addresses. Organizations consider the shared nature of commercial telecommunications services in the implementation of security requirements associated with the use of such services. Commercial telecommunications services are commonly based on network components and consolidated management systems shared by all attached commercial customers and may also include third party-provided access lines and other service elements. Such transmission services may represent sources of increased risk despite contract security provisions.","checks_status": {"fail": 10,"pass": 8,"total": 23,"manual": 0}},"3_13_2": {"name": "3.13.2 Employ architectural designs, software development techniques, and systems engineering principles that promote effective information security within organizational systems","checks": {"rds_instance_multi_az": "FAIL","ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","efs_have_backup_enabled": "FAIL","s3_bucket_public_access": null,"elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","dynamodb_tables_pitr_enabled": null,"awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"cloudtrail_multi_region_enabled": "PASS","acm_certificates_expiration_check": "PASS","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"rds_instance_integration_cloudwatch_logs": "FAIL","awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_13_2","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Organizations apply systems security engineering principles to new development systems or systems undergoing major upgrades. For legacy systems, organizations apply systems security engineering principles to system upgrades and modifications to the extent feasible, given the current state of hardware, software, and firmware components within those systems. The application of systems security engineering concepts and principles helps to develop trustworthy, secure, and resilient systems and system components and reduce the susceptibility of organizations to disruptions, hazards, and threats. Examples of these concepts and principles include developing layered protections; establishing security policies, architecture, and controls as the foundation for design; incorporating security requirements into the system development life cycle; delineating physical and logical security boundaries; ensuring that developers are trained on how to build secure software; and performing threat modeling to identify use cases, threat agents, attack vectors and patterns, design patterns, and compensating controls needed to mitigate risk. Organizations that apply security engineering concepts and principles can facilitate the development of trustworthy, secure systems, system components, and system services; reduce risk to acceptable levels; and make informed risk-management decisions.","checks_status": {"fail": 7,"pass": 8,"total": 23,"manual": 0}},"3_13_3": {"name": "3.13.3 Separate user functionality from system management functionality","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_13_3","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "System management functionality includes functions necessary to administer databases, network components, workstations, or servers, and typically requires privileged user access. The separation of user functionality from system management functionality is physical or logical. Organizations can implement separation of system management functionality from user functionality by using different computers, different central processing units, different instances of operating systems, or different network addresses; virtualization techniques; or combinations of these or other methods, as appropriate. This type of separation includes web administrative interfaces that use separate authentication methods for users of any other system resources. Separation of system and user functionality may include isolating administrative interfaces on different domains and with additional access controls.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"3_13_4": {"name": "3.13.4 Prevent unauthorized and unintended information transfer via shared system resources","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_13_4","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The control of information in shared system resources (e.g., registers, cache memory, main memory, hard disks) is also commonly referred to as object reuse and residual information protection. This requirement prevents information produced by the actions of prior users or roles (or the actions of processes acting on behalf of prior users or roles) from being available to any current users or roles (or current processes acting on behalf of current users or roles) that obtain access to shared system resources after those resources have been released back to the system. This requirement also applies to encrypted representations of information. This requirement does not address information remanence, which refers to residual representation of data that has been nominally deleted; covert channels (including storage or timing channels) where shared resources are manipulated to violate information flow restrictions; or components within systems for which there are only single users or roles.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3_13_5": {"name": "3.13.5 Implement subnetworks for publicly accessible system components that are physically or logically separated from internal networks","checks": {"elb_ssl_listeners": "FAIL","ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_13_5","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Subnetworks that are physically or logically separated from internal networks are referred to as demilitarized zones (DMZs). DMZs are typically implemented with boundary control devices and techniques that include routers, gateways, firewalls, virtualization, or cloud-based technologies.","checks_status": {"fail": 6,"pass": 6,"total": 20,"manual": 0}},"3_13_6": {"name": "3.13.6 Deny network communications traffic by default and allow network communications traffic by exception (i.e., deny all, permit by exception)","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_13_6","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "This requirement applies to inbound and outbound network communications traffic at the system boundary and at identified points within the system. A deny-all, permit-by-exception network communications traffic policy ensures that only those connections which are essential and approved are allowed.","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"3_13_8": {"name": "3.13.8 Implement cryptographic mechanisms to prevent unauthorized disclosure of CUI during transmission unless otherwise protected by alternative physical safeguards","checks": {"elb_ssl_listeners": "FAIL","acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_13_8","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "This requirement applies to internal and external networks and any system components that can transmit information including servers, notebook computers, desktop computers, mobile devices, printers, copiers, scanners, and facsimile machines. Communication paths outside the physical protection of controlled boundaries are susceptible to both interception and modification. Organizations relying on commercial providers offering transmission services as commodity services rather than as fully dedicated services (i.e., services which can be highly specialized to individual customer needs), may find it difficult to obtain the necessary assurances regarding the implementation of the controls for transmission confidentiality. In such situations, organizations determine what types of confidentiality services are available in commercial telecommunication service packages. If it is infeasible or impractical to obtain the necessary safeguards and assurances of the effectiveness of the safeguards through appropriate contracting vehicles, organizations implement compensating safeguards or explicitly accept the additional risk. An example of an alternative physical safeguard is a protected distribution system (PDS) where the distribution medium is protected against electronic or physical intercept, thereby ensuring the confidentiality of the information being transmitted.","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"3_14_1": {"name": "3.14.1 Identify, report, and correct system flaws in a timely manner","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_14_1","Section": "3.14 System and Information integrity","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Organizations identify systems that are affected by announced software and firmware flaws including potential vulnerabilities resulting from those flaws and report this information to designated personnel with information security responsibilities. Security-relevant updates include patches, service packs, hot fixes, and anti-virus signatures. Organizations address flaws discovered during security assessments, continuous monitoring, incident response activities, and system error handling. Organizations can take advantage of available resources such as the Common Weakness Enumeration (CWE) database or Common Vulnerabilities and Exposures (CVE) database in remediating flaws discovered in organizational systems. Organization-defined time periods for updating security-relevant software and firmware may vary based on a variety of factors including the criticality of the update (i.e., severity of the vulnerability related to the discovered flaw). Some types of flaw remediation may require more testing than other types of remediation.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"3_14_2": {"name": "3.14.2 Provide protection from malicious code at designated locations within organizational systems","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_14_2","Section": "3.14 System and Information integrity","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Designated locations include system entry and exit points which may include firewalls, remoteaccess servers, workstations, electronic mail servers, web servers, proxy servers, notebook computers, and mobile devices. Malicious code includes viruses, worms, Trojan horses, and spyware. Malicious code can be encoded in various formats (e.g., UUENCODE, Unicode), contained within compressed or hidden files, or hidden in files using techniques such as steganography. Malicious code can be inserted into systems in a variety of ways including web accesses, electronic mail, electronic mail attachments, and portable storage devices. Malicious code insertions occur through the exploitation of system vulnerabilities. Malicious code protection mechanisms include anti-virus signature definitions and reputationbased technologies. A variety of technologies and methods exist to limit or eliminate the effects of malicious code. Pervasive configuration management and comprehensive software integrity controls may be effective in preventing execution of unauthorized code. In addition to commercial off-the-shelf software, malicious code may also be present in custom-built software. This could include logic bombs, back doors, and other types of cyber-attacks that could affect organizational missions/business functions. Traditional malicious code protection mechanisms cannot always detect such code. In these situations, organizations rely instead on other safeguards including secure coding practices, configuration management and control, trusted procurement processes, and monitoring practices to help ensure that software does not perform functions other than the functions intended.","checks_status": {"fail": 2,"pass": 2,"total": 5,"manual": 0}},"3_14_3": {"name": "3.14.3 Monitor system security alerts and advisories and take action in response","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_14_3","Section": "3.14 System and Information integrity","Service": "aws","SubGroup": null,"SubSection": null}],"description": "There are many publicly available sources of system security alerts and advisories. For example, the Department of Homeland Security’s Cybersecurity and Infrastructure Security Agency (CISA) generates security alerts and advisories to maintain situational awareness across the federal government and in nonfederal organizations. Software vendors, subscription services, and industry information sharing and analysis centers (ISACs) may also provide security alerts and advisories. Examples of response actions include notifying relevant external organizations, for example, external mission/business partners, supply chain partners, external service providers, and peer or supporting organizations.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"3_14_4": {"name": "3.14.4 Update malicious code protection mechanisms when new releases are available","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "3_14_4","Section": "3.14 System and Information integrity","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Malicious code protection mechanisms include anti-virus signature definitions and reputationbased technologies. A variety of technologies and methods exist to limit or eliminate the effects of malicious code. Pervasive configuration management and comprehensive software integrity controls may be effective in preventing execution of unauthorized code. In addition to commercial off-the-shelf software, malicious code may also be present in custom-built software. This could include logic bombs, back doors, and other types of cyber-attacks that could affect organizational missions/business functions. Traditional malicious code protection mechanisms cannot always detect such code. In these situations, organizations rely instead on other safeguards including secure coding practices, configuration management and control, trusted procurement processes, and monitoring practices to help ensure that software does not perform functions other than the functions intended.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3_14_6": {"name": "3.14.6 Monitor organizational systems, including inbound and outbound communications traffic, to detect attacks and indicators of potential attacks","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_14_6","Section": "3.14 System and Information integrity","Service": "aws","SubGroup": null,"SubSection": null}],"description": "System monitoring includes external and internal monitoring. External monitoring includes the observation of events occurring at the system boundary (i.e., part of perimeter defense and boundary protection). Internal monitoring includes the observation of events occurring within the system. Organizations can monitor systems, for example, by observing audit record activities in real time or by observing other system aspects such as access patterns, characteristics of access, and other actions. The monitoring objectives may guide determination of the events. System monitoring capability is achieved through a variety of tools and techniques (e.g., intrusion detection systems, intrusion prevention systems, malicious code protection software, scanning tools, audit record monitoring software, network monitoring software). Strategic locations for monitoring devices include selected perimeter locations and near server farms supporting critical applications, with such devices being employed at managed system interfaces. The granularity of monitoring information collected is based on organizational monitoring objectives and the capability of systems to support such objectives. System monitoring is an integral part of continuous monitoring and incident response programs. Output from system monitoring serves as input to continuous monitoring and incident response programs. A network connection is any connection with a device that communicates through a network (e.g., local area network, Internet). A remote connection is any connection with a device communicating through an external network (e.g., the Internet). Local, network, and remote connections can be either wired or wireless. Unusual or unauthorized activities or conditions related to inbound/outbound communications traffic include internal traffic that indicates the presence of malicious code in systems or propagating among system components, the unauthorized exporting of information, or signaling to external systems. Evidence of malicious code is used to identify potentially compromised systems or system components. System monitoring requirements, including the need for specific types of system monitoring, may be referenced in other requirements.","checks_status": {"fail": 5,"pass": 4,"total": 12,"manual": 0}},"3_14_7": {"name": "3.14.7 Identify unauthorized use of organizational systems","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_14_7","Section": "3.14 System and Information integrity","Service": "aws","SubGroup": null,"SubSection": null}],"description": "System monitoring includes external and internal monitoring. System monitoring can detect unauthorized use of organizational systems. System monitoring is an integral part of continuous monitoring and incident response programs. Monitoring is achieved through a variety of tools and techniques (e.g., intrusion detection systems, intrusion prevention systems, malicious code protection software, scanning tools, audit record monitoring software, network monitoring software). Output from system monitoring serves as input to continuous monitoring and incident response programs. Unusual/unauthorized activities or conditions related to inbound and outbound communications traffic include internal traffic that indicates the presence of malicious code in systems or propagating among system components, the unauthorized exporting of information, or signaling to external systems. Evidence of malicious code is used to identify potentially compromised systems or system components. System monitoring requirements, including the need for specific types of system monitoring, may be referenced in other requirements.","checks_status": {"fail": 5,"pass": 4,"total": 12,"manual": 0}},"3_1_12": {"name": "3.1.12 Monitor and control remote access sessions","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_1_12","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Remote access is access to organizational systems by users (or processes acting on behalf of users) communicating through external networks (e.g., the Internet). Remote access methods include dial-up, broadband, and wireless. Organizations often employ encrypted virtual private networks (VPNs) to enhance confidentiality over remote connections. The use of encrypted VPNs does not make the access non-remote; however, the use of VPNs, when adequately provisioned with appropriate control (e.g., employing encryption techniques for confidentiality protection), may provide sufficient assurance to the organization that it can effectively treat such connections as internal networks. VPNs with encrypted tunnels can affect the capability to adequately monitor network communications traffic for malicious code. Automated monitoring and control of remote access sessions allows organizations to detect cyberattacks and help to ensure ongoing compliance with remote access policies by auditing connection activities of remote users on a variety of system components (e.g., servers, workstations, notebook computers, smart phones, and tablets).","checks_status": {"fail": 4,"pass": 4,"total": 11,"manual": 0}},"3_1_13": {"name": "3.1.13 Employ cryptographic mechanisms to protect the confidentiality of remote access sessions","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_1_13","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Cryptographic standards include FIPS-validated cryptography and NSA-approved cryptography.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"3_1_14": {"name": "3.1.14 Route remote access via managed access control points","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"iam_user_mfa_enabled_console_access": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_1_14","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Routing remote access through managed access control points enhances explicit, organizational control over such connections, reducing the susceptibility to unauthorized access to organizational systems resulting in the unauthorized disclosure of CUI.","checks_status": {"fail": 3,"pass": 5,"total": 14,"manual": 0}},"3_1_20": {"name": "3.1.20 Verify and control/limit connections to and use of external systems","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_1_20","Section": "3.1 Access Control","Service": "aws","SubGroup": null,"SubSection": null}],"description": "External systems are systems or components of systems for which organizations typically have no direct supervision and authority over the application of security requirements and controls or the determination of the effectiveness of implemented controls on those systems. External systems include personally owned systems, components, or devices and privately-owned computing and communications devices resident in commercial or public facilities. This requirement also addresses the use of external systems for the processing, storage, or transmission of CUI, including accessing cloud services (e.g., infrastructure as a service, platform as a service, or software as a service) from organizational systems. Organizations establish terms and conditions for the use of external systems in accordance with organizational security policies and procedures. Terms and conditions address as a minimum, the types of applications that can be accessed on organizational systems from external systems. If terms and conditions with the owners of external systems cannot be established, organizations may impose restrictions on organizational personnel using those external systems. This requirement recognizes that there are circumstances where individuals using external systems (e.g., contractors, coalition partners) need to access organizational systems. In those situations, organizations need confidence that the external systems contain the necessary controls so as not to compromise, damage, or otherwise harm organizational systems. Verification that the required controls have been effectively implemented can be achieved by third-party, independent assessments, attestations, or other means, depending on the assurance or confidence level required by organizations. Note that while ā€œexternalā€ typically refers to outside of the organization's direct supervision and authority, that is not always the case. Regarding the protection of CUI across an organization, the organization may have systems that process CUI and others that do not. And among the systems that process CUI there are likely access restrictions for CUI that apply between systems. Therefore, from the perspective of a given system, other systems within the organization may be considered 'external' to that system.","checks_status": {"fail": 2,"pass": 1,"total": 5,"manual": 0}},"3_5_10": {"name": "3.5.10 Store and transmit only cryptographically-protected passwords","checks": {"ec2_ebs_volume_encryption": "PASS","elbv2_insecure_ssl_ciphers": "PASS","s3_bucket_default_encryption": "PASS","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_5_10","Section": "3.5 Identification and Authentication","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Cryptographically-protected passwords use salted one-way cryptographic hashes of passwords.","checks_status": {"fail": 2,"pass": 3,"total": 6,"manual": 0}},"3_13_11": {"name": "3.13.11 Employ FIPS-validated cryptography when used to protect the confidentiality of CUI","checks": {"ec2_ebs_volume_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","acm_certificates_expiration_check": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_13_11","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Cryptography can be employed to support many security solutions including the protection of controlled unclassified information, the provision of digital signatures, and the enforcement of information separation when authorized individuals have the necessary clearances for such information but lack the necessary formal access approvals. Cryptography can also be used to support random number generation and hash generation. Cryptographic standards include FIPSvalidated cryptography and/or NSA-approved cryptography.","checks_status": {"fail": 6,"pass": 3,"total": 12,"manual": 0}},"3_13_15": {"name": "3.13.15 Protect the authenticity of communications sessions","checks": {"elb_ssl_listeners": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_13_15","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Authenticity protection includes protecting against man-in-the-middle attacks, session hijacking, and the insertion of false information into communications sessions. This requirement addresses communications protection at the session versus packet level (e.g., sessions in service-oriented architectures providing web-based services) and establishes grounds for confidence at both ends of communications sessions in ongoing identities of other parties and in the validity of information transmitted.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3_13_16": {"name": "3.13.16 Protect the confidentiality of CUI at rest","checks": {"ec2_ebs_volume_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "3_13_16","Section": "3.13 System and Communications Protection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Information at rest refers to the state of information when it is not in process or in transit and is located on storage devices as specific components of systems. The focus of protection at rest is not on the type of storage device or the frequency of access but rather the state of the information. Organizations can use different mechanisms to achieve confidentiality protections, including the use of cryptographic mechanisms and file share scanning. Organizations may also use other controls including secure off-line storage in lieu of online storage when adequate protection of information at rest cannot otherwise be achieved or continuous monitoring to identify malicious code at rest.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}}},"requirements_passed": 14,"requirements_failed": 35,"requirements_manual": 1,"total_requirements": 50,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "168b9e98-d0d8-47a8-b53a-32097ec095ac","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "nist_800_53_revision_4_aws","framework": "NIST-800-53-Revision-4","version": "","description": "NIST 800-53 is a regulatory standard that defines the minimum baseline of security controls for all U.S. federal information systems except those related to national security. The controls defined in this standard are customizable and address a diverse set of security and privacy requirements.","region": "eu-west-1","requirements": {"ac_2": {"name": "Account Management (AC-2)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_password_policy_reuse_24": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_2","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Manage system accounts, group memberships, privileges, workflow, notifications, deactivations, and authorizations.","checks_status": {"fail": 3,"pass": 3,"total": 18,"manual": 0}},"ac_3": {"name": "Access Enforcement (AC-3)","checks": {"iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_3","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system enforces approved authorizations for logical access to information and system resources in accordance with applicable access control policies.","checks_status": {"fail": 0,"pass": 3,"total": 14,"manual": 0}},"ac_4": {"name": "Information Flow Enforcement (AC-4)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"acm_certificates_expiration_check": "PASS","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_4","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system enforces approved authorizations for controlling the flow of information within the system and between interconnected systems based on organization-defined information flow control policies.","checks_status": {"fail": 3,"pass": 7,"total": 17,"manual": 0}},"ac_5": {"name": "Separation Of Duties (AC-5)","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_5","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Separate duties of individuals to prevent malevolent activity. automate separation of duties and access authorizations.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"ac_6": {"name": "Least Privilege (AC-6)","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_6","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks in accordance with organizational missions and business functions.","checks_status": {"fail": 1,"pass": 5,"total": 18,"manual": 0}},"au_2": {"name": "Event Logging (AU-2)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_2","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Automate security audit function with other organizational entities. Enable mutual support of audit of auditable events.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_3": {"name": "Content of Audit Records (AU-3)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_3","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system generates audit records containing information that establishes what type of event occurred, when the event occurred, where the event occurred, the source of the event, the outcome of the event, and the identity of any individuals or subjects associated with the event.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_9": {"name": "Protection of Audit Information (AU-9)","checks": {"cloudtrail_kms_encryption_enabled": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_9","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects audit information and audit tools from unauthorized access, modification, and deletion.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"ca_7": {"name": "Continuous Monitoring (CA-7)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ca_7","Section": "Security Assessment And Authorization (CA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Continuously monitor configuration management processes. Determine security impact, environment and operational risks.","checks_status": {"fail": 2,"pass": 3,"total": 9,"manual": 0}},"cm_2": {"name": "Baseline Configuration (CM-2)","checks": {"elbv2_deletion_protection": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","cloudtrail_multi_region_enabled": "PASS","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_2","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization develops, documents, and maintains under configuration control, a current baseline configuration of the information system.","checks_status": {"fail": 5,"pass": 1,"total": 6,"manual": 0}},"cm_7": {"name": "Least Functionality (CM-7)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_7","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization configures the information system to provide only essential capabilities and prohibits or restricts the use of the functions, ports, protocols, and/or services.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cp_9": {"name": "Information System Backup (CP-9)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","dynamodb_tables_pitr_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_9","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization conducts backups of user-level information, system-level information and information system documentation including security-related documentation contained in the information system and protects the confidentiality, integrity, and availability of backup information at storage locations.","checks_status": {"fail": 1,"pass": 1,"total": 4,"manual": 0}},"ia_2": {"name": "Identification and Authentication (Organizational users) (IA-2)","checks": {"iam_password_policy_reuse_24": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2","Section": "Identification and Authentication (IA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ra_5": {"name": "Vulnerability Scanning (RA-5)","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ra_5","Section": "Risk Assessment (RA)","Service": "guardduty","SubGroup": null,"SubSection": null}],"description": "Scan for system vulnerabilities. Share vulnerability information and security controls that eliminate vulnerabilities.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"sa_3": {"name": "System Development Life Cycle (SA-3)","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sa_3","Section": "System and Services Acquisition (SA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization manages the information system using organization-defined system development life cycle, defines and documents information security roles and responsibilities throughout the system development life cycle, identifies individuals having information security roles and responsibilities and integrates the organizational information security risk management process into system development life cycle activities.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sc_2": {"name": "Application Partitioning (SC-2)","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_2","Section": "System and Communications Protection (SC)","Service": "iam","SubGroup": null,"SubSection": null}],"description": "The information system separates user functionality (including user interface services) from information system management functionality.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"sc_4": {"name": "Information In Shared Resources (SC-4)","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_4","Section": "System and Communications Protection (SC)","Service": "ebs","SubGroup": null,"SubSection": null}],"description": "The information system prevents unauthorized and unintended information transfer via shared system resources.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"sc_5": {"name": "Denial Of Service Protection (SC-5)","checks": {"rds_instance_multi_az": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_5","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects against or limits the effects of the following types of denial of service attacks: [Assignment: organization-defined types of denial of service attacks or references to sources for such information] by employing [Assignment: organization-defined security safeguards].","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"sc_7": {"name": "Boundary Protection (SC-7)","checks": {"elb_ssl_listeners": "FAIL","ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system: a. Monitors and controls communications at the external boundary of the system and at key internal boundaries within the system; b. Implements subnetworks for publicly accessible system components that are [Selection: physically; logically] separated from internal organizational networks; and c. Connects to external networks or information systems only through managed interfaces consisting of boundary protection devices arranged in accordance with an organizational security architecture.","checks_status": {"fail": 6,"pass": 6,"total": 20,"manual": 0}},"sc_8": {"name": "Transmission Confidentiality And Integrity (SC-8)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_8","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects the [Selection (one or more): confidentiality; integrity] of transmitted information.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"si_4": {"name": "Information System Monitoring (SI-4)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_waf_acl_attached": "FAIL","ec2_instance_imdsv2_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_4","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization: a.Monitors the information system to detect: 1. Attacks and indicators of potential attacks in accordance with [Assignment: organization-defined monitoring objectives]; and 2.Unauthorized local, network, and remote connections; b. Identifies unauthorized use of the information system through [Assignment: organization-defined techniques and methods]; c. Deploys monitoring devices: 1. Strategically within the information system to collect organization-determined essential information; and 2. At ad hoc locations within the system to track specific types of transactions of interest to the organization; d. Protects information obtained from intrusion-monitoring tools from unauthorized access, modification, and deletion; e. Heightens the level of information system monitoring activity whenever there is an indication of increased risk to organizational operations and assets, individuals, other organizations, or the Nation based on law enforcement information, intelligence information, or other credible sources of information; f. Obtains legal opinion with regard to information system monitoring activities in accordance with applicable federal laws, Executive Orders, directives, policies, or regulations; and g. Provides [Assignment: organization-defined information system monitoring information] to [Assignment: organization-defined personnel or roles] [Selection (one or more): as needed; [Assignment: organization-defined frequency]].","checks_status": {"fail": 3,"pass": 3,"total": 10,"manual": 0}},"si_7": {"name": "Software, Firmware, and Information Integrity (SI-7)","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_7","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization employs integrity verification tools to detect unauthorized changes to [Assignment: organization-defined software, firmware, and information].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ac_21": {"name": "Information Sharing (AC-21)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_21","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Facilitate information sharing. Enable authorized users to grant access to partners.","checks_status": {"fail": 1,"pass": 4,"total": 11,"manual": 0}},"au_11": {"name": "Audit Record Retention (AU-11)","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_11","Section": "Audit and Accountability (AU)","Service": "cloudwatch","SubGroup": null,"SubSection": null}],"description": "The organization retains audit records for [Assignment: organization-defined time period consistent with records retention policy] to provide support for after-the-fact investigations of security incidents and to meet regulatory and organizational information retention requirements.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"au_12": {"name": "Audit Generation (AU-12)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_12","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Audit events defined in AU-2. Allow trusted personnel to select which events to audit. Generate audit records for events.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"cp_10": {"name": "Information System Recovery And Reconstitution (CP-10)","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_10","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization provides for the recovery and reconstitution of the information system to a known state after a disruption, compromise, or failure.","checks_status": {"fail": 4,"pass": 1,"total": 7,"manual": 0}},"sa_10": {"name": "Developer Configuration Management (SA-10)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sa_10","Section": "System and Services Acquisition (SA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization requires the developer of the information system, system component, or information system service to: a. Perform configuration management during system, component, or service [Selection (one or more): design; development; implementation; operation]; b. Document, manage, and control the integrity of changes to [Assignment: organization-defined configuration items under configuration management]; c. Implement only organization-approved changes to the system, component, or service; d. Document approved changes to the system, component, or service and the potential security impacts of such changes; and e. Track security flaws and flaw resolution within the system, component, or service and report findings to [Assignment: organization-defined personnel].","checks_status": {"fail": 2,"pass": 2,"total": 4,"manual": 0}},"sc_12": {"name": "Cryptographic Key Establishment And Management (SC-12)","checks": {"kms_cmk_rotation_enabled": null,"acm_certificates_expiration_check": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_12","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization establishes and manages cryptographic keys for required cryptography employed within the information system in accordance with [Assignment: organization-defined requirements for key generation, distribution, storage, access, and destruction].","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"sc_13": {"name": "Cryptographic Protection (SC-13)","checks": {"dynamodb_tables_kms_cmk_encryption_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_13","Section": "System and Communications Protection (SC)","Service": "dynamodb","SubGroup": null,"SubSection": null}],"description": "The information system implements [Assignment: organization-defined cryptographic uses and type of cryptography required for each use] in accordance with applicable federal laws, Executive Orders, directives, policies, regulations, and standards.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"sc_23": {"name": "Session Authenticity (SC-23)","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_23","Section": "System and Communications Protection (SC)","Service": "elb","SubGroup": null,"SubSection": null}],"description": "The information system protects the authenticity of communications sessions.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"sc_28": {"name": "Protection Of Information At Rest (SC-28)","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_28","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects the [Selection (one or more): confidentiality; integrity] of [Assignment: organization-defined information at rest].","checks_status": {"fail": 5,"pass": 3,"total": 12,"manual": 0}},"si_12": {"name": "Information Handling and Retention (SI-12)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_12","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization handles and retains information within the information system and information output from the system in accordance with applicable federal laws, Executive Orders, directives, policies, regulations, standards, and operational requirements.","checks_status": {"fail": 3,"pass": 1,"total": 6,"manual": 0}},"ac_2_1": {"name": "AC-2(1) Automated System Account Management","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_user_accesskey_unused": null,"iam_password_policy_reuse_24": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_1","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "Access control policies (e.g., identity or role-based policies, control matrices, and cryptography) control access between active entities or subjects (i.e., users or processes acting on behalf of users) and passive entities or objects (e.g., devices, files, records, and domains) in systems. Access enforcement mechanisms can be employed at the application and service level to provide increased information security. Other systems include systems internal and external to the organization. This requirement focuses on account management for systems and applications. The definition of and enforcement of access authorizations, other than those determined by account type (e.g., privileged verses non-privileged) are addressed in requirement 3.1.2.","checks_status": {"fail": 0,"pass": 2,"total": 6,"manual": 0}},"ac_2_3": {"name": "AC-2(3) Disable Inactive Accounts","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_3","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The information system automatically disables inactive accounts after 90 days for user accounts.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"ac_2_4": {"name": "AC-2(4) Automated Audit Actions","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_2_4","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The information system automatically audits account creation, modification, enabling, disabling, and removal actions, and notifies [Assignment: organization-defined personnel or roles].","checks_status": {"fail": 2,"pass": 3,"total": 11,"manual": 0}},"au_6_1": {"name": "AU-6(1) Process Integration","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_6_1","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Review, Analysis And Reporting (AU-6)"}],"description": "The organization employs automated mechanisms to integrate audit review, analysis,and reporting processes to support organizational processes for investigation and response to suspicious activities.","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"au_6_3": {"name": "AU-6(3) Correlate Audit Repositories","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_6_3","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Review, Analysis And Reporting (AU-6)"}],"description": "The organization analyzes and correlates audit records across different repositories to gain organization-wide situational awareness.","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"au_7_1": {"name": "AU-7(1) Automatic Processing","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_7_1","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system provides the capability to process audit records for events of interest based on [Assignment: organization-defined audit fields within audit records].","checks_status": {"fail": 1,"pass": 0,"total": 5,"manual": 0}},"au_9_2": {"name": "AU-9(2) Audit Backup On Separate Physical Systems / Components","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "au_9_2","Section": "Audit and Accountability (AU)","Service": "s3","SubGroup": null,"SubSection": "Protection of Audit Information (AU-9)"}],"description": "The information system backs up audit records [Assignment: organization-defined frequency] onto a physically different system or system component than the system or component being audited.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cm_8_1": {"name": "CM-8(1) Updates During Installation / Removals","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_1","Section": "Configuration Management (CM)","Service": "ec2","SubGroup": null,"SubSection": "Information System Component Inventory (CM-8)"}],"description": "The organization develops and documents an inventory of information system components that accurately reflects the current information system, includes all components within the authorization boundary of the information system, is at the level of granularity deemed necessary for tracking and reporting and reviews and updates the information system component inventory.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cm_8_3": {"name": "CM-8(3) Automated Unauthorized Component Detection","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_3","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Information System Component Inventory (CM-8)"}],"description": "The organization employs automated mechanisms to detect the presence of unauthorized hardware, software, and firmware components within the information system and takes actions (disables network access by such components, isolates the components etc) when unauthorized components are detected.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"ia_2_1": {"name": "IA-2(1) Network Access To Privileged Accounts","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2_1","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "The information system implements multi-factor authentication for network access to privileged accounts.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ia_2_2": {"name": "IA-2(2) Network Access To Non-Privileged Accounts","checks": {"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2_2","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "The information system implements multifactor authentication for network access to non-privileged accounts.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"ia_5_1": {"name": "IA-5(1) Password-Based Authentication","checks": {"iam_password_policy_reuse_24": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_1","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "The information system, for password-based authentication that enforces minimum password complexity, stores and transmits only cryptographically-protected passwords, enforces password minimum and maximum lifetime restrictions, prohibits password reuse, allows the use of a temporary password for system logons with an immediate change to a permanent password etc.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_4": {"name": "IA-5(4) Automated Support For Password Strength Determination","checks": {"iam_password_policy_reuse_24": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_4","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "The organization employs automated tools to determine if password authenticators are sufficiently strong to satisfy [Assignment: organization-defined requirements].","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_7": {"name": "IA-5(7) No Embedded Unencrypted Static Authenticators","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_7","Section": "Identification and Authentication (IA)","Service": "codebuild","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "The organization ensures that unencrypted static authenticators are not embedded in applications or access scripts or stored on function keys.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ir_4_1": {"name": "IR-4(1) Automated Incident Handling Processes","checks": {"guardduty_no_high_severity_findings": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ir_4_1","Section": "Incident Response (IR)","Service": "aws","SubGroup": null,"SubSection": "Incident Handling (IR-4)"}],"description": "The organization employs automated mechanisms to support the incident handling process.","checks_status": {"fail": 1,"pass": 0,"total": 5,"manual": 0}},"ir_6_1": {"name": "IR-6(1) Automated Reporting","checks": {"guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ir_6_1","Section": "Incident Response (IR)","Service": "guardduty","SubGroup": null,"SubSection": "Incident Reporting (IR-6)"}],"description": "The organization employs automated mechanisms to assist in the reporting of security incidents.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ir_7_1": {"name": "IR-7(1) Automation Support For Availability Of Information / Support","checks": {"guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ir_7_1","Section": "Incident Response (IR)","Service": "guardduty","SubGroup": null,"SubSection": "Incident Response Assistance (IR-7)"}],"description": "The organization employs automated mechanisms to increase the availability of incident response-related information and support.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sc_7_3": {"name": "SC-7(3) Access Points","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_3","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "The organization limits the number of external network connections to the information system.","checks_status": {"fail": 3,"pass": 6,"total": 16,"manual": 0}},"sc_8_1": {"name": "SC-8(1) Cryptographic Or Alternate Physical Protection","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_8_1","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Transmission Confidentiality And Integrity (SC-8)"}],"description": "The information system implements cryptographic mechanisms to [Selection (one or more): prevent unauthorized disclosure of information; detect changes to information] during transmission unless otherwise protected by [Assignment: organization-defined alternative physical safeguards].","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"si_2_2": {"name": "SI-2(2) Automates Flaw Remediation Status","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_2_2","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Flaw Remediation (SI-2)"}],"description": "The organization employs automated mechanisms to determine the state of information system components with regard to flaw remediation.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"si_4_1": {"name": "SI-4(1) System-Wide Intrusion Detection System","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_1","Section": "System and Information Integrity (SI)","Service": "guardduty","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The organization connects and configures individual intrusion detection tools into an information system-wide intrusion detection system.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_2": {"name": "SI-4(2) Automated Tools For Real-Time Analysis","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_4_2","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The organization employs automated tools to support near real-time analysis of events.","checks_status": {"fail": 1,"pass": 3,"total": 8,"manual": 0}},"si_4_4": {"name": "SI-4(4) Inbound and Outbound Communications Traffic","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_4_4","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The information system monitors inbound and outbound communications traffic continuously for unusual or unauthorized activities or conditions.","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"si_4_5": {"name": "SI-4(5) System-Generated Alerts","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_4_5","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The information system alerts organization-defined personnel or roles when the following indications of compromise or potential compromise occur: [Assignment: organization-defined compromise indicators].","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"si_7_1": {"name": "SI-7(1) Integrity Checks","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_7_1","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Software, Firmware, and Information Integrity (SI-7)"}],"description": "The information system performs an integrity check of security relevant events at least monthly.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"ac_17_1": {"name": "AC-17(1) Automated Monitoring/Control","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_17_1","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system monitors and controls remote access methods.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"ac_17_2": {"name": "AC-17(2) Protection Of Confidentiality/Integrity Using Encryption","checks": {"elb_ssl_listeners": "FAIL","acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_17_2","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system implements cryptographic mechanisms to protect the confidentiality and integrity of remote access sessions.","checks_status": {"fail": 2,"pass": 1,"total": 3,"manual": 0}},"ac_17_3": {"name": "AC-17(3) Managed Access Control Points","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_17_3","Section": "Access Control (AC)","Service": "vpc","SubGroup": null,"SubSection": null}],"description": "The information system routes all remote accesses through organization-defined managed network access control points.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ac_2_12": {"name": "AC-2(12) Account Monitoring","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_12","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "Monitors and reports atypical usage of information system accounts to organization-defined personnel or roles.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"ac_6_10": {"name": "AC-6(10) Prohibit Non-Privileged Users From Executing Privileged Functions","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_6_10","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Least Privilege (AC-6)"}],"description": "The information system prevents non-privileged users from executing privileged functions to include disabling, circumventing, or altering implemented security safeguards/countermeasures.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_2_11": {"name": "IA-2(11) Remote Access - Separate Device","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2_11","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "The information system implements multifactor authentication for remote access to privileged and non-privileged accounts such that one of the factors is provided by a device separate from the system gaining access and the device meets [Assignment: organization-defined strength of mechanism requirements].","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"si_4_16": {"name": "SI-4(16) Correlate Monitoring Information","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_16","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The organization correlates information from monitoring tools employed throughout the information system.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}}},"requirements_passed": 18,"requirements_failed": 41,"requirements_manual": 5,"total_requirements": 64,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "1c8c75df-34ec-48f2-b6e2-5dba27d9b734","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "kisa_isms_p_2023_aws","framework": "KISA-ISMS-P","version": "2023","description": "The ISMS-P certification, established by KISA (Korea Internet & Security Agency), is a system where an independent certification body evaluates whether a company or organization's information security and privacy protection measures comply with certification standards, and grants certification. This helps organizations improve public trust in their services and respond effectively to increasingly complex cyber threats. The ISMS-P framework also provides comprehensive guidelines for systematically establishing, implementing, and managing information security and privacy protection.","region": "eu-west-1","requirements": {"1.1.1": {"name": "Executive Participation","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.1.1 Executive Participation","Subdomain": "1.1. Management System","AuditEvidence": ["Information protection and personal information protection reporting system (e.g., communication plan)","Minutes of the Information Protection and Personal Information Protection Committee","Information protection and personal information protection policies/guidelines (including executive approval records)","Information protection plans and internal management plans (including executive approval records)","Information protection and personal information protection organization chart"],"AuditChecklist": ["Is there documentation outlining the responsibilities and roles of executives to ensure their participation in the establishment and operation of the information protection and personal information protection management system?","Is there a reporting, review, and approval process in place to ensure that executives actively participate in decision-making regarding information protection and personal information protection activities?"],"NonComplianceCases": ["Case 1: Although it is stated in the information protection and personal information protection policy to report the status of information protection and personal information protection to the executives on a quarterly basis, no such reports have been made for an extended period.","Case 2: In performing major information protection activities (e.g., risk assessment, determining risk acceptance levels, reviewing information protection measures and implementation plans, reviewing the results of information protection measures, security audits, etc.), executives or those authorized by the executives did not participate in decision-making or there was no evidence of their involvement."],"RelatedRegulations": []}],"description": "The CEO must establish and operate a reporting and decision-making system to ensure executive participation in the establishment and operation of the information protection and personal information protection management system.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.2": {"name": "Designation of Chief Officers","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.1.2 Designation of Chief Officers","Subdomain": "1.1. Management System","AuditEvidence": ["Documents related to the appointment of the CISO and CPO (e.g., personnel orders, personnel records)","Information protection and personal information protection organization chart","Information protection and personal information protection policies/guidelines","Job descriptions (roles and responsibilities of the CISO and CPO)","Records of CISO reports","Internal management plans (regarding the appointment of the CPO)"],"AuditChecklist": ["Has the CEO officially designated a chief officer responsible for overseeing information protection and personal information protection?","Are the CISO and CPO appointed at an executive level with authority to allocate resources such as budget and personnel, and do they meet the qualifications required by relevant laws?"],"NonComplianceCases": ["Case 1: Failure to appoint and report a CISO as required under the Information and Communications Network Act, even though the organization is obligated to do so.","Case 2: Appointing a person without substantial authority and status as the CPO, making it difficult to believe that they are responsible for overseeing personal information processing.","Case 3: Although the organization chart specifies the CISO and CPO, the formal appointment process, such as issuing personnel orders, was not followed.","Case 4: Although the entity is subject to ISMS certification and had over 5 trillion won in assets at the end of the previous year, the CISO also holds the position of CIO, in violation of the ISMS requirements."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures), Article 31 (Designation of a Personal Information Protection Officer)","Information and Communications Network Act, Article 45-3 (Designation of a Chief Information Security Officer, etc.)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "The CEO must appoint a Chief Information Security Officer (CISO) responsible for information protection and a Chief Privacy Officer (CPO) responsible for personal information protection, both at an executive level with authority to allocate resources such as budget and personnel.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.3": {"name": "Organization Structure","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.1.3 Organization Structure","Subdomain": "1.1. Management System","AuditEvidence": ["Information protection and personal information protection committee regulations/minutes","Information protection and personal information protection working group regulations/minutes","Information protection and personal information protection organization chart","Internal management plan","Job descriptions"],"AuditChecklist": ["Has the organization established and operated a working group with expertise to support the work of the CISO and CPO and systematically implement the organization's information protection and personal information protection activities?","Has the organization established and operated a committee that can review, approve, and make decisions on important information protection and personal information protection matters across the organization?","Has the organization established and operated a working group composed of information protection and personal information protection officers and department-level personnel for enterprise-wide information protection and personal information protection activities?"],"NonComplianceCases": ["Case 1: The Information Protection and Personal Information Protection Committee was established, but it consists only of department heads without the inclusion of executives, making it difficult to make decisions on the organization's key information and personal information protection matters.","Case 2: Although a working group for information protection and personal information protection was established, including heads of departments that handle important information and personal data, it has not been active for an extended period.","Case 3: Although the Information Protection and Personal Information Protection Committee was convened, major matters such as the annual information protection and personal information protection plan, training plan, budget, and personnel were not reviewed or decided upon.","Case 4: Although an Information Protection Committee was established for deliberation and decision-making on information protection and personal information protection matters, only the operations and IT security departments participated, without the involvement of departments responsible for personal information protection, leaving personal information protection matters undecided."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "The CEO must establish and operate a working group to effectively implement information protection and personal information protection, a committee that can review and approve key matters related to information protection and personal information protection across the organization, and a consultative body consisting of department-level information protection and personal information protection officers for enterprise-wide protection activities.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.4": {"name": "Scope Setting","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.1.4 Scope Setting","Subdomain": "1.1. Management System","AuditEvidence": ["Scope definition document for information protection and personal information protection management system","List of information assets and personal information","Document list","Service flowchart","Personal information flowchart","Organization-wide organizational chart","System and network configuration diagram"],"AuditChecklist": ["Has the organization set the scope of the management system to include key assets that may affect core services and personal information processing?","If there are exceptions within the defined scope, are clear reasons documented, and are consultations with relevant stakeholders and approvals from responsible parties recorded and managed?","Is the organization maintaining documentation that includes the major services, operational status, and systems, allowing for clear verification of the scope of the information protection and personal information protection management system?"],"NonComplianceCases": ["Case 1: The development and test systems, external staff, PCs, and test devices related to the development work for information systems and personal information processing systems were omitted from the management system's scope.","Case 2: Key organizations (personnel) in departments and business units that play critical roles in decision-making for services or businesses within the scope of the information protection and personal information protection management system were not included in the certification scope.","Case 3: The development and test systems, developer PCs, test devices, and development organizations related to the development work for information systems and personal information processing systems were omitted from the management system's scope."],"RelatedRegulations": []}],"description": "The organization must set the scope of the management system by considering its core services and the current state of personal information processing, and document the related services, personal information processing tasks, organizations, assets, and physical locations.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.5": {"name": "Policy Establishment","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.1.5 Policy Establishment","Subdomain": "1.1. Management System","AuditEvidence": ["Information protection and personal information protection policies/guidelines/procedures (including records of new/revised versions)","Meeting minutes of stakeholder reviews of newly established/revised information protection and personal information protection policies/guidelines/procedures","Internal management plans for personal information","Notifications of new/revised information protection and personal information protection policies/guidelines (via groupware, intranet, etc.)","Minutes of the Information Protection and Personal Information Protection Committee"],"AuditChecklist": ["Has the organization established a top-level information protection and personal information protection policy that serves as the foundation for all information protection and personal information protection activities?","Has the organization established detailed guidelines, procedures, and manuals specifying the methods, processes, and frequencies required to implement the information protection and personal information protection policies?","Are the information protection and personal information protection policies and implementation documents approved by the CEO or by someone delegated by the CEO when newly established or revised?","Are the latest versions of the information protection and personal information protection policies and implementation documents provided to relevant employees in an easily understandable format?"],"NonComplianceCases": ["Case 1: Although internal regulations stipulate that revisions to the information protection and personal information protection policies must be approved by the Information Protection and Personal Information Protection Committee, recent revisions were made solely based on the approval of the CISO and CPO without presenting the revisions to the committee.","Case 2: The information protection and personal information protection policies and guidelines were recently revised, but these changes were not communicated to relevant departments and employees, leading some departments to continue operating based on outdated guidelines.","Case 3: The information protection and personal information protection policies and guidelines are managed solely by the security department and are not made available for employees to access through bulletin boards or documents."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "The organization must establish and document information protection and personal information protection policies and implementation documents, clearly stating the organization's information protection and personal information protection guidelines and direction. These policies and implementation documents must be approved by the executive management and communicated in an understandable form to employees and relevant parties.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.6": {"name": "Resource Allocation","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.1.6 Resource Allocation","Subdomain": "1.1. Management System","AuditEvidence": ["Annual action plan for information protection and personal information protection activities (including budget and personnel plans)","Reports on the results of information protection and personal information protection activities","Records of investments in information protection and personal information protection","Information protection and personal information protection organization chart"],"AuditChecklist": ["Has the organization secured personnel with expertise in the fields of information protection and personal information protection?","Has the organization evaluated and allocated the necessary resources, including budget and personnel, for the effective implementation and continuous operation of the information protection and personal information protection management system?","Has the organization established and implemented an annual detailed action plan for information protection and personal information protection, and conducted audits, analyses, and evaluations of the results?"],"NonComplianceCases": ["Case 1: The organization assembled an information protection and personal information protection team, but the team consisted only of personnel without expertise in information protection or IT, resulting in inadequate security staffing.","Case 2: The CEO failed to allocate sufficient resources, such as budget and security solutions, for implementing the technical and managerial safeguards required for personal information processing systems.","Case 3: After obtaining certification, the organization significantly reduced personnel and budget support, reassigned existing staff to other departments, and repurposed part of the budget for other uses."],"RelatedRegulations": []}],"description": "The CEO must allocate the necessary resources, including budget and personnel with expertise in the fields of information protection and personal information protection, for the effective implementation and continuous operation of the management system.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.2.1": {"name": "Identification of Information Assets","checks": {"macie_is_enabled": "PASS","resourceexplorer2_indexes_found": "PASS","config_recorder_all_regions_enabled": null,"organizations_account_part_of_organizations": null,"organizations_tags_policies_enabled_and_attached": null},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.2.1 Identification of Information Assets","Subdomain": "1.2. Risk Management","AuditEvidence": ["Information asset and personal information asset classification criteria","Information asset and personal information asset list (from asset management system screen)","Information asset and personal information security levels","Asset audit details","Risk analysis report (including asset identification)"],"AuditChecklist": ["Has the organization established classification criteria for information assets and identified all assets within the scope of the information protection and personal information protection management system, maintaining them in a list?","For the identified information assets, does the organization determine their importance by considering legal requirements and their impact on operations, and assign security levels?","Does the organization regularly review the status of information assets to keep the list up-to-date?"],"NonComplianceCases": ["Case 1: The list of assets within the scope of the information protection and personal information protection management system omits internal information leakage control systems, such as print security, document encryption, and USB media control, which are used to manage PCs handling important information and personal information.","Case 2: Personal information provided by third parties within the scope of the information protection and personal information protection management system has not been identified as an asset.","Case 3: The asset classification criteria in the internal guidelines and the classification criteria in the asset management register are inconsistent.","Case 4: Although on-premises assets have been identified, assets related to externally entrusted IT services (web hosting, server hosting, cloud, etc.) have been omitted (only for assets within the certification scope).","Case 5: The backup server storing unique identification information and other personal data has been classified with a low confidentiality rating, raising concerns about the reasonableness and reliability of the importance assessment."],"RelatedRegulations": []}],"description": "Organizations must establish classification criteria for information assets according to the characteristics of their operations, identify and classify all information assets within the scope of the management system, assess their importance, and maintain an up-to-date list.","checks_status": {"fail": 0,"pass": 2,"total": 5,"manual": 0}},"1.2.2": {"name": "Status and Flow Analysis","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.2.2 Status and Flow Analysis","Subdomain": "1.2. Risk Management","AuditEvidence": ["Information service status table","Information service workflow charts and process maps","Personal information processing status table (for ISMS-P certification)","Personal information flowcharts (for ISMS-P certification)"],"AuditChecklist": ["Has the organization identified and documented the status and workflows of information services across all areas of the management system?","Has the organization identified and documented the status of personal information processing within the scope of the management system, and mapped out personal information flows in flowcharts?","Does the organization regularly review procedures and workflows in response to changes in services, operations, and information assets, and keep the flowcharts and related documents up-to-date?"],"NonComplianceCases": ["Case 1: There are no documents outlining the workflows and procedures for major services within the scope of the management system.","Case 2: The personal information flowchart contains significant discrepancies from the actual personal information flow, or important personal information flows are missing.","Case 3: After the initial creation of the personal information flowchart, it has not been updated to reflect changes in the personal information flow."],"RelatedRegulations": []}],"description": "Organizations must analyze the status of information services and personal information processing across all areas of the management system, document the procedures and workflows, and review them regularly to maintain their accuracy.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.2.3": {"name": "Risk Assessment","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.2.3 Risk Assessment","Subdomain": "1.2. Risk Management","AuditEvidence": ["Risk management guidelines","Risk management manuals/guides","Risk management plan","Risk assessment report","Minutes of the Information Protection and Personal Information Protection Committee","Minutes of the Information Protection and Personal Information Protection Working Group","Information asset and personal information asset list","Information service and personal information flowcharts"],"AuditChecklist": ["Has the organization defined methods for identifying and assessing risks that could arise from various aspects, depending on the characteristics of the organization or service?","Does the organization annually develop a risk management plan that specifies the personnel, timeline, targets, methods, and budget for risk management activities?","Does the organization conduct regular or ad-hoc risk assessments at least once a year according to the risk management plan?","Has the organization established an acceptable target risk level and identified risks that exceed that level?","Are the results of risk identification and assessment reported to the executives?"],"NonComplianceCases": ["Case 1: The risk management plan specifies the risk assessment period and the targets and methods for risk management, but lacks details on the personnel and budget required for execution.","Case 2: While a risk assessment was conducted in the previous year, no risk assessment was conducted this year due to a lack of changes in assets.","Case 3: The organization conducted risk identification and assessment according to the risk management plan, but failed to assess the risks of important information assets within the scope, or failed to assess compliance with legal requirements related to information protection.","Case 4: The organization identified and assessed risks and set an acceptable target risk level according to the risk management plan, but did not report and seek approval from the executives (e.g., the Chief Information Security Officer).","Case 5: The method defined in the internal guidelines for risk assessment differs from the method actually used.","Case 6: The organization failed to identify and assess risks in the administrative and physical areas related to the information protection management system, and used only the results of technical vulnerability assessments as the risk assessment outcome.","Case 7: The organization set the acceptable target risk level (DoA) unreasonably high, designating risks that required action as acceptable risks, even though these risks were significant and required immediate or short-term action."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "Organizations must collect threat information by analyzing internal and external environments, select a risk assessment method suitable for the organization, conduct a risk assessment at least once a year across all areas of the management system, and manage acceptable risks with the approval of the executives.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.2.4": {"name": "Selection of Protective Measures","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.2.4 Selection of Protective Measures","Subdomain": "1.2. Risk Management","AuditEvidence": ["Information protection and personal information protection implementation plans/risk management plans","Information protection and personal information protection measures","Information protection and personal information protection master plan","Records of management reports and approvals for the information protection and personal information protection implementation plan"],"AuditChecklist": ["Has the organization developed risk treatment strategies (e.g., risk reduction, avoidance, transfer, acceptance) and selected protective measures to address the identified risks?","Has the organization established and reported to management an implementation plan that includes priority, schedule, responsible department/personnel, and budget for the protective measures?"],"NonComplianceCases": ["Case 1: Although an implementation plan for the information protection and personal information protection measures was established, it was not reported to the CISO and CPO.","Case 2: Some risk mitigation actions that were required were missing from the implementation plan.","Case 3: Mandatory legal requirements and risks with high security vulnerabilities were accepted without additional protective measures, instead of being addressed by a risk treatment plan.","Case 4: The rationale and validity for risk acceptance were insufficient, and some risks that could have been addressed immediately or in the short term due to urgency or ease of implementation were classified under long-term plans without specific justification."],"RelatedRegulations": []}],"description": "Based on the results of the risk assessment, appropriate protective measures must be selected to address the identified risks, and an implementation plan including the priority, schedule, responsible department/personnel, and budget for the protective measures must be established and approved by management.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.3.1": {"name": "Implementation of Protective Measures","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.3.1 Implementation of Protective Measures","Subdomain": "1.3. Operation of the Management System","AuditEvidence": ["Information protection and personal information protection implementation plans/risk management plans","Information protection and personal information protection measures","Information protection and personal information protection implementation progress reports (including reports to management)","Information protection and personal information protection implementation completion reports (including reports to management)","Information protection and personal information protection operating statements"],"AuditChecklist": ["Are the protective measures effectively implemented according to the implementation plan, and are the implementation results reported to management to verify their accuracy and effectiveness?","Has the organization created and documented detailed operating statements recording the implementation and operation status of protective measures according to the certification standards of the management system?"],"NonComplianceCases": ["Case 1: The results of the completion of the information protection and personal information protection measures were not reported to the CISO and CPO.","Case 2: The risk action implementation result report indicated 'completed,' but related risks still existed, or the accuracy and effectiveness of the implementation results were not verified.","Case 3: Risks classified as medium- to long-term in the previous year's information protection measures implementation plan were not implemented in the current year, or the results were not reviewed and verified by management.","Case 4: The actual operating status described in the operating statements did not match reality, and related documents, approvals, and meeting minutes mentioned in the operating statements did not exist.","Case 5: Although the implementation results were reported to the CISO and CPO, some incomplete items were not followed up with reasons and corrective actions."],"RelatedRegulations": []}],"description": "The selected protective measures must be effectively implemented according to the implementation plan, and management must verify the accuracy and effectiveness of the implementation results.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.3.2": {"name": "Sharing of Protective Measures","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.3.2 Sharing of Protective Measures","Subdomain": "1.3. Operation of the Management System","AuditEvidence": ["List of operating or implementing departments for each protective measure","Evidence of internal sharing of information protection and personal information protection plans (e.g., notices, training materials, shared documents)"],"AuditChecklist": ["Has the organization clearly identified the departments and personnel responsible for the operation or implementation of the protective measures?","Has the organization shared or provided training to the departments and personnel responsible for the operation or implementation of the protective measures?"],"NonComplianceCases": ["Case 1: Although protective measures were developed and implemented, the relevant information was not sufficiently shared or provided through training, so the departments or personnel responsible for the actual operation or implementation were unaware of the details."],"RelatedRegulations": []}],"description": "The departments and personnel responsible for the actual operation or implementation of the protective measures must be identified, and the related information must be shared and provided through training to ensure continuous operation.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.3.3": {"name": "Operation Status Management","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.3.3 Operation Status Management","Subdomain": "1.3. Operation of the Management System","AuditEvidence": ["Annual plan for information protection and personal information protection","Operation status report for information protection and personal information protection","Results of inspections on the implementation of information protection and personal information protection activities"],"AuditChecklist": ["Are information protection and personal information protection activities that need to be performed periodically or continuously for the operation of the management system documented and managed?","Does management periodically review the effectiveness of the operation of the management system and manage it accordingly?"],"NonComplianceCases": ["Case 1: Failure to document activities that are required to be performed periodically or continuously as part of the operation of the information protection and personal information protection management system.","Case 2: Although documentation of the operational status of the information protection and personal information protection management system has been completed, periodic reviews have not been conducted, resulting in the omission of some required monthly and quarterly activities, and some activities have not been verified for implementation."],"RelatedRegulations": ["Personal Information Protection Act, Article 31 (Designation of a Personal Information Protection Officer)","Information and Communications Network Act, Article 45-3 (Designation of a Chief Information Security Officer, etc.)"]}],"description": "According to the management system established by the organization, operational activities that must be performed continuously or periodically must be recorded and managed in a way that allows identification and tracking, and management must regularly review the effectiveness of operational activities and manage them accordingly.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.4.1": {"name": "Review of Legal Requirements Compliance","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.4.1 Review of Legal Requirements Compliance","Subdomain": "1.4. Inspection and Improvement of the Management System","AuditEvidence": ["Records of legal compliance reviews","Records of reviews and revisions of information protection and personal information protection policies and guidelines","Comparison tables of revised policies and guidelines","Internal sharing documents of legal revisions","Proof of personal information liability insurance or equivalent guarantees (e.g., cyber insurance contracts)","Information protection disclosure records"],"AuditChecklist": ["Is the organization regularly identifying and maintaining up-to-date legal requirements related to information protection and personal information protection?","Is the organization conducting regular reviews of compliance with legal requirements at least once a year?"],"NonComplianceCases": ["Case 1: Although the Information and Communications Network Act and Personal Information Protection Act were recently revised, the organization did not review the impact of the changes on the organization, and as a result, the policy documents, implementation documents, and legal compliance checklists were not updated, leading to inconsistencies between the documents and the law.","Case 2: Although legal requirements that the organization must comply with were amended, the organization failed to conduct legal compliance reviews for an extended period.","Case 3: Inadequate legal compliance reviews resulted in numerous violations of the Personal Information Protection Act and other regulations.","Case 4: The organization was subject to the Personal Information Liability Compensation Guarantee system under the Personal Information Protection Act but failed to recognize this, resulting in non-compliance with insurance or reserve requirements. In cases where insurance was obtained, the organization failed to meet the minimum coverage requirements based on the number of users and revenue.","Case 5: Although the organization was required by law to disclose information protection status, it failed to do so within the legally mandated timeframe.","Case 6: The organization used a mobile app to receive personal location information from a location-based service provider, but failed to report its location-based service business.","Case 7: A foreign personal information controller without a domestic address or business office, whose personal information of domestic subjects stored and managed in the previous three months averaged over one million persons per day, failed to appoint a domestic representative in writing as required."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "The organization must regularly identify and reflect legal requirements related to information protection and personal information protection and continuously review whether compliance is being maintained.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.4.2": {"name": "Management System Audit","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.4.2 Management System Audit","Subdomain": "1.4. Inspection and Improvement of the Management System","AuditEvidence": ["Management system audit plan (internal audit plan, internal inspection plan)","Management system audit report","Minutes of the Information Protection and Personal Information Protection Committee"],"AuditChecklist": ["Has the organization established a management system audit plan that includes the criteria, scope, frequency, and qualifications for audit personnel to audit the management system's effectiveness in accordance with legal requirements and established policies?","Has the organization conducted audits at least once a year with personnel who have independence, objectivity, and expertise, and reported any identified issues to management?"],"NonComplianceCases": ["Case 1: The audit team included personnel from the IT department, which was also the subject of the audit, compromising the independence of the audit.","Case 2: Although a management system audit was conducted this year, the audit scope was limited to certain areas, failing to cover the full scope of the information protection and personal information protection management system.","Case 3: The management system audit team was composed solely of internal staff and external consultants who participated in the development of the management system, compromising the independence of the audit."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "The organization must audit its management system at least once a year with a team of personnel who possess independence and expertise, to ensure the system is operating effectively in accordance with internal policies and legal requirements, and report any identified issues to management.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.4.3": {"name": "Management System Improvement","checks": {},"status": "PASS","attributes": [{"Domain": "1. Establishment and Operation of the Management System","Section": "1.4.3 Management System Improvement","Subdomain": "1.4. Management System Inspection and Improvement","AuditEvidence": ["Management system inspection result reports","Management system inspection action plans and implementation result reports","Preventive measures","Effectiveness measurement indicators and results (including reports to management)"],"AuditChecklist": ["Are the root causes of the issues identified during legal compliance reviews and management system inspections analyzed, and are preventive and improvement measures established and implemented?","Are there criteria and procedures in place to verify the accuracy and effectiveness of preventive and improvement results?"],"NonComplianceCases": ["Case 1: The same issues in the operation of the information protection and personal information protection management system, identified during internal inspections, are repeated each time.","Case 2: Although internal regulations require the analysis of root causes and the establishment of preventive measures for issues identified during internal inspections, recent internal inspections failed to include root cause analysis and preventive measures.","Case 3: Preventive measures for the issues in the management system were established, and key performance indicators (KPIs) were developed for periodic measurement, but the results were not reported to management for a long period.","Case 4: Action plans were not established or the completion of actions was not confirmed for issues identified during management system inspections."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "The root causes of the issues identified during legal compliance reviews and management system inspections must be analyzed, and preventive measures must be established and implemented. The management must confirm the accuracy and effectiveness of the improvement results.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.1.1": {"name": "Policy Maintenance","checks": {},"status": "PASS","attributes": [{"Domain": "2. Control Measures Requirements","Section": "2.1.1 Policy Maintenance","Subdomain": "2.1. Policies, Organization, and Asset Management","AuditEvidence": ["Information protection and personal information protection policies and implementation documents (e.g., guidelines, procedures, manuals)","Results of regular and ad hoc validity reviews of policies and guidelines","Meeting minutes and circulation records with relevant departments regarding policies and guidelines","Revision history of policies and guidelines"],"AuditChecklist": ["Has the organization established and implemented a procedure for regularly reviewing the validity of information protection and personal information protection policies and implementation documents?","When there are significant changes in the internal and external environment, are the impacts on information protection and personal information protection policies and implementation documents reviewed and revised as necessary?","Are stakeholders consulted when revising information protection and personal information protection policies and implementation documents?","Is there a system in place to track the revision history of information protection and personal information protection policies and implementation documents?"],"NonComplianceCases": ["Case 1: There is inconsistency between password setting rules in guidelines and procedures.","Case 2: Information protection activities (e.g., training, encryption, backup) have different targets, frequencies, levels, and methods described in internal regulations, guidelines, and procedures, leading to inconsistency.","Case 3: A new database access control solution was introduced to effectively record and manage access and operation logs for the database, but internal security guidelines such as those for security systems and database security management have not been updated to reflect these new controls.","Case 4: Although the personal information protection policy was revised, the policy implementation date was not specified, and information such as the author, creation date, and approval date were missing from the relevant policy.","Case 5: Although significant changes occurred in laws and regulations related to personal information protection, these changes were not reviewed or reflected in the personal information protection policy and implementation documents."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "Information protection and personal information protection policies and implementation documents must be periodically reviewed and, if necessary, revised in response to changes in laws and regulations, policies of higher organizations and related agencies, and changes in the internal and external environment. These changes must be documented and tracked.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.1.2": {"name": "Organization Maintenance","checks": {},"status": "PASS","attributes": [{"Domain": "2. Control Measures Requirements","Section": "2.1.2 Organization Maintenance","Subdomain": "2.1. Policies, Organization, and Asset Management","AuditEvidence": ["Information protection and personal information protection organization chart","Job descriptions for the information protection and personal information protection organization","Assignment tables for information protection and personal information protection roles","Information protection and personal information protection policies/guidelines and internal management plans","Information protection and personal information protection communication management plans","Records of communication activities (e.g., monthly/weekly reports, internal notices)","Communication channels (e.g., information protection portal, bulletin boards)"],"AuditChecklist": ["Are the roles and responsibilities of those responsible for and involved in information protection and personal information protection clearly defined?","Has the organization established a system for evaluating the activities of those responsible for and involved in information protection and personal information protection?","Has the organization established and implemented systems and procedures for communication between the information protection and personal information protection organization and its members?"],"NonComplianceCases": ["Case 1: Although the roles and responsibilities of the CISO, CPO, and related personnel are defined in internal guidelines and job descriptions, they do not align with the actual operating status.","Case 2: There are no goals, criteria, or performance indicators in place for the periodic evaluation of the activities of the CISO and related personnel.","Case 3: Although internal guidelines require departments to set KPIs related to information protection for the information protection officers in each department to be reflected in performance evaluations, no information protection-related KPIs were set for any of the departmental information protection officers.","Case 4: Although the CISO and CPO are designated, the roles and responsibilities required by law are not specifically defined in internal guidelines or job descriptions."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures), Article 31 (Designation of a Personal Information Protection Officer)","Information and Communications Network Act, Article 45-3 (Designation of a Chief Information Security Officer, etc.)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "Roles and responsibilities related to information protection and personal information protection must be assigned to all members of the organization, and systems must be established for evaluating these activities and for communication between members and departments.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.1.3": {"name": "Management of Information Assets","checks": {"macie_is_enabled": "PASS","resourceexplorer2_indexes_found": "PASS","config_recorder_all_regions_enabled": null,"account_maintain_current_contact_details": null,"organizations_account_part_of_organizations": null,"organizations_tags_policies_enabled_and_attached": null,"account_security_contact_information_is_registered": null,"account_security_questions_are_registered_in_the_aws_account": null,"account_maintain_different_contact_details_to_security_billing_and_operations": null},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.1.3 Management of Information Assets","Subdomain": "2.1. Policy, Organization, Asset Management","AuditEvidence": ["List of information assets (designation of responsible persons and managers)","Handling procedures for information assets (documents, information systems, etc.)","Information asset management system screen","Security classification indicators for information assets"],"AuditChecklist": ["Are handling procedures (creation, introduction, storage, use, disposal) and protection measures defined and implemented according to the security classification of information assets?","Have responsible persons and managers been designated for identified information assets?"],"NonComplianceCases": ["Case 1: Although internal guidelines require security classification to be indicated on documents, this has not been followed.","Case 2: Responsible persons and managers for information assets have not been identified, or the asset list has not been updated, leading to changes in responsible personnel due to resignations, transfers, etc., not being reflected.","Case 3: Although security classifications were assigned to identified information assets after evaluating their importance, handling procedures based on the security classification were not defined."],"RelatedRegulations": []}],"description": "The procedures and protection measures for handling information assets according to their purpose and importance must be established and implemented, and the responsibilities for each asset must be clearly defined and managed.","checks_status": {"fail": 0,"pass": 2,"total": 9,"manual": 0}},"2.2.1": {"name": "Designation and Management of Key Personnel","checks": {"iam_support_role_created": null,"organizations_delegated_administrators": null,"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.2.1 Designation and Management of Key Personnel","Subdomain": "2.2. Personnel Security","AuditEvidence": ["Criteria for key duties","List of key personnel","List of personal information handlers","Account and authority management ledger for key information systems and personal information processing systems","Management status of key personnel (e.g., training results, security pledges)"],"AuditChecklist": ["Are the criteria for key duties, such as handling personal information and important information or accessing key systems, clearly defined?","Are employees and external personnel performing key duties designated as key personnel, and is the list kept up-to-date?","Are personnel handling personal information designated as personal information handlers, and is the list kept up-to-date?","Is the designation of key personnel and personal information handlers minimized based on business needs, and are management plans established and implemented?"],"NonComplianceCases": ["Case 1: Although a list of key personnel (e.g., personal information handlers, secret information managers) has been created, some employees who handle large volumes of personal information (e.g., DBAs, DLP managers) were omitted.","Case 2: Although the list of key personnel and personal information handlers is being managed, it has not been updated, including resigned employees and newly hired personnel.","Case 3: Personal information handler privileges were granted collectively to entire departments, leading to personnel without the need to handle personal information being excessively designated as personal information handlers.","Case 4: Although internal guidelines require approval from the security team and the signing of security pledges when granting key personnel privileges, many key personnel were registered without following this process."],"RelatedRegulations": ["Personal Information Protection Act, Article 28 (Supervision of Personal Information Handlers), Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "Criteria and management plans for key duties, such as handling personal information and important information or accessing key systems, must be established, and the number of key personnel must be minimized and their list kept up-to-date.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"2.2.2": {"name": "Separation of Duties","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.2.2 Separation of Duties","Subdomain": "2.2. Personnel Security","AuditEvidence": ["Guidelines on the separation of duties (e.g., personnel security guidelines)","Job descriptions (e.g., system operation/management, development/operation)","Status of supplementary controls when duties are not separated"],"AuditChecklist": ["Are criteria for the separation of duties established and applied to prevent potential harm from the misuse or abuse of authority?","If separation of duties is difficult, have supplementary controls such as mutual review between personnel, regular monitoring and approval of changes by senior management, and ensuring accountability been established?"],"NonComplianceCases": ["Case 1: Although the organization has sufficient size and personnel to enable separation of duties, the established internal separation of duties criteria were not followed due to operational convenience.","Case 2: Although the organization received approval from senior management to combine development and operation duties due to the organization's characteristics, supplementary control measures such as mutual review between personnel, regular monitoring and review of changes by senior management, and ensuring accountability were not established."],"RelatedRegulations": []}],"description": "Criteria for the separation of duties must be established and applied to prevent potential harm from the misuse or abuse of authority. If separation of duties is unavoidable, supplementary measures must be established and implemented.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.2.3": {"name": "Security Pledge","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.2.3 Security Pledge","Subdomain": "2.2. Human Security","AuditEvidence": ["Security and personal information protection pledge (for employees and external personnel)","Confidentiality agreement (for resigned employees)"],"AuditChecklist": ["When hiring new personnel, is there a signed security and personal information protection agreement that specifies their responsibilities?","If temporary or external personnel are granted access to information assets, is there a signed agreement outlining their responsibilities for information protection and confidentiality?","Upon the resignation of an employee, is a separate confidentiality agreement obtained?","Are security, personal information protection, and confidentiality agreements stored safely and managed in a way that they can be easily retrieved when necessary?"],"NonComplianceCases": ["Case 1: While it is stipulated that new hires must sign a security pledge, some recently hired employees have not completed the pledge.","Case 2: Although employees sign a security pledge, external personnel with direct access to information systems have not signed such an agreement.","Case 3: Submitted security and personal information protection pledges are poorly managed, with documents left accessible on desks where unauthorized personnel can access them.","Case 4: Although personal information handlers have signed security pledges, the content only covers confidentiality and does not include specific responsibilities related to personal information protection."],"RelatedRegulations": []}],"description": "Employees, temporary staff, or external personnel handling information assets or granted access must sign a security and confidentiality agreement in accordance with internal policies.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.2.4": {"name": "Awareness and Training","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.2.4 Awareness and Training","Subdomain": "2.2. Human Security","AuditEvidence": ["Information protection and personal information protection training plan","Training result report","General and job-specific training materials","List of training attendees"],"AuditChecklist": ["Is an annual training plan approved by management, detailing the timing, duration, target audience, content, and method of information protection and personal information protection training?","Are all employees and external personnel within the scope of the management system provided with regular training at least once per year, and are additional training sessions provided when there are significant changes in relevant laws and regulations?","Is information protection and personal information protection training provided to new hires and external personnel before they begin their duties?","Are IT, information protection, and personal information protection staff receiving specialized training to enhance their job-specific expertise?","Are training records maintained, and is the effectiveness of the training evaluated and reflected in future training plans?"],"NonComplianceCases": ["Case 1: Although an annual information protection and personal information protection training plan was established and implemented last year, no such plan was established for the current year without a valid reason.","Case 2: The annual information protection and personal information protection training plan includes the frequency and target audience but lacks details such as schedule, content, and method.","Case 3: Although the annual training plan includes general personal information awareness training for all employees, it does not include job-specific training for those responsible for personal information protection, such as the personal information protection officer.","Case 4: Upon reviewing the training plan and result reports, it was found that certain external contractors (e.g., cleaning staff and security guards who have access to critical facilities within the certification scope) were not included in the training.","Case 5: Although information protection and personal information protection training was conducted, some records (e.g., training materials, attendance lists, evaluation surveys, result reports) were not retained.","Case 6: There is no system in place to identify employees who did not complete the required training or to provide make-up sessions for them (e.g., additional training, online courses)."],"RelatedRegulations": ["Personal Information Protection Act, Article 26 (Limitation on the Processing of Personal Information by Outsourcing), Article 28 (Supervision of Personal Information Handlers), Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans)"]}],"description": "Organizations must establish and operate an annual awareness and training plan to ensure that employees and related external personnel understand the organization's management system and policies and acquire the necessary job-specific expertise. The effectiveness of this plan must be evaluated and reflected in future plans.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.2.5": {"name": "Management of Resignation and Job Changes","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.2.5 Management of Resignation and Job Changes","Subdomain": "2.2. Human Security","AuditEvidence": ["Procedures for resignation and job changes","Asset (account) return management ledger upon resignation","Security checklists and inspection records for resigned employees"],"AuditChecklist": ["Are personnel changes (e.g., resignation, job changes, department transfers, leave of absence) shared among HR, information protection, personal information protection, and IT system operations departments?","Are procedures in place and implemented to promptly return information assets, revoke or adjust access rights, and confirm results when an employee (including temporary staff and external contractors) resigns or changes roles?"],"NonComplianceCases": ["Case 1: Accounts and access rights for personnel no longer handling personal information due to job changes remain active in the personal information processing system.","Case 2: No records of asset returns or access rights revocation procedures were found for recently resigned key personnel and personal information handlers.","Case 3: While asset returns are properly managed for resigned employees, the security check and resignation confirmation forms required by HR regulations are not being completed.","Case 4: Although access rights to personal information processing systems were revoked promptly upon the resignation of personal information handlers, access rights to systems like physical access control and VPN were not revoked in a timely manner."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights)"]}],"description": "Procedures must be established and managed for the return of assets, the revocation or adjustment of accounts and access rights, and confirmation of results when there is a resignation, job change, or leave of absence, involving departments such as HR, information protection, personal information protection, and IT.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.2.6": {"name": "Actions in Case of Security Violations","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.2.6 Actions in Case of Security Violations","Subdomain": "2.2. Human Security","AuditEvidence": ["HR regulations (disciplinary measures for violations of information protection and personal information protection regulations)","Records of disciplinary actions for violations of information protection and personal information protection guidelines","Incident case studies (company-wide notices, training materials)"],"AuditChecklist": ["Has the organization established disciplinary measures for employees and relevant external parties in case of violations of information protection and personal information protection responsibilities and obligations under laws, regulations, and internal policies?","When violations of information protection and personal information protection are detected, are actions taken in accordance with internal procedures?"],"NonComplianceCases": ["Case 1: No disciplinary measures or procedures are included in internal regulations for handling violations of information protection and personal information protection regulations.","Case 2: Although warning messages are sent to those who violate policies detected by security systems (e.g., DLP, database access control system, internal information leakage control system), follow-up actions such as explanations, additional investigations, or disciplinary actions are not carried out in accordance with internal regulations."],"RelatedRegulations": []}],"description": "In the event that employees or relevant external parties violate laws, regulations, or internal policies, the organization must establish and implement procedures to take appropriate actions.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.3.1": {"name": "Management of External Parties","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.3.1 Management of External Parties","Subdomain": "2.3. External Security","AuditEvidence": ["List of outsourced services and external facilities/services","Outsourcing contracts","Risk analysis reports and protective measures","Outsourcing security management guidelines, checklists, etc."],"AuditChecklist": ["Has the organization identified the status of outsourcing and the use of external facilities and services within the scope of the management system?","Has the organization identified the legal requirements and risks associated with outsourcing and the use of external facilities and services, and established appropriate protective measures?"],"NonComplianceCases": ["Case 1: Although the organization manages a list of outsourced services and external facilities/services as required by internal regulations, the list is outdated and does not reflect changes made to vendors several months ago.","Case 2: The organization has migrated some personal information processing systems to external cloud services within the scope of the management system, but no identification or risk assessment has been performed."],"RelatedRegulations": ["Personal Information Protection Act, Article 26 (Restrictions on the Processing of Personal Information by Outsourcing)","Information and Communications Network Act, Article 50-3 (Entrustment of the Transmission of Commercial Information for Profit)"]}],"description": "When outsourcing part of the work (e.g., handling personal information, information protection, operating or developing information systems) or using external facilities or services (e.g., data centers, cloud services, application services), the organization must identify the current status, understand the legal requirements and risks arising from external organizations or services, and establish appropriate protective measures.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.3.2": {"name": "Security in Contracts with External Parties","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.3.2 Security in Contracts with External Parties","Subdomain": "2.3. External Security","AuditEvidence": ["Outsourcing contracts","Information protection and personal information protection agreements (agreements, annexes)","Internal guidelines on outsourcing","RFPs (Requests for Proposals), evaluation forms related to the selection of outsourcing vendors"],"AuditChecklist": ["When selecting external services or outsourcing vendors related to the handling of important information and personal information, does the organization follow procedures to consider the vendors' capabilities in information protection and personal information protection?","Has the organization identified the information protection and personal information protection requirements associated with the use of external services and outsourcing, and specified them in contracts or agreements?","When outsourcing the development of information systems and personal information processing systems, has the organization specified the information protection and personal information protection requirements that must be followed during development in the contract?"],"NonComplianceCases": ["Case 1: No outsourcing contract exists for external vendors performing IT operations, development, or personal information processing tasks.","Case 2: The outsourcing contract with an external vendor handling personal information does not include some items required by the Personal Information Protection Act (e.g., management and supervision provisions).","Case 3: Although infrastructure operation and part of personal information processing tasks are outsourced to external vendors, the contract does not specify security requirements related to the nature of the outsourced work, but only includes general provisions on confidentiality and liability for damages."],"RelatedRegulations": ["Personal Information Protection Act, Article 26 (Restrictions on the Processing of Personal Information by Outsourcing)"]}],"description": "When using external services or outsourcing work to external parties, the organization must identify the information protection and personal information protection requirements and specify them in contracts or agreements.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.3.3": {"name": "External Party Security Implementation Management","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.3.3 External Party Security Implementation Management","Subdomain": "2.3. External Party Security","AuditEvidence": ["Security inspection results for external parties and contractors","Training details for external parties and contractors (training outcomes, attendee list, training materials, etc.)","Personal information outsourcing contract","Evidence of consent for re-outsourcing of personal information processing tasks"],"AuditChecklist": ["Are periodic inspections or audits conducted to ensure external parties comply with information protection and personal information protection requirements specified in contracts, agreements, and internal policies?","When issues are identified during inspections or audits of external parties, are improvement plans established and implemented?","If a contractor entrusted with personal information processing re-outsources related tasks to a third party, does the contractor obtain the principal's consent?"],"NonComplianceCases": ["Case 1: Failure to regularly conduct security inspections of external contractors who perform IT development and operations tasks on-site.","Case 2: Sending a notification to contractors entrusted with personal information processing to conduct security training, but failing to verify whether the training has been conducted.","Case 3: Allowing contractors to perform their own security inspections and report the results, without a verification process to ensure the inspections were properly conducted, thus undermining the reliability of the inspection results.","Case 4: Allowing contractors to re-outsource personal information processing tasks to a third party without the principal's consent.","Case 5: Failure to supervise contractors entrusted with transmitting commercial information for profit."],"RelatedRegulations": ["Personal Information Protection Act, Article 26 (Restrictions on the Outsourcing of Personal Information Processing)","Information and Communications Network Act, Article 50-3 (Outsourcing of the Transmission of Commercial Information for Profit)"]}],"description": "Security measures specified in contracts, agreements, and internal policies must be regularly inspected or audited to ensure external parties comply with information protection and personal information protection requirements.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.3.4": {"name": "Security for External Party Contract Changes and Expiry","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.3.4 Security for External Party Contract Changes and Expiry","Subdomain": "2.3. External Party Security","AuditEvidence": ["Information protection and personal information protection agreements","Confidentiality agreements","Information and personal information destruction agreements","Internal policies and guidelines related to the termination of external party contracts"],"AuditChecklist": ["Has the organization established and implemented security measures to ensure the return of information assets, deletion of information system access accounts, and the acquisition of confidentiality agreements in accordance with official procedures when an external party contract expires, a task is completed, or there is a personnel change?","When an external party contract expires, has the organization established and implemented procedures to confirm whether the external party holds any sensitive or personal information related to the outsourced task, and to retrieve or destroy such information?"],"NonComplianceCases": ["Case 1: Failure to delete accounts and permissions for external parties after their contract has expired, allowing access to certain information systems.","Case 2: During an outsourcing project, failure to take appropriate measures for some contractors who were replaced or whose contracts expired, including failing to obtain security agreements as required by internal regulations.","Case 3: After terminating a contract with a contractor entrusted with personal information processing, failure to verify whether the contractor destroyed any personal information they held."],"RelatedRegulations": ["Personal Information Protection Act, Article 26 (Restrictions on the Outsourcing of Personal Information Processing)","Information and Communications Network Act, Article 50-3 (Outsourcing of the Transmission of Commercial Information for Profit)"]}],"description": "When an external party contract expires, the task is completed, or there is a personnel change, security measures such as returning provided information assets, deleting information system access accounts, destroying sensitive information, and obtaining confidentiality agreements for acquired information must be implemented.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.1": {"name": "Designation of Protected Zones","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.4.1 Designation of Protected Zones","Subdomain": "2.4. Physical Security","AuditEvidence": ["Physical security guidelines (criteria for designating protected zones)","List of designated protected zones","Protected zone signage","List of protection measures for each zone"],"AuditChecklist": ["Has the organization established criteria for designating physical protection zones such as controlled areas, restricted areas, and reception areas to protect personal and sensitive information, documents, storage media, key facilities, and systems from physical and environmental threats?","Has the organization designated physical protection zones in accordance with the criteria and established and implemented protection measures for each zone?"],"NonComplianceCases": ["Case 1: Although internal physical security guidelines state that areas where personal information is stored and processed must be designated as controlled zones, certain document storage rooms containing membership application forms were omitted from the list of controlled zones.","Case 2: Internal physical security guidelines require that controlled zones be marked with specific signs, but some controlled zones do not have the required signage."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 10 (Physical Safety Measures)"]}],"description": "To protect personal and sensitive information, documents, storage media, key facilities, and systems from physical and environmental threats, physical protection zones such as controlled areas, restricted areas, and reception areas must be designated, and protection measures for each zone must be established and implemented.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.2": {"name": "Access Control","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protective Measures Requirements","Section": "2.4.2 Access Control","Subdomain": "2.4. Physical Security","AuditEvidence": ["Access logbook and entry logs","Access registration application form and approval records","Entry record review report","Access control system management screen (status of registered personnel, etc.)"],"AuditChecklist": ["Is access to protected areas controlled so that only authorized personnel are allowed to enter according to access procedures?","Are entry records for internal and external personnel for each protected area retained for a certain period, and are entry records and access permissions reviewed periodically?"],"NonComplianceCases": ["Case 1: Although control areas are defined, protective measures are established, and employees with access are managed, the entry records are not reviewed periodically, resulting in many inactive personnel (due to retirement, transfer, etc.) having long periods of no entry.","Case 2: Although access control devices are installed in controlled areas such as data centers and document storage rooms, they are left open for extended periods without valid reasons or approval.","Case 3: Some external partner employees are excessively granted all-area access cards for unrestricted entry."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 10 (Physical Safety Measures)"]}],"description": "Access to protected areas must be restricted to authorized personnel only, and entry and access logs should be reviewed periodically to ensure accountability.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.3": {"name": "Information System Protection","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protective Measures Requirements","Section": "2.4.3 Information System Protection","Subdomain": "2.4. Physical Security","AuditEvidence": ["Data processing facility diagram","Information system layout","Asset list"],"AuditChecklist": ["Are information systems placed in separated locations based on their importance, usage, and characteristics?","Are there measures in place to easily verify the actual physical location of the information systems?","Are power and communication cables protected from physical damage and electrical interference from external sources?"],"NonComplianceCases": ["Case 1: The system layout is not updated to reflect the latest changes, making it difficult to quickly identify the information system that has experienced a failure.","Case 2: Many cables are tangled and not properly organized on the server room floor or in racks, increasing the risk of failure due to electrical interference, damage, leakage, or negligence."],"RelatedRegulations": []}],"description": "Information systems should be arranged considering their importance and characteristics to reduce environmental threats, harmful factors, and unauthorized access, and communication and power cables should be protected from damage.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.4": {"name": "Operation of Protective Facilities","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protective Measures Requirements","Section": "2.4.4 Operation of Protective Facilities","Subdomain": "2.4. Physical Security","AuditEvidence": ["Physical security guidelines (related to protective facilities)","Data center facility status and inspection checklist","IDC outsourcing contract, SLA, etc."],"AuditChecklist": ["Are necessary facilities established and operational procedures set up based on the importance and characteristics of each protected area to prevent disasters such as fire, flood, and power failure caused by human error or natural disasters?","If operating outsourced integrated data centers (IDC), are physical security requirements included in the contract, and is the operational status periodically reviewed?"],"NonComplianceCases": ["Case 1: In some protected areas, such as the main office data center, the required protective facilities specified in internal guidelines are not installed.","Case 2: Although protective facilities such as UPS and fire suppression systems are in place in the data center, operational and inspection standards for the related facilities are not established.","Case 3: Although temperature and humidity control devices were installed in the data center according to operational guidelines, insufficient capacity means that the standard temperature and humidity levels are not maintained, increasing the risk of failure."],"RelatedRegulations": ["Information and Communications Network Act, Article 46 (Protection of Integrated Data Centers)","Guidelines for the Protection of Integrated Data Centers","Fire Facility Installation and Management Act, Article 12 (Management of Fire Protection Facilities in Specific Fire Protection Objects), Article 16 (Management of Evacuation Facilities, Fire Zones, and Fire Protection Facilities)"]}],"description": "Based on the importance and characteristics of the information systems located in protected areas, protective facilities such as temperature and humidity control, fire detection, firefighting equipment, leak detection, UPS, emergency generators, and dual power lines should be established and operated according to operational procedures.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.5": {"name": "Operations in Secure Zones","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.4.5 Operations in Secure Zones","Subdomain": "2.4. Physical Security","AuditEvidence": ["Operation request forms, operation logs","Entry logs for controlled areas","Records of review of entry and operation logs for controlled areas"],"AuditChecklist": ["When operations within secure zones, such as the introduction and maintenance of information systems, are required, are formal procedures for application and execution of such operations established and implemented?","Are the records of operations within secure zones periodically reviewed to confirm that the operations were carried out in accordance with the control procedures?"],"NonComplianceCases": ["Case 1: The entry log of the data center shows the presence of external maintenance personnel, but there is no record of an operation request or approval for work within the secure zone (i.e., entry and work in the secure zone were carried out without an operation request as required by internal regulations).","Case 2: Although internal regulations state that the records of operations within secure zones must be reviewed at least once per quarter, the review of such records has not been conducted for a long period without a valid reason."],"RelatedRegulations": []}],"description": "Procedures to prevent unauthorized actions and abuse of privileges within secure zones must be established and implemented, and the records of operations should be periodically reviewed.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.6": {"name": "Device Control for Inbound and Outbound","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.4.6 Device Control for Inbound and Outbound","Subdomain": "2.4. Physical Security","AuditEvidence": ["Inbound and outbound application forms for secure zones","Inbound and outbound management logs","Results of the review of inbound and outbound records"],"AuditChecklist": ["Are control procedures established and implemented to prevent security incidents such as information leakage and malware infection when information systems, mobile devices, storage media, etc., are brought into or taken out of secure zones?","Are records maintained and managed in accordance with the inbound and outbound control procedures, and is the compliance with the procedures periodically checked by reviewing the history of inbound and outbound activities?"],"NonComplianceCases": ["Case 1: Although control procedures for the inbound and outbound of mobile computing devices are established, there is no control over the movement of such devices within the controlled area, allowing both internal and external personnel with access to the controlled area to use mobile computing devices without restriction.","Case 2: Although internal guidelines state that inbound and outbound details of IT equipment must be recorded in the operation plan and signed by the person responsible for management, many signatures of responsible managers are missing from the records."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 10 (Physical Safety Measures)"]}],"description": "Procedures to control the inbound and outbound movement of information systems, mobile devices, storage media, etc., within secure zones must be established, implemented, and periodically reviewed.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.7": {"name": "Work Environment Security","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.4.7 Work Environment Security","Subdomain": "2.4. Physical Security","AuditEvidence": ["Security inspection reports for offices and shared spaces","Security inspection checklists for offices and shared spaces","Actions taken for non-compliance (e.g., training, rewards and penalties)","Current status of protection measures for printed and copied materials"],"AuditChecklist": ["Are protection measures established and implemented for shared facilities and office equipment such as document storage, shared PCs, multifunction printers, file servers, etc.?","Are protection measures established and implemented to prevent the exposure or leakage of personal and sensitive information through individual work environments such as work PCs, desks, drawers, etc.?","Are appropriate protection measures in place to ensure the safe handling of printed or copied materials containing personal information, such as paper documents?","Is compliance with information protection requirements in both individual and shared work environments periodically reviewed?"],"NonComplianceCases": ["Case 1: Although the internal management plan for personal information specifies that regular security inspections (e.g., clean desk policies) must be conducted, no such inspections have been carried out.","Case 2: Documents containing personal information, such as membership application forms, are stored in an office cabinet without a lock.","Case 3: Employee computers do not have screen savers or passwords set, and important documents have been left on vacationing employees' desks for an extended period.","Case 4: No protection measures are in place for shared PCs installed in shared office spaces such as meeting rooms, resulting in personal information files being stored unencrypted, or security updates not applied, or antivirus software not installed, leaving the systems vulnerable."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 10 (Physical Safety Measures), Article 12 (Safety Measures for Printing and Copying)"]}],"description": "Protection measures such as clean desk policies and regular inspections must be established and implemented to prevent unauthorized exposure or leakage of personal and sensitive information through shared office equipment (e.g., document storage, shared PCs, multifunction printers, file servers) and individual work environments (e.g., work PCs, desks).","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.5.1": {"name": "User Account Management","checks": {"iam_user_accesskey_unused": null,"iam_securityaudit_role_created": null,"iam_user_console_access_unused": null,"iam_policy_no_full_access_to_kms": null,"iam_role_administratoraccess_policy": null,"iam_user_administrator_access_policy": null,"organizations_scp_check_deny_regions": null,"iam_group_administrator_access_policy": null,"iam_policy_allows_privilege_escalation": null,"iam_inline_policy_no_full_access_to_kms": null,"iam_policy_no_full_access_to_cloudtrail": null,"iam_policy_attached_only_to_group_or_roles": null,"cognito_user_pool_self_registration_disabled": null,"iam_role_cross_account_readonlyaccess_policy": null,"iam_inline_policy_allows_privilege_escalation": null,"iam_inline_policy_no_administrative_privileges": null,"iam_inline_policy_no_full_access_to_cloudtrail": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_role_cross_service_confused_deputy_prevention": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"iam_customer_unattached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.5.1 User Account Management","Subdomain": "2.5. Authentication and Access Management","AuditEvidence": ["User account and access request forms","User account and access management log or screen","Access classification table for information systems and personal information processing systems","Lists of users, administrators, and personal information handlers for each information system and personal information processing system"],"AuditChecklist": ["Has the organization established and implemented formal procedures for registering, changing, and deleting user accounts and access rights to information systems, personal information, and critical information?","When creating and registering user accounts and access rights to information systems, personal information, and critical information, is access limited to the minimum necessary for each job based on the job-specific access classification system?","When granting users accounts and access rights, are they made fully aware that they are responsible for the security of those accounts?"],"NonComplianceCases": ["Case 1: User registration, termination, and approval procedures for accounts and permissions for users and personal information handlers were processed through verbal requests, email, etc., without proper approval and handling records.","Case 2: A personal information handler shared their account with an unauthorized individual for backup purposes during vacations, business trips, or other absences without going through official procedures.","Case 3: Users of information systems or personal information processing systems were granted excessive permissions, allowing access to unnecessary information or personal data."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights)"]}],"description": "To control unauthorized access to information systems, personal information, and critical information, organizations must establish and implement procedures for user registration, termination, and granting, changing, or revoking access rights, ensuring that access rights are granted only to the minimum necessary for work purposes. Additionally, when registering or granting user rights, it must be made clear to users that they are responsible for the security of their accounts.","checks_status": {"fail": 0,"pass": 0,"total": 22,"manual": 0}},"2.5.2": {"name": "User Identification","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.5.2 User Identification","Subdomain": "2.5. Authentication and Access Management","AuditEvidence": ["Login screen for information systems and personal information processing systems","Lists of administrators, users, and personal information handlers for information systems and personal information processing systems","Records of approvals for exceptions"],"AuditChecklist": ["Are unique identifiers assigned to users and personal information handlers in information systems and personal information processing systems, and is the use of easily guessable identifiers restricted?","If the same identifier is shared by multiple users for unavoidable reasons, has the justification been reviewed and have supplementary measures such as approval from the responsible party been established?"],"NonComplianceCases": ["Case 1: The account status of information systems (servers, networks, firewalls, DBMS, etc.) shows that default administrator accounts provided by the manufacturer are still in use, despite being technically modifiable.","Case 2: Developers are sharing personal information processing system accounts for common use without any justification or approval from responsible parties.","Case 3: External personnel maintaining information systems are using operational accounts like personal accounts without going through the required approval procedures."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights)"]}],"description": "User accounts must be assigned unique identifiers that distinguish each user individually, and the use of easily guessable identifiers must be restricted. If the same identifier is shared by multiple users, the reason and justification must be reviewed, supplementary measures such as approval from a responsible party must be established, and accountability must be ensured.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.5.3": {"name": "User Authentication","checks": {"iam_root_mfa_enabled": null,"iam_user_accesskey_unused": null,"iam_check_saml_providers_sts": null,"cognito_user_pool_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_hardware_mfa_enabled": null,"iam_user_two_active_access_key": null,"iam_administrator_access_with_mfa": null,"iam_user_mfa_enabled_console_access": null,"iam_user_with_temporary_credentials": null,"apigatewayv2_api_authorizers_enabled": "FAIL","iam_user_no_setup_initial_access_key": null,"apigateway_restapi_authorizers_enabled": "PASS","rds_cluster_iam_authentication_enabled": "FAIL","rds_instance_iam_authentication_enabled": "FAIL","kafka_cluster_unrestricted_access_disabled": null,"cognito_identity_pool_guest_access_disabled": "FAIL","cognito_user_pool_advanced_security_enabled": null,"cognito_user_pool_self_registration_disabled": null,"directoryservice_supported_mfa_radius_enabled": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cognito_user_pool_client_token_revocation_enabled": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cognito_user_pool_client_prevent_user_existence_errors": null,"opensearch_service_domains_internal_user_database_enabled": null,"cognito_user_pool_blocks_potential_malicious_sign_in_attempts": null,"opensearch_service_domains_use_cognito_authentication_for_kibana": null,"cognito_user_pool_blocks_compromised_credentials_sign_in_attempts": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.5.3 User Authentication","Subdomain": "2.5. Authentication and Authorization Management","AuditEvidence": ["Login screen for information systems and personal information processing systems","Login attempt limitation setting screen","Login failure message screen","Procedures for external access (e.g., external access request forms, list of external accessors)"],"AuditChecklist": ["Is access to information systems and personal information processing systems controlled through secure user authentication procedures, login attempt limitations, and warnings for illegal login attempts?","When accessing personal information processing systems from outside via a communication network, are secure authentication methods or secure access measures applied in accordance with legal requirements?"],"NonComplianceCases": ["Case 1: When a personal information handler accesses a personal information processing system through the public external internet, secure authentication methods are not applied, and authentication is done only through ID and password.","Case 2: In the login process for information systems and personal information processing systems, detailed messages are displayed about whether the ID exists or the password is incorrect, and there is no limit on login failure attempts."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights), Article 6 (Access Control)"]}],"description": "User access to information systems, personal information, and critical information must be secured through safe authentication procedures and, if necessary, enhanced authentication methods. In addition, access control measures such as limiting login attempts and issuing warnings for illegal login attempts must be established and implemented.","checks_status": {"fail": 4,"pass": 1,"total": 29,"manual": 0}},"2.5.4": {"name": "Password Management","checks": {"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_password_policy_minimum_length_14": null,"cognito_user_pool_password_policy_number": null,"cognito_user_pool_password_policy_symbol": null,"cognito_user_pool_password_policy_lowercase": null,"cognito_user_pool_password_policy_uppercase": null,"cognito_user_pool_temporary_password_expiration": null,"cognito_user_pool_password_policy_minimum_length_14": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.5.4 Password Management","Subdomain": "2.5. Authentication and Authorization Management","AuditEvidence": ["Password setting screens for web pages, information systems, and personal information processing systems","Password management policies and procedures"],"AuditChecklist": ["Are procedures for managing and creating secure user passwords for information systems established and implemented?","Are password creation rules established and enforced to ensure that users can use secure passwords?","Are authentication methods for personal information handlers and users securely applied and managed?"],"NonComplianceCases": ["Case 1: Although password creation rules are set in policies and guidelines related to information protection and personal information protection, some information systems and personal information processing systems use passwords that differ from internal guidelines.","Case 2: Internal regulations state that when passwords are reset, temporary passwords must be assigned and forced to be changed, but in practice, temporary passwords are being used without change.","Case 3: Although internal regulations require users and personal information handlers to change their passwords periodically, passwords are being used without change."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights)"]}],"description": "Procedures for managing passwords used by users of information systems, as well as customers and members, must be established and implemented, taking into account legal requirements and external threats.","checks_status": {"fail": 0,"pass": 0,"total": 13,"manual": 0}},"2.5.5": {"name": "Management of Special Accounts and Privileges","checks": {"iam_avoid_root_usage": null,"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_support_role_created": null,"rds_cluster_default_admin": "FAIL","rds_instance_default_admin": "FAIL","ec2_instance_profile_attached": "PASS","iam_root_hardware_mfa_enabled": null,"organizations_delegated_administrators": null,"cloudwatch_log_metric_filter_root_usage": null,"sagemaker_notebook_instance_root_access_disabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measures Requirements","Section": "2.5.5 Management of Special Accounts and Privileges","Subdomain": "2.5. Authentication and Privilege Management","AuditEvidence": ["Guidelines related to special privileges","Records of special privilege requests and approvals","List of special privilege holders","Records of special privilege reviews"],"AuditChecklist": ["Is there a formal privilege request and approval process established and implemented to ensure that special privileges, such as administrative privileges, are only granted to a minimal number of people?","Is there a control procedure established and implemented to identify and manage accounts and privileges granted for special purposes in a separate list?"],"NonComplianceCases": ["Case 1: The approval history for granting administrator and special privileges in the information system and personal information processing system is not documented or does not match the special privileges list.","Case 2: Internal regulations require that personal information administrators and special privilege holders be documented and managed in a list, but the list is not maintained or some special privileges, such as security system administrators, are not identified or managed.","Case 3: A maintenance special account for visiting maintenance once a quarter remains active at all times without a time limit on usage.","Case 4: Regular reviews of administrator and special privilege usage are not conducted, and some individuals retain special privileges even after their roles have changed."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights)"]}],"description": "Accounts and privileges used for special purposes, such as managing information systems, personal information, and important information, should be granted minimally, separately identified, and controlled.","checks_status": {"fail": 2,"pass": 1,"total": 11,"manual": 0}},"2.5.6": {"name": "Review of Access Rights","checks": {"accessanalyzer_enabled": "PASS","cloudtrail_insights_exist": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","accessanalyzer_enabled_without_findings": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_cross_account_sharing_disabled": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cloudtrail_multi_region_enabled_logging_management_events": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measures Requirements","Section": "2.5.6 Review of Access Rights","Subdomain": "2.5. Authentication and Privilege Management","AuditEvidence": ["Access rights review standards and procedures","History of access rights reviews","Access rights review reports and follow-up action records"],"AuditChecklist": ["Are the histories of account and access right creation, registration, granting, use, modification, and deletion for information systems, personal information, and important information being recorded?","Are standards, review subjects, review methods, and periodic review schedules established to regularly review the appropriateness of user accounts and access rights to information systems, personal information, and important information?","When issues such as excessive access rights, failure to follow access right granting procedures, or misuse of access rights are identified in the review results, are appropriate response procedures established and implemented?"],"NonComplianceCases": ["Case 1: The methods, review periods, reporting structure, and misuse criteria related to access rights reviews are not clearly defined in the relevant guidelines, leading to irregular performance of access rights reviews.","Case 2: Although internal policies and guidelines require locking (deactivating) or deleting long-unused accounts, some accounts that have not been accessed for more than six months remain active (indicating that the access rights review was not thoroughly conducted, failing to identify these accounts).","Case 3: During the access rights review, cases of excessive privileges or suspected misuse were identified, but no detailed investigation, internal reporting, or follow-up actions were taken."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights)"]}],"description": "The registration, use, and deletion of user accounts accessing information systems, personal information, and important information, as well as the history of granting, changing, and deleting access rights, should be recorded and periodically reviewed to ensure their appropriateness.","checks_status": {"fail": 2,"pass": 1,"total": 14,"manual": 0}},"2.6.1": {"name": "Network Access","checks": {"ec2_ami_public": null,"elb_internet_facing": "FAIL","ec2_elastic_ip_shodan": null,"elbv2_internet_facing": "PASS","ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","kafka_cluster_is_public": null,"s3_bucket_acl_prohibited": "FAIL","apigateway_restapi_public": "FAIL","lightsail_database_public": null,"lightsail_instance_public": null,"ec2_securitygroup_not_used": "FAIL","elbv2_listeners_underneath": "PASS","networkfirewall_in_all_vpc": "FAIL","s3_bucket_public_write_acl": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","ssm_documents_set_as_public": "PASS","awslambda_function_url_public": null,"dms_instance_no_public_access": null,"rds_instance_no_public_access": "PASS","emr_cluster_publicly_accesible": null,"redshift_cluster_public_access": null,"neptune_cluster_public_snapshot": null,"eks_cluster_private_nodes_enabled": null,"awslambda_function_url_cors_policy": null,"documentdb_cluster_public_snapshot": null,"eks_cluster_network_policy_enabled": null,"neptune_cluster_uses_public_subnet": null,"sns_topics_not_publicly_accessible": "PASS","sqs_queues_not_publicly_accessible": "PASS","vpc_subnet_no_public_ip_by_default": "FAIL","vpc_subnet_separate_private_public": "FAIL","eks_cluster_not_publicly_accessible": null,"glacier_vaults_policy_public_access": null,"iam_user_mfa_enabled_console_access": null,"s3_access_point_public_access_block": "PASS","s3_bucket_level_public_access_block": "PASS","iam_user_administrator_access_policy": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"iam_group_administrator_access_policy": null,"s3_account_level_public_access_blocks": null,"apigateway_restapi_authorizers_enabled": "PASS","elasticache_cluster_uses_public_subnet": "PASS","rds_instance_iam_authentication_enabled": "FAIL","appstream_fleet_maximum_session_duration": null,"ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ecr_repositories_not_publicly_accessible": "PASS","emr_cluster_account_public_block_enabled": "PASS","sagemaker_models_vpc_settings_configured": null,"apigateway_restapi_public_with_authorizer": "FAIL","ec2_instance_port_ftp_exposed_to_internet": "PASS","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","vpc_endpoint_connections_trust_boundaries": "FAIL","appstream_fleet_session_disconnect_timeout": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_instance_port_cifs_exposed_to_internet": "PASS","ec2_instance_port_ldap_exposed_to_internet": "PASS","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","kafka_cluster_unrestricted_access_disabled": null,"sagemaker_models_network_isolation_enabled": null,"cognito_identity_pool_guest_access_disabled": "FAIL","ec2_instance_port_kafka_exposed_to_internet": "PASS","ec2_instance_port_mysql_exposed_to_internet": "PASS","ec2_instance_port_redis_exposed_to_internet": "PASS","workspaces_vpc_2private_1public_subnets_nat": null,"ec2_instance_port_oracle_exposed_to_internet": "PASS","ec2_instance_port_telnet_exposed_to_internet": "PASS","ec2_instance_port_mongodb_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_instance_port_kerberos_exposed_to_internet": "PASS","ec2_transitgateway_auto_accept_vpc_attachments": null,"appstream_fleet_session_idle_disconnect_timeout": null,"ec2_instance_port_cassandra_exposed_to_internet": "PASS","ec2_instance_port_memcached_exposed_to_internet": "PASS","ec2_instance_port_sqlserver_exposed_to_internet": "PASS","rds_instance_event_subscription_security_groups": "FAIL","sagemaker_training_jobs_vpc_settings_configured": null,"vpc_peering_routing_tables_with_least_privilege": "PASS","appstream_fleet_default_internet_access_disabled": null,"ec2_instance_port_postgresql_exposed_to_internet": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","cloudfront_distributions_geo_restrictions_enabled": null,"sagemaker_training_jobs_network_isolation_enabled": null,"opensearch_service_domains_not_publicly_accessible": null,"sagemaker_notebook_instance_vpc_settings_configured": null,"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","vpc_endpoint_services_allowed_principals_trust_boundaries": null,"ec2_instance_port_elasticsearch_kibana_exposed_to_internet": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","cognito_user_pool_blocks_potential_malicious_sign_in_attempts": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Control Measures","Section": "2.6.1 Network Access","Subdomain": "2.6. Access Control","AuditEvidence": ["Network diagram","IP management ledger","Information asset list","Firewall rules"],"AuditChecklist": ["Has the organization identified all access paths to its network and ensured that internal networks are controlled so that only authorized users can access them according to the access control policy?","Has the organization physically or logically segmented the network based on services, user groups, information asset importance, and legal requirements, and applied access control between different network segments?","Has the organization established IP address allocation standards for each network segment, and applied measures such as assigning private IPs to systems like database servers that do not require external connections?","Has the organization implemented protective measures for communication paths when connecting networks between physically separated locations, such as IDCs, branches, and agents?"],"NonComplianceCases": ["Case 1: The network configuration and interviews revealed that data transmission and reception between external sites and the servers located in the IDC are being processed through the general internet line, rather than using VPN or dedicated lines as specified in internal regulations.","Case 2: The IP addresses of some important servers, such as database servers located in the internal network, were set to public IPs instead of private IPs as per internal regulations, and network access blocking was not applied.","Case 3: Although a server farm was established, access from the internal network to the server farm was excessively allowed due to insufficient network access control settings.","Case 4: The network provided to external parties (e.g., external developers, visitors) was not separated from the internal business network without appropriate controls.","Case 5: Contrary to internal regulations, the organization's network could be accessed and used simply by connecting a network cable without applying protective measures such as MAC address authentication and mandatory security software installation."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 6 (Access Control)"]}],"description": "In order to control unauthorized access to the network, management procedures such as IP management and device authentication must be established and implemented. Network segmentation (DMZ, server farm, DB zone, development zone, etc.) and access controls must be applied according to the business purpose and importance.","checks_status": {"fail": 17,"pass": 54,"total": 112,"manual": 0}},"2.6.2": {"name": "Access to Information Systems","checks": {"ec2_elastic_ip_shodan": null,"ec2_instance_public_ip": "FAIL","ec2_elastic_ip_unassigned": "FAIL","lightsail_instance_public": null,"lightsail_static_ip_unused": null,"ec2_instance_managed_by_ssm": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_instance_port_ftp_exposed_to_internet": "PASS","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_instance_port_telnet_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","ec2_instance_internet_facing_with_instance_profile": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Protection Requirements","Section": "2.6.2 Access to Information Systems","Subdomain": "2.6. Access Control","AuditEvidence": ["List of operating system accounts of information systems","Server security settings","Server access control policy (e.g., SecureOS management screen)","Server and network configuration diagram","Information asset list"],"AuditChecklist": ["Have users, access locations, and access means allowed to access operating systems (OS) of information systems such as servers, network systems, and security systems been defined and controlled?","Is the system automatically disconnected when there is no work processed after accessing the information system for a certain period?","Are services unrelated to the purpose of using the information system removed?","Are information systems that provide key services operated on independent servers?"],"NonComplianceCases": ["Case 1: When a server administrator accesses a Windows server located in the IDC from the office using terminal services, session timeout settings are not configured, allowing the session to remain open for a long period without any activity.","Case 2: Due to improper restrictions on server-to-server access, a user authorized to access a particular server can access other unauthorized servers via that server.","Case 3: Unsafe access protocols (e.g., telnet, ftp) are being used without valid reasons or compensatory measures, and unnecessary services and ports are open.","Case 4: Although the access control policy requires all access to servers to go through a server access control system, bypass routes exist that allow access to servers without going through the system."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 6 (Access Control)"]}],"description": "The users, access restriction methods, and secure access means for accessing information systems such as servers and network systems must be defined and controlled.","checks_status": {"fail": 8,"pass": 13,"total": 24,"manual": 0}},"2.6.3": {"name": "Access to Applications","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Requirements","Section": "2.6.3 Access to Applications","Subdomain": "2.6. Access Control","AuditEvidence": ["Application access rights classification system","Application account and rights management screen","Application user and administrator screens (e.g., personal information viewing, etc.)","Application session time and concurrent session restriction settings","Application administrator access log monitoring details","Information asset list","Personal information processing system's personal information viewing and search screens","Personal information masking standards","Personal information masking application screen"],"AuditChecklist": ["Are access rights to applications granted differentially based on the user's tasks to control access to sensitive information?","Are sessions automatically disconnected after a certain period of inactivity, and is the number of simultaneous sessions per user restricted?","Is access to administrator-exclusive applications (e.g., admin web pages, admin consoles) restricted to unauthorized users?","Are criteria established and applied to ensure consistency in protection measures for limiting the display of personal and sensitive information?","Are applications implemented and operated to minimize unnecessary exposure (e.g., viewing, screen display, printing, downloading) of personal and sensitive information?"],"NonComplianceCases": ["Case 1: There is a flaw in the authorization control function of certain personal information processing screens in the application, allowing users without permission to view personal information.","Case 2: The administrator page of the application is open to the public internet without secure authentication methods applied.","Case 3: Session timeouts or concurrent logins for the same user account are not restricted without valid reasons.","Case 4: When personal information is downloaded through the application, the file contains excessive unnecessary information such as resident registration numbers.","Case 5: The application excessively allows 'like' searches, allowing all users to retrieve all customer information by searching only for a surname, even beyond their work scope.","Case 6: Due to the lack of criteria for limiting the display of personal information or failure to adhere to them, different masking standards are applied to the same personal information items on different screens of the personal information processing system.","Case 7: Although personal information is masked on the screen of the personal information processing system, unmasked personal information is exposed by viewing the web browser source."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights), Article 6 (Access Control), Article 12 (Safety Measures for Printing and Copying)"]}],"description": "Access rights to applications must be restricted according to the user's tasks and the importance of the accessed information, and criteria should be established to minimize exposure of unnecessary or sensitive information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.6.4": {"name": "Database Access","checks": {"accessanalyzer_enabled": "PASS","lightsail_database_public": null,"rds_snapshots_public_access": "PASS","dms_instance_no_public_access": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"neptune_cluster_public_snapshot": null,"rds_instance_transport_encrypted": "FAIL","documentdb_cluster_public_snapshot": null,"neptune_cluster_uses_public_subnet": null,"vpc_subnet_separate_private_public": "FAIL","dynamodb_table_cross_account_access": null,"rds_cluster_iam_authentication_enabled": "FAIL","accessanalyzer_enabled_without_findings": "FAIL","rds_instance_iam_authentication_enabled": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","neptune_cluster_iam_authentication_enabled": null,"ec2_instance_port_mysql_exposed_to_internet": "PASS","ec2_instance_port_redis_exposed_to_internet": "PASS","ec2_instance_port_oracle_exposed_to_internet": "PASS","ec2_instance_port_mongodb_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_instance_port_cassandra_exposed_to_internet": "PASS","ec2_instance_port_sqlserver_exposed_to_internet": "PASS","opensearch_service_domains_not_publicly_accessible": null,"opensearch_service_domains_https_communications_enforced": null,"opensearch_service_domains_internal_user_database_enabled": null,"ec2_instance_port_elasticsearch_kibana_exposed_to_internet": "PASS","opensearch_service_domains_use_cognito_authentication_for_kibana": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Protection Measures Requirements","Section": "2.6.4 Database Access","Subdomain": "2.6. Access Control","AuditEvidence": ["Database status (e.g., tables, columns)","List of database user accounts and permissions","Database access control policy (e.g., database access control system management screen)","Network diagram (e.g., database zone)","Information asset list"],"AuditChecklist": ["Are you identifying the information stored and managed in the database, such as the table list?","Are you clearly identifying the applications, information systems (servers), and users that need access to information in the database and controlling access according to the access control policy?"],"NonComplianceCases": ["Case 1: A database that stores and processes a large amount of personal information is operated on the same physical server as a web application accessible via the Internet, without separating them.","Case 2: Developers and operators share accounts used by the application to access the production database.","Case 3: Although internal regulations require database access rights to be restricted by object, access rights to the database are granted uniformly to administrators, even those who do not need access to personal information tables.","Case 4: A database access control solution has been implemented, but access to the database is not properly restricted by IP address, allowing users to bypass the access control solution.","Case 5: The table status of a database storing personal information has not been identified, resulting in the unnecessary retention of personal information in temporary tables that have not been deleted."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 5 (Management of Access Rights), Article 6 (Access Control)"]}],"description": "Identify the information stored and managed in the database, such as the table list, and establish and implement access control policies according to the importance of the information and the type of applications and users.","checks_status": {"fail": 6,"pass": 19,"total": 37,"manual": 0}},"2.6.5": {"name": "Wireless Network Access","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measures Requirements","Section": "2.6.5 Wireless Network Access","Subdomain": "2.6. Access Control","AuditEvidence": ["Network diagram","AP security settings history","Inspection records of unauthorized wireless networks","Wireless network usage application and approval records"],"AuditChecklist": ["When using a wireless network for business purposes, are you establishing and implementing protection measures such as authentication and encryption of transmitted and received data to ensure the security of the wireless AP and network segment?","Have you established and implemented procedures for applying for and terminating access to ensure that only authorized employees can use the wireless network?","Have you established and implemented protection measures against unauthorized wireless networks, such as detecting and blocking AD Hoc connections and unauthorized wireless APs within the organization?"],"NonComplianceCases": ["Case 1: The wireless network segments for external users and internal users are the same, allowing external users to access the internal network without separate control via the wireless network.","Case 2: Although the encryption function for information transmission and reception was enabled when configuring the wireless AP, it was set in an insecure manner.","Case 3: A wireless AP connected to the internal network for business purposes has security settings that are insufficient, such as exposure of the administrator password (using the default password) and lack of access control."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 6 (Access Control)"]}],"description": "When using a wireless network, wireless network protection measures such as user authentication, encryption of transmitted and received data, and AP control must be applied. In addition, protection measures must be established and implemented to prevent unauthorized wireless network access, such as AD Hoc connections and the use of unauthorized APs.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.6.6": {"name": "Remote Access Control","checks": {"vpc_flow_logs_enabled": "FAIL","networkfirewall_in_all_vpc": "FAIL","cognito_user_pool_mfa_enabled": null,"iam_user_console_access_unused": null,"vpc_subnet_no_public_ip_by_default": "FAIL","vpc_subnet_separate_private_public": "FAIL","iam_user_mfa_enabled_console_access": null,"workspaces_volume_encryption_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","appstream_fleet_maximum_session_duration": null,"ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","appstream_fleet_session_disconnect_timeout": null,"ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","cognito_identity_pool_guest_access_disabled": "FAIL","workspaces_vpc_2private_1public_subnets_nat": null,"cognito_user_pool_self_registration_disabled": null,"appstream_fleet_session_idle_disconnect_timeout": null,"appstream_fleet_default_internet_access_disabled": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"ec2_client_vpn_endpoint_connection_logging_enabled": null,"cloudwatch_log_metric_filter_authentication_failures": null,"ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Protective Measures Requirements","Section": "2.6.6 Remote Access Control","Subdomain": "2.6. Access Control","AuditEvidence": ["Remote access application form (e.g., VPN)","VPN account list","VPN access control policy settings","IP management log","Remote access control settings (server settings, security system settings, etc.)","Designation and management of management terminals","Network diagram"],"AuditChecklist": ["Is remote operation of information systems through external networks such as the internet prohibited in principle, and are compensatory measures in place if allowed for unavoidable reasons such as incident response?","Is access through remote operation of information systems allowed only for specific devices when done through internal networks?","Are protective measures established and implemented to prevent security incidents such as data breaches and hacking during remote work, such as telecommuting, remote collaboration, and smart work?","Are the devices used for remote access to personal information processing systems for management, operation, development, and security purposes designated as management terminals, and are safety measures such as prohibiting unauthorized operations and use for purposes other than those intended being applied?"],"NonComplianceCases": ["Case 1: Although internal regulations state that remote access to the system is prohibited in principle and, when allowed, access is restricted through IP-based access control, remote desktop connections and SSH access to the system are not limited by IP addresses, allowing access from any PC.","Case 2: A VPN has been established for remote management, but it is always available without usage approval or access period restrictions.","Case 3: Work-related mobile apps have been installed on personal smart devices for external workers, but appropriate protective measures (e.g., antivirus, encryption, wiping in case of loss or theft) to prevent personal information leaks are not being applied.","Case 4: VPN access for external users is not limited by network segments and information systems, allowing excessive access to the entire internal network and information systems for authenticated remote users."],"RelatedRegulations": ["Personal Information Protection Act Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information Article 6 (Access Control)"]}],"description": "Managing information systems and handling personal information outside of protected areas is, in principle, prohibited. However, if remote access is allowed for unavoidable reasons such as telecommuting, incident response, or remote collaboration, protective measures must be established and implemented, including approval from responsible personnel, designation of access devices, setting access scope and duration, enhanced authentication, encrypted communication, and securing access devices (e.g., antivirus, patches).","checks_status": {"fail": 8,"pass": 5,"total": 26,"manual": 0}},"2.6.7": {"name": "Internet Access Control","checks": {"ec2_elastic_ip_shodan": null,"vpc_flow_logs_enabled": "FAIL","ec2_instance_public_ip": "FAIL","ec2_elastic_ip_unassigned": "FAIL","networkfirewall_in_all_vpc": "FAIL","vpc_subnet_no_public_ip_by_default": "FAIL","vpc_subnet_separate_private_public": "FAIL","workspaces_volume_encryption_enabled": null,"route53_dangling_ip_subdomain_takeover": null,"appstream_fleet_maximum_session_duration": null,"appstream_fleet_session_disconnect_timeout": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"workspaces_vpc_2private_1public_subnets_nat": null,"ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","appstream_fleet_session_idle_disconnect_timeout": null,"appstream_fleet_default_internet_access_disabled": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Domain": "2. Protective Measures Requirements","Section": "2.6.7 Internet Access Control","Subdomain": "2.6. Access Control","AuditEvidence": ["Policy for blocking non-work-related sites (e.g., P2P) (management screen of non-work-related site blocking system)","Internet access monitoring history","List of individuals subject to internet access restriction measures","Procedures and records for data transfer between networks (e.g., application and approval records)","Network diagram"],"AuditChecklist": ["Is there an established and implemented policy to control internet access for work PCs used for key duties and personal information handling terminals?","Is unnecessary external internet access from key information systems (e.g., database servers) being controlled?","Are internet access restrictions being applied in a secure manner for individuals who are required by law to have their internet access restricted?"],"NonComplianceCases": ["Case 1: Internet access restriction measures were applied according to the Personal Information Protection Act, but the restriction was not applied to some individuals with the authority to set access rights for personal information processing systems.","Case 2: Although internet access restriction measures were applied as required under the Personal Information Protection Act, it was possible to bypass the restriction by accessing the system through another server, allowing the download and deletion of personal information.","Case 3: Some servers located in the DMZ and internal network were unnecessarily able to access the internet directly.","Case 4: Although a physical network separation system was applied between internet PCs and internal work PCs, and a data transfer system was established, there was no approval process for data transfers, and there was no periodic review of the data transfer records.","Case 5: Internal regulations require that individuals handling personal information obtain approval from a responsible person before accessing P2P or web hard drive sites, and access is only permitted for a specific period, but there are numerous cases of exceptions being made without going through the approval process."],"RelatedRegulations": ["Personal Information Protection Act Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information Article 6 (Access Control)"]}],"description": "To prevent information leaks, malware infections, and intrusions into the internal network through the internet, policies must be established and implemented to restrict internet access or services (e.g., P2P, web hard drives, messengers) on key information systems, devices handling sensitive duties, and terminals processing personal information.","checks_status": {"fail": 6,"pass": 1,"total": 19,"manual": 0}},"2.7.1": {"name": "Application of Encryption Policy","checks": {"elb_ssl_listeners": "FAIL","backup_vaults_exist": null,"elbv2_ssl_listeners": "FAIL","ssm_document_secrets": "PASS","backup_vaults_encrypted": "PASS","rds_snapshots_encrypted": "FAIL","elb_insecure_ssl_ciphers": "PASS","s3_bucket_kms_encryption": "FAIL","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","elbv2_insecure_ssl_ciphers": "PASS","athena_workgroup_encryption": null,"ec2_ebs_snapshots_encrypted": "FAIL","s3_bucket_default_encryption": "PASS","ec2_instance_secrets_user_data": "PASS","ec2_launch_template_no_secrets": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","rds_instance_transport_encrypted": "FAIL","cloudtrail_kms_encryption_enabled": "FAIL","neptune_cluster_storage_encrypted": null,"s3_bucket_secure_transport_policy": "FAIL","documentdb_cluster_storage_encrypted": null,"workspaces_volume_encryption_enabled": null,"awslambda_function_no_secrets_in_code": "PASS","glue_database_connections_ssl_enabled": null,"athena_workgroup_enforce_configuration": null,"cloudfront_distributions_https_enabled": null,"cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudformation_stack_outputs_find_secrets": "PASS","codebuild_project_no_secrets_in_variables": "PASS","kafka_cluster_encryption_at_rest_uses_cmk": null,"sns_subscription_not_using_http_endpoints": "PASS","sns_topics_kms_encryption_at_rest_enabled": "FAIL","sqs_queues_server_side_encryption_enabled": "PASS","awslambda_function_no_secrets_in_variables": "PASS","dynamodb_tables_kms_cmk_encryption_enabled": null,"glue_etl_jobs_amazon_s3_encryption_enabled": "PASS","acm_certificates_with_secure_key_algorithms": "PASS","cloudwatch_log_group_kms_encryption_enabled": "FAIL","ecs_task_definitions_no_environment_secrets": "PASS","kafka_cluster_in_transit_encryption_enabled": null,"storagegateway_fileshare_encryption_enabled": null,"apigateway_restapi_client_certificate_enabled": "FAIL","glue_etl_jobs_job_bookmark_encryption_enabled": "FAIL","glue_data_catalogs_metadata_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"kafka_cluster_mutual_tls_authentication_enabled": null,"directoryservice_radius_server_security_protocol": null,"glue_development_endpoints_s3_encryption_enabled": null,"glue_etl_jobs_cloudwatch_logs_encryption_enabled": "FAIL","autoscaling_find_secrets_ec2_launch_configuration": "PASS","eks_cluster_kms_cmk_encryption_in_secrets_enabled": null,"elasticache_redis_cluster_rest_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"cloudfront_distributions_field_level_encryption_enabled": null,"cloudfront_distributions_using_deprecated_ssl_protocols": null,"elasticache_redis_cluster_in_transit_encryption_enabled": null,"opensearch_service_domains_https_communications_enforced": null,"sagemaker_training_jobs_intercontainer_encryption_enabled": null,"glue_data_catalogs_connection_passwords_encryption_enabled": "FAIL","glue_development_endpoints_job_bookmark_encryption_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null,"sagemaker_training_jobs_volume_and_output_encryption_enabled": null,"glue_development_endpoints_cloudwatch_logs_encryption_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measures Requirements","Section": "2.7.1 Application of Encryption Policy","Subdomain": "2.7. Application of Encryption","AuditEvidence": ["Encryption control policy (targets, methods, algorithms, etc.)","Encryption application status (during storage and transmission)","Risk analysis results (if encryption is not applied to unique identifiers other than resident registration numbers in the internal network)","Encryption solution management screen"],"AuditChecklist": ["Has an encryption policy been established that includes encryption targets, encryption strength, and encryption usage in consideration of legal requirements for the protection of personal and important information?","Is encryption applied to personal and important information during storage, transmission, and transfer according to the encryption policy?"],"NonComplianceCases": ["Case 1: Internal policies and guidelines do not properly specify encryption targets, encryption strength, encryption methods during storage and transmission, or the roles and responsibilities of those responsible for encryption, considering legal requirements.","Case 2: The company applied incorrect regulations during the creation of its encryption policy, leading to non-compliance with legal encryption requirements (e.g., storing user account numbers without encryption).","Case 3: Although one-way encryption was applied to the passwords of both personal information handlers and data subjects, an insecure MD5 algorithm was used.","Case 4: Although a security server was applied to an internet shopping mall in accordance with relevant laws and internal regulations, encryption was missing in some sections where users' personal information is transmitted (e.g., viewing or modifying member information, password retrieval, password changes).","Case 5: Passwords for accessing information systems, authentication keys, and other values were stored in plaintext in system configuration files and source code."],"RelatedRegulations": ["Personal Information Protection Act, Article 24-2 (Restrictions on Processing of Resident Registration Numbers), Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 7 (Encryption of Personal Information)"]}],"description": "To protect personal and important information, encryption policies that reflect legal requirements, such as encryption targets, encryption strength, and encryption usage policies, must be established. Encryption must be applied during the storage, transmission, and transfer of personal and important information.","checks_status": {"fail": 18,"pass": 19,"total": 66,"manual": 0}},"2.7.2": {"name": "Cryptographic Key Management","checks": {"kms_cmk_are_used": null,"kms_cmk_rotation_enabled": null,"kms_key_not_publicly_accessible": null,"kms_cmk_not_deleted_unintentionally": null,"rds_instance_certificate_expiration": "PASS","secretsmanager_automatic_rotation_enabled": "FAIL","acm_certificates_transparency_logs_enabled": "PASS","directoryservice_ldap_certificate_expiration": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "FAIL","attributes": [{"Domain": "2. Security Control Requirements","Section": "2.7.2 Cryptographic Key Management","Subdomain": "2.7. Application of Encryption","AuditEvidence": ["Cryptographic Key Management Policy","Cryptographic Key Management Log and System Screens"],"AuditChecklist": ["Are procedures for the generation, use, storage, distribution, modification, recovery, and destruction of cryptographic keys established and implemented?","Are cryptographic keys securely stored in a separate location to ensure they can be recovered if necessary, and is access to the use of cryptographic keys minimized?"],"NonComplianceCases": ["Case 1: If encryption policies do not specify procedures and methods for managing cryptographic keys, leading to varying levels and methods of cryptographic key management among personnel, resulting in vulnerabilities.","Case 2: Internal regulations require the generation of encryption keys under the approval of a responsible person when encrypting important information, and to maintain a key management log, but some keys are either missing or outdated in the log.","Case 3: The encryption key applied in the development system is the same as the one applied in the production system, making it easy to decrypt actual data through the development system."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 7 (Encryption of Personal Information)"]}],"description": "Establish and implement management procedures for the secure generation, use, storage, distribution, and destruction of cryptographic keys, and prepare recovery methods if necessary.","checks_status": {"fail": 1,"pass": 2,"total": 9,"manual": 0}},"2.8.1": {"name": "Definition of Security Requirements","checks": {"macie_is_enabled": "PASS","securityhub_enabled": "PASS","fms_policy_compliant": null,"guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","accessanalyzer_enabled": "PASS","networkfirewall_in_all_vpc": "FAIL","guardduty_centrally_managed": "FAIL","wafv2_webacl_logging_enabled": "FAIL","config_recorder_all_regions_enabled": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","codebuild_project_no_secrets_in_variables": "PASS","codebuild_project_user_controlled_buildspec": "PASS","wellarchitected_workload_no_high_or_medium_risks": "FAIL","codebuild_project_source_repo_url_no_sensitive_credentials": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Security Control Requirements","Section": "2.8.1 Definition of Security Requirements","Subdomain": "2.8. Security for Information System Introduction and Development","AuditEvidence": ["Information System Acquisition Standards and Procedures","RFP (Request for Proposal) and Purchase Contracts for Information System Introduction","Development Outputs (Project Execution Plans, Requirements Definition, Screen Design, Security Architecture Design, Test Plans, etc.)","Secure Coding Standards"],"AuditChecklist": ["When introducing, developing, or modifying an information system, are procedures for reviewing the validity of information protection and personal information protection aspects and for acquisition established and implemented?","When introducing, developing, or modifying an information system, are security requirements, including legal requirements and the latest vulnerabilities, clearly defined and reflected from the design stage?","Are coding standards for secure implementation of the information system established and applied?"],"NonComplianceCases": ["Case 1: Lack of established security verification standards and procedures prior to acquiring an information system.","Case 2: Internal regulations require the review of the security impact and the operating environment when introducing a new system, but recent acquisitions of some information systems lacked detailed standards and plans, and therefore, no security review was conducted during the acquisition.","Case 3: Internal development guidelines do not define key security requirements related to development (authentication and encryption, security logging, etc.).","Case 4: In the 'Development Standards Definition Document', user passwords are to be encrypted using insecure algorithms (MD5, SHA1), resulting in failure to comply with relevant legal requirements."],"RelatedRegulations": []}],"description": "When introducing, developing, or modifying information systems, security requirements such as legal requirements related to information protection and personal information protection, the latest security vulnerabilities, and secure coding methods must be defined and applied.","checks_status": {"fail": 7,"pass": 7,"total": 16,"manual": 0}},"2.8.2": {"name": "Review and Testing of Security Requirements","checks": {"macie_is_enabled": "PASS","securityhub_enabled": "PASS","fms_policy_compliant": null,"guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","accessanalyzer_enabled": "PASS","networkfirewall_in_all_vpc": "FAIL","guardduty_centrally_managed": "FAIL","wafv2_webacl_logging_enabled": "FAIL","inspector2_active_findings_exist": "FAIL","config_recorder_all_regions_enabled": null,"guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","accessanalyzer_enabled_without_findings": "FAIL","codebuild_project_no_secrets_in_variables": "PASS","codebuild_project_user_controlled_buildspec": "PASS","wellarchitected_workload_no_high_or_medium_risks": "FAIL","codebuild_project_source_repo_url_no_sensitive_credentials": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Security Control Requirements","Section": "2.8.2 Review and Testing of Security Requirements","Subdomain": "2.8. Security for Information System Introduction and Development","AuditEvidence": ["Information System Acceptance Test Results","Requirements Traceability Matrix","Test Plans, Test Results","Vulnerability Assessment Results","Personal Information Impact Assessment Report","Confirmation of Implementation of Corrective Actions for Personal Information Impact Assessment"],"AuditChecklist": ["When introducing, developing, or modifying an information system, are tests conducted to verify whether the security requirements defined during the analysis and design stages have been effectively applied?","Are vulnerability assessments conducted to confirm that the information system has been securely developed according to secure coding standards?","Are procedures established and implemented to ensure that issues identified during testing and vulnerability assessments are promptly addressed through corrective action plans and follow-up checks?","For public institutions, are impact assessments conducted during the analysis and design stages when developing or modifying personal information processing systems, as required by relevant laws, and are the results reflected during development and modification?"],"NonComplianceCases": ["Case 1: Failure to test security requirements defined in internal guidelines and documents after implementing an information system.","Case 2: In the application program test scenario and technical vulnerability checklist, important validation items such as input validation checks were omitted.","Case 3: Failure to assess whether known technical vulnerabilities exist during implementation or testing, or failure to address identified vulnerabilities without valid reasons or approval.","Case 4: A public institution failed to conduct an impact assessment when developing a personal information file or personal information processing system subject to an impact assessment requirement, such as processing unique identifiers of more than 50,000 data subjects.","Case 5: A public institution failed to submit the impact assessment report to the Personal Information Protection Commission within two months after receiving the report from the impact assessment agency.","Case 6: Internal guidelines require reviewing the security and impact on the operating environment when introducing a new system (e.g., vulnerability assessments), but recent acquisitions of some information systems lacked security reviews during the acceptance process."],"RelatedRegulations": ["Personal Information Protection Act, Article 33 (Personal Information Impact Assessment)","Notification on Personal Information Impact Assessment"]}],"description": "To verify that an information system has been introduced or implemented according to predefined security requirements, review standards and procedures must be established and implemented to check compliance with legal requirements, the latest security vulnerabilities, secure coding implementation, and personal information impact assessment, and corrective measures must be taken for any identified issues.","checks_status": {"fail": 10,"pass": 7,"total": 19,"manual": 0}},"2.8.3": {"name": "Separation of Test and Production Environments","checks": {"codebuild_project_user_controlled_buildspec": "PASS"},"status": "PASS","attributes": [{"Domain": "2. Security Requirements for Protection Measures","Section": "2.8.3 Separation of Test and Production Environments","Subdomain": "2.8. Security for Information System Introduction and Development","AuditEvidence": ["Network diagrams (including test environment configuration)","Current application of access control between the production environment and the development/test environment"],"AuditChecklist": ["Are development and test systems separated from the production system?","If separation of development and production environments is difficult due to unavoidable reasons, have security measures such as mutual review, monitoring by supervisors, approval for changes, and ensuring accountability been implemented?"],"NonComplianceCases": ["Case 1: Source code changes are being made directly in the production environment without a separate development environment or proper approval.","Case 2: Although it is unavoidable to operate the development and production systems without separation, records of mutual review or monitoring are missing.","Case 3: Although a separate development system is in place, access from the development environment to the production environment is not controlled, allowing developers unnecessary access to the production system through the development system."],"RelatedRegulations": []}],"description": "Development and test systems must, in principle, be separated from production systems to reduce the risk of unauthorized access and changes to the production system.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.8.4": {"name": "Test Data Security","checks": {"codebuild_project_no_secrets_in_variables": "PASS"},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.8.4 Test Data Security","Subdomain": "2.8. Security in Information System Introduction and Development","AuditEvidence": ["Test data status","Test data generation rules","If operational data was used in a test environment, the approval history"],"AuditChecklist": ["Is the use of actual operational data restricted during the development and testing of information systems?","If it is inevitable to use operational data in a test environment, are control procedures such as approval by the responsible person, monitoring of access and leakage, and deletion of data after testing established and implemented?"],"NonComplianceCases": ["Case 1: There are no specific standards and procedures established for generating test data for use on the development server.","Case 2: Operational data is being used as test data without proper processing and without approval from the responsible person for a valid reason.","Case 3: Although operational data was approved in advance for use as test data for unavoidable reasons, the same level of access control as the operational database is not applied to the test database.","Case 4: After using operational data for testing purposes, the data was not deleted from the test database even though the testing was completed."],"RelatedRegulations": []}],"description": "In order to prevent the leakage of operational data during system testing, procedures for the creation, use, management, disposal, and technical protection measures of test data must be established and implemented.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.8.5": {"name": "Source Program Management","checks": {"ecr_repositories_not_publicly_accessible": "PASS","codeartifact_packages_external_public_publishing_disabled": null},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.8.5 Source Program Management","Subdomain": "2.8. Security in Information System Introduction and Development","AuditEvidence": ["Status of configuration management systems such as SVN (e.g., list of authorized personnel)","History of changes to the source program"],"AuditChecklist": ["Have procedures been established and implemented to control access to source programs by unauthorized persons?","Is the source program stored safely in a non-operational environment for emergencies such as system failures?","Is the history of changes to the source program being managed?"],"NonComplianceCases": ["Case 1: There is no separate backup or configuration management system for source programs, and previous versions of the source code are stored on the operational server or developer's PC without approval or history management.","Case 2: A configuration management system has been established, but access control, access and change history for the system or the source code stored in the system are not properly managed.","Case 3: The internal regulations require version control of source programs through a configuration management system, but the latest version of the source program is only stored on the developer's PC, and no separate backup is performed."],"RelatedRegulations": []}],"description": "Source programs must be managed so that only authorized users can access them, and it is a principle that they should not be stored in the operational environment.","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"2.8.6": {"name": "Transition to Operational Environment","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.8.6 Transition to Operational Environment","Subdomain": "2.8. Security in Information System Introduction and Development","AuditEvidence": ["Transition procedures","Transition records (requests, approvals, tests, transitions, etc.)"],"AuditChecklist": ["Have control procedures been established and implemented to safely transition newly introduced, developed, or modified systems to the operational environment?","Are contingency plans in place to address issues that may arise during the transition to the operational environment?","Are only the files necessary for service execution installed in the operational environment?"],"NonComplianceCases": ["Case 1: There are no procedures in place to review and approve the transition of developed or modified source programs to the operational environment.","Case 2: Unnecessary files (source code, distribution modules, backups, development-related documents, manuals, etc.) exist in the operational server.","Case 3: The internal guidelines require the preparation of change request and result documents for safe transition and recovery during transitions to the operational environment, but such documents are not available.","Case 4: The internal guidelines require internal review and approval before distributing mobile apps to the app market, but developers are bypassing these procedures and distributing the apps directly."],"RelatedRegulations": []}],"description": "When transitioning newly introduced, developed, or modified systems to the operational environment, the process must be controlled, and the executable code must be run according to test and user acceptance procedures.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.9.1": {"name": "Change Management","checks": {"codebuild_project_older_90_days": "FAIL","config_recorder_all_regions_enabled": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.9.1 Change Management","Subdomain": "2.9. System and Service Operations Management","AuditEvidence": ["Change management procedures","Change management records (requests, approvals, change details, etc.)","Impact analysis results of changes"],"AuditChecklist": ["Have procedures been established and implemented for changes to assets related to information systems (hardware, operating systems, commercial software packages, etc.)?","Are the performance and security impacts analyzed before making changes to information system-related assets?"],"NonComplianceCases": ["Case 1: A recent change to the DMZ section for redundancy was made, but there is no evidence of performing and approving the security risk and performance evaluation that may occur after the change.","Case 2: A recent network change was made, but the review and notification were not sufficiently carried out, so the changes were not properly reflected in the network diagram or some access control systems (e.g., firewalls, database access control systems) ACLs.","Case 3: Although a change management system was established to analyze and discuss the impact on performance and security when information systems are introduced or changed, changes can still be made outside the system, and related changes are not properly reviewed."],"RelatedRegulations": []}],"description": "Procedures must be established and implemented to manage all changes to assets related to information systems, and the impact on system performance and security must be analyzed before changes are made.","checks_status": {"fail": 2,"pass": 0,"total": 14,"manual": 0}},"2.9.2": {"name": "Performance and Fault Management","checks": {"rds_cluster_multi_az": "FAIL","elb_is_in_multiple_az": "FAIL","rds_instance_multi_az": "FAIL","elbv2_is_in_multiple_az": "PASS","s3_bucket_no_mfa_delete": "FAIL","vpc_subnet_different_az": "PASS","neptune_cluster_multi_az": null,"elbv2_deletion_protection": "FAIL","autoscaling_group_multiple_az": null,"dms_instance_multi_az_enabled": null,"rds_cluster_backtrack_enabled": null,"cloudtrail_multi_region_enabled": "PASS","rds_cluster_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL","acm_certificates_expiration_check": "PASS","s3_bucket_cross_region_replication": "FAIL","trustedadvisor_errors_and_warnings": null,"config_recorder_all_regions_enabled": null,"kms_cmk_not_deleted_unintentionally": null,"neptune_cluster_deletion_protection": null,"networkfirewall_deletion_protection": null,"rds_instance_certificate_expiration": "PASS","route53_domains_transferlock_enabled": null,"cloudtrail_bucket_requires_mfa_delete": null,"elb_cross_zone_load_balancing_enabled": "PASS","documentdb_cluster_deletion_protection": null,"documentdb_cluster_cloudwatch_log_export": null,"ec2_instance_detailed_monitoring_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","iam_no_expired_server_certificates_stored": null,"kafka_cluster_enhanced_monitoring_enabled": null,"elasticache_redis_cluster_multi_az_enabled": null,"directoryservice_ldap_certificate_expiration": null,"cognito_user_pool_deletion_protection_enabled": null,"trustedadvisor_premium_support_plan_subscribed": null,"directoryservice_directory_monitor_notifications": null,"cloudformation_stacks_termination_protection_enabled": "FAIL","cloudtrail_multi_region_enabled_logging_management_events": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.9.2 Performance and Fault Management","Subdomain": "2.9. System and Service Operations Management","AuditEvidence": ["Procedures for performance and capacity monitoring","Evidence of performance and capacity monitoring (e.g., internal reporting results)","Fault response procedures","Fault response report"],"AuditChecklist": ["Have procedures been established and implemented to continuously monitor performance and capacity to ensure the availability of information systems?","Are response procedures in place and implemented to address cases where the performance and capacity requirements (thresholds) of the information system are exceeded?","Have procedures been established and implemented to immediately recognize and respond to information system faults?","Are procedures in place to record and manage actions taken in response to faults through fault response reports?","For serious faults, are measures being taken to prevent recurrence through cause analysis?"],"NonComplianceCases": ["Case 1: Failure to define requirements (e.g., thresholds) for managing performance and capacity for each target, or the absence of records in regular inspection reports, making it difficult to assess the current status.","Case 2: Performance or capacity standards were exceeded, but no related reviews or follow-up measures were taken or implemented.","Case 3: Fault response procedures for IT equipment have been established, but internal and external environmental changes such as network configuration or vendor changes are not adequately reflected.","Case 4: Inconsistencies exist between fault handling procedures and fault type-specific response methods, or there is a lack of rationale for estimating response times, making swift, accurate, and systematic responses difficult."],"RelatedRegulations": []}],"description": "To ensure the availability of information systems, performance and capacity requirements must be defined, and the status must be continuously monitored. Procedures for detecting, recording, analyzing, recovering, and reporting in response to faults must be established and managed effectively.","checks_status": {"fail": 11,"pass": 6,"total": 39,"manual": 0}},"2.9.3": {"name": "Backup and Recovery Management","checks": {"ec2_ami_public": null,"backup_plans_exist": "PASS","backup_vaults_exist": null,"backup_vaults_encrypted": "PASS","ec2_ebs_public_snapshot": "PASS","efs_have_backup_enabled": "FAIL","s3_bucket_public_access": null,"backup_reportplans_exist": null,"s3_bucket_kms_encryption": "FAIL","s3_bucket_public_list_acl": null,"s3_bucket_public_write_acl": null,"ec2_ebs_snapshots_encrypted": "FAIL","rds_instance_backup_enabled": "PASS","rds_snapshots_public_access": "PASS","s3_bucket_lifecycle_enabled": "FAIL","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"s3_bucket_default_encryption": "PASS","rds_cluster_backtrack_enabled": null,"neptune_cluster_backup_enabled": null,"ec2_ebs_volume_snapshots_exists": "FAIL","neptune_cluster_public_snapshot": null,"documentdb_cluster_backup_enabled": null,"documentdb_cluster_public_snapshot": null,"rds_cluster_copy_tags_to_snapshots": "FAIL","s3_bucket_cross_region_replication": "FAIL","rds_instance_copy_tags_to_snapshots": null,"redshift_cluster_automated_snapshot": null,"s3_access_point_public_access_block": "PASS","s3_bucket_policy_public_write_access": "PASS","lightsail_instance_automated_snapshots": null,"dlm_ebs_snapshot_lifecycle_policy_exists": "FAIL","elasticache_redis_cluster_backup_enabled": null,"ecr_repositories_lifecycle_policy_enabled": "FAIL","directoryservice_directory_snapshots_limit": null,"ec2_ebs_snapshot_account_block_public_access": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.9.3 Backup and Recovery Management","Subdomain": "2.9. System and Service Operation Management","AuditEvidence": ["Backup and recovery procedures","Recovery test results","Disaster recovery backup status"],"AuditChecklist": ["Have backup and recovery procedures been established and implemented, including targets, frequency, methods, and procedures?","Is regular recovery testing conducted to verify the completeness and accuracy of the backed-up information and the adequacy of the recovery procedures?","For backup media containing critical information, is the media stored in physically separate locations to address disaster recovery?"],"NonComplianceCases": ["Case 1: Backup and recovery procedures, including targets, frequency, methods, and procedures, have not been established.","Case 2: Although a backup policy is in place, information required to be stored for a long period (6 months, 3 years, 5 years, etc.) according to legal requirements is not being stored according to the backup policy.","Case 3: Some systems (e.g., security system policies and logs) that are required to be separately backed up according to higher-level or internal guidelines are not being backed up.","Case 4: Although higher-level or internal guidelines stipulate that recovery tests for backup media should be conducted periodically, recovery tests have not been performed for an extended period."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 11 (Safety Measures for Disaster Recovery)"]}],"description": "To maintain the availability and data integrity of the information system, procedures must be established and implemented regarding the backup targets, frequency, methods, storage locations, retention periods, and disaster recovery. Additionally, management must ensure timely recovery in case of incidents.","checks_status": {"fail": 11,"pass": 8,"total": 37,"manual": 0}},"2.9.4": {"name": "Log and Access Record Management","checks": {"macie_is_enabled": "PASS","elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","inspector2_is_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","ec2_ebs_public_snapshot": "PASS","eventbridge_bus_exposed": "PASS","rds_snapshots_encrypted": "FAIL","s3_bucket_public_access": null,"s3_bucket_kms_encryption": "FAIL","cloudtrail_insights_exist": null,"s3_bucket_public_list_acl": null,"s3_bucket_public_write_acl": null,"ec2_ebs_snapshots_encrypted": "FAIL","ec2_instance_managed_by_ssm": "FAIL","efs_not_publicly_accessible": "FAIL","guardduty_centrally_managed": "FAIL","rds_snapshots_public_access": "PASS","s3_bucket_default_encryption": "PASS","wafv2_webacl_logging_enabled": "FAIL","iam_securityaudit_role_created": null,"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","config_recorder_all_regions_enabled": null,"s3_access_point_public_access_block": "PASS","s3_bucket_level_public_access_block": "PASS","eventbridge_bus_cross_account_access": "FAIL","s3_bucket_policy_public_write_access": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"s3_account_level_public_access_blocks": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"apigatewayv2_api_access_logging_enabled": "FAIL","cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"s3_bucket_server_access_logging_enabled": "FAIL","cloudfront_distributions_logging_enabled": null,"documentdb_cluster_cloudwatch_log_export": null,"ec2_instance_detailed_monitoring_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_cross_account_sharing_disabled": null,"kafka_cluster_enhanced_monitoring_enabled": null,"acm_certificates_transparency_logs_enabled": "PASS","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","cloudwatch_log_metric_filter_policy_changes": null,"eks_control_plane_logging_all_types_enabled": null,"ec2_ebs_snapshot_account_block_public_access": null,"iam_inline_policy_no_full_access_to_cloudtrail": null,"trustedadvisor_premium_support_plan_subscribed": null,"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL","cloudwatch_log_metric_filter_sign_in_without_mfa": null,"directoryservice_directory_monitor_notifications": null,"eventbridge_schema_registry_cross_account_access": "FAIL","glue_etl_jobs_cloudwatch_logs_encryption_enabled": "FAIL","opensearch_service_domains_audit_logging_enabled": null,"directoryservice_directory_log_forwarding_enabled": null,"ec2_client_vpn_endpoint_connection_logging_enabled": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS","cloudwatch_log_metric_filter_authentication_failures": null,"opensearch_service_domains_cloudwatch_logging_enabled": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"route53_public_hosted_zones_cloudwatch_logging_enabled": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudtrail_multi_region_enabled_logging_management_events": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","glue_development_endpoints_cloudwatch_logs_encryption_enabled": null,"awslambda_function_invoke_api_operations_cloudtrail_logging_enabled": "PASS","cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.9.4 Log and Access Record Management","Subdomain": "2.9. System and Service Operation Management","AuditEvidence": ["Log management procedures","Log record details","Access control records for log storage devices","Access records of personal information"],"AuditChecklist": ["Has the organization established log management procedures for information systems such as servers, applications, security systems, and network systems, and is it generating and storing the necessary logs accordingly?","Are log records of information systems securely stored to prevent tampering, theft, or loss, and is access to the log records minimized?","Are access records for personal information processing systems securely stored for a specified period in accordance with legal requirements, including all necessary items?"],"NonComplianceCases": ["Case 1: The detailed criteria and procedures for log recording, retention periods, review frequency, and responsible personnel have not been established.","Case 2: The maximum size for critical logs such as security event logs, application, and service logs (for Windows Server 2008 or later) is not sufficiently configured, resulting in logs not being recorded and retained for the period specified by internal standards.","Case 3: The log records of important Linux/UNIX servers are not separately backed up or adequately protected, allowing users to arbitrarily delete command execution histories and access logs.","Case 4: Upon reviewing access records for the personal information processing system, while the account, access time, and IP address of the user were logged, details about the data subject information handled and the tasks performed (e.g., view, modify, delete, download) were not recorded.","Case 5: The capacity of the log server is insufficient, leaving only two months of access records for the personal information processing system.","Case 6: A personal information processing system handling personal information of 100,000 data subjects is only retaining access logs for one year."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 8 (Retention and Inspection of Access Records)"]}],"description": "The organization must define the types of logs, retention periods, and retention methods for user access records, system logs, and privilege grant records for information systems such as servers, applications, security systems, and network systems, and must securely retain and manage them to prevent tampering, theft, or loss.","checks_status": {"fail": 25,"pass": 15,"total": 81,"manual": 0}},"2.9.5": {"name": "Log and Access Record Inspection","checks": {"cloudtrail_insights_exist": null,"inspector2_active_findings_exist": "FAIL","trustedadvisor_errors_and_warnings": null,"guardduty_no_high_severity_findings": "FAIL","accessanalyzer_enabled_without_findings": "FAIL","cloudtrail_threat_detection_enumeration": null,"cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_cross_account_sharing_disabled": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cognito_user_pool_client_prevent_user_existence_errors": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Control Requirements","Section": "2.9.5 Log and Access Record Inspection","Subdomain": "2.9. System and Service Operation Management","AuditEvidence": ["Log review and monitoring procedures","Log review and monitoring results (review details, reports, etc.)","Access record inspection details for personal information","Criteria and results for verifying reasons for personal information downloads","Evidence of responses to detected anomalies"],"AuditChecklist": ["Are there established log review and monitoring procedures, including the frequency, targets, and methods for detecting errors, misuse (unauthorized access, excessive queries, etc.), fraud, and other anomalies in the information system?","Are the results of log reviews and monitoring reported to the responsible person, and are responses taken following procedures when anomalies are detected?","Are access records of the personal information processing system regularly inspected according to the periods specified in relevant laws?"],"NonComplianceCases": ["Case 1: Monitoring and alert policies (criteria) for abnormal access (e.g., early morning access on holidays, access via bypass routes) or abnormal behaviors (e.g., large-scale data queries or continuous small data queries) on information systems processing important information have not been established.","Case 2: Although periodic inspection/monitoring criteria for access and usage are established in internal guidelines or systems, there is no record of actual review of abnormal access or behavior.","Case 3: The personal information processor sets the inspection frequency of access records for personal information processing systems to once per quarter.","Case 4: The internal management plan for the personal information processor sets criteria for verifying reasons when more than 1,000 items of personal information are downloaded, but the reasons are not verified when such downloads occur."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 8 (Retention and Inspection of Access Records)"]}],"description": "To ensure normal use of the information system and prevent misuse (unauthorized access, excessive queries, etc.) by users, log review criteria for access and usage must be established and inspected periodically, and post-event actions must be taken promptly if issues arise.","checks_status": {"fail": 6,"pass": 0,"total": 26,"manual": 0}},"2.9.6": {"name": "Time Synchronization","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Control Requirements","Section": "2.9.6 Time Synchronization","Subdomain": "2.9. System and Service Operation Management","AuditEvidence": ["Time synchronization settings","Evidence of time synchronization for key systems"],"AuditChecklist": ["Is the system time synchronized with the standard time?","Is regular inspection conducted to ensure that time synchronization is functioning properly?"],"NonComplianceCases": ["Case 1: The time of some critical systems (e.g., security systems, CCTV, etc.) is not synchronized with the standard time, and regular inspections for synchronization are not being conducted.","Case 2: Although internal NTP servers are configured for time synchronization, some systems are not synchronized, and there has been no cause analysis or response."],"RelatedRegulations": []}],"description": "To ensure the accuracy of logs and access records and provide reliable log analysis, the system time must be synchronized with a standard time and regularly maintained.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.9.7": {"name": "Reuse and Disposal of Information Assets","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Control Requirements","Section": "2.9.7 Reuse and Disposal of Information Assets","Subdomain": "2.9. System and Service Operation Management","AuditEvidence": ["Procedures for the disposal and reuse of information assets","Storage media management ledger","Evidence of the disposal of information assets and storage media","Disposal-related outsourcing contracts for information assets and storage media"],"AuditChecklist": ["Are secure reuse and disposal procedures for information assets established and implemented?","When reusing or disposing of information assets and storage media, are personal and critical information processed to be irrecoverable?","If information assets and storage media are disposed of internally, are the disposal records maintained in a management ledger along with evidence of disposal?","If disposal is outsourced to an external company, are disposal procedures specified in the contract and is the complete disposal confirmed?","Are measures in place to protect data on storage media during maintenance, repairs, or replacements of systems and PCs?"],"NonComplianceCases": ["Case 1: Although the policy and procedure require the complete deletion of data using a data deletion program when reusing PCs used by personal information handlers, in practice, PCs are reused without complete deletion or are only formatted before reuse, indicating that procedures are not being followed.","Case 2: Although storage media are disposed of through an external company, the contract lacks details on secure disposal procedures and protective measures, and there is no verification or supervision of the disposal process or evidence of compliance.","Case 3: Instead of recording the serial numbers of disposed HDDs, the system names are recorded, or the disposal ledger is not maintained, making it impossible to verify the disposal history and traceability.","Case 4: Discarded hard disks are left unsecured in an area without locks, and the data has not been fully deleted."],"RelatedRegulations": ["Personal Information Protection Act, Article 21 (Destruction of Personal Information)","Standards for Ensuring the Safety of Personal Information, Article 13 (Destruction of Personal Information)"]}],"description": "To prevent the recovery or regeneration of personal and critical information during the reuse and disposal process, secure reuse and disposal procedures for information assets must be established and implemented.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.1": {"name": "Collection and Use of Personal Information","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.1.1 Collection and Use of Personal Information","Subdomain": "3.1. Protection Measures during Personal Information Collection","AuditEvidence": ["Online personal information collection forms (e.g., website sign-up screens, mobile app registration screens, event participation forms)","Offline personal information collection forms (e.g., membership application forms)","Records of personal information collection consent (e.g., member databases)","Records of legal guardian consent","Privacy policy"],"AuditChecklist": ["When collecting personal information, is it collected in accordance with lawful requirements such as obtaining the data subject’s consent, complying with legal obligations, or concluding and fulfilling contracts?","When obtaining consent from the data subject for the collection of personal information, are the method and timing of obtaining consent appropriate?","When obtaining consent from the data subject for the collection of personal information, are the relevant details clearly communicated, and are significant points required by law highlighted in a way that is easy to understand?","When collecting, using, or providing personal information from children under the age of 14, are necessary details notified to their legal representatives, and is consent obtained?","When obtaining the consent of a legal representative, is only the minimum necessary personal information collected, and are procedures and methods in place to verify the qualifications of the legal representative?","When notifying children under the age of 14 about matters related to the processing of their personal information, are the notifications presented in a format and language that is clear and easy to understand?","Are records of consent obtained from data subjects and legal representatives being retained?","For personal information that can be processed without the consent of the data subject, are the relevant items and legal basis for processing disclosed in the privacy policy or communicated to the data subject separately from the personal information processed with consent?","When personal information is used for additional purposes without the consent of the data subject, are criteria established and implemented to assess the relevance to the original purpose, predictability, impact on the data subject, and safety measures? If additional usage continues to occur, are these criteria disclosed in the privacy policy and regularly reviewed?"],"NonComplianceCases": ["Case 1: A personal information processor subject to the Personal Information Protection Act failed to include the 'right to refuse consent and the consequences of refusal' in the notifications when obtaining consent to collect personal information.","Case 2: During the process of obtaining consent for the collection of personal information, the items of personal information to be collected were not specified in detail, and were instead described in general terms like 'etc.'","Case 3: On a shopping mall website, personal information necessary for membership registration was collected alongside payment and delivery information required for future purchases, even though such information was not necessary at the time of registration.","Case 4: Personal information (e.g., name, email, phone number) was collected through Q&A boards without obtaining the data subject's consent.","Case 5: Personal information of children under the age of 14 was collected without obtaining the consent of their legal guardians.","Case 6: Although the service was not intended for children under 14, some members were under 14 because the website did not check birthdates during registration, allowing them to register without legal guardian consent.","Case 7: The procedure for verifying the authenticity of the legal representative was insufficient, allowing individuals who were not legal guardians to provide consent.","Case 8: Personal information (e.g., name, phone number) of legal guardians was collected for the purpose of obtaining their consent to collect personal information from children under the age of 14, but the consent of the legal guardian was not confirmed for an extended period, and the information was retained without being destroyed.","Case 9: Personal information of children under 14 was collected based on the consent of their legal guardians, but records of this consent were not maintained, making it impossible to verify the details related to legal guardian consent (e.g., legal guardian’s name, time of consent)."],"RelatedRegulations": ["Personal Information Protection Act, Article 15 (Collection and Use of Personal Information), Article 22 (Methods for Obtaining Consent), Article 22-2 (Protection of Personal Information of Children)","Notice on the Processing of Personal Information"]}],"description": "Personal information must be collected and used lawfully and fairly. When collecting personal information based on the consent of the data subject, such consent must be obtained through legal means. Additionally, when collecting personal information from children under the age of 14, consent must be obtained from their legal representative, and it must be verified that such consent was given by the legal representative.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.2": {"name": "Restrictions on the Collection of Personal Information","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.1.2 Restrictions on the Collection of Personal Information","Subdomain": "3.1. Protection Measures during Personal Information Collection","AuditEvidence": ["Online personal information collection forms (e.g., website sign-up screens, event participation forms)","Offline personal information collection forms (e.g., membership application forms)","Privacy policy"],"AuditChecklist": ["When collecting personal information, is only the minimum amount of information necessary for the intended purpose being collected?","When collecting personal information based on the data subject’s consent, is the data subject clearly informed that they can refuse to consent to the collection of additional personal information beyond the minimum required?","Is the data subject not denied goods or services for refusing to consent to the collection of additional personal information beyond the minimum necessary for the intended purpose?"],"NonComplianceCases": ["Case 1: Although personal information was being collected based on the fulfillment of a contract, excessive personal information not essential to the fulfillment of the contract was being collected.","Case 2: During the process of obtaining consent from the data subject for optional information, the data subject was not explicitly informed that they could refuse to provide such information.","Case 3: Although the sign-up form distinguished between required and optional information, the data subject was not clearly informed that they could complete registration without providing optional information (e.g., there was no indication on the personal information entry form of which fields were required and which were optional).","Case 4: On the website registration page, the data subject was unable to proceed or complete registration if they refused to provide optional information or consent to optional matters.","Case 5: During the hiring process, excessive personal information unrelated to the job position (e.g., family details) was collected."],"RelatedRegulations": ["Personal Information Protection Act, Article 16 (Restrictions on the Collection of Personal Information), Article 22 (Methods for Obtaining Consent)"]}],"description": "When collecting personal information, only the minimum amount of personal information necessary for the intended purpose may be collected, and the data subject must not be denied the provision of goods or services for refusing to consent to optional matters.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.3": {"name": "Restrictions on the Processing of Resident Registration Numbers","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.1.3 Restrictions on the Processing of Resident Registration Numbers","Subdomain": "3.1. Protection Measures during Personal Information Collection","AuditEvidence": ["Personal information collection forms (e.g., website sign-up screens, event participation forms, membership application forms)","Online personal information collection forms (alternative registration methods for identity verification)","Evidence of legal grounds for processing resident registration numbers","Privacy policy"],"AuditChecklist": ["Are resident registration numbers only processed when there is a clear legal basis?","Is the legal provision that forms the basis for the collection of resident registration numbers clearly identified?","When processing resident registration numbers under a legal basis, does the organization provide a method for data subjects to register without using their resident registration number during the membership registration process on an internet website?"],"NonComplianceCases": ["Case 1: Resident registration numbers were collected for simple membership management purposes, such as identity verification, during website sign-up based on the data subject's consent.","Case 2: Resident registration numbers were collected based on provisions in enforcement rules or local ordinances.","Case 3: The last 6 digits of the resident registration number were collected for identity verification, such as during password recovery, without any legal basis.","Case 4: Resident registration numbers were collected from job applicants during the hiring process without a legal basis.","Case 5: Resident registration numbers were collected during customer service inquiries at a call center for identity verification purposes.","Case 6: Even when there was a legal basis for the collection of resident registration numbers, alternative registration methods were not provided during the membership registration process on the website, and resident registration numbers were required for identity verification and membership registration."],"RelatedRegulations": ["Personal Information Protection Act, Article 24-2 (Restrictions on the Processing of Resident Registration Numbers)","Information and Communications Network Act, Article 23-2 (Restrictions on the Use of Resident Registration Numbers)"]}],"description": "Resident registration numbers may not be collected, used, or processed unless there is a legal basis for doing so. Even when the processing of resident registration numbers is permitted, alternative methods must be provided, such as through an internet website.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.4": {"name": "Restriction on Processing of Sensitive and Unique Identifying Information","checks": {},"status": "PASS","attributes": [{"Domain": "3. Personal Information Processing Requirements","Section": "3.1.4 Restriction on Processing of Sensitive and Unique Identifying Information","Subdomain": "3.1. Protection Measures for Personal Information Collection","AuditEvidence": ["Online personal information collection forms (e.g., membership sign-up pages, event participation forms)","Offline personal information collection forms (e.g., membership application forms)","Privacy policy"],"AuditChecklist": ["Is sensitive information processed only with the separate consent of the data subject or when legally required?","Is unique identifying information (excluding resident registration numbers) processed only with the separate consent of the data subject or when there is a specific legal basis?","If there is a risk of invasion of privacy due to the disclosure of sensitive information during the provision of goods or services, is the data subject clearly informed of the possibility of such disclosure and how to opt for non-disclosure before the provision of goods or services?"],"NonComplianceCases": ["Case 1: Collecting sensitive information such as disability status for discounts or benefits for disabled individuals, and obtaining blanket consent for all personal information items.","Case 2: Collecting foreign registration numbers only from foreigners during membership registration, and obtaining blanket consent for all personal information items.","Case 3: When obtaining separate consent for the collection of sensitive or unique identifying information, failing to inform or incorrectly informing the data subject about the four key points that must be disclosed (e.g., the right to refuse consent and the consequences of refusal)."],"RelatedRegulations": ["Personal Information Protection Act, Article 23 (Restrictions on Processing of Sensitive Information), Article 24 (Restrictions on Processing of Unique Identifying Information)"]}],"description": "In order to process sensitive information and unique identifying information (excluding resident registration numbers), separate consent from the data subject must be obtained unless the processing is specifically required or permitted by law.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.5": {"name": "Indirect Collection of Personal Information","checks": {},"status": "PASS","attributes": [{"Domain": "3. Personal Information Processing Requirements","Section": "3.1.5 Indirect Collection of Personal Information","Subdomain": "3.1. Protection Measures for Personal Information Collection","AuditEvidence": ["Contracts related to the provision of personal information (agreements with providers)","Records of notifications to data subjects about the source of personal information","Privacy policy"],"AuditChecklist": ["When receiving personal information from a third party, is it clearly stated in the contract that the responsibility for obtaining consent for the collection of personal information lies with the party providing the information?","When collecting personal information from public media or places, is the collection limited to the scope recognized as having the data subject's consent, based on common societal standards?","Even for personal information collected or generated through automated collection devices during the process of providing services, is the principle of minimum collection applied?","When personal information is collected from a source other than the data subject and the data subject requests it, is the required information immediately provided to the data subject?","When personal information collected from a source other than the data subject meets legal requirements in terms of type or scale, is the required information provided to the data subject?","Is there a record of informing the data subject about the source of personal information, and is this record maintained until the personal information is destroyed?"],"NonComplianceCases": ["Case 1: In the case of collecting personal information published on websites or social media, there is no procedure for handling requests from data subjects about the source of the information.","Case 2: Personal information provided by another business entity was received based on consent for the provision of personal information under Article 17(1)(1) of the Personal Information Protection Act, but the data subjects were not notified within three months (note: this applies to cases where the recipient handles the personal information of more than 50,000 data subjects, sensitive information, or unique identifying information, or processes personal information of over 1 million data subjects).","Case 3: The data subject was informed about the source of the personal information as required by law, but some mandatory notification items were omitted, such as the purpose of processing or the right to withdraw consent.","Case 4: The data subject was informed about the source of the personal information, but the record of this notification was not maintained until the personal information was destroyed, in violation of legal obligations."],"RelatedRegulations": ["Personal Information Protection Act, Article 16 (Restrictions on the Collection of Personal Information), Article 19 (Restrictions on Use and Provision of Personal Information Provided by a Third Party), Article 20 (Notification of the Source, Purpose, etc. of Indirectly Collected Personal Information)"]}],"description": "When collecting personal information from sources other than the data subject or when receiving personal information from a third party, only the minimum amount of personal information necessary for the task should be collected or received. If there is a legal basis or at the request of the data subject, the source of the personal information, the purpose of processing, and the right to request a suspension of processing must be disclosed.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.6": {"name": "Installation and Operation of Video Information Processing Devices","checks": {},"status": "PASS","attributes": [{"Domain": "3. Personal Information Processing Requirements","Section": "3.1.6 Installation and Operation of Video Information Processing Devices","Subdomain": "3.1. Protection Measures for Personal Information Collection","AuditEvidence": ["Status of video information processing device operation","Signs for video information processing devices","Video information processing device operation and management policies","Management screens for video information processing devices (e.g., account/permission details, video retention periods)","Contracts with operators of video information processing devices and inspection records"],"AuditChecklist": ["When installing and operating fixed video information processing devices in public places, is it reviewed whether the installation meets legal requirements?","If public institutions install and operate fixed video information processing devices in public places, are public hearings or explanation sessions held to gather opinions from relevant experts and stakeholders, as required by law?","When installing and operating fixed video information processing devices, are necessary measures taken, such as installing signs to ensure the data subject can easily recognize the presence of the devices?","When operating mobile video information processing devices in public places for business purposes, is it reviewed whether the operation meets legal requirements?","When operating mobile video information processing devices in public places for business purposes, is the fact that the video is being recorded indicated and informed to the public through lights, sounds, or signs?","Is there an operation and management policy in place for the safe management of video information processing devices and the video information they record, and is it being implemented?","Is the retention period for video information set, and is the information destroyed without delay after the retention period expires?","When outsourcing the operation of video information processing devices, are the related procedures and requirements reflected in the contract?"],"NonComplianceCases": ["Case 1: The wording on the signs for video information processing devices is incomplete, or there is no established and implemented policy for the operation and management of video information processing devices.","Case 2: Although there is a policy for the operation and management of video information processing devices, the policy is not followed, such as failing to comply with the retention period or failing to implement access control and logging as described in the policy.","Case 3: The operation of video information processing devices is outsourced, but the legal requirements, such as inspection of the video information management status and provisions regarding liability for damages, are not reflected in the contract.","Case 4: The operation of video information processing devices is outsourced, but the signs for the devices do not include the name and contact information of the contractor."],"RelatedRegulations": ["Personal Information Protection Act, Article 25 (Restrictions on the Installation and Operation of Fixed Video Information Processing Devices), Article 25-2 (Restrictions on the Operation of Mobile Video Information Processing Devices)"]}],"description": "When installing and operating fixed video information processing devices in public places or operating mobile video information processing devices in public places for business purposes, legal requirements must be followed according to the purpose and location of the installation, and appropriate protection measures must be established and implemented.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.7": {"name": "Collection and Use of Personal Information for Marketing Purposes","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.1.7 Collection and Use of Personal Information for Marketing Purposes","Subdomain": "3.1. Protection Measures When Collecting Personal Information","AuditEvidence": ["Online personal information collection forms (e.g., website membership sign-up, mobile app sign-up, event participation)","Offline personal information collection forms (e.g., membership application forms)","Marketing consent records","Records of consent for receiving advertising information and confirmation of consent","Administrator screen for advertising information transmission systems (e.g., email, SMS, app push notifications)","Advertising information transmission content","Personal information processing policy"],"AuditChecklist": ["When obtaining consent from data subjects to process personal information for the purpose of promoting or recommending goods or services, is the data subject clearly informed, and is separate consent obtained?","When sending advertising information for profit using electronic transmission media, is the recipient's explicit prior consent obtained, and is the consent reconfirmed every two years?","When a recipient indicates refusal or withdraws prior consent for receiving advertising information for profit, is the transmission of such advertising information stopped?","When sending advertising information for profit, is the sender's name, method for opting out, etc., clearly stated, and are such messages not sent during nighttime hours?"],"NonComplianceCases": ["Case 1: When collecting personal information for 'promotion and marketing' purposes, the purpose is vaguely explained (e.g., 'providing additional services', 'providing partner services') or blanket consent is obtained without distinguishing between different purposes.","Case 2: Even after a user has expressed refusal to receive advertising push notifications via a mobile app, such notifications are sent due to a program error.","Case 3: The option to receive advertising information via text messages or email is pre-selected by default on the online sign-up page.","Case 4: The recipient's consent for receiving advertising information is not reconfirmed every two years.","Case 5: When sending advertising information for profit via email, the subject line does not begin with '(Advertisement)'."],"RelatedRegulations": ["Personal Information Protection Act, Article 22 (Method of Obtaining Consent)","Information and Communications Network Act, Article 50 (Restrictions on Transmission of Advertising Information)"]}],"description": "When collecting and using personal information for marketing purposes, such as promoting goods or services, sales recommendations, or sending advertising information, the purpose must be clearly communicated to the data subject, and their consent must be obtained.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.2.1": {"name": "Management of Personal Information Status","checks": {"macie_is_enabled": "PASS","s3_bucket_lifecycle_enabled": "FAIL"},"status": "FAIL","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.2.1 Management of Personal Information Status","Subdomain": "3.2. Protection Measures When Retaining and Using Personal Information","AuditEvidence": ["Personal information status table","Personal information flowchart","Registration status of personal information files","Personal information file management ledger","Personal information processing policy-related personal information files","Personal information files related to investigations under the Punishment of Tax Offenses Act and the Customs Act","Personal information files for one-time operations deemed to have a low need for continuous management as determined by Presidential Decree","Personal information files for simple tasks such as attending meetings, sending documents or materials, and financial settlements, which have a low need for continuous management","Personal information files processed temporarily for public health or public safety emergencies","Other personal information files collected for one-time tasks that are not stored or recorded","Personal information files classified as confidential under other laws","Personal information files collected or requested for analysis related to national security","Personal video information files processed via video information processing devices","Personal information files retained by financial institutions for handling financial transactions under the Real Name Financial Transactions and Guarantee of Secrecy Act"],"AuditChecklist": ["Is the status of collected and retained personal information, including the items, volume, purpose and method of processing, and retention period, regularly managed?","When a public institution operates or modifies personal information files, are the relevant matters registered with the head of the relevant agency as required by law?","Does the public institution disclose the status of personal information files in the personal information processing policy?"],"NonComplianceCases": ["Case 1: Although personal information files are managed through the website's personal information file registration menu, some personal information files related to website services are missing from the personal information processing policy.","Case 2: Although two months have passed since a new personal information file was created, it has not been registered with the Personal Information Protection Commission.","Case 3: The content of personal information files registered and disclosed with the Personal Information Protection Commission (e.g., items of personal information collected) does not match the actual status of personal information files being processed.","Case 4: A public institution has not registered personal information files with the Personal Information Protection Commission, even though the files do not qualify for exceptions such as employee personal information files or personal information files collected under the Statistics Act."],"RelatedRegulations": ["Personal Information Protection Act, Article 32 (Registration and Disclosure of Personal Information Files)"]}],"description": "The items, volume, purpose and method of processing, and retention period of collected and retained personal information must be regularly managed. In the case of public institutions, such information must be registered with the head of the relevant agency as stipulated by law.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"3.2.2": {"name": "Personal Information Quality Assurance","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.2.2 Personal Information Quality Assurance","Subdomain": "3.2. Protection Measures for Retention and Use of Personal Information","AuditEvidence": ["Form for data subjects to modify/update their personal information (online, offline)","Procedures to maintain the up-to-date status of personal information"],"AuditChecklist": ["Are procedures and methods in place to maintain personal information in an accurate and up-to-date state?","Is there a method provided for data subjects to ensure the accuracy, completeness, and up-to-dateness of their personal information?"],"NonComplianceCases": ["Case 1: Although an identity verification process is implemented when changing member information through the website, the identity verification process is insufficient when changing member information via customer service, making unauthorized changes possible.","Case 2: While an online method is provided for online members to change their personal information, no such method is provided for offline members."],"RelatedRegulations": ["Personal Information Protection Act, Article 3 (Principles of Personal Information Protection)"]}],"description": "Collected personal information must be managed to ensure its accuracy, completeness, and up-to-dateness within the scope necessary for the processing purpose, and procedures must be provided to data subjects to manage their information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.2.3": {"name": "Protection of User Device Access","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.2.3 Protection of User Device Access","Subdomain": "3.2. Protection Measures for Retention and Use of Personal Information","AuditEvidence": ["App access rights consent screen","App access rights settings"],"AuditChecklist": ["When accessing information stored on the user's mobile device or functions installed on the device, are users clearly informed and their consent obtained?","Is it ensured that services are not denied if users do not consent to access rights that are not essential for the service?","Are methods provided for users to consent to or withdraw access rights on their mobile devices?"],"NonComplianceCases": ["Case 1: A smartphone app requests excessive access to personal information areas such as contacts, photos, and messages, even though such access is unnecessary for the service.","Case 2: A service provider's smartphone app accesses information stored on the smartphone and installed functions without notifying the user and obtaining their consent.","Case 3: Consent is obtained for app access rights by informing users that optional permissions are required as essential permissions.","Case 4: A smartphone app supports Android versions below 6.0, where individual consent for access rights is not possible, making it impossible for users to reject optional access rights."],"RelatedRegulations": ["Information and Communications Network Act, Article 22-2 (Consent for Access Rights)"]}],"description": "When accessing information stored on the user's mobile device or functions installed on the mobile device, it is necessary to notify the user clearly and obtain their consent.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.2.4": {"name": "Use and Provision of Personal Information Beyond Purpose","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.2.4 Use and Provision of Personal Information Beyond Purpose","Subdomain": "3.2. Protection Measures for Retention and Use of Personal Information","AuditEvidence": ["Records of personal information use and provision beyond the original purpose (including related evidence such as requests)","Log of personal information use and provision beyond the original purpose (for public institutions)","Records of publication in the official gazette or on the website (for public institutions)","Guidelines for handling information provision requests","Official documents requesting information provision and records of personal information provision"],"AuditChecklist": ["Is personal information used or provided only within the scope of the purpose consented to by the data subject at the time of collection or as permitted by law?","When receiving personal information from a personal information processor, is the information used or provided only within the scope of the purpose for which it was provided?","If personal information is used or provided beyond the scope of the purpose of collection or the purpose for which it was received from a personal information processor, is additional consent obtained from the data subject or limited to cases with a legal basis?","When providing personal information to a third party for purposes beyond the original purpose, is the recipient required to take necessary actions to restrict the use of personal information and ensure safety?","When public institutions use or provide personal information beyond the original purpose, are the legal basis, purpose, and scope published in the official gazette or on the internet?","When public institutions use or provide personal information beyond the original purpose, is there a record of such use or provision and are procedures in place for managing it?"],"NonComplianceCases": ["Case 1: Personal information collected for product delivery is used for telemarketing of other company products without prior consent.","Case 2: Personal information collected for customer satisfaction surveys or sweepstakes entries is used for advertising other promotional events without consent.","Case 3: A public institution provides personal information to another institution for purposes outside the scope of the original purpose based on legal grounds but does not publish the information in the official gazette or on the internet.","Case 4: A public institution provides personal information to a police department for criminal investigation purposes but fails to record the details in the log of personal information use and provision beyond the original purpose."],"RelatedRegulations": ["Personal Information Protection Act, Article 18 (Restriction on the Use and Provision of Personal Information Beyond the Original Purpose), Article 19 (Restriction on Use and Provision by Recipients of Personal Information)"]}],"description": "Personal information must only be used or provided within the scope notified and consented to by the data subject at the time of collection or as permitted by law. If personal information is to be used or provided beyond this scope, additional consent must be obtained from the data subject or the legality must be verified, and appropriate protective measures must be established and implemented.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.2.5": {"name": "Processing of Pseudonymized Information","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.2.5 Processing of Pseudonymized Information","Subdomain": "3.2. Protection Measures for Retention and Use of Personal Information","AuditEvidence": ["Procedures and results of the adequacy review of pseudonymization/anonymization","Records of pseudonymized information processing","Privacy policy (regarding the use and provision of pseudonymized information)"],"AuditChecklist": ["When processing pseudonymized information, are procedures established for purpose limitation, pseudonymization methods and standards, adequacy review, prohibition of re-identification, and actions in case of re-identification?","When using or providing pseudonymized personal information, is the information pseudonymized to a level where individuals cannot be identified without using or combining additional information?","When combining pseudonymized information with that of other personal information processors, is the combination conducted through a specialized agency or data professional organization?","When processing pseudonymized information, are technical, administrative, and physical measures taken to ensure safety, such as deleting or separately storing additional information and keeping records?","Is the processing period for pseudonymized information set to an appropriate period considering the processing purpose, and is the information destroyed without delay when that period expires?","When anonymizing personal information, is the information anonymized to a level where individuals cannot be identified even with the use of additional information, considering the time, cost, and technology available?"],"NonComplianceCases": ["Case 1: When processing pseudonymized information for statistical purposes or scientific research without obtaining consent from data subjects, records of the pseudonymization process were not kept, or the privacy policy was not updated to include relevant information.","Case 2: Additional information was not stored separately from pseudonymized information in the same database, or access rights to both sets of information were not appropriately segregated.","Case 3: Although pseudonymized personal information was used, the pseudonymization process was not sufficient, making it possible to identify individuals by combining the information with other data without using additional information.","Case 4: Personal information was anonymized for generating test data or for public release, but due to outliers or other factors, it was still possible to identify individuals, indicating that the anonymization process was not sufficient."],"RelatedRegulations": ["Personal Information Protection Act, Article 2 (Definitions), Article 28-2 (Processing of Pseudonymized Information), Article 28-3 (Restrictions on Combining Pseudonymized Information), Article 28-4 (Obligations for the Safe Processing of Pseudonymized Information), Article 28-5 (Prohibition of Re-identification in Processing Pseudonymized Information), Article 28-7 (Scope of Application), Article 58-2 (Exemptions)"]}],"description": "When processing pseudonymized information, legal requirements such as purpose limitation, combination restrictions, safety measures, and prohibition obligations must be met, and procedures must be established and implemented to ensure an appropriate level of pseudonymization.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.3.1": {"name": "Provision of Personal Information to Third Parties","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.3.1 Provision of Personal Information to Third Parties","Subdomain": "3.3. Protective Measures When Providing Personal Information","AuditEvidence": ["Forms related to the provision of personal information to third parties online (e.g., membership registration page, consent for third-party provision on websites)","Forms related to the provision of personal information to third parties offline (e.g., membership application forms, consent forms for third-party provision)","Records of third-party provisions","Privacy policy"],"AuditChecklist": ["When providing personal information to third parties, are legal requirements such as consent from the data subject or compliance with legal obligations clearly identified and followed?","When obtaining consent from the data subject for the provision of personal information to third parties, are the related matters clearly communicated, and is consent legally obtained by distinguishing it from other consents?","When obtaining consent from the data subject for the provision of personal information to third parties, are important matters clearly indicated and made easily understandable as required by law?","When providing personal information to third parties, is the information limited to the minimum necessary for the intended purpose?","When providing personal information to third parties, is it done through secure procedures and methods, and is the provision recorded and stored?","When allowing third parties to access personal information, is control implemented in accordance with protection procedures to securely protect the personal information?","When providing additional personal information without the data subject's consent, are criteria for determining the relevance to the original purpose of collection, predictability, potential harm, and safety measures established and followed? If such provisions continue, are these criteria disclosed in the privacy policy and periodically reviewed?"],"NonComplianceCases": ["Case 1: When obtaining consent from the data subject for the provision of personal information to third parties, some necessary information (e.g., the right to refuse consent, the items provided) was omitted.","Case 2: In the process of providing personal information to third parties, personal information from data subjects who did not consent was provided due to improper verification of consent.","Case 3: When obtaining consent for the provision of personal information, the recipient was not specifically identified and was vaguely referred to as Ź»~ etc.ʼ in the consent.","Case 4: Although third-party provision consent was optional during the membership registration process, if the data subject did not agree to third-party provision, the registration process could not be completed.","Case 5: An excessive amount of personal information was provided beyond what was necessary for the recipient's purpose of use."],"RelatedRegulations": ["Personal Information Protection Act, Article 17 (Provision of Personal Information), Article 22 (Methods of Obtaining Consent)","Notification on the Methods of Processing Personal Information"]}],"description": "When providing personal information to third parties, there must be a legal basis or consent from the data subject, and protection measures must be established and implemented to securely protect personal information during the process of providing access to third parties.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.3.2": {"name": "Outsourcing of Personal Information Processing","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.3.2 Outsourcing of Personal Information Processing","Subdomain": "3.3. Protective Measures When Providing Personal Information","AuditEvidence": ["Privacy policy (disclosing details related to the outsourcing of personal information processing)","Personal information collection forms","Contracts for outsourcing personal information processing","Records of notifications to data subjects regarding outsourced tasks related to promoting or selling goods or services"],"AuditChecklist": ["When outsourcing personal information processing tasks (including sub-outsourcing) to third parties, are the details of the outsourced tasks and the trustees regularly updated and disclosed on the website?","When outsourcing tasks related to promoting or selling goods or services, is the data subject notified of the details of the outsourced tasks and the trustees through methods such as written notice, email, or text messages?"],"NonComplianceCases": ["Case 1: Although the details of the outsourcing of personal information processing tasks were disclosed on the website's privacy policy, some trustees and the details of the outsourced tasks were missing.","Case 2: When outsourcing tasks related to promoting or selling goods or services, the details of the outsourced tasks and trustees were not notified to the data subject through written methods, and instead, the information was disclosed only in the privacy policy.","Case 3: After terminating a contract with an existing trustee for personal information processing, the new trustee was not promptly reflected in the privacy policy.","Case 4: Although the trustee sub-outsourced the personal information processing tasks to a third party, the sub-outsourcing details were not disclosed on the website."],"RelatedRegulations": ["Personal Information Protection Act, Article 26 (Restrictions on the Processing of Personal Information by Outsourcing)"]}],"description": "When outsourcing personal information processing tasks to third parties, the details of the outsourced tasks and the trustee must be disclosed. Additionally, if the task involves promoting or selling goods or services, the details of the outsourced task and the trustee must be notified to the data subject.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.3.3": {"name": "Transfer of Personal Information Due to Business Transfers","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.3.3 Transfer of Personal Information Due to Business Transfers","Subdomain": "3.3. Protective Measures When Providing Personal Information","AuditEvidence": ["Records of notifications to data subjects regarding the transfer of personal information (during business transfers)","Privacy policy"],"AuditChecklist": ["When transferring personal information to another party due to the transfer or merger of all or part of the business, are the necessary matters communicated to the data subjects in advance?","When receiving personal information, does the recipient notify the data subjects without delay regarding the fact that personal information has been received and other necessary matters, if legally required?","Does the recipient of the personal information use the information only for its original purpose at the time of transfer, or provide it to third parties in compliance with the original purpose?"],"NonComplianceCases": ["Case 1: When receiving personal information through business acquisition, the data subjects were not notified of the transfer of personal information, even though the data provider failed to notify them of the transfer.","Case 2: When receiving personal information through business acquisition or merger, no procedures or methods were provided to allow data subjects to opt-out of the transfer, nor were such options communicated to the data subjects."],"RelatedRegulations": ["Personal Information Protection Act, Article 27 (Restrictions on the Transfer of Personal Information Due to Business Transfers)"]}],"description": "When transferring or receiving personal information due to business transfers or mergers, appropriate protection measures such as notifying the data subjects must be established and implemented.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.3.4": {"name": "Transfer of Personal Information Abroad","checks": {"s3_bucket_cross_region_replication": "FAIL"},"status": "FAIL","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.3.4 Transfer of Personal Information Abroad","Subdomain": "3.3. Protection Measures When Providing Personal Information","AuditEvidence": ["Consent form for personal information transfer abroad","Contract related to personal information transfer abroad","Privacy policy","Notification or disclosure records regarding outsourcing or storage of personal information abroad"],"AuditChecklist": ["When transferring personal information abroad, has the data subject been fully informed of all notification requirements and obtained separate consent, or complied with certification or recognition, as required by law?","When informing the data subject about the outsourcing or storage of personal information abroad for the purpose of contract execution, are all necessary details included and communicated appropriately?","Has a contract for the transfer of personal information abroad been established, including compliance with personal information protection laws?","Are necessary measures being taken to protect personal information when transferring it abroad?"],"NonComplianceCases": ["Case 1: Personal information was provided to a foreign company during processing, but separate consent for the transfer of personal information abroad was not obtained, even though the conditions for consent exemption (such as certification or recognition by the recipient country) were not met.","Case 2: While using foreign cloud services (foreign regions) for outsourcing and storing personal information, the relevant details, such as the destination country and transfer method, were not disclosed in the privacy policy or communicated to the data subject.","Case 3: While obtaining consent for the transfer of personal information abroad, only the name of the recipient (company name) was disclosed, and the destination country was not properly notified."],"RelatedRegulations": ["Personal Information Protection Act, Articles 28-8 (Transfer of Personal Information Abroad), 28-9 (Order to Suspend Transfer of Personal Information Abroad), 28-10 (Reciprocity), 28-11 (Applicable Provisions)","Regulations on the Operation of Personal Information Transfer Abroad"]}],"description": "When transferring personal information abroad, appropriate protective measures such as obtaining consent and disclosing relevant details about the transfer must be established and implemented.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.4.1": {"name": "Destruction of Personal Information","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.4.1 Destruction of Personal Information","Subdomain": "3.4. Protection Measures When Destroying Personal Information","AuditEvidence": ["Regulations regarding the retention period and destruction of personal information","Destruction results (e.g., from member databases)","Personal information destruction management records"],"AuditChecklist": ["Has an internal policy been established regarding the retention period and destruction of personal information?","Is personal information being destroyed without delay when the processing purpose is achieved or the retention period has expired?","Is personal information destroyed using safe methods that prevent recovery or reconstruction?","Are records kept of the destruction of personal information and managed properly?"],"NonComplianceCases": ["Case 1: When a member withdraws or the purpose of retention is achieved, personal information was destroyed from the member database, but not from associated systems (CRM, DW) where duplicate personal information was stored.","Case 2: Personal information collected during a specific event was not destroyed or no destruction policy was established, even after the event ended.","Case 3: Personal information collected through a call center (such as call logs, recordings) is retained for three years under the Electronic Commerce Act, but the information was not destroyed even after three years had passed.","Case 4: Due to technical limitations, such as using blockchain, it was not possible to completely destroy personal information, so it was anonymized instead. However, the anonymization process was not done properly, allowing partial re-identification of personal information."],"RelatedRegulations": ["Personal Information Protection Act, Article 21 (Destruction of Personal Information)","Standards for Ensuring the Safety of Personal Information, Article 13 (Destruction of Personal Information)"]}],"description": "The organization must establish an internal policy regarding retention periods and destruction of personal information. When the retention period has expired or the purpose of processing has been achieved, personal information must be destroyed without delay using methods that ensure safety and completeness.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.4.2": {"name": "Measures When Retaining Personal Information After Purpose Is Achieved","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.4.2 Measures When Retaining Personal Information After Purpose Is Achieved","Subdomain": "3.4. Protection Measures When Destroying Personal Information","AuditEvidence": ["Regulations regarding the retention period and destruction of personal information","Current status of separated databases (table structure, etc.)","Access permissions for separated databases"],"AuditChecklist": ["When personal information is retained beyond the retention period or after the processing purpose has been achieved, in accordance with relevant laws, is it limited to the minimum necessary period and only the minimum necessary information?","When personal information is retained beyond the retention period or after the processing purpose has been achieved, is it stored separately from other personal information?","Is personal information that is stored separately processed only within the scope allowed by law?","Is access to separately stored personal information limited to the minimum number of personnel?"],"NonComplianceCases": ["Case 1: Information from withdrawn members was not destroyed but kept for a certain period under the Electronic Commerce Act, with only the flag value changed, and stored in the same table as other member information.","Case 2: Records related to consumer complaints and disputes were kept for five years instead of the required three years, due to misinterpretation of legal requirements.","Case 3: Although a separate database was set up, access permissions were not appropriately configured, allowing personnel who did not require access to view the separated database.","Case 4: Information from withdrawn members was stored separately in accordance with the Electronic Commerce Act, but excessive optional information was also stored, even though there was no legal obligation to do so."],"RelatedRegulations": ["Personal Information Protection Act, Article 21 (Destruction of Personal Information)"]}],"description": "If personal information is retained beyond the retention period or after the purpose of processing has been achieved, as permitted by relevant laws, it must be limited to the minimum necessary items and stored separately from other personal information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.5.1": {"name": "Disclosure of Privacy Policy","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.5.1 Disclosure of Privacy Policy","Subdomain": "3.5. Protection of Data Subject's Rights","AuditEvidence": ["Privacy policy","Records of privacy policy amendments (e.g., board notices)"],"AuditChecklist": ["Is the privacy policy written in clear and easy-to-understand language, covering all the contents required by law?","Is the privacy policy continuously updated and made easily accessible to data subjects via the internet or other means?","When the privacy policy is updated, are the reasons for the changes and the contents of the changes promptly notified, and can the data subjects easily recognize the changes at any time?"],"NonComplianceCases": ["Case 1: The privacy policy discloses information about the collection and provision of personal information, but the actual details differ from what is being collected and provided.","Case 2: Changes such as the replacement of the privacy officer or changes in subcontractors have occurred, but these changes have not been reflected in the privacy policy.","Case 3: The privacy policy is disclosed, but it is labeled 'Privacy Protection Policy' instead of 'Privacy Policy,' and its visibility is not enhanced with larger font sizes or color to make it easy for data subjects to find.","Case 4: Several amendments have been made to the privacy policy, but older versions of the policy are not made available for review.","Case 5: Although personal information is retained in compliance with laws such as the Electronic Commerce Act and the Commercial Act, the legal grounds for retention and the retained personal information items are not disclosed in the privacy policy."],"RelatedRegulations": ["Personal Information Protection Act, Article 30 (Establishment and Disclosure of Privacy Policy), Article 30-2 (Evaluation and Improvement Recommendations for Privacy Policy)"]}],"description": "A privacy policy must be established to include all necessary information, such as the purpose of personal information processing, in a way that is easy for data subjects to understand. The policy must be disclosed through appropriate methods so that data subjects can easily access it at any time, and it must be continuously updated.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.5.2": {"name": "Guaranteeing Data Subject's Rights","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.5.2 Guaranteeing Data Subject's Rights","Subdomain": "3.5. Protection of Data Subject's Rights","AuditEvidence": ["Privacy policy","Procedures and forms for handling Requests for Access, etc.","Records of actions taken in response to Requests for Access, etc.","Procedures for member withdrawal and consent withdrawal"],"AuditChecklist": ["Are procedures in place to ensure that data subjects or their representatives can exercise their rights (hereinafter referred to as 'Requests for Access, etc.') to access, rectify, delete, or suspend the processing of their personal information in a way that is not more difficult than the process used for collecting it?","When data subjects or their representatives submit Requests for Access, etc., are the necessary measures taken within the required time frame?","When data subjects withdraw their consent to the collection, use, or provision of their personal information, are the collected personal information and associated data promptly deleted or otherwise handled appropriately?","Are appropriate procedures in place to allow data subjects to object to the actions taken regarding their Requests for Access, etc., and are they informed of these procedures?","Are records kept of data subjects' Requests for Access, etc., and the resulting actions?","When the rights of others, such as privacy or honor, are violated on information networks, does the organization have procedures for the affected individuals to request the deletion of the information from service providers, and are these procedures being implemented?"],"NonComplianceCases": ["Case 1: The method for requesting access, rectification, deletion, or suspension of personal information is not disclosed in a way that data subjects can easily find.","Case 2: There has been no response to access requests for personal information within 10 days, without any valid reason.","Case 3: Records of actions taken in response to personal information access requests are not maintained.","Case 4: Access notifications are being sent without verifying whether the requester is the data subject or their legitimate representative.","Case 5: There has been a failure to respond to rectification or deletion requests within 10 days.","Case 6: It was easy to sign up online as a member, but to withdraw membership, additional documents such as ID must be submitted, or in-person visits are required."],"RelatedRegulations": ["Personal Information Protection Act, Article 34-2 (Deletion or Blocking of Exposed Personal Information), Article 35 (Access to Personal Information), Article 35-2 (Right to Data Portability), Article 36 (Rectification or Deletion of Personal Information), Article 37 (Suspension of Processing, etc.), Article 37-2 (Right of Data Subjects to Contest Automated Decisions), Article 38 (Methods and Procedures for Exercising Rights)","Information and Communications Network Act, Article 44 (Protection of Rights in Information Networks), Article 44-2 (Request for Deletion of Information, etc.), Article 44-3 (Temporary Measures)"]}],"description": "Procedures must be established and implemented to ensure that data subjects can easily exercise their rights, such as requesting access, rectification, deletion, suspension of processing, objection, or withdrawal of consent, through simpler processes than those used for collecting their information. When a request is received, it must be processed without delay, and records must be kept. Measures such as deletion requests and temporary actions must be taken to prevent the distribution of information that infringes on the rights of others, such as invasion of privacy or defamation.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.5.3": {"name": "Notification to Data Subjects","checks": {},"status": "PASS","attributes": [{"Domain": "3. Requirements for Each Stage of Personal Information Processing","Section": "3.5.3 Notification to Data Subjects","Subdomain": "3.5. Protection of Data Subject's Rights","AuditEvidence": ["Records of notifications regarding the use and provision of personal information","Forms and wording used for notifications regarding the use and provision of personal information"],"AuditChecklist": ["If the organization is legally obligated to do so, does it periodically notify data subjects of the use and provision of their personal information, or provide them with access to an information system where they can review such details?","Do the notification items regarding the use and provision of personal information include all legally required elements?"],"NonComplianceCases": ["Case 1: Although the organization is required to notify data subjects of the use and provision of their personal information, no notifications have been sent during the year despite being obligated due to handling personal information of more than 1 million people on a daily average for the past three months at the end of the previous year.","Case 2: Instead of directly notifying individual data subjects, notifications about the use and provision of personal information were made through simple pop-ups or general announcements on the website."],"RelatedRegulations": ["Personal Information Protection Act, Article 20-2 (Notification of Use and Provision of Personal Information)"]}],"description": "The organization must identify matters that must be notified to data subjects, such as the use and provision of personal information, and periodically inform the data subjects of these matters.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.10.1": {"name": "Security System Operation","checks": {"kms_cmk_are_used": null,"macie_is_enabled": "PASS","securityhub_enabled": "PASS","fms_policy_compliant": null,"guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","elbv2_waf_acl_attached": "FAIL","kms_cmk_rotation_enabled": null,"ec2_securitygroup_not_used": "FAIL","guardduty_centrally_managed": "FAIL","wafv2_webacl_logging_enabled": "FAIL","ssm_managed_compliant_patching": "FAIL","kms_key_not_publicly_accessible": null,"ssmincidents_enabled_with_plans": null,"inspector2_active_findings_exist": "FAIL","cloudfront_distributions_using_waf": null,"cognito_user_pool_waf_acl_attached": null,"trustedadvisor_errors_and_warnings": null,"apigateway_restapi_waf_acl_attached": "FAIL","config_recorder_all_regions_enabled": null,"guardduty_no_high_severity_findings": "FAIL","ec2_securitygroup_from_launch_wizard": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","organizations_delegated_administrators": null,"ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_instance_port_ftp_exposed_to_internet": "PASS","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","secretsmanager_automatic_rotation_enabled": "FAIL","ec2_instance_port_cifs_exposed_to_internet": "PASS","ec2_instance_port_ldap_exposed_to_internet": "PASS","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_instance_port_kafka_exposed_to_internet": "PASS","ec2_instance_port_mysql_exposed_to_internet": "PASS","ec2_instance_port_redis_exposed_to_internet": "PASS","ec2_instance_port_oracle_exposed_to_internet": "PASS","ec2_instance_port_telnet_exposed_to_internet": "PASS","ec2_instance_port_mongodb_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_instance_port_kerberos_exposed_to_internet": "PASS","ec2_instance_port_cassandra_exposed_to_internet": "PASS","ec2_instance_port_memcached_exposed_to_internet": "PASS","ec2_instance_port_sqlserver_exposed_to_internet": "PASS","cloudwatch_log_metric_filter_sign_in_without_mfa": null,"ec2_instance_port_postgresql_exposed_to_internet": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","shield_advanced_protection_in_global_accelerators": null,"ec2_instance_internet_facing_with_instance_profile": "FAIL","shield_advanced_protection_in_route53_hosted_zones": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_authentication_failures": null,"shield_advanced_protection_in_associated_elastic_ips": null,"shield_advanced_protection_in_classic_load_balancers": null,"shield_advanced_protection_in_cloudfront_distributions": null,"ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","ec2_instance_port_elasticsearch_kibana_exposed_to_internet": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","shield_advanced_protection_in_internet_facing_load_balancers": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Security Control Requirements","Section": "2.10.1 Security System Operation","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Security system configuration","Network configuration","Security system operational procedures","Firewall policies","Firewall policy setup/modification request forms","Exception list for the security system","Management screens for each security system (firewall, IPS, server access control, DLP, DRM, etc.)","Security system policy review history"],"AuditChecklist": ["Has the organization established and implemented operational procedures for the security systems in use?","Is access to the security system administrators limited to a minimum, and is unauthorized access strictly controlled?","Has the organization established and implemented formal procedures for registering, modifying, and deleting policies for each security system?","Are exception policies for the security system managed according to procedures, and are users of exception policies managed with the minimum privileges?","Is the validity of the policies set on the security system periodically reviewed?","Has the organization installed and operated security systems that perform functions specified by law to prevent illegal access and data leakage in personal information processing systems?"],"NonComplianceCases": ["Case 1: Regular reviews of the security policies for the intrusion prevention system were not conducted, resulting in unnecessary or excessively permissive policies.","Case 2: There are no procedures or criteria for applying, modifying, or deleting security policies, or such procedures exist but are not followed.","Case 3: The assignment and supervision of administrators for the security system were not properly implemented.","Case 4: Although internal guidelines stipulate that the information security officer must record and maintain the history of security policy changes for the security system, the policy management ledger was not periodically maintained, or the policies recorded in the ledger did not match those actually applied in the operating system."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 6 (Access Control)"]}],"description": "For each type of security system, an administrator must be designated, and operational procedures such as updating to the latest policies, modifying rule sets, and monitoring events must be established and implemented. The status of policy application for each security system must be managed.","checks_status": {"fail": 16,"pass": 39,"total": 75,"manual": 0}},"2.10.2": {"name": "Cloud Security","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protective Measure Requirements","Section": "2.10.2 Cloud Security","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Cloud service-related contracts and SLA","Cloud service risk analysis results","Cloud service security control policies","Cloud service administrator privilege assignment status","Cloud service architecture diagram","Cloud service security setting status","Cloud service security setting appropriateness review history"],"AuditChecklist": ["Is the responsibility and role for information protection and personal information protection clearly defined with the cloud service provider, and is it reflected in contracts (such as SLA)?","Are security risks based on the service type evaluated when using cloud services, and are security control policies established and implemented, including security configurations and setting standards, security setting changes and approval procedures, secure connection methods, and authority systems to prevent unauthorized access and configuration errors?","Are administrator privileges for cloud services granted minimally according to roles, and are enhanced protection measures such as strengthened authentication, encryption, access control, and audit logs applied to prevent unauthorized access and abuse of privileges?","Is the monitoring of cloud service security setting changes and operation status conducted, and is the appropriateness of these settings reviewed regularly?"],"NonComplianceCases": ["Case 1: The cloud service contract does not include responsibilities and roles related to security.","Case 2: Employees without a business need have been excessively granted permissions to change the security settings of the cloud service.","Case 3: Internal guidelines require security officer approval when changing access control rules in the private network of the cloud, but many access control rules were registered or changed without following the approval procedure.","Case 4: Due to security setting errors in the cloud service, internal log files were exposed to the internet."],"RelatedRegulations": []}],"description": "When using cloud services, protection measures must be established and implemented for administrator access and security settings to prevent unauthorized access and configuration errors that could lead to the leakage or exposure of critical information and personal data, depending on the service type (SaaS, PaaS, IaaS, etc.).","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.10.3": {"name": "Public Server Security","checks": {"elb_ssl_listeners": "FAIL","elbv2_ssl_listeners": "FAIL","ssm_document_secrets": "PASS","elbv2_waf_acl_attached": "FAIL","elb_insecure_ssl_ciphers": "PASS","apigateway_restapi_public": "FAIL","lightsail_database_public": null,"lightsail_instance_public": null,"elbv2_insecure_ssl_ciphers": "PASS","lightsail_static_ip_unused": null,"networkfirewall_in_all_vpc": "FAIL","ec2_instance_imdsv2_enabled": "PASS","elbv2_desync_mitigation_mode": "FAIL","awslambda_function_inside_vpc": "FAIL","awslambda_function_url_public": null,"ec2_instance_secrets_user_data": "PASS","ec2_launch_template_no_secrets": "PASS","ssm_managed_compliant_patching": "FAIL","inspector2_active_findings_exist": "FAIL","acm_certificates_expiration_check": "PASS","awslambda_function_url_cors_policy": null,"cloudfront_distributions_using_waf": null,"vpc_subnet_separate_private_public": "FAIL","apigateway_restapi_waf_acl_attached": "FAIL","apigatewayv2_api_authorizers_enabled": "FAIL","awslambda_function_no_secrets_in_code": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","apigateway_restapi_authorizers_enabled": "PASS","cloudfront_distributions_https_enabled": null,"ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","apigateway_restapi_public_with_authorizer": "FAIL","ec2_instance_port_ftp_exposed_to_internet": "PASS","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","awslambda_function_no_secrets_in_variables": "PASS","awslambda_function_not_publicly_accessible": "PASS","ec2_instance_port_cifs_exposed_to_internet": "PASS","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","route53_domains_privacy_protection_enabled": null,"ec2_instance_port_kafka_exposed_to_internet": "PASS","ec2_instance_port_mysql_exposed_to_internet": "PASS","ec2_instance_port_redis_exposed_to_internet": "PASS","ec2_instance_port_oracle_exposed_to_internet": "PASS","ec2_instance_port_telnet_exposed_to_internet": "PASS","apigateway_restapi_client_certificate_enabled": "FAIL","ec2_instance_port_mongodb_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_instance_port_kerberos_exposed_to_internet": "PASS","ec2_instance_port_cassandra_exposed_to_internet": "PASS","ec2_instance_port_memcached_exposed_to_internet": "PASS","ec2_instance_port_sqlserver_exposed_to_internet": "PASS","kafka_cluster_mutual_tls_authentication_enabled": null,"ec2_instance_port_postgresql_exposed_to_internet": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","autoscaling_find_secrets_ec2_launch_configuration": "PASS","ec2_instance_internet_facing_with_instance_profile": "FAIL","cloudfront_distributions_using_deprecated_ssl_protocols": null,"ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","ec2_instance_port_elasticsearch_kibana_exposed_to_internet": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Protective Measure Requirements","Section": "2.10.3 Public Server Security","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Network diagram","Website information disclosure procedures and history (e.g., requests, approvals, posting history)","Inspection history of personal and sensitive information exposure"],"AuditChecklist": ["Are protective measures established and implemented for the operation of public servers?","Are public servers installed in a DMZ separated from internal networks and protected by security systems such as firewalls?","When posting or storing personal or sensitive information on public servers, are approval and posting procedures, including obtaining approval from the responsible person, established and followed?","Does the organization regularly check whether sensitive information is being exposed through websites and web servers, and if exposure is detected, are measures taken immediately to block it?"],"NonComplianceCases": ["Case 1: Due to vulnerabilities in publicly exposed websites, unauthorized individuals were able to access others' personal information through Google search.","Case 2: Although internal regulations require approval procedures before posting personal information on websites, there were multiple cases where personal information was posted without following these procedures.","Case 3: In web applications such as bulletin boards, it was possible to arbitrarily modify or delete posts made by others, or view password-protected posts."],"RelatedRegulations": []}],"description": "For servers exposed to external networks, protective measures must be established and implemented, including separating them from internal networks, conducting vulnerability assessments, access control, authentication, and establishing procedures for information collection, storage, and disclosure.","checks_status": {"fail": 19,"pass": 47,"total": 76,"manual": 0}},"2.10.4": {"name": "Security for Electronic Transactions and FinTech","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.10.4 Security for Electronic Transactions and FinTech","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Protection measures for electronic transaction and FinTech services","Security review results for payment system integration"],"AuditChecklist": ["Are protection measures established and implemented to ensure the safety and reliability of transactions when providing electronic transaction and FinTech services?","Are protection measures established and implemented to protect transmitted information when integrating with external systems, such as payment systems, and is the security of the integration checked?"],"NonComplianceCases": ["Case 1: While a contract was made with a payment service provider and integration was established, all payment-related information was transmitted in plain text through a specific URL without appropriate authentication or access restrictions.","Case 2: Although the external payment system was connected via a dedicated network, internal business systems were not properly controlled by firewalls or other security measures.","Case 3: Although internal guidelines required a security review by the information protection team before integrating external FinTech services, the review was skipped due to scheduling reasons when integrating a new FinTech service."],"RelatedRegulations": []}],"description": "When providing electronic transaction and FinTech services, protection measures such as authentication and encryption must be established to prevent data leakage, data tampering, or fraud. The security of external systems, such as payment systems, must be checked when integrated.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.10.5": {"name": "Secure Information Transmission","checks": {"elb_ssl_listeners": "FAIL","elbv2_ssl_listeners": "FAIL","elb_insecure_ssl_ciphers": "PASS","elbv2_insecure_ssl_ciphers": "PASS","rds_instance_transport_encrypted": "FAIL","s3_bucket_secure_transport_policy": "FAIL","glue_database_connections_ssl_enabled": null,"cloudfront_distributions_https_enabled": null,"sns_subscription_not_using_http_endpoints": "PASS","kafka_cluster_in_transit_encryption_enabled": null,"apigateway_restapi_client_certificate_enabled": "FAIL","kafka_cluster_mutual_tls_authentication_enabled": null,"directoryservice_radius_server_security_protocol": null,"cloudfront_distributions_using_deprecated_ssl_protocols": null,"elasticache_redis_cluster_in_transit_encryption_enabled": null,"opensearch_service_domains_https_communications_enforced": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.10.5 Secure Information Transmission","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Information transmission agreement or contract","Technical standards for information transmission","System diagrams and interface definitions related to information transmission"],"AuditChecklist": ["Has a secure transmission policy been established when transmitting personal and critical information to external organizations?","When exchanging personal and critical information between organizations for business purposes, are agreements and protection measures for secure transmission established and implemented?"],"NonComplianceCases": ["Case 1: Although a dedicated network or VPN is applied when integrating with external organizations, there is inadequate management of the timing, method, responsible person, transmitted information, and legal basis for each integration.","Case 2: There is a lack of implementation of security reviews, security standards, and action plans for using weak encryption algorithms (e.g., DES, 3DES) or decrypting during intermediate transmission stages."],"RelatedRegulations": []}],"description": "When transmitting personal or critical information to other organizations, a secure transmission policy must be established, and agreements must be made between organizations regarding management responsibilities, transmission methods, and technical protection measures for personal and critical information.","checks_status": {"fail": 5,"pass": 3,"total": 17,"manual": 0}},"2.10.6": {"name": "Security for Business Devices","checks": {"workspaces_volume_encryption_enabled": null,"appstream_fleet_maximum_session_duration": null,"appstream_fleet_session_disconnect_timeout": null,"workspaces_vpc_2private_1public_subnets_nat": null,"appstream_fleet_session_idle_disconnect_timeout": null,"appstream_fleet_default_internet_access_disabled": null},"status": "PASS","attributes": [{"Domain": "2. Protection Measure Requirements","Section": "2.10.6 Security for Business Devices","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Security control guidelines and procedures for business devices","Registration status of business devices","Security settings for business devices","Authentication and approval history for business devices","Security check status for business devices"],"AuditChecklist": ["Are security control policies, such as device authentication, approval, access scope, and security settings, established and implemented for devices used for business purposes, such as PCs, laptops, virtual PCs, and tablets?","Are policies established and implemented to prevent the leakage of personal and critical information through business devices by prohibiting the use of file-sharing programs, limiting shared settings, and controlling wireless network usage?","Are security measures applied to prevent the leakage of personal and critical information in case of loss or theft of business mobile devices?","Is the appropriateness of access control measures for business devices periodically reviewed?"],"NonComplianceCases": ["Case 1: Although laptops and tablet PCs are used for business purposes, there are no policies established for device approval, usage scope, approval procedures, or authentication methods.","Case 2: The security management guidelines for mobile devices prohibit the use of mobile devices for business purposes unless specifically approved, but unapproved mobile devices are still being used to access internal information systems.","Case 3: Personal and critical information is handled on mobile devices, but security measures such as password protection are not applied to prevent leaks due to loss or theft.","Case 4: Although internal regulations prohibit the use of shared folders on business devices, periodic checks are not conducted, resulting in excessive use of shared folders on many business devices."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 6 (Access Control)"]}],"description": "When connecting devices such as PCs and mobile devices to the network for business purposes, access control measures such as device authentication, approval, access scope, and security settings must be established and periodically checked.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"2.10.7": {"name": "Management of Removable Media","checks": {},"status": "PASS","attributes": [{"Domain": "2. Security Control Requirements","Section": "2.10.7 Management of Removable Media","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Policy on blocking removable media (USB, CD, etc.)","Removable media management log","Inspection records of removable media status"],"AuditChecklist": ["Are policies and procedures established and implemented for handling (use), storage, disposal, and reuse of removable media such as external hard drives, USB memory, and CDs?","Is the status of ownership, use, and management of removable media periodically checked?","Is the use of removable media restricted in controlled areas, such as key information systems or important restricted areas?","Are measures in place to prevent the infection of malware and the leakage of important information through removable media?","Are removable media containing personal or important information stored in a secure location with locking mechanisms?"],"NonComplianceCases": ["Case 1: Although there is a policy restricting the use of removable media in controlled areas like server rooms, several cases were found where removable media was used without following the exception approval process, and periodic inspections of the removable media management status were not conducted, resulting in inadequate updates to the management log.","Case 2: Removable media containing personal information was not stored in a secure location with locking mechanisms and was left unattended in office drawers.","Case 3: Although a solution to control removable media was implemented, some users were granted write access without appropriate approval procedures.","Case 4: Some common PCs and IT equipment in the server room allowed writing to standard USB memory devices, but controls such as media import and usage restrictions, usage history records, and reviews were not applied."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 10 (Physical Safety Measures)"]}],"description": "Procedures must be established and implemented to prevent the leakage of personal or important information or infection by malware through removable media. Removable media containing personal or important information must be stored in a secure location.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.10.8": {"name": "Patch Management","checks": {"ssm_managed_compliant_patching": "FAIL","kafka_cluster_uses_latest_version": null,"ec2_instance_account_imdsv2_enabled": null,"redshift_cluster_automatic_upgrades": null,"eks_cluster_uses_a_supported_version": null,"ec2_instance_older_than_specific_days": "FAIL","rds_instance_deprecated_engine_version": "PASS","rds_cluster_minor_version_upgrade_enabled": "PASS","dms_instance_minor_version_upgrade_enabled": null,"rds_instance_minor_version_upgrade_enabled": "PASS","awslambda_function_using_supported_runtimes": "FAIL","elasticache_redis_cluster_auto_minor_version_upgrades": null,"cloudfront_distributions_using_deprecated_ssl_protocols": null,"opensearch_service_domains_updated_to_the_latest_service_software_version": null},"status": "FAIL","attributes": [{"Domain": "2. Security Control Requirements","Section": "2.10.8 Patch Management","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Patch management policies and procedures","Patch status of each system","Impact analysis results related to patch application"],"AuditChecklist": ["Are patch management policies and procedures for operating systems (OS) and software established and implemented according to the characteristics and importance of each asset, such as servers, network systems, security systems, and PCs?","Are the patch status of installed OS and software on key servers, network systems, and security systems periodically managed?","If applying the latest patches to address vulnerabilities is difficult due to service impact, are alternative measures implemented?","Is the application of patches via public internet access restricted for key servers, network systems, and security systems?","When using a patch management system, are sufficient protection measures, such as access control, established?"],"NonComplianceCases": ["Case 1: In some systems, OS patches were not applied for a long period without valid reasons or approval from the responsible personnel.","Case 2: Some systems were using OS versions that were no longer supported (EOS), but no response plans or alternative measures were in place.","Case 3: Although the latest patches were applied to commercial software and OS, there were no procedures or personnel assigned to confirm and apply the latest patches for open-source programs (e.g., OpenSSL, OpenSSH, Apache), resulting in the lack of application of the latest security patches."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 9 (Prevention of Malware, etc.)"]}],"description": "To prevent security incidents due to vulnerabilities in software, operating systems, or security systems, the latest patches must be applied. However, if the application of the latest patches is difficult due to service impact considerations, alternative measures must be implemented.","checks_status": {"fail": 3,"pass": 3,"total": 14,"manual": 0}},"2.10.9": {"name": "Malware Control","checks": {},"status": "PASS","attributes": [{"Domain": "2. Security Control Requirements","Section": "2.10.9 Malware Control","Subdomain": "2.10. System and Service Security Management","AuditEvidence": ["Guidelines, procedures, and manuals for malware response","Antivirus program installation status","Antivirus program configuration screens","Malware response history (e.g., response reports)"],"AuditChecklist": ["Are protection measures established and implemented to protect information systems and business terminals from malware such as viruses, worms, Trojans, and ransomware?","Are prevention and detection activities for the latest malware continuously performed using security programs such as antivirus software?","Are security programs such as antivirus software kept up to date, and are emergency security updates performed when necessary?","Are procedures for response, such as minimizing the spread of malware and mitigating damage, established and implemented when malware infections are discovered?"],"NonComplianceCases": ["Case 1: Some PCs and servers do not have antivirus software installed, or the antivirus engine has not been updated to the latest version for a long time.","Case 2: Although users can change the antivirus program settings (e.g., real-time scanning, scheduled scanning, update settings) at their discretion, no additional protection measures were established to address this.","Case 3: Insufficient protection measures, such as access control, were in place for the central antivirus management system, leading to the possibility of security incidents through the central management system, or no integrity verification of the antivirus pattern was performed, making it possible for malware to spread through malicious users.","Case 4: Although multiple malware infections were confirmed on some internal network PCs and servers, there was no confirmation of the infection status, infection routes, cause analysis, or resulting actions."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 9 (Prevention of Malware, etc.)"]}],"description": "To protect personal and important information, information systems, and business terminals from malware such as viruses, worms, Trojans, and ransomware, prevention, detection, and response measures must be established and implemented.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.11.1": {"name": "Establishment of Incident Prevention and Response System","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protective Measures Requirements","Section": "2.11.1 Establishment of Incident Prevention and Response System","Subdomain": "2.11. Incident Prevention and Response","AuditEvidence": ["Incident response guidelines/procedures/manual","Incident response organization chart and emergency contact list","Security monitoring service contract (SLA, etc.)"],"AuditChecklist": ["Has the organization established procedures and systems to prevent security breaches and personal information leaks and to respond quickly and effectively when incidents occur?","If the organization is operating an incident response system through an external institution, such as a security monitoring service, are the details of the incident response procedures reflected in the contract?","Has the organization established a cooperative system with external experts, specialized companies, or institutions for monitoring, responding to, and handling security incidents?"],"NonComplianceCases": ["Case 1: Failure to clearly define the incident response organization and procedures for responding to security breaches.","Case 2: Although internal guidelines and procedures specify incident response steps for different phases (before, during, after detection, recovery, reporting, etc.), some or all of the response and recovery procedures for specific incident types and severity levels are not established.","Case 3: Failure to keep the incident response organization chart and emergency contact list up to date, or the roles and responsibilities of each team member are not clearly defined.","Case 4: Errors or outdated information in the contact details for external agencies responsible for incident reporting, notification, and cooperation, or failure to keep some agency details current.","Case 5: When outsourcing incident detection and response to an external security monitoring company or related institution, failure to clearly define the roles and responsibilities for both parties in the contract or SLA.","Case 6: Although incident response procedures are in place, they do not meet the legal requirements for reporting and notifying personal data breaches, such as criteria and timing."],"RelatedRegulations": ["Personal Information Protection Act, Article 34 (Notification and Reporting of Personal Information Leaks, etc.)","Information and Communications Network Act, Article 48-3 (Reporting of Security Incidents), Article 48-4 (Analysis of Causes of Security Incidents, etc.)"]}],"description": "To prevent incidents such as security breaches and personal information leaks, and to respond quickly and effectively in the event of an incident, the organization must establish procedures for detecting, responding to, analyzing, and sharing internal and external intrusion attempts. In addition, the organization must establish a cooperative system with relevant external institutions and experts.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.11.2": {"name": "Vulnerability Inspection and Remediation","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ssm_document_secrets": "PASS","inspector2_is_enabled": "FAIL","ec2_instance_imdsv2_enabled": "PASS","guardduty_centrally_managed": "FAIL","ec2_instance_secrets_user_data": "PASS","ec2_launch_template_no_secrets": "PASS","inspector2_active_findings_exist": "FAIL","trustedadvisor_errors_and_warnings": null,"guardduty_no_high_severity_findings": "FAIL","awslambda_function_no_secrets_in_code": "PASS","cloudwatch_log_group_no_secrets_in_logs": "FAIL","ecr_registry_scan_images_on_push_enabled": "PASS","cloudformation_stack_outputs_find_secrets": "PASS","codebuild_project_no_secrets_in_variables": "PASS","awslambda_function_no_secrets_in_variables": "PASS","ecs_task_definitions_no_environment_secrets": "PASS","ecr_repositories_scan_images_on_push_enabled": "FAIL","trustedadvisor_premium_support_plan_subscribed": null,"autoscaling_find_secrets_ec2_launch_configuration": "PASS","ecr_repositories_scan_vulnerabilities_in_latest_image": null,"codebuild_project_source_repo_url_no_sensitive_credentials": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. Protective Measures Requirements","Section": "2.11.2 Vulnerability Inspection and Remediation","Subdomain": "2.11. Incident Prevention and Response","AuditEvidence": ["Vulnerability inspection plan","Vulnerability inspection report (for web, mobile apps, servers, network systems, security systems, DBMS, etc.)","Vulnerability inspection records","Vulnerability remediation plan","Vulnerability remediation completion report","Penetration testing plan/results report"],"AuditChecklist": ["Has the organization established and implemented procedures for conducting regular vulnerability inspections of information systems?","Are actions taken to address identified vulnerabilities, and are the results reported to the responsible authorities?","Does the organization continuously monitor for new security vulnerabilities and assess their impact on the information systems, taking appropriate actions?","Is a record of vulnerability inspections maintained, and are protective measures implemented to address recurring vulnerabilities identified in previous years?"],"NonComplianceCases": ["Case 1: Although internal regulations require annual technical vulnerability inspections for major systems, some major systems were excluded from the inspection.","Case 2: Failure to implement corrective actions for identified vulnerabilities, or failure to provide justification and approval records for vulnerabilities that cannot be addressed promptly."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 4 (Establishment, Implementation, and Inspection of Internal Management Plans), Article 6 (Access Control)"]}],"description": "Regular vulnerability inspections must be conducted to verify whether information systems have exposed vulnerabilities, and any identified vulnerabilities must be promptly addressed. In addition, the organization must continuously monitor for new security vulnerabilities, assess their impact on the information systems, and take necessary actions.","checks_status": {"fail": 6,"pass": 14,"total": 23,"manual": 0}},"2.11.3": {"name": "Abnormal Behavior Analysis and Monitoring","checks": {"securityhub_enabled": "PASS","fms_policy_compliant": null,"vpc_flow_logs_enabled": "FAIL","cloudtrail_insights_exist": null,"networkfirewall_in_all_vpc": "FAIL","trustedadvisor_errors_and_warnings": null,"guardduty_no_high_severity_findings": "FAIL","cloudtrail_threat_detection_enumeration": null,"cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_cross_account_sharing_disabled": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cognito_user_pool_client_prevent_user_existence_errors": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protection Measures Requirements","Section": "2.11.3 Abnormal Behavior Analysis and Monitoring","Subdomain": "2.11. Incident Prevention and Response","AuditEvidence": ["Status of abnormal behavior analysis and monitoring","Evidence of responses taken when abnormal behaviors were detected"],"AuditChecklist": ["Is the organization collecting, analyzing, and monitoring network traffic, data flows, and event logs from major information systems, applications, networks, and security systems to detect abnormal behaviors such as intrusion attempts, personal information leakage attempts, or fraudulent activities?","Has the organization defined criteria and thresholds to determine abnormal behaviors, and is follow-up action, such as the determination and investigation of abnormal activities, taken in a timely manner?"],"NonComplianceCases": ["Case 1: Failure to establish a real-time or regular monitoring system and procedures to detect intrusion attempts on servers, networks, databases, and security systems from external sources.","Case 2: Although the organization has outsourced monitoring tasks to an external security monitoring agency, there is no record of reviewing the reports provided by the agency, and the organization does not have its own monitoring system for systems excluded from the outsourced service.","Case 3: Although abnormal traffic exceeding internally defined thresholds has been continuously detected, no response measures have been taken."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 6 (Access Control)"]}],"description": "To quickly detect and respond to intrusion attempts, personal information leakage attempts, and fraudulent activities from internal or external sources, the organization must collect and analyze network and data flows. Post-monitoring and inspection actions must be timely.","checks_status": {"fail": 6,"pass": 1,"total": 28,"manual": 0}},"2.11.4": {"name": "Incident Response Training and Improvement","checks": {"ssmincidents_enabled_with_plans": null},"status": "PASS","attributes": [{"Domain": "2. Protection Measures Requirements","Section": "2.11.4 Incident Response Training and Improvement","Subdomain": "2.11. Incident Prevention and Response","AuditEvidence": ["Simulation training plan for responding to security and personal information leakage incidents","Simulation training result reports for responding to security and personal information leakage incidents","Incident response procedures"],"AuditChecklist": ["Has the organization established a simulation training plan for responding to security incidents and personal information leakage incidents, and are such training exercises conducted at least once a year?","Is the organization reflecting the results of security incident and personal information leakage incident training to improve its response system?"],"NonComplianceCases": ["Case 1: Failure to conduct simulation training or provide related training plans and result reports.","Case 2: Although an annual simulation training plan for security incidents was established, it was not conducted within the planned period without valid reason or approval.","Case 3: Simulation training was conducted, but it was not performed according to the procedures and forms defined in the internal guidelines."],"RelatedRegulations": []}],"description": "The organization must conduct at least one simulation training per year based on scenarios to ensure that employees and stakeholders are familiar with the procedures for responding to security incidents and personal information leakage incidents. The response system must be improved based on the training results.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"2.11.5": {"name": "Incident Response and Recovery","checks": {},"status": "PASS","attributes": [{"Domain": "2. Protection Measures Requirements","Section": "2.11.5 Incident Response and Recovery","Subdomain": "2.11. Incident Prevention and Response","AuditEvidence": ["Incident response procedures","Incident response reports","Incident management logs","Personal information leakage reports","Emergency contact list"],"AuditChecklist": ["When signs of or actual incidents of security breaches or personal information leakage are detected, is the organization responding and reporting promptly according to the defined incident response procedures?","Is the organization notifying data subjects and reporting to relevant authorities as required by law in case of a personal information breach?","After the incident is resolved, is the organization analyzing the cause, reporting the results, and sharing them with relevant departments and personnel?","Is the organization utilizing the information obtained from incident analysis to establish preventive measures to prevent similar incidents from recurring, and if necessary, modifying its incident response procedures?"],"NonComplianceCases": ["Case 1: Although internal incident response guidelines require that security incidents be reported to the internal information protection committee and relevant departments, the department in charge responded to the incident independently without reporting to the information protection committee or relevant departments.","Case 2: Although a service outage suspected to be caused by a DDoS attack occurred recently, the organization did not analyze the cause or establish preventive measures.","Case 3: Although a personal information leakage incident occurred due to external hacking, notification and reporting were not made within 72 hours, citing the small number of affected personal information records as the reason.","Case 4: Although personal information of more than 1,000 individuals was leaked due to an employee's mistake on the company website, the affected data subjects were not notified."],"RelatedRegulations": ["Personal Information Protection Act, Article 34 (Notification and Reporting of Personal Information Leakage)","Information and Communications Network Act, Article 48-3 (Reporting of Security Incidents), Article 48-4 (Analysis of Causes of Security Incidents)"]}],"description": "When signs of or actual incidents of security breaches or personal information leakage are detected, the organization must comply with legal notification and reporting obligations, respond and recover promptly according to established procedures, and analyze the incident to establish preventive measures to reflect in the response system.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.12.1": {"name": "Safety Measures for Disaster Preparedness","checks": {"drs_job_exist": "FAIL","backup_plans_exist": "PASS","rds_cluster_multi_az": "FAIL","elb_is_in_multiple_az": "FAIL","rds_instance_multi_az": "FAIL","s3_bucket_object_lock": "FAIL","vpc_different_regions": null,"efs_have_backup_enabled": "FAIL","elbv2_is_in_multiple_az": "PASS","vpc_subnet_different_az": "PASS","backup_reportplans_exist": null,"neptune_cluster_multi_az": null,"elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_lifecycle_enabled": "FAIL","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"autoscaling_group_multiple_az": null,"dms_instance_multi_az_enabled": null,"ec2_ebs_volume_snapshots_exists": "FAIL","rds_cluster_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL","documentdb_cluster_backup_enabled": null,"s3_bucket_cross_region_replication": "FAIL","kms_cmk_not_deleted_unintentionally": null,"neptune_cluster_deletion_protection": null,"redshift_cluster_automated_snapshot": null,"elb_cross_zone_load_balancing_enabled": "PASS","lightsail_instance_automated_snapshots": null,"dlm_ebs_snapshot_lifecycle_policy_exists": "FAIL","documentdb_cluster_cloudwatch_log_export": null,"elasticache_redis_cluster_backup_enabled": null,"elasticache_redis_cluster_multi_az_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protective Measure Requirements","Section": "2.12.1 Safety Measures for Disaster Preparedness","Subdomain": "2.12. Disaster Recovery","AuditEvidence": ["IT disaster recovery guidelines/procedures","IT disaster recovery plans (including RTO and RPO definitions)","Emergency contact list","Crisis response manual for personal information processing systems"],"AuditChecklist": ["Has the organization identified IT disaster types that could threaten the continuity of core services (businesses) and analyzed the expected scale of damage and impact on operations to identify core IT services (businesses) and systems?","Has the organization defined recovery time objectives (RTO) and recovery point objectives (RPO) based on the importance and characteristics of core IT services and systems?","Has the organization established and implemented disaster recovery plans, including recovery strategies, emergency recovery teams, emergency contact networks, and recovery procedures, to ensure the continuity of core services and systems during disasters?"],"NonComplianceCases": ["Case 1: The IT disaster recovery procedures lack critical details such as the definition of IT disaster recovery teams and roles, emergency contact systems, and recovery procedures and methods.","Case 2: Although a backup center has been established to ensure the continuity of information systems and minimize damage during emergencies, the relevant policies do not include disaster recovery procedures using the backup center, making disaster recovery tests and actual recovery efforts ineffective.","Case 3: Recovery time objectives for some critical systems related to service operations have not been defined, and appropriate recovery strategies are not in place.","Case 4: The disaster recovery guidelines do not define the recovery priorities, RTO, or RPO for IT services or systems.","Case 5: Unrealistic recovery objectives have been set, either too high or too low, and the RPO and backup policies (e.g., targets, frequency) are not appropriately linked, making it difficult to ensure the effectiveness of recovery."],"RelatedRegulations": ["Personal Information Protection Act, Article 29 (Obligation to Take Safety Measures)","Standards for Ensuring the Safety of Personal Information, Article 11 (Safety Measures for Disaster Preparedness)"]}],"description": "Identify types of disasters that could threaten the operational continuity of the organization's core services and systems, such as natural disasters, communication or power failures, and hacking. Analyze the expected scale of damage and impact for each type, define the recovery time objective (RTO) and recovery point objective (RPO), and establish a disaster recovery system including recovery strategies, emergency recovery teams, emergency contact networks, and recovery procedures.","checks_status": {"fail": 14,"pass": 5,"total": 33,"manual": 0}},"2.12.2": {"name": "Disaster Recovery Testing and Improvement","checks": {"drs_job_exist": "FAIL","backup_plans_exist": "PASS","rds_cluster_multi_az": "FAIL","elb_is_in_multiple_az": "FAIL","rds_instance_multi_az": "FAIL","s3_bucket_object_lock": "FAIL","vpc_different_regions": null,"efs_have_backup_enabled": "FAIL","elbv2_is_in_multiple_az": "PASS","vpc_subnet_different_az": "PASS","backup_reportplans_exist": null,"neptune_cluster_multi_az": null,"elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_lifecycle_enabled": "FAIL","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"autoscaling_group_multiple_az": null,"dms_instance_multi_az_enabled": null,"ec2_ebs_volume_snapshots_exists": "FAIL","rds_cluster_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL","documentdb_cluster_backup_enabled": null,"s3_bucket_cross_region_replication": "FAIL","kms_cmk_not_deleted_unintentionally": null,"neptune_cluster_deletion_protection": null,"redshift_cluster_automated_snapshot": null,"elb_cross_zone_load_balancing_enabled": "PASS","lightsail_instance_automated_snapshots": null,"dlm_ebs_snapshot_lifecycle_policy_exists": "FAIL","documentdb_cluster_cloudwatch_log_export": null,"elasticache_redis_cluster_backup_enabled": null,"elasticache_redis_cluster_multi_az_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. Protective Measure Requirements","Section": "2.12.2 Disaster Recovery Testing and Improvement","Subdomain": "2.12. Disaster Recovery","AuditEvidence": ["IT disaster recovery procedures","IT disaster recovery test plans","IT disaster recovery test results"],"AuditChecklist": ["Has the organization established and implemented disaster recovery test plans to evaluate the effectiveness of the established IT disaster recovery system?","Are the disaster recovery strategies and plans regularly reviewed and supplemented to reflect test results, changes in the information system environment, and legal requirements?"],"NonComplianceCases": ["Case 1: Disaster recovery drills were not planned or conducted, and the related plans and result reports are not available.","Case 2: Although a disaster recovery drill plan was established, it was not conducted as planned or approved, and the related result reports are missing.","Case 3: Disaster recovery drills were conducted, but they did not follow the procedures and forms outlined in the internal guidelines, making it difficult to evaluate the adequacy and effectiveness of the disaster recovery procedures."],"RelatedRegulations": []}],"description": "Regularly test the adequacy of the disaster recovery strategies and plans, and supplement the recovery strategies and plans based on test results, changes in the information system environment, and legal requirements.","checks_status": {"fail": 14,"pass": 5,"total": 33,"manual": 0}}},"requirements_passed": 10,"requirements_failed": 27,"requirements_manual": 64,"total_requirements": 101,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "23a633ec-caa6-4021-809a-a247c6f177e6","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "nist_csf_1.1_aws","framework": "NIST-CSF","version": "1.1","description": "The NIST Cybersecurity Framework (CSF) is supported by governments and industries worldwide as a recommended baseline for use by any organization, regardless of sector or size. The NIST Cybersecurity Framework consists of three primary components: the framework core, the profiles, and the implementation tiers. The framework core contains desired cybersecurity activities and outcomes organized into 23 categories that cover the breadth of cybersecurity objectives for an organization. The profiles contain an organization's unique alignment of their organizational requirements and objectives, risk appetite, and resources using the desired outcomes of the framework core. The implementation tiers describe the degree to which an organization’s cybersecurity risk management practices exhibit the characteristics defined in the framework core.","region": "eu-west-1","requirements": {"ac_1": {"name": "PR.AC-1","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_password_policy_reuse_24": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_1","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Identity Management and Access Control (PR.AC)"}],"description": "Identities and credentials are issued, managed, verified, revoked, and audited for authorized devices, users and processes.","checks_status": {"fail": 1,"pass": 0,"total": 9,"manual": 0}},"ac_3": {"name": "PR.AC-3","checks": {"iam_root_mfa_enabled": null,"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"iam_root_hardware_mfa_enabled": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"iam_user_mfa_enabled_console_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Identity Management and Access Control (PR.AC)"}],"description": "Remote access is managed.","checks_status": {"fail": 3,"pass": 6,"total": 20,"manual": 0}},"ac_4": {"name": "PR.AC-4","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_4","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Identity Management and Access Control (PR.AC)"}],"description": "Access permissions and authorizations are managed, incorporating the principles of least privilege and separation of duties.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"ac_5": {"name": "PR.AC-5","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"acm_certificates_expiration_check": "PASS","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_5","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Identity Management and Access Control (PR.AC)"}],"description": "Network integrity is protected (e.g., network segregation, network segmentation).","checks_status": {"fail": 3,"pass": 7,"total": 17,"manual": 0}},"ac_6": {"name": "PR.AC-6","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_6","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Identity Management and Access Control (PR.AC)"}],"description": "Identities are proofed and bound to credentials and asserted in interactions.","checks_status": {"fail": 1,"pass": 1,"total": 4,"manual": 0}},"ac_7": {"name": "PR.AC-7","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_7","Section": "Protect (PR)","Service": "iam","SubGroup": null,"SubSection": "Identity Management and Access Control (PR.AC)"}],"description": "Users, devices, and other assets are authenticated (e.g., single-factor, multi-factor) commensurate with the risk of the transaction (e.g., individuals’ security and privacy risks and other organizational risks).","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ae_1": {"name": "DE.AE-1","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","s3_bucket_server_access_logging_enabled": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ae_1","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Anomalies and Events (DE.AE)"}],"description": "A baseline of network operations and expected data flows for users and systems is established and managed.","checks_status": {"fail": 7,"pass": 3,"total": 13,"manual": 0}},"ae_2": {"name": "DE.AE-2","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ae_2","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Anomalies and Events (DE.AE)"}],"description": "Detected events are analyzed to understand attack targets and methods.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"ae_3": {"name": "DE.AE-3","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ae_3","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Anomalies and Events (DE.AE)"}],"description": "Event data are collected and correlated from multiple sources and sensors.","checks_status": {"fail": 5,"pass": 2,"total": 11,"manual": 0}},"ae_4": {"name": "DE.AE-4","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ae_4","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Anomalies and Events (DE.AE)"}],"description": "Impact of events is determined.","checks_status": {"fail": 4,"pass": 3,"total": 10,"manual": 0}},"ae_5": {"name": "DE.AE-5","checks": {"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ae_5","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Anomalies and Events (DE.AE)"}],"description": "Incident alert thresholds are established.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"am_1": {"name": "ID.AM-1","checks": {"ec2_instance_managed_by_ssm": "FAIL","config_recorder_all_regions_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "am_1","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Asset Management (ID.AM)"}],"description": "Physical devices and systems within the organization are inventoried.","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"am_2": {"name": "ID.AM-2","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "am_2","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Asset Management (ID.AM)"}],"description": "Software platforms and applications within the organization are inventoried.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"am_3": {"name": "ID.AM-3","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "am_3","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Asset Management (ID.AM)"}],"description": "Organizational communication and data flows are mapped.","checks_status": {"fail": 4,"pass": 2,"total": 8,"manual": 0}},"am_5": {"name": "ID.AM-5","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "am_5","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Asset Management (ID.AM)"}],"description": "Resources (e.g., hardware, devices, data, time, personnel, and software) are prioritized based on their classification, criticality, and business value.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"am_6": {"name": "ID.AM-6","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "am_6","Section": "Identify (ID)","Service": "iam","SubGroup": null,"SubSection": "Asset Management (ID.AM)"}],"description": "Cybersecurity roles and responsibilities for the entire workforce and third-party stakeholders (e.g., suppliers, customers, partners) are established.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"an_2": {"name": "RS.AN-2","checks": {"guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "an_2","Section": "Respond (RS)","Service": "guardduty","SubGroup": null,"SubSection": "Analysis (RS.AN)"}],"description": "The impact of the incident is understood.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"be_5": {"name": "ID.BE-5","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "be_5","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Business Environment (ID.BE)"}],"description": "Resilience requirements to support delivery of critical services are established for all operating states (e.g. under duress/attack, during recovery, normal operations)","checks_status": {"fail": 3,"pass": 1,"total": 4,"manual": 0}},"cm_1": {"name": "DE.CM-1","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_1","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Security Continuous Monitoring (DE.CM)"}],"description": "The network is monitored to detect potential cybersecurity events.","checks_status": {"fail": 4,"pass": 4,"total": 11,"manual": 0}},"cm_2": {"name": "DE.CM-2","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","config_recorder_all_regions_enabled": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_2","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Security Continuous Monitoring (DE.CM)"}],"description": "The physical environment is monitored to detect potential cybersecurity events.","checks_status": {"fail": 2,"pass": 3,"total": 20,"manual": 0}},"cm_3": {"name": "DE.CM-3","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_multi_region_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_3","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Security Continuous Monitoring (DE.CM)"}],"description": "Personnel activity is monitored to detect potential cybersecurity events.","checks_status": {"fail": 1,"pass": 3,"total": 7,"manual": 0}},"cm_4": {"name": "DE.CM-4","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "cm_4","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Security Continuous Monitoring (DE.CM)"}],"description": "Malicious code is detected.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"cm_5": {"name": "DE.CM-5","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_waf_acl_attached": "FAIL","ec2_instance_imdsv2_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_5","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Security Continuous Monitoring (DE.CM)"}],"description": "Unauthorized mobile code is detected.","checks_status": {"fail": 3,"pass": 3,"total": 10,"manual": 0}},"cm_6": {"name": "DE.CM-6","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_multi_region_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_6","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Security Continuous Monitoring (DE.CM)"}],"description": "External service provider activity is monitored to detect potential cybersecurity events.","checks_status": {"fail": 1,"pass": 3,"total": 7,"manual": 0}},"cm_7": {"name": "DE.CM-7","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_7","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Security Continuous Monitoring (DE.CM)"}],"description": "Monitoring for unauthorized personnel, connections, devices, and software is performed.","checks_status": {"fail": 4,"pass": 4,"total": 11,"manual": 0}},"cp_4": {"name": "DE.DP-4","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_waf_acl_attached": "FAIL","ec2_instance_imdsv2_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_4","Section": "Detect (DE)","Service": "aws","SubGroup": null,"SubSection": "Detection Processes (DE.DP)"}],"description": "Event detection information is communicated.","checks_status": {"fail": 3,"pass": 3,"total": 10,"manual": 0}},"cp_5": {"name": "DE.DP-5","checks": {"ec2_instance_imdsv2_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "cp_5","Section": "Detect (DE)","Service": "ec2","SubGroup": null,"SubSection": "Detection Processes (DE.DP)"}],"description": "Detection processes are continuously improved.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ds_1": {"name": "PR.DS-1","checks": {"ec2_ebs_volume_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","cloudtrail_kms_encryption_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ds_1","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Data Security (PR.DS)"}],"description": "Data-at-rest is protected.","checks_status": {"fail": 5,"pass": 2,"total": 9,"manual": 0}},"ds_2": {"name": "PR.DS-2","checks": {"elb_ssl_listeners": "FAIL","acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ds_2","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Data Security (PR.DS)"}],"description": "Data-in-transit is protected.","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"ds_3": {"name": "PR.DS-3","checks": {"ec2_elastic_ip_unassigned": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ds_3","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Data Security (PR.DS)"}],"description": "Assets are formally managed throughout removal, transfers, and disposition.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"ds_4": {"name": "PR.DS-4","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ds_4","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Data Security (PR.DS)"}],"description": "Adequate capacity to ensure availability is maintained.","checks_status": {"fail": 4,"pass": 1,"total": 5,"manual": 0}},"ds_5": {"name": "PR.DS-5","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"cloudtrail_multi_region_enabled": "PASS","s3_bucket_policy_public_write_access": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"s3_account_level_public_access_blocks": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ds_5","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Data Security (PR.DS)"}],"description": "Protections against data leaks are implemented.","checks_status": {"fail": 4,"pass": 7,"total": 19,"manual": 0}},"ds_6": {"name": "PR.DS-6","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ds_6","Section": "Protect (PR)","Service": "cloudtrail","SubGroup": null,"SubSection": "Data Security (PR.DS)"}],"description": "Integrity checking mechanisms are used to verify software, firmware, and information integrity.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ds_7": {"name": "PR.DS-7","checks": {"elbv2_deletion_protection": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","ec2_instance_older_than_specific_days": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ds_7","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Data Security (PR.DS)"}],"description": "The development and testing environment(s) are separate from the production environment.","checks_status": {"fail": 5,"pass": 1,"total": 6,"manual": 0}},"ds_8": {"name": "PR.DS-8","checks": {"securityhub_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ds_8","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Data Security (PR.DS)"}],"description": "Integrity checking mechanisms are used to verify hardware integrity.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"ip_1": {"name": "PR.IP-1","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ip_1","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Information Protection Processes and Procedures (PR.IP)"}],"description": "A baseline configuration of information technology/industrial control systems is created and maintained incorporating security principles (e.g. concept of least functionality).","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"ip_2": {"name": "PR.IP-2","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ip_2","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Information Protection Processes and Procedures (PR.IP)"}],"description": "A System Development Life Cycle to manage systems is implemented.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ip_3": {"name": "PR.IP-3","checks": {"elbv2_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ip_3","Section": "Protect (PR)","Service": "elb","SubGroup": null,"SubSection": "Information Protection Processes and Procedures (PR.IP)"}],"description": "Configuration change control processes are in place.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ip_4": {"name": "PR.IP-4","checks": {"rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ip_4","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Information Protection Processes and Procedures (PR.IP)"}],"description": "Backups of information are conducted, maintained, and tested periodically.","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"ip_7": {"name": "PR.IP-7","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "ip_7","Section": "Protect (PR)","Service": "ec2","SubGroup": null,"SubSection": "Information Protection Processes and Procedures (PR.IP)"}],"description": "Protection processes are improved.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ip_8": {"name": "PR.IP-8","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"eks_cluster_not_publicly_accessible": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ip_8","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Information Protection Processes and Procedures (PR.IP)"}],"description": "Effectiveness of protection technologies is shared.","checks_status": {"fail": 1,"pass": 4,"total": 13,"manual": 0}},"ip_9": {"name": "PR.IP-9","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ip_9","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Information Protection Processes and Procedures (PR.IP)"}],"description": "Response plans (Incident Response and Business Continuity) and recovery plans (Incident Recovery and Disaster Recovery) are in place and managed.","checks_status": {"fail": 4,"pass": 1,"total": 10,"manual": 0}},"ma_2": {"name": "PR.MA-2","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ma_2","Section": "Protect (PR)","Service": "cloudtrail","SubGroup": null,"SubSection": "Maintenance (PR.MA)"}],"description": "Remote maintenance of organizational assets is approved, logged, and performed in a manner that prevents unauthorized access.","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"mi_3": {"name": "RS.MI-3","checks": {"guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "mi_3","Section": "Respond (RS)","Service": "guardduty","SubGroup": null,"SubSection": "Mitigation (RS.MI)"}],"description": "Newly identified vulnerabilities are mitigated or documented as accepted risks.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"pt_1": {"name": "PR.PT-1","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pt_1","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Protective Technology (PR.PT)"}],"description": "Audit/log records are determined, documented, implemented, and reviewed in accordance with policy.","checks_status": {"fail": 5,"pass": 2,"total": 8,"manual": 0}},"pt_3": {"name": "PR.PT-3","checks": {"iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","s3_account_level_public_access_blocks": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "pt_3","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Protective Technology (PR.PT)"}],"description": "The principle of least functionality is incorporated by configuring systems to provide only essential capabilities.","checks_status": {"fail": 0,"pass": 3,"total": 11,"manual": 0}},"pt_4": {"name": "PR.PT-4","checks": {"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pt_4","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Protective Technology (PR.PT)"}],"description": "Communications and control networks are protected.","checks_status": {"fail": 1,"pass": 3,"total": 6,"manual": 0}},"pt_5": {"name": "PR.PT-5","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pt_5","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Protective Technology (PR.PT)"}],"description": "Mechanisms (e.g., failsafe, load balancing, hot swap) are implemented to achieve resilience requirements in normal and adverse situations.","checks_status": {"fail": 3,"pass": 1,"total": 4,"manual": 0}},"ra_1": {"name": "ID.RA-1","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ra_1","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Risk Assessment (ID.RA)"}],"description": "Asset vulnerabilities are identified and documented.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"ra_2": {"name": "ID.RA-2","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_2","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Risk Assessment (ID.RA)"}],"description": "Cyber threat intelligence is received from information sharing forums and sources.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"ra_3": {"name": "ID.RA-3","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_3","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Risk Assessment (ID.RA)"}],"description": "Threats, both internal and external, are identified and documented.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"ra_5": {"name": "ID.RA-5","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","config_recorder_all_regions_enabled": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ra_5","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Risk Assessment (ID.RA)"}],"description": "Threats, vulnerabilities, likelihoods, and impacts are used to determine risk.","checks_status": {"fail": 2,"pass": 3,"total": 20,"manual": 0}},"rp_1": {"name": "RS.RP-1","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "rp_1","Section": "Respond (RS)","Service": "aws","SubGroup": null,"SubSection": "Response Planning (RS.RP)"}],"description": "Response plan is executed during or after an incident.","checks_status": {"fail": 4,"pass": 1,"total": 11,"manual": 0}},"sc_4": {"name": "ID.SC-4","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","config_recorder_all_regions_enabled": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_4","Section": "Identify (ID)","Service": "aws","SubGroup": null,"SubSection": "Supply Chain Risk Management (ID.SC)"}],"description": "Suppliers and third-party partners are routinely assessed using audits, test results, or other forms of evaluations to confirm they are meeting their contractual obligations.","checks_status": {"fail": 2,"pass": 3,"total": 16,"manual": 0}},"ip_12": {"name": "PR.IP-12","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","config_recorder_all_regions_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ip_12","Section": "Protect (PR)","Service": "aws","SubGroup": null,"SubSection": "Information Protection Processes and Procedures (PR.IP)"}],"description": "A vulnerability management plan is developed and implemented.","checks_status": {"fail": 2,"pass": 0,"total": 4,"manual": 0}}},"requirements_passed": 11,"requirements_failed": 42,"requirements_manual": 3,"total_requirements": 56,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "23ef3629-e1cd-4f16-af98-ab0daaff257e","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "fedramp_low_revision_4_aws","framework": "FedRAMP-Low-Revision-4","version": "","description": "The Federal Risk and Authorization Management Program (FedRAMP) was established in 2011. It provides a cost-effective, risk-based approach for the adoption and use of cloud services by the U.S. federal government. FedRAMP empowers federal agencies to use modern cloud technologies, with an emphasis on the security and protection of federal information.","region": "eu-west-1","requirements": {"ac-2": {"name": "Account Management (AC-2)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_hardware_mfa_enabled": null,"iam_user_console_access_unused": null,"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","iam_user_mfa_enabled_console_access": null,"cloudtrail_s3_dataevents_read_enabled": null,"iam_password_policy_minimum_length_14": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"iam_aws_attached_policy_no_administrative_privileges": null,"opensearch_service_domains_cloudwatch_logging_enabled": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-2","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Manage system accounts, group memberships, privileges, workflow, notifications, deactivations, and authorizations.","checks_status": {"fail": 3,"pass": 4,"total": 26,"manual": 0}},"ac-3": {"name": "Account Management (AC-3)","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-3","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system enforces approved authorizations for logical access to information and system resources in accordance with applicable access control policies.","checks_status": {"fail": 1,"pass": 6,"total": 20,"manual": 0}},"au-2": {"name": "Audit Events (AU-2)","checks": {"elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-2","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization: a. Determines that the information system is capable of auditing the following events: [Assignment: organization-defined auditable events]; b. Coordinates the security audit function with other organizational entities requiring audit- related information to enhance mutual support and to help guide the selection of auditable events; c. Provides a rationale for why the auditable events are deemed to be adequate support after- the-fact investigations of security incidents","checks_status": {"fail": 5,"pass": 2,"total": 11,"manual": 0}},"au-9": {"name": "Protection of Audit Information (AU-9)","checks": {"s3_bucket_object_versioning": "FAIL","cloudtrail_kms_encryption_enabled": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-9","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects audit information and audit tools from unauthorized access, modification, and deletion.","checks_status": {"fail": 4,"pass": 0,"total": 4,"manual": 0}},"ca-7": {"name": "Continuous Monitoring (CA-7)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_waf_acl_attached": "FAIL","ec2_instance_imdsv2_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_network_acls_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ca-7","Section": "Security Assessment And Authorization (CA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Continuously monitor configuration management processes. Determine security impact, environment and operational risks.","checks_status": {"fail": 2,"pass": 4,"total": 11,"manual": 0}},"cm-2": {"name": "Baseline Configuration (CM-2)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"elbv2_deletion_protection": "FAIL","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"ssm_managed_compliant_patching": "FAIL","apigateway_restapi_waf_acl_attached": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm-2","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization develops, documents, and maintains under configuration control, a current baseline configuration of the information system.","checks_status": {"fail": 7,"pass": 6,"total": 21,"manual": 0}},"cm-8": {"name": "Information System Component Inventory (CM-8)","checks": {"guardduty_is_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm-8","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization develops and documents an inventory of information system components that accurately reflects the current information system, includes all components within the authorization boundary of the information system, is at the level of granularity deemed necessary for tracking and reporting and reviews and updates the information system component inventory.","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"cp-9": {"name": "Information System Backup (CP-9)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp-9","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization conducts backups of user-level information, system-level information and information system documentation including security-related documentation contained in the information system and protects the confidentiality, integrity, and availability of backup information at storage locations.","checks_status": {"fail": 2,"pass": 1,"total": 7,"manual": 0}},"ia-2": {"name": "Identification and Authentication (Organizational users) (IA-2)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia-2","Section": "Identification and Authentication (IA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"ir-4": {"name": "Incident Handling (IR-4)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ir-4","Section": "Incident Response (IR)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization implements an incident handling capability for security incidents that includes preparation, detection and analysis, containment, eradication, and recovery, coordinates incident handling activities with contingency planning activities and incorporates lessons learned from ongoing incident handling activities into incident response procedures, training, and testing, and implements the resulting changes accordingly.","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"sa-3": {"name": "System Development Life Cycle (SA-3)","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sa-3","Section": "System and Services Acquisition (SA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization manages the information system using organization-defined system development life cycle, defines and documents information security roles and responsibilities throughout the system development life cycle, identifies individuals having information security roles and responsibilities and integrates the organizational information security risk management process into system development life cycle activities.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sc-5": {"name": "Denial Of Service Protection (SC-5)","checks": {"guardduty_is_enabled": "PASS","rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL","redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-5","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects against or limits the effects of the following types of denial of service attacks: [Assignment: organization-defined types of denial of service attacks or references to sources for such information] by employing [Assignment: organization-defined security safeguards].","checks_status": {"fail": 4,"pass": 2,"total": 8,"manual": 0}},"sc-7": {"name": "Boundary Protection (SC-7)","checks": {"elb_ssl_listeners": "FAIL","ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-7","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system: a. Monitors and controls communications at the external boundary of the system and at key internal boundaries within the system; b. Implements subnetworks for publicly accessible system components that are [Selection: physically; logically] separated from internal organizational networks; and c. Connects to external networks or information systems only through managed interfaces consisting of boundary protection devices arranged in accordance with an organizational security architecture.","checks_status": {"fail": 6,"pass": 6,"total": 21,"manual": 0}},"ac-17": {"name": "Remote Access (AC-17)","checks": {"elb_ssl_listeners": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-17","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Authorize remote access systems prior to connection. Enforce remote connection requirements to information systems.","checks_status": {"fail": 5,"pass": 9,"total": 21,"manual": 0}},"au-11": {"name": "Audit Record Retention (AU-11)","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-11","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization retains audit records for at least 90 days to provide support for after-the-fact investigations of security incidents and to meet regulatory and organizational information retention requirements.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cp-10": {"name": "Information System Recovery And Reconstitution (CP-10)","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp-10","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization provides for the recovery and reconstitution of the information system to a known state after a disruption, compromise, or failure.","checks_status": {"fail": 4,"pass": 1,"total": 9,"manual": 0}},"sc-12": {"name": "Cryptographic Key Establishment And Management (SC-12)","checks": {"kms_cmk_rotation_enabled": null,"acm_certificates_expiration_check": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc-12","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization establishes and manages cryptographic keys for required cryptography employed within the information system in accordance with [Assignment: organization-defined requirements for key generation, distribution, storage, access, and destruction].","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"sc-13": {"name": "Use of Cryptography (SC-13)","checks": {"s3_bucket_default_encryption": "PASS","sns_topics_kms_encryption_at_rest_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"sagemaker_training_jobs_volume_and_output_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-13","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system implements FIPS-validated or NSA-approved cryptography in accordance with applicable federal laws, Executive Orders, directives, policies, regulations, and standards.","checks_status": {"fail": 1,"pass": 1,"total": 4,"manual": 0}}},"requirements_passed": 2,"requirements_failed": 16,"requirements_manual": 0,"total_requirements": 18,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "2d3bdafb-2503-4e04-a107-bdda7c4163ba","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "aws_audit_manager_control_tower_guardrails_aws","framework": "AWS-Audit-Manager-Control-Tower-Guardrails","version": "","description": "AWS Control Tower is a management and governance service that you can use to navigate through the setup process and governance requirements that are involved in creating a multi-account AWS environment.","region": "eu-west-1","requirements": {"1.0.1": {"name": "Disallow launch of EC2 instance types that are not EBS-optimized","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "1.0.1","Section": "EBS checks","Service": "ebs","SubGroup": null,"SubSection": null}],"description": "Checks whether EBS optimization is enabled for your EC2 instances that can be EBS-optimized","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.0.2": {"name": "Disallow EBS volumes that are unattached to an EC2 instance","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "1.0.2","Section": "EBS checks","Service": "ebs","SubGroup": null,"SubSection": null}],"description": "Checks whether EBS volumes are attached to EC2 instances","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.0.3": {"name": "Enable encryption for EBS volumes attached to EC2 instances","checks": {"ec2_ebs_default_encryption": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "1.0.3","Section": "EBS checks","Service": "ebs","SubGroup": null,"SubSection": null}],"description": "Checks whether EBS volumes that are in an attached state are encrypted","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.0.1": {"name": "Disallow internet connection through RDP","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "2.0.1","Section": "Disallow Internet Connection","Service": "vpc","SubGroup": null,"SubSection": null}],"description": "Checks whether security groups that are in use disallow unrestricted incoming TCP traffic to the specified","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.0.2": {"name": "Disallow internet connection through SSH","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "2.0.2","Section": "Disallow Internet Connection","Service": "vpc","SubGroup": null,"SubSection": null}],"description": "Checks whether security groups that are in use disallow unrestricted incoming SSH traffic.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3.0.1": {"name": "Disallow access to IAM users without MFA","checks": {"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3.0.1","Section": "Multi-Factor Authentication","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Checks whether the AWS Identity and Access Management users have multi-factor authentication (MFA) enabled.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.0.2": {"name": "Disallow console access to IAM users without MFA","checks": {"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3.0.2","Section": "Multi-Factor Authentication","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Checks whether AWS Multi-Factor Authentication (MFA) is enabled for all AWS Identity and Access Management (IAM) users that use a console password.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.0.3": {"name": "Enable MFA for the root user","checks": {"iam_root_mfa_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "3.0.3","Section": "Multi-Factor Authentication","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Checks whether the root user of your AWS account requires multi-factor authentication for console sign-in.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.0.1": {"name": "Disallow public access to RDS database instances","checks": {"rds_instance_no_public_access": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "4.0.1","Section": "Disallow Public Access","Service": "rds","SubGroup": null,"SubSection": null}],"description": "Checks whether the Amazon Relational Database Service (RDS) instances are not publicly accessible. The rule is non-compliant if the publiclyAccessible field is true in the instance configuration item.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"4.0.2": {"name": "Disallow public access to RDS database snapshots","checks": {"rds_snapshots_public_access": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "4.0.2","Section": "Disallow Public Access","Service": "rds","SubGroup": null,"SubSection": null}],"description": "Checks if Amazon Relational Database Service (Amazon RDS) snapshots are public. The rule is non-compliant if any existing and new Amazon RDS snapshots are public.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"4.1.1": {"name": "Disallow public read access to S3 buckets","checks": {"rds_instance_no_public_access": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "4.1.1","Section": "Disallow Public Access","Service": "s3","SubGroup": null,"SubSection": null}],"description": "Checks that your S3 buckets do not allow public read access.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"4.1.2": {"name": "Disallow public write access to S3 buckets","checks": {"s3_bucket_policy_public_write_access": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "4.1.2","Section": "Disallow Public Access","Service": "s3","SubGroup": null,"SubSection": null}],"description": "Checks that your S3 buckets do not allow public write access.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"5.0.1": {"name": "Disallow RDS database instances that are not storage encrypted ","checks": {"rds_instance_storage_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "5.0.1","Section": "Disallow Instances","Service": "rds","SubGroup": null,"SubSection": null}],"description": "Checks whether storage encryption is enabled for your RDS DB instances.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"5.1.1": {"name": "Disallow S3 buckets that are not versioning enabled","checks": {"s3_bucket_object_versioning": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "5.1.1","Section": "Disallow Instances","Service": "s3","SubGroup": null,"SubSection": null}],"description": "Checks whether versioning is enabled for your S3 buckets.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 10,"requirements_failed": 2,"requirements_manual": 2,"total_requirements": 14,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "3477e5c1-467e-4fb1-9b4b-1c2bc8fcd03e","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "pci_3.2.1_aws","framework": "PCI","version": "3.2.1","description": "The Payment Card Industry Data Security Standard (PCI DSS) is a proprietary information security standard. It's administered by the PCI Security Standards Council, which was founded by American Express, Discover Financial Services, JCB International, MasterCard Worldwide, and Visa Inc. PCI DSS applies to entities that store, process, or transmit cardholder data (CHD) or sensitive authentication data (SAD). This includes, but isn't limited to, merchants, processors, acquirers, issuers, and service providers. The PCI DSS is mandated by the card brands and administered by the Payment Card Industry Security Standards Council.","region": "eu-west-1","requirements": {"cw": {"name": "CloudWatch","checks": {"cloudwatch_log_metric_filter_root_usage": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "cw","Section": null,"Service": "cloudwatch","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring CloudWatch resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"s3": {"name": "S3","checks": {"s3_bucket_public_access": null,"s3_bucket_default_encryption": "PASS","s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "s3","Section": null,"Service": "s3","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS S3 resources and options.","checks_status": {"fail": 1,"pass": 2,"total": 5,"manual": 0}},"dms": {"name": "DMS","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "dms","Section": null,"Service": "dms","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS DMS resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ec2": {"name": "EC2","checks": {"vpc_flow_logs_enabled": "FAIL","ec2_ebs_public_snapshot": "PASS","ec2_elastic_ip_unassigned": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ec2","Section": null,"Service": "ec2","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring EC2 resources and options.","checks_status": {"fail": 3,"pass": 3,"total": 6,"manual": 0}},"iam": {"name": "IAM","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "iam","Section": null,"Service": "iam","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS IAM resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 15,"manual": 0}},"kms": {"name": "KMS","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "kms","Section": null,"Service": "kms","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS KMS resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"rds": {"name": "RDS","checks": {"rds_snapshots_public_access": "PASS","rds_instance_no_public_access": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "rds","Section": null,"Service": "rds","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS RDS resources and options.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"ssm": {"name": "SSM","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ssm","Section": null,"Service": "ssm","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS SSM resources and options.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"elbv2": {"name": "ELBV2","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "elbv2","Section": null,"Service": "elbv2","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Elastic Load Balancer resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"config": {"name": "Config","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "config","Section": null,"Service": "config","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Config.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"lambda": {"name": "Lambda","checks": {"awslambda_function_url_public": null,"awslambda_function_not_publicly_accessible": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "lambda","Section": null,"Service": "lambda","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Lambda resources and options.","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"redshift": {"name": "Redshift","checks": {"redshift_cluster_public_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "redshift","Section": null,"Service": "redshift","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Redshift resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"codebuild": {"name": "CodeBuild","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "codebuild","Section": null,"Service": "codebuild","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring CodeBuild resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"guardduty": {"name": "GuardDuty","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "guardduty","Section": null,"Service": "guardduty","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS GuardDuty resources and options.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sagemaker": {"name": "SageMaker","checks": {"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sagemaker","Section": null,"Service": "sagemaker","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Sagemaker resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"cloudtrail": {"name": "CloudTrail","checks": {"cloudtrail_multi_region_enabled": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cloudtrail","Section": null,"Service": "cloudtrail","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring CloudTrail resources and options.","checks_status": {"fail": 3,"pass": 1,"total": 4,"manual": 0}},"opensearch": {"name": "OpenSearch","checks": {"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "opensearch","Section": null,"Service": "opensearch","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring OpenSearch resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"autoscaling": {"name": "Auto Scaling","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "autoscaling","Section": null,"Service": "autoscaling","SubGroup": null,"SubSection": null}],"description": "This control checks whether your Auto Scaling groups that are associated with a load balancer are using Elastic Load Balancing health checks. PCI DSS does not require load balancing or highly available configurations. However, this check aligns with AWS best practices.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"elasticsearch": {"name": "Elasticsearch","checks": {"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "elasticsearch","Section": null,"Service": "elasticsearch","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Elasticsearch resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 11,"requirements_failed": 4,"requirements_manual": 4,"total_requirements": 19,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "34f5d2fe-fe37-4143-81ce-fdf21d9a9826","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "gxp_eu_annex_11_aws","framework": "GxP-EU-Annex-11","version": "","description": "The GxP EU Annex 11 framework is the European equivalent to the FDA 21 CFR part 11 framework in the United States. This annex applies to all forms of computerized systems that are used as part of Good Manufacturing Practices (GMP) regulated activities. A computerized system is a set of software and hardware components that together fulfill certain functionalities. The application should be validated and IT infrastructure should be qualified. Where a computerized system replaces a manual operation, there should be no resultant decrease in product quality, process control, or quality assurance. There should be no increase in the overall risk of the process.","region": "eu-west-1","requirements": {"5-data": {"name": "5 Data","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "5-data","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Computerised systems exchanging data electronically with other systems should include appropriate built-in checks for the correct and secure entry and processing of data, in order to minimize the risks.","checks_status": {"fail": 2,"pass": 1,"total": 8,"manual": 0}},"17-archiving": {"name": "17 Archiving","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "17-archiving","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Data may be archived. This data should be checked for accessibility, readability and integrity. If relevant changes are to be made to the system (e.g. computer equipment or programs), then the ability to retrieve the data should be ensured and tested.","checks_status": {"fail": 2,"pass": 1,"total": 9,"manual": 0}},"9-audit-trails": {"name": "9 Audit Trails","checks": {"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "9-audit-trails","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Consideration should be given, based on a risk assessment, to building into the system the creation of a record of all GMP-relevant changes and deletions (a system generated 'audit trail'). For change or deletion of GMP-relevant data the reason should be documented. Audit trails need to be available and convertible to a generally intelligible form and regularly reviewed.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1-risk-management": {"name": "1 Risk Management","checks": {"securityhub_enabled": "PASS","cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "1-risk-management","Section": "General","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Risk management should be applied throughout the lifecycle of the computerised system taking into account patient safety, data integrity and product quality. As part of a risk management system, decisions on the extent of validation and data integrity controls should be based on a justified and documented risk assessment of the computerised system.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"16-business-continuity": {"name": "16 Business Continuity","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "16-business-continuity","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "For the availability of computerised systems supporting critical processes, provisions should be made to ensure continuity of support for those processes in the event of a system breakdown (e.g. a manual or alternative system). The time required to bring the alternative arrangements into use should be based on risk and appropriate for a particular system and the business process it supports. These arrangements should be adequately documented and tested.","checks_status": {"fail": 2,"pass": 1,"total": 9,"manual": 0}},"7.2-data-storage-backups": {"name": "7.2 Data Storage - Backups","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "7.2-data-storage-backups","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Regular back-ups of all relevant data should be done. Integrity and accuracy of backup data and the ability to restore the data should be checked during validation and monitored periodically.","checks_status": {"fail": 2,"pass": 1,"total": 8,"manual": 0}},"12.4-security-audit-trail": {"name": "12.4 Security - Audit Trail","checks": {"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "12.4-security-audit-trail","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Management systems for data and for documents should be designed to record the identity of operators entering, changing, confirming or deleting data including date and time.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"8.2-printouts-data-changes": {"name": "8.2 Printouts - Data Changes","checks": {"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "8.2-printouts-data-changes","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "For records supporting batch release it should be possible to generate printouts indicating if any of the data has been changed since the original entry.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"4.8-validation-data-transfer": {"name": "4.8 Validation - Data Transfer","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "4.8-validation-data-transfer","Section": "Project Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "If data are transferred to another data format or system, validation should include checks that data are not altered in value and/or meaning during this migration process.","checks_status": {"fail": 2,"pass": 1,"total": 9,"manual": 0}},"4.5-validation-development-quality": {"name": "4.5 Validation - Development Quality","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "4.5-validation-development-quality","Section": "Project Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The regulated user should take all reasonable steps, to ensure that the system has been developed in accordance with an appropriate quality management system. The supplier should be assessed appropriately.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.6-validation-quality-performance": {"name": "4.6 Validation - Quality and Performance","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "4.6-validation-quality-performance","Section": "Project Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "For the validation of bespoke or customised computerised systems there should be a process in place that ensures the formal assessment and reporting of quality and performance measures for all the life-cycle stages of the system.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"7.1-data-storage-damage-protection": {"name": "7.1 Data Storage - Damage Protection","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","redshift_cluster_automated_snapshot": null,"sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"eks_cluster_kms_cmk_encryption_in_secrets_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "7.1-data-storage-damage-protection","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Data should be secured by both physical and electronic means against damage. Stored data should be checked for accessibility, readability and accuracy. Access to data should be ensured throughout the retention period.","checks_status": {"fail": 6,"pass": 4,"total": 22,"manual": 0}},"10-change-and-configuration-management": {"name": "10 Change and Configuration Management","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "10-change-and-configuration-management","Section": "Operational Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Any changes to a computerised system including system configurations should only be made in a controlled manner in accordance with a defined procedure.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.2-validation-documentation-change-control": {"name": "4.2 Validation - Documentation Change Control","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "4.2-validation-documentation-change-control","Section": "Project Phase","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Validation documentation should include change control records (if applicable) and reports on any deviations observed during the validation process.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}}},"requirements_passed": 8,"requirements_failed": 6,"requirements_manual": 0,"total_requirements": 14,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "376854be-93cd-44ab-a070-1e996b24184d","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "cis_1.5_aws","framework": "CIS","version": "1.5","description": "The CIS Amazon Web Services Foundations Benchmark provides prescriptive guidance for configuring security options for a subset of Amazon Web Services with an emphasis on foundational, testable, and architecture agnostic settings.","region": "eu-west-1","requirements": {"1.1": {"name": "1.1","checks": {"account_maintain_current_contact_details": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/manage-account-payment.html#contact-info","Description": "Ensure contact email and telephone details for AWS accounts are current and map to more than one individual in your organization.An AWS account supports a number of contact details, and AWS will use these to contact the account owner if activity judged to be in breach of Acceptable Use Policy or indicative of likely security compromise is observed by the AWS Abuse team. Contact details should not be for a single individual, as circumstances may arise where that individual is unavailable. Email contact details should point to a mail alias which forwards email to multiple individuals within the organization; where feasible, phone contact details should point to a PABX hunt group or other call-forwarding system.","DefaultValue": null,"AuditProcedure": "This activity can only be performed via the AWS Console, with a user who has permission to read and write Billing information (aws-portal:\\*Billing )1. Sign in to the AWS Management Console and open the `Billing and Cost Management` console at https://console.aws.amazon.com/billing/home#/. 2. On the navigation bar, choose your account name, and then choose `My Account`. 3. On the `Account Settings` page, review and verify the current details. 4. Under `Contact Information`, review and verify the current details.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "If an AWS account is observed to be behaving in a prohibited or suspicious manner, AWS will attempt to contact the account owner by email and phone using the contact details listed. If this is unsuccessful and the account behavior needs urgent mitigation, proactive measures may be taken, including throttling of traffic between the account exhibiting suspicious behavior and the AWS API endpoints and the Internet. This will result in impaired service to and from the account in question, so it is in both the customers' and AWS' best interests that prompt contact can be established. This is best achieved by setting AWS account contact details to point to resources which have multiple individuals as recipients, such as email aliases and PABX hunt groups.","RemediationProcedure": "This activity can only be performed via the AWS Console, with a user who has permission to read and write Billing information (aws-portal:\\*Billing ).1. Sign in to the AWS Management Console and open the `Billing and Cost Management` console at https://console.aws.amazon.com/billing/home#/. 2. On the navigation bar, choose your account name, and then choose `My Account`. 3. On the `Account Settings` page, next to `Account Settings`, choose `Edit`. 4. Next to the field that you need to update, choose `Edit`. 5. After you have entered your changes, choose `Save changes`. 6. After you have made your changes, choose `Done`. 7. To edit your contact information, under `Contact Information`, choose `Edit`. 8. For the fields that you want to change, type your updated information, and then choose `Update`.","AdditionalInformation": ""}],"description": "Maintain current contact details","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.2": {"name": "1.2","checks": {"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "","Description": "AWS provides customers with the option of specifying the contact information for account's security team. It is recommended that this information be provided.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if security contact information is present:**From Console:**1. Click on your account name at the top right corner of the console 2. From the drop-down menu Click `My Account`3. Scroll down to the `Alternate Contacts` section 4. Ensure contact information is specified in the `Security` section","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Specifying security-specific contact information will help ensure that security advisories sent by AWS reach the team in your organization that is best equipped to respond to them.","RemediationProcedure": "Perform the following to establish security contact information:**From Console:**1. Click on your account name at the top right corner of the console. 2. From the drop-down menu Click `My Account`3. Scroll down to the `Alternate Contacts` section 4. Enter contact information in the `Security` section**Note:** Consider specifying an internal email distribution list to ensure emails are regularly monitored by more than one individual.","AdditionalInformation": ""}],"description": "Ensure security contact information is registered","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.3": {"name": "1.3","checks": {"account_security_questions_are_registered_in_the_aws_account": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "","Description": "The AWS support portal allows account owners to establish security questions that can be used to authenticate individuals calling AWS customer service for support. It is recommended that security questions be established.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS account as the 'root' user 2. On the top right you will see the __ 3. Click on the __ 4. From the drop-down menu Click `My Account`5. In the `Configure Security Challenge Questions` section on the `Personal Information` page, configure three security challenge questions. 6. Click `Save questions` .","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "When creating a new AWS account, a default super user is automatically created. This account is referred to as the 'root user' or 'root' account. It is recommended that the use of this account be limited and highly controlled. During events in which the 'root' password is no longer accessible or the MFA token associated with 'root' is lost/destroyed it is possible, through authentication using secret questions and associated answers, to recover 'root' user login access.","RemediationProcedure": "**From Console:**1. Login to the AWS Account as the 'root' user 2. Click on the __ from the top right of the console 3. From the drop-down menu Click _My Account_ 4. Scroll down to the `Configure Security Questions` section 5. Click on `Edit`6. Click on each `Question` - From the drop-down select an appropriate question- Click on the `Answer` section- Enter an appropriate answer - Follow process for all 3 questions 7. Click `Update` when complete 8. Save Questions and Answers and place in a secure physical location","AdditionalInformation": ""}],"description": "Ensure security questions are registered in the AWS account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.4": {"name": "1.4","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "http://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html:http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html:http://docs.aws.amazon.com/IAM/latest/APIReference/API_GetAccountSummary.html:https://aws.amazon.com/blogs/security/an-easier-way-to-determine-the-presence-of-aws-account-access-keys/","Description": "The 'root' user account is the most privileged user in an AWS account. AWS Access Keys provide programmatic access to a given AWS account. It is recommended that all access keys associated with the 'root' user account be removed.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has access keys:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on `Credential Report`5. This will download a `.csv` file which contains credential usage for all IAM users within an AWS Account - open this file 6. For the `` user, ensure the `access_key_1_active` and `access_key_2_active` fields are set to `FALSE` .**From Command Line:**Run the following command: ```aws iam get-account-summary | grep \"AccountAccessKeysPresent\"``` If no 'root' access keys exist the output will show \"AccountAccessKeysPresent\": 0,. If the output shows a \"1\" than 'root' keys exist, refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Removing access keys associated with the 'root' user account limits vectors by which the account can be compromised. Additionally, removing the 'root' access keys encourages the creation and use of role based accounts that are least privileged.","RemediationProcedure": "Perform the following to delete or disable active 'root' user access keys**From Console:**1. Sign in to the AWS Management Console as 'root' and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. Click on __ at the top right and select `My Security Credentials` from the drop down list 3. On the pop out screen Click on `Continue to Security Credentials`4. Click on `Access Keys` _(Access Key ID and Secret Access Key)_ 5. Under the `Status` column if there are any Keys which are Active- Click on `Make Inactive` - (Temporarily disable Key - may be needed again)- Click `Delete` - (Deleted keys cannot be recovered)","AdditionalInformation": "IAM User account \"root\" for us-gov cloud regions is not enabled by default. However, on request to AWS support enables 'root' access only through access-keys (CLI, API methods) for us-gov cloud region."}],"description": "Ensure no 'root' user account access key exists","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.5": {"name": "1.5","checks": {"iam_root_mfa_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#id_root-user_manage_mfa:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html#enable-virt-mfa-for-root","Description": "The 'root' user account is the most privileged user in an AWS account. Multi-factor Authentication (MFA) adds an extra layer of protection on top of a username and password. With MFA enabled, when a user signs in to an AWS website, they will be prompted for their username and password as well as for an authentication code from their AWS MFA device.**Note:** When virtual MFA is used for 'root' accounts, it is recommended that the device used is NOT a personal device, but rather a dedicated mobile device (tablet or phone) that is managed to be kept charged and secured independent of any individual personal devices. (\"non-personal virtual MFA\") This lessens the risks of losing access to the MFA due to device loss, device trade-in or if the individual owning the device is no longer employed at the company.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has MFA setup:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on `Credential Report`5. This will download a `.csv` file which contains credential usage for all IAM users within an AWS Account - open this file 6. For the `` user, ensure the `mfa_active` field is set to `TRUE` .**From Command Line:**1. Run the following command: ```aws iam get-account-summary | grep \"AccountMFAEnabled\" ``` 2. Ensure the AccountMFAEnabled property is set to 1","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling MFA provides increased security for console access as it requires the authenticating principal to possess a device that emits a time-sensitive key and have knowledge of a credential.","RemediationProcedure": "Perform the following to establish MFA for the 'root' user account:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). Note: to manage MFA devices for the 'root' AWS account, you must use your 'root' account credentials to sign in to AWS. You cannot manage MFA devices for the 'root' account using other credentials.2. Choose `Dashboard` , and under `Security Status` , expand `Activate MFA` on your root account. 3. Choose `Activate MFA`4. In the wizard, choose `A virtual MFA` device and then choose `Next Step` . 5. IAM generates and displays configuration information for the virtual MFA device, including a QR code graphic. The graphic is a representation of the 'secret configuration key' that is available for manual entry on devices that do not support QR codes. 6. Open your virtual MFA application. (For a list of apps that you can use for hosting virtual MFA devices, see [Virtual MFA Applications](http://aws.amazon.com/iam/details/mfa/#Virtual_MFA_Applications).) If the virtual MFA application supports multiple accounts (multiple virtual MFA devices), choose the option to create a new account (a new virtual MFA device). 7. Determine whether the MFA app supports QR codes, and then do one of the following: - Use the app to scan the QR code. For example, you might choose the camera icon or choose an option similar to Scan code, and then use the device's camera to scan the code.- In the Manage MFA Device wizard, choose Show secret key for manual configuration, and then type the secret configuration key into your MFA application.When you are finished, the virtual MFA device starts generating one-time passwords.In the Manage MFA Device wizard, in the Authentication Code 1 box, type the one-time password that currently appears in the virtual MFA device. Wait up to 30 seconds for the device to generate a new one-time password. Then type the second one-time password into the Authentication Code 2 box. Choose Assign Virtual MFA.","AdditionalInformation": "IAM User account \"root\" for us-gov cloud regions does not have console access. This recommendation is not applicable for us-gov cloud regions."}],"description": "Ensure MFA is enabled for the 'root' user account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.6": {"name": "1.6","checks": {"iam_root_hardware_mfa_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_physical.html#enable-hw-mfa-for-root","Description": "The 'root' user account is the most privileged user in an AWS account. MFA adds an extra layer of protection on top of a user name and password. With MFA enabled, when a user signs in to an AWS website, they will be prompted for their user name and password as well as for an authentication code from their AWS MFA device. For Level 2, it is recommended that the 'root' user account be protected with a hardware MFA.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has a hardware MFA setup:1. Run the following command to determine if the 'root' account has MFA setup: ```aws iam get-account-summary | grep \"AccountMFAEnabled\" ```The `AccountMFAEnabled` property is set to `1` will ensure that the 'root' user account has MFA (Virtual or Hardware) Enabled. If `AccountMFAEnabled` property is set to `0` the account is not compliant with this recommendation.2. If `AccountMFAEnabled` property is set to `1`, determine 'root' account has Hardware MFA enabled. Run the following command to list all virtual MFA devices: ```aws iam list-virtual-mfa-devices``` If the output contains one MFA with the following Serial Number, it means the MFA is virtual, not hardware and the account is not compliant with this recommendation: `\"SerialNumber\": \"arn:aws:iam::__:mfa/root-account-mfa-device\"`","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "A hardware MFA has a smaller attack surface than a virtual MFA. For example, a hardware MFA does not suffer the attack surface introduced by the mobile smartphone on which a virtual MFA resides.**Note**: Using hardware MFA for many, many AWS accounts may create a logistical device management issue. If this is the case, consider implementing this Level 2 recommendation selectively to the highest security AWS accounts and the Level 1 recommendation applied to the remaining accounts.","RemediationProcedure": "Perform the following to establish a hardware MFA for the 'root' user account:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). Note: to manage MFA devices for the AWS 'root' user account, you must use your 'root' account credentials to sign in to AWS. You cannot manage MFA devices for the 'root' account using other credentials. 2. Choose `Dashboard` , and under `Security Status` , expand `Activate MFA` on your root account. 3. Choose `Activate MFA`4. In the wizard, choose `A hardware MFA` device and then choose `Next Step` . 5. In the `Serial Number` box, enter the serial number that is found on the back of the MFA device. 6. In the `Authentication Code 1` box, enter the six-digit number displayed by the MFA device. You might need to press the button on the front of the device to display the number. 7. Wait 30 seconds while the device refreshes the code, and then enter the next six-digit number into the `Authentication Code 2` box. You might need to press the button on the front of the device again to display the second number. 8. Choose `Next Step` . The MFA device is now associated with the AWS account. The next time you use your AWS account credentials to sign in, you must type a code from the hardware MFA device.Remediation for this recommendation is not available through AWS CLI.","AdditionalInformation": "IAM User account 'root' for us-gov cloud regions does not have console access. This control is not applicable for us-gov cloud regions."}],"description": "Ensure hardware MFA is enabled for the 'root' user account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.7": {"name": "1.7","checks": {"iam_avoid_root_usage": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html:https://docs.aws.amazon.com/general/latest/gr/aws_tasks-that-require-root.html","Description": "With the creation of an AWS account, a 'root user' is created that cannot be disabled or deleted. That user has unrestricted access to and control over all resources in the AWS account. It is highly recommended that the use of this account be avoided for everyday tasks.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console at `https://console.aws.amazon.com/iam/` 2. In the left pane, click `Credential Report` 3. Click on `Download Report` 4. Open of Save the file locally 5. Locate the `` under the user column 6. Review `password_last_used, access_key_1_last_used_date, access_key_2_last_used_date` to determine when the 'root user' was last used.**From Command Line:**Run the following CLI commands to provide a credential report for determining the last time the 'root user' was used: ``` aws iam generate-credential-report ``` ``` aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,5,11,16 | grep -B1 '' ```Review `password_last_used`, `access_key_1_last_used_date`, `access_key_2_last_used_date` to determine when the _root user_ was last used.**Note:** There are a few conditions under which the use of the 'root' user account is required. Please see the reference links for all of the tasks that require use of the 'root' user.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "The 'root user' has unrestricted access to and control over all account resources. Use of it is inconsistent with the principles of least privilege and separation of duties, and can lead to unnecessary harm due to error or account compromise.","RemediationProcedure": "If you find that the 'root' user account is being used for daily activity to include administrative tasks that do not require the 'root' user:1. Change the 'root' user password. 2. Deactivate or delete any access keys associate with the 'root' user.**Remember, anyone who has 'root' user credentials for your AWS account has unrestricted access to and control of all the resources in your account, including billing information.","AdditionalInformation": "The 'root' user for us-gov cloud regions is not enabled by default. However, on request to AWS support, they can enable the 'root' user and grant access only through access-keys (CLI, API methods) for us-gov cloud region. If the 'root' user for us-gov cloud regions is enabled, this recommendation is applicable.Monitoring usage of the 'root' user can be accomplished by implementing recommendation 3.3 Ensure a log metric filter and alarm exist for usage of the 'root' user."}],"description": "Eliminate use of the 'root' user for administrative and daily tasks","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.8": {"name": "1.8","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy","Description": "Password policies are, in part, used to enforce password complexity requirements. IAM password policies can be used to ensure password are at least a given length. It is recommended that the password policy require a minimum password length 14.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure the password policy is configured as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Ensure \"Minimum password length\" is set to 14 or greater.**From Command Line:** ``` aws iam get-account-password-policy ``` Ensure the output of the above command includes \"MinimumPasswordLength\": 14 (or higher)","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Setting a password complexity policy increases account resiliency against brute force login attempts.","RemediationProcedure": "Perform the following to set the password policy as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Set \"Minimum password length\" to `14` or greater. 5. Click \"Apply password policy\"**From Command Line:** ```aws iam update-account-password-policy --minimum-password-length 14 ``` Note: All commands starting with \"aws iam update-account-password-policy\" can be combined into a single command.","AdditionalInformation": ""}],"description": "Ensure IAM password policy requires minimum length of 14 or greater","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.9": {"name": "1.9","checks": {"iam_password_policy_reuse_24": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy","Description": "IAM password policies can prevent the reuse of a given password by the same user. It is recommended that the password policy prevent the reuse of passwords.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure the password policy is configured as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Ensure \"Prevent password reuse\" is checked 5. Ensure \"Number of passwords to remember\" is set to 24**From Command Line:** ``` aws iam get-account-password-policy``` Ensure the output of the above command includes \"PasswordReusePrevention\": 24","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Preventing password reuse increases account resiliency against brute force login attempts.","RemediationProcedure": "Perform the following to set the password policy as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Check \"Prevent password reuse\" 5. Set \"Number of passwords to remember\" is set to `24` **From Command Line:** ```aws iam update-account-password-policy --password-reuse-prevention 24 ``` Note: All commands starting with \"aws iam update-account-password-policy\" can be combined into a single command.","AdditionalInformation": ""}],"description": "Ensure IAM password policy prevents password reuse","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.1": {"name": "3.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-management-events:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-management-and-data-events-with-cloudtrail.html?icmpid=docs_cloudtrail_console#logging-management-events:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-supported-services.html#cloud-trail-supported-services-data-events","Description": "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. CloudTrail provides a history of AWS API calls for an account, including API calls made via the Management Console, SDKs, command line tools, and higher-level AWS services (such as CloudFormation).","DefaultValue": null,"AuditProcedure": "Perform the following to determine if CloudTrail is enabled for all regions:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane- You will be presented with a list of trails across all regions 3. Ensure at least one Trail has `All` specified in the `Region` column 4. Click on a trail via the link in the _Name_ column 5. Ensure `Logging` is set to `ON`6. Ensure `Apply trail to all regions` is set to `Yes` 7. In section `Management Events` ensure `Read/Write Events` set to `ALL`**From Command Line:** ```aws cloudtrail describe-trails ``` Ensure `IsMultiRegionTrail` is set to `true```` aws cloudtrail get-trail-status --name  ``` Ensure `IsLogging` is set to `true` ``` aws cloudtrail get-event-selectors --trail-name  ``` Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`","ImpactStatement": "S3 lifecycle features can be used to manage the accumulation and management of logs over time. See the following AWS resource for more information on these features:1. https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html","AssessmentStatus": "Automated","RationaleStatement": "The AWS API call history produced by CloudTrail enables security analysis, resource change tracking, and compliance auditing. Additionally, - ensuring that a multi-regions trail exists will ensure that unexpected activity occurring in otherwise unused regions is detected- ensuring that a multi-regions trail exists will ensure that `Global Service Logging` is enabled for a trail by default to capture recording of events generated onAWS global services- for a multi-regions trail, ensuring that management events configured for all type of Read/Writes ensures recording of management operations that are performed on all resources in an AWS account","RemediationProcedure": "Perform the following to enable global (Multi-region) CloudTrail logging:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on _Trails_ on the left navigation pane 3. Click `Get Started Now` , if presented- Click `Add new trail` - Enter a trail name in the `Trail name` box- Set the `Apply trail to all regions` option to `Yes` - Specify an S3 bucket name in the `S3 bucket` box- Click `Create`4. If 1 or more trails already exist, select the target trail to enable for global logging 5. Click the edit icon (pencil) next to `Apply trail to all regions` , Click `Yes` and Click `Save`. 6. Click the edit icon (pencil) next to `Management Events` click `All` for setting `Read/Write Events` and Click `Save`.**From Command Line:** ``` aws cloudtrail create-trail --name  --bucket-name  --is-multi-region-trailaws cloudtrail update-trail --name  --is-multi-region-trail ```Note: Creating CloudTrail via CLI without providing any overriding options configures `Management Events` to set `All` type of `Read/Writes` by default.","AdditionalInformation": ""}],"description": "Ensure CloudTrail is enabled in all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3.2": {"name": "3.2","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-file-validation-enabling.html","Description": "CloudTrail log file validation creates a digitally signed digest file containing a hash of each log that CloudTrail writes to S3. These digest files can be used to determine whether a log file was changed, deleted, or unchanged after CloudTrail delivered the log. It is recommended that file validation be enabled on all CloudTrails.","DefaultValue": null,"AuditProcedure": "Perform the following on each trail to determine if log file validation is enabled:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane 3. For Every Trail: - Click on a trail via the link in the _Name_ column - Under the `General details` section, ensure `Log file validation` is set to `Enabled` **From Command Line:** ``` aws cloudtrail describe-trails ``` Ensure `LogFileValidationEnabled` is set to `true` for each trail","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling log file validation will provide additional integrity checking of CloudTrail logs.","RemediationProcedure": "Perform the following to enable log file validation on a given trail:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane 3. Click on target trail 4. Within the `General details` section click `edit` 5. Under the `Advanced settings` section 6. Check the enable box under `Log file validation`7. Click `Save changes` **From Command Line:** ``` aws cloudtrail update-trail --name  --enable-log-file-validation ``` Note that periodic validation of logs using these digests can be performed by running the following command: ``` aws cloudtrail validate-logs --trail-arn  --start-time  --end-time  ```","AdditionalInformation": ""}],"description": "Ensure CloudTrail log file validation is enabled","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.3": {"name": "3.3","checks": {"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html","Description": "CloudTrail logs a record of every API call made in your AWS account. These logs file are stored in an S3 bucket. It is recommended that the bucket policy or access control list (ACL) applied to the S3 bucket that CloudTrail logs to prevent public access to the CloudTrail logs.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if any public access is granted to an S3 bucket via an ACL or S3 bucket policy:**From Console:**1. Go to the Amazon CloudTrail console at [https://console.aws.amazon.com/cloudtrail/home](https://console.aws.amazon.com/cloudtrail/home) 2. In the `API activity history` pane on the left, click `Trails`3. In the `Trails` pane, note the bucket names in the `S3 bucket` column 4. Go to Amazon S3 console at [https://console.aws.amazon.com/s3/home](https://console.aws.amazon.com/s3/home) 5. For each bucket noted in step 3, right-click on the bucket and click `Properties`6. In the `Properties` pane, click the `Permissions` tab. 7. The tab shows a list of grants, one row per grant, in the bucket ACL. Each row identifies the grantee and the permissions granted. 8. Ensure no rows exists that have the `Grantee` set to `Everyone` or the `Grantee` set to `Any Authenticated User.`9. If the `Edit bucket policy` button is present, click it to review the bucket policy. 10. Ensure the policy does not contain a `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ```aws cloudtrail describe-trails --query 'trailList[*].S3BucketName' ``` 2. Ensure the `AllUsers` principal is not granted privileges to that `` : ```aws s3api get-bucket-acl --bucket  --query 'Grants[?Grantee.URI== `https://acs.amazonaws.com/groups/global/AllUsers` ]' ``` 3. Ensure the `AuthenticatedUsers` principal is not granted privileges to that ``: ```aws s3api get-bucket-acl --bucket  --query 'Grants[?Grantee.URI== `https://acs.amazonaws.com/groups/global/Authenticated Users` ]' ``` 4. Get the S3 Bucket Policy ```aws s3api get-bucket-policy --bucket ``` 5. Ensure the policy does not contain a `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}**Note:** Principal set to \"\\*\" or {\"AWS\" : \"\\*\"} allows anonymous access.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Allowing public access to CloudTrail log content may aid an adversary in identifying weaknesses in the affected account's use or configuration.","RemediationProcedure": "Perform the following to remove any public access that has been granted to the bucket via an ACL or S3 bucket policy:1. Go to Amazon S3 console at [https://console.aws.amazon.com/s3/home](https://console.aws.amazon.com/s3/home) 2. Right-click on the bucket and click Properties 3. In the `Properties` pane, click the `Permissions` tab. 4. The tab shows a list of grants, one row per grant, in the bucket ACL. Each row identifies the grantee and the permissions granted. 5. Select the row that grants permission to `Everyone` or `Any Authenticated User`6. Uncheck all the permissions granted to `Everyone` or `Any Authenticated User` (click `x` to delete the row). 7. Click `Save` to save the ACL. 8. If the `Edit bucket policy` button is present, click it. 9. Remove any `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}.","AdditionalInformation": ""}],"description": "Ensure the S3 bucket used to store CloudTrail logs is not publicly accessible","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3.4": {"name": "3.4","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-user-guide.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/how-cloudtrail-works.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-aws-service-specific-topics.html","Description": "AWS CloudTrail is a web service that records AWS API calls made in a given AWS account. 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. CloudTrail uses Amazon S3 for log file storage and delivery, so log files are stored durably. In addition to capturing CloudTrail logs within a specified S3 bucket for long term analysis, realtime analysis can be performed by configuring CloudTrail to send logs to CloudWatch Logs. For a trail that is enabled in all regions in an account, CloudTrail sends log files from all those regions to a CloudWatch Logs log group. It is recommended that CloudTrail logs be sent to CloudWatch Logs.Note: The intent of this recommendation is to ensure AWS account activity is being captured, monitored, and appropriately alarmed on. CloudWatch Logs is a native way to accomplish this using AWS services but does not preclude the use of an alternate solution.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure CloudTrail is configured as prescribed:**From Console:**1. Login to the CloudTrail console at `https://console.aws.amazon.com/cloudtrail/` 2. Under `Trails` , click on the CloudTrail you wish to evaluate 3. Under the `CloudWatch Logs` section. 4. Ensure a `CloudWatch Logs` log group is configured and listed. 5. Under `General details` confirm `Last log file delivered` has a recent (~one day old) timestamp.**From Command Line:**1. Run the following command to get a listing of existing trails: ```aws cloudtrail describe-trails ``` 2. Ensure `CloudWatchLogsLogGroupArn` is not empty and note the value of the `Name` property. 3. Using the noted value of the `Name` property, run the following command: ```aws cloudtrail get-trail-status --name  ``` 4. Ensure the `LatestcloudwatchLogdDeliveryTime` property is set to a recent (~one day old) timestamp.If the `CloudWatch Logs` log group is not setup and the delivery time is not recent refer to the remediation below.","ImpactStatement": "Note: By default, CloudWatch Logs will store Logs indefinitely unless a specific retention period is defined for the log group. When choosing the number of days to retain, keep in mind the average days it takes an organization to realize they have been breached is 210 days (at the time of this writing). Since additional time is required to research a breach, a minimum 365 day retention policy allows time for detection and research. You may also wish to archive the logs to a cheaper storage service rather than simply deleting them. See the following AWS resource to manage CloudWatch Logs retention periods:1. https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/SettingLogRetention.html","AssessmentStatus": "Automated","RationaleStatement": "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.","RemediationProcedure": "Perform the following to establish the prescribed state:**From Console:**1. Login to the CloudTrail console at `https://console.aws.amazon.com/cloudtrail/` 2. Select the `Trail` the needs to be updated. 3. Scroll down to `CloudWatch Logs` 4. Click `Edit` 5. Under `CloudWatch Logs` click the box `Enabled` 6. Under `Log Group` pick new or select an existing log group 7. Edit the `Log group name` to match the CloudTrail or pick the existing CloudWatch Group. 8. Under `IAM Role` pick new or select an existing. 9. Edit the `Role name` to match the CloudTrail or pick the existing IAM Role. 10. Click `Save changes.**From Command Line:** ``` aws cloudtrail update-trail --name  --cloudwatch-logs-log-group-arn  --cloudwatch-logs-role-arn  ```","AdditionalInformation": ""}],"description": "Ensure CloudTrail trails are integrated with CloudWatch Logs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.5": {"name": "3.5","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/cli/latest/reference/configservice/describe-configuration-recorder-status.html","Description": "AWS Config is a web service that performs configuration management of supported AWS resources within your account and delivers log files to you. The recorded information includes the configuration item (AWS resource), relationships between configuration items (AWS resources), any configuration changes between resources. It is recommended AWS Config be enabled in all regions.","DefaultValue": null,"AuditProcedure": "Process to evaluate AWS Config configuration per region**From Console:**1. Sign in to the AWS Management Console and open the AWS Config console at [https://console.aws.amazon.com/config/](https://console.aws.amazon.com/config/). 2. On the top right of the console select target Region. 3. If presented with Setup AWS Config - follow remediation procedure: 4. On the Resource inventory page, Click on edit (the gear icon). The Set Up AWS Config page appears. 5. Ensure 1 or both check-boxes under \"All Resources\" is checked.- Include global resources related to IAM resources - which needs to be enabled in 1 region only 6. Ensure the correct S3 bucket has been defined. 7. Ensure the correct SNS topic has been defined. 8. Repeat steps 2 to 7 for each region.**From Command Line:**1. Run this command to show all AWS Config recorders and their properties: ``` aws configservice describe-configuration-recorders ``` 2. Evaluate the output to ensure that there's at least one recorder for which `recordingGroup` object includes `\"allSupported\": true` AND `\"includeGlobalResourceTypes\": true`Note: There is one more parameter \"ResourceTypes\" in recordingGroup object. We don't need to check the same as whenever we set \"allSupported\": true, AWS enforces resource types to be empty (\"ResourceTypes\":[])Sample Output:``` {\"ConfigurationRecorders\": [{\"recordingGroup\": {\"allSupported\": true,\"resourceTypes\": [],\"includeGlobalResourceTypes\": true},\"roleARN\": \"arn:aws:iam:::role/service-role/\",\"name\": \"default\"}] } ```3. Run this command to show the status for all AWS Config recorders: ``` aws configservice describe-configuration-recorder-status ``` 4. In the output, find recorders with `name` key matching the recorders that met criteria in step 2. Ensure that at least one of them includes `\"recording\": true` and `\"lastStatus\": \"SUCCESS\"`","ImpactStatement": "It is recommended AWS Config be enabled in all regions.","AssessmentStatus": "Automated","RationaleStatement": "The AWS configuration item history captured by AWS Config enables security analysis, resource change tracking, and compliance auditing.","RemediationProcedure": "To implement AWS Config configuration:**From Console:**1. Select the region you want to focus on in the top right of the console 2. Click `Services`3. Click `Config`4. Define which resources you want to record in the selected region 5. Choose to include global resources (IAM resources) 6. Specify an S3 bucket in the same account or in another managed AWS account 7. Create an SNS Topic from the same AWS account or another managed AWS account**From Command Line:**1. Ensure there is an appropriate S3 bucket, SNS topic, and IAM role per the [AWS Config Service prerequisites](http://docs.aws.amazon.com/config/latest/developerguide/gs-cli-prereq.html). 2. Run this command to set up the configuration recorder ``` aws configservice subscribe --s3-bucket my-config-bucket --sns-topic arn:aws:sns:us-east-1:012345678912:my-config-notice --iam-role arn:aws:iam::012345678912:role/myConfigRole ``` 3. Run this command to start the configuration recorder: ``` start-configuration-recorder --configuration-recorder-name  ```","AdditionalInformation": ""}],"description": "Ensure AWS Config is enabled in all regions","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.6": {"name": "3.6","checks": {"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerLogs.html","Description": "S3 Bucket Access Logging generates a log that contains access records for each request made to your S3 bucket. An access log record contains details about the request, such as the request type, the resources specified in the request worked, and the time and date the request was processed. It is recommended that bucket access logging be enabled on the CloudTrail S3 bucket.","DefaultValue": null,"AuditProcedure": "Perform the following ensure the CloudTrail S3 bucket has access logging is enabled:**From Console:**1. Go to the Amazon CloudTrail console at [https://console.aws.amazon.com/cloudtrail/home](https://console.aws.amazon.com/cloudtrail/home) 2. In the API activity history pane on the left, click Trails 3. In the Trails pane, note the bucket names in the S3 bucket column 4. Sign in to the AWS Management Console and open the S3 console at [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3). 5. Under `All Buckets` click on a target S3 bucket 6. Click on `Properties` in the top right of the console 7. Under `Bucket:` _ `` _ click on `Logging`8. Ensure `Enabled` is checked.**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ```aws cloudtrail describe-trails --query 'trailList[*].S3BucketName'``` 2. Ensure Bucket Logging is enabled: ``` aws s3api get-bucket-logging --bucket  ``` Ensure command does not returns empty output.Sample Output for a bucket with logging enabled:``` {\"LoggingEnabled\": {\"TargetPrefix\": \"\",\"TargetBucket\": \"\"} } ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "By enabling S3 bucket logging on target S3 buckets, it is possible to capture all events which may affect objects within any target buckets. Configuring logs to be placed in a separate bucket allows access to log information which can be useful in security and incident response workflows.","RemediationProcedure": "Perform the following to enable S3 bucket logging:**From Console:**1. Sign in to the AWS Management Console and open the S3 console at [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3). 2. Under `All Buckets` click on the target S3 bucket 3. Click on `Properties` in the top right of the console 4. Under `Bucket:`  click on `Logging`5. Configure bucket logging- Click on the `Enabled` checkbox- Select Target Bucket from list- Enter a Target Prefix 6. Click `Save`.**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ``` aws cloudtrail describe-trails --region  --query trailList[*].S3BucketName ``` 2. Copy and add target bucket name at ``, Prefix for logfile at `` and optionally add an email address in the following template and save it as ``: ``` {\"LoggingEnabled\": {\"TargetBucket\": \"\",\"TargetPrefix\": \"\",\"TargetGrants\": [{\"Grantee\": {\"Type\": \"AmazonCustomerByEmail\",\"EmailAddress\": \"\"},\"Permission\": \"FULL_CONTROL\"}]}} ``` 3. Run the `put-bucket-logging` command with bucket name and `` as input, for more information refer at [put-bucket-logging](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-logging.html): ``` aws s3api put-bucket-logging --bucket  --bucket-logging-status file:// ```","AdditionalInformation": ""}],"description": "Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.7": {"name": "3.7","checks": {"cloudtrail_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/encrypting-cloudtrail-log-files-with-aws-kms.html:https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html","Description": "AWS CloudTrail is a web service that records AWS API calls for an account and makes those logs available to users and resources in accordance with IAM policies. AWS Key Management Service (KMS) is a managed service that helps create and control the encryption keys used to encrypt account data, and uses Hardware Security Modules (HSMs) to protect the security of encryption keys. CloudTrail logs can be configured to leverage server side encryption (SSE) and KMS customer created master keys (CMK) to further protect CloudTrail logs. It is recommended that CloudTrail be configured to use SSE-KMS.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if CloudTrail is configured to use SSE-KMS:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. In the left navigation pane, choose `Trails` . 3. Select a Trail 4. Under the `S3` section, ensure `Encrypt log files` is set to `Yes` and a KMS key ID is specified in the `KSM Key Id` field.**From Command Line:**1. Run the following command: ```aws cloudtrail describe-trails``` 2. For each trail listed, SSE-KMS is enabled if the trail has a `KmsKeyId` property defined.","ImpactStatement": "Customer created keys incur an additional cost. See https://aws.amazon.com/kms/pricing/ for more information.","AssessmentStatus": "Automated","RationaleStatement": "Configuring CloudTrail to use SSE-KMS provides additional confidentiality controls on log data as a given user must have S3 read permission on the corresponding log bucket and must be granted decrypt permission by the CMK policy.","RemediationProcedure": "Perform the following to configure CloudTrail to use SSE-KMS:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. In the left navigation pane, choose `Trails` . 3. Click on a Trail 4. Under the `S3` section click on the edit button (pencil icon) 5. Click `Advanced`6. Select an existing CMK from the `KMS key Id` drop-down menu- Note: Ensure the CMK is located in the same region as the S3 bucket- Note: You will need to apply a KMS Key policy on the selected CMK in order for CloudTrail as a service to encrypt and decrypt log files using the CMK provided. Steps are provided [here](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/create-kms-key-policy-for-cloudtrail.html) for editing the selected CMK Key policy 7. Click `Save`8. You will see a notification message stating that you need to have decrypt permissions on the specified KMS key to decrypt log files. 9. Click `Yes` **From Command Line:** ``` aws cloudtrail update-trail --name  --kms-id  aws kms put-key-policy --key-id  --policy  ```","AdditionalInformation": "3 statements which need to be added to the CMK policy:1\\. Enable Cloudtrail to describe CMK properties ``` 
{\"Sid\": \"Allow CloudTrail access\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\"Action\": \"kms:DescribeKey\",\"Resource\": \"*\" } ``` 2\\. Granting encrypt permissions ``` 
{\"Sid\": \"Allow CloudTrail to encrypt logs\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\"Action\": \"kms:GenerateDataKey*\",\"Resource\": \"*\",\"Condition\": {\"StringLike\": {\"kms:EncryptionContext:aws:cloudtrail:arn\": [\"arn:aws:cloudtrail:*:aws-account-id:trail/*\"]}} } ``` 3\\. Granting decrypt permissions ``` 
{\"Sid\": \"Enable CloudTrail log decrypt permissions\",\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"arn:aws:iam::aws-account-id:user/username\"},\"Action\": \"kms:Decrypt\",\"Resource\": \"*\",\"Condition\": {\"Null\": {\"kms:EncryptionContext:aws:cloudtrail:arn\": \"false\"}} } ```"}],"description": "Ensure CloudTrail logs are encrypted at rest using KMS CMKs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.8": {"name": "3.8","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://aws.amazon.com/kms/pricing/:https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final","Description": "AWS Key Management Service (KMS) allows customers to rotate the backing key which is key material stored within the KMS which is tied to the key ID of the Customer Created customer master key (CMK). It is the backing key that is used to perform cryptographic operations such as encryption and decryption. Automated key rotation currently retains all prior backing keys so that decryption of encrypted data can take place transparently. It is recommended that CMK key rotation be enabled for symmetric keys. Key rotation can not be enabled for any asymmetric CMK.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam](https://console.aws.amazon.com/iam). 2. In the left navigation pane, choose `Customer managed keys` 3. Select a customer managed CMK where `Key spec = SYMMETRIC_DEFAULT` 4. Underneath the `General configuration` panel open the tab `Key rotation` 5. Ensure that the checkbox `Automatically rotate this KMS key every year.` is activated 6. Repeat steps 3 - 5 for all customer managed CMKs where \"Key spec = SYMMETRIC_DEFAULT\"**From Command Line:**1. Run the following command to get a list of all keys and their associated `KeyIds````aws kms list-keys ``` 2. For each key, note the KeyId and run the following command ``` describe-key --key-id  ``` 3. If the response contains \"KeySpec = SYMMETRIC_DEFAULT\" run the following command ```aws kms get-key-rotation-status --key-id  ``` 4. Ensure `KeyRotationEnabled` is set to `true` 5. Repeat steps 2 - 4 for all remaining CMKs","ImpactStatement": "Creation, management, and storage of CMKs may require additional time from and administrator.","AssessmentStatus": "Automated","RationaleStatement": "Rotating encryption keys helps reduce the potential impact of a compromised key as data encrypted with a new key cannot be accessed with a previous key that may have been exposed. Keys should be rotated every year, or upon event that would result in the compromise of that key.","RemediationProcedure": "**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam](https://console.aws.amazon.com/iam). 2. In the left navigation pane, choose `Customer managed keys` . 3. Select a customer managed CMK where `Key spec = SYMMETRIC_DEFAULT` 4. Underneath the \"General configuration\" panel open the tab \"Key rotation\" 5. Check the \"Automatically rotate this KMS key every year.\" checkbox**From Command Line:**1. Run the following command to enable key rotation: ```aws kms enable-key-rotation --key-id  ```","AdditionalInformation": ""}],"description": "Ensure rotation for customer created symmetric CMKs is enabled","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.9": {"name": "3.9","checks": {"vpc_flow_logs_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/flow-logs.html","Description": "VPC Flow Logs is a feature that enables you to capture information about the IP traffic going to and from network interfaces in your VPC. After you've created a flow log, you can view and retrieve its data in Amazon CloudWatch Logs. It is recommended that VPC Flow Logs be enabled for packet \"Rejects\" for VPCs.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if VPC Flow logs are enabled:**From Console:**1. Sign into the management console 2. Select `Services` then `VPC`3. In the left navigation pane, select `Your VPCs`4. Select a VPC 5. In the right pane, select the `Flow Logs` tab. 6. Ensure a Log Flow exists that has `Active` in the `Status` column.**From Command Line:**1. Run `describe-vpcs` command (OSX/Linux/UNIX) to list the VPC networks available in the current AWS region: ``` aws ec2 describe-vpcs --region  --query Vpcs[].VpcId ``` 2. The command output returns the `VpcId` available in the selected region. 3. Run `describe-flow-logs` command (OSX/Linux/UNIX) using the VPC ID to determine if the selected virtual network has the Flow Logs feature enabled: ``` aws ec2 describe-flow-logs --filter \"Name=resource-id,Values=\" ``` 4. If there are no Flow Logs created for the selected VPC, the command output will return an `empty list []`. 5. Repeat step 3 for other VPCs available in the same region. 6. Change the region by updating `--region` and repeat steps 1 - 5 for all the VPCs.","ImpactStatement": "By default, CloudWatch Logs will store Logs indefinitely unless a specific retention period is defined for the log group. When choosing the number of days to retain, keep in mind the average days it takes an organization to realize they have been breached is 210 days (at the time of this writing). Since additional time is required to research a breach, a minimum 365 day retention policy allows time for detection and research. You may also wish to archive the logs to a cheaper storage service rather than simply deleting them. See the following AWS resource to manage CloudWatch Logs retention periods:1. https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/SettingLogRetention.html","AssessmentStatus": "Automated","RationaleStatement": "VPC Flow Logs provide visibility into network traffic that traverses the VPC and can be used to detect anomalous traffic or insight during security workflows.","RemediationProcedure": "Perform the following to determine if VPC Flow logs is enabled:**From Console:**1. Sign into the management console 2. Select `Services` then `VPC`3. In the left navigation pane, select `Your VPCs`4. Select a VPC 5. In the right pane, select the `Flow Logs` tab. 6. If no Flow Log exists, click `Create Flow Log`7. For Filter, select `Reject` 8. Enter in a `Role` and `Destination Log Group`9. Click `Create Log Flow`10. Click on `CloudWatch Logs Group` **Note:** Setting the filter to \"Reject\" will dramatically reduce the logging data accumulation for this recommendation and provide sufficient information for the purposes of breach detection, research and remediation. However, during periods of least privilege security group engineering, setting this the filter to \"All\" can be very helpful in discovering existing traffic flows required for proper operation of an already running environment.**From Command Line:**1. Create a policy document and name it as `role_policy_document.json` and paste the following content: ``` {\"Version\": \"2012-10-17\",\"Statement\": [{\"Sid\": \"test\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"ec2.amazonaws.com\"},\"Action\": \"sts:AssumeRole\"}] } ``` 2. Create another policy document and name it as `iam_policy.json` and paste the following content: ``` {\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Action\":[\"logs:CreateLogGroup\",\"logs:CreateLogStream\",\"logs:DescribeLogGroups\",\"logs:DescribeLogStreams\",\"logs:PutLogEvents\",\"logs:GetLogEvents\",\"logs:FilterLogEvents\"],\"Resource\": \"*\"}] } ``` 3. Run the below command to create an IAM role: ``` aws iam create-role --role-name  --assume-role-policy-document file://role_policy_document.json``` 4. Run the below command to create an IAM policy: ``` aws iam create-policy --policy-name  --policy-document file://iam-policy.json ``` 5. Run `attach-group-policy` command using the IAM policy ARN returned at the previous step to attach the policy to the IAM role (if the command succeeds, no output is returned): ``` aws iam attach-group-policy --policy-arn arn:aws:iam:::policy/ --group-name  ``` 6. Run `describe-vpcs` to get the VpcId available in the selected region: ``` aws ec2 describe-vpcs --region  ``` 7. The command output should return the VPC Id available in the selected region. 8. Run `create-flow-logs` to create a flow log for the vpc: ``` aws ec2 create-flow-logs --resource-type VPC --resource-ids  --traffic-type REJECT --log-group-name  --deliver-logs-permission-arn  ``` 9. Repeat step 8 for other vpcs available in the selected region. 10. Change the region by updating --region and repeat remediation procedure for other vpcs.","AdditionalInformation": ""}],"description": "Ensure VPC flow logging is enabled in all VPCs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"4.1": {"name": "4.1","checks": {"cloudwatch_log_metric_filter_unauthorized_api_calls": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://aws.amazon.com/sns/:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for unauthorized API calls.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with \"Name\":` note ``- From value associated with \"CloudWatchLogsLogGroupArn\" note Example: for CloudWatchLogsLogGroupArn that looks like arn:aws:logs:::log-group:NewGroup:*,  would be NewGroup- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name <\"Name\" as shown in describe-trails>`Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this `` that you captured in step 1:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.errorCode = *UnauthorizedOperation) || ($.errorCode = AccessDenied*) || ($.sourceIPAddress!=delivery.logs.amazonaws.com) || ($.eventName!=HeadBucket) }\", ```4. Note the \"filterName\" `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query \"MetricAlarms[?MetricName == `unauthorized_api_calls_metric`]\" ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "This alert may be triggered by normal read-only console activities that attempt to opportunistically gather optional information, but gracefully fail if they don't have permissions.If an excessive number of alerts are being generated then an organization may wish to consider adding read access to the limited IAM user permissions simply to quiet the alerts.In some cases doing this may allow the users to actually view some areas of the system - any additional access given should be reviewed for alignment with the original limited IAM user intent.","AssessmentStatus": "Automated","RationaleStatement": "Monitoring unauthorized API calls will help reveal application errors and may reduce time to detect malicious activity.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for unauthorized API calls and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name \"cloudtrail_log_group_name\" --filter-name \"\" --metric-transformations metricName=unauthorized_api_calls_metric,metricNamespace=CISBenchmark,metricValue=1 --filter-pattern \"{ ($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\") || ($.sourceIPAddress!=\"delivery.logs.amazonaws.com\") || ($.eventName!=\"HeadBucket\") }\" ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms. **Note**: Capture the TopicArn displayed when creating the SNS Topic in Step 2.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name \"unauthorized_api_calls_alarm\" --metric-name \"unauthorized_api_calls_metric\" --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace \"CISBenchmark\" --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for unauthorized API calls","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.2": {"name": "4.2","checks": {"cloudwatch_log_metric_filter_sign_in_without_mfa": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/viewing_metrics_with_cloudwatch.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for console logins that are not protected by multi-factor authentication (MFA).","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all `CloudTrails`:``` aws cloudtrail describe-trails ```- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region `CloudTrail` is active``` aws cloudtrail get-trail-status --name  ```Ensure in the output that `IsLogging` is set to `TRUE`- Ensure identified Multi-region 'Cloudtrail' captures all Management Events``` aws cloudtrail get-event-selectors --trail-name  ```Ensure in the output there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }\" ```Or (To reduce false positives incase Single Sign-On (SSO) is used in organization):``` \"filterPattern\": \"{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\") }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring for single-factor console logins will increase visibility into accounts that are not protected by MFA.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Management Console sign-in without MFA and the `` taken from audit step 1.Use Command: ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }' ```Or (To reduce false positives incase Single Sign-On (SSO) is used in organization):``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\") }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored -Filter pattern set to `{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\"}` reduces false alarms raised when user logs in via SSO account."}],"description": "Ensure a log metric filter and alarm exist for Management Console sign-in without MFA","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.3": {"name": "4.3","checks": {"cloudwatch_log_metric_filter_root_usage": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for 'root' login attempts.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails:`aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring for 'root' account logins will provide visibility into the use of a fully privileged account and an opportunity to reduce the use of it.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for 'Root' account usage and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name `` --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "**Configuring log metric filter and alarm on Multi-region (global) CloudTrail**- ensures that activities from all regions (used as well as unused) are monitored- ensures that activities on all supported global services are monitored- ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for usage of 'root' account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.4": {"name": "4.4","checks": {"cloudwatch_log_metric_filter_policy_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established changes made to Identity and Access Management (IAM) policies.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails:`aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to IAM policies will help ensure authentication and authorization controls remain intact.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for IAM policy changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name `` --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for IAM policy changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.5": {"name": "4.5","checks": {"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for detecting changes to CloudTrail's configurations.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to CloudTrail's configuration will help ensure sustained visibility to activities performed in the AWS account.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for cloudtrail configuration changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for CloudTrail configuration changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.6": {"name": "4.6","checks": {"cloudwatch_log_metric_filter_authentication_failures": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for failed console authentication attempts.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring failed console logins may decrease lead time to detect an attempt to brute force a credential, which may provide an indicator, such as source IP, that can be used in other event correlation.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS management Console Login Failures and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }' ``` **Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for AWS Management Console authentication failures","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.7": {"name": "4.7","checks": {"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for customer created CMKs which have changed state to disabled or scheduled deletion.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Data encrypted with disabled or deleted keys will no longer be accessible.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for disabled or scheduled for deletion CMK's and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }' ``` **Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.8": {"name": "4.8","checks": {"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for changes to S3 bucket policies.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to S3 bucket policies may reduce time to detect and correct permissive policies on sensitive S3 buckets.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for S3 bucket policy changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for S3 bucket policy changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.9": {"name": "4.9","checks": {"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for detecting changes to CloudTrail's configurations.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to AWS Config configuration will help ensure sustained visibility of configuration items within the AWS account.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Configuration changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for AWS Config configuration changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"5.1": {"name": "5.1","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html:https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Security.html#VPC_Security_Comparison","Description": "The Network Access Control List (NACL) function provide stateless filtering of ingress and egress network traffic to AWS resources. It is recommended that no NACL allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "**From Console:**Perform the following to determine if the account is configured as prescribed: 1. Login to the AWS Management Console at https://console.aws.amazon.com/vpc/home 2. In the left pane, click `Network ACLs` 3. For each network ACL, perform the following:- Select the network ACL- Click the `Inbound Rules` tab- Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `0.0.0.0/0` and shows `ALLOW`**Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "**From Console:**Perform the following: 1. Login to the AWS Management Console at https://console.aws.amazon.com/vpc/home 2. In the left pane, click `Network ACLs` 3. For each network ACL to remediate, perform the following:- Select the network ACL- Click the `Inbound Rules` tab- Click `Edit inbound rules`- Either A) update the Source field to a range other than 0.0.0.0/0, or, B) Click `Delete` to remove the offending inbound rule- Click `Save`","AdditionalInformation": ""}],"description": "Ensure no Network ACLs allow ingress from 0.0.0.0/0 to remote server administration ports","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"5.2": {"name": "5.2","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#deleting-security-group-rule","Description": "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `0.0.0.0/0` **Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports.","ImpactStatement": "When updating an existing environment, ensure that administrators have access to remote server administration ports through another mechanism before removing access by deleting the 0.0.0.0/0 inbound rule.","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "Perform the following to implement the prescribed state:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Click the `Edit inbound rules` button 4. Identify the rules to be edited or removed 5. Either A) update the Source field to a range other than 0.0.0.0/0, or, B) Click `Delete` to remove the offending inbound rule 6. Click `Save rules`","AdditionalInformation": ""}],"description": "Ensure no security groups allow ingress from 0.0.0.0/0 to remote server administration ports","checks_status": {"fail": 0,"pass": 3,"total": 3,"manual": 0}},"5.3": {"name": "5.3","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#deleting-security-group-rule","Description": "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `::/0` **Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports.","ImpactStatement": "When updating an existing environment, ensure that administrators have access to remote server administration ports through another mechanism before removing access by deleting the ::/0 inbound rule.","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "Perform the following to implement the prescribed state:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Click the `Edit inbound rules` button 4. Identify the rules to be edited or removed 5. Either A) update the Source field to a range other than ::/0, or, B) Click `Delete` to remove the offending inbound rule 6. Click `Save rules`","AdditionalInformation": ""}],"description": "Ensure no security groups allow ingress from ::/0 to remote server administration ports","checks_status": {"fail": 0,"pass": 3,"total": 3,"manual": 0}},"5.4": {"name": "5.4","checks": {"ec2_securitygroup_default_restrict_traffic": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#default-security-group","Description": "A VPC comes with a default security group whose initial settings deny all inbound traffic, allow all outbound traffic, and allow all traffic between instances assigned to the security group. If you don't specify a security group when you launch an instance, the instance is automatically assigned to this default security group. Security groups provide stateful filtering of ingress/egress network traffic to AWS resources. It is recommended that the default security group restrict all traffic.The default VPC in every region should have its default security group updated to comply. Any newly created VPCs will automatically contain a default security group that will need remediation to comply with this recommendation.**NOTE:** When implementing this recommendation, VPC flow logging is invaluable in determining the least privilege port access required by systems to work properly because it can log all packet acceptances and rejections occurring under the current security groups. This dramatically reduces the primary barrier to least privilege engineering - discovering the minimum ports required by systems in the environment. Even if the VPC flow logging recommendation in this benchmark is not adopted as a permanent security measure, it should be used during any period of discovery and engineering for least privileged security groups.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:Security Group State1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. For each default security group, perform the following: 1. Select the `default` security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exist 4. Click the `Outbound Rules` tab 5. Ensure no rules existSecurity Group Members1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all default groups in all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. Copy the id of the default security group. 5. Change to the EC2 Management Console at https://console.aws.amazon.com/ec2/v2/home 6. In the filter column type 'Security Group ID : < security group id from #4 >'","ImpactStatement": "Implementing this recommendation in an existing VPC containing operating resources requires extremely careful migration planning as the default security groups are likely to be enabling many ports that are unknown. Enabling VPC flow logging (of accepts) in an existing environment that is known to be breach free will reveal the current pattern of ports being used for each instance to communicate successfully.","AssessmentStatus": "Automated","RationaleStatement": "Configuring all VPC default security groups to restrict all traffic will encourage least privilege security group development and mindful placement of AWS resources into security groups which will in-turn reduce the exposure of those resources.","RemediationProcedure": "Security Group MembersPerform the following to implement the prescribed state:1. Identify AWS resources that exist within the default security group 2. Create a set of least privilege security groups for those resources 3. Place the resources in those security groups 4. Remove the resources noted in #1 from the default security groupSecurity Group State1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. For each default security group, perform the following: 1. Select the `default` security group 2. Click the `Inbound Rules` tab 3. Remove any inbound rules 4. Click the `Outbound Rules` tab 5. Remove any Outbound rulesRecommended:IAM groups allow you to edit the \"name\" field. After remediating default groups rules for all VPCs in all regions, edit this field to add text similar to \"DO NOT USE. DO NOT ADD RULES\"","AdditionalInformation": ""}],"description": "Ensure the default security group of every VPC restricts all traffic","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"5.5": {"name": "5.5","checks": {"vpc_peering_routing_tables_with_least_privilege": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "5. Networking","References": "https://docs.aws.amazon.com/AmazonVPC/latest/PeeringGuide/peering-configurations-partial-access.html:https://docs.aws.amazon.com/cli/latest/reference/ec2/create-vpc-peering-connection.html","Description": "Once a VPC peering connection is established, routing tables must be updated to establish any connections between the peered VPCs. These routes can be as specific as desired - even peering a VPC to only a single host on the other side of the connection.","DefaultValue": null,"AuditProcedure": "Review routing tables of peered VPCs for whether they route all subnets of each VPC and whether that is necessary to accomplish the intended purposes for peering the VPCs.**From Command Line:**1. List all the route tables from a VPC and check if \"GatewayId\" is pointing to a __ (e.g. pcx-1a2b3c4d) and if \"DestinationCidrBlock\" is as specific as desired. ``` aws ec2 describe-route-tables --filter \"Name=vpc-id,Values=\" --query \"RouteTables[*].{RouteTableId:RouteTableId, VpcId:VpcId, Routes:Routes, AssociatedSubnets:Associations[*].SubnetId}\" ```","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Being highly selective in peering routing tables is a very effective way of minimizing the impact of breach as resources outside of these routes are inaccessible to the peered VPC.","RemediationProcedure": "Remove and add route table entries to ensure that the least number of subnets or hosts as is required to accomplish the purpose for peering are routable.**From Command Line:**1. For each __ containing routes non compliant with your routing policy (which grants more than desired \"least access\"), delete the non compliant route: ``` aws ec2 delete-route --route-table-id  --destination-cidr-block  ```2. Create a new compliant route: ``` aws ec2 create-route --route-table-id  --destination-cidr-block  --vpc-peering-connection-id  ```","AdditionalInformation": "If an organization has AWS transit gateway implemented in their VPC architecture they should look to apply the recommendation above for \"least access\" routing architecture at the AWS transit gateway level in combination with what must be implemented at the standard VPC route table. More specifically, to route traffic between two or more VPCs via a transit gateway VPCs must have an attachment to a transit gateway route table as well as a route, therefore to avoid routing traffic between VPCs an attachment to the transit gateway route table should only be added where there is an intention to route traffic between the VPCs. As transit gateways are able to host multiple route tables it is possible to group VPCs by attaching them to a common route table."}],"description": "Ensure routing tables for VPC peering are \"least access\"","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.10": {"name": "1.10","checks": {"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://tools.ietf.org/html/rfc6238:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#enable-mfa-for-privileged-users:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html:https://blogs.aws.amazon.com/security/post/Tx2SJJYE082KBUK/How-to-Delegate-Management-of-Multi-Factor-Authentication-to-AWS-IAM-Users","Description": "Multi-Factor Authentication (MFA) adds an extra layer of authentication assurance beyond traditional credentials. With MFA enabled, when a user signs in to the AWS Console, they will be prompted for their user name and password as well as for an authentication code from their physical or virtual MFA token. It is recommended that MFA be enabled for all accounts that have a console password.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if a MFA device is enabled for all IAM users having a console password:**From Console:**1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the left pane, select `Users`3. If the `MFA` or `Password age` columns are not visible in the table, click the gear icon at the upper right corner of the table and ensure a checkmark is next to both, then click `Close`. 4. Ensure that for each user where the `Password age` column shows a password age, the `MFA` column shows `Virtual`, `U2F Security Key`, or `Hardware`.**From Command Line:**1. Run the following command (OSX/Linux/UNIX) to generate a list of all IAM users along with their password and MFA status: ```aws iam generate-credential-report ``` ```aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,8``` 2. The output of this command will produce a table similar to the following: ```user,password_enabled,mfa_activeelise,false,falsebrandon,true,truerakesh,false,falsehelene,false,falseparas,true,trueanitha,false,false``` 3. For any column having `password_enabled` set to `true` , ensure `mfa_active` is also set to `true.`","ImpactStatement": "AWS will soon end support for SMS multi-factor authentication (MFA). New customers are not allowed to use this feature. We recommend that existing customers switch to one of the following alternative methods of MFA.","AssessmentStatus": "Automated","RationaleStatement": "Enabling MFA provides increased security for console access as it requires the authenticating principal to possess a device that displays a time-sensitive key and have knowledge of a credential.","RemediationProcedure": "Perform the following to enable MFA:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at 'https://console.aws.amazon.com/iam/' 2. In the left pane, select `Users`. 3. In the `User Name` list, choose the name of the intended MFA user. 4. Choose the `Security Credentials` tab, and then choose `Manage MFA Device`. 5. In the `Manage MFA Device wizard`, choose `Virtual MFA` device, and then choose `Continue`. IAM generates and displays configuration information for the virtual MFA device, including a QR code graphic. The graphic is a representation of the 'secret configuration key' that is available for manual entry on devices that do not support QR codes.6. Open your virtual MFA application. (For a list of apps that you can use for hosting virtual MFA devices, see Virtual MFA Applications at https://aws.amazon.com/iam/details/mfa/#Virtual_MFA_Applications). If the virtual MFA application supports multiple accounts (multiple virtual MFA devices), choose the option to create a new account (a new virtual MFA device). 7. Determine whether the MFA app supports QR codes, and then do one of the following: - Use the app to scan the QR code. For example, you might choose the camera icon or choose an option similar to Scan code, and then use the device's camera to scan the code.- In the Manage MFA Device wizard, choose Show secret key for manual configuration, and then type the secret configuration key into your MFA application. When you are finished, the virtual MFA device starts generating one-time passwords.8. In the `Manage MFA Device wizard`, in the `MFA Code 1 box`, type the `one-time password` that currently appears in the virtual MFA device. Wait up to 30 seconds for the device to generate a new one-time password. Then type the second `one-time password` into the `MFA Code 2 box`.9. Click `Assign MFA`.","AdditionalInformation": "**Forced IAM User Self-Service Remediation**Amazon has published a pattern that forces users to self-service setup MFA before they have access to their complete permissions set. Until they complete this step, they cannot access their full permissions. This pattern can be used on new AWS accounts. It can also be used on existing accounts - it is recommended users are given instructions and a grace period to accomplish MFA enrollment before active enforcement on existing AWS accounts."}],"description": "Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.11": {"name": "1.11","checks": {"iam_user_no_setup_initial_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/cli/latest/reference/iam/delete-access-key.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html","Description": "AWS console defaults to no check boxes selected when creating a new IAM user. When cerating the IAM User credentials you have to determine what type of access they require. Programmatic access: The IAM user might need to make API calls, use the AWS CLI, or use the Tools for Windows PowerShell. In that case, create an access key (access key ID and a secret access key) for that user. AWS Management Console access: If the user needs to access the AWS Management Console, create a password for the user.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if access keys were created upon user creation and are being used and rotated as prescribed:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on a User where column `Password age` and `Access key age` is not set to `None` 5. Click on `Security credentials` Tab 6. Compare the user 'Creation time` to the Access Key `Created` date. 6. For any that match, the key was created during initial user setup.- Keys that were created at the same time as the user profile and do not have a last used date should be deleted. Refer to the remediation below.**From Command Line:**1. Run the following command (OSX/Linux/UNIX) to generate a list of all IAM users along with their access keys utilization: ```aws iam generate-credential-report ``` ```aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,9,11,14,16 ``` 2. The output of this command will produce a table similar to the following: ``` user,password_enabled,access_key_1_active,access_key_1_last_used_date,access_key_2_active,access_key_2_last_used_dateelise,false,true,2015-04-16T15:14:00+00:00,false,N/Abrandon,true,true,N/A,false,N/Arakesh,false,false,N/A,false,N/Ahelene,false,true,2015-11-18T17:47:00+00:00,false,N/Aparas,true,true,2016-08-28T12:04:00+00:00,true,2016-03-04T10:11:00+00:00anitha,true,true,2016-06-08T11:43:00+00:00,true,N/A``` 3. For any user having `password_enabled` set to `true` AND `access_key_last_used_date` set to `N/A` refer to the remediation below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Requiring the additional steps be taken by the user for programmatic access after their profile has been created will give a stronger indication of intent that access keys are [a] necessary for their work and [b] once the access key is established on an account that the keys may be in use somewhere in the organization.**Note**: Even if it is known the user will need access keys, require them to create the keys themselves or put in a support ticket to have them created as a separate step from user creation.","RemediationProcedure": "Perform the following to delete access keys that do not pass the audit:**From Console:**1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. As an Administrator - Click on the X `(Delete)` for keys that were created at the same time as the user profile but have not been used. 7. As an IAM User- Click on the X `(Delete)` for keys that were created at the same time as the user profile but have not been used.**From Command Line:** ``` aws iam delete-access-key --access-key-id  --user-name  ```","AdditionalInformation": "Credential report does not appear to contain \"Key Creation Date\""}],"description": "Do not setup access keys during initial user setup for all IAM users that have a console password","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.12": {"name": "1.12","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#remove-credentials:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_admin-change-user.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "AWS IAM users can access AWS resources using different types of credentials, such as passwords or access keys. It is recommended that all credentials that have been unused in 45 or greater days be deactivated or removed.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if unused credentials exist:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM` 4. Click on `Users` 5. Click the `Settings` (gear) icon. 6. Select `Console last sign-in`, `Access key last used`, and `Access Key Id` 7. Click on `Close`8. Check and ensure that `Console last sign-in` is less than 45 days ago.**Note** - `Never` means the user has never logged in.9. Check and ensure that `Access key age` is less than 45 days and that `Access key last used` does not say `None`If the user hasn't signed into the Console in the last 45 days or Access keys are over 45 days old refer to the remediation.**From Command Line:****Download Credential Report:**1. Run the following commands: ```aws iam generate-credential-report aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,5,6,9,10,11,14,15,16 | grep -v '^' ```**Ensure unused credentials do not exist:**2. For each user having `password_enabled` set to `TRUE` , ensure `password_last_used_date` is less than `45` days ago.- When `password_enabled` is set to `TRUE` and `password_last_used` is set to `No_Information` , ensure `password_last_changed` is less than 45 days ago.3. For each user having an `access_key_1_active` or `access_key_2_active` to `TRUE` , ensure the corresponding `access_key_n_last_used_date` is less than `45` days ago.- When a user having an `access_key_x_active` (where x is 1 or 2) to `TRUE` and corresponding access_key_x_last_used_date is set to `N/A', ensure `access_key_x_last_rotated` is less than 45 days ago.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Disabling or removing unnecessary credentials will reduce the window of opportunity for credentials associated with a compromised or abandoned account to be used.","RemediationProcedure": "**From Console:**Perform the following to manage Unused Password (IAM user console access)1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. Select user whose `Console last sign-in` is greater than 45 days 7. Click `Security credentials` 8. In section `Sign-in credentials`, `Console password` click `Manage`9. Under Console Access select `Disable` 10.Click `Apply`Perform the following to deactivate Access Keys:1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. Select any access keys that are over 45 days old and that have been used and - Click on `Make Inactive` 7. Select any access keys that are over 45 days old and that have not been used and - Click the X to `Delete`","AdditionalInformation": " is excluded in the audit since the root account should not be used for day to day business and would likely be unused for more than 45 days."}],"description": "Ensure credentials unused for 45 days or greater are disabled","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1.13": {"name": "1.13","checks": {"iam_user_two_active_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "Access keys are long-term credentials for an IAM user or the AWS account 'root' user. You can use access keys to sign programmatic requests to the AWS CLI or AWS API (directly or using the AWS SDK)","DefaultValue": null,"AuditProcedure": "**From Console:**1. Sign in to the AWS Management Console and navigate to IAM dashboard at `https://console.aws.amazon.com/iam/`. 2. In the left navigation panel, choose `Users`. 3. Click on the IAM user name that you want to examine. 4. On the IAM user configuration page, select `Security Credentials` tab. 5. Under `Access Keys` section, in the Status column, check the current status for each access key associated with the IAM user. If the selected IAM user has more than one access key activated then the users access configuration does not adhere to security best practices and the risk of accidental exposures increases. - Repeat steps no. 3 – 5 for each IAM user in your AWS account.**From Command Line:**1. Run `list-users` command to list all IAM users within your account: ``` aws iam list-users --query \"Users[*].UserName\" ``` The command output should return an array that contains all your IAM user names.2. Run `list-access-keys` command using the IAM user name list to return the current status of each access key associated with the selected IAM user: ``` aws iam list-access-keys --user-name  ``` The command output should expose the metadata `(\"Username\", \"AccessKeyId\", \"Status\", \"CreateDate\")` for each access key on that user account.3. Check the `Status` property value for each key returned to determine each keys current state. If the `Status` property value for more than one IAM access key is set to `Active`, the user access configuration does not adhere to this recommendation, refer to the remediation below.- Repeat steps no. 2 and 3 for each IAM user in your AWS account.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Access keys are long-term credentials for an IAM user or the AWS account 'root' user. You can use access keys to sign programmatic requests to the AWS CLI or AWS API. One of the best ways to protect your account is to not allow users to have multiple access keys.","RemediationProcedure": "**From Console:**1. Sign in to the AWS Management Console and navigate to IAM dashboard at `https://console.aws.amazon.com/iam/`. 2. In the left navigation panel, choose `Users`. 3. Click on the IAM user name that you want to examine. 4. On the IAM user configuration page, select `Security Credentials` tab. 5. In `Access Keys` section, choose one access key that is less than 90 days old. This should be the only active key used by this IAM user to access AWS resources programmatically. Test your application(s) to make sure that the chosen access key is working. 6. In the same `Access Keys` section, identify your non-operational access keys (other than the chosen one) and deactivate it by clicking the `Make Inactive` link. 7. If you receive the `Change Key Status` confirmation box, click `Deactivate` to switch off the selected key. 8. Repeat steps no. 3 – 7 for each IAM user in your AWS account.**From Command Line:**1. Using the IAM user and access key information provided in the `Audit CLI`, choose one access key that is less than 90 days old. This should be the only active key used by this IAM user to access AWS resources programmatically. Test your application(s) to make sure that the chosen access key is working.2. Run the `update-access-key` command below using the IAM user name and the non-operational access key IDs to deactivate the unnecessary key(s). Refer to the Audit section to identify the unnecessary access key ID for the selected IAM user**Note** - the command does not return any output: ``` aws iam update-access-key --access-key-id  --status Inactive --user-name  ``` 3. To confirm that the selected access key pair has been successfully `deactivated` run the `list-access-keys` audit command again for that IAM User: ``` aws iam list-access-keys --user-name  ``` - The command output should expose the metadata for each access key associated with the IAM user. If the non-operational key pair(s) `Status` is set to `Inactive`, the key has been successfully deactivated and the IAM user access configuration adheres now to this recommendation.4. Repeat steps no. 1 – 3 for each IAM user in your AWS account.","AdditionalInformation": ""}],"description": "Ensure there is only one active access key available for any single IAM user","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.14": {"name": "1.14","checks": {"iam_rotate_access_key_90_days": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#rotate-credentials:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html:https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "Access keys consist of an access key ID and secret access key, which are used to sign programmatic requests that you make to AWS. AWS users need their own access keys to make programmatic calls to AWS from the AWS Command Line Interface (AWS CLI), Tools for Windows PowerShell, the AWS SDKs, or direct HTTP calls using the APIs for individual AWS services. It is recommended that all access keys be regularly rotated.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if access keys are rotated as prescribed:**From Console:**1. Go to Management Console (https://console.aws.amazon.com/iam) 2. Click on `Users` 3. Click `setting` icon 4. Select `Console last sign-in` 5. Click `Close` 6. Ensure that `Access key age` is less than 90 days ago. note) `None` in the `Access key age` means the user has not used the access key.**From Command Line:**``` aws iam generate-credential-report aws iam get-credential-report --query 'Content' --output text | base64 -d ``` The `access_key_1_last_rotated` field in this file notes The date and time, in ISO 8601 date-time format, when the user's access key was created or last changed. If the user does not have an active access key, the value in this field is N/A (not applicable).","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Rotating access keys will reduce the window of opportunity for an access key that is associated with a compromised or terminated account to be used.Access keys should be rotated to ensure that data cannot be accessed with an old key which might have been lost, cracked, or stolen.","RemediationProcedure": "Perform the following to rotate access keys:**From Console:**1. Go to Management Console (https://console.aws.amazon.com/iam) 2. Click on `Users` 3. Click on `Security Credentials`4. As an Administrator - Click on `Make Inactive` for keys that have not been rotated in `90` Days 5. As an IAM User- Click on `Make Inactive` or `Delete` for keys which have not been rotated or used in `90` Days 6. Click on `Create Access Key`7. Update programmatic call with new Access Key credentials**From Command Line:**1. While the first access key is still active, create a second access key, which is active by default. Run the following command: ``` aws iam create-access-key ```At this point, the user has two active access keys.2. Update all applications and tools to use the new access key. 3. Determine whether the first access key is still in use by using this command: ``` aws iam get-access-key-last-used ``` 4. One approach is to wait several days and then check the old access key for any use before proceeding.Even if step Step 3 indicates no use of the old key, it is recommended that you do not immediately delete the first access key. Instead, change the state of the first access key to Inactive using this command: ``` aws iam update-access-key ``` 5. Use only the new access key to confirm that your applications are working. Any applications and tools that still use the original access key will stop working at this point because they no longer have access to AWS resources. If you find such an application or tool, you can switch its state back to Active to reenable the first access key. Then return to step Step 2 and update this application to use the new key.6. After you wait some period of time to ensure that all applications and tools have been updated, you can delete the first access key with this command: ``` aws iam delete-access-key ```","AdditionalInformation": ""}],"description": "Ensure access keys are rotated every 90 days or less","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.15": {"name": "1.15","checks": {"iam_policy_attached_only_to_group_or_roles": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html","Description": "IAM users are granted access to services, functions, and data through IAM policies. There are three ways to define policies for a user: 1) Edit the user policy directly, aka an inline, or user, policy; 2) attach a policy directly to a user; 3) add the user to an IAM group that has an attached policy. Only the third implementation is recommended.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if an inline policy is set or a policy is directly attached to users:1. Run the following to get a list of IAM users: ```aws iam list-users --query 'Users[*].UserName' --output text``` 2. For each user returned, run the following command to determine if any policies are attached to them: ```aws iam list-attached-user-policies --user-name aws iam list-user-policies --user-name ``` 3. If any policies are returned, the user has an inline policy or direct policy attachment.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Assigning IAM policy only through groups unifies permissions management to a single, flexible layer consistent with organizational functional roles. By unifying permissions management, the likelihood of excessive permissions is reduced.","RemediationProcedure": "Perform the following to create an IAM group and assign a policy to it:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click `Groups` and then click `Create New Group` . 3. In the `Group Name` box, type the name of the group and then click `Next Step` . 4. In the list of policies, select the check box for each policy that you want to apply to all members of the group. Then click `Next Step` . 5. Click `Create Group` Perform the following to add a user to a given group:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click `Groups`3. Select the group to add a user to 4. Click `Add Users To Group`5. Select the users to be added to the group 6. Click `Add Users` Perform the following to remove a direct association between a user and policy:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the left navigation pane, click on Users 3. For each user:- Select the user- Click on the `Permissions` tab- Expand `Permissions policies` - Click `X` for each policy; then click Detach or Remove (depending on policy type)","AdditionalInformation": ""}],"description": "Ensure IAM Users Receive Permissions Only Through Groups","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.16": {"name": "1.16","checks": {"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html:https://docs.aws.amazon.com/cli/latest/reference/iam/index.html#cli-aws-iam","Description": "IAM policies are the means by which privileges are granted to users, groups, or roles. It is recommended and considered a standard security advice to grant _least privilege_ -that is, granting only the permissions required to perform a task. Determine what users need to do and then craft policies for them that let the users perform _only_ those tasks, instead of allowing full administrative privileges.","DefaultValue": null,"AuditProcedure": "Perform the following to determine what policies are created:**From Command Line:**1. Run the following to get a list of IAM policies: ```aws iam list-policies --only-attached --output text ``` 2. For each policy returned, run the following command to determine if any policies is allowing full administrative privileges on the account: ```aws iam get-policy-version --policy-arn  --version-id  ``` 3. In output ensure policy should not have any Statement block with `\"Effect\": \"Allow\"` and `Action` set to `\"*\"` and `Resource` set to `\"*\"`","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "It's more secure to start with a minimum set of permissions and grant additional permissions as necessary, rather than starting with permissions that are too lenient and then trying to tighten them later.Providing full administrative privileges instead of restricting to the minimum set of permissions that the user is required to do exposes the resources to potentially unwanted actions.IAM policies that have a statement with \"Effect\": \"Allow\" with \"Action\": \"\\*\" over \"Resource\": \"\\*\" should be removed.","RemediationProcedure": "**From Console:**Perform the following to detach the policy that has full administrative privileges:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click Policies and then search for the policy name found in the audit step. 3. Select the policy that needs to be deleted. 4. In the policy action menu, select first `Detach`5. Select all Users, Groups, Roles that have this policy attached 6. Click `Detach Policy`7. In the policy action menu, select `Detach` **From Command Line:**Perform the following to detach the policy that has full administrative privileges as found in the audit step:1. Lists all IAM users, groups, and roles that the specified managed policy is attached to.```aws iam list-entities-for-policy --policy-arn  ``` 2. Detach the policy from all IAM Users: ```aws iam detach-user-policy --user-name  --policy-arn  ``` 3. Detach the policy from all IAM Groups: ```aws iam detach-group-policy --group-name  --policy-arn  ``` 4. Detach the policy from all IAM Roles: ```aws iam detach-role-policy --role-name  --policy-arn  ```","AdditionalInformation": ""}],"description": "Ensure IAM policies that allow full \"*:*\" administrative privileges are not attached","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1.17": {"name": "1.17","checks": {"iam_support_role_created": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html:https://aws.amazon.com/premiumsupport/pricing/:https://docs.aws.amazon.com/cli/latest/reference/iam/list-policies.html:https://docs.aws.amazon.com/cli/latest/reference/iam/attach-role-policy.html:https://docs.aws.amazon.com/cli/latest/reference/iam/list-entities-for-policy.html","Description": "AWS provides a support center that can be used for incident notification and response, as well as technical support and customer services. Create an IAM Role to allow authorized users to manage incidents with AWS Support.","DefaultValue": null,"AuditProcedure": "**From Command Line:**1. List IAM policies, filter for the 'AWSSupportAccess' managed policy, and note the \"Arn\" element value: ``` aws iam list-policies --query \"Policies[?PolicyName == 'AWSSupportAccess']\" ``` 2. Check if the 'AWSSupportAccess' policy is attached to any role:``` aws iam list-entities-for-policy --policy-arn arn:aws:iam::aws:policy/AWSSupportAccess ```3. In Output, Ensure `PolicyRoles` does not return empty. 'Example: Example: PolicyRoles: [ ]'If it returns empty refer to the remediation below.","ImpactStatement": "All AWS Support plans include an unlimited number of account and billing support cases, with no long-term contracts. Support billing calculations are performed on a per-account basis for all plans. Enterprise Support plan customers have the option to include multiple enabled accounts in an aggregated monthly billing calculation. Monthly charges for the Business and Enterprise support plans are based on each month's AWS usage charges, subject to a monthly minimum, billed in advance.","AssessmentStatus": "Automated","RationaleStatement": "By implementing least privilege for access control, an IAM Role will require an appropriate IAM Policy to allow Support Center Access in order to manage Incidents with AWS Support.","RemediationProcedure": "**From Command Line:**1. Create an IAM role for managing incidents with AWS:- Create a trust relationship policy document that allows  to manage AWS incidents, and save it locally as /tmp/TrustPolicy.json: ```{\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"\"},\"Action\": \"sts:AssumeRole\"}]} ``` 2. Create the IAM role using the above trust policy: ``` aws iam create-role --role-name  --assume-role-policy-document file:///tmp/TrustPolicy.json ``` 3. Attach 'AWSSupportAccess' managed policy to the created IAM role: ``` aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AWSSupportAccess --role-name  ```","AdditionalInformation": "AWSSupportAccess policy is a global AWS resource. It has same ARN as `arn:aws:iam::aws:policy/AWSSupportAccess` for every account."}],"description": "Ensure a support role has been created to manage incidents with AWS Support","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.18": {"name": "1.18","checks": {"ec2_instance_profile_attached": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html","Description": "AWS access from within AWS instances can be done by either encoding AWS keys into AWS API calls or by assigning the instance to a role which has an appropriate permissions policy for the required access. \"AWS Access\" means accessing the APIs of AWS in order to access AWS resources or manage AWS account resources.","DefaultValue": null,"AuditProcedure": "Where an instance is associated with a Role:For instances that are known to perform AWS actions, ensure that they belong to an instance role that has the necessary permissions:1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Open the EC2 Dashboard and choose \"Instances\" 3. Click the EC2 instance that performs AWS actions, in the lower pane details find \"IAM Role\" 4. If the Role is blank, the instance is not assigned to one. 5. If the Role is filled in, it does not mean the instance might not \\*also\\* have credentials encoded on it for some activities.Where an Instance Contains Embedded Credentials:- On the instance that is known to perform AWS actions, audit all scripts and environment variables to ensure that none of them contain AWS credentials.Where an Instance Application Contains Embedded Credentials:- Applications that run on an instance may also have credentials embedded. This is a bad practice, but even worse if the source code is stored in a public code repository such as github. When an application contains credentials can be determined by eliminating all other sources of credentials and if the application can still access AWS resources - it likely contains embedded credentials. Another method is to examine all source code and configuration files of the application.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "AWS IAM roles reduce the risks associated with sharing and rotating credentials that can be used outside of AWS itself. If credentials are compromised, they can be used from outside of the AWS account they give access to. In contrast, in order to leverage role permissions an attacker would need to gain and maintain access to a specific instance to use the privileges associated with it.Additionally, if credentials are encoded into compiled applications or other hard to change mechanisms, then they are even more unlikely to be properly rotated due to service disruption risks. As time goes on, credentials that cannot be rotated are more likely to be known by an increasing number of individuals who no longer work for the organization owning the credentials.","RemediationProcedure": "IAM roles can only be associated at the launch of an instance. To remediate an instance to add it to a role you must create a new instance.If the instance has no external dependencies on its current private ip or public addresses are elastic IPs:1. In AWS IAM create a new role. Assign a permissions policy if needed permissions are already known. 2. In the AWS console launch a new instance with identical settings to the existing instance, and ensure that the newly created role is selected. 3. Shutdown both the existing instance and the new instance. 4. Detach disks from both instances. 5. Attach the existing instance disks to the new instance. 6. Boot the new instance and you should have the same machine, but with the associated role.**Note:** if your environment has dependencies on a dynamically assigned PRIVATE IP address you can create an AMI from the existing instance, destroy the old one and then when launching from the AMI, manually assign the previous private IP address.**Note: **if your environment has dependencies on a dynamically assigned PUBLIC IP address there is not a way ensure the address is retained and assign an instance role. Dependencies on dynamically assigned public IP addresses are a bad practice and, if possible, you may wish to rebuild the instance with a new elastic IP address and make the investment to remediate affected systems while assigning the system to a role.","AdditionalInformation": ""}],"description": "Ensure IAM instance roles are used for AWS resource access from instances","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.19": {"name": "1.19","checks": {"iam_no_expired_server_certificates_stored": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_server-certs.html:https://docs.aws.amazon.com/cli/latest/reference/iam/delete-server-certificate.html","Description": "To enable HTTPS connections to your website or application in AWS, you need an SSL/TLS server certificate. You can use ACM or IAM to store and deploy server certificates.Use IAM as a certificate manager only when you must support HTTPS connections in a region that is not supported by ACM. IAM securely encrypts your private keys and stores the encrypted version in IAM SSL certificate storage. IAM supports deploying server certificates in all regions, but you must obtain your certificate from an external provider for use with AWS. You cannot upload an ACM certificate to IAM. Additionally, you cannot manage your certificates from the IAM Console.","DefaultValue": null,"AuditProcedure": "**From Console:**Getting the certificates expiration information via AWS Management Console is not currently supported.To request information about the SSL/TLS certificates stored in IAM via the AWS API use the Command Line Interface (CLI).**From Command Line:**Run list-server-certificates command to list all the IAM-stored server certificates:``` aws iam list-server-certificates ```The command output should return an array that contains all the SSL/TLS certificates currently stored in IAM and their metadata (name, ID, expiration date, etc):``` {\"ServerCertificateMetadataList\": [{\"ServerCertificateId\": \"EHDGFRW7EJFYTE88D\",\"ServerCertificateName\": \"MyServerCertificate\",\"Expiration\": \"2018-07-10T23:59:59Z\",\"Path\": \"/\",\"Arn\": \"arn:aws:iam::012345678910:server-certificate/MySSLCertificate\",\"UploadDate\": \"2018-06-10T11:56:08Z\"}] } ```Verify the `ServerCertificateName` and `Expiration` parameter value (expiration date) for each SSL/TLS certificate returned by the list-server-certificates command and determine if there are any expired server certificates currently stored in AWS IAM. If so, use the AWS API to remove them.If this command returns: ``` { { \"ServerCertificateMetadataList\": [] } ``` This means that there are no expired certificates, It DOES NOT mean that no certificates exist.","ImpactStatement": "Deleting the certificate could have implications for your application if you are using an expired server certificate with Elastic Load Balancing, CloudFront, etc. One has to make configurations at respective services to ensure there is no interruption in application functionality.","AssessmentStatus": "Automated","RationaleStatement": "Removing expired SSL/TLS certificates eliminates the risk that an invalid certificate will be deployed accidentally to a resource such as AWS Elastic Load Balancer (ELB), which can damage the credibility of the application/website behind the ELB. As a best practice, it is recommended to delete expired certificates.","RemediationProcedure": "**From Console:**Removing expired certificates via AWS Management Console is not currently supported. To delete SSL/TLS certificates stored in IAM via the AWS API use the Command Line Interface (CLI).**From Command Line:**To delete Expired Certificate run following command by replacing  with the name of the certificate to delete:``` aws iam delete-server-certificate --server-certificate-name  ```When the preceding command is successful, it does not return any output.","AdditionalInformation": ""}],"description": "Ensure that all the expired SSL/TLS certificates stored in AWS IAM are removed","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.20": {"name": "1.20","checks": {"accessanalyzer_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-getting-started.html:https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/get-analyzer.html:https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/create-analyzer.html","Description": "Enable IAM Access analyzer for IAM policies about all resources in each region.IAM Access Analyzer is a technology introduced at AWS reinvent 2019. After the Analyzer is enabled in IAM, scan results are displayed on the console showing the accessible resources. Scans show resources that other accounts and federated users can access, such as KMS keys and IAM roles. So the results allow you to determine if an unintended user is allowed, making it easier for administrators to monitor least privileges access. Access Analyzer analyzes only policies that are applied to resources in the same AWS Region.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Open the IAM console at `https://console.aws.amazon.com/iam/` 2. Choose `Access analyzer` 3. Click 'Analyzers' 4. Ensure that at least one analyzer is present 5. Ensure that the `STATUS` is set to `Active` 6. Repeat these step for each active region**From Command Line:**1. Run the following command: ``` aws accessanalyzer list-analyzers | grep status ``` 2. Ensure that at least one Analyzer the `status` is set to `ACTIVE`3. Repeat the steps above for each active region.If an Access analyzer is not listed for each region or the status is not set to active refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "AWS IAM Access Analyzer helps you identify the resources in your organization and accounts, such as Amazon S3 buckets or IAM roles, that are shared with an external entity. This lets you identify unintended access to your resources and data. Access Analyzer identifies resources that are shared with external principals by using logic-based reasoning to analyze the resource-based policies in your AWS environment. IAM Access Analyzer continuously monitors all policies for S3 bucket, IAM roles, KMS(Key Management Service) keys, AWS Lambda functions, and Amazon SQS(Simple Queue Service) queues.","RemediationProcedure": "**From Console:**Perform the following to enable IAM Access analyzer for IAM policies:1. Open the IAM console at `https://console.aws.amazon.com/iam/.` 2. Choose `Access analyzer`. 3. Choose `Create analyzer`. 4. On the `Create analyzer` page, confirm that the `Region` displayed is the Region where you want to enable Access Analyzer. 5. Enter a name for the analyzer. `Optional as it will generate a name for you automatically`. 6. Add any tags that you want to apply to the analyzer. `Optional`.7. Choose `Create Analyzer`. 8. Repeat these step for each active region**From Command Line:**Run the following command: ``` aws accessanalyzer create-analyzer --analyzer-name  --type  ``` Repeat this command above for each active region.**Note:** The IAM Access Analyzer is successfully configured only when the account you use has the necessary permissions.","AdditionalInformation": ""}],"description": "Ensure that IAM Access analyzer is enabled for all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.21": {"name": "1.21","checks": {"iam_check_saml_providers_sts": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "","Description": "In multi-account environments, IAM user centralization facilitates greater user control. User access beyond the initial account is then provided via role assumption. Centralization of users can be accomplished through federation with an external identity provider or through the use of AWS Organizations.","DefaultValue": null,"AuditProcedure": "For multi-account AWS environments with an external identity provider... 1. Determine the master account for identity federation or IAM user management 2. Login to that account through the AWS Management Console 3. Click `Services`4. Click `IAM`5. Click `Identity providers` 6. Verify the configurationThen..., determine all accounts that should not have local users present. For each account...1. Determine all accounts that should not have local users present 2. Log into the AWS Management Console 3. Switch role into each identified account 4. Click `Services`5. Click `IAM`6. Click `Users` 7. Confirm that no IAM users representing individuals are presentFor multi-account AWS environments implementing AWS Organizations without an external identity provider... 1. Determine all accounts that should not have local users present 2. Log into the AWS Management Console 3. Switch role into each identified account 4. Click `Services`5. Click `IAM`6. Click `Users` 7. Confirm that no IAM users representing individuals are present","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Centralizing IAM user management to a single identity store reduces complexity and thus the likelihood of access management errors.","RemediationProcedure": "The remediation procedure will vary based on the individual organization's implementation of identity federation and/or AWS Organizations with the acceptance criteria that no non-service IAM users, and non-root accounts, are present outside the account providing centralized IAM user management.","AdditionalInformation": ""}],"description": "Ensure IAM users are managed centrally via identity federation or AWS Organizations for multi-account environments","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.10": {"name": "3.10","checks": {"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-cloudtrail-events.html","Description": "S3 object-level API operations such as GetObject, DeleteObject, and PutObject are called data events. By default, CloudTrail trails don't log data events and so it is recommended to enable Object-level logging for S3 buckets.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to CloudTrail dashboard at `https://console.aws.amazon.com/cloudtrail/` 2. In the left panel, click `Trails` and then click on the CloudTrail Name that you want to examine. 3. Review `General details` 4. Confirm that `Multi-region trail` is set to `Yes` 5. Scroll down to `Data events` 6. Confirm that it reads: Data events: S3 Bucket Name: All current and future S3 buckets Read: Enabled Write: Enabled 7. Repeat steps 2 to 6 to verify that Multi-region trail and Data events logging of S3 buckets in CloudTrail. If the CloudTrails do not have multi-region and data events configured for S3 refer to the remediation below.**From Command Line:**1. Run `list-trails` command to list the names of all Amazon CloudTrail trails currently available in all AWS regions: ``` aws cloudtrail list-trails ``` 2. The command output will be a list of all the trail names to include. \"TrailARN\": \"arn:aws:cloudtrail:::trail/\", \"Name\": \"\", \"HomeRegion\": \"\" 3. Next run 'get-trail- command to determine Multi-region. ``` aws cloudtrail get-trail --name  --region  ``` 4. The command output should include: \"IsMultiRegionTrail\": true, 5. Next run `get-event-selectors` command using the `Name` of the trail and the `region` returned in step 2 to determine if Data events logging feature is enabled within the selected CloudTrail trail for all S3 buckets: ``` aws cloudtrail get-event-selectors --region  --trail-name  --query EventSelectors[*].DataResources[] ``` 6. The command output should be an array that contains the configuration of the AWS resource(S3 bucket) defined for the Data events selector. \"Type\": \"AWS::S3::Object\",\"Values\": [\"arn:aws:s3\" 7. If the `get-event-selectors` command returns an empty array '[]', the Data events are not included in the selected AWS Cloudtrail trail logging configuration, therefore the S3 object-level API operations performed within your AWS account are not recorded. 8. Repeat steps 1 to 5 for auditing each CloudTrail to determine if Data events for S3 are covered. If Multi-region is not set to true and the Data events does not show S3 defined as shown refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling object-level logging will help you meet data compliance requirements within your organization, perform comprehensive security analysis, monitor specific patterns of user behavior in your AWS account or take immediate actions on any object-level API activity within your S3 Buckets using Amazon CloudWatch Events.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. Click on the `Object-level` logging setting, enter the CloudTrail name for the recording activity. You can choose an existing Cloudtrail or create a new one by navigating to the Cloudtrail console link `https://console.aws.amazon.com/cloudtrail/` 5. Once the Cloudtrail is selected, check the `Write` event checkbox, so that `object-level` logging for Write events is enabled. 6. Repeat steps 2 to 5 to enable object-level logging of write events for other S3 buckets.**From Command Line:**1. To enable `object-level` data events logging for S3 buckets within your AWS account, run `put-event-selectors` command using the name of the trail that you want to reconfigure as identifier: ``` aws cloudtrail put-event-selectors --region  --trail-name  --event-selectors '[{ \"ReadWriteType\": \"WriteOnly\", \"IncludeManagementEvents\":true, \"DataResources\": [{ \"Type\": \"AWS::S3::Object\", \"Values\": [\"arn:aws:s3:::/\"] }] }]' ``` 2. The command output will be `object-level` event trail configuration. 3. If you want to enable it for all buckets at once then change Values parameter to `[\"arn:aws:s3\"]` in command given above. 4. Repeat step 1 for each s3 bucket to update `object-level` logging of write events. 5. Change the AWS region by updating the `--region` command parameter and perform the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that Object-level logging for write events is enabled for S3 bucket","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.11": {"name": "3.11","checks": {"cloudtrail_s3_dataevents_read_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-cloudtrail-events.html","Description": "S3 object-level API operations such as GetObject, DeleteObject, and PutObject are called data events. By default, CloudTrail trails don't log data events and so it is recommended to enable Object-level logging for S3 buckets.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. If the current status for `Object-level` logging is set to `Disabled`, then object-level logging of read events for the selected s3 bucket is not set. 5. If the current status for `Object-level` logging is set to `Enabled`, but the Read event check-box is unchecked, then object-level logging of read events for the selected s3 bucket is not set. 6. Repeat steps 2 to 5 to verify `object-level` logging for `read` events of your other S3 buckets.**From Command Line:** 1. Run `describe-trails` command to list the names of all Amazon CloudTrail trails currently available in the selected AWS region: ``` aws cloudtrail describe-trails --region  --output table --query trailList[*].Name ``` 2. The command output will be table of the requested trail names. 3. Run `get-event-selectors` command using the name of the trail returned at the previous step and custom query filters to determine if Data events logging feature is enabled within the selected CloudTrail trail configuration for s3 bucket resources: ``` aws cloudtrail get-event-selectors --region  --trail-name  --query EventSelectors[*].DataResources[] ``` 4. The command output should be an array that contains the configuration of the AWS resource(S3 bucket) defined for the Data events selector. 5. If the `get-event-selectors` command returns an empty array, the Data events are not included into the selected AWS Cloudtrail trail logging configuration, therefore the S3 object-level API operations performed within your AWS account are not recorded. 6. Repeat steps 1 to 5 for auditing each s3 bucket to identify other trails that are missing the capability to log Data events. 7. Change the AWS region by updating the `--region` command parameter and perform the audit process for other regions.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling object-level logging will help you meet data compliance requirements within your organization, perform comprehensive security analysis, monitor specific patterns of user behavior in your AWS account or take immediate actions on any object-level API activity using Amazon CloudWatch Events.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. Click on the `Object-level` logging setting, enter the CloudTrail name for the recording activity. You can choose an existing Cloudtrail or create a new one by navigating to the Cloudtrail console link `https://console.aws.amazon.com/cloudtrail/` 5. Once the Cloudtrail is selected, check the Read event checkbox, so that `object-level` logging for `Read` events is enabled. 6. Repeat steps 2 to 5 to enable `object-level` logging of read events for other S3 buckets.**From Command Line:** 1. To enable `object-level` data events logging for S3 buckets within your AWS account, run `put-event-selectors` command using the name of the trail that you want to reconfigure as identifier: ``` aws cloudtrail put-event-selectors --region  --trail-name  --event-selectors '[{ \"ReadWriteType\": \"ReadOnly\", \"IncludeManagementEvents\":true, \"DataResources\": [{ \"Type\": \"AWS::S3::Object\", \"Values\": [\"arn:aws:s3:::/\"] }] }]' ``` 2. The command output will be `object-level` event trail configuration. 3. If you want to enable it for all buckets at ones then change Values parameter to `[\"arn:aws:s3\"]` in command given above. 4. Repeat step 1 for each s3 bucket to update `object-level` logging of read events. 5. Change the AWS region by updating the `--region` command parameter and perform the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that Object-level logging for read events is enabled for S3 bucket","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.10": {"name": "4.10","checks": {"cloudwatch_log_metric_filter_security_group_changes": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Security Groups are a stateful packet filter that controls ingress and egress traffic within a VPC. It is recommended that a metric filter and alarm be established for detecting changes to Security Groups.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query \"MetricAlarms[?MetricName== '']\" ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to security group will help ensure that resources and services are not unintentionally exposed.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for security groups changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name \"\" --filter-name \"\" --metric-transformations metricName= \"\" ,metricNamespace=\"CISBenchmark\",metricValue=1 --filter-pattern \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\" ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name \"\" ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn \"\" --protocol  --notification-endpoint \"\" ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name \"\" --metric-name \"\" --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace \"CISBenchmark\" --alarm-actions \"\" ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for security group changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.11": {"name": "4.11","checks": {"cloudwatch_changes_to_network_acls_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. NACLs are used as a stateless packet filter to control ingress and egress traffic for subnets within a VPC. It is recommended that a metric filter and alarm be established for changes made to NACLs.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to NACLs will help ensure that AWS resources and services are not unintentionally exposed.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for NACL changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL)","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.12": {"name": "4.12","checks": {"cloudwatch_changes_to_network_gateways_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Network gateways are required to send/receive traffic to a destination outside of a VPC. It is recommended that a metric filter and alarm be established for changes to network gateways.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to network gateways will help ensure that all ingress/egress traffic traverses the VPC border via a controlled path.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for network gateways changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for changes to network gateways","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.13": {"name": "4.13","checks": {"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Routing tables are used to route network traffic between subnets and to network gateways. It is recommended that a metric filter and alarm be established for changes to route tables.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to route tables will help ensure that all VPC traffic flows through an expected path.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for route table changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for route table changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.14": {"name": "4.14","checks": {"cloudwatch_changes_to_vpcs_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is possible to have more than 1 VPC within an account, in addition it is also possible to create a peer connection between 2 VPCs enabling network traffic to route between VPCs. It is recommended that a metric filter and alarm be established for changes made to VPCs.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to VPC will help ensure VPC traffic flow is not getting impacted.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for VPC changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for VPC changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.15": {"name": "4.15","checks": {"cloudwatch_log_metric_filter_aws_organizations_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/organizations/latest/userguide/orgs_security_incident-response.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for AWS Organizations changes made in the master AWS Account.","DefaultValue": null,"AuditProcedure": "1. Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured: - Identify the log group name configured for use with active multi-region CloudTrail: - List all CloudTrails:``` aws cloudtrail describe-trails ``` - Identify Multi region Cloudtrails, Trails with `\"IsMultiRegionTrail\"` set to true - From value associated with CloudWatchLogsLogGroupArn note **Example:** for CloudWatchLogsLogGroupArn that looks like arn:aws:logs:::log-group:NewGroup:*,  would be NewGroup- Ensure Identified Multi region CloudTrail is active: ``` aws cloudtrail get-trail-status --name  ``` Ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events: ``` aws cloudtrail get-event-selectors --trail-name  ``` - Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to true and `ReadWriteType` set to `All`.2. Get a list of all associated metric filters for this : ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdatePolicy\") || ($.eventName = \"UpdateOrganizationalUnit\")) }\" ``` 4. Note the `` value associated with the filterPattern found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4: ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the AlarmActions value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic: ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. Example of valid \"SubscriptionArn\":``` \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring AWS Organizations changes can help you prevent any unwanted, accidental or intentional modifications that may lead to unauthorized access or other security breaches. This monitoring technique helps you to ensure that any unexpected changes performed within your AWS Organizations can be investigated and any unwanted changes can be rolled back.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Organizations changes and the `` taken from audit step 1: ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdatePolicy\") || ($.eventName = \"UpdateOrganizationalUnit\")) }' ``` **Note:** You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify: ``` aws sns create-topic --name  ``` **Note:** you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2: ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note:** you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2: ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": ""}],"description": "Ensure a log metric filter and alarm exists for AWS Organizations changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.16": {"name": "4.16","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-get-started.html:https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-enable.html#securityhub-enable-api:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/securityhub/enable-security-hub.html","Description": "Security Hub collects security data from across AWS accounts, services, and supported third-party partner products and helps you analyze your security trends and identify the highest priority security issues. When you enable Security Hub, it begins to consume, aggregate, organize, and prioritize findings from AWS services that you have enabled, such as Amazon GuardDuty, Amazon Inspector, and Amazon Macie. You can also enable integrations with AWS partner security products.","DefaultValue": null,"AuditProcedure": "The process to evaluate AWS Security Hub configuration per region **From Console:**1. Sign in to the AWS Management Console and open the AWS Security Hub console at https://console.aws.amazon.com/securityhub/. 2. On the top right of the console, select the target Region. 3. If presented with the Security Hub > Summary page then Security Hub is set-up for the selected region. 4. If presented with Setup Security Hub or Get Started With Security Hub - follow the online instructions. 5. Repeat steps 2 to 4 for each region.","ImpactStatement": "It is recommended AWS Security Hub be enabled in all regions. AWS Security Hub requires AWS Config to be enabled.","AssessmentStatus": "Automated","RationaleStatement": "AWS Security Hub provides you with a comprehensive view of your security state in AWS and helps you check your environment against security industry standards and best practices - enabling you to quickly assess the security posture across your AWS accounts.","RemediationProcedure": "To grant the permissions required to enable Security Hub, attach the Security Hub managed policy AWSSecurityHubFullAccess to an IAM user, group, or role.Enabling Security Hub**From Console:**1. Use the credentials of the IAM identity to sign in to the Security Hub console. 2. When you open the Security Hub console for the first time, choose Enable AWS Security Hub. 3. On the welcome page, Security standards list the security standards that Security Hub supports. 4. Choose Enable Security Hub.**From Command Line:**1. Run the enable-security-hub command. To enable the default standards, include `--enable-default-standards`. ``` aws securityhub enable-security-hub --enable-default-standards ```2. To enable the security hub without the default standards, include `--no-enable-default-standards`. ``` aws securityhub enable-security-hub --no-enable-default-standards ```","AdditionalInformation": ""}],"description": "Ensure AWS Security Hub is enabled","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.1": {"name": "2.1.1","checks": {"s3_bucket_default_encryption": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/default-bucket-encryption.html:https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html#bucket-encryption-related-resources","Description": "Amazon S3 provides a variety of no, or low, cost encryption options to protect data at rest.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select a Bucket. 3. Click on 'Properties'. 4. Verify that `Default Encryption` is enabled, and displays either `AES-256`, `AWS-KMS`, `SSE-KMS` or `SSE-S3`. 5. Repeat for all the buckets in your AWS account.**From Command Line:**1. Run command to list buckets ``` aws s3 ls ``` 2. For each bucket, run``` aws s3api get-bucket-encryption --bucket  ``` 3. Verify that either``` \"SSEAlgorithm\": \"AES256\" ```or``` \"SSEAlgorithm\": \"aws:kms\"```is displayed.","ImpactStatement": "Amazon S3 buckets with default bucket encryption using SSE-KMS cannot be used as destination buckets for Amazon S3 server access logging. Only SSE-S3 default encryption is supported for server access log destination buckets.","AssessmentStatus": "Automated","RationaleStatement": "Encrypting data at rest reduces the likelihood that it is unintentionally exposed and can nullify the impact of disclosure if the encryption remains unbroken.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select a Bucket. 3. Click on 'Properties'. 4. Click edit on `Default Encryption`. 5. Select either `AES-256`, `AWS-KMS`, `SSE-KMS` or `SSE-S3`. 6. Click `Save` 7. Repeat for all the buckets in your AWS account lacking encryption.**From Command Line:**Run either``` aws s3api put-bucket-encryption --bucket  --server-side-encryption-configuration '{\"Rules\": [{\"ApplyServerSideEncryptionByDefault\": {\"SSEAlgorithm\": \"AES256\"}}]}' ```or``` aws s3api put-bucket-encryption --bucket  --server-side-encryption-configuration '{\"Rules\": [{\"ApplyServerSideEncryptionByDefault\": {\"SSEAlgorithm\": \"aws:kms\",\"KMSMasterKeyID\": \"aws/s3\"}}]}' ```**Note:** the KMSMasterKeyID can be set to the master key of your choosing; aws/s3 is an AWS preconfigured default.","AdditionalInformation": "S3 bucket encryption only applies to objects as they are placed in the bucket. Enabling S3 bucket encryption does **not** encrypt objects previously stored within the bucket."}],"description": "Ensure all S3 buckets employ encryption-at-rest","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.2": {"name": "2.1.2","checks": {"s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-policy-for-config-rule/:https://aws.amazon.com/blogs/security/how-to-use-bucket-policies-and-apply-defense-in-depth-to-help-secure-your-amazon-s3-data/:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-bucket-policy.html","Description": "At the Amazon S3 bucket level, you can configure permissions through a bucket policy making the objects accessible only through HTTPS.","DefaultValue": null,"AuditProcedure": "To allow access to HTTPS you can use a condition that checks for the key `\"aws:SecureTransport: true\"`. This means that the request is sent through HTTPS but that HTTP can still be used. So to make sure you do not allow HTTP access confirm that there is a bucket policy that explicitly denies access for HTTP requests and that it contains the key \"aws:SecureTransport\": \"false\".**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/ 2. Select the Check box next to the Bucket. 3. Click on 'Permissions', then Click on `Bucket Policy`. 4. Ensure that a policy is listed that matches: ``` '{\"Sid\": ,\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}' ``` `` and `` will be specific to your account5. Repeat for all the buckets in your AWS account.**From Command Line:**1. List all of the S3 Buckets``` aws s3 ls ``` 2. Using the list of buckets run this command on each of them: ``` aws s3api get-bucket-policy --bucket  | grep aws:SecureTransport ``` 3. Confirm that `aws:SecureTransport` is set to false `aws:SecureTransport:false` 4. Confirm that the policy line has Effect set to Deny 'Effect:Deny'","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "By default, Amazon S3 allows both HTTP and HTTPS requests. To achieve only allowing access to Amazon S3 objects through HTTPS you also have to explicitly deny access to HTTP requests. Bucket policies that allow HTTPS requests without explicitly denying HTTP requests will not comply with this recommendation.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/ 2. Select the Check box next to the Bucket. 3. Click on 'Permissions'. 4. Click 'Bucket Policy' 5. Add this to the existing policy filling in the required information ``` {\"Sid\": \",\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}}} ``` 6. Save 7. Repeat for all the buckets in your AWS account that contain sensitive data.**From Console** using AWS Policy Generator:1. Repeat steps 1-4 above. 2. Click on `Policy Generator` at the bottom of the Bucket Policy Editor 3. Select Policy Type `S3 Bucket Policy` 4. Add Statements - `Effect` = Deny - `Principal` = * - `AWS Service` = Amazon S3 - `Actions` = * - `Amazon Resource Name` =  5. Generate Policy 6. Copy the text and add it to the Bucket Policy.**From Command Line:**1. Export the bucket policy to a json file. ``` aws s3api get-bucket-policy --bucket  --query Policy --output text > policy.json ```2. Modify the policy.json file by adding in this statement: ``` {\"Sid\": \",\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}}} ``` 3. Apply this modified policy back to the S3 bucket: ``` aws s3api put-bucket-policy --bucket  --policy file://policy.json ```","AdditionalInformation": ""}],"description": "Ensure S3 Bucket Policy is set to deny HTTP requests","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.1.3": {"name": "2.1.3","checks": {"s3_bucket_no_mfa_delete": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html#MultiFactorAuthenticationDelete:https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMFADelete.html:https://aws.amazon.com/blogs/security/securing-access-to-aws-using-mfa-part-3/:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_lost-or-broken.html","Description": "Once MFA Delete is enabled on your sensitive and classified S3 bucket it requires the user to have two forms of authentication.","DefaultValue": null,"AuditProcedure": "Perform the steps below to confirm MFA delete is configured on an S3 Bucket**From Console:**1. Login to the S3 console at `https://console.aws.amazon.com/s3/`2. Click the `Check` box next to the Bucket name you want to confirm3. In the window under `Properties`4. Confirm that Versioning is `Enabled`5. Confirm that MFA Delete is `Enabled`**From Command Line:**1. Run the `get-bucket-versioning` ``` aws s3api get-bucket-versioning --bucket my-bucket ```Output example: ```  EnabledEnabled ```If the Console or the CLI output does not show Versioning and MFA Delete `enabled` refer to the remediation below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Adding MFA delete to an S3 bucket, requires additional authentication when you change the version state of your bucket or you delete and object version adding another layer of security in the event your security credentials are compromised or unauthorized access is granted.","RemediationProcedure": "Perform the steps below to enable MFA delete on an S3 bucket.Note: -You cannot enable MFA Delete using the AWS Management Console. You must use the AWS CLI or API. -You must use your 'root' account to enable MFA Delete on S3 buckets.**From Command line:**1. Run the s3api put-bucket-versioning command``` aws s3api put-bucket-versioning --profile my-root-profile --bucket Bucket_Name --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa ā€œarn:aws:iam::aws_account_id:mfa/root-account-mfa-device passcodeā€ ```","AdditionalInformation": ""}],"description": "Ensure MFA Delete is enabled on S3 buckets","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.1.4": {"name": "2.1.4","checks": {"macie_is_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://aws.amazon.com/macie/getting-started/:https://docs.aws.amazon.com/workspaces/latest/adminguide/data-protection.html:https://docs.aws.amazon.com/macie/latest/user/data-classification.html","Description": "Amazon S3 buckets can contain sensitive data, that for security purposes should be discovered, monitored, classified and protected. Macie along with other 3rd party tools can automatically provide an inventory of Amazon S3 buckets.","DefaultValue": null,"AuditProcedure": "Perform the following steps to determine if Macie is running:**From Console:** 1. Login to the Macie console at https://console.aws.amazon.com/macie/ 2. In the left hand pane click on By job under findings. 3. Confirm that you have a Job setup for your S3 BucketsWhen you log into the Macie console if you aren't taken to the summary page and you don't have a job setup and running then refer to the remediation procedure below.If you are using a 3rd Party tool to manage and protect your s3 data you meet this recommendation.","ImpactStatement": "There is a cost associated with using Amazon Macie. There is also typically a cost associated with 3rd Party tools that perform similar processes and protection.","AssessmentStatus": "Manual","RationaleStatement": "Using a Cloud service or 3rd Party software to continuously monitor and automate the process of data discovery and classification for S3 buckets using machine learning and pattern matching is a strong defense in protecting that information.Amazon Macie is a fully managed data security and data privacy service that uses machine learning and pattern matching to discover and protect your sensitive data in AWS.","RemediationProcedure": "Perform the steps below to enable and configure Amazon Macie**From Console:**1. Log on to the Macie console at `https://console.aws.amazon.com/macie/`2. Click `Get started`.3. Click `Enable Macie`.Setup a repository for sensitive data discovery results1. In the Left pane, under Settings, click `Discovery results`.2. Make sure `Create bucket` is selected.3. Create a bucket, enter a name for the bucket. The name must be unique across all S3 buckets. In addition, the name must start with a lowercase letter or a number.4. Click on `Advanced`.5. Block all public access, make sure `Yes` is selected.6. KMS encryption, specify the AWS KMS key that you want to use to encrypt the results. The key must be a symmetric, customer master key (CMK) that's in the same Region as the S3 bucket.7. Click on `Save`Create a job to discover sensitive data1. In the left pane, click `S3 buckets`. Macie displays a list of all the S3 buckets for your account.2. Select the `check box` for each bucket that you want Macie to analyze as part of the job3. Click `Create job`.3. Click `Quick create`.4. For the Name and description step, enter a name and, optionally, a description of the job.5. Then click `Next`.6. For the Review and create step, click `Submit`.Review your findings1. In the left pane, click `Findings`.2. To view the details of a specific finding, choose any field other than the check box for the finding.If you are using a 3rd Party tool to manage and protect your s3 data, follow the Vendor documentation for implementing and configuring that tool.","AdditionalInformation": ""}],"description": "Ensure all data in Amazon S3 has been discovered, classified and secured when required.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.5": {"name": "2.1.5","checks": {"s3_bucket_level_public_access_block": "PASS","s3_account_level_public_access_blocks": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/block-public-access-account.html","Description": "Amazon S3 provides `Block public access (bucket settings)` and `Block public access (account settings)` to help you manage public access to Amazon S3 resources. By default, S3 buckets and objects are created with public access disabled. However, an IAM principal with sufficient S3 permissions can enable public access at the bucket and/or object level. While enabled, `Block public access (bucket settings)` prevents an individual bucket, and its contained objects, from becoming publicly accessible. Similarly, `Block public access (account settings)` prevents all buckets, and contained objects, from becoming publicly accessible across the entire account.","DefaultValue": null,"AuditProcedure": "**If utilizing Block Public Access (bucket settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select the Check box next to the Bucket. 3. Click on 'Edit public access settings'. 4. Ensure that block public access settings are set appropriately for this bucket 5. Repeat for all the buckets in your AWS account.**From Command Line:**1. List all of the S3 Buckets ``` aws s3 ls ``` 2. Find the public access setting on that bucket ``` aws s3api get-public-access-block --bucket  ``` Output if Block Public access is enabled:``` {\"PublicAccessBlockConfiguration\": {\"BlockPublicAcls\": true,\"IgnorePublicAcls\": true,\"BlockPublicPolicy\": true,\"RestrictPublicBuckets\": true} } ```If the output reads `false` for the separate configuration settings then proceed to the remediation.**If utilizing Block Public Access (account settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Choose `Block public access (account settings)` 3. Ensure that block public access settings are set appropriately for your AWS account.**From Command Line:**To check Public access settings for this account status, run the following command, `aws s3control get-public-access-block --account-id  --region `Output if Block Public access is enabled:``` {\"PublicAccessBlockConfiguration\": {\"IgnorePublicAcls\": true, \"BlockPublicPolicy\": true, \"BlockPublicAcls\": true, \"RestrictPublicBuckets\": true} } ```If the output reads `false` for the separate configuration settings then proceed to the remediation.","ImpactStatement": "When you apply Block Public Access settings to an account, the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously, but they eventually propagate to all Regions.","AssessmentStatus": "Automated","RationaleStatement": "Amazon S3 `Block public access (bucket settings)` prevents the accidental or malicious public exposure of data contained within the respective bucket(s). Amazon S3 `Block public access (account settings)` prevents the accidental or malicious public exposure of data contained within all buckets of the respective AWS account.Whether blocking public access to all or some buckets is an organizational decision that should be based on data sensitivity, least privilege, and use case.","RemediationProcedure": "**If utilizing Block Public Access (bucket settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select the Check box next to the Bucket. 3. Click on 'Edit public access settings'. 4. Click 'Block all public access' 5. Repeat for all the buckets in your AWS account that contain sensitive data.**From Command Line:**1. List all of the S3 Buckets ``` aws s3 ls ``` 2. Set the Block Public Access to true on that bucket ``` aws s3api put-public-access-block --bucket  --public-access-block-configuration \"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true\" ```**If utilizing Block Public Access (account settings)****From Console:**If the output reads `true` for the separate configuration settings then it is set on the account.1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Choose `Block Public Access (account settings)` 3. Choose `Edit` to change the block public access settings for all the buckets in your AWS account 4. Choose the settings you want to change, and then choose `Save`. For details about each setting, pause on the `i` icons. 5. When you're asked for confirmation, enter `confirm`. Then Click `Confirm` to save your changes.**From Command Line:**To set Block Public access settings for this account, run the following command: ``` aws s3control put-public-access-block --public-access-block-configuration BlockPublicAcls=true, IgnorePublicAcls=true, BlockPublicPolicy=true, RestrictPublicBuckets=true --account-id  ```","AdditionalInformation": ""}],"description": "Ensure that S3 Buckets are configured with 'Block public access (bucket settings)'","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"2.2.1": {"name": "2.2.1","checks": {"ec2_ebs_volume_encryption": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.2. Elastic Compute Cloud (EC2)","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html:https://aws.amazon.com/blogs/aws/new-opt-in-to-default-encryption-for-new-ebs-volumes/","Description": "Elastic Compute Cloud (EC2) supports encryption at rest when using the Elastic Block Store (EBS) service. While disabled by default, forcing encryption at EBS volume creation is supported.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under `Account attributes`, click `EBS encryption`. 3. Verify `Always encrypt new EBS volumes` displays `Enabled`. 4. Review every region in-use.**Note:** EBS volume encryption is configured per region.**From Command Line:**1. Run``` aws --region  ec2 get-ebs-encryption-by-default ``` 2. Verify that `\"EbsEncryptionByDefault\": true` is displayed. 3. Review every region in-use.**Note:** EBS volume encryption is configured per region.","ImpactStatement": "Losing access or removing the KMS key in use by the EBS volumes will result in no longer being able to access the volumes.","AssessmentStatus": "Automated","RationaleStatement": "Encrypting data at rest reduces the likelihood that it is unintentionally exposed and can nullify the impact of disclosure if the encryption remains unbroken.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under `Account attributes`, click `EBS encryption`. 3. Click `Manage`. 4. Click the `Enable` checkbox. 5. Click `Update EBS encryption` 6. Repeat for every region requiring the change.**Note:** EBS volume encryption is configured per region.**From Command Line:**1. Run``` aws --region  ec2 enable-ebs-encryption-by-default ``` 2. Verify that `\"EbsEncryptionByDefault\": true` is displayed. 3. Repeat every region requiring the change.**Note:** EBS volume encryption is configured per region.","AdditionalInformation": "Default EBS volume encryption only applies to newly created EBS volumes. Existing EBS volumes are **not** converted automatically."}],"description": "Ensure EBS Volume Encryption is Enabled in all Regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.3.1": {"name": "2.3.1","checks": {"rds_instance_storage_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Encryption.html:https://aws.amazon.com/blogs/database/selecting-the-right-encryption-options-for-amazon-rds-and-amazon-aurora-database-engines/#:~:text=With%20RDS%2Dencrypted%20resources%2C%20data,transparent%20to%20your%20database%20engine.:https://aws.amazon.com/rds/features/security/","Description": "Amazon RDS encrypted DB instances use the industry standard AES-256 encryption algorithm to encrypt your data on the server that hosts your Amazon RDS DB instances. After your data is encrypted, Amazon RDS handles authentication of access and decryption of your data transparently with a minimal impact on performance.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and open the RDS dashboard at https://console.aws.amazon.com/rds/ 2. In the navigation pane, under RDS dashboard, click `Databases`. 3. Select the RDS Instance that you want to examine 4. Click `Instance Name` to see details, then click on `Configuration` tab. 5. Under Configuration Details section, In Storage pane search for the `Encryption Enabled` Status. 6. If the current status is set to `Disabled`, Encryption is not enabled for the selected RDS Instance database instance. 7. Repeat steps 3 to 7 to verify encryption status of other RDS Instance in same region. 8. Change region from the top of the navigation bar and repeat audit for other regions.**From Command Line:**1. Run `describe-db-instances` command to list all RDS Instance database names, available in the selected AWS region, Output will return each Instance database identifier-name.``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. Run again `describe-db-instances` command using the RDS Instance identifier returned earlier, to determine if the selected database instance is encrypted, The command output should return the encryption status `True` Or `False`. ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].StorageEncrypted' ``` 3. If the StorageEncrypted parameter value is `False`, Encryption is not enabled for the selected RDS database instance. 4. Repeat steps 1 to 3 for auditing each RDS Instance and change Region to verify for other regions","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Databases are likely to hold sensitive and critical data, it is highly recommended to implement encryption in order to protect your data from unauthorized access or disclosure. With RDS encryption enabled, the data stored on the instance's underlying storage, the automated backups, read replicas, and snapshots, are all encrypted.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and open the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases` 3. Select the Database instance that needs to be encrypted. 4. Click on `Actions` button placed at the top right and select `Take Snapshot`. 5. On the Take Snapshot page, enter a database name of which you want to take a snapshot in the `Snapshot Name` field and click on `Take Snapshot`. 6. Select the newly created snapshot and click on the `Action` button placed at the top right and select `Copy snapshot` from the Action menu. 7. On the Make Copy of DB Snapshot page, perform the following:- In the New DB Snapshot Identifier field, Enter a name for the `new snapshot`. - Check `Copy Tags`, New snapshot must have the same tags as the source snapshot. - Select `Yes` from the `Enable Encryption` dropdown list to enable encryption, You can choose to use the AWS default encryption key or custom key from Master Key dropdown list.8. Click `Copy Snapshot` to create an encrypted copy of the selected instance snapshot. 9. Select the new Snapshot Encrypted Copy and click on the `Action` button placed at the top right and select `Restore Snapshot` button from the Action menu, This will restore the encrypted snapshot to a new database instance. 10. On the Restore DB Instance page, enter a unique name for the new database instance in the DB Instance Identifier field. 11. Review the instance configuration details and click `Restore DB Instance`. 12. As the new instance provisioning process is completed can update application configuration to refer to the endpoint of the new Encrypted database instance Once the database endpoint is changed at the application level, can remove the unencrypted instance.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names available in the selected AWS region, The command output should return the database instance identifier. ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. Run `create-db-snapshot` command to create a snapshot for the selected database instance, The command output will return the `new snapshot` with name DB Snapshot Name. ``` aws rds create-db-snapshot --region  --db-snapshot-identifier  --db-instance-identifier  ``` 3. Now run `list-aliases` command to list the KMS keys aliases available in a specified region, The command output should return each `key alias currently available`. For our RDS encryption activation process, locate the ID of the AWS default KMS key. ``` aws kms list-aliases --region  ``` 4. Run `copy-db-snapshot` command using the default KMS key ID for RDS instances returned earlier to create an encrypted copy of the database instance snapshot, The command output will return the `encrypted instance snapshot configuration`. ``` aws rds copy-db-snapshot --region  --source-db-snapshot-identifier  --target-db-snapshot-identifier  --copy-tags --kms-key-id  ``` 5. Run `restore-db-instance-from-db-snapshot` command to restore the encrypted snapshot created at the previous step to a new database instance, If successful, the command output should return the new encrypted database instance configuration. ``` aws rds restore-db-instance-from-db-snapshot --region  --db-instance-identifier  --db-snapshot-identifier  ``` 6. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region, Output will return database instance identifier name Select encrypted database name that we just created DB-Name-Encrypted. ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 7. Run again `describe-db-instances` command using the RDS instance identifier returned earlier, to determine if the selected database instance is encrypted, The command output should return the encryption status `True`. ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].StorageEncrypted' ```","AdditionalInformation": ""}],"description": "Ensure that encryption is enabled for RDS Instances","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.3.2": {"name": "2.3.2","checks": {"rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_RDS_Managing.html:https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.Upgrading.html:https://aws.amazon.com/rds/faqs/","Description": "Ensure that RDS database instances have the Auto Minor Version Upgrade flag enabled in order to receive automatically minor engine upgrades during the specified maintenance window. So, RDS instances can get the new features, bug fixes, and security patches for their database engines.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases`. 3. Select the RDS instance that wants to examine. 4. Click on the `Maintenance and backups` panel. 5. Under the `Maintenance` section, search for the Auto Minor Version Upgrade status. - If the current status is set to `Disabled`, means the feature is not set and the minor engine upgrades released will not be applied to the selected RDS instance**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance identifier. 3. Run again `describe-db-instances` command using the RDS instance identifier returned earlier to determine the Auto Minor Version Upgrade status for the selected instance: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].AutoMinorVersionUpgrade' ``` 4. The command output should return the feature current status. If the current status is set to `true`, the feature is enabled and the minor engine upgrades will be applied to the selected RDS instance.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "AWS RDS will occasionally deprecate minor engine versions and provide new ones for an upgrade. When the last version number within the release is replaced, the version changed is considered minor. With Auto Minor Version Upgrade feature enabled, the version upgrades will occur automatically during the specified maintenance window so your RDS instances can get the new features, bug fixes, and security patches for their database engines.","RemediationProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases`. 3. Select the RDS instance that wants to update. 4. Click on the `Modify` button placed on the top right side. 5. On the `Modify DB Instance: ` page, In the `Maintenance` section, select `Auto minor version upgrade` click on the `Yes` radio button. 6. At the bottom of the page click on `Continue`, check to Apply Immediately to apply the changes immediately, or select `Apply during the next scheduled maintenance window` to avoid any downtime. 7. Review the changes and click on `Modify DB Instance`. The instance status should change from available to modifying and back to available. Once the feature is enabled, the `Auto Minor Version Upgrade` status should change to `Yes`.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database instance names, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance identifier. 3. Run the `modify-db-instance` command to modify the selected RDS instance configuration this command will apply the changes immediately, Remove `--apply-immediately` to apply changes during the next scheduled maintenance window and avoid any downtime: ``` aws rds modify-db-instance --region  --db-instance-identifier  --auto-minor-version-upgrade --apply-immediately ``` 4. The command output should reveal the new configuration metadata for the RDS instance and check `AutoMinorVersionUpgrade` parameter value. 5. Run `describe-db-instances` command to check if the Auto Minor Version Upgrade feature has been successfully enable: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].AutoMinorVersionUpgrade' ``` 6. The command output should return the feature current status set to `true`, the feature is `enabled` and the minor engine upgrades will be applied to the selected RDS instance.","AdditionalInformation": ""}],"description": "Ensure Auto Minor Version Upgrade feature is Enabled for RDS Instances","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.3.3": {"name": "2.3.3","checks": {"rds_instance_no_public_access": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.html:https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario2.html:https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html:https://aws.amazon.com/rds/faqs/","Description": "Ensure and verify that RDS database instances provisioned in your AWS account do restrict unauthorized access in order to minimize security risks. To restrict access to any publicly accessible RDS database instance, you must disable the database Publicly Accessible flag and update the VPC security group associated with the instance.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. Under the navigation panel, On RDS Dashboard, click `Databases`. 3. Select the RDS instance that you want to examine. 4. Click `Instance Name` from the dashboard, Under `Connectivity and Security. 5. On the `Security`, check if the Publicly Accessible flag status is set to `Yes`, follow the below-mentioned steps to check database subnet access. - In the `networking` section, click the subnet link available under `Subnets` - The link will redirect you to the VPC Subnets page. - Select the subnet listed on the page and click the `Route Table` tab from the dashboard bottom panel. If the route table contains any entries with the destination `CIDR block set to 0.0.0.0/0` and with an `Internet Gateway` attached. - The selected RDS database instance was provisioned inside a public subnet, therefore is not running within a logically isolated environment and can be accessible from the Internet. 6. Repeat steps no. 4 and 5 to determine the type (public or private) and subnet for other RDS database instances provisioned in the current region. 8. Change the AWS region from the navigation bar and repeat the audit process for other regions.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance `identifier`. 3. Run again `describe-db-instances` command using the `PubliclyAccessible` parameter as query filter to reveal the database instance Publicly Accessible flag status: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].PubliclyAccessible' ``` 4. Check for the Publicly Accessible parameter status, If the Publicly Accessible flag is set to `Yes`. Then selected RDS database instance is publicly accessible and insecure, follow the below-mentioned steps to check database subnet access 5. Run again `describe-db-instances` command using the RDS database instance identifier that you want to check and appropriate filtering to describe the VPC subnet(s) associated with the selected instance: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].DBSubnetGroup.Subnets[]' ``` - The command output should list the subnets available in the selected database subnet group. 6. Run `describe-route-tables` command using the ID of the subnet returned at the previous step to describe the routes of the VPC route table associated with the selected subnet: ``` aws ec2 describe-route-tables --region  --filters \"Name=association.subnet-id,Values=\" --query 'RouteTables[*].Routes[]' ``` - If the command returns the route table associated with database instance subnet ID. Check the `GatewayId` and `DestinationCidrBlock` attributes values returned in the output. If the route table contains any entries with the `GatewayId` value set to `igw-xxxxxxxx` and the `DestinationCidrBlock` value set to `0.0.0.0/0`, the selected RDS database instance was provisioned inside a public subnet. - Or - If the command returns empty results, the route table is implicitly associated with subnet, therefore the audit process continues with the next step 7. Run again `describe-db-instances` command using the RDS database instance identifier that you want to check and appropriate filtering to describe the VPC ID associated with the selected instance: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].DBSubnetGroup.VpcId' ``` - The command output should show the VPC ID in the selected database subnet group 8. Now run `describe-route-tables` command using the ID of the VPC returned at the previous step to describe the routes of the VPC main route table implicitly associated with the selected subnet: ``` aws ec2 describe-route-tables --region  --filters \"Name=vpc-id,Values=\" \"Name=association.main,Values=true\" --query 'RouteTables[*].Routes[]' ``` - The command output returns the VPC main route table implicitly associated with database instance subnet ID. Check the `GatewayId` and `DestinationCidrBlock` attributes values returned in the output. If the route table contains any entries with the `GatewayId` value set to `igw-xxxxxxxx` and the `DestinationCidrBlock` value set to `0.0.0.0/0`, the selected RDS database instance was provisioned inside a public subnet, therefore is not running within a logically isolated environment and does not adhere to AWS security best practices.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Ensure that no public-facing RDS database instances are provisioned in your AWS account and restrict unauthorized access in order to minimize security risks. When the RDS instance allows unrestricted access (0.0.0.0/0), everyone and everything on the Internet can establish a connection to your database and this can increase the opportunity for malicious activities such as brute force attacks, PostgreSQL injections, or DoS/DDoS attacks.","RemediationProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. Under the navigation panel, On RDS Dashboard, click `Databases`. 3. Select the RDS instance that you want to update. 4. Click `Modify` from the dashboard top menu. 5. On the Modify DB Instance panel, under the `Connectivity` section, click on `Additional connectivity configuration` and update the value for `Publicly Accessible` to Not publicly accessible to restrict public access. Follow the below steps to update subnet configurations: - Select the `Connectivity and security` tab, and click on the VPC attribute value inside the `Networking` section. - Select the `Details` tab from the VPC dashboard bottom panel and click on Route table configuration attribute value. - On the Route table details page, select the Routes tab from the dashboard bottom panel and click on `Edit routes`. - On the Edit routes page, update the Destination of Target which is set to `igw-xxxxx` and click on `Save` routes. 6. On the Modify DB Instance panel Click on `Continue` and In the Scheduling of modifications section, perform one of the following actions based on your requirements: - Select Apply during the next scheduled maintenance window to apply the changes automatically during the next scheduled maintenance window. - Select Apply immediately to apply the changes right away. With this option, any pending modifications will be asynchronously applied as soon as possible, regardless of the maintenance window setting for this RDS database instance. Note that any changes available in the pending modifications queue are also applied. If any of the pending modifications require downtime, choosing this option can cause unexpected downtime for the application. 7. Repeat steps 3 to 6 for each RDS instance available in the current region. 8. Change the AWS region from the navigation bar to repeat the process for other regions.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names identifiers, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance identifier. 3. Run `modify-db-instance` command to modify the selected RDS instance configuration. Then use the following command to disable the `Publicly Accessible` flag for the selected RDS instances. This command use the apply-immediately flag. If you want `to avoid any downtime --no-apply-immediately flag can be used`: ``` aws rds modify-db-instance --region  --db-instance-identifier  --no-publicly-accessible --apply-immediately ``` 4. The command output should reveal the `PubliclyAccessible` configuration under pending values and should get applied at the specified time. 5. Updating the Internet Gateway Destination via AWS CLI is not currently supported To update information about Internet Gateway use the AWS Console Procedure. 6. Repeat steps 1 to 5 for each RDS instance provisioned in the current region. 7. Change the AWS region by using the --region filter to repeat the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that public access is not given to RDS Instance","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.4.1": {"name": "2.4.1","checks": {"efs_encryption_at_rest_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.4 Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/efs/index.html#efs","Description": "EFS data should be encrypted at rest using AWS KMS (Key Management Service).","DefaultValue": null,"AuditProcedure": "**From Console:** 1. Login to the AWS Management Console and Navigate to `Elastic File System (EFS) dashboard. 2. Select `File Systems` from the left navigation panel. 3. Each item on the list has a visible Encrypted field that displays data at rest encryption status. 4. Validate that this field reads `Encrypted` for all EFS file systems in all AWS regions.**From CLI:** 1. Run describe-file-systems command using custom query filters to list the identifiers of all AWS EFS file systems currently available within the selected region: ``` aws efs describe-file-systems --region  --output table --query 'FileSystems[*].FileSystemId' ``` 2. The command output should return a table with the requested file system IDs. 3. Run describe-file-systems command using the ID of the file system that you want to examine as identifier and the necessary query filters: ``` aws efs describe-file-systems --region  --file-system-id  --query 'FileSystems[*].Encrypted' ``` 4. The command output should return the file system encryption status true or false. If the returned value is `false`, the selected AWS EFS file system is not encrypted and if the returned value is `true`, the selected AWS EFS file system is encrypted.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Data should be encrypted at rest to reduce the risk of a data breach via direct access to the storage device.","RemediationProcedure": "**It is important to note that EFS file system data at rest encryption must be turned on when creating the file system.**If an EFS file system has been created without data at rest encryption enabled then you must create another EFS file system with the correct configuration and transfer the data.**Steps to create an EFS file system with data encrypted at rest:****From Console:** 1. Login to the AWS Management Console and Navigate to `Elastic File System (EFS)` dashboard. 2. Select `File Systems` from the left navigation panel. 3. Click `Create File System` button from the dashboard top menu to start the file system setup process. 4. On the `Configure file system access` configuration page, perform the following actions. - Choose the right VPC from the VPC dropdown list. - Within Create mount targets section, select the checkboxes for all of the Availability Zones (AZs) within the selected VPC. These will be your mount targets. - Click `Next step` to continue.5. Perform the following on the `Configure optional settings` page. - Create `tags` to describe your new file system. - Choose `performance mode` based on your requirements. - Check `Enable encryption` checkbox and choose `aws/elasticfilesystem` from Select KMS master key dropdown list to enable encryption for the new file system using the default master key provided and managed by AWS KMS. - Click `Next step` to continue.6. Review the file system configuration details on the `review and create` page and then click `Create File System` to create your new AWS EFS file system. 7. Copy the data from the old unencrypted EFS file system onto the newly create encrypted file system. 8. Remove the unencrypted file system as soon as your data migration to the newly create encrypted file system is completed. 9. Change the AWS region from the navigation bar and repeat the entire process for other aws regions.**From CLI:** 1. Run describe-file-systems command to describe the configuration information available for the selected (unencrypted) file system (see Audit section to identify the right resource): ``` aws efs describe-file-systems --region  --file-system-id  ``` 2. The command output should return the requested configuration information. 3. To provision a new AWS EFS file system, you need to generate a universally unique identifier (UUID) in order to create the token required by the create-file-system command. To create the required token, you can use a randomly generated UUID from \"https://www.uuidgenerator.net\". 4. Run create-file-system command using the unique token created at the previous step. ``` aws efs create-file-system --region  --creation-token  --performance-mode generalPurpose --encrypted ``` 5. The command output should return the new file system configuration metadata. 6. Run create-mount-target command using the newly created EFS file system ID returned at the previous step as identifier and the ID of the Availability Zone (AZ) that will represent the mount target: ``` aws efs create-mount-target --region  --file-system-id  --subnet-id  ``` 7. The command output should return the new mount target metadata. 8. Now you can mount your file system from an EC2 instance. 9. Copy the data from the old unencrypted EFS file system onto the newly create encrypted file system. 10. Remove the unencrypted file system as soon as your data migration to the newly create encrypted file system is completed. ``` aws efs delete-file-system --region  --file-system-id  ``` 11. Change the AWS region by updating the --region and repeat the entire process for other aws regions.","AdditionalInformation": ""}],"description": "Ensure that encryption is enabled for EFS file systems","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 52,"requirements_failed": 11,"requirements_manual": 0,"total_requirements": 63,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "407c3a08-81aa-4d24-9aca-46a0904f4b1d","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "aws_account_security_onboarding_aws","framework": "AWS-Account-Security-Onboarding","version": "","description": "Checklist when onboarding new AWS Accounts to existing AWS Organization.","region": "eu-west-1","requirements": {"S3 protection": {"name": "S3 protection","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "S3","SubGroup": null,"SubSection": null}],"description": "Protection using S3","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"RDS protection": {"name": "RDS protection","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "GuardDuty","SubGroup": null,"SubSection": null}],"description": "Protection for RDS instances","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Block root user": {"name": "Block root user","checks": {"iam_avoid_root_usage": null,"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "SCPs","Service": "IAM","SubGroup": null,"SubSection": "Apply existing SCPs based on OU placement"}],"description": "Block root user","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"Malware Scanning": {"name": "Malware Scanning","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "GuardDuty","SubGroup": null,"SubSection": null}],"description": "Conducting a Comprehensive Scan for Malicious Software","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Threat Detection": {"name": "Threat Detection","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "GuardDuty","SubGroup": null,"SubSection": null}],"description": "Detection of Threats in your AWS environment","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Lambda protection": {"name": "Lambda protection","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "Lambda","SubGroup": null,"SubSection": null}],"description": "Protection using Lambda","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Runtime protection": {"name": "Runtime protection","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Optional","ItemId": null,"Section": "Enable GuardDuty","Service": "GuardDuty","SubGroup": null,"SubSection": null}],"description": "Brand new and in need of thorough testing.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Predefine IAM Roles": {"name": "Predefine IAM Roles","checks": {"iam_support_role_created": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_role_cross_service_confused_deputy_prevention": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Deploy account from predefined IaC template","Service": "IAM","SubGroup": null,"SubSection": null}],"description": "Check if exists predefine IAM Roles","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"Block unused regions": {"name": "Block unused regions","checks": {"organizations_scp_check_deny_regions": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "SCPs","Service": "IAM","SubGroup": null,"SubSection": "Apply existing SCPs based on OU placement"}],"description": "Block unsued regions","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"S3 Block Public Access": {"name": "S3 Block Public Access","checks": {"s3_bucket_public_access": null,"s3_bucket_level_public_access_block": "PASS","s3_account_level_public_access_blocks": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Deploy account from predefined IaC template","Service": "S3","SubGroup": null,"SubSection": null}],"description": "Block public access to S3 buckets","checks_status": {"fail": 0,"pass": 1,"total": 3,"manual": 0}},"Organization invitation": {"name": "Organization invitation","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Deploy account from predefined IaC template","Service": "Organizations","SubGroup": null,"SubSection": null}],"description": "Check if organization invitation is enabled","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Additional managed rules": {"name": "Additional managed rules","checks": {},"status": "PASS","attributes": [{"Type": "Discuss","ItemId": null,"Section": "WAFv2","Service": "WAFv2","SubGroup": null,"SubSection": "Deploy WAF setup for each public web service"}],"description": "Supplementary managed rules","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Blanket rate-based rules": {"name": "Blanket rate-based rules","checks": {},"status": "PASS","attributes": [{"Type": "Must","ItemId": null,"Section": "WAFv2","Service": "WAFv2","SubGroup": null,"SubSection": "Deploy WAF setup for each public web service"}],"description": "Establishing rules based on a standardized, all-encompassing rate.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Restrict instances types": {"name": "Restrict instances types","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "SCPs","Service": "IAM","SubGroup": null,"SubSection": "Apply existing SCPs based on OU placement"}],"description": "Restrict instances types","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Alert on IAM user changes": {"name": "Alert on IAM user changes","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "CloudTrail","SubGroup": null,"SubSection": "CloudTrail"}],"description": "Alert on IAM user changes","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Enabled security services": {"name": "Enabled security services","checks": {"macie_is_enabled": "PASS","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","accessanalyzer_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Deploy account from predefined IaC template","Service": "SecurityServices","SubGroup": null,"SubSection": null}],"description": "Check if security services are enabled","checks_status": {"fail": 0,"pass": 4,"total": 4,"manual": 0}},"Alert on blocked DNS query": {"name": "Alert on blocked DNS query","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "Route53","SubGroup": null,"SubSection": "R53 DNS Resolver"}],"description": "Notify when a DNS query is obstructed.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Alert on each High finding": {"name": "Alert on each High finding","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Alerting","Service": "GuardDuty","SubGroup": null,"SubSection": "GuardDuty"}],"description": "Checks that GuardDuty is enabled and configured to send High findings to CloudWatch Events","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"Disable AMI public sharing": {"name": "Disable AMI public sharing","checks": {"ec2_ami_public": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Deploy account from predefined IaC template","Service": "EC2","SubGroup": null,"SubSection": null}],"description": "Disable AMI public sharing","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"Add custom SCPs if required": {"name": "Add custom SCPs if required","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "SCPs","Service": "IAM","SubGroup": null,"SubSection": null}],"description": "Add custom SCPs if required","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Scoped-down rate-based rules": {"name": "Scoped-down rate-based rules","checks": {"elbv2_waf_acl_attached": "FAIL","cloudfront_distributions_using_waf": null,"apigateway_restapi_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Type": "Discuss","ItemId": null,"Section": "WAFv2","Service": "WAFv2","SubGroup": null,"SubSection": "Deploy WAF setup for each public web service"}],"description": "Rate-based rules with a narrowed scope","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"Global allow - and block-lists": {"name": "Global allow - and block-lists","checks": {"elbv2_waf_acl_attached": "FAIL","cloudfront_distributions_using_waf": null,"apigateway_restapi_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "WAFv2","Service": "WAFv2","SubGroup": null,"SubSection": "Deploy WAF setup for each public web service"}],"description": "Establishing International Lists for Permissions and Restrictions","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"Service-unique exclusion rules": {"name": "Service-unique exclusion rules","checks": {"elbv2_waf_acl_attached": "FAIL","cloudfront_distributions_using_waf": null,"apigateway_restapi_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "WAFv2","Service": "WAFv2","SubGroup": null,"SubSection": "Deploy WAF setup for each public web service"}],"description": "Exclusion rules specific to the service provided.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"Alert on snapshot manipulations": {"name": "Alert on snapshot manipulations","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "CloudTrail","SubGroup": null,"SubSection": "CloudTrail"}],"description": "Alert when a snapshot is manipulated","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"EKS protection (if EKS is used)": {"name": "EKS protection (if EKS is used)","checks": {},"status": "PASS","attributes": [{"Type": "Optional","ItemId": null,"Section": "Enable GuardDuty","Service": "EKS","SubGroup": null,"SubSection": null}],"description": "Enhanced Kubernetes Security (EKS) protection, if the Kubernetes service is employed.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Predefined set of managed rules": {"name": "Predefined set of managed rules","checks": {"elbv2_waf_acl_attached": "FAIL","cloudfront_distributions_using_waf": null,"apigateway_restapi_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "WAFv2","Service": "WAFv2","SubGroup": null,"SubSection": "Deploy WAF setup for each public web service"}],"description": "A pre-established collection of rules under management control.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"Alerts based on rate-based rules": {"name": "Alerts based on rate-based rules","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "WAF","SubGroup": null,"SubSection": "WAF"}],"description": "Notifications triggered by rate-based regulations","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Use strictly AWS VPC DNS resolver": {"name": "Use strictly AWS VPC DNS resolver","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "R53 DNS Resolver Firewall","Service": "Route53","SubGroup": null,"SubSection": null}],"description": "Exclusively Employ Amazon Web Services (AWS) Virtual Private Cloud (VPC) DNS Resolver","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Alert based on DDoSDetected metric": {"name": "Alert based on DDoSDetected metric","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "Shield","SubGroup": null,"SubSection": "Shield"}],"description": "Generate an alert triggered by the detection of a DDoS attack based on the DDoSDetected metric.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Enable and configure AWS Inspector": {"name": "Enable and configure AWS Inspector","checks": {"inspector2_is_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Vulnerability Scanning","Service": "EC2","SubGroup": null,"SubSection": "EC2 used as servers"}],"description": "Enable and set up AWS Inspector.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"IDC integration, SSO configuration": {"name": "IDC integration, SSO configuration","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Deploy account from predefined IaC template","Service": "IAM Identity Center","SubGroup": null,"SubSection": null}],"description": "Check if IDC integration and SSO configuration is enabled","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Send DNS Resolvers queries to SIEM": {"name": "Send DNS Resolvers queries to SIEM","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Logging","Service": "Logging","SubGroup": null,"SubSection": null}],"description": "Send DNS Resolvers queries to SIEM","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Alerts on raised cost anomaly events": {"name": "Alerts on raised cost anomaly events","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "Billing","SubGroup": null,"SubSection": "Cost Anomaly"}],"description": "Alert when cost anomaly events are raised","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Enable as part of Organization trail": {"name": "Enable as part of Organization trail","checks": {"cloudtrail_multi_region_enabled": "PASS","cloudtrail_multi_region_enabled_logging_management_events": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "AWS Cloudtrail","Service": "CloudTrail","SubGroup": null,"SubSection": null}],"description": "Activate as a component of the Organization trail.","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"Root user - distribution email + MFA": {"name": "Root user - distribution email + MFA","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Deploy account from predefined IaC template","Service": "IAM","SubGroup": null,"SubSection": null}],"description": "Check if root user has distribution email and MFA enabled","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"Billing, emergency, security contacts": {"name": "Billing, emergency, security contacts","checks": {"account_maintain_current_contact_details": null,"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Deploy account from predefined IaC template","Service": "Billing","SubGroup": null,"SubSection": null}],"description": "Check if billing, emergency, security contacts are configured","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"Realert on inactivity in a set period": {"name": "Realert on inactivity in a set period","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "SecurityHub","SubGroup": null,"SubSection": "SecurityHub"}],"description": "Activate a re-alert system for detecting inactivity within a specified time frame.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Confirm that events are present in SIEM": {"name": "Confirm that events are present in SIEM","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "GuardDuty","SubGroup": null,"SubSection": null}],"description": "Confirm that events are present in SIEM","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Create analyzers in each active regions": {"name": "Create analyzers in each active regions","checks": {"accessanalyzer_enabled": "PASS","accessanalyzer_enabled_without_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "IAM Access Analyzer","Service": "IAM Access Analyzer","SubGroup": null,"SubSection": null}],"description": "Establish analyzers within every active region.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Export metrics in centralized collector": {"name": "Export metrics in centralized collector","checks": {"wafv2_webacl_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "WAFv2","Service": "CloudWatch","SubGroup": null,"SubSection": null}],"description": "Exporting metrics to a centralized collector for comprehensive data aggregation.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"CFD + ALB + secret rotation architecture": {"name": "CFD + ALB + secret rotation architecture","checks": {"elbv2_waf_acl_attached": "FAIL","cloudfront_distributions_using_waf": null,"apigateway_restapi_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "WAFv2","Service": "WAFv2","SubGroup": null,"SubSection": "Deploy WAF setup for each public web service"}],"description": "Designing an Architecture for Computational Fluid Dynamics (CFD), Application Load Balancing (ALB), and Secret Rotation Integration","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"Critical alert on every root user activity": {"name": "Critical alert on every root user activity","checks": {"cloudwatch_log_metric_filter_root_usage": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Alerting","Service": "CloudTrail","SubGroup": null,"SubSection": "CloudTrail"}],"description": "Send critical alert on every root user activity","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"Consider enabling for critical buckets only": {"name": "Consider enabling for critical buckets only","checks": {"macie_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Macie","Service": "Macie","SubGroup": null,"SubSection": null}],"description": "Please contemplate activating this feature exclusively for essential or crucial buckets.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"Alert on rise of ConsoleLoginFailures events": {"name": "Alert on rise of ConsoleLoginFailures events","checks": {"cloudwatch_log_metric_filter_authentication_failures": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Alerting","Service": "CloudTrail","SubGroup": null,"SubSection": "CloudTrail"}],"description": "Alert on rise ConsoleLoginFailures events","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"Send VPC Flow Logs (only DENYs) to S3 bucket": {"name": "Send VPC Flow Logs (only DENYs) to S3 bucket","checks": {"vpc_flow_logs_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Logging","Service": "Logging","SubGroup": null,"SubSection": null}],"description": "Send VPC Flow Logs (only DENYs) to S3 bucket","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"Critical alert on cloudtrail settings changes": {"name": "Critical alert on cloudtrail settings changes","checks": {"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Alerting","Service": "CloudTrail","SubGroup": null,"SubSection": "CloudTrail"}],"description": "Send critical alert on cloudtrail settings changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"Scan images for vulnerability on upload to ECR": {"name": "Scan images for vulnerability on upload to ECR","checks": {"inspector2_is_enabled": "FAIL","inspector2_active_findings_exist": "FAIL","ecr_registry_scan_images_on_push_enabled": "PASS","ecr_repositories_scan_images_on_push_enabled": "FAIL","ecr_repositories_scan_vulnerabilities_in_latest_image": null},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Vulnerability Scanning","Service": "ECR","SubGroup": null,"SubSection": "ECR used as docker images hub"}],"description": "Check uploaded images for vulnerabilities when adding them to the ECR (Elastic Container Registry).","checks_status": {"fail": 3,"pass": 1,"total": 5,"manual": 0}},"Alert on critical vulnerabilities in AMIs/Images": {"name": "Alert on critical vulnerabilities in AMIs/Images","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "Inspector","SubGroup": null,"SubSection": "Vulnerability Scanning"}],"description": "Notification regarding severe vulnerabilities detected in AMIs/Images.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Ban outbound DNS calls from all VPCs to ports 53": {"name": "Ban outbound DNS calls from all VPCs to ports 53","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "R53 DNS Resolver Firewall","Service": "Route53","SubGroup": null,"SubSection": null}],"description": "Prohibit all Virtual Private Clouds (VPCs) from initiating outbound DNS calls on port 53.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Enable/disable additional standards and controls": {"name": "Enable/disable additional standards and controls","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Enable AWS SecurityHub","Service": "SecurityHub","SubGroup": null,"SubSection": null}],"description": "Implement SecurityHub Central Configuration across the organization.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"Confirm that logs are present in S3 bucket and SIEM": {"name": "Confirm that logs are present in S3 bucket and SIEM","checks": {"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "AWS Cloudtrail","Service": "CloudTrail","SubGroup": null,"SubSection": null}],"description": "Verify the existence of logs within both the S3 bucket and the SIEM system.","checks_status": {"fail": 1,"pass": 0,"total": 3,"manual": 0}},"Alerts based on (at least) each new CRITICAL finding": {"name": "Alerts based on (at least) each new CRITICAL finding","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "SecurityHub","SubGroup": null,"SubSection": "SecurityHub"}],"description": "Alerts triggered by every new CRITICAL finding, at a minimum.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Apply suppression filters to disable useless findings": {"name": "Apply suppression filters to disable useless findings","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "GuardDuty","SubGroup": null,"SubSection": null}],"description": "Implementing suppression filters to deactivate non-essential detections.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Enable continuous recording for most of the resources": {"name": "Enable continuous recording for most of the resources","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Enable AWS Config","Service": "Config","SubGroup": null,"SubSection": null}],"description": "Activate continuous recording for the majority of resources.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"Adopt incident response guide and prepared battle card": {"name": "Adopt incident response guide and prepared battle card","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "Shield","SubGroup": null,"SubSection": "Shield"}],"description": "Utilize the incident response manual and have the battle card ready for use.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Confirm that records are present in central aggregator": {"name": "Confirm that records are present in central aggregator","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Enable AWS Config","Service": "Config","SubGroup": null,"SubSection": null}],"description": "Confirm that records are present in central aggregator","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"Configure R53 health checks for all protected resources": {"name": "Configure R53 health checks for all protected resources","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "WAFv2","Service": "Route53","SubGroup": null,"SubSection": null}],"description": "Establishing Amazon Route 53 (R53) health checks to monitor the well-being of all safeguarded resources.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Export scan results as metrics in centralized collector": {"name": "Export scan results as metrics in centralized collector","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Vulnerability Scanning","Service": "ECR","SubGroup": null,"SubSection": "ECR used as docker images hub"}],"description": "Generate metric data from scan results and store it in a centralized collector.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Include in process of incident response based on events": {"name": "Include in process of incident response based on events","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "GuardDuty","SubGroup": null,"SubSection": null}],"description": "Incorporate within the procedural framework of incident response, taking into account the triggering events.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Apply SecurityHub Central Configuration for Organization": {"name": "Apply SecurityHub Central Configuration for Organization","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Enable AWS SecurityHub","Service": "SecurityHub","SubGroup": null,"SubSection": null}],"description": "Apply SecurityHub Central Configuration for Organization","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"Enable as part of central configuration for Organization": {"name": "Enable as part of central configuration for Organization","checks": {"guardduty_is_enabled": "PASS","guardduty_centrally_managed": "FAIL"},"status": "FAIL","attributes": [{"Type": "Must","ItemId": null,"Section": "Enable GuardDuty","Service": "GuardDuty","SubGroup": null,"SubSection": null}],"description": "Please verify the existence of records within the central aggregator.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"Deploy solution to alert on at least critical new findings": {"name": "Deploy solution to alert on at least critical new findings","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Enable AWS SecurityHub","Service": "SecurityHub","SubGroup": null,"SubSection": null}],"description": "Implement a solution to trigger alerts for newly identified critical issues at minimum.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"Apply managed domain name lists for Resolver in block mode)": {"name": "Apply managed domain name lists for Resolver in block mode)","checks": {"route53_domains_transferlock_enabled": null,"route53_domains_privacy_protection_enabled": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "R53 DNS Resolver Firewall","Service": "Route53","SubGroup": null,"SubSection": null}],"description": "Utilize managed domain name lists within Resolver to implement block mode.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"Block tampering with security-related settings and services": {"name": "Block tampering with security-related settings and services","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "SCPs","Service": "IAM","SubGroup": null,"SubSection": "Apply existing SCPs based on OU placement"}],"description": "Block tampering with security-related settings and services","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Enable Shield Advanced subscription for public facing account": {"name": "Enable Shield Advanced subscription for public facing account","checks": {"shield_advanced_protection_in_global_accelerators": null,"shield_advanced_protection_in_route53_hosted_zones": null,"shield_advanced_protection_in_associated_elastic_ips": null,"shield_advanced_protection_in_classic_load_balancers": null,"shield_advanced_protection_in_cloudfront_distributions": null,"shield_advanced_protection_in_internet_facing_load_balancers": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Shield Advanced","Service": "Shield Advanced","SubGroup": null,"SubSection": null}],"description": "Activate the Shield Advanced subscription for the publicly accessible account.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"Verify that events are present in SecurityHub aggregated view": {"name": "Verify that events are present in SecurityHub aggregated view","checks": {"securityhub_enabled": "PASS","accessanalyzer_enabled": "PASS","accessanalyzer_enabled_without_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "IAM Access Analyzer","Service": "SecurityHub","SubGroup": null,"SubSection": null}],"description": "Confirm the presence of events within the aggregated view of SecurityHub.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"Configure sensitive fields redaction and send WAF logs to SIEM": {"name": "Configure sensitive fields redaction and send WAF logs to SIEM","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "WAFv2","Service": "WAFv2","SubGroup": null,"SubSection": null}],"description": "Configure the redaction of sensitive fields and transmit Web Application Firewall (WAF) logs to the Security Information and Event Management (SIEM) system.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Confirm that findings are being visible in the aggregated view": {"name": "Confirm that findings are being visible in the aggregated view","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Enable AWS SecurityHub","Service": "SecurityHub","SubGroup": null,"SubSection": null}],"description": "Please verify that the findings are visible when viewed in the aggregated perspective.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"Send S3 access logs for critical buckets to separate S3 bucket": {"name": "Send S3 access logs for critical buckets to separate S3 bucket","checks": {"cloudtrail_s3_dataevents_write_enabled": null,"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": "Automated","ItemId": null,"Section": "Logging","Service": "Logging","SubGroup": null,"SubSection": null}],"description": "Send S3 access logs for critical buckets to separate S3 bucket","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"Consider periodic recording for some resources to optimize bill": {"name": "Consider periodic recording for some resources to optimize bill","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Enable AWS Config","Service": "Config","SubGroup": null,"SubSection": null}],"description": "Think about implementing scheduled monitoring for specific resources in order to maximize cost efficiency.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Create DDoS battle card with main info about protected services": {"name": "Create DDoS battle card with main info about protected services","checks": {"shield_advanced_protection_in_global_accelerators": null,"shield_advanced_protection_in_route53_hosted_zones": null,"shield_advanced_protection_in_associated_elastic_ips": null,"shield_advanced_protection_in_classic_load_balancers": null,"shield_advanced_protection_in_cloudfront_distributions": null,"shield_advanced_protection_in_internet_facing_load_balancers": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Shield Advanced","Service": "Shield Advanced","SubGroup": null,"SubSection": null}],"description": "Prepare a Detailed Distributed Denial of Service (DDoS) Battle Card Encompassing Key Information Regarding Safeguarded Services.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"Alerts based on high amount of blocked requests by managed rules": {"name": "Alerts based on high amount of blocked requests by managed rules","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "WAF","SubGroup": null,"SubSection": "WAF"}],"description": "Notifications triggered by a significant number of blocked requests as a result of managed rules.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Alerts based on aggregated findings with severity Medium and below": {"name": "Alerts based on aggregated findings with severity Medium and below","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Alerting","Service": "GuardDuty","SubGroup": null,"SubSection": "GuardDuty"}],"description": "Alert based on aggregated findings with severity Medium and below","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Create Cost Anomaly Detection monitors to alert spending anomalies": {"name": "Create Cost Anomaly Detection monitors to alert spending anomalies","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Budget Alarms","Service": "CloudWatch","SubGroup": null,"SubSection": "QA"}],"description": "Establish monitoring systems for cost anomaly detection to promptly notify about unusual spending patterns.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Enable Shield Advanced automatic application layer DDoS mitigation": {"name": "Enable Shield Advanced automatic application layer DDoS mitigation","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "WAFv2","Service": "Shield Advanced","SubGroup": null,"SubSection": null}],"description": "Activate automatic application layer Distributed Denial of Service (DDoS) mitigation within Shield Advanced.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Apply custom threat list for GuardDuty to alert on access to DoH servers": {"name": "Apply custom threat list for GuardDuty to alert on access to DoH servers","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "R53 DNS Resolver Firewall","Service": "Route53","SubGroup": null,"SubSection": null}],"description": "Implement a customized threat list within GuardDuty to generate alerts when there is access to Domain Name System over HTTPS (DoH) servers.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Configure Budgets Actions to stop services in cases of big unexpected spendings": {"name": "Configure Budgets Actions to stop services in cases of big unexpected spendings","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Budget Alarms","Service": "SNS","SubGroup": null,"SubSection": "QA"}],"description": "Set up Budgets Actions to halt services when significant unexpected expenses occur.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"Ensure that there are no critical (and considered critical) findings present in account": {"name": "Ensure that there are no critical (and considered critical) findings present in account","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Enable AWS SecurityHub","Service": "SecurityHub","SubGroup": null,"SubSection": null}],"description": "Make certain that there are no critical findings, whether deemed critical or not, within the account.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"Deploy solution to periodically rescan currently used images and report found vulnerabilities": {"name": "Deploy solution to periodically rescan currently used images and report found vulnerabilities","checks": {"ecr_repositories_scan_vulnerabilities_in_latest_image": null},"status": "PASS","attributes": [{"Type": "Automated","ItemId": null,"Section": "Vulnerability Scanning","Service": "ECR","SubGroup": null,"SubSection": "ECR used as docker images hub"}],"description": "Implement a solution to conduct regular scans on currently employed images and notify about any identified vulnerabilities.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"Establish ready-to-be-enabled pipelines to deliver ALB and CFD to SIEM to toggle in case of emergency and investigations": {"name": "Establish ready-to-be-enabled pipelines to deliver ALB and CFD to SIEM to toggle in case of emergency and investigations","checks": {},"status": "PASS","attributes": [{"Type": "Manual","ItemId": null,"Section": "Logging","Service": "Logging","SubGroup": null,"SubSection": null}],"description": "Establish ready-to-be-enabled pipelines to deliver ALB and CFD to SIEM to toggle in case of emergency and investigations","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}}},"requirements_passed": 26,"requirements_failed": 23,"requirements_manual": 34,"total_requirements": 83,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "623480b7-012a-4aab-b553-16d3b8898136","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "hipaa_aws","framework": "HIPAA","version": "","description": "The Health Insurance Portability and Accountability Act of 1996 (HIPAA) is legislation that helps US workers to retain health insurance coverage when they change or lose jobs. The legislation also seeks to encourage electronic health records to improve the efficiency and quality of the US healthcare system through improved information sharing.","region": "eu-west-1","requirements": {"164_312_b": {"name": "164.312(b) Audit controls","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_b","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement hardware, software, and/or procedural mechanisms that record and examine activity in information systems that contain or use electronic protected health information.","checks_status": {"fail": 8,"pass": 4,"total": 16,"manual": 0}},"164_312_d": {"name": "164.312(d) Person or entity authentication","checks": {"iam_root_mfa_enabled": null,"iam_password_policy_reuse_24": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_312_d","Section": "164.312 Technical Safeguards","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Implement procedures to verify that a person or entity seeking access to electronic protected health information is the one claimed.","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"164_308_a_8": {"name": "164.308(a)(8) Evaluation","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_8","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Perform a periodic technical and nontechnical evaluation, based initially upon the standards implemented under this rule and subsequently, in response to environmental or operational changes affecting the security of electronic protected health information, that establishes the extent to which an entity's security policies and procedures meet the requirements of this subpart.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"164_312_a_1": {"name": "164.312(a)(1) Access control","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"iam_user_mfa_enabled_console_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"awslambda_function_not_publicly_accessible": "PASS","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_a_1","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement technical policies and procedures for electronic information systems that maintain electronic protected health information to allow access only to those persons or software programs that have been granted access rights as specified in 164.308(a)(4).","checks_status": {"fail": 1,"pass": 5,"total": 16,"manual": 0}},"164_312_c_1": {"name": "164.312(c)(1) Integrity","checks": {"ec2_ebs_volume_encryption": "PASS","s3_bucket_object_versioning": "FAIL","s3_bucket_default_encryption": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_c_1","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement policies and procedures to protect electronic protected health information from improper alteration or destruction.","checks_status": {"fail": 4,"pass": 2,"total": 6,"manual": 0}},"164_312_c_2": {"name": "164.312(c)(2) Mechanism to authenticate electronic protected health information","checks": {"vpc_flow_logs_enabled": "FAIL","ec2_ebs_volume_encryption": "PASS","s3_bucket_object_versioning": "FAIL","s3_bucket_default_encryption": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_c_2","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement electronic mechanisms to corroborate that electronic protected health information has not been altered or destroyed in an unauthorized manner.","checks_status": {"fail": 5,"pass": 2,"total": 7,"manual": 0}},"164_312_e_1": {"name": "164.312(e)(1) Transmission security","checks": {"elb_ssl_listeners": "FAIL","acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","cloudfront_distributions_https_enabled": null,"awslambda_function_not_publicly_accessible": "PASS","opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_e_1","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement technical security measures to guard against unauthorized access to electronic protected health information that is being transmitted over an electronic communications network.","checks_status": {"fail": 3,"pass": 3,"total": 9,"manual": 0}},"164_308_a_3_i": {"name": "164.308(a)(3)(i) Workforce security","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_3_i","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement policies and procedures to ensure that all members of its workforce have appropriate access to electronic protected health information, as provided under paragraph (a)(4) of this section, and to prevent those workforce members who do not have access under paragraph (a)(4) of this section from obtaining access to electronic protected health information.","checks_status": {"fail": 1,"pass": 5,"total": 15,"manual": 0}},"164_308_a_4_i": {"name": "164.308(a)(4)(i) Information access management","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_4_i","Section": "164.308 Administrative Safeguards","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Implement policies and procedures for authorizing access to electronic protected health information that are consistent with the applicable requirements of subpart E of this part.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"164_308_a_6_i": {"name": "164.308(a)(6)(i) Security incident procedures","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_6_i","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement policies and procedures to address security incidents.","checks_status": {"fail": 0,"pass": 2,"total": 8,"manual": 0}},"164_308_a_7_i": {"name": "164.308(a)(7)(i) Contingency plan","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_7_i","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establish (and implement as needed) policies and procedures for responding to an emergency or other occurrence (for example, fire, vandalism, system failure, and natural disaster) that damages systems that contain electronic protected health information.","checks_status": {"fail": 3,"pass": 1,"total": 10,"manual": 0}},"164_312_a_2_i": {"name": "164.312(a)(2)(i) Unique user identification","checks": {"iam_no_root_access_key": null,"s3_bucket_public_access": null,"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_312_a_2_i","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Assign a unique name and/or number for identifying and tracking user identity.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"164_312_e_2_i": {"name": "164.312(e)(2)(i) Integrity controls","checks": {"elb_ssl_listeners": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_multi_region_enabled": "PASS","s3_bucket_secure_transport_policy": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_e_2_i","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement security measures to ensure that electronically transmitted electronic protected health information is not improperly modified without detection until disposed of.","checks_status": {"fail": 4,"pass": 3,"total": 10,"manual": 0}},"164_308_a_6_ii": {"name": "164.308(a)(6)(ii) Response and reporting","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"cloudwatch_log_metric_filter_root_usage": null,"s3_bucket_server_access_logging_enabled": "FAIL","cloudwatch_log_metric_filter_authentication_failures": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_6_ii","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Identify and respond to suspected or known security incidents; mitigate, to the extent practicable, harmful effects of security incidents that are known to the covered entity or business associate; and document security incidents and their outcomes.","checks_status": {"fail": 6,"pass": 4,"total": 15,"manual": 0}},"164_312_a_2_ii": {"name": "164.312(a)(2)(ii) Emergency access procedure","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_a_2_ii","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establish (and implement as needed) procedures for obtaining necessary electronic protected health information during an emergency.","checks_status": {"fail": 2,"pass": 1,"total": 9,"manual": 0}},"164_312_a_2_iv": {"name": "164.312(a)(2)(iv) Encryption and decryption","checks": {"kms_cmk_rotation_enabled": null,"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"eks_cluster_kms_cmk_encryption_in_secrets_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_a_2_iv","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement a mechanism to encrypt and decrypt electronic protected health information.","checks_status": {"fail": 6,"pass": 3,"total": 19,"manual": 0}},"164_312_e_2_ii": {"name": "164.312(e)(2)(ii) Encryption","checks": {"elb_ssl_listeners": "FAIL","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"eks_cluster_kms_cmk_encryption_in_secrets_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_312_e_2_ii","Section": "164.312 Technical Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement a mechanism to encrypt electronic protected health information whenever deemed appropriate.","checks_status": {"fail": 7,"pass": 3,"total": 19,"manual": 0}},"164_308_a_1_ii_a": {"name": "164.308(a)(1)(ii)(A) Risk analysis","checks": {"guardduty_is_enabled": "PASS","config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_1_ii_a","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Conduct an accurate and thorough assessment of the potential risks and vulnerabilities to the confidentiality, integrity, and availability of electronic protected health information held by the covered entity or business associate.","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"164_308_a_1_ii_b": {"name": "164.308(a)(1)(ii)(B) Risk Management","checks": {"elb_ssl_listeners": "FAIL","rds_instance_multi_az": "FAIL","ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"ec2_ebs_volume_encryption": "PASS","elbv2_deletion_protection": "FAIL","ec2_ebs_default_encryption": "PASS","rds_instance_backup_enabled": "PASS","rds_snapshots_public_access": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"s3_bucket_default_encryption": "PASS","awslambda_function_url_public": null,"efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"redshift_cluster_public_access": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"cloudtrail_log_file_validation_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","awslambda_function_not_publicly_accessible": "PASS","cloudwatch_log_group_kms_encryption_enabled": "FAIL","iam_inline_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_encryption_enabled": null,"iam_aws_attached_policy_no_administrative_privileges": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"iam_customer_attached_policy_no_administrative_privileges": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_1_ii_b","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement security measures sufficient to reduce risks and vulnerabilities to a reasonable and appropriate level to comply with 164.306(a): Ensure the confidentiality, integrity, and availability of all electronic protected health information the covered entity or business associate creates, receives, maintains, or transmits.","checks_status": {"fail": 14,"pass": 9,"total": 39,"manual": 0}},"164_308_a_1_ii_d": {"name": "164.308(a)(1)(ii)(D) Information system activity review","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_1_ii_d","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement procedures to regularly review records of information system activity, such as audit logs, access reports, and security incident tracking reports.","checks_status": {"fail": 7,"pass": 4,"total": 15,"manual": 0}},"164_308_a_3_ii_a": {"name": "164.308(a)(3)(ii)(A) Authorization and/or supervision","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_root_mfa_enabled": null,"elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","iam_root_hardware_mfa_enabled": null,"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","iam_user_mfa_enabled_console_access": null,"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_3_ii_a","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement procedures for the authorization and/or supervision of workforce members who work with electronic protected health information or in locations where it might be accessed.","checks_status": {"fail": 4,"pass": 4,"total": 16,"manual": 0}},"164_308_a_3_ii_b": {"name": "164.308(a)(3)(ii)(B) Workforce clearance procedure","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_3_ii_b","Section": "164.308 Administrative Safeguards","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Implement procedures to determine that the access of a workforce member to electronic protected health information is appropriate.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"164_308_a_3_ii_c": {"name": "164.308(a)(3)(ii)(C) Termination procedures","checks": {"iam_rotate_access_key_90_days": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_3_ii_c","Section": "164.308 Administrative Safeguards","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Implement procedures for terminating access to electronic protected health information when the employment of, or other arrangement with, a workforce member ends or as required by determinations made as specified in paragraph (a)(3)(ii)(b).","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"164_308_a_4_ii_a": {"name": "164.308(a)(4)(ii)(A) Isolating health care clearinghouse functions","checks": {"elb_ssl_listeners": "FAIL","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","rds_instance_backup_enabled": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"acm_certificates_expiration_check": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","redshift_cluster_automated_snapshot": null,"cloudfront_distributions_https_enabled": null,"rds_instance_integration_cloudwatch_logs": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"eks_cluster_kms_cmk_encryption_in_secrets_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_4_ii_a","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "If a health care clearinghouse is part of a larger organization, the clearinghouse must implement policies and procedures that protect the electronic protected health information of the clearinghouse from unauthorized access by the larger organization.","checks_status": {"fail": 7,"pass": 5,"total": 25,"manual": 0}},"164_308_a_4_ii_b": {"name": "164.308(a)(4)(ii)(B) Access authorization","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_4_ii_b","Section": "164.308 Administrative Safeguards","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Implement policies and procedures for granting access to electronic protected health information, As one illustrative example, through access to a workstation, transaction, program, process, or other mechanism.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"164_308_a_4_ii_c": {"name": "164.308(a)(4)(ii)(B) Access authorization","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_password_policy_reuse_24": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_4_ii_c","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement policies and procedures that, based upon the covered entity's or the business associate's access authorization policies, establish, document, review, and modify a user's right of access to a workstation, transaction, program, or process.","checks_status": {"fail": 1,"pass": 0,"total": 9,"manual": 0}},"164_308_a_5_ii_b": {"name": "164.308(a)(5)(ii)(B) Protection from malicious software","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_5_ii_b","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Procedures for guarding against, detecting, and reporting malicious software.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"164_308_a_5_ii_c": {"name": "164.308(a)(5)(ii)(C) Log-in monitoring","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudwatch_log_metric_filter_authentication_failures": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_5_ii_c","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Procedures for monitoring log-in attempts and reporting discrepancies.","checks_status": {"fail": 0,"pass": 2,"total": 3,"manual": 0}},"164_308_a_5_ii_d": {"name": "164.308(a)(5)(ii)(D) Password management","checks": {"iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "164_308_a_5_ii_d","Section": "164.308 Administrative Safeguards","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Procedures for creating, changing, and safeguarding passwords.","checks_status": {"fail": 0,"pass": 0,"total": 9,"manual": 0}},"164_308_a_7_ii_a": {"name": "164.308(a)(7)(ii)(A) Data backup plan","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_7_ii_a","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establish and implement procedures to create and maintain retrievable exact copies of electronic protected health information.","checks_status": {"fail": 3,"pass": 1,"total": 10,"manual": 0}},"164_308_a_7_ii_b": {"name": "164.308(a)(7)(ii)(B) Disaster recovery plan","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_7_ii_b","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establish (and implement as needed) procedures to restore any loss of data.","checks_status": {"fail": 3,"pass": 1,"total": 10,"manual": 0}},"164_308_a_7_ii_c": {"name": "164.308(a)(7)(ii)(C) Emergency mode operation plan","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "164_308_a_7_ii_c","Section": "164.308 Administrative Safeguards","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establish (and implement as needed) procedures to enable continuation of critical business processes for protection of the security of electronic protected health information while operating in emergency mode.","checks_status": {"fail": 3,"pass": 1,"total": 10,"manual": 0}}},"requirements_passed": 11,"requirements_failed": 21,"requirements_manual": 0,"total_requirements": 32,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "6a808cc7-3501-4085-98f9-e4a9fa251f4c","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "mitre_attack_aws","framework": "MITRE-ATTACK","version": "","description": "MITRE ATT&CKĀ® is a globally-accessible knowledge base of adversary tactics and techniques based on real-world observations. The ATT&CK knowledge base is used as a foundation for the development of specific threat models and methodologies in the private sector, in government, and in the cybersecurity product and service community.","region": "eu-west-1","requirements": {"T1040": {"name": "Network Sniffing","checks": {"elb_ssl_listeners": "FAIL","elbv2_ssl_listeners": "FAIL","iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_hardware_mfa_enabled": null,"rds_instance_transport_encrypted": "FAIL","acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL","config_recorder_all_regions_enabled": null,"iam_user_mfa_enabled_console_access": null,"cloudfront_distributions_https_enabled": null,"iam_policy_allows_privilege_escalation": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","iam_inline_policy_no_administrative_privileges": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "AWS CloudWatch uses TLS/SSL connections to communicate with other AWS resources which protects against network sniffing attacks. As a result, this mapping is given a score of Significant.","Category": "Protect","AWSService": "AWS CloudWatch"},{"Value": "Significant","Comment": "AWS RDS and AWS RDS Proxy support TLS/SSL connections to database instances which protects against network sniffing attacks. As a result, this mapping is given a score of Significant.","Category": "Protect","AWSService": "AWS RDS"},{"Value": "Significant","Comment": "The VPC service's support for the AWS Virtual Private Network (VPN) can be used to encrypt traffic traversing over untrusted networks which can prevent information from being gathered via network sniffing.","Category": "Protect","AWSService": "Amazon Virtual Private Cloud"},{"Value": "Partial","Comment": "The following AWS IoT Device Defender audit checks and corresponding mitigation actions can identify and resolve configuration problems that should be fixed in order to ensure SSL/TLS encryption is enabled and secure to protect network traffic to/from IoT devices: 'CA certificate expiring' ('CA_CERTIFICATE_EXPIRING_CHECK' in the CLI and API), 'CA certificate key quality' ('CA_CERTIFICATE_KEY_QUALITY_CHECK' in the CLI and API), and 'CA certificate revoked but device certificates still active' ('REVOKED_CA_CERTIFICATE_STILL_ACTIVE_CHECK' in the CLI and API) can identify problems with certificate authority (CA) certificates being used for signing and support the 'UPDATE_CA_CERTIFICATE' mitigation action which can resolve them. 'Device certificate expiring' ('DEVICE_CERTIFICATE_EXPIRING_CHECK' in the CLI and API), 'Device certificate key quality' ('DEVICE_CERTIFICATE_KEY_QUALITY_CHECK' in the CLI and API), 'Device certificate shared' ('DEVICE_CERTIFICATE_SHARED_CHECK' in the CLI and API), and 'Revoked device certificate still active' ('REVOKED_DEVICE_CERTIFICATE_STILL_ACTIVE_CHECK' in the CLI and API) can identify problems with IoT devices' certificates and support the 'UPDATE_DEVICE_CERTIFICATE' and 'ADD_THINGS_TO_THING_GROUP' mitigation actions which can resolve them. Coverage factor is partial for these checks and mitigations, since they are specific to IoT device communication and can only mitigate behavior for adversaries who are unable to decrypt the relevant traffic, resulting in an overall score of Partial.","Category": "Protect","AWSService": "AWS IoT Device Defender"},{"Value": "Partial","Comment": "The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure SSL/TLS encryption is enabled to protect network traffic: 'acm-certificate-expiration-check' for nearly expired certificates in AWS Certificate Manager (ACM); 'alb-http-to-https-redirection-check' for Application Load Balancer (ALB) HTTP listeners; 'api-gw-ssl-enabled' for API Gateway REST API stages; 'cloudfront-custom-ssl-certificate', 'cloudfront-sni-enabled', and 'cloudfront-viewer-policy-https', for Amazon CloudFront distributions; 'elb-acm-certificate-required', 'elb-custom-security-policy-ssl-check', 'elb-predefined-security-policy-ssl-check', and 'elb-tls-https-listeners-only' for Elastic Load Balancing (ELB) Classic Load Balancer listeners; 'redshift-require-tls-ssl' for Amazon Redshift cluster connections to SQL clients; 's3-bucket-ssl-requests-only' for requests for S3 bucket contents; and 'elasticsearch-node-to-node-encryption-check' for Amazon ElasticSearch Service node-to-node communications. The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure that private traffic is routed securely and only within VPCs rather than on the public Internet: 'api-gw-endpoint-type-check' for Amazon API Gateway APIs, 'elasticsearch-in-vpc-only' for Amazon ElasticSearch Service domains, and 'redshift-enhanced-vpc-routing-enabled' for Amazon Redshift cluster traffic. All of these are run on configuration changes except 'alb-http-to-https-redirection-check' and 'elasticsearch-in-vpc-only', which are run periodically. Coverage factor is partial for these rules, since they are specific to a subset of the available AWS services and can only mitigate behavior for adversaries who are unable to decrypt the relevant traffic and/or do not have access to traffic within the relevant VPCs, resulting in an overall score of Partial.","Category": "Protect","AWSService": "AWS Config"}],"description": "Adversaries may sniff network traffic to capture information about an environment, including authentication material passed over the network. Network sniffing refers to using the network interface on a system to monitor or capture information sent over a wired or wireless connection. An adversary may place a network interface into promiscuous mode to passively access data in transit over the network, or use span ports to capture a larger amount of data.","checks_status": {"fail": 5,"pass": 1,"total": 17,"manual": 0}},"T1046": {"name": "Network Service Discovery","checks": {"guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","elbv2_waf_acl_attached": "FAIL","networkfirewall_in_all_vpc": "FAIL","inspector2_active_findings_exist": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Value": "Partial","Comment": "The following AWS IoT Device Defender device-side detection metrics can detect indicators that an adversary may be leveraging compromised AWS IoT devices to search their networks for other hosts and their running services, possibly to subsequently carry out lateral movement techniques: 'Destination IPs' ('aws:destination-ip-addresses') outside of expected IP address ranges may suggest that a device is communicating with unexpected devices. 'Bytes in' ('aws:all-bytes-in'), 'Bytes out' ('aws:all-bytes-out'), 'Packets in' ('aws:all-packets-in'), and 'Packets out' ('aws:all-packets-out') values outside of expected norms may indicate that the device is sending and/or receiving non-standard traffic, which may traffic used to discover other hosts/services. 'Listening TCP ports' ('aws:listening-tcp-ports'), 'Listening TCP port count' ('aws:num-listening-tcp-ports'), 'Established TCP connections count' ('aws:num-established-tcp-connections'), 'Listening UDP ports' ('aws:listening-udp-ports'), and 'Listening UDP port count' ('aws:num-listening-udp-ports') values outside of expected norms may indicate that devices are communicating via unexpected ports/protocols that may suggest scanning is taking place. Coverage factor is partial, since these metrics are limited to IoT device communication and detection is only based on network traffic, resulting in an overall score of Partial.","Category": "Detect","AWSService": "AWS IoT Device Defender"},{"Value": "Partial","Comment": "AWS Network Firewall has the ability to pass, drop, or alert on traffic based on the network protocol as well as perform deep packet inspection on the payload. This functionality can be used to restrict access to the endpoints within the virtual private cloud and protect against network service scanning. This mapping is given a score of Partial because it only protects against network service scanning attacks that originate from outside the firewall and not from within network protected by the firewall.","Category": "Protect","AWSService": "AWS Network Firewall"},{"Value": "Partial","Comment": "AWS WAF protects against bots that run scans against web applications such as Nessus (vulnerability assessments) and Nmap (IP address and port scans) among others. AWS WAF does this by blocking malicious traffic that indicate bad bots such as those listed above (e.g., via User-Agent values). AWS WAF uses the following rule sets to provide this protection. AWSManagedRulesCommonRuleSet AWSManagedRulesBotControlRuleSet. This is scored as Partial because the rule sets, while they block malicious traffic in near real-time, only protect web applications against scans performed by bots.","Category": "Protect","AWSService": "AWS Web Application Firewall"},{"Value": "Partial","Comment": "The following GuardDuty finding types reflect flagged events where there is an attempt to get a list of services running on a remote host. Recon:EC2/PortProbeEMRUnprotectedPort Recon:EC2/PortProbeUnprotectedPort Recon:EC2/Portscan Impact:EC2/PortSweep","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Partial","Comment": "The Amazon Inspector Network Reachability assessment package can assess whether or not cloud/network components are vulnerable (e.g., publicly accessible from the Internet). Amazon Inspector does not directly protect cloud/network components rather reports on vulnerabilities that it identifies which can then be used to securely configure the cloud/network components. Due to this, the score is capped at Partial.","Category": "Protect","AWSService": "Amazon Inspector"},{"Value": "Significant","Comment": "VPC security groups and network access control lists (NACLs) can filter both internal and external network traffic and therefore, can mitigate unauthorized network service scanning.","Category": "Protect","AWSService": "Amazon Virtual Private Cloud"}],"description": "Adversaries may attempt to get a listing of services running on remote hosts and local network infrastructure devices, including those that may be vulnerable to remote software exploitation. Common methods to acquire this information include port and/or vulnerability scans using tools that are brought onto a system.","checks_status": {"fail": 7,"pass": 16,"total": 23,"manual": 0}},"T1048": {"name": "Exfiltration Over Alternative Protocol","checks": {"guardduty_is_enabled": "PASS","networkfirewall_in_all_vpc": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Value": "Partial","Comment": "AWS Network Firewall has the ability to pass, drop, or alert on traffic based on the network protocol as well as perform deep packet inspection on the payload. This functionality can be used to block adversaries from accessing resources from which to exfiltrate data as well as prevent resources from communicating with known-bad IP addresses and domains that might be used to receive exfiltrated data. This mapping is given a score of Partial because the known-bad IP addresses and domains would need to be known in advance and AWS Network Firewall wouldn't have deep packet inspection visibility into encrypted non-C2 protocols.","Category": "Protect","AWSService": "AWS Network Firewall"},{"Value": "Partial","Comment": "The following GuardDuty finding type flags events where adversaries may steal data by exfiltrating it over a different protocol than that of the existing command-and-control channel. Trojan:EC2/DNSDataExfiltration Behavior:EC2/TrafficVolumeUnusual.","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Partial","Comment": "This control provides partial coverage for this technique and all of its sub-techniques, resulting in an overall score of Partial.","Category": "Detect","AWSService": "AWS IoT Device Defender"},{"Value": "Partial","Comment": "VPC security groups and network access control lists (NACLs) can limit access to external hosts and can therefore provide mitigation of this technique. For environments where Internet access is required, these controls can be used to block known malicious addresses. Because this latter protection is limited to known malicious endpoints, it provides Partial coverage resulting in an overall Partial score.","Category": "Protect","AWSService": "Amazon Virtual Private Cloud"}],"description": "Adversaries may steal data by exfiltrating it over a different protocol than that of the existing command and control channel. The data may also be sent to an alternate network location from the main command and control server.","checks_status": {"fail": 4,"pass": 16,"total": 20,"manual": 0}},"T1049": {"name": "System Network Connections Discovery","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may attempt to get a listing of network connections to or from the compromised system they are currently accessing or from remote systems by querying for information over the network.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1059": {"name": "Command and Scripting Interpreter","checks": {"elbv2_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Value": "Partial","Comment": "The AWS WAF protects web applications from injection attacks that leverage command and scripting interpreters. AWS WAF provides this protection via the following rule sets that block malicious traffic across a variety of operating systems and applications. AWSManagedRulesCommonRuleSet AWSManagedRulesSQLiRuleSet AWSManagedRulesUnixRuleSet AWSManagedRulesWindowsRuleSet AWSManagedRulesPHPRuleSet AWSManagedRulesWordPressRuleSet. This is given a score of Partial (instead of Minimal) because while it only protects against a subset of SubTechniques (3 out of 8), it does provide protections for command and scripting interpreters that do not have SubTechniques (SQL, PHP, etc.). Furthermore, it blocks the malicious content in near real-time.","Category": "Protect","AWSService": "AWS Web Application Firewall"}],"description": "Adversaries may abuse command and script interpreters to execute commands, scripts, or binaries. These interfaces and languages provide ways of interacting with computer systems and are a common feature across many different platforms. Most systems come with some built-in command-line interface and scripting capabilities, for example, macOS and Linux distributions include some flavor of Unix Shell while Windows installations include the Windows Command Shell and PowerShell.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"T1069": {"name": "Permission Groups Discovery","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may attempt to discover group and permission settings. This information can help adversaries determine which user accounts and groups are available, the membership of users in particular groups, and which users and groups have elevated permissions.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1074": {"name": "Data from Cloud Storage","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may stage collected data in a central location or directory prior to Exfiltration. Data may be kept in separate files or combined into one file through techniques such as Archive Collected Data. Interactive command shells may be used, and common functionality within cmd and bash may be used to copy data into a staging location.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1078": {"name": "Valid Accounts","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_avoid_root_usage": null,"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_hardware_mfa_enabled": null,"iam_user_console_access_unused": null,"iam_user_two_active_access_key": null,"iam_policy_no_full_access_to_kms": null,"iam_administrator_access_with_mfa": null,"config_recorder_all_regions_enabled": null,"iam_user_mfa_enabled_console_access": null,"iam_user_no_setup_initial_access_key": null,"organizations_scp_check_deny_regions": null,"iam_password_policy_minimum_length_14": null,"iam_policy_allows_privilege_escalation": null,"organizations_delegated_administrators": null,"iam_policy_no_full_access_to_cloudtrail": null,"iam_no_expired_server_certificates_stored": null,"organizations_account_part_of_organizations": null,"iam_role_cross_account_readonlyaccess_policy": null,"iam_inline_policy_no_administrative_privileges": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_role_cross_service_confused_deputy_prevention": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"iam_customer_unattached_policy_no_administrative_privileges": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Value": "Partial","Comment": "GuardDuty implements a finding that flags occurrences unattended behavior from an IAM User in the Account. PenTest:IAMUser/KaliLinux, PenTest:IAMUser/ParrotLinux, PenTest:IAMUser/PentooLinux, Policy:IAMUser/RootCredentialUsage, PrivilegeEscalation:IAMUser/AdministrativePermissions, UnauthorizedAccess:IAMUser/ConsoleLogin, UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B, UnauthorizedAccess:IAMUser/MaliciousIPCaller, UnauthorizedAccess:IAMUser/MaliciousIPCaller.Custom, UnauthorizedAccess:IAMUser/TorIPCaller, Policy:S3/AccountBlockPublicAccessDisabled, Policy:S3/BucketAnonymousAccessGranted, Policy:S3/BucketBlockPublicAccessDisabled, Policy:S3/BucketPublicAccessGranted, CredentialAccess:IAMUser/AnomalousBehavior, DefenseEvasion:IAMUser/AnomalousBehavior, Discovery:IAMUser/AnomalousBehavior, Exfiltration:IAMUser/AnomalousBehavior, Impact:IAMUser/AnomalousBehavior, Persistence:IAMUser/AnomalousBehavior, Recon:IAMUser/MaliciousIPCaller, Recon:IAMUser/MaliciousIPCaller.Custom, UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Minimal","Comment": "This control provides significant coverage for one of this technique's SubTechniques, resulting in an overall score of Minimal.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Partial","Comment": "This control provides detection capability for one of this technique's SubTechniques and some of its procedure examples resulting in an overall Partial protection score.","Category": "Detect","AWSService": "AWS IAM"},{"Value": "Partial","Comment": "This control provides protection capability for one of this technique's SubTechniques and some of its procedure examples resulting in an overall Partial protection score.","Category": "Protect","AWSService": "AWS IAM"},{"Value": "Partial","Comment": "This control provides protection capability for one of this technique's SubTechniques and some of its procedure examples resulting in an overall Partial protection score.","Category": "Protect","AWSService": "AWS Single Sign-On"},{"Value": "Minimal","Comment": "This control provides partial detection capability for one of this technique's SubTechniques and a few of its procedure examples resulting in an overall Minimal protection score.","Category": "Detect","AWSService": "AWS IoT Device Defender"},{"Value": "Minimal","Comment": "This control provides partial protection for one of this technique's SubTechniques and a few of its procedure examples resulting in an overall Minimal protection score.","Category": "Protect","AWSService": "AWS IoT Device Defender"},{"Value": "Partial","Comment": "This control may protect against malicious use of cloud accounts but may not mitigate exploitation of local, domain, or default accounts present within deployed resources.","Category": "Protect","AWSService": "AWS Organizations"},{"Value": "Minimal","Comment": "AWS Security Hub detects suspicious activity by AWS accounts which could indicate valid accounts being leveraged by an adversary. AWS Security Hub provides these detections with the following managed insights. AWS principals with suspicious access key activity Credentials that may have leaked AWS resources with unauthorized access attempts IAM users with suspicious activity. AWS Security Hub also performs checks from the AWS Foundations CIS Benchmark and PCI-DSS security standard that, if implemented, would help towards detecting the misuse of valid accounts. AWS Security Hub provides these detections with the following checks. 3.1 Ensure a log metric filter and alarm exist for unauthorized API calls 3.2 Ensure a log metric filter and alarm exist for Management Console sign-in without MFA 3.3 Ensure a log metric filter and alarm exist for usage of root account 3.4 Ensure a log metric filter and alarm exist for IAM policy changes 3.6 Ensure a log metric filter and alarm exist for AWS Management Console authentication failures [PCI.CW.1] A log metric filter and alarm should exist for usage of the root user. By monitoring the root account, activity where accounts make unauthorized API calls, and changes to IAM permissions among other things, it may be possible to detect valid accounts that are being misused and are potentially compromised. This is scored as Minimal because it only supports a subset of the SubTechniques (1 of 4).","Category": "Detect","AWSService": "AWS Security Hub"},{"Value": "Minimal","Comment": "This control provides partial protection for one of this technique's SubTechniques and a few of its procedure examples resulting in an overall Minimal protection score.","Category": "Protect","AWSService": "Amazon Cognito"}],"description": "Adversaries may obtain and abuse credentials of existing accounts as a means of gaining Initial Access, Persistence, Privilege Escalation, or Defense Evasion. Compromised credentials may be used to bypass access controls placed on various resources on systems within the network and may even be used for persistent access to remote systems and externally available services, such as VPNs, Outlook Web Access, network devices, and remote desktop.[1] Compromised credentials may also grant an adversary increased privilege to specific systems or access to restricted areas of the network. Adversaries may choose not to use malware or tools in conjunction with the legitimate access those credentials provide to make it harder to detect their presence.","checks_status": {"fail": 0,"pass": 2,"total": 36,"manual": 0}},"T1082": {"name": "System Information Discovery","checks": {},"status": "PASS","attributes": [],"description": "An adversary may attempt to get detailed information about the operating system and hardware, including version, patches, hotfixes, service packs, and architecture. Adversaries may use the information from System Information Discovery during automated discovery to shape follow-on behaviors, including whether or not the adversary fully infects the target and/or attempts specific actions.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1087": {"name": "Account Discovery","checks": {"organizations_account_part_of_organizations": null},"status": "PASS","attributes": [{"Value": "Minimal","Comment": "This control may protect against cloud account discovery but does not mitigate against other forms of account discovery.","Category": "Protect","AWSService": "AWS Organizations"}],"description": "Adversaries may attempt to get a listing of valid accounts, usernames, or email addresses on a system or within a compromised environment. This information can help adversaries determine which accounts exist, which can aid in follow-on behavior such as brute-forcing, spear-phishing attacks, or account takeovers (e.g., Valid Accounts).","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"T1098": {"name": "Account Manipulation","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_avoid_root_usage": null,"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_hardware_mfa_enabled": null,"iam_policy_no_full_access_to_kms": null,"iam_administrator_access_with_mfa": null,"config_recorder_all_regions_enabled": null,"iam_user_mfa_enabled_console_access": null,"iam_policy_allows_privilege_escalation": null,"iam_policy_no_full_access_to_cloudtrail": null,"iam_inline_policy_no_administrative_privileges": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Value": "Minimal","Comment": "This control provides significant coverage for one of this technique's SubTechniques, resulting in an overall score of Minimal.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Minimal","Comment": "This control may generate logs for creation and manipulation of accounts but the relevant security information would be handled by another security control.","Category": "Detect","AWSService": "AWS IAM"},{"Value": "Minimal","Comment": "AWS Security Hub performs a check from the AWS Foundations CIS Benchmark that, if implemented, would help towards detecting the manipulation of accounts. AWS Security Hub provides this detection with the following check. 3.4 Ensure a log metric filter and alarm exist for IAM policy changes. This is scored as Minimal because it only supports a subset of the SubTechniques (1 of 4).","Category": "Detect","AWSService": "AWS Security Hub"},{"Value": "Partial","Comment": "GuardDuty has a finding types that flag events where an adversary may have compromised an AWS IAM User. Finding Type: Persistence:IAMUser/AnomalousBehavior.","Category": "Detect","AWSService": "Amazon GuardDuty"}],"description": "Adversaries may manipulate accounts to maintain access to victim systems. Account manipulation may consist of any action that preserves adversary access to a compromised account, such as modifying credentials or permission groups. These actions could also include account activity designed to subvert security policies, such as performing iterative password updates to bypass password duration policies and preserve the life of compromised credentials.","checks_status": {"fail": 0,"pass": 2,"total": 16,"manual": 0}},"T1110": {"name": "Brute Force","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_root_mfa_enabled": null,"inspector2_is_enabled": "FAIL","iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_hardware_mfa_enabled": null,"iam_user_console_access_unused": null,"inspector2_active_findings_exist": "FAIL","config_recorder_all_regions_enabled": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "This control provides significant coverage for all of this technique's sub-techniques, resulting in an overall score of Significant.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Significant","Comment": "This control provides significant coverage for all of this technique's sub-techniques, resulting in an overall score of Significant.","Category": "Protect","AWSService": "AWS IAM"},{"Value": "Partial","Comment": "This control may not provide any mitigation against password cracking.","Category": "Protect","AWSService": "AWS Single Sign-On"},{"Value": "Significant","Comment": "Amazon Cognito's MFA capability provides significant protection against password compromises, requiring the adversary to complete an additional authentication method before their access is permitted.","Category": "Protect","AWSService": "Amazon Cognito"},{"Value": "Minimal","Comment": "AWS Security Hub performs a check from the AWS Foundations CIS Benchmark that, if implemented, would help towards detecting the brute forcing of accounts. AWS Security Hub provides this detection with the following checks. 3.6 Ensure a log metric filter and alarm exist for AWS Management Console authentication failures. This is scored as Minimal because it only applies to the AWS Management Console and not other access mechanisms (e.g., CLI, SDK, etc.) and it only supports a subset of the sub-techniques (3 of 4). Furthermore, it does not detect brute-forcing methods for other components such as EC2 instances.","Category": "Detect","AWSService": "AWS Security Hub"},{"Value": "Minimal","Comment": "Finding types such as UnauthorizedAccess:EC2/RDPBruteForce, UnauthorizedAccess:EC2/SSHBruteForce, Impact:EC2/WinRMBruteForce, and Stealth:IAMUser/PasswordPolicyChange can detect when an EC2 instance may be involved in a brute force attack aimed at obtaining passwords. Due to the detection being limited to a specific set of application protocols, its coverage is Minimal resulting in a Minimal score.","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Minimal","Comment": "The Amazon Inspector Best Practices assessment package can detect security control settings related to authentication and password policies on Linux endpoints. Specific security controls it can assess include 'Disable password authentication over SSH', 'Configure password maximum age', 'Configure password minimum length', and 'Configure password complexity' all of which impact the ability to brute force a password. This information can be used identify insecure configurations and harden the endpoints. Amazon Inspector does not directly protect against brute force attacks. Given Amazon Inspector can only assess these security controls on Linux platforms (although it also supports Windows), the coverage score is Minimal leading to an overall Minimal score.","Category": "Protect","AWSService": "Amazon Inspector"}],"description": "Adversaries may use brute force techniques to gain access to accounts when passwords are unknown or when password hashes are obtained. Without knowledge of the password for an account or set of accounts, an adversary may systematically guess the password using a repetitive or iterative mechanism. Brute forcing passwords can take place via interaction with a service that will check the validity of those credentials or offline against previously acquired credential data, such as password hashes.","checks_status": {"fail": 2,"pass": 2,"total": 19,"manual": 0}},"T1119": {"name": "Automated Collection","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","ec2_ebs_snapshots_encrypted": "FAIL","s3_bucket_default_encryption": "PASS","rds_instance_storage_encrypted": "FAIL","config_recorder_all_regions_enabled": null},"status": "FAIL","attributes": [{"Value": "Minimal","Comment": "The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure that storage volumes are encrypted, which may mitigate adversary attempts to automate collection within cloud environments: 'ec2-ebs-encryption-by-default' which is run periodically and 'encrypted-volumes' which is run on configuration changes. Coverage factor is minimal for these rules, since they are specific to EBS volumes and will only prevent certain forms of collection since adversaries with access to mounted volumes may be able to decrypt their contents, resulting in an overall score of Minimal.","Category": "Protect","AWSService": "AWS Config"}],"description": "Once established within a system or network, an adversary may use automated techniques for collecting internal data. Methods for performing this technique could include use of a Command and Scripting Interpreter to search for and copy information fitting set criteria such as file type, location, or name at specific time intervals. In cloud-based environments, adversaries may also use cloud APIs, command line interfaces, or extract, transform, and load (ETL) services to automatically collect data. This functionality could also be built into remote access tools.","checks_status": {"fail": 2,"pass": 3,"total": 6,"manual": 0}},"T1136": {"name": "Create Account","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Value": "Minimal","Comment": "This control provides partial coverage for one of this technique's SubTechniques, resulting in an overall score of Minimal.","Category": "Protect","AWSService": "AWS Config"}],"description": "Adversaries may create an account to maintain access to victim systems. With a sufficient level of access, creating such accounts may be used to establish secondary credentialed access that do not require persistent remote access tools to be deployed on the system.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"T1190": {"name": "Exploit Public-Facing Application","checks": {"drs_job_exist": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","rds_instance_backup_enabled": "PASS","inspector2_active_findings_exist": "FAIL","config_recorder_all_regions_enabled": null,"awslambda_function_not_publicly_accessible": "PASS","rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "AWS CloudEndure Disaster Recovery enables the replication and recovery of servers into AWS Cloud. In the event that a public-facing application or server is compromised, AWS CloudEndure can be used to provision an instance of the server from a previous point in time within minutes. As a result, this mapping is given a score of Significant.","Category": "Respond","AWSService": "AWS CloudEndure Disaster Recovery"},{"Value": "Partial","Comment": "The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure that applications intended for internal use cannot be accessed externally for exploitation: 'api-gw-endpoint-type-check' can ensure that Amazon API Gateway APIs are private and can only be accessed from within VPCs, 'elasticsearch-in-vpc-only' can ensure that Amazon ElasticSearch Service (Amazon ES) domains are in the same VPC and the domain endpoint is not public, 'lambda-function-public-access-prohibited' can verify that AWS Lambda functions are not publicly available, and 'ec2-instance-no-public-ip' can verify whether EC2 instances have public IP addresses. The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure that insecure applications are not installed and installed packages are kept updated, reducing the likelihood of adversary exploitation: the 'ec2-managedinstance-applications-blacklisted' managed rule verifies that a pre-defined list of applications are not installed on specified managed instances. It can be used to identify the presence of vulnerable applications (prompting removal before they can be exploited) and/or to identify the presence of allowed packages below a minimum version (prompting updates before they can be exploited). The 'ec2-managedinstance-platform-check' managed rule verifies that managed instances are running desired platform types, including using a desired version (as opposed to an out-of-date one). Both can reduce instances' attack surface for adversary exploitation. 'rds-automatic-minor-version-upgrade-enabled' can verify that Amazon RDS is being patched, and 'elastic-beanstalk-managed-updates-enabled' can verify that Elastic Beanstalk is being patched. Coverage factor is partial for these rules, since they are specific to a subset of the available AWS services that can be used to host public-facing applications and will only protect against certain forms of identifiable exploitation, resulting in an overall score of Partial.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Partial","Comment": "AWS RDS supports the automatic patching of minor versions of database instances. This can result in security flaws in the database instances being fixed before they can be exploited. This mapping is given a score of Partial because it does not protect against misconfigured database instances which may be susceptible to exploitation.","Category": "Protect","AWSService": "AWS RDS"},{"Value": "Significant","Comment": "AWS RDS supports the replication and recovery of database instances. In the event that a database instance is compromised, AWS RDS can be used to restore the database instance to a previous point in time. As a result, this mapping is given a score of Significant.","Category": "Respond","AWSService": "AWS RDS"},{"Value": "Minimal","Comment": "There is a GuardDuty finding type that captures when vulnerable publicly facing resources are leveraged to capture data not intended to be viewable (e.g., IAM credentials associated with the resource). UnauthorizedAccess:EC2/MetadataDNSRebind - This finding type only detects MetadataDNSRebind and is more focused on the EC2 instance and not the application running on the instance itself resulting in Minimal coverage.","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Partial","Comment": "AWS Security Hub reports on EC2 instances that are missing security patches for vulnerabilities which could enable an adversary to exploit vulnerabilities through the attack lifecycle. AWS Security Hub provides this detection with the following managed insight. EC2 instances that have missing security patches for important vulnerabilities. This is scored as Partial because the checks associated with Security Hub would only report on missing patches for known vulnerabilities. It doesn't not cover zero-day vulnerabilities.","Category": "Detect","AWSService": "AWS Security Hub"},{"Value": "Significant","Comment": "The AWS WAF protects public-facing applications against a range of vulnerabilities including those listed in the OWASP Top 10. AWS WAF provides this protection via the following rule sets that block malicious traffic across a variety of operating systems and applications. AWSManagedRulesCommonRuleSet AWSManagedRulesKnownBadInputRuleSet AWSManagedRulesSQLiRuleSet AWSManagedRulesLinuxRuleSet AWSManagedRulesUnixRuleSet AWSManagedRulesWindowsRuleSet AWSManagedRulesPHPRuleSet AWSManagedRulesWordPressRuleSet. This is given a score of Significant because it protects against vulnerabilities across multiple operating systems (Windows, Linux, POSIX) and technologies (JavaScript, SQL, PHP, WordPress). Furthermore, it blocks the malicious content in near real-time.","Category": "Protect","AWSService": "AWS Web Application Firewall"},{"Value": "Partial","Comment": "Amazon Inspector can detect known vulnerabilities on various Windows and Linux endpoints. Furthermore, the Amazon Inspector Best Practices assessment package can assess security controls for 'Enable Address Space Layout Randomization (ASLR)' and 'Enable Data Execution Prevention (DEP)' that makes it more difficult for an attacker to exploit vulnerabilities in software. This information can be used to patch, isolate, and remove vulnerable software and endpoints. Amazon Inspector does not directly protect against exploitation and it is not effective against zero-day attacks, vulnerabilities with no available patch, and software that may not be analyzed by the scanner. As a result, the score is capped at Partial.","Category": "Protect","AWSService": "Amazon Inspector"}],"description": "Adversaries may attempt to exploit a weakness in an Internet-facing host or system to initially access a network. The weakness in the system can be a software bug, a temporary glitch, or a misconfiguration.","checks_status": {"fail": 5,"pass": 5,"total": 11,"manual": 0}},"T1199": {"name": "Trusted Relationship","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Value": "Partial","Comment": "VPC network access control lists (NACLs) can isolate portions of the network that do not require network-wide access, limiting some attackers that leverage trusted relationships such as remote access for vendor maintenance. Coverage partial, Temporal Immediate.","Category": "Protect","AWSService": "Amazon Virtual Private Cloud"}],"description": "Adversaries may breach or otherwise leverage organizations who have access to intended victims. Access through trusted third party relationship abuses an existing connection that may not be protected or receives less scrutiny than standard mechanisms of gaining access to a network.","checks_status": {"fail": 3,"pass": 15,"total": 18,"manual": 0}},"T1201": {"name": "Password Policy Discovery","checks": {"iam_policy_allows_privilege_escalation": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Value": "Significant","Comment": "Ensure least privilege in IAM since password policies can be discovered in cloud environments using available APIs such as GetAccountPasswordPolicy in AWS.","Category": "Protect","AWSService": "AWS IAM"}],"description": "Adversaries may attempt to access detailed information about the password policy used within an enterprise network or cloud environment. Password policies are a way to enforce complex passwords that are difficult to guess or crack through Brute Force. This information may help the adversary to create a list of common passwords and launch dictionary and/or brute force attacks which adheres to the policy (e.g. if the minimum password length should be 8, then not trying passwords such as 'pass123'; not checking for more than 3-4 passwords per account if the lockout is set to 6 as to not lock out accounts).","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"T1204": {"name": "User Execution","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Value": "Minimal","Comment": "This control provides significant coverage for one of this technique's SubTechniques, resulting in an overall score of Minimal.","Category": "Detect","AWSService": "AWS Config"}],"description": "An adversary may rely upon specific actions by a user in order to gain execution. Users may be subjected to social engineering to get them to execute malicious code by, for example, opening a malicious document file or link. These user actions will typically be observed as follow-on behavior from forms of Phishing.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"T1213": {"name": "Data from Information Repositories","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may leverage information repositories to mine valuable information. Information repositories are tools that allow for storage of information, typically to facilitate collaboration or information sharing between users, and can store a wide variety of data that may aid adversaries in further objectives, or direct access to the target information. Adversaries may also abuse external sharing features to share sensitive documents with recipients outside of the organization.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1485": {"name": "Data Destruction","checks": {"drs_job_exist": "FAIL","backup_plans_exist": "PASS","s3_bucket_object_lock": "FAIL","efs_have_backup_enabled": "FAIL","s3_bucket_no_mfa_delete": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL","config_recorder_all_regions_enabled": null,"s3_bucket_policy_public_write_access": "PASS","cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "AWS CloudEndure Disaster Recovery enables the replication and recovery of servers into AWS Cloud. In the event that data on servers is destroyed, AWS CloudEndure can be used to provision an instance of the server from a previous point in time within minutes. As a result, this mapping is given a score of Significant.","Category": "Respond","AWSService": "AWS CloudEndure Disaster Recovery"},{"Value": "Partial","Comment": "The following AWS Config managed rules can identify configuration problems that should be fixed in order to prevent malicious write access to data within Amazon Simple Storage Service (S3) storage, which may include data destruction: 's3-bucket-blacklisted-actions-prohibited' checks whether bucket policies prohibit disallowed actions (including S3:DeleteObject) for principals from other AWS accounts, 's3-bucket-default-lock-enabled' checks whether a bucket that should be locked in write-once-read-many (WORM) mode is configured to prevent modification, and 's3-bucket-public-write-prohibited' checks whether a bucket is configured to allow public access and modification. All of these controls are run on configuration changes. The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure backups and redundancy are in place which can mitigate the effects of data destruction: 'aurora-mysql-backtracking-enabled' for data in Aurora MySQL; 'db-instance-backup-enabled' and 'rds-in-backup-plan' for Amazon Relational Database Service (RDS) data; 'dynamodb-in-backup-plan' and 'dynamodb-pitr-enabled' for Amazon DynamoDB table contents; 'ebs-in-backup-plan' for Elastic Block Store (EBS) volumes; 'efs-in-backup-plan' for Amazon Elastic File System (EFS) file systems; 'elasticache-redis-cluster-automatic-backup-check' for Amazon ElastiCache Redis cluster data; 'redshift-backup-enabled' and 'redshift-cluster-maintenancesettings-check' for Redshift; 's3-bucket-replication-enabled' and 's3-bucket-versioning-enabled' for S3 storage; and 'cloudfront-origin-failover-enabled' for CloudFront. The following AWS Config managed rules provide specific detections for configuration problems that should be fixed in order to prevent malicious deletion of specific data: 'elb-deletion-protection-enabled' for Elastic Block Store (EBS) volumes, and 'rds-cluster-deletion-protection-enabled' and 'rds-instance-deletion-protection-enabled' for RDS data. Coverage factor is partial for these rules, since they are specific to a subset of the available AWS services and will only protect certain types of data against destruction, resulting in an overall score of Partial.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Partial","Comment": "AWS RDS generates events for database instances and includes the following events that may indicate that an adversary has destroyed the database instance. RDS-EVENT-0003: The DB instance has been deleted RDS-EVENT-0041: A DB snapshot has been deleted. This mapping is given a score of Partial because it can't differentiate between an authorized and unauthorized deletion.","Category": "Detect","AWSService": "AWS RDS"},{"Value": "Significant","Comment": "AWS RDS provides deletion protection which prevents any user from deleting a database instance. If applied, the setting may mitigate attempts to delete a database instance. As a result, this mapping is given a score of Significant.","Category": "Protect","AWSService": "AWS RDS"},{"Value": "Significant","Comment": "AWS RDS supports the replication and recovery of database instances. In the event that a database instance is deleted, AWS RDS can be used to restore the database instance to a previous point in time. As a result, this mapping is given a score of Significant.","Category": "Respond","AWSService": "AWS RDS"},{"Value": "Significant","Comment": "AWS S3 may protect against data destruction through application of several best practices. Multi-factor authentication can be enabled for delete operations and for changing the versioning state of a bucket. Versioning can be enabled to revert objects to a previous state after malicious destruction or corruption. S3 Object Lock can help prevent objects from being deleted or overwritten for a fixed amount of time or indefinitely. In addition, S3 Cross Region Replication can be used to replicate S3 buckets to another AWS region for add protection.","Category": "Protect","AWSService": "AWS S3"},{"Value": "Minimal","Comment": "AWS Security Hub performs a check from the AWS Foundations CIS Benchmark that, if implemented, would help towards detecting the scheduled destruction of Customer Master Keys (CMKs) which are critical for being able to decrypt data. AWS Security Hub provides this detection with the following check. Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs. This is scored as Minimal because CMKs only represent one type of data that could be destroyed by an adversary.","Category": "Detect","AWSService": "AWS Security Hub"},{"Value": "Partial","Comment": "The following GuardDuty finding type flags events where adversaries may destroy data and files on specific systems or in large numbers on a network to interrupt availability to systems, services, and network resources. Impact:S3/MaliciousIPCaller, Impact:IAMUser/AnomalousBehavior Stealth:S3/ServerAccessLoggingDisabled UnauthorizedAccess:S3/MaliciousIPCaller.Custom UnauthorizedAccess:S3/TorIPCaller PenTest:S3/PentooLinux PenTest:S3/ParrotLinux PenTest:S3/KaliLinux.","Category": "Detect","AWSService": "Amazon GuardDuty"}],"description": "Adversaries may destroy data and files on specific systems or in large numbers on a network to interrupt availability to systems, services, and network resources. Data destruction is likely to render stored data irrecoverable by forensic techniques through overwriting files or data on local and remote drives.[1][2][3][4][5][6] Common operating system file deletion commands such as del and rm often only remove pointers to files without wiping the contents of the files themselves, making the files recoverable by proper forensic methodology. This behavior is distinct from Disk Content Wipe and Disk Structure Wipe because individual files are destroyed rather than sections of a storage disk or the disk's logical structure.","checks_status": {"fail": 6,"pass": 3,"total": 12,"manual": 0}},"T1486": {"name": "Data Encrypted for Impact","checks": {"drs_job_exist": "FAIL","backup_plans_exist": "PASS","s3_bucket_object_lock": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"config_recorder_all_regions_enabled": null,"s3_bucket_policy_public_write_access": "PASS"},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "AWS CloudEndure Disaster Recovery enables the replication and recovery of servers into AWS Cloud. In the event that data on servers is destroyed, AWS CloudEndure can be used to provision an instance of the server from a previous point in time within minutes. As a result, this mapping is given a score of Significant.","Category": "Respond","AWSService": "AWS CloudEndure Disaster Recovery"},{"Value": "Partial","Comment": "The following AWS Config managed rules can identify configuration problems that should be fixed in order to prevent malicious changes to data encryption within Amazon Simple Storage Service (S3) storage: 's3-bucket-blacklisted-actions-prohibited' checks whether bucket policies prohibit disallowed actions (including encryption configuration changes) for principals from other AWS accounts, 's3-bucket-default-lock-enabled' checks whether a bucket that should be locked in write-once-read-many (WORM) mode is configured to prevent modification, and 's3-bucket-public-write-prohibited' checks whether a bucket is configured to allow public access and modification. All of these controls are run on configuration changes. The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure backups and redundancy are in place which can mitigate the effects of malicious changes to data encryption: 'aurora-mysql-backtracking-enabled' for data in Aurora MySQL; 'db-instance-backup-enabled' and 'rds-in-backup-plan' for Amazon Relational Database Service (RDS) data; 'dynamodb-in-backup-plan' and 'dynamodb-pitr-enabled' for Amazon DynamoDB table contents; 'ebs-in-backup-plan' for Elastic Block Store (EBS) volumes; 'efs-in-backup-plan' for Amazon Elastic File System (EFS) file systems; 'elasticache-redis-cluster-automatic-backup-check' for Amazon ElastiCache Redis cluster data; 'redshift-backup-enabled' and 'redshift-cluster-maintenancesettings-check' for Redshift; 's3-bucket-replication-enabled' and 's3-bucket-versioning-enabled' for S3 storage; and 'cloudfront-origin-failover-enabled' for CloudFront. Coverage factor is partial for these rules, since they are specific to a subset of the available AWS services and will only protect certain types of data against malicious encryption changes, resulting in an overall score of Partial.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Significant","Comment": "AWS RDS supports the replication and recovery of database instances. In the event that a database instance is encrypted by an adversary (e.g., ransomware), AWS RDS can be used to restore the database instance to a previous point in time. As a result, this mapping is given a score of Significant.","Category": "Respond","AWSService": "AWS RDS"},{"Value": "Partial","Comment": "The following GuardDuty finding type flags events where adversaries may encrypt data on target systems or on large numbers of systems in a network to interrupt availability to system and network resources. Impact:S3/MaliciousIPCaller Stealth:S3/ServerAccessLoggingDisabled UnauthorizedAccess:S3/MaliciousIPCaller.Custom UnauthorizedAccess:S3/TorIPCaller PenTest:S3/PentooLinux PenTest:S3/ParrotLinux PenTest:S3/KaliLinux","Category": "Detect","AWSService": "Amazon GuardDuty"}],"description": "Adversaries may encrypt data on target systems or on large numbers of systems in a network to interrupt availability to system and network resources. They can attempt to render stored data inaccessible by encrypting files or data on local and remote drives and withholding access to a decryption key. This may be done in order to extract monetary compensation from a victim in exchange for decryption or a decryption key (ransomware) or to render data permanently inaccessible in cases where the key is not saved or transmitted.","checks_status": {"fail": 4,"pass": 3,"total": 9,"manual": 0}},"T1490": {"name": "Inhibit System Recovery","checks": {"drs_job_exist": "FAIL","rds_instance_backup_enabled": "PASS"},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "AWS CloudEndure Disaster Recovery enables the replication and recovery of servers into AWS Cloud. In the event that servers are defaced, AWS CloudEndure can be used to provision an instance of the server from a previous point in time within minutes. This mapping is given a score of Significant because it supports all of the sub-techniques (2 of 2).","Category": "Respond","AWSService": "AWS CloudEndure Disaster Recovery"},{"Value": "Partial","Comment": "AWS RDS generates events for database instances and includes the following event that may indicate that an adversary has attempted to inhibit system recovery. RDS-EVENT-0028: Automatic backups for this DB instance have been disabled. This mapping is given a score of Partial because it can't differentiate between an authorized and unauthorized disabling of automatic backups.","Category": "Detect","AWSService": "AWS RDS"},{"Value": "Significant","Comment": "AWS RDS supports the replication and recovery of database instances. In the event that a database instance is compromised and modified to disrupt recovery, AWS RDS can be used to restore the database instance to a previous point in time. As a result, this mapping is given a score of Significant.","Category": "Respond","AWSService": "AWS RDS"}],"description": "Adversaries may delete or remove built-in data and turn off services designed to aid in the recovery of a corrupted system to prevent recovery.[1][2] This may deny access to available backups and recovery options.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"T1491": {"name": "Defacement","checks": {"drs_job_exist": "FAIL","config_recorder_all_regions_enabled": null},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "AWS CloudEndure Disaster Recovery enables the replication and recovery of servers into AWS Cloud. In the event that servers are defaced, AWS CloudEndure can be used to provision an instance of the server from a previous point in time within minutes. This mapping is given a score of Significant because it supports all of the sub-techniques (2 of 2).","Category": "Respond","AWSService": "AWS CloudEndure Disaster Recovery"},{"Value": "Significant","Comment": "This control provides significant coverage for all of this technique's sub-techniques, resulting in an overall score of Significant.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Partial","Comment": "GuardDuty provides multiple finding types that flag malicious activity against resources. These findings focus on API calls that look suspicious and although they do not flag events such as Defacement specifically, it can be inferred that these findings can result in mitigating this technique's negative impact. With this assumption the score is capped at Partial.","Category": "Detect","AWSService": "Amazon GuardDuty"}],"description": "Adversaries may modify visual content available internally or externally to an enterprise network, thus affecting the integrity of the original content. Reasons for Defacement include delivering messaging, intimidation, or claiming (possibly false) credit for an intrusion. Disturbing or offensive images may be used as a part of Defacement in order to cause user discomfort, or to pressure compliance with accompanying messages.","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"T1496": {"name": "Resource Hijacking","checks": {"guardduty_is_enabled": "PASS","config_recorder_all_regions_enabled": null,"cloudwatch_log_metric_filter_root_usage": null,"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Value": "Partial","Comment": "AWS CloudWatch provides various metrics including CPU utilization, connections, disk space, memory, bytes sent/received, and the number of running containers among others. The following metrics (not an exhaustive list) could be used to detect if the usage of a resource has increased such as when an adversary hijacks a resource to perform intensive tasks. Linux/Mac OS ------------- cpu_time_active cpu_time_guest cpu_usage_active cpu_usage_guest disk_free disk_total disk_used ethtool_bw_in_allowance_exceeded ethtool_bw_out_allowance_exceeded ethtool_conntrack_allowance_exceeded mem_active mem_available_percent mem_free net_bytes_recv net_bytes_sent net_packets_sent net_packets_recv netstat_tcp_established netstat_tcp_listen processes_running processes_total swap_free swap_used. Containers ---------- CpuUtilized MemoryUtilized NetworkRxBytes NetworkTxBytes node_cpu_usage_total node_cpu_utilization node_filesystem_utilization node_memory_utilization. This mapping is given a score of Partial because it is not possible to differentiate between an authorized and unauthorized increase in resource utilization.","Category": "Detect","AWSService": "AWS CloudWatch"},{"Value": "Partial","Comment": "The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure alarms exist for spikes in resource utilization, which help to identify malicious use of resources within a cloud environment: 'cloudwatch-alarm-action-check', 'cloudwatch-alarm-resource-check', 'cloudwatch-alarm-settings-check', 'desired-instance-tenancy', 'desired-instance-type', 'dynamodb-autoscaling-enabled', 'dynamodb-throughput-limit-check', 'ec2-instance-detailed-monitoring-enabled', and 'rds-enhanced-monitoring-enabled'. Coverage factor is partial for these rules, since they are specific to a subset of the available AWS services and will only detect resource hijacking that results in a change in utilization that is significant enough to trigger alarms, resulting in an overall score of Partial.","Category": "Detect","AWSService": "AWS Config"},{"Value": "Partial","Comment": "The following AWS IoT Device Defender device-side detection metrics can detect indicators that an adversary may be leveraging compromised AWS IoT devices' resources to perform resource-intensive operations like mining cryptocurrency or performing denial of service attacks on other environments: 'Destination IPs' ('aws:destination-ip-addresses') outside of expected IP address ranges may suggest that a device is communicating with unexpected parties. 'Bytes in' ('aws:all-bytes-in'), 'Bytes out' ('aws:all-bytes-out'), 'Packets in' ('aws:all-packets-in'), and 'Packets out' ('aws:all-packets-out') values outside of expected norms may indicate that the device is sending and/or receiving non-standard traffic, which may include traffic related to resource hijacking activities. 'Listening TCP ports' ('aws:listening-tcp-ports'), 'Listening TCP port count' ('aws:num-listening-tcp-ports'), 'Established TCP connections count' ('aws:num-established-tcp-connections'), 'Listening UDP ports' ('aws:listening-udp-ports'), and 'Listening UDP port count' ('aws:num-listening-udp-ports') values outside of expected norms may indicate that devices are communicating via unexpected ports/protocols which may include traffic related to resource hijacking activities. Coverage factor is partial, since these metrics are limited to IoT device hijacking, resulting in an overall score of Partial.","Category": "Detect","AWSService": "AWS IoT Device Defender"},{"Value": "Partial","Comment": "The following GuardDuty finding types flag events where adversaries may leverage the resources of co-opted systems in order to solve resource intensive problems which may impact system and/or hosted service availability. CryptoCurrency:EC2/BitcoinTool.B CryptoCurrency:EC2/BitcoinTool.B!DNS Impact:EC2/BitcoinDomainRequest.Reputation UnauthorizedAccess:EC2/TorRelay","Category": "Detect","AWSService": "Amazon GuardDuty"}],"description": "Adversaries may leverage the resources of co-opted systems in order to solve resource intensive problems, which may impact system and/or hosted service availability.","checks_status": {"fail": 1,"pass": 1,"total": 18,"manual": 0}},"T1498": {"name": "Network Denial of Service","checks": {"guardduty_is_enabled": "PASS","networkfirewall_in_all_vpc": "FAIL","config_recorder_all_regions_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","shield_advanced_protection_in_global_accelerators": null,"shield_advanced_protection_in_route53_hosted_zones": null,"shield_advanced_protection_in_associated_elastic_ips": null,"shield_advanced_protection_in_classic_load_balancers": null,"shield_advanced_protection_in_cloudfront_distributions": null,"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","shield_advanced_protection_in_internet_facing_load_balancers": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Value": "Minimal","Comment": "This control provides minimal coverage for this technique's sub-techniques as well as its procedures, resulting in an overall score of Minimal.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Minimal","Comment": "AWS Network Firewall has the ability to pass, drop, or alert on traffic based on the network protocol as well as perform deep packet inspection on the payload. This functionality can be used to block the sources of smaller-scale network denial of service attacks. While AWS Network Firewall supports both all sub-techniques (2 of 2), this mapping is given a score of Minimal because often times it is necessary to block the traffic at an Internet Service Provider or Content Provider Network level.","Category": "Protect","AWSService": "AWS Network Firewall"},{"Value": "Significant","Comment": "AWS Shield is a service that protects against Distributed Denial of Service attacks. There are two tiers for this service Standard and Advanced. AWS Shield Standard defends against most common, frequently occurring network and transport (Layer 3 and 4 attacks) layer DDoS attacks that target your web site or applications. AWS Shield Advanced adds on to standard by providing additional detection and mitigation against large and sophisticated DDoS attacks. There is near real-time visibility into attacks. AWS Shield Advanced also comes with 24x7 access to the AWS DDoS Response Team (DRT).","Category": "Respond","AWSService": "AWS Shield"},{"Value": "Partial","Comment": "The following finding types in GuardDuty flag events where adversaries may perform Network Denial of Service (DoS) attacks to degrade or block the availability of targeted resources to users. Backdoor:EC2/DenialOfService.UdpOnTcpPorts Backdoor:EC2/DenialOfService.UnusualProtocol Backdoor:EC2/DenialOfService.Udp Backdoor:EC2/DenialOfService.Tcp Backdoor:EC2/DenialOfService.Dns","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Minimal","Comment": "VPC security groups and network access control lists (NACLs) can be used to restrict access to endpoints but will prove effective at mitigating only low-end DOS attacks resulting in a Minimal score.","Category": "Protect","AWSService": "Amazon Virtual Private Cloud"}],"description": "Adversaries may perform Network Denial of Service (DoS) attacks to degrade or block the availability of targeted resources to users. Network DoS can be performed by exhausting the network bandwidth services rely on. Example resources include specific websites, email services, DNS, and web-based applications. Adversaries have been observed conducting network DoS attacks for political purposes[1] and to support other malicious activities, including distraction[2], hacktivism, and extortion.","checks_status": {"fail": 4,"pass": 16,"total": 27,"manual": 0}},"T1499": {"name": "Endpoint Denial of Service","checks": {"networkfirewall_in_all_vpc": "FAIL","config_recorder_all_regions_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","shield_advanced_protection_in_global_accelerators": null,"shield_advanced_protection_in_route53_hosted_zones": null,"shield_advanced_protection_in_associated_elastic_ips": null,"shield_advanced_protection_in_classic_load_balancers": null,"shield_advanced_protection_in_cloudfront_distributions": null,"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","shield_advanced_protection_in_internet_facing_load_balancers": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "AWS Shield is a service that protects against Distributed Denial of Service attacks. There are two tiers for this service Standard and Advanced. AWS Shield Standard defends against most common, frequently occurring network and transport (Layer 3 and 4 attacks) layer DDoS attacks that target your web site or applications. AWS Shield Advanced adds on to standard by providing additional detection and mitigation against large and sophisticated DDoS attacks. There is near real-time visibility into attacks. AWS Shield Advanced also comes with 24x7 access to the AWS DDoS Response Team (DRT).","Category": "Respond","AWSService": "AWS Shield"},{"Value": "Minimal","Comment": "This control provides minimal coverage for this technique's sub-techniques as well as its procedures, resulting in an overall score of Minimal.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Partial","Comment": "AWS Network Firewall has the ability to pass, drop, or alert on traffic based on the network protocol as well as perform deep packet inspection on the payload. This functionality can be used to block adversaries from carrying out denial of service attacks by implementing restrictions on which IP addresses and domains can access the resources (e.g., allow lists) as well as which protocol traffic is permitted. That is, the AWS Network Firewall could block the source of the denial of service attack. This mapping is given a score of Partial because it only supports a subset of the sub-techniques (3 of 4) and because the source of the attack would have to be known before rules could be put in place to protect against it.","Category": "Protect","AWSService": "AWS Network Firewall"},{"Value": "Minimal","Comment": "VPC security groups and network access control lists (NACLs) provides minimal protection for a majority of this control's sub-techniques and procedure examples resulting in an overall score of Minimal.","Category": "Protect","AWSService": "Amazon Virtual Private Cloud"}],"description": "Adversaries may perform Endpoint Denial of Service (DoS) attacks to degrade or block the availability of services to users. Endpoint DoS can be performed by exhausting the system resources those services are hosted on or exploiting the system to cause a persistent crash condition. Example services include websites, email services, DNS, and web-based applications. Adversaries have been observed conducting DoS attacks for political purposes[1] and to support other malicious activities, including distraction[2], hacktivism, and extortion.","checks_status": {"fail": 4,"pass": 15,"total": 26,"manual": 0}},"T1518": {"name": "Software Discovery","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may attempt to get a listing of software and software versions that are installed on a system or in a cloud environment. Adversaries may use the information from Software Discovery during automated discovery to shape follow-on behaviors, including whether or not the adversary fully infects the target and/or attempts specific actions.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1525": {"name": "Implant Internal Image","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Value": "Minimal","Comment": "The following AWS Config managed rules can identify running instances that are not using AMIs within a specified allow list: 'approved-amis-by-id' and 'approved-amis-by-tag', both of which are run on configuration changes. This does not provide detection of the image implanting itself, but does provide detection for any subsequent use of images that are implanted and not present within the allow list, resulting in a score of Minimal.","Category": "Detect","AWSService": "AWS Config"}],"description": "Adversaries may implant cloud or container images with malicious code to establish persistence after gaining access to an environment. Amazon Web Services (AWS) Amazon Machine Images (AMIs), Google Cloud Platform (GCP) Images, and Azure Images as well as popular container runtimes such as Docker can be implanted or backdoored. Unlike Upload Malware, this technique focuses on adversaries implanting an image in a registry within a victim’s environment. Depending on how the infrastructure is provisioned, this could provide persistent access if the infrastructure provisioning tool is instructed to always use the latest image.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"T1526": {"name": "Cloud Service Discovery","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Value": "Partial","Comment": "GuardDuty has the following finding types to flag events where there is an attempt to discover information about resources on the account. Recon:IAMUser/MaliciousIPCaller Recon:IAMUser/MaliciousIPCaller.Custom Recon:IAMUser/TorIPCaller","Category": "Detect","AWSService": "Amazon GuardDuty"}],"description": "An adversary may attempt to enumerate the cloud services running on a system after gaining access. These methods can differ from platform-as-a-service (PaaS), to infrastructure-as-a-service (IaaS), or software-as-a-service (SaaS). Many services exist throughout the various cloud providers and can include Continuous Integration and Continuous Delivery (CI/CD), Lambda Functions, Azure AD, etc. They may also include security services, such as AWS GuardDuty and Microsoft Defender for Cloud, and logging services, such as AWS CloudTrail and Google Cloud Audit Logs.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"T1530": {"name": "Data from Cloud Storage","checks": {"macie_is_enabled": "PASS","securityhub_enabled": "PASS","s3_bucket_public_access": null,"networkfirewall_in_all_vpc": "FAIL","efs_not_publicly_accessible": "FAIL","rds_snapshots_public_access": "PASS","s3_bucket_default_encryption": "PASS","rds_instance_no_public_access": "PASS","efs_encryption_at_rest_enabled": "FAIL","emr_cluster_publicly_accesible": null,"rds_instance_storage_encrypted": "FAIL","redshift_cluster_public_access": null,"rds_instance_transport_encrypted": "FAIL","config_recorder_all_regions_enabled": null,"s3_bucket_level_public_access_block": "PASS","s3_account_level_public_access_blocks": null,"sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"sagemaker_training_jobs_intercontainer_encryption_enabled": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Value": "Significant","Comment": "The following AWS Config managed rules can identify configuration problems that should be fixed in order to prevent malicious access of data within Amazon Simple Storage Service (S3) storage: 's3-account-level-public-access-blocks', 's3-bucket-level-public-access-prohibited', 's3-bucket-public-read-prohibited', 's3-bucket-policy-not-more-permissive', 'cloudfront-origin-access-identity-enabled', and 'cloudfront-default-root-object-configured' identify objects that are publicly available or subject to overly permissive access policies; 's3-bucket-blacklisted-actions-prohibited' checks whether bucket policies prohibit disallowed actions for principals from other AWS accounts; and 's3-bucket-policy-grantee-check' checks whether bucket policies appropriately control which AWS principals, federated users, service principals, IP addresses, and VPCs have access. All of these controls are run on configuration changes. The following AWS Config managed rules can identify configuration problems that should be fixed in order to prevent malicious access of data from other AWS services: 'dms-replication-not-public' for AWS Database Migration Service; 'emr-master-no-public-ip' for Amazon Elastic MapReduce (EMR); 'rds-cluster-iam-authentication-enabled', 'rds-instance-iam-authentication-enabled', 'rds-instance-public-access-check' and 'rds-snapshots-public-prohibited' for Amazon Relational Database Service; 'redshift-cluster-public-access-check' for Amazon Redshift; and 'sagemaker-notebook-no-direct-internet-access' for SageMaker. The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure that cloud storage data are encrypted to prevent malicious access: 'dax-encryption-enabled', 'dynamodb-table-encrypted-kms', and 'dynamodb-table-encryption-enabled' for Amazon DynamoDB table contents; 'efs-encrypted-check' for Amazon Elastic File System (EFS) file systems; 'elasticsearch-encrypted-at-rest' for Elasticsearch Service (ES) domains; 'rds-snapshot-encrypted' and 'rds-storage-encrypted' for Amazon Relational Database Service; 's3-bucket-server-side-encryption-enabled' and 's3-default-encryption-kms' for S3 storage; 'sns-encrypted-kms' for Amazon Simple Notification Service (SNS); 'redshift-cluster-configuration-check' and 'redshift-cluster-kms-enabled' for Redshift clusters; 'sagemaker-endpoint-configuration-kms-key-configured' and 'sagemaker-notebook-instance-kms-key-configured' for SageMaker. These rules provide a wide range of coverage for many AWS services, especially those most significant to procedures for this technique, resulting in an overall score of Significant.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Partial","Comment": "The following AWS IoT Device Defender cloud-side detection metrics can detect indicators that an adversary may be leveraging compromised AWS IoT devices and the Message Queuing Telemetry Transport (MQTT) protocol for unauthorized data transfer from cloud-side data sources: 'Source IP' ('aws:source-ip-address') values outside of expected IP address ranges may suggest that a device has been stolen. 'Messages sent' ('aws:num-messages-sent'), 'Messages received' ('aws:num-messages-received'), and 'Message size' ('aws:message-byte-size') values outside of expected norms may indicate that devices are sending and/or receiving non-standard traffic, which may include data retrieved from cloud storage. The following AWS IoT Device Defender device-side detection metrics can detect indicators that an adversary may be leveraging compromised AWS IoT devices and the Message Queuing Telemetry Transport (MQTT) protocol for unauthorized data transfer from cloud-side data sources: 'Bytes in' ('aws:all-bytes-in'), 'Bytes out' ('aws:all-bytes-out'), 'Packets in' ('aws:all-packets-in'), and 'Packets out' ('aws:all-packets-out') values outside of expected norms may indicate that devices are sending and/or receiving non-standard traffic, which may include data retrieved from cloud storage. Coverage factor is partial, since these metrics are limited to IoT device-based collection, resulting in an overall score of Partial.","Category": "Detect","AWSService": "AWS IoT Device Defender"},{"Value": "Partial","Comment": "AWS Network Firewall has the ability to pass, drop, or alert on traffic based on the network protocol as well as perform deep packet inspection on the payload. This functionality can be used to block adversaries from accessing resources such as cloud storage objects by implementing restrictions on which IP addresses and domains can access the resources (e.g., allow lists). However, since cloud storage objects are located outside the virtual private cloud where the AWS Network Firewall protects, the mapping is only given a score of Partial.","Category": "Protect","AWSService": "AWS Network Firewall"},{"Value": "Significant","Comment": "AWS RDS supports the encryption of the underlying storage for database instances, backups, read replicas, and snapshots using the AES-256 encryption algorithm. This can protect against an adversary from gaining access to a database instance in the event they get access to the underlying system where the database instance is hosted or to S3 where the backups are stored. Furthermore, with AWS RDS, there is a setting that specifies whether or not a database instances is publicly accessible. When public accessibility is turned off, the database instance will not be available outside the VPC in which it was created. As a result, this mapping is given a score of Significant.","Category": "Protect","AWSService": "AWS RDS"},{"Value": "Significant","Comment": "S3 provides full control of access via Identity and Access Management (IAM) policies and with its access control lists (ACLs). The S3 Block Public Access feature allows for policies limiting public access to Amazon S3 resources that are enforced regardless of how the resources are created or associated IAM policies. Server-side encryption can be enabled for data at rest and allows for use of S3-managed keys, AWS Key Management Service managed keys, or customer-provided keys.","Category": "Protect","AWSService": "AWS S3"},{"Value": "Partial","Comment": "AWS Security Hub detects improperly secured data from S3 buckets such as public read and write access that may result in an adversary getting access to data in cloud storage. AWS Security Hub provides this detection with the following managed insight. S3 buckets with public write or read permissions. AWS Security Hub also performs checks from the AWS Foundations CIS Benchmark that, if implemented, would help towards detecting improperly secured S3 buckets which could result in them being discovered. AWS Security Hub provides this detection with the following check. 3.8 Ensure a log metric filter and alarm exist for S3 bucket policy changes. This is scored as Partial because it only detects when S3 buckets have public read or write access and doesn't detect improperly secured data in other storage types (e.g., DBs, NFS, etc.).","Category": "Detect","AWSService": "AWS Security Hub"},{"Value": "Partial","Comment": "The following GuardDuty finding types flag events where adversaries may have access data objects from improperly secured cloud storage. UnauthorizedAccess:S3/MaliciousIPCaller.Custom UnauthorizedAccess:S3/TorIPCaller Impact:S3/MaliciousIPCaller Exfiltration:S3/MaliciousIPCaller Exfiltration:S3/ObjectRead.Unusual PenTest:S3/KaliLinux PenTest:S3/ParrotLinux PenTest:S3/PentooLinux UnauthorizedAccess:S3/MaliciousIPCaller.Custom UnauthorizedAccess:S3/TorIPCaller.","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Minimal","Comment": "The following Macie findings can detect the collection of data from S3 buckets: Policy:IAMUser/S3BlockPublicAccessDisabled Policy:IAMUser/S3BucketEncryptionDisabled Policy:IAMUser/S3BucketPublic Policy:IAMUser/S3BucketReplicatedExternally Policy:IAMUser/S3BucketSharedExternally. This type of detection is limited to only the S3 storage type and not other storage types available on the platform (such as file or block storage) and therefore has Minimal coverage resulting in a Minimal score.","Category": "Detect","AWSService": "Amazon Macie"},{"Value": "Minimal","Comment": "The following Macie findings can protect against collection of sensitive data from S3 buckets: SensitiveData:S3Object/Credentials SensitiveData:S3Object/CustomIdentifier SensitiveData:S3Object/Financial SensitiveData:S3Object/Multiple SensitiveData:S3Object/Personal. The ability to discover this type of sensitive data stored in a bucket may lead to hardening steps or removing the data altogether which would prevent an adversary from being able to collect the data. This type of protection is limited to only the S3 storage type and not other storage types available on the platform (such as file or block storage) and therefore has Minimal coverage resulting in a Minimal score.","Category": "Protect","AWSService": "Amazon Macie"}],"description": "Adversaries may collect sensitive data from these cloud storage solutions. Providers typically offer security guides to help end users configure systems, though misconfigurations are a common problem.[5][6][7] There have been numerous incidents where cloud storage has been improperly secured, typically by unintentionally allowing public access to unauthenticated users, overly-broad access by all users, or even access for any anonymous person outside the control of the Identity Access Management system without even needing basic user permissions.","checks_status": {"fail": 6,"pass": 6,"total": 22,"manual": 0}},"T1535": {"name": "Unused/Unsupported Cloud Regions","checks": {"organizations_scp_check_deny_regions": null},"status": "PASS","attributes": [],"description": "Adversaries may create cloud instances in unused geographic service regions in order to evade detection. Access is usually obtained through compromising accounts used to manage cloud infrastructure.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"T1537": {"name": "Transfer Data to Cloud Account","checks": {"macie_is_enabled": "PASS"},"status": "PASS","attributes": [{"Value": "Minimal","Comment": "The following Macie findings can detect attempts to replicate data objects from a monitored bucket to an Amazon Web Services account that isn't part of your organization: Policy:IAMUser/S3BucketReplicatedExternally Policy:IAMUser/S3BucketSharedExternally. This type of detection is limited to only the S3 storage type and not other storage types available on the platform (such as file or block storage) and therefore has Minimal coverage resulting in a Minimal score.","Category": "Detect","AWSService": "Amazon Macie"}],"description": "Adversaries may exfiltrate data by transferring the data, including backups of cloud environments, to another cloud account they control on the same service to avoid typical file transfers/downloads and network-based exfiltration detection.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"T1538": {"name": "Cloud Service Dashboard","checks": {"iam_user_mfa_enabled_console_access": null,"organizations_account_part_of_organizations": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Value": "Partial","Comment": "This control may protect against cloud service dashboard abuse by segmenting accounts into separate organizational units and restricting dashboard access by least privilege.","Category": "Protect","AWSService": "AWS Organizations"},{"Value": "Significant","Comment": "The 'mfa-enabled-for-iam-console-access' managed rule checks whether multi-factor authentication is enabled for all AWS IAM users that use a console password, protecting against misuse of those accounts' dashboard access. It is run periodically, and provides significant coverage, resulting in an overall score of Significant.","Category": "Protect","AWSService": "AWS Config"}],"description": "An adversary may use a cloud service dashboard GUI with stolen credentials to gain useful information from an operational cloud environment, such as specific services, resources, and features. For example, the GCP Command Center can be used to view all assets, findings of potential security risks, and to run additional queries, such as finding public IP addresses and open ports.","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"T1546": {"name": "Event Triggered Execution","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may establish persistence and/or elevate privileges using system mechanisms that trigger execution based on specific events. Various operating systems have means to monitor and subscribe to events such as logons or other user activity such as running specific applications/binaries. Cloud environments may also support various functions and services that monitor and can be invoked in response to specific cloud events.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1550": {"name": "Use Alternate Authentication Material","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_hardware_mfa_enabled": null,"iam_user_console_access_unused": null,"iam_user_two_active_access_key": null,"iam_policy_no_full_access_to_kms": null,"iam_administrator_access_with_mfa": null,"iam_user_mfa_enabled_console_access": null,"iam_user_no_setup_initial_access_key": null,"iam_policy_allows_privilege_escalation": null,"iam_policy_no_full_access_to_cloudtrail": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Value": "Minimal","Comment": "This control provides significant coverage for one of this technique's SubTechniques, resulting in an overall score of Minimal.","Category": "Protect","AWSService": "AWS IAM"}],"description": "Adversaries may use alternate authentication material, such as password hashes, Kerberos tickets, and application access tokens, in order to move laterally within an environment and bypass normal system access controls.","checks_status": {"fail": 0,"pass": 0,"total": 17,"manual": 0}},"T1552": {"name": "Unsecured Credentials","checks": {"macie_is_enabled": "PASS","guardduty_is_enabled": "PASS","ssm_document_secrets": "PASS","ec2_instance_imdsv2_enabled": "PASS","ec2_instance_secrets_user_data": "PASS","ec2_launch_template_no_secrets": "PASS","awslambda_function_no_secrets_in_code": "PASS","cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudformation_stack_outputs_find_secrets": "PASS","secretsmanager_automatic_rotation_enabled": "FAIL","awslambda_function_no_secrets_in_variables": "PASS","ecs_task_definitions_no_environment_secrets": "PASS","autoscaling_find_secrets_ec2_launch_configuration": "PASS","eks_cluster_kms_cmk_encryption_in_secrets_enabled": null},"status": "FAIL","attributes": [{"Value": "Minimal","Comment": "This control's protection is specific to a minority of this technique's sub-techniques and procedure examples resulting in a Minimal Coverage score and consequently an overall score of Minimal.","Category": "Protect","AWSService": "AWS CloudHSM"},{"Value": "Significant","Comment": "The following AWS Config managed rules can identify insecure plaintext credentials within specific parts of a cloud environment: 'codebuild-project-envvar-awscred-check' for credentials (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY) stored within environment variables, 'codebuild-project-source-repo-url-check' for personal access tokens and/or credentials within source repository URLs. The following AWS Config managed rules can identify configuration problems that should be fixed in order to ensure that the contents of secrets in AWS Secrets Manager (including credentials) are properly secured to avoid adversary access: 'secretsmanager-rotation-enabled-check', 'secretsmanager-scheduled-rotation-success-check', 'secretsmanager-secret-periodic-rotation', and 'secretsmanager-using-cmk'. This control provides partial coverage for a minority of this technique's sub-techniques, in addition to the parent coverage above, resulting in an overall score of Partial.","Category": "Protect","AWSService": "AWS Config"},{"Value": "Minimal","Comment": "This control provides partial coverage for a minority of this technique's sub-techniques, resulting in an overall score of Minimal.","Category": "Detect","AWSService": "AWS IoT Device Defender"},{"Value": "Minimal","Comment": "This control's protection is specific to a minority of this technique's sub-techniques and procedure examples resulting in a Minimal Coverage score and consequently an overall score of Minimal.","Category": "Protect","AWSService": "AWS Key Management Service"},{"Value": "Partial","Comment": "This control is relevant for credentials stored in applications or configuration files but not credentials entered directly by a user.","Category": "Protect","AWSService": "AWS Secrets Manager"},{"Value": "Minimal","Comment": "This control provides minimal to partial coverage for a minority of this technique's sub-techniques, and without specific coverage for its procedures, resulting in an overall score of Minimal.","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Minimal","Comment": "Macie only provides detection for the Credentials in Files sub-technique of this technique and only for the S3 storage type resulting in Minimal coverage and an overall Minimal score.","Category": "Protect","AWSService": "Amazon Macie"}],"description": "Adversaries may search compromised systems to find and obtain insecurely stored credentials. These credentials can be stored and/or misplaced in many locations on a system, including plaintext files (e.g. Bash History), operating system or application-specific repositories (e.g. Credentials in Registry), or other specialized files/artifacts (e.g. Private Keys).","checks_status": {"fail": 2,"pass": 11,"total": 14,"manual": 0}},"T1556": {"name": "Modify Authentication Process","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Value": "Partial","Comment": "This control provides coverage for one of this technique's SubTechniques, resulting in an overall score of Partial. Enforce MFA in IAM Users.","Category": "Protect","AWSService": "AWS IAM"}],"description": "Adversaries may modify authentication mechanisms and processes to access user credentials or enable otherwise unwarranted access to accounts. The authentication process is handled by mechanisms, such as the Local Security Authentication Server (LSASS) process and the Security Accounts Manager (SAM) on Windows, pluggable authentication modules (PAM) on Unix-based systems, and authorization plugins on MacOS systems, responsible for gathering, storing, and validating credentials. By modifying an authentication process, an adversary may be able to authenticate to a service or system without using Valid Accounts.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"T1562": {"name": "Impair Defenses","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","inspector2_active_findings_exist": "FAIL","config_recorder_all_regions_enabled": null},"status": "FAIL","attributes": [{"Value": "Minimal","Comment": "This control provides significant coverage for a minority of this technique's SubTechniques, resulting in an overall score of Minimal.","Category": "Detect","AWSService": "AWS Config"},{"Value": "Minimal","Comment": "This control provides partial coverage for a minority of this technique's SubTechniques, resulting in an overall score of Minimal.","Category": "Detect","AWSService": "AWS IoT Device Defender"},{"Value": "Minimal","Comment": "This control provides partial coverage for a minority of this technique's SubTechniques, resulting in an overall score of Minimal.","Category": "Respond","AWSService": "AWS IoT Device Defender"}],"description": "Adversaries may maliciously modify components of a victim environment in order to hinder or disable defensive mechanisms. This not only involves impairing preventative defenses, such as firewalls and anti-virus, but also detection capabilities that defenders can use to audit activity and identify malicious behavior. This may also span both native defenses as well as supplemental capabilities installed by users and administrators.","checks_status": {"fail": 2,"pass": 2,"total": 5,"manual": 0}},"T1578": {"name": "Modify Cloud Compute Infrastructure","checks": {"iam_policy_no_full_access_to_kms": null,"iam_policy_allows_privilege_escalation": null,"iam_policy_no_full_access_to_cloudtrail": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Value": "Significant","Comment": "Limit permissions for creating, deleting, and otherwise altering compute components in accordance with least privilege.","Category": "Protect","AWSService": "AWS IAM"}],"description": "An adversary may attempt to modify a cloud account's compute service infrastructure to evade defenses. A modification to the compute service infrastructure can include the creation, deletion, or modification of one or more components such as compute instances, virtual machines, and snapshots.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"T1580": {"name": "Cloud Infrastructure Discovery","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_policy_no_full_access_to_kms": null,"iam_policy_allows_privilege_escalation": null,"iam_policy_no_full_access_to_cloudtrail": null,"organizations_account_part_of_organizations": null,"iam_inline_policy_no_administrative_privileges": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Value": "Partial","Comment": "This control may protect against cloud infrastructure discovery by segmenting accounts into separate organizational units and restricting infrastructure access by least privilege.","Category": "Protect","AWSService": "AWS Organizations"},{"Value": "Partial","Comment": "AWS Security Hub detects improperly secured data from S3 buckets such as public read and write access as well as accessible EC2 instances that may result in an adversary learning about cloud infrastructure used by the organization. AWS Security Hub provides these detections with the following managed insights. S3 buckets with public write or read permissions EC2 instances that have ports accessible from the Internet EC2 instances that are open to the Internet. AWS Security Hub also performs checks from the AWS Foundations CIS Benchmark that, if implemented, would help towards detecting improperly secured S3 buckets which could result in them being discovered. AWS Security Hub provides this detection with the following check. 3.8 Ensure a log metric filter and alarm exist for S3 bucket policy changes. This is scored as Partial because S3 and EC2 only represent a subset of available cloud infrastructure components.","Category": "Detect","AWSService": "AWS Security Hub"},{"Value": "Partial","Comment": "The following GuardDuty finding types flag events that are linked to Discovery techniques and can be used to capture events where a malicious user may be searching through the account looking for available resources. The finding types are also used to flag certain signatures of running services to detect malicious user activities from commonly used pentest operating systems. Discovery:IAMUser/AnomalousBehavior Discovery:S3/MaliciousIPCaller Discovery:S3/MaliciousIPCaller.Custom Discovery:S3/TorIPCaller PenTest:IAMUser/KaliLinux PenTest:IAMUser/ParrotLinux PenTest:IAMUser/PentooLinux PenTest:S3/KaliLinux PenTest:S3/ParrotLinux PenTest:S3/PentooLinux.","Category": "Detect","AWSService": "Amazon GuardDuty"},{"Value": "Significant","Comment": "Limit IAM permissions to discover cloud infrastructure in accordance with least privilege. Organizations should limit the number of users within the organization with an IAM role that has administrative privileges, strive to reduce all permanent privileged role assignments, and conduct periodic entitlement reviews on IAM users, roles and policies.","Category": "Protect","AWSService": "AWS IAM"}],"description": "An adversary may attempt to discover infrastructure and resources that are available within an infrastructure-as-a-service (IaaS) environment. This includes compute service resources such as instances, virtual machines, and snapshots as well as resources of other services including the storage and database services.","checks_status": {"fail": 0,"pass": 2,"total": 10,"manual": 0}},"T1606": {"name": "Forge Web Credentials","checks": {"iam_policy_allows_privilege_escalation": null,"iam_no_custom_policy_permissive_role_assumption": null},"status": "PASS","attributes": [{"Value": "Partial","Comment": "Limit IAM permissions from calling the sts:GetFederationToken API unless explicitly required, in accordance with least privilege.","Category": "Protect","AWSService": "AWS IAM"}],"description": "Adversaries may forge credential materials that can be used to gain access to web applications or Internet services. Web applications and services (hosted in cloud SaaS environments or on-premise servers) often use session cookies, tokens, or other materials to authenticate and authorize user access.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"T1614": {"name": "System Location Discovery","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may gather information in an attempt to calculate the geographical location of a victim host. Adversaries may use the information from System Location Discovery during automated discovery to shape follow-on behaviors, including whether or not the adversary fully infects the target and/or attempts specific actions.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1619": {"name": "Cloud Storage Object Discovery","checks": {"iam_policy_allows_privilege_escalation": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Value": "Significant","Comment": "Restrict granting of permissions related to listing objects in AWS S3 Buckets to necessary accounts.","Category": "Protect","AWSService": "AWS IAM"}],"description": "Adversaries may enumerate objects in cloud storage infrastructure. Adversaries may use this information during automated discovery to shape follow-on behaviors, including requesting all or specific objects from cloud storage. Similar to File and Directory Discovery on a local host, after identifying available storage services (i.e. Cloud Infrastructure Discovery) adversaries may access the contents/objects stored in cloud infrastructure.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"T1621": {"name": "Multi-Factor Authentication Request Generation","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may attempt to bypass multi-factor authentication (MFA) mechanisms and gain access to accounts by generating MFA requests sent to users.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"T1648": {"name": "Serverless Execution","checks": {"iam_policy_no_full_access_to_kms": null,"iam_policy_allows_privilege_escalation": null,"iam_policy_no_full_access_to_cloudtrail": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Value": "Significant","Comment": "Remove permissions to create, modify, or run serverless resources from users that do not explicitly require them.","Category": "Protect","AWSService": "AWS IAM"}],"description": "Adversaries may abuse serverless computing, integration, and automation services to execute arbitrary code in cloud environments. Many cloud providers offer a variety of serverless resources, including compute engines, application integration services, and web servers.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"T1651": {"name": "Cloud Administration Command","checks": {},"status": "PASS","attributes": [],"description": "Adversaries may abuse cloud management services to execute commands within virtual machines or hybrid-joined devices. Resources such as AWS Systems Manager, Azure RunCommand, and Runbooks allow users to remotely run scripts in virtual machines by leveraging installed virtual machine agents. Similarly, in Azure AD environments, Microsoft Endpoint Manager allows Global or Intune Administrators to run scripts as SYSTEM on on-premises devices joined to the Azure AD.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}}},"requirements_passed": 18,"requirements_failed": 18,"requirements_manual": 10,"total_requirements": 46,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "6e52644d-3557-4704-9cf6-e33e4c1a316b","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "ffiec_aws","framework": "FFIEC","version": "","description": "In light of the increasing volume and sophistication of cyber threats, the Federal Financial Institutions Examination Council (FFIEC) developed the Cybersecurity Assessment Tool (Assessment), on behalf of its members, to help institutions identify their risks and determine their cybersecurity maturity.","region": "eu-west-1","requirements": {"d1-g-it-b-1": {"name": "D1.G.IT.B.1","checks": {"ec2_elastic_ip_unassigned": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d1-g-it-b-1","Section": "Cyber Risk Management and Oversight (Domain 1)","Service": "aws","SubGroup": null,"SubSection": "Governance (G)"}],"description": "An inventory of organizational assets (e.g., hardware, software, data, and systems hosted externally) is maintained.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"d4-c-co-b-2": {"name": "D4.C.Co.B.2","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d4-c-co-b-2","Section": "External Dependency Management (Domain 4)","Service": "aws","SubGroup": null,"SubSection": "Connections (C)"}],"description": "The institution ensures that third-party connections are authorized.","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"d1-rm-ra-b-2": {"name": "D1.RM.RA.B.2","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "d1-rm-ra-b-2","Section": "Cyber Risk Management and Oversight (Domain 1)","Service": "aws","SubGroup": null,"SubSection": "Risk Management (RM)"}],"description": "The risk assessment identifies Internet- based systems and high-risk transactions that warrant additional authentication controls.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"d1-rm-rm-b-1": {"name": "D1.RM.Rm.B.1","checks": {"rds_instance_multi_az": "FAIL","rds_instance_backup_enabled": "PASS","redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d1-rm-rm-b-1","Section": "Cyber Risk Management and Oversight (Domain 1)","Service": "aws","SubGroup": null,"SubSection": "Risk Management (RM)"}],"description": "An information security and business continuity risk management function(s) exists within the institution.","checks_status": {"fail": 1,"pass": 1,"total": 4,"manual": 0}},"d2-is-is-b-1": {"name": "D2.IS.Is.B.1","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d2-is-is-b-1","Section": "Threat Intelligence and Collaboration (Domain 2)","Service": "aws","SubGroup": null,"SubSection": "Information Sharing (IS)"}],"description": "Information security threats are gathered and shared with applicable internal employees.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"d2-ma-ma-b-1": {"name": "D2.MA.Ma.B.1","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","opensearch_service_domains_cloudwatch_logging_enabled": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d2-ma-ma-b-1","Section": "Threat Intelligence and Collaboration (Domain 2)","Service": "aws","SubGroup": null,"SubSection": "Monitoring and Analyzing (MA)"}],"description": "Information security threats are gathered and shared with applicable internal employees.","checks_status": {"fail": 7,"pass": 2,"total": 14,"manual": 0}},"d2-ma-ma-b-2": {"name": "D2.MA.Ma.B.2","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","opensearch_service_domains_cloudwatch_logging_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d2-ma-ma-b-2","Section": "Threat Intelligence and Collaboration (Domain 2)","Service": "aws","SubGroup": null,"SubSection": "Monitoring and Analyzing (MA)"}],"description": "Computer event logs are used for investigations once an event has occurred.","checks_status": {"fail": 5,"pass": 2,"total": 12,"manual": 0}},"d2-ti-ti-b-1": {"name": "D2.TI.Ti.B.1","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "d2-ti-ti-b-1","Section": "Threat Intelligence and Collaboration (Domain 2)","Service": "aws","SubGroup": null,"SubSection": "Threat Intelligence (TI)"}],"description": "The institution belongs or subscribes to a threat and vulnerability information-sharing source(s) that provides information on threats (e.g., FS-ISAC, US- CERT).","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"d2-ti-ti-b-2": {"name": "D2.TI.Ti.B.2","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d2-ti-ti-b-2","Section": "Threat Intelligence and Collaboration (Domain 2)","Service": "aws","SubGroup": null,"SubSection": "Threat Intelligence (TI)"}],"description": "Threat information is used to monitor threats and vulnerabilities.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"d2-ti-ti-b-3": {"name": "D2.TI.Ti.B.3","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "d2-ti-ti-b-3","Section": "Threat Intelligence and Collaboration (Domain 2)","Service": "aws","SubGroup": null,"SubSection": "Threat Intelligence (TI)"}],"description": "Threat information is used to enhance internal risk management and controls.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"d3-cc-pm-b-1": {"name": "D3.CC.PM.B.1","checks": {"ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-cc-pm-b-1","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Corrective Controls (CC)"}],"description": "A patch management program is implemented and ensures that software and firmware patches are applied in a timely manner.","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"d3-cc-pm-b-3": {"name": "D3.CC.PM.B.3","checks": {"ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-cc-pm-b-3","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Corrective Controls (CC)"}],"description": "Patch management reports are reviewed and reflect missing security patches.","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"d3-dc-an-b-1": {"name": "D3.DC.An.B.1","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-dc-an-b-1","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "The institution is able to detect anomalous activities through monitoring across the environment.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"d3-dc-an-b-2": {"name": "D3.DC.An.B.2","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-dc-an-b-2","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "Customer transactions generating anomalous activity alerts are monitored and reviewed.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"d3-dc-an-b-3": {"name": "D3.DC.An.B.3","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","opensearch_service_domains_cloudwatch_logging_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-dc-an-b-3","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "Logs of physical and/or logical access are reviewed following events.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"d3-dc-an-b-4": {"name": "D3.DC.An.B.4","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","opensearch_service_domains_cloudwatch_logging_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-dc-an-b-4","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "Access to critical systems by third parties is monitored for unauthorized or unusual activity.","checks_status": {"fail": 6,"pass": 2,"total": 13,"manual": 0}},"d3-dc-an-b-5": {"name": "D3.DC.An.B.5","checks": {"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-dc-an-b-5","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "Elevated privileges are monitored.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"d3-dc-ev-b-1": {"name": "D3.DC.Ev.B.1","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-dc-ev-b-1","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "A normal network activity baseline is established.","checks_status": {"fail": 4,"pass": 2,"total": 10,"manual": 0}},"d3-dc-ev-b-2": {"name": "D3.DC.Ev.B.2","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-dc-ev-b-2","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "Mechanisms (e.g., antivirus alerts, log event alerts) are in place to alert management to potential attacks.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"d3-dc-ev-b-3": {"name": "D3.DC.Ev.B.3","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-dc-ev-b-3","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "Processes are in place to monitor for the presence of unauthorized users, devices, connections, and software.","checks_status": {"fail": 1,"pass": 3,"total": 4,"manual": 0}},"d3-dc-th-b-1": {"name": "D3.DC.Th.B.1","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-dc-th-b-1","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Detective Controls (DC)"}],"description": "Independent testing (including penetration testing and vulnerability scanning) is conducted according to the risk assessment for external-facing systems and the internal network.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"d3-pc-am-b-1": {"name": "D3.PC.Am.B.1","checks": {"iam_no_root_access_key": null,"ec2_instance_profile_attached": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-1","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Employee access is granted to systems and confidential data based on job responsibilities and the principles of least privilege.","checks_status": {"fail": 0,"pass": 1,"total": 6,"manual": 0}},"d3-pc-am-b-2": {"name": "D3.PC.Am.B.2","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-2","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Employee access to systems and confidential data provides for separation of duties.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"d3-pc-am-b-3": {"name": "D3.PC.Am.B.3","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_root_hardware_mfa_enabled": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-3","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Elevated privileges (e.g., administrator privileges) are limited and tightly controlled (e.g., assigned to individuals, not shared, and require stronger password controls","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"d3-pc-am-b-6": {"name": "D3.PC.Am.B.6","checks": {"iam_root_mfa_enabled": null,"iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-6","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Identification and authentication are required and managed for access to systems, applications, and hardware.","checks_status": {"fail": 0,"pass": 0,"total": 16,"manual": 0}},"d3-pc-am-b-7": {"name": "D3.PC.Am.B.7","checks": {"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-7","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Access controls include password complexity and limits to password attempts and reuse.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"d3-pc-am-b-8": {"name": "D3.PC.Am.B.8","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-8","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "All default passwords and unnecessary default accounts are changed before system implementation.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"d3-pc-im-b-1": {"name": "D3.PC.Im.B.1","checks": {"ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"acm_certificates_expiration_check": "PASS","apigateway_restapi_waf_acl_attached": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-im-b-1","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Network perimeter defense tools (e.g., border router and firewall) are used.","checks_status": {"fail": 5,"pass": 7,"total": 20,"manual": 0}},"d3-pc-im-b-2": {"name": "D3.PC.Im.B.2","checks": {"elbv2_waf_acl_attached": "FAIL","apigateway_restapi_waf_acl_attached": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-im-b-2","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Systems that are accessed from the Internet or by external parties are protected by firewalls or other similar devices.","checks_status": {"fail": 4,"pass": 1,"total": 6,"manual": 0}},"d3-pc-im-b-3": {"name": "D3.PC.Im.B.3","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-im-b-3","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "All ports are monitored.","checks_status": {"fail": 4,"pass": 2,"total": 6,"manual": 0}},"d3-pc-im-b-5": {"name": "D3.PC.Im.B.5","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-im-b-5","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Systems configurations (for servers, desktops, routers, etc.) follow industry standards and are enforced","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"d3-pc-im-b-6": {"name": "D3.PC.Im.B.6","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-im-b-6","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Ports, functions, protocols and services are prohibited if no longer needed for business purposes.","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"d3-pc-im-b-7": {"name": "D3.PC.Im.B.7","checks": {"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-im-b-7","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Access to make changes to systems configurations (including virtual machines and hypervisors) is controlled and monitored.","checks_status": {"fail": 1,"pass": 1,"total": 6,"manual": 0}},"d3-pc-se-b-1": {"name": "D3.PC.Se.B.1","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-pc-se-b1","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Developers working for the institution follow secure program coding practices, as part of a system development life cycle (SDLC), that meet industry standards.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"d5-dr-de-b-1": {"name": "D5.DR.De.B.1","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "d5-dr-de-b-1","Section": "Cyber Incident Management and Resilience (Domain 5)","Service": "aws","SubGroup": null,"SubSection": "Detection, Response, & Mitigation (DR)"}],"description": "Alert parameters are set for detecting information security incidents that prompt mitigating actions.","checks_status": {"fail": 0,"pass": 2,"total": 6,"manual": 0}},"d5-dr-de-b-2": {"name": "D5.DR.De.B.2","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "d5-dr-de-b-2","Section": "Cyber Incident Management and Resilience (Domain 5)","Service": "aws","SubGroup": null,"SubSection": "Detection, Response, & Mitigation (DR)"}],"description": "System performance reports contain information that can be used as a risk indicator to detect information security incidents.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"d5-dr-de-b-3": {"name": "D5.DR.De.B.3","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d5-dr-de-b-3","Section": "Cyber Incident Management and Resilience (Domain 5)","Service": "aws","SubGroup": null,"SubSection": "Detection, Response, & Mitigation (DR)"}],"description": "Tools and processes are in place to detect, alert, and trigger the incident response program.","checks_status": {"fail": 5,"pass": 3,"total": 16,"manual": 0}},"d5-er-es-b-4": {"name": "D5.ER.Es.B.4","checks": {"guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d5-er-es-b-4","Section": "Cyber Incident Management and Resilience (Domain 5)","Service": "aws","SubGroup": null,"SubSection": "Escalation and Reporting (ER)"}],"description": "Incidents are classified, logged and tracked.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"d5-ir-pl-b-6": {"name": "D5.IR.Pl.B.6","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d5-ir-pl-b-6","Section": "Cyber Incident Management and Resilience (Domain 5)","Service": "aws","SubGroup": null,"SubSection": "Incident Resilience Planning & Strategy (IR)"}],"description": "The institution plans to use business continuity, disaster recovery, and data backup programs to recover operations following an incident.","checks_status": {"fail": 5,"pass": 1,"total": 8,"manual": 0}},"d3-pc-am-b-10": {"name": "D3.PC.Am.B.10","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-10","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Production and non-production environments are segregated to prevent unauthorized access or changes to information assets. (*N/A if no production environment exists at the institution or the institution's third party.)","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"d3-pc-am-b-12": {"name": "D3.PC.Am.B.12","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-12","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "All passwords are encrypted in storage and in transit.","checks_status": {"fail": 4,"pass": 3,"total": 10,"manual": 0}},"d3-pc-am-b-13": {"name": "D3.PC.Am.B.13","checks": {"elb_ssl_listeners": "FAIL","elbv2_insecure_ssl_ciphers": "PASS","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-13","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Confidential data is encrypted when transmitted across public or untrusted networks (e.g., Internet).","checks_status": {"fail": 3,"pass": 1,"total": 4,"manual": 0}},"d3-pc-am-b-15": {"name": "D3.PC.Am.B.15","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"s3_bucket_secure_transport_policy": "FAIL","iam_user_mfa_enabled_console_access": null,"apigateway_restapi_client_certificate_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-15","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Remote access to critical systems by employees, contractors, and third parties uses encrypted connections and multifactor authentication.","checks_status": {"fail": 2,"pass": 0,"total": 5,"manual": 0}},"d3-pc-am-b-16": {"name": "D3.PC.Am.B.16","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "d3-pc-am-b-16","Section": "Cybersecurity Controls (Domain 3)","Service": "aws","SubGroup": null,"SubSection": "Preventative Controls (PC)"}],"description": "Administrative, physical, or technical controls are in place to prevent users without administrative responsibilities from installing unauthorized software.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}}},"requirements_passed": 13,"requirements_failed": 29,"requirements_manual": 2,"total_requirements": 44,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "7058bd2a-3241-4e0e-9773-9a0136d861bc","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "cis_2.0_aws","framework": "CIS","version": "2.0","description": "The CIS Amazon Web Services Foundations Benchmark provides prescriptive guidance for configuring security options for a subset of Amazon Web Services with an emphasis on foundational, testable, and architecture agnostic settings.","region": "eu-west-1","requirements": {"1.1": {"name": "1.1","checks": {"account_maintain_current_contact_details": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/manage-account-payment.html#contact-info","Description": "Ensure contact email and telephone details for AWS accounts are current and map to more than one individual in your organization.An AWS account supports a number of contact details, and AWS will use these to contact the account owner if activity judged to be in breach of Acceptable Use Policy or indicative of likely security compromise is observed by the AWS Abuse team. Contact details should not be for a single individual, as circumstances may arise where that individual is unavailable. Email contact details should point to a mail alias which forwards email to multiple individuals within the organization; where feasible, phone contact details should point to a PABX hunt group or other call-forwarding system.","DefaultValue": null,"AuditProcedure": "This activity can only be performed via the AWS Console, with a user who has permission to read and write Billing information (aws-portal:\\*Billing )1. Sign in to the AWS Management Console and open the `Billing and Cost Management` console at https://console.aws.amazon.com/billing/home#/. 2. On the navigation bar, choose your account name, and then choose `My Account`. 3. On the `Account Settings` page, review and verify the current details. 4. Under `Contact Information`, review and verify the current details.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "If an AWS account is observed to be behaving in a prohibited or suspicious manner, AWS will attempt to contact the account owner by email and phone using the contact details listed. If this is unsuccessful and the account behavior needs urgent mitigation, proactive measures may be taken, including throttling of traffic between the account exhibiting suspicious behavior and the AWS API endpoints and the Internet. This will result in impaired service to and from the account in question, so it is in both the customers' and AWS' best interests that prompt contact can be established. This is best achieved by setting AWS account contact details to point to resources which have multiple individuals as recipients, such as email aliases and PABX hunt groups.","RemediationProcedure": "This activity can only be performed via the AWS Console, with a user who has permission to read and write Billing information (aws-portal:\\*Billing ).1. Sign in to the AWS Management Console and open the `Billing and Cost Management` console at https://console.aws.amazon.com/billing/home#/. 2. On the navigation bar, choose your account name, and then choose `My Account`. 3. On the `Account Settings` page, next to `Account Settings`, choose `Edit`. 4. Next to the field that you need to update, choose `Edit`. 5. After you have entered your changes, choose `Save changes`. 6. After you have made your changes, choose `Done`. 7. To edit your contact information, under `Contact Information`, choose `Edit`. 8. For the fields that you want to change, type your updated information, and then choose `Update`.","AdditionalInformation": ""}],"description": "Maintain current contact details","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.2": {"name": "1.2","checks": {"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "","Description": "AWS provides customers with the option of specifying the contact information for account's security team. It is recommended that this information be provided.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if security contact information is present:**From Console:**1. Click on your account name at the top right corner of the console 2. From the drop-down menu Click `My Account`3. Scroll down to the `Alternate Contacts` section 4. Ensure contact information is specified in the `Security` section","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Specifying security-specific contact information will help ensure that security advisories sent by AWS reach the team in your organization that is best equipped to respond to them.","RemediationProcedure": "Perform the following to establish security contact information:**From Console:**1. Click on your account name at the top right corner of the console. 2. From the drop-down menu Click `My Account`3. Scroll down to the `Alternate Contacts` section 4. Enter contact information in the `Security` section**Note:** Consider specifying an internal email distribution list to ensure emails are regularly monitored by more than one individual.","AdditionalInformation": ""}],"description": "Ensure security contact information is registered","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.3": {"name": "1.3","checks": {"account_security_questions_are_registered_in_the_aws_account": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "","Description": "The AWS support portal allows account owners to establish security questions that can be used to authenticate individuals calling AWS customer service for support. It is recommended that security questions be established.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS account as the 'root' user 2. On the top right you will see the __ 3. Click on the __ 4. From the drop-down menu Click `My Account`5. In the `Configure Security Challenge Questions` section on the `Personal Information` page, configure three security challenge questions. 6. Click `Save questions` .","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "When creating a new AWS account, a default super user is automatically created. This account is referred to as the 'root user' or 'root' account. It is recommended that the use of this account be limited and highly controlled. During events in which the 'root' password is no longer accessible or the MFA token associated with 'root' is lost/destroyed it is possible, through authentication using secret questions and associated answers, to recover 'root' user login access.","RemediationProcedure": "**From Console:**1. Login to the AWS Account as the 'root' user 2. Click on the __ from the top right of the console 3. From the drop-down menu Click _My Account_ 4. Scroll down to the `Configure Security Questions` section 5. Click on `Edit`6. Click on each `Question` - From the drop-down select an appropriate question- Click on the `Answer` section- Enter an appropriate answer - Follow process for all 3 questions 7. Click `Update` when complete 8. Save Questions and Answers and place in a secure physical location","AdditionalInformation": ""}],"description": "Ensure security questions are registered in the AWS account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.4": {"name": "1.4","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "http://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html:http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html:http://docs.aws.amazon.com/IAM/latest/APIReference/API_GetAccountSummary.html:https://aws.amazon.com/blogs/security/an-easier-way-to-determine-the-presence-of-aws-account-access-keys/","Description": "The 'root' user account is the most privileged user in an AWS account. AWS Access Keys provide programmatic access to a given AWS account. It is recommended that all access keys associated with the 'root' user account be removed.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has access keys:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on `Credential Report`5. This will download a `.csv` file which contains credential usage for all IAM users within an AWS Account - open this file 6. For the `` user, ensure the `access_key_1_active` and `access_key_2_active` fields are set to `FALSE` .**From Command Line:**Run the following command: ```aws iam get-account-summary | grep \"AccountAccessKeysPresent\"``` If no 'root' access keys exist the output will show \"AccountAccessKeysPresent\": 0,. If the output shows a \"1\" than 'root' keys exist, refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Removing access keys associated with the 'root' user account limits vectors by which the account can be compromised. Additionally, removing the 'root' access keys encourages the creation and use of role based accounts that are least privileged.","RemediationProcedure": "Perform the following to delete or disable active 'root' user access keys**From Console:**1. Sign in to the AWS Management Console as 'root' and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. Click on __ at the top right and select `My Security Credentials` from the drop down list 3. On the pop out screen Click on `Continue to Security Credentials`4. Click on `Access Keys` _(Access Key ID and Secret Access Key)_ 5. Under the `Status` column if there are any Keys which are Active- Click on `Make Inactive` - (Temporarily disable Key - may be needed again)- Click `Delete` - (Deleted keys cannot be recovered)","AdditionalInformation": "IAM User account \"root\" for us-gov cloud regions is not enabled by default. However, on request to AWS support enables 'root' access only through access-keys (CLI, API methods) for us-gov cloud region."}],"description": "Ensure no 'root' user account access key exists","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.5": {"name": "1.5","checks": {"iam_root_mfa_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#id_root-user_manage_mfa:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html#enable-virt-mfa-for-root","Description": "The 'root' user account is the most privileged user in an AWS account. Multi-factor Authentication (MFA) adds an extra layer of protection on top of a username and password. With MFA enabled, when a user signs in to an AWS website, they will be prompted for their username and password as well as for an authentication code from their AWS MFA device.**Note:** When virtual MFA is used for 'root' accounts, it is recommended that the device used is NOT a personal device, but rather a dedicated mobile device (tablet or phone) that is managed to be kept charged and secured independent of any individual personal devices. (\"non-personal virtual MFA\") This lessens the risks of losing access to the MFA due to device loss, device trade-in or if the individual owning the device is no longer employed at the company.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has MFA setup:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on `Credential Report`5. This will download a `.csv` file which contains credential usage for all IAM users within an AWS Account - open this file 6. For the `` user, ensure the `mfa_active` field is set to `TRUE` .**From Command Line:**1. Run the following command: ```aws iam get-account-summary | grep \"AccountMFAEnabled\" ``` 2. Ensure the AccountMFAEnabled property is set to 1","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling MFA provides increased security for console access as it requires the authenticating principal to possess a device that emits a time-sensitive key and have knowledge of a credential.","RemediationProcedure": "Perform the following to establish MFA for the 'root' user account:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). Note: to manage MFA devices for the 'root' AWS account, you must use your 'root' account credentials to sign in to AWS. You cannot manage MFA devices for the 'root' account using other credentials.2. Choose `Dashboard` , and under `Security Status` , expand `Activate MFA` on your root account. 3. Choose `Activate MFA`4. In the wizard, choose `A virtual MFA` device and then choose `Next Step` . 5. IAM generates and displays configuration information for the virtual MFA device, including a QR code graphic. The graphic is a representation of the 'secret configuration key' that is available for manual entry on devices that do not support QR codes. 6. Open your virtual MFA application. (For a list of apps that you can use for hosting virtual MFA devices, see [Virtual MFA Applications](http://aws.amazon.com/iam/details/mfa/#Virtual_MFA_Applications).) If the virtual MFA application supports multiple accounts (multiple virtual MFA devices), choose the option to create a new account (a new virtual MFA device). 7. Determine whether the MFA app supports QR codes, and then do one of the following: - Use the app to scan the QR code. For example, you might choose the camera icon or choose an option similar to Scan code, and then use the device's camera to scan the code.- In the Manage MFA Device wizard, choose Show secret key for manual configuration, and then type the secret configuration key into your MFA application.When you are finished, the virtual MFA device starts generating one-time passwords.In the Manage MFA Device wizard, in the Authentication Code 1 box, type the one-time password that currently appears in the virtual MFA device. Wait up to 30 seconds for the device to generate a new one-time password. Then type the second one-time password into the Authentication Code 2 box. Choose Assign Virtual MFA.","AdditionalInformation": "IAM User account \"root\" for us-gov cloud regions does not have console access. This recommendation is not applicable for us-gov cloud regions."}],"description": "Ensure MFA is enabled for the 'root' user account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.6": {"name": "1.6","checks": {"iam_root_hardware_mfa_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_physical.html#enable-hw-mfa-for-root","Description": "The 'root' user account is the most privileged user in an AWS account. MFA adds an extra layer of protection on top of a user name and password. With MFA enabled, when a user signs in to an AWS website, they will be prompted for their user name and password as well as for an authentication code from their AWS MFA device. For Level 2, it is recommended that the 'root' user account be protected with a hardware MFA.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has a hardware MFA setup:1. Run the following command to determine if the 'root' account has MFA setup: ```aws iam get-account-summary | grep \"AccountMFAEnabled\" ```The `AccountMFAEnabled` property is set to `1` will ensure that the 'root' user account has MFA (Virtual or Hardware) Enabled. If `AccountMFAEnabled` property is set to `0` the account is not compliant with this recommendation.2. If `AccountMFAEnabled` property is set to `1`, determine 'root' account has Hardware MFA enabled. Run the following command to list all virtual MFA devices: ```aws iam list-virtual-mfa-devices``` If the output contains one MFA with the following Serial Number, it means the MFA is virtual, not hardware and the account is not compliant with this recommendation: `\"SerialNumber\": \"arn:aws:iam::__:mfa/root-account-mfa-device\"`","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "A hardware MFA has a smaller attack surface than a virtual MFA. For example, a hardware MFA does not suffer the attack surface introduced by the mobile smartphone on which a virtual MFA resides.**Note**: Using hardware MFA for many, many AWS accounts may create a logistical device management issue. If this is the case, consider implementing this Level 2 recommendation selectively to the highest security AWS accounts and the Level 1 recommendation applied to the remaining accounts.","RemediationProcedure": "Perform the following to establish a hardware MFA for the 'root' user account:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). Note: to manage MFA devices for the AWS 'root' user account, you must use your 'root' account credentials to sign in to AWS. You cannot manage MFA devices for the 'root' account using other credentials. 2. Choose `Dashboard` , and under `Security Status` , expand `Activate MFA` on your root account. 3. Choose `Activate MFA`4. In the wizard, choose `A hardware MFA` device and then choose `Next Step` . 5. In the `Serial Number` box, enter the serial number that is found on the back of the MFA device. 6. In the `Authentication Code 1` box, enter the six-digit number displayed by the MFA device. You might need to press the button on the front of the device to display the number. 7. Wait 30 seconds while the device refreshes the code, and then enter the next six-digit number into the `Authentication Code 2` box. You might need to press the button on the front of the device again to display the second number. 8. Choose `Next Step` . The MFA device is now associated with the AWS account. The next time you use your AWS account credentials to sign in, you must type a code from the hardware MFA device.Remediation for this recommendation is not available through AWS CLI.","AdditionalInformation": "IAM User account 'root' for us-gov cloud regions does not have console access. This control is not applicable for us-gov cloud regions."}],"description": "Ensure hardware MFA is enabled for the 'root' user account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.7": {"name": "1.7","checks": {"iam_avoid_root_usage": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html:https://docs.aws.amazon.com/general/latest/gr/aws_tasks-that-require-root.html","Description": "With the creation of an AWS account, a 'root user' is created that cannot be disabled or deleted. That user has unrestricted access to and control over all resources in the AWS account. It is highly recommended that the use of this account be avoided for everyday tasks.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console at `https://console.aws.amazon.com/iam/` 2. In the left pane, click `Credential Report` 3. Click on `Download Report` 4. Open of Save the file locally 5. Locate the `` under the user column 6. Review `password_last_used, access_key_1_last_used_date, access_key_2_last_used_date` to determine when the 'root user' was last used.**From Command Line:**Run the following CLI commands to provide a credential report for determining the last time the 'root user' was used: ``` aws iam generate-credential-report ``` ``` aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,5,11,16 | grep -B1 '' ```Review `password_last_used`, `access_key_1_last_used_date`, `access_key_2_last_used_date` to determine when the _root user_ was last used.**Note:** There are a few conditions under which the use of the 'root' user account is required. Please see the reference links for all of the tasks that require use of the 'root' user.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "The 'root user' has unrestricted access to and control over all account resources. Use of it is inconsistent with the principles of least privilege and separation of duties, and can lead to unnecessary harm due to error or account compromise.","RemediationProcedure": "If you find that the 'root' user account is being used for daily activity to include administrative tasks that do not require the 'root' user:1. Change the 'root' user password. 2. Deactivate or delete any access keys associate with the 'root' user.**Remember, anyone who has 'root' user credentials for your AWS account has unrestricted access to and control of all the resources in your account, including billing information.","AdditionalInformation": "The 'root' user for us-gov cloud regions is not enabled by default. However, on request to AWS support, they can enable the 'root' user and grant access only through access-keys (CLI, API methods) for us-gov cloud region. If the 'root' user for us-gov cloud regions is enabled, this recommendation is applicable.Monitoring usage of the 'root' user can be accomplished by implementing recommendation 3.3 Ensure a log metric filter and alarm exist for usage of the 'root' user."}],"description": "Eliminate use of the 'root' user for administrative and daily tasks","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.8": {"name": "1.8","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy","Description": "Password policies are, in part, used to enforce password complexity requirements. IAM password policies can be used to ensure password are at least a given length. It is recommended that the password policy require a minimum password length 14.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure the password policy is configured as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Ensure \"Minimum password length\" is set to 14 or greater.**From Command Line:** ``` aws iam get-account-password-policy ``` Ensure the output of the above command includes \"MinimumPasswordLength\": 14 (or higher)","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Setting a password complexity policy increases account resiliency against brute force login attempts.","RemediationProcedure": "Perform the following to set the password policy as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Set \"Minimum password length\" to `14` or greater. 5. Click \"Apply password policy\"**From Command Line:** ```aws iam update-account-password-policy --minimum-password-length 14 ``` Note: All commands starting with \"aws iam update-account-password-policy\" can be combined into a single command.","AdditionalInformation": ""}],"description": "Ensure IAM password policy requires minimum length of 14 or greater","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.9": {"name": "1.9","checks": {"iam_password_policy_reuse_24": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy","Description": "IAM password policies can prevent the reuse of a given password by the same user. It is recommended that the password policy prevent the reuse of passwords.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure the password policy is configured as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Ensure \"Prevent password reuse\" is checked 5. Ensure \"Number of passwords to remember\" is set to 24**From Command Line:** ``` aws iam get-account-password-policy``` Ensure the output of the above command includes \"PasswordReusePrevention\": 24","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Preventing password reuse increases account resiliency against brute force login attempts.","RemediationProcedure": "Perform the following to set the password policy as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Check \"Prevent password reuse\" 5. Set \"Number of passwords to remember\" is set to `24` **From Command Line:** ```aws iam update-account-password-policy --password-reuse-prevention 24 ``` Note: All commands starting with \"aws iam update-account-password-policy\" can be combined into a single command.","AdditionalInformation": ""}],"description": "Ensure IAM password policy prevents password reuse","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.1": {"name": "3.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-management-events:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-management-and-data-events-with-cloudtrail.html?icmpid=docs_cloudtrail_console#logging-management-events:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-supported-services.html#cloud-trail-supported-services-data-events","Description": "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. CloudTrail provides a history of AWS API calls for an account, including API calls made via the Management Console, SDKs, command line tools, and higher-level AWS services (such as CloudFormation).","DefaultValue": null,"AuditProcedure": "Perform the following to determine if CloudTrail is enabled for all regions:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane- You will be presented with a list of trails across all regions 3. Ensure at least one Trail has `All` specified in the `Region` column 4. Click on a trail via the link in the _Name_ column 5. Ensure `Logging` is set to `ON`6. Ensure `Apply trail to all regions` is set to `Yes` 7. In section `Management Events` ensure `Read/Write Events` set to `ALL`**From Command Line:** ```aws cloudtrail describe-trails ``` Ensure `IsMultiRegionTrail` is set to `true```` aws cloudtrail get-trail-status --name  ``` Ensure `IsLogging` is set to `true` ``` aws cloudtrail get-event-selectors --trail-name  ``` Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`","ImpactStatement": "S3 lifecycle features can be used to manage the accumulation and management of logs over time. See the following AWS resource for more information on these features:1. https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html","AssessmentStatus": "Automated","RationaleStatement": "The AWS API call history produced by CloudTrail enables security analysis, resource change tracking, and compliance auditing. Additionally, - ensuring that a multi-regions trail exists will ensure that unexpected activity occurring in otherwise unused regions is detected- ensuring that a multi-regions trail exists will ensure that `Global Service Logging` is enabled for a trail by default to capture recording of events generated onAWS global services- for a multi-regions trail, ensuring that management events configured for all type of Read/Writes ensures recording of management operations that are performed on all resources in an AWS account","RemediationProcedure": "Perform the following to enable global (Multi-region) CloudTrail logging:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on _Trails_ on the left navigation pane 3. Click `Get Started Now` , if presented- Click `Add new trail` - Enter a trail name in the `Trail name` box- Set the `Apply trail to all regions` option to `Yes` - Specify an S3 bucket name in the `S3 bucket` box- Click `Create`4. If 1 or more trails already exist, select the target trail to enable for global logging 5. Click the edit icon (pencil) next to `Apply trail to all regions` , Click `Yes` and Click `Save`. 6. Click the edit icon (pencil) next to `Management Events` click `All` for setting `Read/Write Events` and Click `Save`.**From Command Line:** ``` aws cloudtrail create-trail --name  --bucket-name  --is-multi-region-trailaws cloudtrail update-trail --name  --is-multi-region-trail ```Note: Creating CloudTrail via CLI without providing any overriding options configures `Management Events` to set `All` type of `Read/Writes` by default.","AdditionalInformation": ""}],"description": "Ensure CloudTrail is enabled in all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3.2": {"name": "3.2","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-file-validation-enabling.html","Description": "CloudTrail log file validation creates a digitally signed digest file containing a hash of each log that CloudTrail writes to S3. These digest files can be used to determine whether a log file was changed, deleted, or unchanged after CloudTrail delivered the log. It is recommended that file validation be enabled on all CloudTrails.","DefaultValue": null,"AuditProcedure": "Perform the following on each trail to determine if log file validation is enabled:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane 3. For Every Trail: - Click on a trail via the link in the _Name_ column - Under the `General details` section, ensure `Log file validation` is set to `Enabled` **From Command Line:** ``` aws cloudtrail describe-trails ``` Ensure `LogFileValidationEnabled` is set to `true` for each trail","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling log file validation will provide additional integrity checking of CloudTrail logs.","RemediationProcedure": "Perform the following to enable log file validation on a given trail:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane 3. Click on target trail 4. Within the `General details` section click `edit` 5. Under the `Advanced settings` section 6. Check the enable box under `Log file validation`7. Click `Save changes` **From Command Line:** ``` aws cloudtrail update-trail --name  --enable-log-file-validation ``` Note that periodic validation of logs using these digests can be performed by running the following command: ``` aws cloudtrail validate-logs --trail-arn  --start-time  --end-time  ```","AdditionalInformation": ""}],"description": "Ensure CloudTrail log file validation is enabled","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.3": {"name": "3.3","checks": {"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html","Description": "CloudTrail logs a record of every API call made in your AWS account. These logs file are stored in an S3 bucket. It is recommended that the bucket policy or access control list (ACL) applied to the S3 bucket that CloudTrail logs to prevent public access to the CloudTrail logs.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if any public access is granted to an S3 bucket via an ACL or S3 bucket policy:**From Console:**1. Go to the Amazon CloudTrail console at [https://console.aws.amazon.com/cloudtrail/home](https://console.aws.amazon.com/cloudtrail/home) 2. In the `API activity history` pane on the left, click `Trails`3. In the `Trails` pane, note the bucket names in the `S3 bucket` column 4. Go to Amazon S3 console at [https://console.aws.amazon.com/s3/home](https://console.aws.amazon.com/s3/home) 5. For each bucket noted in step 3, right-click on the bucket and click `Properties`6. In the `Properties` pane, click the `Permissions` tab. 7. The tab shows a list of grants, one row per grant, in the bucket ACL. Each row identifies the grantee and the permissions granted. 8. Ensure no rows exists that have the `Grantee` set to `Everyone` or the `Grantee` set to `Any Authenticated User.`9. If the `Edit bucket policy` button is present, click it to review the bucket policy. 10. Ensure the policy does not contain a `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ```aws cloudtrail describe-trails --query 'trailList[*].S3BucketName' ``` 2. Ensure the `AllUsers` principal is not granted privileges to that `` : ```aws s3api get-bucket-acl --bucket  --query 'Grants[?Grantee.URI== `https://acs.amazonaws.com/groups/global/AllUsers` ]' ``` 3. Ensure the `AuthenticatedUsers` principal is not granted privileges to that ``: ```aws s3api get-bucket-acl --bucket  --query 'Grants[?Grantee.URI== `https://acs.amazonaws.com/groups/global/Authenticated Users` ]' ``` 4. Get the S3 Bucket Policy ```aws s3api get-bucket-policy --bucket ``` 5. Ensure the policy does not contain a `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}**Note:** Principal set to \"\\*\" or {\"AWS\" : \"\\*\"} allows anonymous access.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Allowing public access to CloudTrail log content may aid an adversary in identifying weaknesses in the affected account's use or configuration.","RemediationProcedure": "Perform the following to remove any public access that has been granted to the bucket via an ACL or S3 bucket policy:1. Go to Amazon S3 console at [https://console.aws.amazon.com/s3/home](https://console.aws.amazon.com/s3/home) 2. Right-click on the bucket and click Properties 3. In the `Properties` pane, click the `Permissions` tab. 4. The tab shows a list of grants, one row per grant, in the bucket ACL. Each row identifies the grantee and the permissions granted. 5. Select the row that grants permission to `Everyone` or `Any Authenticated User`6. Uncheck all the permissions granted to `Everyone` or `Any Authenticated User` (click `x` to delete the row). 7. Click `Save` to save the ACL. 8. If the `Edit bucket policy` button is present, click it. 9. Remove any `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}.","AdditionalInformation": ""}],"description": "Ensure the S3 bucket used to store CloudTrail logs is not publicly accessible","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3.4": {"name": "3.4","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-user-guide.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/how-cloudtrail-works.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-aws-service-specific-topics.html","Description": "AWS CloudTrail is a web service that records AWS API calls made in a given AWS account. 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. CloudTrail uses Amazon S3 for log file storage and delivery, so log files are stored durably. In addition to capturing CloudTrail logs within a specified S3 bucket for long term analysis, realtime analysis can be performed by configuring CloudTrail to send logs to CloudWatch Logs. For a trail that is enabled in all regions in an account, CloudTrail sends log files from all those regions to a CloudWatch Logs log group. It is recommended that CloudTrail logs be sent to CloudWatch Logs.Note: The intent of this recommendation is to ensure AWS account activity is being captured, monitored, and appropriately alarmed on. CloudWatch Logs is a native way to accomplish this using AWS services but does not preclude the use of an alternate solution.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure CloudTrail is configured as prescribed:**From Console:**1. Login to the CloudTrail console at `https://console.aws.amazon.com/cloudtrail/` 2. Under `Trails` , click on the CloudTrail you wish to evaluate 3. Under the `CloudWatch Logs` section. 4. Ensure a `CloudWatch Logs` log group is configured and listed. 5. Under `General details` confirm `Last log file delivered` has a recent (~one day old) timestamp.**From Command Line:**1. Run the following command to get a listing of existing trails: ```aws cloudtrail describe-trails ``` 2. Ensure `CloudWatchLogsLogGroupArn` is not empty and note the value of the `Name` property. 3. Using the noted value of the `Name` property, run the following command: ```aws cloudtrail get-trail-status --name  ``` 4. Ensure the `LatestcloudwatchLogdDeliveryTime` property is set to a recent (~one day old) timestamp.If the `CloudWatch Logs` log group is not setup and the delivery time is not recent refer to the remediation below.","ImpactStatement": "Note: By default, CloudWatch Logs will store Logs indefinitely unless a specific retention period is defined for the log group. When choosing the number of days to retain, keep in mind the average days it takes an organization to realize they have been breached is 210 days (at the time of this writing). Since additional time is required to research a breach, a minimum 365 day retention policy allows time for detection and research. You may also wish to archive the logs to a cheaper storage service rather than simply deleting them. See the following AWS resource to manage CloudWatch Logs retention periods:1. https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/SettingLogRetention.html","AssessmentStatus": "Automated","RationaleStatement": "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.","RemediationProcedure": "Perform the following to establish the prescribed state:**From Console:**1. Login to the CloudTrail console at `https://console.aws.amazon.com/cloudtrail/` 2. Select the `Trail` the needs to be updated. 3. Scroll down to `CloudWatch Logs` 4. Click `Edit` 5. Under `CloudWatch Logs` click the box `Enabled` 6. Under `Log Group` pick new or select an existing log group 7. Edit the `Log group name` to match the CloudTrail or pick the existing CloudWatch Group. 8. Under `IAM Role` pick new or select an existing. 9. Edit the `Role name` to match the CloudTrail or pick the existing IAM Role. 10. Click `Save changes.**From Command Line:** ``` aws cloudtrail update-trail --name  --cloudwatch-logs-log-group-arn  --cloudwatch-logs-role-arn  ```","AdditionalInformation": ""}],"description": "Ensure CloudTrail trails are integrated with CloudWatch Logs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.5": {"name": "3.5","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/cli/latest/reference/configservice/describe-configuration-recorder-status.html","Description": "AWS Config is a web service that performs configuration management of supported AWS resources within your account and delivers log files to you. The recorded information includes the configuration item (AWS resource), relationships between configuration items (AWS resources), any configuration changes between resources. It is recommended AWS Config be enabled in all regions.","DefaultValue": null,"AuditProcedure": "Process to evaluate AWS Config configuration per region**From Console:**1. Sign in to the AWS Management Console and open the AWS Config console at [https://console.aws.amazon.com/config/](https://console.aws.amazon.com/config/). 2. On the top right of the console select target Region. 3. If presented with Setup AWS Config - follow remediation procedure: 4. On the Resource inventory page, Click on edit (the gear icon). The Set Up AWS Config page appears. 5. Ensure 1 or both check-boxes under \"All Resources\" is checked.- Include global resources related to IAM resources - which needs to be enabled in 1 region only 6. Ensure the correct S3 bucket has been defined. 7. Ensure the correct SNS topic has been defined. 8. Repeat steps 2 to 7 for each region.**From Command Line:**1. Run this command to show all AWS Config recorders and their properties: ``` aws configservice describe-configuration-recorders ``` 2. Evaluate the output to ensure that there's at least one recorder for which `recordingGroup` object includes `\"allSupported\": true` AND `\"includeGlobalResourceTypes\": true`Note: There is one more parameter \"ResourceTypes\" in recordingGroup object. We don't need to check the same as whenever we set \"allSupported\": true, AWS enforces resource types to be empty (\"ResourceTypes\":[])Sample Output:``` {\"ConfigurationRecorders\": [{\"recordingGroup\": {\"allSupported\": true,\"resourceTypes\": [],\"includeGlobalResourceTypes\": true},\"roleARN\": \"arn:aws:iam:::role/service-role/\",\"name\": \"default\"}] } ```3. Run this command to show the status for all AWS Config recorders: ``` aws configservice describe-configuration-recorder-status ``` 4. In the output, find recorders with `name` key matching the recorders that met criteria in step 2. Ensure that at least one of them includes `\"recording\": true` and `\"lastStatus\": \"SUCCESS\"`","ImpactStatement": "It is recommended AWS Config be enabled in all regions.","AssessmentStatus": "Automated","RationaleStatement": "The AWS configuration item history captured by AWS Config enables security analysis, resource change tracking, and compliance auditing.","RemediationProcedure": "To implement AWS Config configuration:**From Console:**1. Select the region you want to focus on in the top right of the console 2. Click `Services`3. Click `Config`4. Define which resources you want to record in the selected region 5. Choose to include global resources (IAM resources) 6. Specify an S3 bucket in the same account or in another managed AWS account 7. Create an SNS Topic from the same AWS account or another managed AWS account**From Command Line:**1. Ensure there is an appropriate S3 bucket, SNS topic, and IAM role per the [AWS Config Service prerequisites](http://docs.aws.amazon.com/config/latest/developerguide/gs-cli-prereq.html). 2. Run this command to set up the configuration recorder ``` aws configservice subscribe --s3-bucket my-config-bucket --sns-topic arn:aws:sns:us-east-1:012345678912:my-config-notice --iam-role arn:aws:iam::012345678912:role/myConfigRole ``` 3. Run this command to start the configuration recorder: ``` start-configuration-recorder --configuration-recorder-name  ```","AdditionalInformation": ""}],"description": "Ensure AWS Config is enabled in all regions","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.6": {"name": "3.6","checks": {"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerLogs.html","Description": "S3 Bucket Access Logging generates a log that contains access records for each request made to your S3 bucket. An access log record contains details about the request, such as the request type, the resources specified in the request worked, and the time and date the request was processed. It is recommended that bucket access logging be enabled on the CloudTrail S3 bucket.","DefaultValue": null,"AuditProcedure": "Perform the following ensure the CloudTrail S3 bucket has access logging is enabled:**From Console:**1. Go to the Amazon CloudTrail console at [https://console.aws.amazon.com/cloudtrail/home](https://console.aws.amazon.com/cloudtrail/home) 2. In the API activity history pane on the left, click Trails 3. In the Trails pane, note the bucket names in the S3 bucket column 4. Sign in to the AWS Management Console and open the S3 console at [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3). 5. Under `All Buckets` click on a target S3 bucket 6. Click on `Properties` in the top right of the console 7. Under `Bucket:` _ `` _ click on `Logging`8. Ensure `Enabled` is checked.**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ```aws cloudtrail describe-trails --query 'trailList[*].S3BucketName'``` 2. Ensure Bucket Logging is enabled: ``` aws s3api get-bucket-logging --bucket  ``` Ensure command does not returns empty output.Sample Output for a bucket with logging enabled:``` {\"LoggingEnabled\": {\"TargetPrefix\": \"\",\"TargetBucket\": \"\"} } ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "By enabling S3 bucket logging on target S3 buckets, it is possible to capture all events which may affect objects within any target buckets. Configuring logs to be placed in a separate bucket allows access to log information which can be useful in security and incident response workflows.","RemediationProcedure": "Perform the following to enable S3 bucket logging:**From Console:**1. Sign in to the AWS Management Console and open the S3 console at [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3). 2. Under `All Buckets` click on the target S3 bucket 3. Click on `Properties` in the top right of the console 4. Under `Bucket:`  click on `Logging`5. Configure bucket logging- Click on the `Enabled` checkbox- Select Target Bucket from list- Enter a Target Prefix 6. Click `Save`.**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ``` aws cloudtrail describe-trails --region  --query trailList[*].S3BucketName ``` 2. Copy and add target bucket name at ``, Prefix for logfile at `` and optionally add an email address in the following template and save it as ``: ``` {\"LoggingEnabled\": {\"TargetBucket\": \"\",\"TargetPrefix\": \"\",\"TargetGrants\": [{\"Grantee\": {\"Type\": \"AmazonCustomerByEmail\",\"EmailAddress\": \"\"},\"Permission\": \"FULL_CONTROL\"}]}} ``` 3. Run the `put-bucket-logging` command with bucket name and `` as input, for more information refer at [put-bucket-logging](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-logging.html): ``` aws s3api put-bucket-logging --bucket  --bucket-logging-status file:// ```","AdditionalInformation": ""}],"description": "Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.7": {"name": "3.7","checks": {"cloudtrail_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/encrypting-cloudtrail-log-files-with-aws-kms.html:https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html","Description": "AWS CloudTrail is a web service that records AWS API calls for an account and makes those logs available to users and resources in accordance with IAM policies. AWS Key Management Service (KMS) is a managed service that helps create and control the encryption keys used to encrypt account data, and uses Hardware Security Modules (HSMs) to protect the security of encryption keys. CloudTrail logs can be configured to leverage server side encryption (SSE) and KMS customer created master keys (CMK) to further protect CloudTrail logs. It is recommended that CloudTrail be configured to use SSE-KMS.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if CloudTrail is configured to use SSE-KMS:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. In the left navigation pane, choose `Trails` . 3. Select a Trail 4. Under the `S3` section, ensure `Encrypt log files` is set to `Yes` and a KMS key ID is specified in the `KSM Key Id` field.**From Command Line:**1. Run the following command: ```aws cloudtrail describe-trails``` 2. For each trail listed, SSE-KMS is enabled if the trail has a `KmsKeyId` property defined.","ImpactStatement": "Customer created keys incur an additional cost. See https://aws.amazon.com/kms/pricing/ for more information.","AssessmentStatus": "Automated","RationaleStatement": "Configuring CloudTrail to use SSE-KMS provides additional confidentiality controls on log data as a given user must have S3 read permission on the corresponding log bucket and must be granted decrypt permission by the CMK policy.","RemediationProcedure": "Perform the following to configure CloudTrail to use SSE-KMS:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. In the left navigation pane, choose `Trails` . 3. Click on a Trail 4. Under the `S3` section click on the edit button (pencil icon) 5. Click `Advanced`6. Select an existing CMK from the `KMS key Id` drop-down menu- Note: Ensure the CMK is located in the same region as the S3 bucket- Note: You will need to apply a KMS Key policy on the selected CMK in order for CloudTrail as a service to encrypt and decrypt log files using the CMK provided. Steps are provided [here](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/create-kms-key-policy-for-cloudtrail.html) for editing the selected CMK Key policy 7. Click `Save`8. You will see a notification message stating that you need to have decrypt permissions on the specified KMS key to decrypt log files. 9. Click `Yes` **From Command Line:** ``` aws cloudtrail update-trail --name  --kms-id  aws kms put-key-policy --key-id  --policy  ```","AdditionalInformation": "3 statements which need to be added to the CMK policy:1\\. Enable Cloudtrail to describe CMK properties ``` 
{\"Sid\": \"Allow CloudTrail access\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\"Action\": \"kms:DescribeKey\",\"Resource\": \"*\" } ``` 2\\. Granting encrypt permissions ``` 
{\"Sid\": \"Allow CloudTrail to encrypt logs\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\"Action\": \"kms:GenerateDataKey*\",\"Resource\": \"*\",\"Condition\": {\"StringLike\": {\"kms:EncryptionContext:aws:cloudtrail:arn\": [\"arn:aws:cloudtrail:*:aws-account-id:trail/*\"]}} } ``` 3\\. Granting decrypt permissions ``` 
{\"Sid\": \"Enable CloudTrail log decrypt permissions\",\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"arn:aws:iam::aws-account-id:user/username\"},\"Action\": \"kms:Decrypt\",\"Resource\": \"*\",\"Condition\": {\"Null\": {\"kms:EncryptionContext:aws:cloudtrail:arn\": \"false\"}} } ```"}],"description": "Ensure CloudTrail logs are encrypted at rest using KMS CMKs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.8": {"name": "3.8","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://aws.amazon.com/kms/pricing/:https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final","Description": "AWS Key Management Service (KMS) allows customers to rotate the backing key which is key material stored within the KMS which is tied to the key ID of the Customer Created customer master key (CMK). It is the backing key that is used to perform cryptographic operations such as encryption and decryption. Automated key rotation currently retains all prior backing keys so that decryption of encrypted data can take place transparently. It is recommended that CMK key rotation be enabled for symmetric keys. Key rotation can not be enabled for any asymmetric CMK.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam](https://console.aws.amazon.com/iam). 2. In the left navigation pane, choose `Customer managed keys` 3. Select a customer managed CMK where `Key spec = SYMMETRIC_DEFAULT` 4. Underneath the `General configuration` panel open the tab `Key rotation` 5. Ensure that the checkbox `Automatically rotate this KMS key every year.` is activated 6. Repeat steps 3 - 5 for all customer managed CMKs where \"Key spec = SYMMETRIC_DEFAULT\"**From Command Line:**1. Run the following command to get a list of all keys and their associated `KeyIds````aws kms list-keys ``` 2. For each key, note the KeyId and run the following command ``` describe-key --key-id  ``` 3. If the response contains \"KeySpec = SYMMETRIC_DEFAULT\" run the following command ```aws kms get-key-rotation-status --key-id  ``` 4. Ensure `KeyRotationEnabled` is set to `true` 5. Repeat steps 2 - 4 for all remaining CMKs","ImpactStatement": "Creation, management, and storage of CMKs may require additional time from and administrator.","AssessmentStatus": "Automated","RationaleStatement": "Rotating encryption keys helps reduce the potential impact of a compromised key as data encrypted with a new key cannot be accessed with a previous key that may have been exposed. Keys should be rotated every year, or upon event that would result in the compromise of that key.","RemediationProcedure": "**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam](https://console.aws.amazon.com/iam). 2. In the left navigation pane, choose `Customer managed keys` . 3. Select a customer managed CMK where `Key spec = SYMMETRIC_DEFAULT` 4. Underneath the \"General configuration\" panel open the tab \"Key rotation\" 5. Check the \"Automatically rotate this KMS key every year.\" checkbox**From Command Line:**1. Run the following command to enable key rotation: ```aws kms enable-key-rotation --key-id  ```","AdditionalInformation": ""}],"description": "Ensure rotation for customer created symmetric CMKs is enabled","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.9": {"name": "3.9","checks": {"vpc_flow_logs_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/flow-logs.html","Description": "VPC Flow Logs is a feature that enables you to capture information about the IP traffic going to and from network interfaces in your VPC. After you've created a flow log, you can view and retrieve its data in Amazon CloudWatch Logs. It is recommended that VPC Flow Logs be enabled for packet \"Rejects\" for VPCs.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if VPC Flow logs are enabled:**From Console:**1. Sign into the management console 2. Select `Services` then `VPC`3. In the left navigation pane, select `Your VPCs`4. Select a VPC 5. In the right pane, select the `Flow Logs` tab. 6. Ensure a Log Flow exists that has `Active` in the `Status` column.**From Command Line:**1. Run `describe-vpcs` command (OSX/Linux/UNIX) to list the VPC networks available in the current AWS region: ``` aws ec2 describe-vpcs --region  --query Vpcs[].VpcId ``` 2. The command output returns the `VpcId` available in the selected region. 3. Run `describe-flow-logs` command (OSX/Linux/UNIX) using the VPC ID to determine if the selected virtual network has the Flow Logs feature enabled: ``` aws ec2 describe-flow-logs --filter \"Name=resource-id,Values=\" ``` 4. If there are no Flow Logs created for the selected VPC, the command output will return an `empty list []`. 5. Repeat step 3 for other VPCs available in the same region. 6. Change the region by updating `--region` and repeat steps 1 - 5 for all the VPCs.","ImpactStatement": "By default, CloudWatch Logs will store Logs indefinitely unless a specific retention period is defined for the log group. When choosing the number of days to retain, keep in mind the average days it takes an organization to realize they have been breached is 210 days (at the time of this writing). Since additional time is required to research a breach, a minimum 365 day retention policy allows time for detection and research. You may also wish to archive the logs to a cheaper storage service rather than simply deleting them. See the following AWS resource to manage CloudWatch Logs retention periods:1. https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/SettingLogRetention.html","AssessmentStatus": "Automated","RationaleStatement": "VPC Flow Logs provide visibility into network traffic that traverses the VPC and can be used to detect anomalous traffic or insight during security workflows.","RemediationProcedure": "Perform the following to determine if VPC Flow logs is enabled:**From Console:**1. Sign into the management console 2. Select `Services` then `VPC`3. In the left navigation pane, select `Your VPCs`4. Select a VPC 5. In the right pane, select the `Flow Logs` tab. 6. If no Flow Log exists, click `Create Flow Log`7. For Filter, select `Reject` 8. Enter in a `Role` and `Destination Log Group`9. Click `Create Log Flow`10. Click on `CloudWatch Logs Group` **Note:** Setting the filter to \"Reject\" will dramatically reduce the logging data accumulation for this recommendation and provide sufficient information for the purposes of breach detection, research and remediation. However, during periods of least privilege security group engineering, setting this the filter to \"All\" can be very helpful in discovering existing traffic flows required for proper operation of an already running environment.**From Command Line:**1. Create a policy document and name it as `role_policy_document.json` and paste the following content: ``` {\"Version\": \"2012-10-17\",\"Statement\": [{\"Sid\": \"test\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"ec2.amazonaws.com\"},\"Action\": \"sts:AssumeRole\"}] } ``` 2. Create another policy document and name it as `iam_policy.json` and paste the following content: ``` {\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Action\":[\"logs:CreateLogGroup\",\"logs:CreateLogStream\",\"logs:DescribeLogGroups\",\"logs:DescribeLogStreams\",\"logs:PutLogEvents\",\"logs:GetLogEvents\",\"logs:FilterLogEvents\"],\"Resource\": \"*\"}] } ``` 3. Run the below command to create an IAM role: ``` aws iam create-role --role-name  --assume-role-policy-document file://role_policy_document.json``` 4. Run the below command to create an IAM policy: ``` aws iam create-policy --policy-name  --policy-document file://iam-policy.json ``` 5. Run `attach-group-policy` command using the IAM policy ARN returned at the previous step to attach the policy to the IAM role (if the command succeeds, no output is returned): ``` aws iam attach-group-policy --policy-arn arn:aws:iam:::policy/ --group-name  ``` 6. Run `describe-vpcs` to get the VpcId available in the selected region: ``` aws ec2 describe-vpcs --region  ``` 7. The command output should return the VPC Id available in the selected region. 8. Run `create-flow-logs` to create a flow log for the vpc: ``` aws ec2 create-flow-logs --resource-type VPC --resource-ids  --traffic-type REJECT --log-group-name  --deliver-logs-permission-arn  ``` 9. Repeat step 8 for other vpcs available in the selected region. 10. Change the region by updating --region and repeat remediation procedure for other vpcs.","AdditionalInformation": ""}],"description": "Ensure VPC flow logging is enabled in all VPCs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"4.1": {"name": "4.1","checks": {"cloudwatch_log_metric_filter_unauthorized_api_calls": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://aws.amazon.com/sns/:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for unauthorized API calls.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with \"Name\":` note ``- From value associated with \"CloudWatchLogsLogGroupArn\" note Example: for CloudWatchLogsLogGroupArn that looks like arn:aws:logs:::log-group:NewGroup:*,  would be NewGroup- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name <\"Name\" as shown in describe-trails>`Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this `` that you captured in step 1:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.errorCode = *UnauthorizedOperation) || ($.errorCode = AccessDenied*) || ($.sourceIPAddress!=delivery.logs.amazonaws.com) || ($.eventName!=HeadBucket) }\", ```4. Note the \"filterName\" `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query \"MetricAlarms[?MetricName == `unauthorized_api_calls_metric`]\" ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "This alert may be triggered by normal read-only console activities that attempt to opportunistically gather optional information, but gracefully fail if they don't have permissions.If an excessive number of alerts are being generated then an organization may wish to consider adding read access to the limited IAM user permissions simply to quiet the alerts.In some cases doing this may allow the users to actually view some areas of the system - any additional access given should be reviewed for alignment with the original limited IAM user intent.","AssessmentStatus": "Automated","RationaleStatement": "Monitoring unauthorized API calls will help reveal application errors and may reduce time to detect malicious activity.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for unauthorized API calls and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name \"cloudtrail_log_group_name\" --filter-name \"\" --metric-transformations metricName=unauthorized_api_calls_metric,metricNamespace=CISBenchmark,metricValue=1 --filter-pattern \"{ ($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\") || ($.sourceIPAddress!=\"delivery.logs.amazonaws.com\") || ($.eventName!=\"HeadBucket\") }\" ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms. **Note**: Capture the TopicArn displayed when creating the SNS Topic in Step 2.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name \"unauthorized_api_calls_alarm\" --metric-name \"unauthorized_api_calls_metric\" --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace \"CISBenchmark\" --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for unauthorized API calls","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.2": {"name": "4.2","checks": {"cloudwatch_log_metric_filter_sign_in_without_mfa": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/viewing_metrics_with_cloudwatch.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for console logins that are not protected by multi-factor authentication (MFA).","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all `CloudTrails`:``` aws cloudtrail describe-trails ```- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region `CloudTrail` is active``` aws cloudtrail get-trail-status --name  ```Ensure in the output that `IsLogging` is set to `TRUE`- Ensure identified Multi-region 'Cloudtrail' captures all Management Events``` aws cloudtrail get-event-selectors --trail-name  ```Ensure in the output there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }\" ```Or (To reduce false positives incase Single Sign-On (SSO) is used in organization):``` \"filterPattern\": \"{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\") }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring for single-factor console logins will increase visibility into accounts that are not protected by MFA.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Management Console sign-in without MFA and the `` taken from audit step 1.Use Command: ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }' ```Or (To reduce false positives incase Single Sign-On (SSO) is used in organization):``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\") }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored -Filter pattern set to `{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\"}` reduces false alarms raised when user logs in via SSO account."}],"description": "Ensure a log metric filter and alarm exist for Management Console sign-in without MFA","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.3": {"name": "4.3","checks": {"cloudwatch_log_metric_filter_root_usage": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for 'root' login attempts.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails:`aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring for 'root' account logins will provide visibility into the use of a fully privileged account and an opportunity to reduce the use of it.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for 'Root' account usage and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name `` --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "**Configuring log metric filter and alarm on Multi-region (global) CloudTrail**- ensures that activities from all regions (used as well as unused) are monitored- ensures that activities on all supported global services are monitored- ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for usage of 'root' account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.4": {"name": "4.4","checks": {"cloudwatch_log_metric_filter_policy_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established changes made to Identity and Access Management (IAM) policies.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails:`aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to IAM policies will help ensure authentication and authorization controls remain intact.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for IAM policy changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name `` --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for IAM policy changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.5": {"name": "4.5","checks": {"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for detecting changes to CloudTrail's configurations.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to CloudTrail's configuration will help ensure sustained visibility to activities performed in the AWS account.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for cloudtrail configuration changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for CloudTrail configuration changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.6": {"name": "4.6","checks": {"cloudwatch_log_metric_filter_authentication_failures": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for failed console authentication attempts.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring failed console logins may decrease lead time to detect an attempt to brute force a credential, which may provide an indicator, such as source IP, that can be used in other event correlation.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS management Console Login Failures and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }' ``` **Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for AWS Management Console authentication failures","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.7": {"name": "4.7","checks": {"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for customer created CMKs which have changed state to disabled or scheduled deletion.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Data encrypted with disabled or deleted keys will no longer be accessible.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for disabled or scheduled for deletion CMK's and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }' ``` **Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.8": {"name": "4.8","checks": {"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for changes to S3 bucket policies.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to S3 bucket policies may reduce time to detect and correct permissive policies on sensitive S3 buckets.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for S3 bucket policy changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for S3 bucket policy changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.9": {"name": "4.9","checks": {"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for detecting changes to CloudTrail's configurations.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to AWS Config configuration will help ensure sustained visibility of configuration items within the AWS account.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Configuration changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for AWS Config configuration changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"5.1": {"name": "5.1","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html:https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Security.html#VPC_Security_Comparison","Description": "The Network Access Control List (NACL) function provide stateless filtering of ingress and egress network traffic to AWS resources. It is recommended that no NACL allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "**From Console:**Perform the following to determine if the account is configured as prescribed: 1. Login to the AWS Management Console at https://console.aws.amazon.com/vpc/home 2. In the left pane, click `Network ACLs` 3. For each network ACL, perform the following:- Select the network ACL- Click the `Inbound Rules` tab- Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `0.0.0.0/0` and shows `ALLOW`**Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "**From Console:**Perform the following: 1. Login to the AWS Management Console at https://console.aws.amazon.com/vpc/home 2. In the left pane, click `Network ACLs` 3. For each network ACL to remediate, perform the following:- Select the network ACL- Click the `Inbound Rules` tab- Click `Edit inbound rules`- Either A) update the Source field to a range other than 0.0.0.0/0, or, B) Click `Delete` to remove the offending inbound rule- Click `Save`","AdditionalInformation": ""}],"description": "Ensure no Network ACLs allow ingress from 0.0.0.0/0 to remote server administration ports","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"5.2": {"name": "5.2","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#deleting-security-group-rule","Description": "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `0.0.0.0/0` **Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports.","ImpactStatement": "When updating an existing environment, ensure that administrators have access to remote server administration ports through another mechanism before removing access by deleting the 0.0.0.0/0 inbound rule.","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "Perform the following to implement the prescribed state:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Click the `Edit inbound rules` button 4. Identify the rules to be edited or removed 5. Either A) update the Source field to a range other than 0.0.0.0/0, or, B) Click `Delete` to remove the offending inbound rule 6. Click `Save rules`","AdditionalInformation": ""}],"description": "Ensure no security groups allow ingress from 0.0.0.0/0 to remote server administration ports","checks_status": {"fail": 0,"pass": 3,"total": 3,"manual": 0}},"5.3": {"name": "5.3","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#deleting-security-group-rule","Description": "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `::/0` **Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports.","ImpactStatement": "When updating an existing environment, ensure that administrators have access to remote server administration ports through another mechanism before removing access by deleting the ::/0 inbound rule.","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "Perform the following to implement the prescribed state:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Click the `Edit inbound rules` button 4. Identify the rules to be edited or removed 5. Either A) update the Source field to a range other than ::/0, or, B) Click `Delete` to remove the offending inbound rule 6. Click `Save rules`","AdditionalInformation": ""}],"description": "Ensure no security groups allow ingress from ::/0 to remote server administration ports","checks_status": {"fail": 0,"pass": 3,"total": 3,"manual": 0}},"5.4": {"name": "5.4","checks": {"ec2_securitygroup_default_restrict_traffic": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#default-security-group","Description": "A VPC comes with a default security group whose initial settings deny all inbound traffic, allow all outbound traffic, and allow all traffic between instances assigned to the security group. If you don't specify a security group when you launch an instance, the instance is automatically assigned to this default security group. Security groups provide stateful filtering of ingress/egress network traffic to AWS resources. It is recommended that the default security group restrict all traffic.The default VPC in every region should have its default security group updated to comply. Any newly created VPCs will automatically contain a default security group that will need remediation to comply with this recommendation.**NOTE:** When implementing this recommendation, VPC flow logging is invaluable in determining the least privilege port access required by systems to work properly because it can log all packet acceptances and rejections occurring under the current security groups. This dramatically reduces the primary barrier to least privilege engineering - discovering the minimum ports required by systems in the environment. Even if the VPC flow logging recommendation in this benchmark is not adopted as a permanent security measure, it should be used during any period of discovery and engineering for least privileged security groups.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:Security Group State1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. For each default security group, perform the following: 1. Select the `default` security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exist 4. Click the `Outbound Rules` tab 5. Ensure no rules existSecurity Group Members1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all default groups in all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. Copy the id of the default security group. 5. Change to the EC2 Management Console at https://console.aws.amazon.com/ec2/v2/home 6. In the filter column type 'Security Group ID : < security group id from #4 >'","ImpactStatement": "Implementing this recommendation in an existing VPC containing operating resources requires extremely careful migration planning as the default security groups are likely to be enabling many ports that are unknown. Enabling VPC flow logging (of accepts) in an existing environment that is known to be breach free will reveal the current pattern of ports being used for each instance to communicate successfully.","AssessmentStatus": "Automated","RationaleStatement": "Configuring all VPC default security groups to restrict all traffic will encourage least privilege security group development and mindful placement of AWS resources into security groups which will in-turn reduce the exposure of those resources.","RemediationProcedure": "Security Group MembersPerform the following to implement the prescribed state:1. Identify AWS resources that exist within the default security group 2. Create a set of least privilege security groups for those resources 3. Place the resources in those security groups 4. Remove the resources noted in #1 from the default security groupSecurity Group State1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. For each default security group, perform the following: 1. Select the `default` security group 2. Click the `Inbound Rules` tab 3. Remove any inbound rules 4. Click the `Outbound Rules` tab 5. Remove any Outbound rulesRecommended:IAM groups allow you to edit the \"name\" field. After remediating default groups rules for all VPCs in all regions, edit this field to add text similar to \"DO NOT USE. DO NOT ADD RULES\"","AdditionalInformation": ""}],"description": "Ensure the default security group of every VPC restricts all traffic","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"5.5": {"name": "5.5","checks": {"vpc_peering_routing_tables_with_least_privilege": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "5. Networking","References": "https://docs.aws.amazon.com/AmazonVPC/latest/PeeringGuide/peering-configurations-partial-access.html:https://docs.aws.amazon.com/cli/latest/reference/ec2/create-vpc-peering-connection.html","Description": "Once a VPC peering connection is established, routing tables must be updated to establish any connections between the peered VPCs. These routes can be as specific as desired - even peering a VPC to only a single host on the other side of the connection.","DefaultValue": null,"AuditProcedure": "Review routing tables of peered VPCs for whether they route all subnets of each VPC and whether that is necessary to accomplish the intended purposes for peering the VPCs.**From Command Line:**1. List all the route tables from a VPC and check if \"GatewayId\" is pointing to a __ (e.g. pcx-1a2b3c4d) and if \"DestinationCidrBlock\" is as specific as desired. ``` aws ec2 describe-route-tables --filter \"Name=vpc-id,Values=\" --query \"RouteTables[*].{RouteTableId:RouteTableId, VpcId:VpcId, Routes:Routes, AssociatedSubnets:Associations[*].SubnetId}\" ```","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Being highly selective in peering routing tables is a very effective way of minimizing the impact of breach as resources outside of these routes are inaccessible to the peered VPC.","RemediationProcedure": "Remove and add route table entries to ensure that the least number of subnets or hosts as is required to accomplish the purpose for peering are routable.**From Command Line:**1. For each __ containing routes non compliant with your routing policy (which grants more than desired \"least access\"), delete the non compliant route: ``` aws ec2 delete-route --route-table-id  --destination-cidr-block  ```2. Create a new compliant route: ``` aws ec2 create-route --route-table-id  --destination-cidr-block  --vpc-peering-connection-id  ```","AdditionalInformation": "If an organization has AWS transit gateway implemented in their VPC architecture they should look to apply the recommendation above for \"least access\" routing architecture at the AWS transit gateway level in combination with what must be implemented at the standard VPC route table. More specifically, to route traffic between two or more VPCs via a transit gateway VPCs must have an attachment to a transit gateway route table as well as a route, therefore to avoid routing traffic between VPCs an attachment to the transit gateway route table should only be added where there is an intention to route traffic between the VPCs. As transit gateways are able to host multiple route tables it is possible to group VPCs by attaching them to a common route table."}],"description": "Ensure routing tables for VPC peering are \"least access\"","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"5.6": {"name": "5.6","checks": {"ec2_instance_imdsv2_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service/:https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html","Description": "When enabling the Metadata Service on AWS EC2 instances, users have the option of using either Instance Metadata Service Version 1 (IMDSv1; a request/response method) or Instance Metadata Service Version 2 (IMDSv2; a session-oriented method).","DefaultValue": null,"AuditProcedure": "From Console:1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under the Instances menu, select Instances.3. For each Instance, select the instance, then choose Actions > Modify instance metadata options.4. If the Instance metadata service is enabled, verify whether IMDSv2 is set to required. From Command Line:1. Use the describe-instances CLI command2. Ensure for all ec2 instances that the metadata-options.http-tokens setting is set to required.3. Repeat for all active regions.```aws ec2 describe-instances --filters \"\"Name=metadata-options.http-tokens\",\"Values=optional\" \"\"Name=metadata-options.state\"\",\"\"Values=applied\"\" --query \"\"Reservations[*].Instances[*].\"\" ``` ","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Allowing Version 1 of the service may open EC2 instances to Server-Side Request Forgery (SSRF) attacks, so Amazon recommends utilizing Version 2 for better instance security.","RemediationProcedure": "From Console:1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/ 2. Under the Instances menu, select Instances.3. For each Instance, select the instance, then choose Actions > Modify instance metadata options.4. If the Instance metadata service is enabled, set IMDSv2 to Required. From Command Line:```aws ec2 modify-instance-metadata-options --instance-id  --http-tokens required``` ","AdditionalInformation": ""}],"description": "Ensure that EC2 Metadata Service only allows IMDSv2","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.10": {"name": "1.10","checks": {"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://tools.ietf.org/html/rfc6238:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#enable-mfa-for-privileged-users:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html:https://blogs.aws.amazon.com/security/post/Tx2SJJYE082KBUK/How-to-Delegate-Management-of-Multi-Factor-Authentication-to-AWS-IAM-Users","Description": "Multi-Factor Authentication (MFA) adds an extra layer of authentication assurance beyond traditional credentials. With MFA enabled, when a user signs in to the AWS Console, they will be prompted for their user name and password as well as for an authentication code from their physical or virtual MFA token. It is recommended that MFA be enabled for all accounts that have a console password.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if a MFA device is enabled for all IAM users having a console password:**From Console:**1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the left pane, select `Users`3. If the `MFA` or `Password age` columns are not visible in the table, click the gear icon at the upper right corner of the table and ensure a checkmark is next to both, then click `Close`. 4. Ensure that for each user where the `Password age` column shows a password age, the `MFA` column shows `Virtual`, `U2F Security Key`, or `Hardware`.**From Command Line:**1. Run the following command (OSX/Linux/UNIX) to generate a list of all IAM users along with their password and MFA status: ```aws iam generate-credential-report ``` ```aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,8``` 2. The output of this command will produce a table similar to the following: ```user,password_enabled,mfa_activeelise,false,falsebrandon,true,truerakesh,false,falsehelene,false,falseparas,true,trueanitha,false,false``` 3. For any column having `password_enabled` set to `true` , ensure `mfa_active` is also set to `true.`","ImpactStatement": "AWS will soon end support for SMS multi-factor authentication (MFA). New customers are not allowed to use this feature. We recommend that existing customers switch to one of the following alternative methods of MFA.","AssessmentStatus": "Automated","RationaleStatement": "Enabling MFA provides increased security for console access as it requires the authenticating principal to possess a device that displays a time-sensitive key and have knowledge of a credential.","RemediationProcedure": "Perform the following to enable MFA:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at 'https://console.aws.amazon.com/iam/' 2. In the left pane, select `Users`. 3. In the `User Name` list, choose the name of the intended MFA user. 4. Choose the `Security Credentials` tab, and then choose `Manage MFA Device`. 5. In the `Manage MFA Device wizard`, choose `Virtual MFA` device, and then choose `Continue`. IAM generates and displays configuration information for the virtual MFA device, including a QR code graphic. The graphic is a representation of the 'secret configuration key' that is available for manual entry on devices that do not support QR codes.6. Open your virtual MFA application. (For a list of apps that you can use for hosting virtual MFA devices, see Virtual MFA Applications at https://aws.amazon.com/iam/details/mfa/#Virtual_MFA_Applications). If the virtual MFA application supports multiple accounts (multiple virtual MFA devices), choose the option to create a new account (a new virtual MFA device). 7. Determine whether the MFA app supports QR codes, and then do one of the following: - Use the app to scan the QR code. For example, you might choose the camera icon or choose an option similar to Scan code, and then use the device's camera to scan the code.- In the Manage MFA Device wizard, choose Show secret key for manual configuration, and then type the secret configuration key into your MFA application. When you are finished, the virtual MFA device starts generating one-time passwords.8. In the `Manage MFA Device wizard`, in the `MFA Code 1 box`, type the `one-time password` that currently appears in the virtual MFA device. Wait up to 30 seconds for the device to generate a new one-time password. Then type the second `one-time password` into the `MFA Code 2 box`.9. Click `Assign MFA`.","AdditionalInformation": "**Forced IAM User Self-Service Remediation**Amazon has published a pattern that forces users to self-service setup MFA before they have access to their complete permissions set. Until they complete this step, they cannot access their full permissions. This pattern can be used on new AWS accounts. It can also be used on existing accounts - it is recommended users are given instructions and a grace period to accomplish MFA enrollment before active enforcement on existing AWS accounts."}],"description": "Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.11": {"name": "1.11","checks": {"iam_user_no_setup_initial_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/cli/latest/reference/iam/delete-access-key.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html","Description": "AWS console defaults to no check boxes selected when creating a new IAM user. When cerating the IAM User credentials you have to determine what type of access they require. Programmatic access: The IAM user might need to make API calls, use the AWS CLI, or use the Tools for Windows PowerShell. In that case, create an access key (access key ID and a secret access key) for that user. AWS Management Console access: If the user needs to access the AWS Management Console, create a password for the user.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if access keys were created upon user creation and are being used and rotated as prescribed:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on a User where column `Password age` and `Access key age` is not set to `None` 5. Click on `Security credentials` Tab 6. Compare the user 'Creation time` to the Access Key `Created` date. 6. For any that match, the key was created during initial user setup.- Keys that were created at the same time as the user profile and do not have a last used date should be deleted. Refer to the remediation below.**From Command Line:**1. Run the following command (OSX/Linux/UNIX) to generate a list of all IAM users along with their access keys utilization: ```aws iam generate-credential-report ``` ```aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,9,11,14,16 ``` 2. The output of this command will produce a table similar to the following: ``` user,password_enabled,access_key_1_active,access_key_1_last_used_date,access_key_2_active,access_key_2_last_used_dateelise,false,true,2015-04-16T15:14:00+00:00,false,N/Abrandon,true,true,N/A,false,N/Arakesh,false,false,N/A,false,N/Ahelene,false,true,2015-11-18T17:47:00+00:00,false,N/Aparas,true,true,2016-08-28T12:04:00+00:00,true,2016-03-04T10:11:00+00:00anitha,true,true,2016-06-08T11:43:00+00:00,true,N/A``` 3. For any user having `password_enabled` set to `true` AND `access_key_last_used_date` set to `N/A` refer to the remediation below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Requiring the additional steps be taken by the user for programmatic access after their profile has been created will give a stronger indication of intent that access keys are [a] necessary for their work and [b] once the access key is established on an account that the keys may be in use somewhere in the organization.**Note**: Even if it is known the user will need access keys, require them to create the keys themselves or put in a support ticket to have them created as a separate step from user creation.","RemediationProcedure": "Perform the following to delete access keys that do not pass the audit:**From Console:**1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. As an Administrator - Click on the X `(Delete)` for keys that were created at the same time as the user profile but have not been used. 7. As an IAM User- Click on the X `(Delete)` for keys that were created at the same time as the user profile but have not been used.**From Command Line:** ``` aws iam delete-access-key --access-key-id  --user-name  ```","AdditionalInformation": "Credential report does not appear to contain \"Key Creation Date\""}],"description": "Do not setup access keys during initial user setup for all IAM users that have a console password","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.12": {"name": "1.12","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#remove-credentials:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_admin-change-user.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "AWS IAM users can access AWS resources using different types of credentials, such as passwords or access keys. It is recommended that all credentials that have been unused in 45 or greater days be deactivated or removed.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if unused credentials exist:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM` 4. Click on `Users` 5. Click the `Settings` (gear) icon. 6. Select `Console last sign-in`, `Access key last used`, and `Access Key Id` 7. Click on `Close`8. Check and ensure that `Console last sign-in` is less than 45 days ago.**Note** - `Never` means the user has never logged in.9. Check and ensure that `Access key age` is less than 45 days and that `Access key last used` does not say `None`If the user hasn't signed into the Console in the last 45 days or Access keys are over 45 days old refer to the remediation.**From Command Line:****Download Credential Report:**1. Run the following commands: ```aws iam generate-credential-report aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,5,6,9,10,11,14,15,16 | grep -v '^' ```**Ensure unused credentials do not exist:**2. For each user having `password_enabled` set to `TRUE` , ensure `password_last_used_date` is less than `45` days ago.- When `password_enabled` is set to `TRUE` and `password_last_used` is set to `No_Information` , ensure `password_last_changed` is less than 45 days ago.3. For each user having an `access_key_1_active` or `access_key_2_active` to `TRUE` , ensure the corresponding `access_key_n_last_used_date` is less than `45` days ago.- When a user having an `access_key_x_active` (where x is 1 or 2) to `TRUE` and corresponding access_key_x_last_used_date is set to `N/A', ensure `access_key_x_last_rotated` is less than 45 days ago.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Disabling or removing unnecessary credentials will reduce the window of opportunity for credentials associated with a compromised or abandoned account to be used.","RemediationProcedure": "**From Console:**Perform the following to manage Unused Password (IAM user console access)1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. Select user whose `Console last sign-in` is greater than 45 days 7. Click `Security credentials` 8. In section `Sign-in credentials`, `Console password` click `Manage`9. Under Console Access select `Disable` 10.Click `Apply`Perform the following to deactivate Access Keys:1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. Select any access keys that are over 45 days old and that have been used and - Click on `Make Inactive` 7. Select any access keys that are over 45 days old and that have not been used and - Click the X to `Delete`","AdditionalInformation": " is excluded in the audit since the root account should not be used for day to day business and would likely be unused for more than 45 days."}],"description": "Ensure credentials unused for 45 days or greater are disabled","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1.13": {"name": "1.13","checks": {"iam_user_two_active_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "Access keys are long-term credentials for an IAM user or the AWS account 'root' user. You can use access keys to sign programmatic requests to the AWS CLI or AWS API (directly or using the AWS SDK)","DefaultValue": null,"AuditProcedure": "**From Console:**1. Sign in to the AWS Management Console and navigate to IAM dashboard at `https://console.aws.amazon.com/iam/`. 2. In the left navigation panel, choose `Users`. 3. Click on the IAM user name that you want to examine. 4. On the IAM user configuration page, select `Security Credentials` tab. 5. Under `Access Keys` section, in the Status column, check the current status for each access key associated with the IAM user. If the selected IAM user has more than one access key activated then the users access configuration does not adhere to security best practices and the risk of accidental exposures increases. - Repeat steps no. 3 – 5 for each IAM user in your AWS account.**From Command Line:**1. Run `list-users` command to list all IAM users within your account: ``` aws iam list-users --query \"Users[*].UserName\" ``` The command output should return an array that contains all your IAM user names.2. Run `list-access-keys` command using the IAM user name list to return the current status of each access key associated with the selected IAM user: ``` aws iam list-access-keys --user-name  ``` The command output should expose the metadata `(\"Username\", \"AccessKeyId\", \"Status\", \"CreateDate\")` for each access key on that user account.3. Check the `Status` property value for each key returned to determine each keys current state. If the `Status` property value for more than one IAM access key is set to `Active`, the user access configuration does not adhere to this recommendation, refer to the remediation below.- Repeat steps no. 2 and 3 for each IAM user in your AWS account.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Access keys are long-term credentials for an IAM user or the AWS account 'root' user. You can use access keys to sign programmatic requests to the AWS CLI or AWS API. One of the best ways to protect your account is to not allow users to have multiple access keys.","RemediationProcedure": "**From Console:**1. Sign in to the AWS Management Console and navigate to IAM dashboard at `https://console.aws.amazon.com/iam/`. 2. In the left navigation panel, choose `Users`. 3. Click on the IAM user name that you want to examine. 4. On the IAM user configuration page, select `Security Credentials` tab. 5. In `Access Keys` section, choose one access key that is less than 90 days old. This should be the only active key used by this IAM user to access AWS resources programmatically. Test your application(s) to make sure that the chosen access key is working. 6. In the same `Access Keys` section, identify your non-operational access keys (other than the chosen one) and deactivate it by clicking the `Make Inactive` link. 7. If you receive the `Change Key Status` confirmation box, click `Deactivate` to switch off the selected key. 8. Repeat steps no. 3 – 7 for each IAM user in your AWS account.**From Command Line:**1. Using the IAM user and access key information provided in the `Audit CLI`, choose one access key that is less than 90 days old. This should be the only active key used by this IAM user to access AWS resources programmatically. Test your application(s) to make sure that the chosen access key is working.2. Run the `update-access-key` command below using the IAM user name and the non-operational access key IDs to deactivate the unnecessary key(s). Refer to the Audit section to identify the unnecessary access key ID for the selected IAM user**Note** - the command does not return any output: ``` aws iam update-access-key --access-key-id  --status Inactive --user-name  ``` 3. To confirm that the selected access key pair has been successfully `deactivated` run the `list-access-keys` audit command again for that IAM User: ``` aws iam list-access-keys --user-name  ``` - The command output should expose the metadata for each access key associated with the IAM user. If the non-operational key pair(s) `Status` is set to `Inactive`, the key has been successfully deactivated and the IAM user access configuration adheres now to this recommendation.4. Repeat steps no. 1 – 3 for each IAM user in your AWS account.","AdditionalInformation": ""}],"description": "Ensure there is only one active access key available for any single IAM user","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.14": {"name": "1.14","checks": {"iam_rotate_access_key_90_days": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#rotate-credentials:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html:https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "Access keys consist of an access key ID and secret access key, which are used to sign programmatic requests that you make to AWS. AWS users need their own access keys to make programmatic calls to AWS from the AWS Command Line Interface (AWS CLI), Tools for Windows PowerShell, the AWS SDKs, or direct HTTP calls using the APIs for individual AWS services. It is recommended that all access keys be regularly rotated.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if access keys are rotated as prescribed:**From Console:**1. Go to Management Console (https://console.aws.amazon.com/iam) 2. Click on `Users` 3. Click `setting` icon 4. Select `Console last sign-in` 5. Click `Close` 6. Ensure that `Access key age` is less than 90 days ago. note) `None` in the `Access key age` means the user has not used the access key.**From Command Line:**``` aws iam generate-credential-report aws iam get-credential-report --query 'Content' --output text | base64 -d ``` The `access_key_1_last_rotated` field in this file notes The date and time, in ISO 8601 date-time format, when the user's access key was created or last changed. If the user does not have an active access key, the value in this field is N/A (not applicable).","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Rotating access keys will reduce the window of opportunity for an access key that is associated with a compromised or terminated account to be used.Access keys should be rotated to ensure that data cannot be accessed with an old key which might have been lost, cracked, or stolen.","RemediationProcedure": "Perform the following to rotate access keys:**From Console:**1. Go to Management Console (https://console.aws.amazon.com/iam) 2. Click on `Users` 3. Click on `Security Credentials`4. As an Administrator - Click on `Make Inactive` for keys that have not been rotated in `90` Days 5. As an IAM User- Click on `Make Inactive` or `Delete` for keys which have not been rotated or used in `90` Days 6. Click on `Create Access Key`7. Update programmatic call with new Access Key credentials**From Command Line:**1. While the first access key is still active, create a second access key, which is active by default. Run the following command: ``` aws iam create-access-key ```At this point, the user has two active access keys.2. Update all applications and tools to use the new access key. 3. Determine whether the first access key is still in use by using this command: ``` aws iam get-access-key-last-used ``` 4. One approach is to wait several days and then check the old access key for any use before proceeding.Even if step Step 3 indicates no use of the old key, it is recommended that you do not immediately delete the first access key. Instead, change the state of the first access key to Inactive using this command: ``` aws iam update-access-key ``` 5. Use only the new access key to confirm that your applications are working. Any applications and tools that still use the original access key will stop working at this point because they no longer have access to AWS resources. If you find such an application or tool, you can switch its state back to Active to reenable the first access key. Then return to step Step 2 and update this application to use the new key.6. After you wait some period of time to ensure that all applications and tools have been updated, you can delete the first access key with this command: ``` aws iam delete-access-key ```","AdditionalInformation": ""}],"description": "Ensure access keys are rotated every 90 days or less","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.15": {"name": "1.15","checks": {"iam_policy_attached_only_to_group_or_roles": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html","Description": "IAM users are granted access to services, functions, and data through IAM policies. There are three ways to define policies for a user: 1) Edit the user policy directly, aka an inline, or user, policy; 2) attach a policy directly to a user; 3) add the user to an IAM group that has an attached policy. Only the third implementation is recommended.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if an inline policy is set or a policy is directly attached to users:1. Run the following to get a list of IAM users: ```aws iam list-users --query 'Users[*].UserName' --output text``` 2. For each user returned, run the following command to determine if any policies are attached to them: ```aws iam list-attached-user-policies --user-name aws iam list-user-policies --user-name ``` 3. If any policies are returned, the user has an inline policy or direct policy attachment.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Assigning IAM policy only through groups unifies permissions management to a single, flexible layer consistent with organizational functional roles. By unifying permissions management, the likelihood of excessive permissions is reduced.","RemediationProcedure": "Perform the following to create an IAM group and assign a policy to it:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click `Groups` and then click `Create New Group` . 3. In the `Group Name` box, type the name of the group and then click `Next Step` . 4. In the list of policies, select the check box for each policy that you want to apply to all members of the group. Then click `Next Step` . 5. Click `Create Group` Perform the following to add a user to a given group:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click `Groups`3. Select the group to add a user to 4. Click `Add Users To Group`5. Select the users to be added to the group 6. Click `Add Users` Perform the following to remove a direct association between a user and policy:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the left navigation pane, click on Users 3. For each user:- Select the user- Click on the `Permissions` tab- Expand `Permissions policies` - Click `X` for each policy; then click Detach or Remove (depending on policy type)","AdditionalInformation": ""}],"description": "Ensure IAM Users Receive Permissions Only Through Groups","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.16": {"name": "1.16","checks": {"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html:https://docs.aws.amazon.com/cli/latest/reference/iam/index.html#cli-aws-iam","Description": "IAM policies are the means by which privileges are granted to users, groups, or roles. It is recommended and considered a standard security advice to grant _least privilege_ -that is, granting only the permissions required to perform a task. Determine what users need to do and then craft policies for them that let the users perform _only_ those tasks, instead of allowing full administrative privileges.","DefaultValue": null,"AuditProcedure": "Perform the following to determine what policies are created:**From Command Line:**1. Run the following to get a list of IAM policies: ```aws iam list-policies --only-attached --output text ``` 2. For each policy returned, run the following command to determine if any policies is allowing full administrative privileges on the account: ```aws iam get-policy-version --policy-arn  --version-id  ``` 3. In output ensure policy should not have any Statement block with `\"Effect\": \"Allow\"` and `Action` set to `\"*\"` and `Resource` set to `\"*\"`","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "It's more secure to start with a minimum set of permissions and grant additional permissions as necessary, rather than starting with permissions that are too lenient and then trying to tighten them later.Providing full administrative privileges instead of restricting to the minimum set of permissions that the user is required to do exposes the resources to potentially unwanted actions.IAM policies that have a statement with \"Effect\": \"Allow\" with \"Action\": \"\\*\" over \"Resource\": \"\\*\" should be removed.","RemediationProcedure": "**From Console:**Perform the following to detach the policy that has full administrative privileges:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click Policies and then search for the policy name found in the audit step. 3. Select the policy that needs to be deleted. 4. In the policy action menu, select first `Detach`5. Select all Users, Groups, Roles that have this policy attached 6. Click `Detach Policy`7. In the policy action menu, select `Detach` **From Command Line:**Perform the following to detach the policy that has full administrative privileges as found in the audit step:1. Lists all IAM users, groups, and roles that the specified managed policy is attached to.```aws iam list-entities-for-policy --policy-arn  ``` 2. Detach the policy from all IAM Users: ```aws iam detach-user-policy --user-name  --policy-arn  ``` 3. Detach the policy from all IAM Groups: ```aws iam detach-group-policy --group-name  --policy-arn  ``` 4. Detach the policy from all IAM Roles: ```aws iam detach-role-policy --role-name  --policy-arn  ```","AdditionalInformation": ""}],"description": "Ensure IAM policies that allow full \"*:*\" administrative privileges are not attached","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1.17": {"name": "1.17","checks": {"iam_support_role_created": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html:https://aws.amazon.com/premiumsupport/pricing/:https://docs.aws.amazon.com/cli/latest/reference/iam/list-policies.html:https://docs.aws.amazon.com/cli/latest/reference/iam/attach-role-policy.html:https://docs.aws.amazon.com/cli/latest/reference/iam/list-entities-for-policy.html","Description": "AWS provides a support center that can be used for incident notification and response, as well as technical support and customer services. Create an IAM Role to allow authorized users to manage incidents with AWS Support.","DefaultValue": null,"AuditProcedure": "**From Command Line:**1. List IAM policies, filter for the 'AWSSupportAccess' managed policy, and note the \"Arn\" element value: ``` aws iam list-policies --query \"Policies[?PolicyName == 'AWSSupportAccess']\" ``` 2. Check if the 'AWSSupportAccess' policy is attached to any role:``` aws iam list-entities-for-policy --policy-arn arn:aws:iam::aws:policy/AWSSupportAccess ```3. In Output, Ensure `PolicyRoles` does not return empty. 'Example: Example: PolicyRoles: [ ]'If it returns empty refer to the remediation below.","ImpactStatement": "All AWS Support plans include an unlimited number of account and billing support cases, with no long-term contracts. Support billing calculations are performed on a per-account basis for all plans. Enterprise Support plan customers have the option to include multiple enabled accounts in an aggregated monthly billing calculation. Monthly charges for the Business and Enterprise support plans are based on each month's AWS usage charges, subject to a monthly minimum, billed in advance.","AssessmentStatus": "Automated","RationaleStatement": "By implementing least privilege for access control, an IAM Role will require an appropriate IAM Policy to allow Support Center Access in order to manage Incidents with AWS Support.","RemediationProcedure": "**From Command Line:**1. Create an IAM role for managing incidents with AWS:- Create a trust relationship policy document that allows  to manage AWS incidents, and save it locally as /tmp/TrustPolicy.json: ```{\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"\"},\"Action\": \"sts:AssumeRole\"}]} ``` 2. Create the IAM role using the above trust policy: ``` aws iam create-role --role-name  --assume-role-policy-document file:///tmp/TrustPolicy.json ``` 3. Attach 'AWSSupportAccess' managed policy to the created IAM role: ``` aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AWSSupportAccess --role-name  ```","AdditionalInformation": "AWSSupportAccess policy is a global AWS resource. It has same ARN as `arn:aws:iam::aws:policy/AWSSupportAccess` for every account."}],"description": "Ensure a support role has been created to manage incidents with AWS Support","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.18": {"name": "1.18","checks": {"ec2_instance_profile_attached": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html","Description": "AWS access from within AWS instances can be done by either encoding AWS keys into AWS API calls or by assigning the instance to a role which has an appropriate permissions policy for the required access. \"AWS Access\" means accessing the APIs of AWS in order to access AWS resources or manage AWS account resources.","DefaultValue": null,"AuditProcedure": "Where an instance is associated with a Role:For instances that are known to perform AWS actions, ensure that they belong to an instance role that has the necessary permissions:1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Open the EC2 Dashboard and choose \"Instances\" 3. Click the EC2 instance that performs AWS actions, in the lower pane details find \"IAM Role\" 4. If the Role is blank, the instance is not assigned to one. 5. If the Role is filled in, it does not mean the instance might not \\*also\\* have credentials encoded on it for some activities.Where an Instance Contains Embedded Credentials:- On the instance that is known to perform AWS actions, audit all scripts and environment variables to ensure that none of them contain AWS credentials.Where an Instance Application Contains Embedded Credentials:- Applications that run on an instance may also have credentials embedded. This is a bad practice, but even worse if the source code is stored in a public code repository such as github. When an application contains credentials can be determined by eliminating all other sources of credentials and if the application can still access AWS resources - it likely contains embedded credentials. Another method is to examine all source code and configuration files of the application.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "AWS IAM roles reduce the risks associated with sharing and rotating credentials that can be used outside of AWS itself. If credentials are compromised, they can be used from outside of the AWS account they give access to. In contrast, in order to leverage role permissions an attacker would need to gain and maintain access to a specific instance to use the privileges associated with it.Additionally, if credentials are encoded into compiled applications or other hard to change mechanisms, then they are even more unlikely to be properly rotated due to service disruption risks. As time goes on, credentials that cannot be rotated are more likely to be known by an increasing number of individuals who no longer work for the organization owning the credentials.","RemediationProcedure": "IAM roles can only be associated at the launch of an instance. To remediate an instance to add it to a role you must create a new instance.If the instance has no external dependencies on its current private ip or public addresses are elastic IPs:1. In AWS IAM create a new role. Assign a permissions policy if needed permissions are already known. 2. In the AWS console launch a new instance with identical settings to the existing instance, and ensure that the newly created role is selected. 3. Shutdown both the existing instance and the new instance. 4. Detach disks from both instances. 5. Attach the existing instance disks to the new instance. 6. Boot the new instance and you should have the same machine, but with the associated role.**Note:** if your environment has dependencies on a dynamically assigned PRIVATE IP address you can create an AMI from the existing instance, destroy the old one and then when launching from the AMI, manually assign the previous private IP address.**Note: **if your environment has dependencies on a dynamically assigned PUBLIC IP address there is not a way ensure the address is retained and assign an instance role. Dependencies on dynamically assigned public IP addresses are a bad practice and, if possible, you may wish to rebuild the instance with a new elastic IP address and make the investment to remediate affected systems while assigning the system to a role.","AdditionalInformation": ""}],"description": "Ensure IAM instance roles are used for AWS resource access from instances","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.19": {"name": "1.19","checks": {"iam_no_expired_server_certificates_stored": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_server-certs.html:https://docs.aws.amazon.com/cli/latest/reference/iam/delete-server-certificate.html","Description": "To enable HTTPS connections to your website or application in AWS, you need an SSL/TLS server certificate. You can use ACM or IAM to store and deploy server certificates.Use IAM as a certificate manager only when you must support HTTPS connections in a region that is not supported by ACM. IAM securely encrypts your private keys and stores the encrypted version in IAM SSL certificate storage. IAM supports deploying server certificates in all regions, but you must obtain your certificate from an external provider for use with AWS. You cannot upload an ACM certificate to IAM. Additionally, you cannot manage your certificates from the IAM Console.","DefaultValue": null,"AuditProcedure": "**From Console:**Getting the certificates expiration information via AWS Management Console is not currently supported.To request information about the SSL/TLS certificates stored in IAM via the AWS API use the Command Line Interface (CLI).**From Command Line:**Run list-server-certificates command to list all the IAM-stored server certificates:``` aws iam list-server-certificates ```The command output should return an array that contains all the SSL/TLS certificates currently stored in IAM and their metadata (name, ID, expiration date, etc):``` {\"ServerCertificateMetadataList\": [{\"ServerCertificateId\": \"EHDGFRW7EJFYTE88D\",\"ServerCertificateName\": \"MyServerCertificate\",\"Expiration\": \"2018-07-10T23:59:59Z\",\"Path\": \"/\",\"Arn\": \"arn:aws:iam::012345678910:server-certificate/MySSLCertificate\",\"UploadDate\": \"2018-06-10T11:56:08Z\"}] } ```Verify the `ServerCertificateName` and `Expiration` parameter value (expiration date) for each SSL/TLS certificate returned by the list-server-certificates command and determine if there are any expired server certificates currently stored in AWS IAM. If so, use the AWS API to remove them.If this command returns: ``` { { \"ServerCertificateMetadataList\": [] } ``` This means that there are no expired certificates, It DOES NOT mean that no certificates exist.","ImpactStatement": "Deleting the certificate could have implications for your application if you are using an expired server certificate with Elastic Load Balancing, CloudFront, etc. One has to make configurations at respective services to ensure there is no interruption in application functionality.","AssessmentStatus": "Automated","RationaleStatement": "Removing expired SSL/TLS certificates eliminates the risk that an invalid certificate will be deployed accidentally to a resource such as AWS Elastic Load Balancer (ELB), which can damage the credibility of the application/website behind the ELB. As a best practice, it is recommended to delete expired certificates.","RemediationProcedure": "**From Console:**Removing expired certificates via AWS Management Console is not currently supported. To delete SSL/TLS certificates stored in IAM via the AWS API use the Command Line Interface (CLI).**From Command Line:**To delete Expired Certificate run following command by replacing  with the name of the certificate to delete:``` aws iam delete-server-certificate --server-certificate-name  ```When the preceding command is successful, it does not return any output.","AdditionalInformation": ""}],"description": "Ensure that all the expired SSL/TLS certificates stored in AWS IAM are removed","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.20": {"name": "1.20","checks": {"accessanalyzer_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-getting-started.html:https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/get-analyzer.html:https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/create-analyzer.html","Description": "Enable IAM Access analyzer for IAM policies about all resources in each region.IAM Access Analyzer is a technology introduced at AWS reinvent 2019. After the Analyzer is enabled in IAM, scan results are displayed on the console showing the accessible resources. Scans show resources that other accounts and federated users can access, such as KMS keys and IAM roles. So the results allow you to determine if an unintended user is allowed, making it easier for administrators to monitor least privileges access. Access Analyzer analyzes only policies that are applied to resources in the same AWS Region.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Open the IAM console at `https://console.aws.amazon.com/iam/` 2. Choose `Access analyzer` 3. Click 'Analyzers' 4. Ensure that at least one analyzer is present 5. Ensure that the `STATUS` is set to `Active` 6. Repeat these step for each active region**From Command Line:**1. Run the following command: ``` aws accessanalyzer list-analyzers | grep status ``` 2. Ensure that at least one Analyzer the `status` is set to `ACTIVE`3. Repeat the steps above for each active region.If an Access analyzer is not listed for each region or the status is not set to active refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "AWS IAM Access Analyzer helps you identify the resources in your organization and accounts, such as Amazon S3 buckets or IAM roles, that are shared with an external entity. This lets you identify unintended access to your resources and data. Access Analyzer identifies resources that are shared with external principals by using logic-based reasoning to analyze the resource-based policies in your AWS environment. IAM Access Analyzer continuously monitors all policies for S3 bucket, IAM roles, KMS(Key Management Service) keys, AWS Lambda functions, and Amazon SQS(Simple Queue Service) queues.","RemediationProcedure": "**From Console:**Perform the following to enable IAM Access analyzer for IAM policies:1. Open the IAM console at `https://console.aws.amazon.com/iam/.` 2. Choose `Access analyzer`. 3. Choose `Create analyzer`. 4. On the `Create analyzer` page, confirm that the `Region` displayed is the Region where you want to enable Access Analyzer. 5. Enter a name for the analyzer. `Optional as it will generate a name for you automatically`. 6. Add any tags that you want to apply to the analyzer. `Optional`.7. Choose `Create Analyzer`. 8. Repeat these step for each active region**From Command Line:**Run the following command: ``` aws accessanalyzer create-analyzer --analyzer-name  --type  ``` Repeat this command above for each active region.**Note:** The IAM Access Analyzer is successfully configured only when the account you use has the necessary permissions.","AdditionalInformation": ""}],"description": "Ensure that IAM Access analyzer is enabled for all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.21": {"name": "1.21","checks": {"iam_check_saml_providers_sts": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "","Description": "In multi-account environments, IAM user centralization facilitates greater user control. User access beyond the initial account is then provided via role assumption. Centralization of users can be accomplished through federation with an external identity provider or through the use of AWS Organizations.","DefaultValue": null,"AuditProcedure": "For multi-account AWS environments with an external identity provider... 1. Determine the master account for identity federation or IAM user management 2. Login to that account through the AWS Management Console 3. Click `Services`4. Click `IAM`5. Click `Identity providers` 6. Verify the configurationThen..., determine all accounts that should not have local users present. For each account...1. Determine all accounts that should not have local users present 2. Log into the AWS Management Console 3. Switch role into each identified account 4. Click `Services`5. Click `IAM`6. Click `Users` 7. Confirm that no IAM users representing individuals are presentFor multi-account AWS environments implementing AWS Organizations without an external identity provider... 1. Determine all accounts that should not have local users present 2. Log into the AWS Management Console 3. Switch role into each identified account 4. Click `Services`5. Click `IAM`6. Click `Users` 7. Confirm that no IAM users representing individuals are present","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Centralizing IAM user management to a single identity store reduces complexity and thus the likelihood of access management errors.","RemediationProcedure": "The remediation procedure will vary based on the individual organization's implementation of identity federation and/or AWS Organizations with the acceptance criteria that no non-service IAM users, and non-root accounts, are present outside the account providing centralized IAM user management.","AdditionalInformation": ""}],"description": "Ensure IAM users are managed centrally via identity federation or AWS Organizations for multi-account environments","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.22": {"name": "1.22","checks": {},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/cloudshell/latest/userguide/sec-auth-with-identities.html","Description": "AWS CloudShell is a convenient way of running CLI commands against AWS services; a managed IAM policy ('AWSCloudShellFullAccess') provides full access to CloudShell, which allows file upload and download capability between a user's local system and the CloudShell environment. Within the CloudShell environment a user has sudo permissions, and can access the internet. So it is feasible to install file transfer software (for example) and move data from CloudShell to external internet servers.","DefaultValue": null,"AuditProcedure": "**From Console** 1. Open the IAM console at https://console.aws.amazon.com/iam/2. In the left pane, select Policies3. Search for and select AWSCloudShellFullAccess4. On the Entities attached tab, ensure that there are no entities using this policy **From Command Line**1. List IAM policies, filter for the 'AWSCloudShellFullAccess' managed policy, and note the \"\"Arn\"\" element value:```aws iam list-policies --query \"\"Policies[?PolicyName == 'AWSCloudShellFullAccess']\"\"``` 2. Check if the 'AWSCloudShellFullAccess' policy is attached to any role: ```aws iam list-entities-for-policy --policy-arn arn:aws:iam::aws:policy/AWSCloudShellFullAccess```3. In Output, Ensure PolicyRoles returns empty. 'Example: Example: PolicyRoles: [ ]'If it does not return empty refer to the remediation below.Note: Keep in mind that other policies may grant access.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Access to this policy should be restricted as it presents a potential channel for data exfiltration by malicious cloud admins that are given full permissions to the service. AWS documentation describes how to create a more restrictive IAM policy which denies file transfer permissions.","RemediationProcedure": "**From Console**1. Open the IAM console at https://console.aws.amazon.com/iam/2. In the left pane, select Policies 3. Search for and select AWSCloudShellFullAccess4. On the Entities attached tab, for each item, check the box and select Detach","AdditionalInformation": ""}],"description": "Ensure access to AWSCloudShellFullAccess is restricted","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.10": {"name": "3.10","checks": {"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-cloudtrail-events.html","Description": "S3 object-level API operations such as GetObject, DeleteObject, and PutObject are called data events. By default, CloudTrail trails don't log data events and so it is recommended to enable Object-level logging for S3 buckets.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to CloudTrail dashboard at `https://console.aws.amazon.com/cloudtrail/` 2. In the left panel, click `Trails` and then click on the CloudTrail Name that you want to examine. 3. Review `General details` 4. Confirm that `Multi-region trail` is set to `Yes` 5. Scroll down to `Data events` 6. Confirm that it reads: Data events: S3 Bucket Name: All current and future S3 buckets Read: Enabled Write: Enabled 7. Repeat steps 2 to 6 to verify that Multi-region trail and Data events logging of S3 buckets in CloudTrail. If the CloudTrails do not have multi-region and data events configured for S3 refer to the remediation below.**From Command Line:**1. Run `list-trails` command to list the names of all Amazon CloudTrail trails currently available in all AWS regions: ``` aws cloudtrail list-trails ``` 2. The command output will be a list of all the trail names to include. \"TrailARN\": \"arn:aws:cloudtrail:::trail/\", \"Name\": \"\", \"HomeRegion\": \"\" 3. Next run 'get-trail- command to determine Multi-region. ``` aws cloudtrail get-trail --name  --region  ``` 4. The command output should include: \"IsMultiRegionTrail\": true, 5. Next run `get-event-selectors` command using the `Name` of the trail and the `region` returned in step 2 to determine if Data events logging feature is enabled within the selected CloudTrail trail for all S3 buckets: ``` aws cloudtrail get-event-selectors --region  --trail-name  --query EventSelectors[*].DataResources[] ``` 6. The command output should be an array that contains the configuration of the AWS resource(S3 bucket) defined for the Data events selector. \"Type\": \"AWS::S3::Object\",\"Values\": [\"arn:aws:s3\" 7. If the `get-event-selectors` command returns an empty array '[]', the Data events are not included in the selected AWS Cloudtrail trail logging configuration, therefore the S3 object-level API operations performed within your AWS account are not recorded. 8. Repeat steps 1 to 5 for auditing each CloudTrail to determine if Data events for S3 are covered. If Multi-region is not set to true and the Data events does not show S3 defined as shown refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling object-level logging will help you meet data compliance requirements within your organization, perform comprehensive security analysis, monitor specific patterns of user behavior in your AWS account or take immediate actions on any object-level API activity within your S3 Buckets using Amazon CloudWatch Events.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. Click on the `Object-level` logging setting, enter the CloudTrail name for the recording activity. You can choose an existing Cloudtrail or create a new one by navigating to the Cloudtrail console link `https://console.aws.amazon.com/cloudtrail/` 5. Once the Cloudtrail is selected, check the `Write` event checkbox, so that `object-level` logging for Write events is enabled. 6. Repeat steps 2 to 5 to enable object-level logging of write events for other S3 buckets.**From Command Line:**1. To enable `object-level` data events logging for S3 buckets within your AWS account, run `put-event-selectors` command using the name of the trail that you want to reconfigure as identifier: ``` aws cloudtrail put-event-selectors --region  --trail-name  --event-selectors '[{ \"ReadWriteType\": \"WriteOnly\", \"IncludeManagementEvents\":true, \"DataResources\": [{ \"Type\": \"AWS::S3::Object\", \"Values\": [\"arn:aws:s3:::/\"] }] }]' ``` 2. The command output will be `object-level` event trail configuration. 3. If you want to enable it for all buckets at once then change Values parameter to `[\"arn:aws:s3\"]` in command given above. 4. Repeat step 1 for each s3 bucket to update `object-level` logging of write events. 5. Change the AWS region by updating the `--region` command parameter and perform the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that Object-level logging for write events is enabled for S3 bucket","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.11": {"name": "3.11","checks": {"cloudtrail_s3_dataevents_read_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-cloudtrail-events.html","Description": "S3 object-level API operations such as GetObject, DeleteObject, and PutObject are called data events. By default, CloudTrail trails don't log data events and so it is recommended to enable Object-level logging for S3 buckets.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. If the current status for `Object-level` logging is set to `Disabled`, then object-level logging of read events for the selected s3 bucket is not set. 5. If the current status for `Object-level` logging is set to `Enabled`, but the Read event check-box is unchecked, then object-level logging of read events for the selected s3 bucket is not set. 6. Repeat steps 2 to 5 to verify `object-level` logging for `read` events of your other S3 buckets.**From Command Line:** 1. Run `describe-trails` command to list the names of all Amazon CloudTrail trails currently available in the selected AWS region: ``` aws cloudtrail describe-trails --region  --output table --query trailList[*].Name ``` 2. The command output will be table of the requested trail names. 3. Run `get-event-selectors` command using the name of the trail returned at the previous step and custom query filters to determine if Data events logging feature is enabled within the selected CloudTrail trail configuration for s3 bucket resources: ``` aws cloudtrail get-event-selectors --region  --trail-name  --query EventSelectors[*].DataResources[] ``` 4. The command output should be an array that contains the configuration of the AWS resource(S3 bucket) defined for the Data events selector. 5. If the `get-event-selectors` command returns an empty array, the Data events are not included into the selected AWS Cloudtrail trail logging configuration, therefore the S3 object-level API operations performed within your AWS account are not recorded. 6. Repeat steps 1 to 5 for auditing each s3 bucket to identify other trails that are missing the capability to log Data events. 7. Change the AWS region by updating the `--region` command parameter and perform the audit process for other regions.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling object-level logging will help you meet data compliance requirements within your organization, perform comprehensive security analysis, monitor specific patterns of user behavior in your AWS account or take immediate actions on any object-level API activity using Amazon CloudWatch Events.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. Click on the `Object-level` logging setting, enter the CloudTrail name for the recording activity. You can choose an existing Cloudtrail or create a new one by navigating to the Cloudtrail console link `https://console.aws.amazon.com/cloudtrail/` 5. Once the Cloudtrail is selected, check the Read event checkbox, so that `object-level` logging for `Read` events is enabled. 6. Repeat steps 2 to 5 to enable `object-level` logging of read events for other S3 buckets.**From Command Line:** 1. To enable `object-level` data events logging for S3 buckets within your AWS account, run `put-event-selectors` command using the name of the trail that you want to reconfigure as identifier: ``` aws cloudtrail put-event-selectors --region  --trail-name  --event-selectors '[{ \"ReadWriteType\": \"ReadOnly\", \"IncludeManagementEvents\":true, \"DataResources\": [{ \"Type\": \"AWS::S3::Object\", \"Values\": [\"arn:aws:s3:::/\"] }] }]' ``` 2. The command output will be `object-level` event trail configuration. 3. If you want to enable it for all buckets at ones then change Values parameter to `[\"arn:aws:s3\"]` in command given above. 4. Repeat step 1 for each s3 bucket to update `object-level` logging of read events. 5. Change the AWS region by updating the `--region` command parameter and perform the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that Object-level logging for read events is enabled for S3 bucket","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.10": {"name": "4.10","checks": {"cloudwatch_log_metric_filter_security_group_changes": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Security Groups are a stateful packet filter that controls ingress and egress traffic within a VPC. It is recommended that a metric filter and alarm be established for detecting changes to Security Groups.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query \"MetricAlarms[?MetricName== '']\" ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to security group will help ensure that resources and services are not unintentionally exposed.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for security groups changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name \"\" --filter-name \"\" --metric-transformations metricName= \"\" ,metricNamespace=\"CISBenchmark\",metricValue=1 --filter-pattern \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\" ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name \"\" ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn \"\" --protocol  --notification-endpoint \"\" ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name \"\" --metric-name \"\" --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace \"CISBenchmark\" --alarm-actions \"\" ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for security group changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.11": {"name": "4.11","checks": {"cloudwatch_changes_to_network_acls_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. NACLs are used as a stateless packet filter to control ingress and egress traffic for subnets within a VPC. It is recommended that a metric filter and alarm be established for changes made to NACLs.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to NACLs will help ensure that AWS resources and services are not unintentionally exposed.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for NACL changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL)","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.12": {"name": "4.12","checks": {"cloudwatch_changes_to_network_gateways_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Network gateways are required to send/receive traffic to a destination outside of a VPC. It is recommended that a metric filter and alarm be established for changes to network gateways.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to network gateways will help ensure that all ingress/egress traffic traverses the VPC border via a controlled path.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for network gateways changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for changes to network gateways","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.13": {"name": "4.13","checks": {"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Routing tables are used to route network traffic between subnets and to network gateways. It is recommended that a metric filter and alarm be established for changes to route tables.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to route tables will help ensure that all VPC traffic flows through an expected path.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for route table changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for route table changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.14": {"name": "4.14","checks": {"cloudwatch_changes_to_vpcs_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is possible to have more than 1 VPC within an account, in addition it is also possible to create a peer connection between 2 VPCs enabling network traffic to route between VPCs. It is recommended that a metric filter and alarm be established for changes made to VPCs.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to VPC will help ensure VPC traffic flow is not getting impacted.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for VPC changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for VPC changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.15": {"name": "4.15","checks": {"cloudwatch_log_metric_filter_aws_organizations_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/organizations/latest/userguide/orgs_security_incident-response.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for AWS Organizations changes made in the master AWS Account.","DefaultValue": null,"AuditProcedure": "1. Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured: - Identify the log group name configured for use with active multi-region CloudTrail: - List all CloudTrails:``` aws cloudtrail describe-trails ``` - Identify Multi region Cloudtrails, Trails with `\"IsMultiRegionTrail\"` set to true - From value associated with CloudWatchLogsLogGroupArn note **Example:** for CloudWatchLogsLogGroupArn that looks like arn:aws:logs:::log-group:NewGroup:*,  would be NewGroup- Ensure Identified Multi region CloudTrail is active: ``` aws cloudtrail get-trail-status --name  ``` Ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events: ``` aws cloudtrail get-event-selectors --trail-name  ``` - Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to true and `ReadWriteType` set to `All`.2. Get a list of all associated metric filters for this : ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdatePolicy\") || ($.eventName = \"UpdateOrganizationalUnit\")) }\" ``` 4. Note the `` value associated with the filterPattern found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4: ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the AlarmActions value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic: ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. Example of valid \"SubscriptionArn\":``` \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring AWS Organizations changes can help you prevent any unwanted, accidental or intentional modifications that may lead to unauthorized access or other security breaches. This monitoring technique helps you to ensure that any unexpected changes performed within your AWS Organizations can be investigated and any unwanted changes can be rolled back.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Organizations changes and the `` taken from audit step 1: ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdatePolicy\") || ($.eventName = \"UpdateOrganizationalUnit\")) }' ``` **Note:** You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify: ``` aws sns create-topic --name  ``` **Note:** you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2: ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note:** you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2: ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": ""}],"description": "Ensure a log metric filter and alarm exists for AWS Organizations changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.16": {"name": "4.16","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-get-started.html:https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-enable.html#securityhub-enable-api:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/securityhub/enable-security-hub.html","Description": "Security Hub collects security data from across AWS accounts, services, and supported third-party partner products and helps you analyze your security trends and identify the highest priority security issues. When you enable Security Hub, it begins to consume, aggregate, organize, and prioritize findings from AWS services that you have enabled, such as Amazon GuardDuty, Amazon Inspector, and Amazon Macie. You can also enable integrations with AWS partner security products.","DefaultValue": null,"AuditProcedure": "The process to evaluate AWS Security Hub configuration per region **From Console:**1. Sign in to the AWS Management Console and open the AWS Security Hub console at https://console.aws.amazon.com/securityhub/. 2. On the top right of the console, select the target Region. 3. If presented with the Security Hub > Summary page then Security Hub is set-up for the selected region. 4. If presented with Setup Security Hub or Get Started With Security Hub - follow the online instructions. 5. Repeat steps 2 to 4 for each region.","ImpactStatement": "It is recommended AWS Security Hub be enabled in all regions. AWS Security Hub requires AWS Config to be enabled.","AssessmentStatus": "Automated","RationaleStatement": "AWS Security Hub provides you with a comprehensive view of your security state in AWS and helps you check your environment against security industry standards and best practices - enabling you to quickly assess the security posture across your AWS accounts.","RemediationProcedure": "To grant the permissions required to enable Security Hub, attach the Security Hub managed policy AWSSecurityHubFullAccess to an IAM user, group, or role.Enabling Security Hub**From Console:**1. Use the credentials of the IAM identity to sign in to the Security Hub console. 2. When you open the Security Hub console for the first time, choose Enable AWS Security Hub. 3. On the welcome page, Security standards list the security standards that Security Hub supports. 4. Choose Enable Security Hub.**From Command Line:**1. Run the enable-security-hub command. To enable the default standards, include `--enable-default-standards`. ``` aws securityhub enable-security-hub --enable-default-standards ```2. To enable the security hub without the default standards, include `--no-enable-default-standards`. ``` aws securityhub enable-security-hub --no-enable-default-standards ```","AdditionalInformation": ""}],"description": "Ensure AWS Security Hub is enabled","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.1": {"name": "2.1.1","checks": {"s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-policy-for-config-rule/:https://aws.amazon.com/blogs/security/how-to-use-bucket-policies-and-apply-defense-in-depth-to-help-secure-your-amazon-s3-data/:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-bucket-policy.html","Description": "At the Amazon S3 bucket level, you can configure permissions through a bucket policy making the objects accessible only through HTTPS.","DefaultValue": null,"AuditProcedure": "To allow access to HTTPS you can use a condition that checks for the key `\"aws:SecureTransport: true\"`. This means that the request is sent through HTTPS but that HTTP can still be used. So to make sure you do not allow HTTP access confirm that there is a bucket policy that explicitly denies access for HTTP requests and that it contains the key \"aws:SecureTransport\": \"false\".**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/ 2. Select the Check box next to the Bucket. 3. Click on 'Permissions', then Click on `Bucket Policy`. 4. Ensure that a policy is listed that matches: ``` '{\"Sid\": ,\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}' ``` `` and `` will be specific to your account5. Repeat for all the buckets in your AWS account.**From Command Line:**1. List all of the S3 Buckets``` aws s3 ls ``` 2. Using the list of buckets run this command on each of them: ``` aws s3api get-bucket-policy --bucket  | grep aws:SecureTransport ``` 3. Confirm that `aws:SecureTransport` is set to false `aws:SecureTransport:false` 4. Confirm that the policy line has Effect set to Deny 'Effect:Deny'","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "By default, Amazon S3 allows both HTTP and HTTPS requests. To achieve only allowing access to Amazon S3 objects through HTTPS you also have to explicitly deny access to HTTP requests. Bucket policies that allow HTTPS requests without explicitly denying HTTP requests will not comply with this recommendation.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/ 2. Select the Check box next to the Bucket. 3. Click on 'Permissions'. 4. Click 'Bucket Policy' 5. Add this to the existing policy filling in the required information ``` {\"Sid\": \",\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}}} ``` 6. Save 7. Repeat for all the buckets in your AWS account that contain sensitive data.**From Console** using AWS Policy Generator:1. Repeat steps 1-4 above. 2. Click on `Policy Generator` at the bottom of the Bucket Policy Editor 3. Select Policy Type `S3 Bucket Policy` 4. Add Statements - `Effect` = Deny - `Principal` = * - `AWS Service` = Amazon S3 - `Actions` = * - `Amazon Resource Name` =  5. Generate Policy 6. Copy the text and add it to the Bucket Policy.**From Command Line:**1. Export the bucket policy to a json file. ``` aws s3api get-bucket-policy --bucket  --query Policy --output text > policy.json ```2. Modify the policy.json file by adding in this statement: ``` {\"Sid\": \",\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}}} ``` 3. Apply this modified policy back to the S3 bucket: ``` aws s3api put-bucket-policy --bucket  --policy file://policy.json ```","AdditionalInformation": ""}],"description": "Ensure S3 Bucket Policy is set to deny HTTP requests","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.1.2": {"name": "2.1.2","checks": {"s3_bucket_no_mfa_delete": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html#MultiFactorAuthenticationDelete:https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMFADelete.html:https://aws.amazon.com/blogs/security/securing-access-to-aws-using-mfa-part-3/:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_lost-or-broken.html","Description": "Once MFA Delete is enabled on your sensitive and classified S3 bucket it requires the user to have two forms of authentication.","DefaultValue": null,"AuditProcedure": "Perform the steps below to confirm MFA delete is configured on an S3 Bucket**From Console:**1. Login to the S3 console at `https://console.aws.amazon.com/s3/`2. Click the `Check` box next to the Bucket name you want to confirm3. In the window under `Properties`4. Confirm that Versioning is `Enabled`5. Confirm that MFA Delete is `Enabled`**From Command Line:**1. Run the `get-bucket-versioning` ``` aws s3api get-bucket-versioning --bucket my-bucket ```Output example: ```  EnabledEnabled ```If the Console or the CLI output does not show Versioning and MFA Delete `enabled` refer to the remediation below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Adding MFA delete to an S3 bucket, requires additional authentication when you change the version state of your bucket or you delete and object version adding another layer of security in the event your security credentials are compromised or unauthorized access is granted.","RemediationProcedure": "Perform the steps below to enable MFA delete on an S3 bucket.Note: -You cannot enable MFA Delete using the AWS Management Console. You must use the AWS CLI or API. -You must use your 'root' account to enable MFA Delete on S3 buckets.**From Command line:**1. Run the s3api put-bucket-versioning command``` aws s3api put-bucket-versioning --profile my-root-profile --bucket Bucket_Name --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa ā€œarn:aws:iam::aws_account_id:mfa/root-account-mfa-device passcodeā€ ```","AdditionalInformation": ""}],"description": "Ensure MFA Delete is enabled on S3 buckets","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.1.3": {"name": "2.1.3","checks": {"macie_is_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://aws.amazon.com/macie/getting-started/:https://docs.aws.amazon.com/workspaces/latest/adminguide/data-protection.html:https://docs.aws.amazon.com/macie/latest/user/data-classification.html","Description": "Amazon S3 buckets can contain sensitive data, that for security purposes should be discovered, monitored, classified and protected. Macie along with other 3rd party tools can automatically provide an inventory of Amazon S3 buckets.","DefaultValue": null,"AuditProcedure": "Perform the following steps to determine if Macie is running:**From Console:** 1. Login to the Macie console at https://console.aws.amazon.com/macie/ 2. In the left hand pane click on By job under findings. 3. Confirm that you have a Job setup for your S3 BucketsWhen you log into the Macie console if you aren't taken to the summary page and you don't have a job setup and running then refer to the remediation procedure below.If you are using a 3rd Party tool to manage and protect your s3 data you meet this recommendation.","ImpactStatement": "There is a cost associated with using Amazon Macie. There is also typically a cost associated with 3rd Party tools that perform similar processes and protection.","AssessmentStatus": "Manual","RationaleStatement": "Using a Cloud service or 3rd Party software to continuously monitor and automate the process of data discovery and classification for S3 buckets using machine learning and pattern matching is a strong defense in protecting that information.Amazon Macie is a fully managed data security and data privacy service that uses machine learning and pattern matching to discover and protect your sensitive data in AWS.","RemediationProcedure": "Perform the steps below to enable and configure Amazon Macie**From Console:**1. Log on to the Macie console at `https://console.aws.amazon.com/macie/`2. Click `Get started`.3. Click `Enable Macie`.Setup a repository for sensitive data discovery results1. In the Left pane, under Settings, click `Discovery results`.2. Make sure `Create bucket` is selected.3. Create a bucket, enter a name for the bucket. The name must be unique across all S3 buckets. In addition, the name must start with a lowercase letter or a number.4. Click on `Advanced`.5. Block all public access, make sure `Yes` is selected.6. KMS encryption, specify the AWS KMS key that you want to use to encrypt the results. The key must be a symmetric, customer master key (CMK) that's in the same Region as the S3 bucket.7. Click on `Save`Create a job to discover sensitive data1. In the left pane, click `S3 buckets`. Macie displays a list of all the S3 buckets for your account.2. Select the `check box` for each bucket that you want Macie to analyze as part of the job3. Click `Create job`.3. Click `Quick create`.4. For the Name and description step, enter a name and, optionally, a description of the job.5. Then click `Next`.6. For the Review and create step, click `Submit`.Review your findings1. In the left pane, click `Findings`.2. To view the details of a specific finding, choose any field other than the check box for the finding.If you are using a 3rd Party tool to manage and protect your s3 data, follow the Vendor documentation for implementing and configuring that tool.","AdditionalInformation": ""}],"description": "Ensure all data in Amazon S3 has been discovered, classified and secured when required.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.4": {"name": "2.1.4","checks": {"s3_bucket_level_public_access_block": "PASS","s3_account_level_public_access_blocks": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/block-public-access-account.html","Description": "Amazon S3 provides `Block public access (bucket settings)` and `Block public access (account settings)` to help you manage public access to Amazon S3 resources. By default, S3 buckets and objects are created with public access disabled. However, an IAM principal with sufficient S3 permissions can enable public access at the bucket and/or object level. While enabled, `Block public access (bucket settings)` prevents an individual bucket, and its contained objects, from becoming publicly accessible. Similarly, `Block public access (account settings)` prevents all buckets, and contained objects, from becoming publicly accessible across the entire account.","DefaultValue": null,"AuditProcedure": "**If utilizing Block Public Access (bucket settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select the Check box next to the Bucket. 3. Click on 'Edit public access settings'. 4. Ensure that block public access settings are set appropriately for this bucket 5. Repeat for all the buckets in your AWS account.**From Command Line:**1. List all of the S3 Buckets ``` aws s3 ls ``` 2. Find the public access setting on that bucket ``` aws s3api get-public-access-block --bucket  ``` Output if Block Public access is enabled:``` {\"PublicAccessBlockConfiguration\": {\"BlockPublicAcls\": true,\"IgnorePublicAcls\": true,\"BlockPublicPolicy\": true,\"RestrictPublicBuckets\": true} } ```If the output reads `false` for the separate configuration settings then proceed to the remediation.**If utilizing Block Public Access (account settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Choose `Block public access (account settings)` 3. Ensure that block public access settings are set appropriately for your AWS account.**From Command Line:**To check Public access settings for this account status, run the following command, `aws s3control get-public-access-block --account-id  --region `Output if Block Public access is enabled:``` {\"PublicAccessBlockConfiguration\": {\"IgnorePublicAcls\": true, \"BlockPublicPolicy\": true, \"BlockPublicAcls\": true, \"RestrictPublicBuckets\": true} } ```If the output reads `false` for the separate configuration settings then proceed to the remediation.","ImpactStatement": "When you apply Block Public Access settings to an account, the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously, but they eventually propagate to all Regions.","AssessmentStatus": "Automated","RationaleStatement": "Amazon S3 `Block public access (bucket settings)` prevents the accidental or malicious public exposure of data contained within the respective bucket(s). Amazon S3 `Block public access (account settings)` prevents the accidental or malicious public exposure of data contained within all buckets of the respective AWS account.Whether blocking public access to all or some buckets is an organizational decision that should be based on data sensitivity, least privilege, and use case.","RemediationProcedure": "**If utilizing Block Public Access (bucket settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select the Check box next to the Bucket. 3. Click on 'Edit public access settings'. 4. Click 'Block all public access' 5. Repeat for all the buckets in your AWS account that contain sensitive data.**From Command Line:**1. List all of the S3 Buckets ``` aws s3 ls ``` 2. Set the Block Public Access to true on that bucket ``` aws s3api put-public-access-block --bucket  --public-access-block-configuration \"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true\" ```**If utilizing Block Public Access (account settings)****From Console:**If the output reads `true` for the separate configuration settings then it is set on the account.1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Choose `Block Public Access (account settings)` 3. Choose `Edit` to change the block public access settings for all the buckets in your AWS account 4. Choose the settings you want to change, and then choose `Save`. For details about each setting, pause on the `i` icons. 5. When you're asked for confirmation, enter `confirm`. Then Click `Confirm` to save your changes.**From Command Line:**To set Block Public access settings for this account, run the following command: ``` aws s3control put-public-access-block --public-access-block-configuration BlockPublicAcls=true, IgnorePublicAcls=true, BlockPublicPolicy=true, RestrictPublicBuckets=true --account-id  ```","AdditionalInformation": ""}],"description": "Ensure that S3 Buckets are configured with 'Block public access (bucket settings)'","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"2.2.1": {"name": "2.2.1","checks": {"ec2_ebs_volume_encryption": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.2. Elastic Compute Cloud (EC2)","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html:https://aws.amazon.com/blogs/aws/new-opt-in-to-default-encryption-for-new-ebs-volumes/","Description": "Elastic Compute Cloud (EC2) supports encryption at rest when using the Elastic Block Store (EBS) service. While disabled by default, forcing encryption at EBS volume creation is supported.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under `Account attributes`, click `EBS encryption`. 3. Verify `Always encrypt new EBS volumes` displays `Enabled`. 4. Review every region in-use.**Note:** EBS volume encryption is configured per region.**From Command Line:**1. Run``` aws --region  ec2 get-ebs-encryption-by-default ``` 2. Verify that `\"EbsEncryptionByDefault\": true` is displayed. 3. Review every region in-use.**Note:** EBS volume encryption is configured per region.","ImpactStatement": "Losing access or removing the KMS key in use by the EBS volumes will result in no longer being able to access the volumes.","AssessmentStatus": "Automated","RationaleStatement": "Encrypting data at rest reduces the likelihood that it is unintentionally exposed and can nullify the impact of disclosure if the encryption remains unbroken.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under `Account attributes`, click `EBS encryption`. 3. Click `Manage`. 4. Click the `Enable` checkbox. 5. Click `Update EBS encryption` 6. Repeat for every region requiring the change.**Note:** EBS volume encryption is configured per region.**From Command Line:**1. Run``` aws --region  ec2 enable-ebs-encryption-by-default ``` 2. Verify that `\"EbsEncryptionByDefault\": true` is displayed. 3. Repeat every region requiring the change.**Note:** EBS volume encryption is configured per region.","AdditionalInformation": "Default EBS volume encryption only applies to newly created EBS volumes. Existing EBS volumes are **not** converted automatically."}],"description": "Ensure EBS Volume Encryption is Enabled in all Regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.3.1": {"name": "2.3.1","checks": {"rds_instance_storage_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Encryption.html:https://aws.amazon.com/blogs/database/selecting-the-right-encryption-options-for-amazon-rds-and-amazon-aurora-database-engines/#:~:text=With%20RDS%2Dencrypted%20resources%2C%20data,transparent%20to%20your%20database%20engine.:https://aws.amazon.com/rds/features/security/","Description": "Amazon RDS encrypted DB instances use the industry standard AES-256 encryption algorithm to encrypt your data on the server that hosts your Amazon RDS DB instances. After your data is encrypted, Amazon RDS handles authentication of access and decryption of your data transparently with a minimal impact on performance.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and open the RDS dashboard at https://console.aws.amazon.com/rds/ 2. In the navigation pane, under RDS dashboard, click `Databases`. 3. Select the RDS Instance that you want to examine 4. Click `Instance Name` to see details, then click on `Configuration` tab. 5. Under Configuration Details section, In Storage pane search for the `Encryption Enabled` Status. 6. If the current status is set to `Disabled`, Encryption is not enabled for the selected RDS Instance database instance. 7. Repeat steps 3 to 7 to verify encryption status of other RDS Instance in same region. 8. Change region from the top of the navigation bar and repeat audit for other regions.**From Command Line:**1. Run `describe-db-instances` command to list all RDS Instance database names, available in the selected AWS region, Output will return each Instance database identifier-name.``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. Run again `describe-db-instances` command using the RDS Instance identifier returned earlier, to determine if the selected database instance is encrypted, The command output should return the encryption status `True` Or `False`. ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].StorageEncrypted' ``` 3. If the StorageEncrypted parameter value is `False`, Encryption is not enabled for the selected RDS database instance. 4. Repeat steps 1 to 3 for auditing each RDS Instance and change Region to verify for other regions","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Databases are likely to hold sensitive and critical data, it is highly recommended to implement encryption in order to protect your data from unauthorized access or disclosure. With RDS encryption enabled, the data stored on the instance's underlying storage, the automated backups, read replicas, and snapshots, are all encrypted.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and open the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases` 3. Select the Database instance that needs to be encrypted. 4. Click on `Actions` button placed at the top right and select `Take Snapshot`. 5. On the Take Snapshot page, enter a database name of which you want to take a snapshot in the `Snapshot Name` field and click on `Take Snapshot`. 6. Select the newly created snapshot and click on the `Action` button placed at the top right and select `Copy snapshot` from the Action menu. 7. On the Make Copy of DB Snapshot page, perform the following:- In the New DB Snapshot Identifier field, Enter a name for the `new snapshot`. - Check `Copy Tags`, New snapshot must have the same tags as the source snapshot. - Select `Yes` from the `Enable Encryption` dropdown list to enable encryption, You can choose to use the AWS default encryption key or custom key from Master Key dropdown list.8. Click `Copy Snapshot` to create an encrypted copy of the selected instance snapshot. 9. Select the new Snapshot Encrypted Copy and click on the `Action` button placed at the top right and select `Restore Snapshot` button from the Action menu, This will restore the encrypted snapshot to a new database instance. 10. On the Restore DB Instance page, enter a unique name for the new database instance in the DB Instance Identifier field. 11. Review the instance configuration details and click `Restore DB Instance`. 12. As the new instance provisioning process is completed can update application configuration to refer to the endpoint of the new Encrypted database instance Once the database endpoint is changed at the application level, can remove the unencrypted instance.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names available in the selected AWS region, The command output should return the database instance identifier. ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. Run `create-db-snapshot` command to create a snapshot for the selected database instance, The command output will return the `new snapshot` with name DB Snapshot Name. ``` aws rds create-db-snapshot --region  --db-snapshot-identifier  --db-instance-identifier  ``` 3. Now run `list-aliases` command to list the KMS keys aliases available in a specified region, The command output should return each `key alias currently available`. For our RDS encryption activation process, locate the ID of the AWS default KMS key. ``` aws kms list-aliases --region  ``` 4. Run `copy-db-snapshot` command using the default KMS key ID for RDS instances returned earlier to create an encrypted copy of the database instance snapshot, The command output will return the `encrypted instance snapshot configuration`. ``` aws rds copy-db-snapshot --region  --source-db-snapshot-identifier  --target-db-snapshot-identifier  --copy-tags --kms-key-id  ``` 5. Run `restore-db-instance-from-db-snapshot` command to restore the encrypted snapshot created at the previous step to a new database instance, If successful, the command output should return the new encrypted database instance configuration. ``` aws rds restore-db-instance-from-db-snapshot --region  --db-instance-identifier  --db-snapshot-identifier  ``` 6. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region, Output will return database instance identifier name Select encrypted database name that we just created DB-Name-Encrypted. ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 7. Run again `describe-db-instances` command using the RDS instance identifier returned earlier, to determine if the selected database instance is encrypted, The command output should return the encryption status `True`. ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].StorageEncrypted' ```","AdditionalInformation": ""}],"description": "Ensure that encryption is enabled for RDS Instances","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.3.2": {"name": "2.3.2","checks": {"rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_RDS_Managing.html:https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.Upgrading.html:https://aws.amazon.com/rds/faqs/","Description": "Ensure that RDS database instances have the Auto Minor Version Upgrade flag enabled in order to receive automatically minor engine upgrades during the specified maintenance window. So, RDS instances can get the new features, bug fixes, and security patches for their database engines.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases`. 3. Select the RDS instance that wants to examine. 4. Click on the `Maintenance and backups` panel. 5. Under the `Maintenance` section, search for the Auto Minor Version Upgrade status. - If the current status is set to `Disabled`, means the feature is not set and the minor engine upgrades released will not be applied to the selected RDS instance**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance identifier. 3. Run again `describe-db-instances` command using the RDS instance identifier returned earlier to determine the Auto Minor Version Upgrade status for the selected instance: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].AutoMinorVersionUpgrade' ``` 4. The command output should return the feature current status. If the current status is set to `true`, the feature is enabled and the minor engine upgrades will be applied to the selected RDS instance.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "AWS RDS will occasionally deprecate minor engine versions and provide new ones for an upgrade. When the last version number within the release is replaced, the version changed is considered minor. With Auto Minor Version Upgrade feature enabled, the version upgrades will occur automatically during the specified maintenance window so your RDS instances can get the new features, bug fixes, and security patches for their database engines.","RemediationProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases`. 3. Select the RDS instance that wants to update. 4. Click on the `Modify` button placed on the top right side. 5. On the `Modify DB Instance: ` page, In the `Maintenance` section, select `Auto minor version upgrade` click on the `Yes` radio button. 6. At the bottom of the page click on `Continue`, check to Apply Immediately to apply the changes immediately, or select `Apply during the next scheduled maintenance window` to avoid any downtime. 7. Review the changes and click on `Modify DB Instance`. The instance status should change from available to modifying and back to available. Once the feature is enabled, the `Auto Minor Version Upgrade` status should change to `Yes`.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database instance names, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance identifier. 3. Run the `modify-db-instance` command to modify the selected RDS instance configuration this command will apply the changes immediately, Remove `--apply-immediately` to apply changes during the next scheduled maintenance window and avoid any downtime: ``` aws rds modify-db-instance --region  --db-instance-identifier  --auto-minor-version-upgrade --apply-immediately ``` 4. The command output should reveal the new configuration metadata for the RDS instance and check `AutoMinorVersionUpgrade` parameter value. 5. Run `describe-db-instances` command to check if the Auto Minor Version Upgrade feature has been successfully enable: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].AutoMinorVersionUpgrade' ``` 6. The command output should return the feature current status set to `true`, the feature is `enabled` and the minor engine upgrades will be applied to the selected RDS instance.","AdditionalInformation": ""}],"description": "Ensure Auto Minor Version Upgrade feature is Enabled for RDS Instances","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.3.3": {"name": "2.3.3","checks": {"rds_instance_no_public_access": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.html:https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario2.html:https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html:https://aws.amazon.com/rds/faqs/","Description": "Ensure and verify that RDS database instances provisioned in your AWS account do restrict unauthorized access in order to minimize security risks. To restrict access to any publicly accessible RDS database instance, you must disable the database Publicly Accessible flag and update the VPC security group associated with the instance.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. Under the navigation panel, On RDS Dashboard, click `Databases`. 3. Select the RDS instance that you want to examine. 4. Click `Instance Name` from the dashboard, Under `Connectivity and Security. 5. On the `Security`, check if the Publicly Accessible flag status is set to `Yes`, follow the below-mentioned steps to check database subnet access. - In the `networking` section, click the subnet link available under `Subnets` - The link will redirect you to the VPC Subnets page. - Select the subnet listed on the page and click the `Route Table` tab from the dashboard bottom panel. If the route table contains any entries with the destination `CIDR block set to 0.0.0.0/0` and with an `Internet Gateway` attached. - The selected RDS database instance was provisioned inside a public subnet, therefore is not running within a logically isolated environment and can be accessible from the Internet. 6. Repeat steps no. 4 and 5 to determine the type (public or private) and subnet for other RDS database instances provisioned in the current region. 8. Change the AWS region from the navigation bar and repeat the audit process for other regions.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance `identifier`. 3. Run again `describe-db-instances` command using the `PubliclyAccessible` parameter as query filter to reveal the database instance Publicly Accessible flag status: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].PubliclyAccessible' ``` 4. Check for the Publicly Accessible parameter status, If the Publicly Accessible flag is set to `Yes`. Then selected RDS database instance is publicly accessible and insecure, follow the below-mentioned steps to check database subnet access 5. Run again `describe-db-instances` command using the RDS database instance identifier that you want to check and appropriate filtering to describe the VPC subnet(s) associated with the selected instance: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].DBSubnetGroup.Subnets[]' ``` - The command output should list the subnets available in the selected database subnet group. 6. Run `describe-route-tables` command using the ID of the subnet returned at the previous step to describe the routes of the VPC route table associated with the selected subnet: ``` aws ec2 describe-route-tables --region  --filters \"Name=association.subnet-id,Values=\" --query 'RouteTables[*].Routes[]' ``` - If the command returns the route table associated with database instance subnet ID. Check the `GatewayId` and `DestinationCidrBlock` attributes values returned in the output. If the route table contains any entries with the `GatewayId` value set to `igw-xxxxxxxx` and the `DestinationCidrBlock` value set to `0.0.0.0/0`, the selected RDS database instance was provisioned inside a public subnet. - Or - If the command returns empty results, the route table is implicitly associated with subnet, therefore the audit process continues with the next step 7. Run again `describe-db-instances` command using the RDS database instance identifier that you want to check and appropriate filtering to describe the VPC ID associated with the selected instance: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].DBSubnetGroup.VpcId' ``` - The command output should show the VPC ID in the selected database subnet group 8. Now run `describe-route-tables` command using the ID of the VPC returned at the previous step to describe the routes of the VPC main route table implicitly associated with the selected subnet: ``` aws ec2 describe-route-tables --region  --filters \"Name=vpc-id,Values=\" \"Name=association.main,Values=true\" --query 'RouteTables[*].Routes[]' ``` - The command output returns the VPC main route table implicitly associated with database instance subnet ID. Check the `GatewayId` and `DestinationCidrBlock` attributes values returned in the output. If the route table contains any entries with the `GatewayId` value set to `igw-xxxxxxxx` and the `DestinationCidrBlock` value set to `0.0.0.0/0`, the selected RDS database instance was provisioned inside a public subnet, therefore is not running within a logically isolated environment and does not adhere to AWS security best practices.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Ensure that no public-facing RDS database instances are provisioned in your AWS account and restrict unauthorized access in order to minimize security risks. When the RDS instance allows unrestricted access (0.0.0.0/0), everyone and everything on the Internet can establish a connection to your database and this can increase the opportunity for malicious activities such as brute force attacks, PostgreSQL injections, or DoS/DDoS attacks.","RemediationProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. Under the navigation panel, On RDS Dashboard, click `Databases`. 3. Select the RDS instance that you want to update. 4. Click `Modify` from the dashboard top menu. 5. On the Modify DB Instance panel, under the `Connectivity` section, click on `Additional connectivity configuration` and update the value for `Publicly Accessible` to Not publicly accessible to restrict public access. Follow the below steps to update subnet configurations: - Select the `Connectivity and security` tab, and click on the VPC attribute value inside the `Networking` section. - Select the `Details` tab from the VPC dashboard bottom panel and click on Route table configuration attribute value. - On the Route table details page, select the Routes tab from the dashboard bottom panel and click on `Edit routes`. - On the Edit routes page, update the Destination of Target which is set to `igw-xxxxx` and click on `Save` routes. 6. On the Modify DB Instance panel Click on `Continue` and In the Scheduling of modifications section, perform one of the following actions based on your requirements: - Select Apply during the next scheduled maintenance window to apply the changes automatically during the next scheduled maintenance window. - Select Apply immediately to apply the changes right away. With this option, any pending modifications will be asynchronously applied as soon as possible, regardless of the maintenance window setting for this RDS database instance. Note that any changes available in the pending modifications queue are also applied. If any of the pending modifications require downtime, choosing this option can cause unexpected downtime for the application. 7. Repeat steps 3 to 6 for each RDS instance available in the current region. 8. Change the AWS region from the navigation bar to repeat the process for other regions.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names identifiers, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance identifier. 3. Run `modify-db-instance` command to modify the selected RDS instance configuration. Then use the following command to disable the `Publicly Accessible` flag for the selected RDS instances. This command use the apply-immediately flag. If you want `to avoid any downtime --no-apply-immediately flag can be used`: ``` aws rds modify-db-instance --region  --db-instance-identifier  --no-publicly-accessible --apply-immediately ``` 4. The command output should reveal the `PubliclyAccessible` configuration under pending values and should get applied at the specified time. 5. Updating the Internet Gateway Destination via AWS CLI is not currently supported To update information about Internet Gateway use the AWS Console Procedure. 6. Repeat steps 1 to 5 for each RDS instance provisioned in the current region. 7. Change the AWS region by using the --region filter to repeat the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that public access is not given to RDS Instance","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.4.1": {"name": "2.4.1","checks": {"efs_encryption_at_rest_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.4 Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/efs/index.html#efs","Description": "EFS data should be encrypted at rest using AWS KMS (Key Management Service).","DefaultValue": null,"AuditProcedure": "**From Console:** 1. Login to the AWS Management Console and Navigate to `Elastic File System (EFS) dashboard. 2. Select `File Systems` from the left navigation panel. 3. Each item on the list has a visible Encrypted field that displays data at rest encryption status. 4. Validate that this field reads `Encrypted` for all EFS file systems in all AWS regions.**From CLI:** 1. Run describe-file-systems command using custom query filters to list the identifiers of all AWS EFS file systems currently available within the selected region: ``` aws efs describe-file-systems --region  --output table --query 'FileSystems[*].FileSystemId' ``` 2. The command output should return a table with the requested file system IDs. 3. Run describe-file-systems command using the ID of the file system that you want to examine as identifier and the necessary query filters: ``` aws efs describe-file-systems --region  --file-system-id  --query 'FileSystems[*].Encrypted' ``` 4. The command output should return the file system encryption status true or false. If the returned value is `false`, the selected AWS EFS file system is not encrypted and if the returned value is `true`, the selected AWS EFS file system is encrypted.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Data should be encrypted at rest to reduce the risk of a data breach via direct access to the storage device.","RemediationProcedure": "**It is important to note that EFS file system data at rest encryption must be turned on when creating the file system.**If an EFS file system has been created without data at rest encryption enabled then you must create another EFS file system with the correct configuration and transfer the data.**Steps to create an EFS file system with data encrypted at rest:****From Console:** 1. Login to the AWS Management Console and Navigate to `Elastic File System (EFS)` dashboard. 2. Select `File Systems` from the left navigation panel. 3. Click `Create File System` button from the dashboard top menu to start the file system setup process. 4. On the `Configure file system access` configuration page, perform the following actions. - Choose the right VPC from the VPC dropdown list. - Within Create mount targets section, select the checkboxes for all of the Availability Zones (AZs) within the selected VPC. These will be your mount targets. - Click `Next step` to continue.5. Perform the following on the `Configure optional settings` page. - Create `tags` to describe your new file system. - Choose `performance mode` based on your requirements. - Check `Enable encryption` checkbox and choose `aws/elasticfilesystem` from Select KMS master key dropdown list to enable encryption for the new file system using the default master key provided and managed by AWS KMS. - Click `Next step` to continue.6. Review the file system configuration details on the `review and create` page and then click `Create File System` to create your new AWS EFS file system. 7. Copy the data from the old unencrypted EFS file system onto the newly create encrypted file system. 8. Remove the unencrypted file system as soon as your data migration to the newly create encrypted file system is completed. 9. Change the AWS region from the navigation bar and repeat the entire process for other aws regions.**From CLI:** 1. Run describe-file-systems command to describe the configuration information available for the selected (unencrypted) file system (see Audit section to identify the right resource): ``` aws efs describe-file-systems --region  --file-system-id  ``` 2. The command output should return the requested configuration information. 3. To provision a new AWS EFS file system, you need to generate a universally unique identifier (UUID) in order to create the token required by the create-file-system command. To create the required token, you can use a randomly generated UUID from \"https://www.uuidgenerator.net\". 4. Run create-file-system command using the unique token created at the previous step. ``` aws efs create-file-system --region  --creation-token  --performance-mode generalPurpose --encrypted ``` 5. The command output should return the new file system configuration metadata. 6. Run create-mount-target command using the newly created EFS file system ID returned at the previous step as identifier and the ID of the Availability Zone (AZ) that will represent the mount target: ``` aws efs create-mount-target --region  --file-system-id  --subnet-id  ``` 7. The command output should return the new mount target metadata. 8. Now you can mount your file system from an EC2 instance. 9. Copy the data from the old unencrypted EFS file system onto the newly create encrypted file system. 10. Remove the unencrypted file system as soon as your data migration to the newly create encrypted file system is completed. ``` aws efs delete-file-system --region  --file-system-id  ``` 11. Change the AWS region by updating the --region and repeat the entire process for other aws regions.","AdditionalInformation": ""}],"description": "Ensure that encryption is enabled for EFS file systems","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 52,"requirements_failed": 11,"requirements_manual": 1,"total_requirements": 64,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "7aee25d8-9e9a-44e1-8e01-336bfd9d9582","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "aws_well_architected_framework_reliability_pillar_aws","framework": "AWS-Well-Architected-Framework-Reliability-Pillar","version": "","description": "Best Practices for the AWS Well-Architected Framework Reliability Pillar encompasses the ability of a workload to perform its intended function correctly and consistently when it’s expected to. This includes the ability to operate and test the workload through its total lifecycle.","region": "eu-west-1","requirements": {"REL06-BP01": {"name": "REL06-BP01","checks": {"elb_logging_enabled": "FAIL","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","apigatewayv2_api_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","opensearch_service_domains_audit_logging_enabled": null,"opensearch_service_domains_cloudwatch_logging_enabled": null,"awslambda_function_invoke_api_operations_cloudtrail_logging_enabled": "PASS"},"status": "FAIL","attributes": [{"Name": "REL06-BP01 Monitor all components for the workload (Generation)","Section": "Change management","SubSection": "Monitor workload resources","Description": "Monitor components and services of AWS workload effectifely, using tools like Amazon CloudWatch and AWS Health Dashboard. Define relevant metrics, set thresholds, and analyze metrics and logs for early detection of issues.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_monitor_aws_resources_monitor_resources.html#implementation-guidance","WellArchitectedPracticeId": "rel_monitor_aws_resources_monitor_resources","WellArchitectedQuestionId": "monitor-aws-resources"}],"description": "Monitor components and services of AWS workload effectifely, using tools like Amazon CloudWatch and AWS Health Dashboard. Define relevant metrics, set thresholds, and analyze metrics and logs for early detection of issues.","checks_status": {"fail": 5,"pass": 2,"total": 9,"manual": 0}},"REL09-BP03": {"name": "REL09-BP03","checks": {"rds_instance_backup_enabled": "PASS","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL","cloudformation_stacks_termination_protection_enabled": "FAIL"},"status": "FAIL","attributes": [{"Name": "REL09-BP03 Perform data backup automatically","Section": "Failure management","SubSection": "Backup up data","Description": "Configure backups to be taken automatically based on a periodic schedule informed by the Recovery Point Objective (RPO), or by changes in the dataset. Critical datasets with low data loss requirements need to be backed up automatically on a frequent basis, whereas less critical data where some loss is acceptable can be backed up less frequently.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_backing_up_data_automated_backups_data.html#implementation-guidance","WellArchitectedPracticeId": "rel_backing_up_data_automated_backups_data","WellArchitectedQuestionId": "backing-up-data"}],"description": "Configure backups to be taken automatically based on a periodic schedule informed by the Recovery Point Objective (RPO), or by changes in the dataset. Critical datasets with low data loss requirements need to be backed up automatically on a frequent basis, whereas less critical data where some loss is acceptable can be backed up less frequently.","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"REL10-BP01": {"name": "REL10-BP01","checks": {"rds_instance_multi_az": "FAIL"},"status": "FAIL","attributes": [{"Name": "REL10-BP01 Deploy the workload to multiple locations","Section": "Failure management","SubSection": "Use fault isolation to protect your workload","Description": "Distribute workload data and resources across multiple Availability Zones or, where necessary, across AWS Regions. These locations can be as diverse as required.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/use-fault-isolation-to-protect-your-workload.html#implementation-guidance.","WellArchitectedPracticeId": "rel_fault_isolation_multiaz_region_system","WellArchitectedQuestionId": "fault-isolation"}],"description": "Distribute workload data and resources across multiple Availability Zones or, where necessary, across AWS Regions. These locations can be as diverse as required.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 0,"requirements_failed": 3,"requirements_manual": 0,"total_requirements": 3,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "85c783d4-a01a-4297-b490-216e38ee144e","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "iso27001_2013_aws","framework": "ISO27001","version": "2013","description": "ISO (the International Organization for Standardization) and IEC (the International Electrotechnical Commission) form the specialized system for worldwide standardization. National bodies that are members of ISO or IEC participate in the development of International Standards through technical committees established by the respective organization to deal with particular fields of technical activity. ISO and IEC technical committees collaborate in fields of mutual interest. Other international organizations, governmental and non-governmental, in liaison with ISO and IEC, also take part in the work.","region": "eu-west-1","requirements": {"A.9.2": {"name": "User Access Management","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Category": "A.9 Access Control","Objetive_ID": "A.9.2","Check_Summary": "Ensure no root account access key exists","Objetive_Name": "User Access Management"}],"description": "Ensure no root account access key exists","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"A.9.3": {"name": "User Responsibilities","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Category": "A.9 Access Control","Objetive_ID": "A.9.3","Check_Summary": "Ensure credentials unused for 90 days or greater are disabled","Objetive_Name": "User Responsibilities"}],"description": "Ensure credentials unused for 90 days or greater are disabled","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"A.9.4": {"name": "System and Application Access Control","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Category": "A.9 Access Control","Objetive_ID": "A.9.4","Check_Summary": "Ensure no root account access key exists","Objetive_Name": "System and Application Access Control"}],"description": "Ensure no root account access key exists","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"A.10.1": {"name": "Cryptographic Controls","checks": {"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "PASS","attributes": [{"Category": "A.10 Cryptography","Objetive_ID": "A.10.1","Check_Summary": "Detect Customer Master Keys (CMKs) scheduled for deletion","Objetive_Name": "Cryptographic Controls"}],"description": "Detect Customer Master Keys (CMKs) scheduled for deletion","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"A.12.4": {"name": "Logging and Monitoring","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Category": "A.12 Operations Security","Objetive_ID": "A.12.4","Check_Summary": "Ensure CloudTrail is enabled in all regions","Objetive_Name": "Logging and Monitoring"}],"description": "Ensure CloudTrail is enabled in all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"A.12.6": {"name": "Technical Vulnerability Management","checks": {"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS"},"status": "PASS","attributes": [{"Category": "A.12 Operations Security","Objetive_ID": "A.12.6","Check_Summary": "Ensure the S3 bucket CloudTrail logs to is not publicly accessible","Objetive_Name": "Technical Vulnerability Management"}],"description": "Ensure the S3 bucket CloudTrail logs to is not publicly accessible","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"A.13.1": {"name": "Network Security Management","checks": {"rds_instance_no_public_access": "PASS"},"status": "PASS","attributes": [{"Category": "A.13 Communications Security","Objetive_ID": "A.13.1","Check_Summary": "Ensure RDS instances are not accessible to the world.","Objetive_Name": "Network Security Management"}],"description": "Ensure RDS instances are not accessible to the world.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}}},"requirements_passed": 79,"requirements_failed": 0,"requirements_manual": 0,"total_requirements": 79,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "86401f28-9311-42b9-ac06-a3cdcc9e5e39","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "soc2_aws","framework": "SOC2","version": "","description": "System and Organization Controls (SOC), defined by the American Institute of Certified Public Accountants (AICPA), is the name of a set of reports that's produced during an audit. It's intended for use by service organizations (organizations that provide information systems as a service to other organizations) to issue validated reports of internal controls over those information systems to the users of those services. The reports focus on controls grouped into five categories known as Trust Service Principles.","region": "eu-west-1","requirements": {"p_1_1": {"name": "P1.1 The entity provides notice to data subjects about its privacy practices to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_1_1","Section": "P1.0 - Privacy Criteria Related to Notice and Communication of Objectives Related to Privacy","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The entity provides notice to data subjects about its privacy practices to meet the entity’s objectives related to privacy. The notice is updated and communicated to data subjects in a timely manner for changes to the entity’s privacy practices, including changes in the use of personal information, to meet the entity’s objectives related to privacy. Communicates to Data Subjects - Notice is provided to data subjects regarding the following: Purpose for collecting personal informationChoice and consentTypes of personal information collectedMethods of collection (for example, use of cookies or other tracking techniques)Use, retention, and disposalAccessDisclosure to third partiesSecurity for privacyQuality, including data subjects’ responsibilities for qualityMonitoring and enforcementIf personal information is collected from sources other than the individual, such sources are described in the privacy notice. Provides Notice to Data Subjects - Notice is provided to data subjects (1) at or before the time personal information is collected or as soon as practical thereafter, (2) at or before the entity changes its privacy notice or as soon as practical thereafter, or (3) before personal information is used for new purposes not previously identified. Covers Entities and Activities in Notice - An objective description of the entities and activities covered is included in the entity’s privacy notice. Uses Clear and Conspicuous Language - The entity’s privacy notice is conspicuous and uses clear language.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_2_1": {"name": "P2.1 The entity communicates choices available regarding the collection, use, retention, disclosure, and disposal of personal information to the data subjects and the consequences, if any, of each choice","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_2_1","Section": "P2.0 - Privacy Criteria Related to Choice and Consent","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The entity communicates choices available regarding the collection, use, retention, disclosure, and disposal of personal information to the data subjects and the consequences, if any, of each choice. Explicit consent for the collection, use, retention, disclosure, and disposal of personal information is obtained from data subjects or other authorized persons, if required. Such consent is obtained only for the intended purpose of the information to meet the entity’s objectives related to privacy. The entity’s basis for determining implicit consent for the collection, use, retention, disclosure, and disposal of personal information is documented. Communicates to Data Subjects - Data subjects are informed (a) about the choices available to them with respect to the collection, use, and disclosure of personal information and (b) that implicit or explicit consent is required to collect, use, and disclose personal information, unless a law or regulation specifically requires or allows otherwise. Communicates Consequences of Denying or Withdrawing Consent - When personal information is collected, data subjects are informed of the consequences of refusing to provide personal information or denying or withdrawing consent to use personal information for purposes identified in the notice. Obtains Implicit or Explicit Consent - Implicit or explicit consent is obtained from data subjects at or before the time personal information is collected or soon thereafter. The individual’s preferences expressed in his or her consent are confirmed and implemented. Documents and Obtains Consent for New Purposes and Uses - If information that was previously collected is to be used for purposes not previously identified in the privacy notice, the new purpose is documented, the data subject is notified, and implicit or explicit consent is obtained prior to such new use or purpose. Obtains Explicit Consent for Sensitive Information - Explicit consent is obtained directly from the data subject when sensitive personal information is collected, used, or disclosed, unless a law or regulation specifically requires otherwise.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_3_1": {"name": "P3.1 Personal information is collected consistent with the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_3_1","Section": "P3.0 - Privacy Criteria Related to Collection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Limits the Collection of Personal Information - The collection of personal information is limited to that necessary to meet the entity’s objectives. Collects Information by Fair and Lawful Means - Methods of collecting personal information are reviewed by management before they are implemented to confirm that personal information is obtained (a) fairly, without intimidation or deception, and (b) lawfully, adhering to all relevant rules of law, whether derived from statute or common law, relating to the collection of personal information. Collects Information From Reliable Sources - Management confirms that third parties from whom personal information is collected (that is, sources other than the individual) are reliable sources that collect information fairly and lawfully. Informs Data Subjects When Additional Information Is Acquired - Data subjects are informed if the entity develops or acquires additional information about them for its use.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_3_2": {"name": "P3.2 For information requiring explicit consent, the entity communicates the need for such consent, as well as the consequences of a failure to provide consent for the request for personal information, and obtains the consent prior to the collection of the information to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_3_2","Section": "P3.0 - Privacy Criteria Related to Collection","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Obtains Explicit Consent for Sensitive Information - Explicit consent is obtained directly from the data subject when sensitive personal information is collected, used, or disclosed, unless a law or regulation specifically requires otherwise. Documents Explicit Consent to Retain Information - Documentation of explicit consent for the collection, use, or disclosure of sensitive personal information is retained in accordance with objectives related to privacy.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_4_1": {"name": "P4.1 The entity limits the use of personal information to the purposes identified in the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_4_1","Section": "P4.0 - Privacy Criteria Related to Use, Retention, and Disposal","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Uses Personal Information for Intended Purposes - Personal information is used only for the intended purposes for which it was collected and only when implicit or explicit consent has been obtained unless a law or regulation specifically requires otherwise.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_4_2": {"name": "P4.2 The entity retains personal information consistent with the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_4_2","Section": "P4.0 - Privacy Criteria Related to Use, Retention, and Disposal","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Retains Personal Information - Personal information is retained for no longer than necessary to fulfill the stated purposes, unless a law or regulation specifically requires otherwise. Protects Personal Information - Policies and procedures have been implemented to protect personal information from erasure or destruction during the specified retention period of the information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_4_3": {"name": "P4.3 The entity securely disposes of personal information to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_4_3","Section": "P4.0 - Privacy Criteria Related to Use, Retention, and Disposal","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Captures, Identifies, and Flags Requests for Deletion - Requests for deletion of personal information are captured, and information related to the requests is identified and flagged for destruction to meet the entity’s objectives related to privacy. Disposes of, Destroys, and Redacts Personal Information - Personal information no longer retained is anonymized, disposed of, or destroyed in a manner that prevents loss, theft, misuse, or unauthorized access. Destroys Personal Information - Policies and procedures are implemented to erase or otherwise destroy personal information that has been identified for destruction.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_5_1": {"name": "P5.1 The entity grants identified and authenticated data subjects the ability to access their stored personal information for review and, upon request, provides physical or electronic copies of that information to data subjects to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_5_1","Section": "P5.0 - Privacy Criteria Related to Access","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The entity grants identified and authenticated data subjects the ability to access their stored personal information for review and, upon request, provides physical or electronic copies of that information to data subjects to meet the entity’s objectives related to privacy. If access is denied, data subjects are informed of the denial and reason for such denial, as required, to meet the entity’s objectives related to privacy. Authenticates Data Subjects’ Identity - The identity of data subjects who request access to their personal information is authenticated before they are given access to that information. Permits Data Subjects Access to Their Personal Information - Data subjects are able to determine whether the entity maintains personal information about them and, upon request, may obtain access to their personal information. Provides Understandable Personal Information Within Reasonable Time - Personal information is provided to data subjects in an understandable form, in a reasonable time frame, and at a reasonable cost, if any. Informs Data Subjects If Access Is Denied - When data subjects are denied access to their personal information, the entity informs them of the denial and the reason for the denial in a timely manner, unless prohibited by law or regulation.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_5_2": {"name": "P5.2 The entity corrects, amends, or appends personal information based on information provided by data subjects and communicates such information to third parties, as committed or required, to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_5_2","Section": "P5.0 - Privacy Criteria Related to Access","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The entity corrects, amends, or appends personal information based on information provided by data subjects and communicates such information to third parties, as committed or required, to meet the entity’s objectives related to privacy. If a request for correction is denied, data subjects are informed of the denial and reason for such denial to meet the entity’s objectives related to privacy. Communicates Denial of Access Requests - Data subjects are informed, in writing, of the reason a request for access to their personal information was denied, the source of the entity’s legal right to deny such access, if applicable, and the individual’s right, if any, to challenge such denial, as specifically permitted or required by law or regulation. Permits Data Subjects to Update or Correct Personal Information - Data subjects are able to update or correct personal information held by the entity. The entity provides such updated or corrected information to third parties that were previously provided with the data subject’s personal information consistent with the entity’s objective related to privacy. Communicates Denial of Correction Requests - Data subjects are informed, in writing, about the reason a request for correction of personal information was denied and how they may appeal.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_6_1": {"name": "P6.1 The entity discloses personal information to third parties with the explicit consent of data subjects, and such consent is obtained prior to disclosure to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_6_1","Section": "P6.0 - Privacy Criteria Related to Disclosure and Notification","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Communicates Privacy Policies to Third Parties - Privacy policies or other specific instructions or requirements for handling personal information are communicated to third parties to whom personal information is disclosed. Discloses Personal Information Only When Appropriate - Personal information is disclosed to third parties only for the purposes for which it was collected or created and only when implicit or explicit consent has been obtained from the data subject, unless a law or regulation specifically requires otherwise. Discloses Personal Information Only to Appropriate Third Parties - Personal information is disclosed only to third parties who have agreements with the entity to protect personal information in a manner consistent with the relevant aspects of the entity’s privacy notice or other specific instructions or requirements. The entity has procedures in place to evaluate that the third parties have effective controls to meet the terms of the agreement, instructions, or requirements.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_6_2": {"name": "P6.2 The entity creates and retains a complete, accurate, and timely record of authorized disclosures of personal information to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_6_2","Section": "P6.0 - Privacy Criteria Related to Disclosure and Notification","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Creates and Retains Record of Authorized Disclosures - The entity creates and maintains a record of authorized disclosures of personal information that is complete, accurate, and timely.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_6_3": {"name": "P6.3 The entity creates and retains a complete, accurate, and timely record of detected or reported unauthorized disclosures (including breaches) of personal information to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_6_3","Section": "P6.0 - Privacy Criteria Related to Disclosure and Notification","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Creates and Retains Record of Detected or Reported Unauthorized Disclosures - The entity creates and maintains a record of detected or reported unauthorized disclosures of personal information that is complete, accurate, and timely.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_6_4": {"name": "P6.4 The entity obtains privacy commitments from vendors and other third parties who have access to personal information to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_6_4","Section": "P6.0 - Privacy Criteria Related to Disclosure and Notification","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The entity obtains privacy commitments from vendors and other third parties who have access to personal information to meet the entity’s objectives related to privacy. The entity assesses those parties’ compliance on a periodic and as-needed basis and takes corrective action, if necessary. Discloses Personal Information Only to Appropriate Third Parties - Personal information is disclosed only to third parties who have agreements with the entity to protect personal information in a manner consistent with the relevant aspects of the entity’s privacy notice or other specific instructions or requirements. The entity has procedures in place to evaluate that the third parties have effective controls to meet the terms of the agreement, instructions, or requirements. Remediates Misuse of Personal Information by a Third Party - The entity takes remedial action in response to misuse of personal information by a third party to whom the entity has transferred such information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_6_5": {"name": "P6.5 The entity obtains commitments from vendors and other third parties with access to personal information to notify the entity in the event of actual or suspected unauthorized disclosures of personal information","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_6_5","Section": "P6.0 - Privacy Criteria Related to Disclosure and Notification","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The entity obtains commitments from vendors and other third parties with access to personal information to notify the entity in the event of actual or suspected unauthorized disclosures of personal information. Such notifications are reported to appropriate personnel and acted on in accordance with established incident response procedures to meet the entity’s objectives related to privacy. Remediates Misuse of Personal Information by a Third Party - The entity takes remedial action in response to misuse of personal information by a third party to whom the entity has transferred such information. Reports Actual or Suspected Unauthorized Disclosures - A process exists for obtaining commitments from vendors and other third parties to report to the entity actual or suspected unauthorized disclosures of personal information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_6_6": {"name": "P6.6 The entity provides notification of breaches and incidents to affected data subjects, regulators, and others to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_6_6","Section": "P6.0 - Privacy Criteria Related to Disclosure and Notification","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Remediates Misuse of Personal Information by a Third Party - The entity takes remedial action in response to misuse of personal information by a third party to whom the entity has transferred such information. Reports Actual or Suspected Unauthorized Disclosures - A process exists for obtaining commitments from vendors and other third parties to report to the entity actual or suspected unauthorized disclosures of personal information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_6_7": {"name": "P6.7 The entity provides data subjects with an accounting of the personal information held and disclosure of the data subjects’ personal information, upon the data subjects’ request, to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_6_7","Section": "P6.0 - Privacy Criteria Related to Disclosure and Notification","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Identifies Types of Personal Information and Handling Process - The types of personal information and sensitive personal information and the related processes, systems, and third parties involved in the handling of such information are identified. Captures, Identifies, and Communicates Requests for Information - Requests for an accounting of personal information held and disclosures of the data subjects’ personal information are captured, and information related to the requests is identified and communicated to data subjects to meet the entity’s objectives related to privacy.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_7_1": {"name": "P7.1 The entity collects and maintains accurate, up-to-date, complete, and relevant personal information to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_7_1","Section": "P7.0 - Privacy Criteria Related to Quality","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Ensures Accuracy and Completeness of Personal Information - Personal information is accurate and complete for the purposes for which it is to be used. Ensures Relevance of Personal Information - Personal information is relevant to the purposes for which it is to be used.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"p_8_1": {"name": "P8.1 The entity implements a process for receiving, addressing, resolving, and communicating the resolution of inquiries, complaints, and disputes from data subjects and others and periodically monitors compliance to meet the entity’s objectives related to privacy","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "p_8_1","Section": "P8.0 - Privacy Criteria Related to Monitoring and Enforcement","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The entity implements a process for receiving, addressing, resolving, and communicating the resolution of inquiries, complaints, and disputes from data subjects and others and periodically monitors compliance to meet the entity’s objectives related to privacy. Corrections and other necessary actions related to identified deficiencies are made or taken in a timely manner. Communicates to Data Subjects—Data subjects are informed about how to contact the entity with inquiries, complaints, and disputes. Addresses Inquiries, Complaints, and Disputes - A process is in place to address inquiries, complaints, and disputes. Documents and Communicates Dispute Resolution and Recourse - Each complaint is addressed, and the resolution is documented and communicated to the individual. Documents and Reports Compliance Review Results - Compliance with objectives related to privacy are reviewed and documented, and the results of such reviews are reported to management. If problems are identified, remediation plans are developed and implemented. Documents and Reports Instances of Noncompliance - Instances of noncompliance with objectives related to privacy are documented and reported and, if needed, corrective and disciplinary measures are taken on a timely basis. Performs Ongoing Monitoring - Ongoing procedures are performed for monitoring the effectiveness of controls over personal information and for taking timely corrective actions when necessary.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_1_1": {"name": "CC1.1 COSO Principle 1: The entity demonstrates a commitment to integrity and ethical values","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_1_1","Section": "CC1.0 - Common Criteria Related to Control Environment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Sets the Tone at the Top - The board of directors and management, at all levels, demonstrate through their directives, actions, and behavior the importance of integrity and ethical values to support the functioning of the system of internal control. Establishes Standards of Conduct - The expectations of the board of directors and senior management concerning integrity and ethical values are defined in the entity’s standards of conduct and understood at all levels of the entity and by outsourced service providers and business partners. Evaluates Adherence to Standards of Conduct - Processes are in place to evaluate the performance of individuals and teams against the entity’s expected standards of conduct. Addresses Deviations in a Timely Manner - Deviations from the entity’s expected standards of conduct are identified and remedied in a timely and consistent manner.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_1_2": {"name": "CC1.2 COSO Principle 2: The board of directors demonstrates independence from management and exercises oversight of the development and performance of internal control","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_1_2","Section": "CC1.0 - Common Criteria Related to Control Environment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establishes Oversight Responsibilities - The board of directors identifies and accepts its oversight responsibilities in relation to established requirements and expectations. Applies Relevant Expertise - The board of directors defines, maintains, and periodically evaluates the skills and expertise needed among its members to enable them to ask probing questions of senior management and take commensurate action. Operates Independently - The board of directors has sufficient members who are independent from management and objective in evaluations and decision making. Additional point of focus specifically related to all engagements using the trust services criteria: Supplements Board Expertise - The board of directors supplements its expertise relevant to security, availability, processing integrity, confidentiality, and privacy, as needed, through the use of a subcommittee or consultants.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_1_3": {"name": "CC1.3 COSO Principle 3: Management establishes, with board oversight, structures, reporting lines, and appropriate authorities and responsibilities in the pursuit of objectives","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_1_3","Section": "CC1.0 - Common Criteria Related to Control Environment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Considers All Structures of the Entity - Management and the board of directors consider the multiple structures used (including operating units, legal entities, geographic distribution, and outsourced service providers) to support the achievement of objectives. Establishes Reporting Lines - Management designs and evaluates lines of reporting for each entity structure to enable execution of authorities and responsibilities and flow of information to manage the activities of the entity. Defines, Assigns, and Limits Authorities and Responsibilities - Management and the board of directors delegate authority, define responsibilities, and use appropriate processes and technology to assign responsibility and segregate duties as necessary at the various levels of the organization. Additional points of focus specifically related to all engagements using the trust services criteria: Addresses Specific Requirements When Defining Authorities and Responsibilities—Management and the board of directors consider requirements relevant to security, availability, processing integrity, confidentiality, and privacy when defining authorities and responsibilities. Considers Interactions With External Parties When Establishing Structures, Reporting Lines, Authorities, and Responsibilities — Management and the board of directors consider the need for the entity to interact with and monitor the activities of external parties when establishing structures, reporting lines, authorities, and responsibilities.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"cc_1_4": {"name": "CC1.4 COSO Principle 4: The entity demonstrates a commitment to attract, develop, and retain competent individuals in alignment with objectives","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_1_4","Section": "CC1.0 - Common Criteria Related to Control Environment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establishes Policies and Practices - Policies and practices reflect expectations of competence necessary to support the achievement of objectives. Evaluates Competence and Addresses Shortcomings - The board of directors and management evaluate competence across the entity and in outsourced service providers in relation to established policies and practices and act as necessary to address shortcomings. Attracts, Develops, and Retains Individuals - The entity provides the mentoring and training needed to attract, develop, and retain sufficient and competent personnel and outsourced service providers to support the achievement of objectives. Plans and Prepares for Succession - Senior management and the board of directors develop contingency plans for assignments of responsibility important for internal control. Additional point of focus specifically related to all engagements using the trust services criteria: Considers the Background of Individuals - The entity considers the background of potential and existing personnel, contractors, and vendor employees when determining whether to employ and retain the individuals. Considers the Technical Competency of Individuals - The entity considers the technical competency of potential and existing personnel, contractors, and vendor employees when determining whether to employ and retain the individuals. Provides Training to Maintain Technical Competencies - The entity provides training programs, including continuing education and training, to ensure skill sets and technical competency of existing personnel, contractors, and vendor employees are developed and maintained.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_1_5": {"name": "CC1.5 COSO Principle 5: The entity holds individuals accountable for their internal control responsibilities in the pursuit of objectives","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_1_5","Section": "CC1.0 - Common Criteria Related to Control Environment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Enforces Accountability Through Structures, Authorities, and Responsibilities - Management and the board of directors establish the mechanisms to communicate and hold individuals accountable for performance of internal control responsibilities across the entity and implement corrective action as necessary. Establishes Performance Measures, Incentives, and Rewards - Management and the board of directors establish performance measures, incentives, and other rewards appropriate for responsibilities at all levels of the entity, reflecting appropriate dimensions of performance and expected standards of conduct, and considering the achievement of both short-term and longer-term objectives. Evaluates Performance Measures, Incentives, and Rewards for Ongoing Relevance - Management and the board of directors align incentives and rewards with the fulfillment of internal control responsibilities in the achievement of objectives. Considers Excessive Pressures - Management and the board of directors evaluate and adjust pressures associated with the achievement of objectives as they assign responsibilities, develop performance measures, and evaluate performance. Evaluates Performance and Rewards or Disciplines Individuals - Management and the board of directors evaluate performance of internal control responsibilities, including adherence to standards of conduct and expected levels of competence, and provide rewards or exercise disciplinary action, as appropriate.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_2_1": {"name": "CC2.1 COSO Principle 13: The entity obtains or generates and uses relevant, quality information to support the functioning of internal control","checks": {"cloudtrail_multi_region_enabled": "PASS","config_recorder_all_regions_enabled": null,"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_2_1","Section": "CC2.0 - Common Criteria Related to Communication and Information","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Identifies Information Requirements - A process is in place to identify the information required and expected to support the functioning of the other components of internal control and the achievement of the entity’s objectives. Captures Internal and External Sources of Data - Information systems capture internal and external sources of data. Processes Relevant Data Into Information - Information systems process and transform relevant data into information. Maintains Quality Throughout Processing - Information systems produce information that is timely, current, accurate, complete, accessible, protected, verifiable, and retained. Information is reviewed to assess its relevance in supporting the internal control components.","checks_status": {"fail": 0,"pass": 1,"total": 4,"manual": 0}},"cc_2_2": {"name": "CC2.2 COSO Principle 14: The entity internally communicates information, including objectives and responsibilities for internal control, necessary to support the functioning of internal control","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_2_2","Section": "CC2.0 - Common Criteria Related to Communication and Information","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Communicates Internal Control Information - A process is in place to communicate required information to enable all personnel to understand and carry out their internal control responsibilities. Communicates With the Board of Directors - Communication exists between management and the board of directors so that both have information needed to fulfill their roles with respect to the entity’s objectives. Provides Separate Communication Lines - Separate communication channels, such as whistle-blower hotlines, are in place and serve as fail-safe mechanisms to enable anonymous or confidential communication when normal channels are inoperative or ineffective. Selects Relevant Method of Communication - The method of communication considers the timing, audience, and nature of the information. Additional point of focus specifically related to all engagements using the trust services criteria: Communicates Responsibilities - Entity personnel with responsibility for designing, developing, implementing,operating, maintaining, or monitoring system controls receive communications about their responsibilities, including changes in their responsibilities, and have the information necessary to carry out those responsibilities. Communicates Information on Reporting Failures, Incidents, Concerns, and Other Matters—Entity personnel are provided with information on how to report systems failures, incidents, concerns, and other complaints to personnel. Communicates Objectives and Changes to Objectives - The entity communicates its objectives and changes to those objectives to personnel in a timely manner. Communicates Information to Improve Security Knowledge and Awareness - The entity communicates information to improve security knowledge and awareness and to model appropriate security behaviors to personnel through a security awareness training program. Additional points of focus that apply only when an engagement using the trust services criteria is performed at the system level: Communicates Information About System Operation and Boundaries - The entity prepares and communicates information about the design and operation of the system and its boundaries to authorized personnel to enable them to understand their role in the system and the results of system operation. Communicates System Objectives - The entity communicates its objectives to personnel to enable them to carry out their responsibilities. Communicates System Changes - System changes that affect responsibilities or the achievement of the entity's objectives are communicated in a timely manner.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_2_3": {"name": "CC2.3 COSO Principle 15: The entity communicates with external parties regarding matters affecting the functioning of internal control","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_2_3","Section": "CC2.0 - Common Criteria Related to Communication and Information","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Communicates to External Parties - Processes are in place to communicate relevant and timely information to external parties, including shareholders, partners, owners, regulators, customers, financial analysts, and other external parties. Enables Inbound Communications - Open communication channels allow input from customers, consumers, suppliers, external auditors, regulators, financial analysts, and others, providing management and the board of directors with relevant information. Communicates With the Board of Directors - Relevant information resulting from assessments conducted by external parties is communicated to the board of directors. Provides Separate Communication Lines - Separate communication channels, such as whistle-blower hotlines, are in place and serve as fail-safe mechanisms to enable anonymous or confidential communication when normal channels are inoperative or ineffective. Selects Relevant Method of Communication - The method of communication considers the timing, audience, and nature of the communication and legal, regulatory, and fiduciary requirements and expectations. Communicates Objectives Related to Confidentiality and Changes to Objectives - The entity communicates, to external users, vendors, business partners and others whose products and services are part of the system, objectives and changes to objectives related to confidentiality. Additional point of focus that applies only to an engagement using the trust services criteria for privacy: Communicates Objectives Related to Privacy and Changes to Objectives - The entity communicates, to external users, vendors, business partners and others whose products and services are part of the system, objectives related to privacy and changes to those objectives. Additional points of focus that apply only when an engagement using the trust services criteria is performed at the system level: Communicates Information About System Operation and Boundaries - The entity prepares and communicates information about the design and operation of the system and its boundaries to authorized external users to permit users to understand their role in the system and the results of system operation. Communicates System Objectives - The entity communicates its system objectives to appropriate external users. Communicates System Responsibilities - External users with responsibility for designing, developing, implementing, operating, maintaining, and monitoring system controls receive communications about their responsibilities and have the information necessary to carry out those responsibilities. Communicates Information on Reporting System Failures, Incidents, Concerns, and Other Matters - External users are provided with information on how to report systems failures, incidents, concerns, and other complaints to appropriate personnel.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_3_1": {"name": "CC3.1 COSO Principle 6: The entity specifies objectives with sufficient clarity to enable the identification and assessment of risks relating to objectives","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_3_1","Section": "CC3.0 - Common Criteria Related to Risk Assessment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Operations Objectives: Reflects Management's Choices - Operations objectives reflect management's choices about structure, industry considerations, and performance of the entity. Considers Tolerances for Risk - Management considers the acceptable levels of variation relative to the achievement of operations objectives. External Financial Reporting Objectives: Complies With Applicable Accounting Standards - Financial reporting objectives are consistent with accounting principles suitable and available for that entity. The accounting principles selected are appropriate in the circumstances. External Nonfinancial Reporting Objectives: Complies With Externally Established Frameworks - Management establishes objectives consistent with laws and regulations or standards and frameworks of recognized external organizations. Reflects Entity Activities - External reporting reflects the underlying transactions and events within a range of acceptable limits. Considers the Required Level of Precision—Management reflects the required level of precision and accuracy suitable for user needs and based on criteria established by third parties in nonfinancial reporting. Internal Reporting Objectives: Reflects Management's Choices - Internal reporting provides management with accurate and complete information regarding management's choices and information needed in managing the entity. Considers the Required Level of Precision—Management reflects the required level of precision and accuracy suitable for user needs in nonfinancial reporting objectives and materiality within financial reporting objectives. Reflects Entity Activities—Internal reporting reflects the underlying transactions and events within a range of acceptable limits. Compliance Objectives: Reflects External Laws and Regulations - Laws and regulations establish minimum standards of conduct, which the entity integrates into compliance objectives. Considers Tolerances for Risk - Management considers the acceptable levels of variation relative to the achievement of operations objectives. Additional point of focus specifically related to all engagements using the trust services criteria: Establishes Sub-objectives to Support Objectives—Management identifies sub-objectives related to security, availability, processing integrity, confidentiality, and privacy to support the achievement of the entity’s objectives related to reporting, operations, and compliance.","checks_status": {"fail": 0,"pass": 2,"total": 3,"manual": 0}},"cc_3_2": {"name": "CC3.2 COSO Principle 7: The entity identifies risks to the achievement of its objectives across the entity and analyzes risks as a basis for determining how the risks should be managed","checks": {"guardduty_is_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_3_2","Section": "CC3.0 - Common Criteria Related to Risk Assessment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Includes Entity, Subsidiary, Division, Operating Unit, and Functional Levels - The entity identifies and assesses risk at the entity, subsidiary, division, operating unit, and functional levels relevant to the achievement of objectives. Analyzes Internal and External Factors - Risk identification considers both internal and external factors and their impact on the achievement of objectives. Involves Appropriate Levels of Management - The entity puts into place effective risk assessment mechanisms that involve appropriate levels of management. Estimates Significance of Risks Identified - Identified risks are analyzed through a process that includes estimating the potential significance of the risk. Determines How to Respond to Risks - Risk assessment includes considering how the risk should be managed and whether to accept, avoid, reduce, or share the risk. Additional points of focus specifically related to all engagements using the trust services criteria: Identifies and Assesses Criticality of Information Assets and Identifies Threats and Vulnerabilities - The entity's risk identification and assessment process includes (1) identifying information assets, including physical devices and systems, virtual devices, software, data and data flows, external information systems, and organizational roles; (2) assessing the criticality of those information assets; (3) identifying the threats to the assets from intentional (including malicious) and unintentional acts and environmental events; and (4) identifying the vulnerabilities of the identified assets.","checks_status": {"fail": 3,"pass": 1,"total": 5,"manual": 0}},"cc_3_3": {"name": "CC3.3 COSO Principle 8: The entity considers the potential for fraud in assessing risks to the achievement of objectives","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_3_3","Section": "CC3.0 - Common Criteria Related to Risk Assessment","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Considers Various Types of Fraud - The assessment of fraud considers fraudulent reporting, possible loss of assets, and corruption resulting from the various ways that fraud and misconduct can occur. Assesses Incentives and Pressures - The assessment of fraud risks considers incentives and pressures. Assesses Opportunities - The assessment of fraud risk considers opportunities for unauthorized acquisition,use, or disposal of assets, altering the entity’s reporting records, or committing other inappropriate acts. Assesses Attitudes and Rationalizations - The assessment of fraud risk considers how management and other personnel might engage in or justify inappropriate actions. Additional point of focus specifically related to all engagements using the trust services criteria: Considers the Risks Related to the Use of IT and Access to Information - The assessment of fraud risks includes consideration of threats and vulnerabilities that arise specifically from the use of IT and access to information.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_3_4": {"name": "CC3.4 COSO Principle 9: The entity identifies and assesses changes that could significantly impact the system of internal control","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_3_4","Section": "CC3.0 - Common Criteria Related to Risk Assessment","Service": "config","SubGroup": null,"SubSection": null}],"description": "Assesses Changes in the External Environment - The risk identification process considers changes to the regulatory, economic, and physical environment in which the entity operates. Assesses Changes in the Business Model - The entity considers the potential impacts of new business lines, dramatically altered compositions of existing business lines, acquired or divested business operations on the system of internal control, rapid growth, changing reliance on foreign geographies, and new technologies. Assesses Changes in Leadership - The entity considers changes in management and respective attitudes and philosophies on the system of internal control. Assess Changes in Systems and Technology - The risk identification process considers changes arising from changes in the entity’s systems and changes in the technology environment. Assess Changes in Vendor and Business Partner Relationships - The risk identification process considers changes in vendor and business partner relationships.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"cc_4_1": {"name": "CC4.1 COSO Principle 16: The entity selects, develops, and performs ongoing and/or separate evaluations to ascertain whether the components of internal control are present and functioning","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_4_1","Section": "CC4.0 - Monitoring Activities","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Considers a Mix of Ongoing and Separate Evaluations - Management includes a balance of ongoing and separate evaluations. Considers Rate of Change - Management considers the rate of change in business and business processes when selecting and developing ongoing and separate evaluations. Establishes Baseline Understanding - The design and current state of an internal control system are used to establish a baseline for ongoing and separate evaluations. Uses Knowledgeable Personnel - Evaluators performing ongoing and separate evaluations have sufficient knowledge to understand what is being evaluated. Integrates With Business Processes - Ongoing evaluations are built into the business processes and adjust to changing conditions. Adjusts Scope and Frequency—Management varies the scope and frequency of separate evaluations depending on risk. Objectively Evaluates - Separate evaluations are performed periodically to provide objective feedback. Considers Different Types of Ongoing and Separate Evaluations - Management uses a variety of different types of ongoing and separate evaluations, including penetration testing, independent certification made against established specifications (for example, ISO certifications), and internal audit assessments.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_4_2": {"name": "CC4.2 COSO Principle 17: The entity evaluates and communicates internal control deficiencies in a timely manner to those parties responsible for taking corrective action, including senior management and the board of directors, as appropriate","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_4_2","Section": "CC4.0 - Monitoring Activities","Service": "guardduty","SubGroup": null,"SubSection": null}],"description": "Assesses Results - Management and the board of directors, as appropriate, assess results of ongoing and separate evaluations. Communicates Deficiencies - Deficiencies are communicated to parties responsible for taking corrective action and to senior management and the board of directors, as appropriate. Monitors Corrective Action - Management tracks whether deficiencies are remedied on a timely basis.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"cc_5_1": {"name": "CC5.1 COSO Principle 10: The entity selects and develops control activities that contribute to the mitigation of risks to the achievement of objectives to acceptable levels","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_5_1","Section": "CC5.0 - Control Activities","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Integrates With Risk Assessment - Control activities help ensure that risk responses that address and mitigate risks are carried out. Considers Entity-Specific Factors - Management considers how the environment, complexity, nature, and scope of its operations, as well as the specific characteristics of its organization, affect the selection and development of control activities. Determines Relevant Business Processes - Management determines which relevant business processes require control activities. Evaluates a Mix of 2017 Data Submitted Types - Control activities include a range and variety of controls and may include a balance of approaches to mitigate risks, considering both manual and automated controls, and preventive and detective controls. Considers at What Level Activities Are Applied - Management considers control activities at various levels in the entity. Addresses Segregation of Duties - Management segregates incompatible duties, and where such segregation is not practical, management selects and develops alternative control activities.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_5_2": {"name": "CC5.2 COSO Principle 11: The entity also selects and develops general control activities over technology to support the achievement of objectives","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_5_2","Section": "CC5.0 - Control Activities","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Determines Dependency Between the Use of Technology in Business Processes and Technology General Controls - Management understands and determines the dependency and linkage between business processes, automated control activities, and technology general controls. Establishes Relevant Technology Infrastructure Control Activities - Management selects and develops control activities over the technology infrastructure, which are designed and implemented to help ensure the completeness, accuracy, and availability of technology processing. Establishes Relevant Security Management Process Controls Activities - Management selects and develops control activities that are designed and implemented to restrict technology access rights to authorized users commensurate with their job responsibilities and to protect the entity’s assets from external threats. Establishes Relevant Technology Acquisition, Development, and Maintenance Process Control Activities - Management selects and develops control activities over the acquisition, development, and maintenance of technology and its infrastructure to achieve management’s objectives.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_5_3": {"name": "CCC5.3 COSO Principle 12: The entity deploys control activities through policies that establish what is expected and in procedures that put policies into action","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_5_3","Section": "CC5.0 - Control Activities","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establishes Policies and Procedures to Support Deployment of Management ā€˜s Directives - Management establishes control activities that are built into business processes and employees’ day-to-day activities through policies establishing what is expected and relevant procedures specifying actions. Establishes Responsibility and Accountability for Executing Policies and Procedures - Management establishes responsibility and accountability for control activities with management (or other designated personnel) of the business unit or function in which the relevant risks reside. Performs in a Timely Manner - Responsible personnel perform control activities in a timely manner as defined by the policies and procedures. Takes Corrective Action - Responsible personnel investigate and act on matters identified as a result of executing control activities. Performs Using Competent Personnel - Competent personnel with sufficient authority perform control activities with diligence and continuing focus. Reassesses Policies and Procedures - Management periodically reviews control activities to determine their continued relevance and refreshes them when necessary.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_6_1": {"name": "CC6.1 The entity implements logical access security software, infrastructure, and architectures over protected information assets to protect them from security events to meet the entity's objectives","checks": {"s3_bucket_public_access": null},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_6_1","Section": "CC6.0 - Logical and Physical Access","Service": "s3","SubGroup": null,"SubSection": null}],"description": "Identifies and Manages the Inventory of Information Assets - The entity identifies, inventories, classifies, and manages information assets. Restricts Logical Access - Logical access to information assets, including hardware, data (at-rest, during processing, or in transmission), software, administrative authorities, mobile devices, output, and offline system components is restricted through the use of access control software and rule sets. Identifies and Authenticates Users - Persons, infrastructure and software are identified and authenticated prior to accessing information assets, whether locally or remotely. Considers Network Segmentation - Network segmentation permits unrelated portions of the entity's information system to be isolated from each other. Manages Points of Access - Points of access by outside entities and the types of data that flow through the points of access are identified, inventoried, and managed. The types of individuals and systems using each point of access are identified, documented, and managed. Restricts Access to Information Assets - Combinations of data classification, separate data structures, port restrictions, access protocol restrictions, user identification, and digital certificates are used to establish access control rules for information assets. Manages Identification and Authentication - Identification and authentication requirements are established, documented, and managed for individuals and systems accessing entity information, infrastructure and software. Manages Credentials for Infrastructure and Software - New internal and external infrastructure and software are registered, authorized, and documented prior to being granted access credentials and implemented on the network or access point. Credentials are removed and access is disabled when access is no longer required or the infrastructure and software are no longer in use. Uses Encryption to Protect Data - The entity uses encryption to supplement other measures used to protect data-at-rest, when such protections are deemed appropriate based on assessed risk. Protects Encryption Keys - Processes are in place to protect encryption keys during generation, storage, use, and destruction.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"cc_6_2": {"name": "CC6.2 Prior to issuing system credentials and granting system access, the entity registers and authorizes new internal and external users whose access is administered by the entity","checks": {"rds_instance_no_public_access": "PASS"},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_6_2","Section": "CC6.0 - Logical and Physical Access","Service": "rds","SubGroup": null,"SubSection": null}],"description": "Prior to issuing system credentials and granting system access, the entity registers and authorizes new internal and external users whose access is administered by the entity. For those users whose access is administered by the entity, user system credentials are removed when user access is no longer authorized. Controls Access Credentials to Protected Assets - Information asset access credentials are created based on an authorization from the system's asset owner or authorized custodian. Removes Access to Protected Assets When Appropriate - Processes are in place to remove credential access when an individual no longer requires such access. Reviews Appropriateness of Access Credentials - The appropriateness of access credentials is reviewed on a periodic basis for unnecessary and inappropriate individuals with credentials.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"cc_6_3": {"name": "CC6.3 The entity authorizes, modifies, or removes access to data, software, functions, and other protected information assets based on roles, responsibilities, or the system design and changes, giving consideration to the concepts of least privilege and segregation of duties, to meet the entity’s objectives","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_6_3","Section": "CC6.0 - Logical and Physical Access","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Creates or Modifies Access to Protected Information Assets - Processes are in place to create or modify access to protected information assets based on authorization from the asset’s owner. Removes Access to Protected Information Assets - Processes are in place to remove access to protected information assets when an individual no longer requires access. Uses Role-Based Access Controls - Role-based access control is utilized to support segregation of incompatible functions.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"cc_6_4": {"name": "CC6.4 The entity restricts physical access to facilities and protected information assets to authorized personnel to meet the entity’s objectives","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_6_4","Section": "CC6.0 - Logical and Physical Access","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Creates or Modifies Physical Access - Processes are in place to create or modify physical access to facilities such as data centers, office spaces, and work areas, based on authorization from the system's asset owner. Removes Physical Access - Processes are in place to remove access to physical resources when an individual no longer requires access. Reviews Physical Access - Processes are in place to periodically review physical access to ensure consistency with job responsibilities.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_6_5": {"name": "CC6.5 The entity discontinues logical and physical protections over physical assets only after the ability to read or recover data and software from those assets has been diminished and is no longer required to meet the entity’s objectives","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_6_5","Section": "CC6.0 - Logical and Physical Access","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Identifies Data and Software for Disposal - Procedures are in place to identify data and software stored on equipment to be disposed and to render such data and software unreadable. Removes Data and Software From Entity Control - Procedures are in place to remove data and software stored on equipment to be removed from the physical control of the entity and to render such data and software unreadable.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_6_6": {"name": "CC6.6 The entity implements logical access security measures to protect against threats from sources outside its system boundaries","checks": {"ec2_instance_public_ip": "FAIL"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_6_6","Section": "CC6.0 - Logical and Physical Access","Service": "ec2","SubGroup": null,"SubSection": null}],"description": "Restricts Access — The types of activities that can occur through a communication channel (for example, FTP site, router port) are restricted. Protects Identification and Authentication Credentials — Identification and authentication credentials are protected during transmission outside its system boundaries. Requires Additional Authentication or Credentials — Additional authentication information or credentials are required when accessing the system from outside its boundaries. Implements Boundary Protection Systems — Boundary protection systems (for example, firewalls, demilitarized zones, and intrusion detection systems) are implemented to protect external access points from attempts and unauthorized access and are monitored to detect such attempts.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cc_6_7": {"name": "CC6.7 The entity restricts the transmission, movement, and removal of information to authorized internal and external users and processes, and protects it during transmission, movement, or removal to meet the entity’s objectives","checks": {"acm_certificates_expiration_check": "PASS"},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_6_7","Section": "CC6.0 - Logical and Physical Access","Service": "acm","SubGroup": null,"SubSection": null}],"description": "Restricts the Ability to Perform Transmission - Data loss prevention processes and technologies are used to restrict ability to authorize and execute transmission, movement and removal of information. Uses Encryption Technologies or Secure Communication Channels to Protect Data - Encryption technologies or secured communication channels are used to protect transmission of data and other communications beyond connectivity access points. Protects Removal Media - Encryption technologies and physical asset protections are used for removable media (such as USB drives and back-up tapes), as appropriate. Protects Mobile Devices - Processes are in place to protect mobile devices (such as laptops, smart phones and tablets) that serve as information assets.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"cc_6_8": {"name": "CC6.8 The entity implements controls to prevent or detect and act upon the introduction of unauthorized or malicious software to meet the entity’s objectives","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_6_8","Section": "CC6.0 - Logical and Physical Access","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Restricts Application and Software Installation - The ability to install applications and software is restricted to authorized individuals. Detects Unauthorized Changes to Software and Configuration Parameters - Processes are in place to detect changes to software and configuration parameters that may be indicative of unauthorized or malicious software. Uses a Defined Change Control Process - A management-defined change control process is used for the implementation of software. Uses Antivirus and Anti-Malware Software - Antivirus and anti-malware software is implemented and maintained to provide for the interception or detection and remediation of malware. Scans Information Assets from Outside the Entity for Malware and Other Unauthorized Software - Procedures are in place to scan information assets that have been transferred or returned to the entity’s custody for malware and other unauthorized software and to remove any items detected prior to its implementation on the network.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"cc_7_1": {"name": "CC7.1 To meet its objectives, the entity uses detection and monitoring procedures to identify (1) changes to configurations that result in the introduction of new vulnerabilities, and (2) susceptibilities to newly discovered vulnerabilities","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_7_1","Section": "CC7.0 - System Operations","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Uses Defined Configuration Standards - Management has defined configuration standards. Monitors Infrastructure and Software - The entity monitors infrastructure and software for noncompliance with the standards, which could threaten the achievement of the entity's objectives. Implements Change-Detection Mechanisms - The IT system includes a change-detection mechanism (for example, file integrity monitoring tools) to alert personnel to unauthorized modifications of critical system files, configuration files, or content files. Detects Unknown or Unauthorized Components - Procedures are in place to detect the introduction of unknown or unauthorized components. Conducts Vulnerability Scans - The entity conducts vulnerability scans designed to identify potential vulnerabilities or misconfigurations on a periodic basis and after any significant change in the environment and takes action to remediate identified deficiencies on a timely basis.","checks_status": {"fail": 2,"pass": 2,"total": 4,"manual": 0}},"cc_7_2": {"name": "CC7.2 The entity monitors system components and the operation of those components for anomalies that are indicative of malicious acts, natural disasters, and errors affecting the entity's ability to meet its objectives; anomalies are analyzed to determine whether they represent security events","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","ec2_instance_imdsv2_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_7_2","Section": "CC7.0 - System Operations","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implements Detection Policies, Procedures, and Tools - Detection policies and procedures are defined and implemented, and detection tools are implemented on Infrastructure and software to identify anomalies in the operation or unusual activity on systems. Procedures may include (1) a defined governance process for security event detection and management that includes provision of resources; (2) use of intelligence sources to identify newly discovered threats and vulnerabilities; and (3) logging of unusual system activities. Designs Detection Measures - Detection measures are designed to identify anomalies that could result from actual or attempted (1) compromise of physical barriers; (2) unauthorized actions of authorized personnel; (3) use of compromised identification and authentication credentials; (4) unauthorized access from outside the system boundaries; (5) compromise of authorized external parties; and (6) implementation or connection of unauthorized hardware and software. Implements Filters to Analyze Anomalies - Management has implemented procedures to filter, summarize, and analyze anomalies to identify security events. Monitors Detection Tools for Effective Operation - Management has implemented processes to monitor the effectiveness of detection tools.","checks_status": {"fail": 7,"pass": 6,"total": 21,"manual": 0}},"cc_7_3": {"name": "CC7.3 The entity evaluates security events to determine whether they could or have resulted in a failure of the entity to meet its objectives (security incidents) and, if so, takes actions to prevent or address such failures","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","apigateway_restapi_logging_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL","s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_7_3","Section": "CC7.0 - System Operations","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Responds to Security Incidents - Procedures are in place for responding to security incidents and evaluating the effectiveness of those policies and procedures on a periodic basis. Communicates and Reviews Detected Security Events - Detected security events are communicated to and reviewed by the individuals responsible for the management of the security program and actions are taken, if necessary. Develops and Implements Procedures to Analyze Security Incidents - Procedures are in place to analyze security incidents and determine system impact. Assesses the Impact on Personal Information - Detected security events are evaluated to determine whether they could or did result in the unauthorized disclosure or use of personal information and whether there has been a failure to comply with applicable laws or regulations. Determines Personal Information Used or Disclosed - When an unauthorized use or disclosure of personal information has occurred, the affected information is identified.","checks_status": {"fail": 10,"pass": 3,"total": 17,"manual": 0}},"cc_7_4": {"name": "CC7.4 The entity responds to identified security incidents by executing a defined incident response program to understand, contain, remediate, and communicate security incidents, as appropriate","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"guardduty_no_high_severity_findings": "FAIL","redshift_cluster_automated_snapshot": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_7_4","Section": "CC7.0 - System Operations","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Assigns Roles and Responsibilities - Roles and responsibilities for the design, implementation, maintenance, and execution of the incident response program are assigned, including the use of external resources when necessary. Contains Security Incidents - Procedures are in place to contain security incidents that actively threaten entity objectives. Mitigates Ongoing Security Incidents - Procedures are in place to mitigate the effects of ongoing security incidents. Ends Threats Posed by Security Incidents - Procedures are in place to end the threats posed by security incidents through closure of the vulnerability, removal of unauthorized access, and other remediation actions. Restores Operations - Procedures are in place to restore data and business operations to an interim state that permits the achievement of entity objectives. Develops and Implements Communication Protocols for Security Incidents - Protocols for communicating security incidents and actions taken to affected parties are developed and implemented to meet the entity's objectives. Obtains Understanding of Nature of Incident and Determines Containment Strategy - An understanding of the nature (for example, the method by which the incident occurred and the affected system resources) and severity of the security incident is obtained to determine the appropriate containment strategy, including (1) a determination of the appropriate response time frame, and (2) the determination and execution of the containment approach. Remediates Identified Vulnerabilities - Identified vulnerabilities are remediated through the development and execution of remediation activities. Communicates Remediation Activities - Remediation activities are documented and communicated in accordance with the incident response program. Evaluates the Effectiveness of Incident Response - The design of incident response activities is evaluated for effectiveness on a periodic basis. Periodically Evaluates Incidents - Periodically, management reviews incidents related to security, availability, processing integrity, confidentiality, and privacy and identifies the need for system changes based on incident patterns and root causes. Communicates Unauthorized Use and Disclosure - Events that resulted in unauthorized use or disclosure of personal information are communicated to the data subjects, legal and regulatory authorities, and others as required. Application of Sanctions - The conduct of individuals and organizations operating under the authority of the entity and involved in the unauthorized use or disclosure of personal information is evaluated and, if appropriate, sanctioned in accordance with entity policies and legal and regulatory requirements.","checks_status": {"fail": 3,"pass": 3,"total": 16,"manual": 0}},"cc_7_5": {"name": "CC7.5 The entity identifies, develops, and implements activities to recover from identified security incidents","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_7_5","Section": "CC7.0 - System Operations","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Restores the Affected Environment - The activities restore the affected environment to functional operation by rebuilding systems, updating software, installing patches, and changing configurations, as needed. Communicates Information About the Event - Communications about the nature of the incident, recovery actions taken, and activities required for the prevention of future security events are made to management and others as appropriate (internal and external). Determines Root Cause of the Event - The root cause of the event is determined. Implements Changes to Prevent and Detect Recurrences - Additional architecture or changes to preventive and detective controls, or both, are implemented to prevent and detect recurrences on a timely basis. Improves Response and Recovery Procedures - Lessons learned are analyzed, and the incident response plan and recovery procedures are improved. Implements Incident Recovery Plan Testing - Incident recovery plan testing is performed on a periodic basis. The testing includes (1) development of testing scenarios based on threat likelihood and magnitude; (2) consideration of relevant system components from across the entity that can impair availability; (3) scenarios that consider the potential for the lack of availability of key personnel; and (4) revision of continuity plans and systems based on test results.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_8_1": {"name": "CC8.1 The entity authorizes, designs, develops or acquires, configures, documents, tests, approves, and implements changes to infrastructure, data, software, and procedures to meet its objectives","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": "automated","ItemId": "cc_8_1","Section": "CC8.0 - Change Management","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Manages Changes Throughout the System Lifecycle - A process for managing system changes throughout the lifecycle of the system and its components (infrastructure, data, software and procedures) is used to support system availability and processing integrity. Authorizes Changes - A process is in place to authorize system changes prior to development. Designs and Develops Changes - A process is in place to design and develop system changes. Documents Changes - A process is in place to document system changes to support ongoing maintenance of the system and to support system users in performing their responsibilities. Tracks System Changes - A process is in place to track system changes prior to implementation. Configures Software - A process is in place to select and implement the configuration parameters used to control the functionality of software. Tests System Changes - A process is in place to test system changes prior to implementation. Approves System Changes - A process is in place to approve system changes prior to implementation. Deploys System Changes - A process is in place to implement system changes. Identifies and Evaluates System Changes - Objectives affected by system changes are identified, and the ability of the modified system to meet the objectives is evaluated throughout the system development life cycle. Identifies Changes in Infrastructure, Data, Software, and Procedures Required to Remediate Incidents - Changes in infrastructure, data, software, and procedures required to remediate incidents to continue to meet objectives are identified, and the change process is initiated upon identification. Creates Baseline Configuration of IT Technology - A baseline configuration of IT and control systems is created and maintained. Provides for Changes Necessary in Emergency Situations - A process is in place for authorizing, designing, testing, approving and implementing changes necessary in emergency situations (that is, changes that need to be implemented in an urgent timeframe). Protects Confidential Information - The entity protects confidential information during system design, development, testing, implementation, and change processes to meet the entity’s objectives related to confidentiality. Protects Personal Information - The entity protects personal information during system design, development, testing, implementation, and change processes to meet the entity’s objectives related to privacy.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"cc_9_1": {"name": "CC9.1 The entity identifies, selects, and develops risk mitigation activities for risks arising from potential business disruptions","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_9_1","Section": "CC9.0 - Risk Mitigation","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Considers Mitigation of Risks of Business Disruption - Risk mitigation activities include the development of planned policies, procedures, communications, and alternative processing solutions to respond to, mitigate, and recover from security events that disrupt business operations. Those policies and procedures include monitoring processes and information and communications to meet the entity's objectives during response, mitigation, and recovery efforts. Considers the Use of Insurance to Mitigate Financial Impact Risks - The risk management activities consider the use of insurance to offset the financial impact of loss events that would otherwise impair the ability of the entity to meet its objectives.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_9_2": {"name": "CC9.2 The entity assesses and manages risks associated with vendors and business partners","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_9_2","Section": "CC9.0 - Risk Mitigation","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Establishes Requirements for Vendor and Business Partner Engagements - The entity establishes specific requirements for a vendor and business partner engagement that includes (1) scope of services and product specifications, (2) roles and responsibilities, (3) compliance requirements, and (4) service levels. Assesses Vendor and Business Partner Risks - The entity assesses, on a periodic basis, the risks that vendors and business partners (and those entities’ vendors and business partners) represent to the achievement of the entity's objectives. Assigns Responsibility and Accountability for Managing Vendors and Business Partners - The entity assigns responsibility and accountability for the management of risks associated with vendors and business partners. Establishes Communication Protocols for Vendors and Business Partners - The entity establishes communication and resolution protocols for service or product issues related to vendors and business partners. Establishes Exception Handling Procedures From Vendors and Business Partners - The entity establishes exception handling procedures for service or product issues related to vendors and business partners. Assesses Vendor and Business Partner Performance - The entity periodically assesses the performance of vendors and business partners. Implements Procedures for Addressing Issues Identified During Vendor and Business Partner Assessments - The entity implements procedures for addressing issues identified with vendor and business partner relationships. Implements Procedures for Terminating Vendor and Business Partner Relationships - The entity implements procedures for terminating vendor and business partner relationships. Obtains Confidentiality Commitments from Vendors and Business Partners - The entity obtains confidentiality commitments that are consistent with the entity’s confidentiality commitments and requirements from vendors and business partners who have access to confidential information. Assesses Compliance With Confidentiality Commitments of Vendors and Business Partners - On a periodic and as-needed basis, the entity assesses compliance by vendors and business partners with the entity’s confidentiality commitments and requirements. Obtains Privacy Commitments from Vendors and Business Partners - The entity obtains privacy commitments, consistent with the entity’s privacy commitments and requirements, from vendors and business partners who have access to personal information. Assesses Compliance with Privacy Commitments of Vendors and Business Partners - On a periodic and as-needed basis, the entity assesses compliance by vendors and business partners with the entity’s privacy commitments and requirements and takes corrective action as necessary.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_a_1_1": {"name": "A1.1 The entity maintains, monitors, and evaluates current processing capacity and use of system components (infrastructure, data, and software) to manage capacity demand and to enable the implementation of additional capacity to help meet its objectives","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_a_1_1","Section": "CCA1.0 - Additional Criterial for Availability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Measures Current Usage - The use of the system components is measured to establish a baseline for capacity management and to use when evaluating the risk of impaired availability due to capacity constraints. Forecasts Capacity - The expected average and peak use of system components is forecasted and compared to system capacity and associated tolerances. Forecasting considers capacity in the event of the failure of system components that constrain capacity. Makes Changes Based on Forecasts - The system change management process is initiated when forecasted usage exceeds capacity tolerances.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_a_1_2": {"name": "A1.2 The entity authorizes, designs, develops or acquires, implements, operates, approves, maintains, and monitors environmental protections, software, data back-up processes, and recovery infrastructure to meet its objectives","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","redshift_cluster_automated_snapshot": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_a_1_2","Section": "CCA1.0 - Additional Criterial for Availability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Measures Current Usage - The use of the system components is measured to establish a baseline for capacity management and to use when evaluating the risk of impaired availability due to capacity constraints. Forecasts Capacity - The expected average and peak use of system components is forecasted and compared to system capacity and associated tolerances. Forecasting considers capacity in the event of the failure of system components that constrain capacity. Makes Changes Based on Forecasts - The system change management process is initiated when forecasted usage exceeds capacity tolerances.","checks_status": {"fail": 6,"pass": 3,"total": 16,"manual": 0}},"cc_a_1_3": {"name": "A1.3 The entity tests recovery plan procedures supporting system recovery to meet its objectives","checks": {},"status": "PASS","attributes": [{"Type": "manual","ItemId": "cc_a_1_3","Section": "CCA1.0 - Additional Criterial for Availability","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implements Business Continuity Plan Testing - Business continuity plan testing is performed on a periodic basis. The testing includes (1) development of testing scenarios based on threat likelihood and magnitude; (2) consideration of system components from across the entity that can impair the availability; (3) scenarios that consider the potential for the lack of availability of key personnel; and (4) revision of continuity plans and systems based on test results. Tests Integrity and Completeness of Back-Up Data - The integrity and completeness of back-up information is tested on a periodic basis.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"cc_c_1_1": {"name": "C1.1 The entity identifies and maintains confidential information to meet the entity’s objectives related to confidentiality","checks": {"rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_c_1_1","Section": "CCC1.0 - Additional Criterial for Confidentiality","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Identifies Confidential information - Procedures are in place to identify and designate confidential information when it is received or created and to determine the period over which the confidential information is to be retained. Protects Confidential Information from Destruction - Procedures are in place to protect confidential information from erasure or destruction during the specified retention period of the information","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cc_c_1_2": {"name": "C1.2 The entity disposes of confidential information to meet the entity’s objectives related to confidentiality","checks": {"s3_bucket_object_versioning": "FAIL"},"status": "FAIL","attributes": [{"Type": "automated","ItemId": "cc_c_1_2","Section": "CCC1.0 - Additional Criterial for Confidentiality","Service": "s3","SubGroup": null,"SubSection": null}],"description": "Identifies Confidential Information for Destruction - Procedures are in place to identify confidential information requiring destruction when the end of the retention period is reached. Destroys Confidential Information - Procedures are in place to erase or otherwise destroy confidential information that has been identified for destruction.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 10,"requirements_failed": 10,"requirements_manual": 36,"total_requirements": 56,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "8f43ba1e-a5fb-42c5-95ca-d0b199c62975","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "cis_3.0_aws","framework": "CIS","version": "3.0","description": "The CIS Amazon Web Services Foundations Benchmark provides prescriptive guidance for configuring security options for a subset of Amazon Web Services with an emphasis on foundational, testable, and architecture agnostic settings.","region": "eu-west-1","requirements": {"1.1": {"name": "1.1","checks": {"account_maintain_current_contact_details": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/manage-account-payment.html#contact-info","Description": "Ensure contact email and telephone details for AWS accounts are current and map to more than one individual in your organization.An AWS account supports a number of contact details, and AWS will use these to contact the account owner if activity judged to be in breach of Acceptable Use Policy or indicative of likely security compromise is observed by the AWS Abuse team. Contact details should not be for a single individual, as circumstances may arise where that individual is unavailable. Email contact details should point to a mail alias which forwards email to multiple individuals within the organization; where feasible, phone contact details should point to a PABX hunt group or other call-forwarding system.","DefaultValue": null,"AuditProcedure": "This activity can only be performed via the AWS Console, with a user who has permission to read and write Billing information (aws-portal:*Billing ) 1. Sign in to the AWS Management Console and open the Billing and Cost Management console at https://console.aws.amazon.com/billing/home#/. 2. On the navigation bar, choose your account name, and then choose Account. 3. On the Account Settings page, review and verify the current details. 4. Under Contact Information, review and verify the current details.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "If an AWS account is observed to be behaving in a prohibited or suspicious manner, AWS will attempt to contact the account owner by email and phone using the contact details listed. If this is unsuccessful and the account behavior needs urgent mitigation, proactive measures may be taken, including throttling of traffic between the account exhibiting suspicious behavior and the AWS API endpoints and the Internet. This will result in impaired service to and from the account in question, so it is in both the customers' and AWS' best interests that prompt contact can be established. This is best achieved by setting AWS account contact details to point to resources which have multiple individuals as recipients, such as email aliases and PABX hunt groups.","RemediationProcedure": "This activity can only be performed via the AWS Console, with a user who has permission to read and write Billing information (aws-portal:*Billing ). 1. Sign in to the AWS Management Console and open the Billing and Cost Management console at https://console.aws.amazon.com/billing/home#/. 2. On the navigation bar, choose your account name, and then choose Account. 3. On the Account Settings page, next to Account Settings, choose Edit. 4. Next to the field that you need to update, choose Edit. 5. After you have entered your changes, choose Save changes. 6. After you have made your changes, choose Done. 7. To edit your contact information, under Contact Information, choose Edit. 8. For the fields that you want to change, type your updated information, and then choose Update.","AdditionalInformation": ""}],"description": "Maintain current contact details","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.2": {"name": "1.2","checks": {"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "","Description": "AWS provides customers with the option of specifying the contact information for account's security team. It is recommended that this information be provided.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if security contact information is present:**From Console:**1. Click on your account name at the top right corner of the console 2. From the drop-down menu Click `My Account`3. Scroll down to the `Alternate Contacts` section 4. Ensure contact information is specified in the `Security` section","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Specifying security-specific contact information will help ensure that security advisories sent by AWS reach the team in your organization that is best equipped to respond to them.","RemediationProcedure": "Perform the following to establish security contact information:**From Console:**1. Click on your account name at the top right corner of the console. 2. From the drop-down menu Click `My Account`3. Scroll down to the `Alternate Contacts` section 4. Enter contact information in the `Security` section**Note:** Consider specifying an internal email distribution list to ensure emails are regularly monitored by more than one individual.","AdditionalInformation": ""}],"description": "Ensure security contact information is registered","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.3": {"name": "1.3","checks": {"account_security_questions_are_registered_in_the_aws_account": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "","Description": "The AWS support portal allows account owners to establish security questions that can be used to authenticate individuals calling AWS customer service for support. It is recommended that security questions be established.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS account as the 'root' user 2. On the top right you will see the __ 3. Click on the __ 4. From the drop-down menu Click `My Account`5. In the `Configure Security Challenge Questions` section on the `Personal Information` page, configure three security challenge questions. 6. Click `Save questions` .","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "When creating a new AWS account, a default super user is automatically created. This account is referred to as the 'root user' or 'root' account. It is recommended that the use of this account be limited and highly controlled. During events in which the 'root' password is no longer accessible or the MFA token associated with 'root' is lost/destroyed it is possible, through authentication using secret questions and associated answers, to recover 'root' user login access.","RemediationProcedure": "**From Console:**1. Login to the AWS Account as the 'root' user 2. Click on the __ from the top right of the console 3. From the drop-down menu Click _My Account_ 4. Scroll down to the `Configure Security Questions` section 5. Click on `Edit`6. Click on each `Question` - From the drop-down select an appropriate question- Click on the `Answer` section- Enter an appropriate answer - Follow process for all 3 questions 7. Click `Update` when complete 8. Save Questions and Answers and place in a secure physical location","AdditionalInformation": ""}],"description": "Ensure security questions are registered in the AWS account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.4": {"name": "1.4","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "http://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html:http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html:http://docs.aws.amazon.com/IAM/latest/APIReference/API_GetAccountSummary.html:https://aws.amazon.com/blogs/security/an-easier-way-to-determine-the-presence-of-aws-account-access-keys/","Description": "The 'root' user account is the most privileged user in an AWS account. AWS Access Keys provide programmatic access to a given AWS account. It is recommended that all access keys associated with the 'root' user account be removed.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has access keys:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on `Credential Report`5. This will download a `.csv` file which contains credential usage for all IAM users within an AWS Account - open this file 6. For the `` user, ensure the `access_key_1_active` and `access_key_2_active` fields are set to `FALSE` .**From Command Line:**Run the following command: ```aws iam get-account-summary | grep \"AccountAccessKeysPresent\"``` If no 'root' access keys exist the output will show \"AccountAccessKeysPresent\": 0,. If the output shows a \"1\" than 'root' keys exist, refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Removing access keys associated with the 'root' user account limits vectors by which the account can be compromised. Additionally, removing the 'root' access keys encourages the creation and use of role based accounts that are least privileged.","RemediationProcedure": "Perform the following to delete or disable active 'root' user access keys**From Console:**1. Sign in to the AWS Management Console as 'root' and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. Click on __ at the top right and select `My Security Credentials` from the drop down list 3. On the pop out screen Click on `Continue to Security Credentials`4. Click on `Access Keys` _(Access Key ID and Secret Access Key)_ 5. Under the `Status` column if there are any Keys which are Active- Click on `Make Inactive` - (Temporarily disable Key - may be needed again)- Click `Delete` - (Deleted keys cannot be recovered)","AdditionalInformation": "IAM User account \"root\" for us-gov cloud regions is not enabled by default. However, on request to AWS support enables 'root' access only through access-keys (CLI, API methods) for us-gov cloud region."}],"description": "Ensure no 'root' user account access key exists","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.5": {"name": "1.5","checks": {"iam_root_mfa_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#id_root-user_manage_mfa:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html#enable-virt-mfa-for-root","Description": "The 'root' user account is the most privileged user in an AWS account. Multi-factor Authentication (MFA) adds an extra layer of protection on top of a username and password. With MFA enabled, when a user signs in to an AWS website, they will be prompted for their username and password as well as for an authentication code from their AWS MFA device.**Note:** When virtual MFA is used for 'root' accounts, it is recommended that the device used is NOT a personal device, but rather a dedicated mobile device (tablet or phone) that is managed to be kept charged and secured independent of any individual personal devices. (\"non-personal virtual MFA\") This lessens the risks of losing access to the MFA due to device loss, device trade-in or if the individual owning the device is no longer employed at the company.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has MFA setup:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on `Credential Report`5. This will download a `.csv` file which contains credential usage for all IAM users within an AWS Account - open this file 6. For the `` user, ensure the `mfa_active` field is set to `TRUE` .**From Command Line:**1. Run the following command: ```aws iam get-account-summary | grep \"AccountMFAEnabled\" ``` 2. Ensure the AccountMFAEnabled property is set to 1","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling MFA provides increased security for console access as it requires the authenticating principal to possess a device that emits a time-sensitive key and have knowledge of a credential.","RemediationProcedure": "Perform the following to establish MFA for the 'root' user account:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). Note: to manage MFA devices for the 'root' AWS account, you must use your 'root' account credentials to sign in to AWS. You cannot manage MFA devices for the 'root' account using other credentials.2. Choose `Dashboard` , and under `Security Status` , expand `Activate MFA` on your root account. 3. Choose `Activate MFA`4. In the wizard, choose `A virtual MFA` device and then choose `Next Step` . 5. IAM generates and displays configuration information for the virtual MFA device, including a QR code graphic. The graphic is a representation of the 'secret configuration key' that is available for manual entry on devices that do not support QR codes. 6. Open your virtual MFA application. (For a list of apps that you can use for hosting virtual MFA devices, see [Virtual MFA Applications](http://aws.amazon.com/iam/details/mfa/#Virtual_MFA_Applications).) If the virtual MFA application supports multiple accounts (multiple virtual MFA devices), choose the option to create a new account (a new virtual MFA device). 7. Determine whether the MFA app supports QR codes, and then do one of the following: - Use the app to scan the QR code. For example, you might choose the camera icon or choose an option similar to Scan code, and then use the device's camera to scan the code.- In the Manage MFA Device wizard, choose Show secret key for manual configuration, and then type the secret configuration key into your MFA application.When you are finished, the virtual MFA device starts generating one-time passwords.In the Manage MFA Device wizard, in the Authentication Code 1 box, type the one-time password that currently appears in the virtual MFA device. Wait up to 30 seconds for the device to generate a new one-time password. Then type the second one-time password into the Authentication Code 2 box. Choose Assign Virtual MFA.","AdditionalInformation": "IAM User account \"root\" for us-gov cloud regions does not have console access. This recommendation is not applicable for us-gov cloud regions."}],"description": "Ensure MFA is enabled for the 'root' user account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.6": {"name": "1.6","checks": {"iam_root_hardware_mfa_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_physical.html#enable-hw-mfa-for-root","Description": "The 'root' user account is the most privileged user in an AWS account. MFA adds an extra layer of protection on top of a user name and password. With MFA enabled, when a user signs in to an AWS website, they will be prompted for their user name and password as well as for an authentication code from their AWS MFA device. For Level 2, it is recommended that the 'root' user account be protected with a hardware MFA.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has a hardware MFA setup:1. Run the following command to determine if the 'root' account has MFA setup: ```aws iam get-account-summary | grep \"AccountMFAEnabled\" ```The `AccountMFAEnabled` property is set to `1` will ensure that the 'root' user account has MFA (Virtual or Hardware) Enabled. If `AccountMFAEnabled` property is set to `0` the account is not compliant with this recommendation.2. If `AccountMFAEnabled` property is set to `1`, determine 'root' account has Hardware MFA enabled. Run the following command to list all virtual MFA devices: ```aws iam list-virtual-mfa-devices``` If the output contains one MFA with the following Serial Number, it means the MFA is virtual, not hardware and the account is not compliant with this recommendation: `\"SerialNumber\": \"arn:aws:iam::__:mfa/root-account-mfa-device\"`","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "A hardware MFA has a smaller attack surface than a virtual MFA. For example, a hardware MFA does not suffer the attack surface introduced by the mobile smartphone on which a virtual MFA resides.**Note**: Using hardware MFA for many, many AWS accounts may create a logistical device management issue. If this is the case, consider implementing this Level 2 recommendation selectively to the highest security AWS accounts and the Level 1 recommendation applied to the remaining accounts.","RemediationProcedure": "Perform the following to establish a hardware MFA for the 'root' user account:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). Note: to manage MFA devices for the AWS 'root' user account, you must use your 'root' account credentials to sign in to AWS. You cannot manage MFA devices for the 'root' account using other credentials. 2. Choose `Dashboard` , and under `Security Status` , expand `Activate MFA` on your root account. 3. Choose `Activate MFA`4. In the wizard, choose `A hardware MFA` device and then choose `Next Step` . 5. In the `Serial Number` box, enter the serial number that is found on the back of the MFA device. 6. In the `Authentication Code 1` box, enter the six-digit number displayed by the MFA device. You might need to press the button on the front of the device to display the number. 7. Wait 30 seconds while the device refreshes the code, and then enter the next six-digit number into the `Authentication Code 2` box. You might need to press the button on the front of the device again to display the second number. 8. Choose `Next Step` . The MFA device is now associated with the AWS account. The next time you use your AWS account credentials to sign in, you must type a code from the hardware MFA device.Remediation for this recommendation is not available through AWS CLI.","AdditionalInformation": "IAM User account 'root' for us-gov cloud regions does not have console access. This control is not applicable for us-gov cloud regions."}],"description": "Ensure hardware MFA is enabled for the 'root' user account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.7": {"name": "1.7","checks": {"iam_avoid_root_usage": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html:https://docs.aws.amazon.com/general/latest/gr/aws_tasks-that-require-root.html","Description": "With the creation of an AWS account, a 'root user' is created that cannot be disabled or deleted. That user has unrestricted access to and control over all resources in the AWS account. It is highly recommended that the use of this account be avoided for everyday tasks.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console at `https://console.aws.amazon.com/iam/` 2. In the left pane, click `Credential Report` 3. Click on `Download Report` 4. Open of Save the file locally 5. Locate the `` under the user column 6. Review `password_last_used, access_key_1_last_used_date, access_key_2_last_used_date` to determine when the 'root user' was last used.**From Command Line:**Run the following CLI commands to provide a credential report for determining the last time the 'root user' was used: ``` aws iam generate-credential-report ``` ``` aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,5,11,16 | grep -B1 '' ```Review `password_last_used`, `access_key_1_last_used_date`, `access_key_2_last_used_date` to determine when the _root user_ was last used.**Note:** There are a few conditions under which the use of the 'root' user account is required. Please see the reference links for all of the tasks that require use of the 'root' user.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "The 'root user' has unrestricted access to and control over all account resources. Use of it is inconsistent with the principles of least privilege and separation of duties, and can lead to unnecessary harm due to error or account compromise.","RemediationProcedure": "If you find that the 'root' user account is being used for daily activity to include administrative tasks that do not require the 'root' user:1. Change the 'root' user password. 2. Deactivate or delete any access keys associate with the 'root' user.**Remember, anyone who has 'root' user credentials for your AWS account has unrestricted access to and control of all the resources in your account, including billing information.","AdditionalInformation": "The 'root' user for us-gov cloud regions is not enabled by default. However, on request to AWS support, they can enable the 'root' user and grant access only through access-keys (CLI, API methods) for us-gov cloud region. If the 'root' user for us-gov cloud regions is enabled, this recommendation is applicable.Monitoring usage of the 'root' user can be accomplished by implementing recommendation 3.3 Ensure a log metric filter and alarm exist for usage of the 'root' user."}],"description": "Eliminate use of the 'root' user for administrative and daily tasks","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.8": {"name": "1.8","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy","Description": "Password policies are, in part, used to enforce password complexity requirements. IAM password policies can be used to ensure password are at least a given length. It is recommended that the password policy require a minimum password length 14.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure the password policy is configured as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Ensure \"Minimum password length\" is set to 14 or greater.**From Command Line:** ``` aws iam get-account-password-policy ``` Ensure the output of the above command includes \"MinimumPasswordLength\": 14 (or higher)","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Setting a password complexity policy increases account resiliency against brute force login attempts.","RemediationProcedure": "Perform the following to set the password policy as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Set \"Minimum password length\" to `14` or greater. 5. Click \"Apply password policy\"**From Command Line:** ```aws iam update-account-password-policy --minimum-password-length 14 ``` Note: All commands starting with \"aws iam update-account-password-policy\" can be combined into a single command.","AdditionalInformation": ""}],"description": "Ensure IAM password policy requires minimum length of 14 or greater","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.9": {"name": "1.9","checks": {"iam_password_policy_reuse_24": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy","Description": "IAM password policies can prevent the reuse of a given password by the same user. It is recommended that the password policy prevent the reuse of passwords.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure the password policy is configured as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Ensure \"Prevent password reuse\" is checked 5. Ensure \"Number of passwords to remember\" is set to 24**From Command Line:** ``` aws iam get-account-password-policy``` Ensure the output of the above command includes \"PasswordReusePrevention\": 24","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Preventing password reuse increases account resiliency against brute force login attempts.","RemediationProcedure": "Perform the following to set the password policy as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Check \"Prevent password reuse\" 5. Set \"Number of passwords to remember\" is set to `24` **From Command Line:** ```aws iam update-account-password-policy --password-reuse-prevention 24 ``` Note: All commands starting with \"aws iam update-account-password-policy\" can be combined into a single command.","AdditionalInformation": ""}],"description": "Ensure IAM password policy prevents password reuse","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.1": {"name": "3.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-management-events:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-management-and-data-events-with-cloudtrail.html?icmpid=docs_cloudtrail_console#logging-management-events:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-supported-services.html#cloud-trail-supported-services-data-events","Description": "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. CloudTrail provides a history of AWS API calls for an account, including API calls made via the Management Console, SDKs, command line tools, and higher-level AWS services (such as CloudFormation).","DefaultValue": null,"AuditProcedure": "Perform the following to determine if CloudTrail is enabled for all regions:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane- You will be presented with a list of trails across all regions 3. Ensure at least one Trail has `All` specified in the `Region` column 4. Click on a trail via the link in the _Name_ column 5. Ensure `Logging` is set to `ON`6. Ensure `Apply trail to all regions` is set to `Yes` 7. In section `Management Events` ensure `Read/Write Events` set to `ALL`**From Command Line:** ```aws cloudtrail describe-trails ``` Ensure `IsMultiRegionTrail` is set to `true```` aws cloudtrail get-trail-status --name  ``` Ensure `IsLogging` is set to `true` ``` aws cloudtrail get-event-selectors --trail-name  ``` Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`","ImpactStatement": "S3 lifecycle features can be used to manage the accumulation and management of logs over time. See the following AWS resource for more information on these features:1. https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html","AssessmentStatus": "Automated","RationaleStatement": "The AWS API call history produced by CloudTrail enables security analysis, resource change tracking, and compliance auditing. Additionally, - ensuring that a multi-regions trail exists will ensure that unexpected activity occurring in otherwise unused regions is detected- ensuring that a multi-regions trail exists will ensure that `Global Service Logging` is enabled for a trail by default to capture recording of events generated onAWS global services- for a multi-regions trail, ensuring that management events configured for all type of Read/Writes ensures recording of management operations that are performed on all resources in an AWS account","RemediationProcedure": "Perform the following to enable global (Multi-region) CloudTrail logging:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on _Trails_ on the left navigation pane 3. Click `Get Started Now` , if presented- Click `Add new trail` - Enter a trail name in the `Trail name` box- Set the `Apply trail to all regions` option to `Yes` - Specify an S3 bucket name in the `S3 bucket` box- Click `Create`4. If 1 or more trails already exist, select the target trail to enable for global logging 5. Click the edit icon (pencil) next to `Apply trail to all regions` , Click `Yes` and Click `Save`. 6. Click the edit icon (pencil) next to `Management Events` click `All` for setting `Read/Write Events` and Click `Save`.**From Command Line:** ``` aws cloudtrail create-trail --name  --bucket-name  --is-multi-region-trailaws cloudtrail update-trail --name  --is-multi-region-trail ```Note: Creating CloudTrail via CLI without providing any overriding options configures `Management Events` to set `All` type of `Read/Writes` by default.","AdditionalInformation": ""}],"description": "Ensure CloudTrail is enabled in all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3.2": {"name": "3.2","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-file-validation-enabling.html","Description": "CloudTrail log file validation creates a digitally signed digest file containing a hash of each log that CloudTrail writes to S3. These digest files can be used to determine whether a log file was changed, deleted, or unchanged after CloudTrail delivered the log. It is recommended that file validation be enabled on all CloudTrails.","DefaultValue": null,"AuditProcedure": "Perform the following on each trail to determine if log file validation is enabled:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane 3. For Every Trail: - Click on a trail via the link in the _Name_ column - Under the `General details` section, ensure `Log file validation` is set to `Enabled` **From Command Line:** ``` aws cloudtrail describe-trails ``` Ensure `LogFileValidationEnabled` is set to `true` for each trail","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling log file validation will provide additional integrity checking of CloudTrail logs.","RemediationProcedure": "Perform the following to enable log file validation on a given trail:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane 3. Click on target trail 4. Within the `General details` section click `edit` 5. Under the `Advanced settings` section 6. Check the enable box under `Log file validation`7. Click `Save changes` **From Command Line:** ``` aws cloudtrail update-trail --name  --enable-log-file-validation ``` Note that periodic validation of logs using these digests can be performed by running the following command: ``` aws cloudtrail validate-logs --trail-arn  --start-time  --end-time  ```","AdditionalInformation": ""}],"description": "Ensure CloudTrail log file validation is enabled","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.3": {"name": "3.3","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/cli/latest/reference/configservice/describe-configuration-recorder-status.html","Description": "AWS Config is a web service that performs configuration management of supported AWS resources within your account and delivers log files to you. The recorded information includes the configuration item (AWS resource), relationships between configuration items (AWS resources), any configuration changes between resources. It is recommended AWS Config be enabled in all regions.","DefaultValue": null,"AuditProcedure": "Process to evaluate AWS Config configuration per region**From Console:**1. Sign in to the AWS Management Console and open the AWS Config console at [https://console.aws.amazon.com/config/](https://console.aws.amazon.com/config/). 2. On the top right of the console select target Region. 3. If presented with Setup AWS Config - follow remediation procedure: 4. On the Resource inventory page, Click on edit (the gear icon). The Set Up AWS Config page appears. 5. Ensure 1 or both check-boxes under \"All Resources\" is checked.- Include global resources related to IAM resources - which needs to be enabled in 1 region only 6. Ensure the correct S3 bucket has been defined. 7. Ensure the correct SNS topic has been defined. 8. Repeat steps 2 to 7 for each region.**From Command Line:**1. Run this command to show all AWS Config recorders and their properties: ``` aws configservice describe-configuration-recorders ``` 2. Evaluate the output to ensure that there's at least one recorder for which `recordingGroup` object includes `\"allSupported\": true` AND `\"includeGlobalResourceTypes\": true`Note: There is one more parameter \"ResourceTypes\" in recordingGroup object. We don't need to check the same as whenever we set \"allSupported\": true, AWS enforces resource types to be empty (\"ResourceTypes\":[])Sample Output:``` {\"ConfigurationRecorders\": [{\"recordingGroup\": {\"allSupported\": true,\"resourceTypes\": [],\"includeGlobalResourceTypes\": true},\"roleARN\": \"arn:aws:iam:::role/service-role/\",\"name\": \"default\"}] } ```3. Run this command to show the status for all AWS Config recorders: ``` aws configservice describe-configuration-recorder-status ``` 4. In the output, find recorders with `name` key matching the recorders that met criteria in step 2. Ensure that at least one of them includes `\"recording\": true` and `\"lastStatus\": \"SUCCESS\"`","ImpactStatement": "It is recommended AWS Config be enabled in all regions.","AssessmentStatus": "Automated","RationaleStatement": "The AWS configuration item history captured by AWS Config enables security analysis, resource change tracking, and compliance auditing.","RemediationProcedure": "To implement AWS Config configuration:**From Console:**1. Select the region you want to focus on in the top right of the console 2. Click `Services`3. Click `Config`4. Define which resources you want to record in the selected region 5. Choose to include global resources (IAM resources) 6. Specify an S3 bucket in the same account or in another managed AWS account 7. Create an SNS Topic from the same AWS account or another managed AWS account**From Command Line:**1. Ensure there is an appropriate S3 bucket, SNS topic, and IAM role per the [AWS Config Service prerequisites](http://docs.aws.amazon.com/config/latest/developerguide/gs-cli-prereq.html). 2. Run this command to set up the configuration recorder ``` aws configservice subscribe --s3-bucket my-config-bucket --sns-topic arn:aws:sns:us-east-1:012345678912:my-config-notice --iam-role arn:aws:iam::012345678912:role/myConfigRole ``` 3. Run this command to start the configuration recorder: ``` start-configuration-recorder --configuration-recorder-name  ```","AdditionalInformation": ""}],"description": "Ensure AWS Config is enabled in all regions","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.4": {"name": "3.4","checks": {"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerLogs.html","Description": "S3 Bucket Access Logging generates a log that contains access records for each request made to your S3 bucket. An access log record contains details about the request, such as the request type, the resources specified in the request worked, and the time and date the request was processed. It is recommended that bucket access logging be enabled on the CloudTrail S3 bucket.","DefaultValue": null,"AuditProcedure": "Perform the following ensure the CloudTrail S3 bucket has access logging is enabled:**From Console:**1. Go to the Amazon CloudTrail console at [https://console.aws.amazon.com/cloudtrail/home](https://console.aws.amazon.com/cloudtrail/home) 2. In the API activity history pane on the left, click Trails 3. In the Trails pane, note the bucket names in the S3 bucket column 4. Sign in to the AWS Management Console and open the S3 console at [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3). 5. Under `All Buckets` click on a target S3 bucket 6. Click on `Properties` in the top right of the console 7. Under `Bucket:` _ `` _ click on `Logging`8. Ensure `Enabled` is checked.**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ```aws cloudtrail describe-trails --query 'trailList[*].S3BucketName'``` 2. Ensure Bucket Logging is enabled: ``` aws s3api get-bucket-logging --bucket  ``` Ensure command does not returns empty output.Sample Output for a bucket with logging enabled:``` {\"LoggingEnabled\": {\"TargetPrefix\": \"\",\"TargetBucket\": \"\"} } ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "By enabling S3 bucket logging on target S3 buckets, it is possible to capture all events which may affect objects within any target buckets. Configuring logs to be placed in a separate bucket allows access to log information which can be useful in security and incident response workflows.","RemediationProcedure": "Perform the following to enable S3 bucket logging:**From Console:**1. Sign in to the AWS Management Console and open the S3 console at [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3). 2. Under `All Buckets` click on the target S3 bucket 3. Click on `Properties` in the top right of the console 4. Under `Bucket:`  click on `Logging`5. Configure bucket logging- Click on the `Enabled` checkbox- Select Target Bucket from list- Enter a Target Prefix 6. Click `Save`.**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ``` aws cloudtrail describe-trails --region  --query trailList[*].S3BucketName ``` 2. Copy and add target bucket name at ``, Prefix for logfile at `` and optionally add an email address in the following template and save it as ``: ``` {\"LoggingEnabled\": {\"TargetBucket\": \"\",\"TargetPrefix\": \"\",\"TargetGrants\": [{\"Grantee\": {\"Type\": \"AmazonCustomerByEmail\",\"EmailAddress\": \"\"},\"Permission\": \"FULL_CONTROL\"}]}} ``` 3. Run the `put-bucket-logging` command with bucket name and `` as input, for more information refer at [put-bucket-logging](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-logging.html): ``` aws s3api put-bucket-logging --bucket  --bucket-logging-status file:// ```","AdditionalInformation": ""}],"description": "Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.5": {"name": "3.5","checks": {"cloudtrail_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/encrypting-cloudtrail-log-files-with-aws-kms.html:https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html","Description": "AWS CloudTrail is a web service that records AWS API calls for an account and makes those logs available to users and resources in accordance with IAM policies. AWS Key Management Service (KMS) is a managed service that helps create and control the encryption keys used to encrypt account data, and uses Hardware Security Modules (HSMs) to protect the security of encryption keys. CloudTrail logs can be configured to leverage server side encryption (SSE) and KMS customer created master keys (CMK) to further protect CloudTrail logs. It is recommended that CloudTrail be configured to use SSE-KMS.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if CloudTrail is configured to use SSE-KMS:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. In the left navigation pane, choose `Trails` . 3. Select a Trail 4. Under the `S3` section, ensure `Encrypt log files` is set to `Yes` and a KMS key ID is specified in the `KSM Key Id` field.**From Command Line:**1. Run the following command: ```aws cloudtrail describe-trails``` 2. For each trail listed, SSE-KMS is enabled if the trail has a `KmsKeyId` property defined.","ImpactStatement": "Customer created keys incur an additional cost. See https://aws.amazon.com/kms/pricing/ for more information.","AssessmentStatus": "Automated","RationaleStatement": "Configuring CloudTrail to use SSE-KMS provides additional confidentiality controls on log data as a given user must have S3 read permission on the corresponding log bucket and must be granted decrypt permission by the CMK policy.","RemediationProcedure": "Perform the following to configure CloudTrail to use SSE-KMS:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. In the left navigation pane, choose `Trails` . 3. Click on a Trail 4. Under the `S3` section click on the edit button (pencil icon) 5. Click `Advanced`6. Select an existing CMK from the `KMS key Id` drop-down menu- Note: Ensure the CMK is located in the same region as the S3 bucket- Note: You will need to apply a KMS Key policy on the selected CMK in order for CloudTrail as a service to encrypt and decrypt log files using the CMK provided. Steps are provided [here](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/create-kms-key-policy-for-cloudtrail.html) for editing the selected CMK Key policy 7. Click `Save`8. You will see a notification message stating that you need to have decrypt permissions on the specified KMS key to decrypt log files. 9. Click `Yes` **From Command Line:** ``` aws cloudtrail update-trail --name  --kms-id  aws kms put-key-policy --key-id  --policy  ```","AdditionalInformation": "3 statements which need to be added to the CMK policy:1\\. Enable Cloudtrail to describe CMK properties ``` 
{\"Sid\": \"Allow CloudTrail access\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\"Action\": \"kms:DescribeKey\",\"Resource\": \"*\" } ``` 2\\. Granting encrypt permissions ``` 
{\"Sid\": \"Allow CloudTrail to encrypt logs\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\"Action\": \"kms:GenerateDataKey*\",\"Resource\": \"*\",\"Condition\": {\"StringLike\": {\"kms:EncryptionContext:aws:cloudtrail:arn\": [\"arn:aws:cloudtrail:*:aws-account-id:trail/*\"]}} } ``` 3\\. Granting decrypt permissions ``` 
{\"Sid\": \"Enable CloudTrail log decrypt permissions\",\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"arn:aws:iam::aws-account-id:user/username\"},\"Action\": \"kms:Decrypt\",\"Resource\": \"*\",\"Condition\": {\"Null\": {\"kms:EncryptionContext:aws:cloudtrail:arn\": \"false\"}} } ```"}],"description": "Ensure CloudTrail logs are encrypted at rest using KMS CMKs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.6": {"name": "3.6","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://aws.amazon.com/kms/pricing/:https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final","Description": "AWS Key Management Service (KMS) allows customers to rotate the backing key which is key material stored within the KMS which is tied to the key ID of the Customer Created customer master key (CMK). It is the backing key that is used to perform cryptographic operations such as encryption and decryption. Automated key rotation currently retains all prior backing keys so that decryption of encrypted data can take place transparently. It is recommended that CMK key rotation be enabled for symmetric keys. Key rotation can not be enabled for any asymmetric CMK.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Sign in to the AWS Management Console and open the KMS console at: https://console.aws.amazon.com/kms. 2. In the left navigation pane, click Customer-managed keys. 3. Select a customer managed CMK where Key spec = SYMMETRIC_DEFAULT. 4. Select the Key rotation tab. 5. Ensure the Automatically rotate this KMS key every year checkbox is checked. 6. Repeat steps 3–5 for all customer-managed CMKs where 'Key spec = SYMMETRIC_DEFAULT'.","ImpactStatement": "Creation, management, and storage of CMKs may require additional time from and administrator.","AssessmentStatus": "Automated","RationaleStatement": "Rotating encryption keys helps reduce the potential impact of a compromised key as data encrypted with a new key cannot be accessed with a previous key that may have been exposed. Keys should be rotated every year, or upon event that would result in the compromise of that key.","RemediationProcedure": "**From Console:**1. Sign in to the AWS Management Console and open the KMS console at: https://console.aws.amazon.com/kms. 2. In the left navigation pane, click Customer-managed keys. 3. Select a key where Key spec = SYMMETRIC_DEFAULT that does not have automatic rotation enabled. 4. Select the Key rotation tab. 5. Check the Automatically rotate this KMS key every year checkbox. 6. Click Save. 7. Repeat steps 3–6 for all customer-managed CMKs that do not have automatic rotation enabled.","AdditionalInformation": ""}],"description": "Ensure rotation for customer created symmetric CMKs is enabled","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.7": {"name": "3.7","checks": {"vpc_flow_logs_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/flow-logs.html","Description": "VPC Flow Logs is a feature that enables you to capture information about the IP traffic going to and from network interfaces in your VPC. After you've created a flow log, you can view and retrieve its data in Amazon CloudWatch Logs. It is recommended that VPC Flow Logs be enabled for packet \"Rejects\" for VPCs.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if VPC Flow logs are enabled:**From Console:**1. Sign into the management console 2. Select `Services` then `VPC`3. In the left navigation pane, select `Your VPCs`4. Select a VPC 5. In the right pane, select the `Flow Logs` tab. 6. Ensure a Log Flow exists that has `Active` in the `Status` column.**From Command Line:**1. Run `describe-vpcs` command (OSX/Linux/UNIX) to list the VPC networks available in the current AWS region: ``` aws ec2 describe-vpcs --region  --query Vpcs[].VpcId ``` 2. The command output returns the `VpcId` available in the selected region. 3. Run `describe-flow-logs` command (OSX/Linux/UNIX) using the VPC ID to determine if the selected virtual network has the Flow Logs feature enabled: ``` aws ec2 describe-flow-logs --filter \"Name=resource-id,Values=\" ``` 4. If there are no Flow Logs created for the selected VPC, the command output will return an `empty list []`. 5. Repeat step 3 for other VPCs available in the same region. 6. Change the region by updating `--region` and repeat steps 1 - 5 for all the VPCs.","ImpactStatement": "By default, CloudWatch Logs will store Logs indefinitely unless a specific retention period is defined for the log group. When choosing the number of days to retain, keep in mind the average days it takes an organization to realize they have been breached is 210 days (at the time of this writing). Since additional time is required to research a breach, a minimum 365 day retention policy allows time for detection and research. You may also wish to archive the logs to a cheaper storage service rather than simply deleting them. See the following AWS resource to manage CloudWatch Logs retention periods:1. https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/SettingLogRetention.html","AssessmentStatus": "Automated","RationaleStatement": "VPC Flow Logs provide visibility into network traffic that traverses the VPC and can be used to detect anomalous traffic or insight during security workflows.","RemediationProcedure": "Perform the following to determine if VPC Flow logs is enabled:**From Console:**1. Sign into the management console 2. Select `Services` then `VPC`3. In the left navigation pane, select `Your VPCs`4. Select a VPC 5. In the right pane, select the `Flow Logs` tab. 6. If no Flow Log exists, click `Create Flow Log`7. For Filter, select `Reject` 8. Enter in a `Role` and `Destination Log Group`9. Click `Create Log Flow`10. Click on `CloudWatch Logs Group` **Note:** Setting the filter to \"Reject\" will dramatically reduce the logging data accumulation for this recommendation and provide sufficient information for the purposes of breach detection, research and remediation. However, during periods of least privilege security group engineering, setting this the filter to \"All\" can be very helpful in discovering existing traffic flows required for proper operation of an already running environment.**From Command Line:**1. Create a policy document and name it as `role_policy_document.json` and paste the following content: ``` {\"Version\": \"2012-10-17\",\"Statement\": [{\"Sid\": \"test\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"ec2.amazonaws.com\"},\"Action\": \"sts:AssumeRole\"}] } ``` 2. Create another policy document and name it as `iam_policy.json` and paste the following content: ``` {\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Action\":[\"logs:CreateLogGroup\",\"logs:CreateLogStream\",\"logs:DescribeLogGroups\",\"logs:DescribeLogStreams\",\"logs:PutLogEvents\",\"logs:GetLogEvents\",\"logs:FilterLogEvents\"],\"Resource\": \"*\"}] } ``` 3. Run the below command to create an IAM role: ``` aws iam create-role --role-name  --assume-role-policy-document file://role_policy_document.json``` 4. Run the below command to create an IAM policy: ``` aws iam create-policy --policy-name  --policy-document file://iam-policy.json ``` 5. Run `attach-group-policy` command using the IAM policy ARN returned at the previous step to attach the policy to the IAM role (if the command succeeds, no output is returned): ``` aws iam attach-group-policy --policy-arn arn:aws:iam:::policy/ --group-name  ``` 6. Run `describe-vpcs` to get the VpcId available in the selected region: ``` aws ec2 describe-vpcs --region  ``` 7. The command output should return the VPC Id available in the selected region. 8. Run `create-flow-logs` to create a flow log for the vpc: ``` aws ec2 create-flow-logs --resource-type VPC --resource-ids  --traffic-type REJECT --log-group-name  --deliver-logs-permission-arn  ``` 9. Repeat step 8 for other vpcs available in the selected region. 10. Change the region by updating --region and repeat remediation procedure for other vpcs.","AdditionalInformation": ""}],"description": "Ensure VPC flow logging is enabled in all VPCs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.8": {"name": "3.8","checks": {"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-cloudtrail-events.html","Description": "S3 object-level API operations such as GetObject, DeleteObject, and PutObject are called data events. By default, CloudTrail trails don't log data events and so it is recommended to enable Object-level logging for S3 buckets.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to CloudTrail dashboard at https://console.aws.amazon.com/cloudtrail/ 2. In the left panel, click Trails and then click on the CloudTrail Name that you want to examine. 3. Review General details 4. Confirm that Multi-region trail is set to Yes 5. Scroll down to Data events 6. Confirm that it reads: Data Events:S3 Log selector template Log all events If 'basic events selectors' is being used it should read: Data events: S3 Bucket Name: All current and future S3 buckets Write: Enabled 7. Repeat steps 2 to 6 to verify that Multi-region trail and Data events logging of S3 buckets in CloudTrail. If the CloudTrails do not have multi-region and data events configured for S3 refer to the remediation below..","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling object-level logging will help you meet data compliance requirements within your organization, perform comprehensive security analysis, monitor specific patterns of user behavior in your AWS account or take immediate actions on any object-level API activity within your S3 Buckets using Amazon CloudWatch Events.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at https://console.aws.amazon.com/s3/ 2. In the left navigation panel, click buckets and then click on the S3 Bucket Name that you want to examine. 3. Click Properties tab to see in detail bucket configuration. 4. In the AWS Cloud Trail data events' section select the CloudTrail name for the recording activity. You can choose an existing Cloudtrail or create a new one by slicking the Configure in Cloudtrailbutton or navigating to the Cloudtrail console linkhttps://console.aws.amazon.com/cloudtrail/` 5. Once the Cloudtrail is selected, Select the data Data Events check box. 6. Select S3 from the `Data event type drop down. 7. Select Log all events from the Log selector template drop down. 8. Repeat steps 2 to 5 to enable object-level logging of write events for other S3 buckets.","AdditionalInformation": ""}],"description": "Ensure that Object-level logging for write events is enabled for S3 bucket","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.9": {"name": "3.9","checks": {"cloudtrail_s3_dataevents_read_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-cloudtrail-events.html","Description": "S3 object-level API operations such as GetObject, DeleteObject, and PutObject are called data events. By default, CloudTrail trails don't log data events and so it is recommended to enable Object-level logging for S3 buckets.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. If the current status for `Object-level` logging is set to `Disabled`, then object-level logging of read events for the selected s3 bucket is not set. 5. If the current status for `Object-level` logging is set to `Enabled`, but the Read event check-box is unchecked, then object-level logging of read events for the selected s3 bucket is not set. 6. Repeat steps 2 to 5 to verify `object-level` logging for `read` events of your other S3 buckets.**From Command Line:** 1. Run `describe-trails` command to list the names of all Amazon CloudTrail trails currently available in the selected AWS region: ``` aws cloudtrail describe-trails --region  --output table --query trailList[*].Name ``` 2. The command output will be table of the requested trail names. 3. Run `get-event-selectors` command using the name of the trail returned at the previous step and custom query filters to determine if Data events logging feature is enabled within the selected CloudTrail trail configuration for s3 bucket resources: ``` aws cloudtrail get-event-selectors --region  --trail-name  --query EventSelectors[*].DataResources[] ``` 4. The command output should be an array that contains the configuration of the AWS resource(S3 bucket) defined for the Data events selector. 5. If the `get-event-selectors` command returns an empty array, the Data events are not included into the selected AWS Cloudtrail trail logging configuration, therefore the S3 object-level API operations performed within your AWS account are not recorded. 6. Repeat steps 1 to 5 for auditing each s3 bucket to identify other trails that are missing the capability to log Data events. 7. Change the AWS region by updating the `--region` command parameter and perform the audit process for other regions.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling object-level logging will help you meet data compliance requirements within your organization, perform comprehensive security analysis, monitor specific patterns of user behavior in your AWS account or take immediate actions on any object-level API activity using Amazon CloudWatch Events.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. Click on the `Object-level` logging setting, enter the CloudTrail name for the recording activity. You can choose an existing Cloudtrail or create a new one by navigating to the Cloudtrail console link `https://console.aws.amazon.com/cloudtrail/` 5. Once the Cloudtrail is selected, check the Read event checkbox, so that `object-level` logging for `Read` events is enabled. 6. Repeat steps 2 to 5 to enable `object-level` logging of read events for other S3 buckets.**From Command Line:** 1. To enable `object-level` data events logging for S3 buckets within your AWS account, run `put-event-selectors` command using the name of the trail that you want to reconfigure as identifier: ``` aws cloudtrail put-event-selectors --region  --trail-name  --event-selectors '[{ \"ReadWriteType\": \"ReadOnly\", \"IncludeManagementEvents\":true, \"DataResources\": [{ \"Type\": \"AWS::S3::Object\", \"Values\": [\"arn:aws:s3:::/\"] }] }]' ``` 2. The command output will be `object-level` event trail configuration. 3. If you want to enable it for all buckets at ones then change Values parameter to `[\"arn:aws:s3\"]` in command given above. 4. Repeat step 1 for each s3 bucket to update `object-level` logging of read events. 5. Change the AWS region by updating the `--region` command parameter and perform the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that Object-level logging for read events is enabled for S3 bucket","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.1": {"name": "4.1","checks": {"cloudwatch_log_metric_filter_unauthorized_api_calls": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://aws.amazon.com/sns/:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for unauthorized API calls.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with \"Name\":` note ``- From value associated with \"CloudWatchLogsLogGroupArn\" note Example: for CloudWatchLogsLogGroupArn that looks like arn:aws:logs:::log-group:NewGroup:*,  would be NewGroup- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name <\"Name\" as shown in describe-trails>`Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this `` that you captured in step 1:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.errorCode = *UnauthorizedOperation) || ($.errorCode = AccessDenied*) || ($.sourceIPAddress!=delivery.logs.amazonaws.com) || ($.eventName!=HeadBucket) }\", ```4. Note the \"filterName\" `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query \"MetricAlarms[?MetricName == `unauthorized_api_calls_metric`]\" ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "This alert may be triggered by normal read-only console activities that attempt to opportunistically gather optional information, but gracefully fail if they don't have permissions.If an excessive number of alerts are being generated then an organization may wish to consider adding read access to the limited IAM user permissions simply to quiet the alerts.In some cases doing this may allow the users to actually view some areas of the system - any additional access given should be reviewed for alignment with the original limited IAM user intent.","AssessmentStatus": "Automated","RationaleStatement": "Monitoring unauthorized API calls will help reveal application errors and may reduce time to detect malicious activity.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for unauthorized API calls and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name \"cloudtrail_log_group_name\" --filter-name \"\" --metric-transformations metricName=unauthorized_api_calls_metric,metricNamespace=CISBenchmark,metricValue=1 --filter-pattern \"{ ($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\") || ($.sourceIPAddress!=\"delivery.logs.amazonaws.com\") || ($.eventName!=\"HeadBucket\") }\" ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms. **Note**: Capture the TopicArn displayed when creating the SNS Topic in Step 2.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name \"unauthorized_api_calls_alarm\" --metric-name \"unauthorized_api_calls_metric\" --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace \"CISBenchmark\" --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for unauthorized API calls","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.2": {"name": "4.2","checks": {"cloudwatch_log_metric_filter_sign_in_without_mfa": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/viewing_metrics_with_cloudwatch.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for console logins that are not protected by multi-factor authentication (MFA).","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all `CloudTrails`:``` aws cloudtrail describe-trails ```- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region `CloudTrail` is active``` aws cloudtrail get-trail-status --name  ```Ensure in the output that `IsLogging` is set to `TRUE`- Ensure identified Multi-region 'Cloudtrail' captures all Management Events``` aws cloudtrail get-event-selectors --trail-name  ```Ensure in the output there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }\" ```Or (To reduce false positives incase Single Sign-On (SSO) is used in organization):``` \"filterPattern\": \"{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\") }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring for single-factor console logins will increase visibility into accounts that are not protected by MFA.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Management Console sign-in without MFA and the `` taken from audit step 1.Use Command: ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }' ```Or (To reduce false positives incase Single Sign-On (SSO) is used in organization):``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\") }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored -Filter pattern set to `{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\"}` reduces false alarms raised when user logs in via SSO account."}],"description": "Ensure a log metric filter and alarm exist for Management Console sign-in without MFA","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.3": {"name": "4.3","checks": {"cloudwatch_log_metric_filter_root_usage": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for 'root' login attempts.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails:`aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring for 'root' account logins will provide visibility into the use of a fully privileged account and an opportunity to reduce the use of it.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for 'Root' account usage and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name `` --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "**Configuring log metric filter and alarm on Multi-region (global) CloudTrail**- ensures that activities from all regions (used as well as unused) are monitored- ensures that activities on all supported global services are monitored- ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for usage of 'root' account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.4": {"name": "4.4","checks": {"cloudwatch_log_metric_filter_policy_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established changes made to Identity and Access Management (IAM) policies.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails:`aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to IAM policies will help ensure authentication and authorization controls remain intact.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for IAM policy changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name `` --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for IAM policy changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.5": {"name": "4.5","checks": {"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for detecting changes to CloudTrail's configurations.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to CloudTrail's configuration will help ensure sustained visibility to activities performed in the AWS account.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for cloudtrail configuration changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for CloudTrail configuration changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.6": {"name": "4.6","checks": {"cloudwatch_log_metric_filter_authentication_failures": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for failed console authentication attempts.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring failed console logins may decrease lead time to detect an attempt to brute force a credential, which may provide an indicator, such as source IP, that can be used in other event correlation.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS management Console Login Failures and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }' ``` **Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for AWS Management Console authentication failures","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.7": {"name": "4.7","checks": {"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for customer created CMKs which have changed state to disabled or scheduled deletion.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Data encrypted with disabled or deleted keys will no longer be accessible.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for disabled or scheduled for deletion CMK's and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }' ``` **Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.8": {"name": "4.8","checks": {"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for changes to S3 bucket policies.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to S3 bucket policies may reduce time to detect and correct permissive policies on sensitive S3 buckets.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for S3 bucket policy changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for S3 bucket policy changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.9": {"name": "4.9","checks": {"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for detecting changes to CloudTrail's configurations.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to AWS Config configuration will help ensure sustained visibility of configuration items within the AWS account.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Configuration changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for AWS Config configuration changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"5.1": {"name": "5.1","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html:https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Security.html#VPC_Security_Comparison","Description": "The Network Access Control List (NACL) function provide stateless filtering of ingress and egress network traffic to AWS resources. It is recommended that no NACL allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "**From Console:**Perform the following to determine if the account is configured as prescribed: 1. Login to the AWS Management Console at https://console.aws.amazon.com/vpc/home 2. In the left pane, click `Network ACLs` 3. For each network ACL, perform the following:- Select the network ACL- Click the `Inbound Rules` tab- Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `0.0.0.0/0` and shows `ALLOW`**Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "**From Console:**Perform the following: 1. Login to the AWS Management Console at https://console.aws.amazon.com/vpc/home 2. In the left pane, click `Network ACLs` 3. For each network ACL to remediate, perform the following:- Select the network ACL- Click the `Inbound Rules` tab- Click `Edit inbound rules`- Either A) update the Source field to a range other than 0.0.0.0/0, or, B) Click `Delete` to remove the offending inbound rule- Click `Save`","AdditionalInformation": ""}],"description": "Ensure no Network ACLs allow ingress from 0.0.0.0/0 to remote server administration ports","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"5.2": {"name": "5.2","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#deleting-security-group-rule","Description": "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `0.0.0.0/0` **Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports.","ImpactStatement": "When updating an existing environment, ensure that administrators have access to remote server administration ports through another mechanism before removing access by deleting the 0.0.0.0/0 inbound rule.","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "Perform the following to implement the prescribed state:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Click the `Edit inbound rules` button 4. Identify the rules to be edited or removed 5. Either A) update the Source field to a range other than 0.0.0.0/0, or, B) Click `Delete` to remove the offending inbound rule 6. Click `Save rules`","AdditionalInformation": ""}],"description": "Ensure no security groups allow ingress from 0.0.0.0/0 to remote server administration ports","checks_status": {"fail": 0,"pass": 3,"total": 3,"manual": 0}},"5.3": {"name": "5.3","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#deleting-security-group-rule","Description": "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `::/0` **Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports.","ImpactStatement": "When updating an existing environment, ensure that administrators have access to remote server administration ports through another mechanism before removing access by deleting the ::/0 inbound rule.","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "Perform the following to implement the prescribed state:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Click the `Edit inbound rules` button 4. Identify the rules to be edited or removed 5. Either A) update the Source field to a range other than ::/0, or, B) Click `Delete` to remove the offending inbound rule 6. Click `Save rules`","AdditionalInformation": ""}],"description": "Ensure no security groups allow ingress from ::/0 to remote server administration ports","checks_status": {"fail": 0,"pass": 3,"total": 3,"manual": 0}},"5.4": {"name": "5.4","checks": {"ec2_securitygroup_default_restrict_traffic": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#default-security-group","Description": "A VPC comes with a default security group whose initial settings deny all inbound traffic, allow all outbound traffic, and allow all traffic between instances assigned to the security group. If you don't specify a security group when you launch an instance, the instance is automatically assigned to this default security group. Security groups provide stateful filtering of ingress/egress network traffic to AWS resources. It is recommended that the default security group restrict all traffic.The default VPC in every region should have its default security group updated to comply. Any newly created VPCs will automatically contain a default security group that will need remediation to comply with this recommendation.**NOTE:** When implementing this recommendation, VPC flow logging is invaluable in determining the least privilege port access required by systems to work properly because it can log all packet acceptances and rejections occurring under the current security groups. This dramatically reduces the primary barrier to least privilege engineering - discovering the minimum ports required by systems in the environment. Even if the VPC flow logging recommendation in this benchmark is not adopted as a permanent security measure, it should be used during any period of discovery and engineering for least privileged security groups.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:Security Group State1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. For each default security group, perform the following: 1. Select the `default` security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exist 4. Click the `Outbound Rules` tab 5. Ensure no rules existSecurity Group Members1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all default groups in all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. Copy the id of the default security group. 5. Change to the EC2 Management Console at https://console.aws.amazon.com/ec2/v2/home 6. In the filter column type 'Security Group ID : < security group id from #4 >'","ImpactStatement": "Implementing this recommendation in an existing VPC containing operating resources requires extremely careful migration planning as the default security groups are likely to be enabling many ports that are unknown. Enabling VPC flow logging (of accepts) in an existing environment that is known to be breach free will reveal the current pattern of ports being used for each instance to communicate successfully.","AssessmentStatus": "Automated","RationaleStatement": "Configuring all VPC default security groups to restrict all traffic will encourage least privilege security group development and mindful placement of AWS resources into security groups which will in-turn reduce the exposure of those resources.","RemediationProcedure": "Security Group MembersPerform the following to implement the prescribed state:1. Identify AWS resources that exist within the default security group 2. Create a set of least privilege security groups for those resources 3. Place the resources in those security groups 4. Remove the resources noted in #1 from the default security groupSecurity Group State1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. For each default security group, perform the following: 1. Select the `default` security group 2. Click the `Inbound Rules` tab 3. Remove any inbound rules 4. Click the `Outbound Rules` tab 5. Remove any Outbound rulesRecommended:IAM groups allow you to edit the \"name\" field. After remediating default groups rules for all VPCs in all regions, edit this field to add text similar to \"DO NOT USE. DO NOT ADD RULES\"","AdditionalInformation": ""}],"description": "Ensure the default security group of every VPC restricts all traffic","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"5.5": {"name": "5.5","checks": {"vpc_peering_routing_tables_with_least_privilege": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "5. Networking","References": "https://docs.aws.amazon.com/AmazonVPC/latest/PeeringGuide/peering-configurations-partial-access.html:https://docs.aws.amazon.com/cli/latest/reference/ec2/create-vpc-peering-connection.html","Description": "Once a VPC peering connection is established, routing tables must be updated to establish any connections between the peered VPCs. These routes can be as specific as desired - even peering a VPC to only a single host on the other side of the connection.","DefaultValue": null,"AuditProcedure": "Review routing tables of peered VPCs for whether they route all subnets of each VPC and whether that is necessary to accomplish the intended purposes for peering the VPCs.**From Command Line:**1. List all the route tables from a VPC and check if \"GatewayId\" is pointing to a __ (e.g. pcx-1a2b3c4d) and if \"DestinationCidrBlock\" is as specific as desired. ``` aws ec2 describe-route-tables --filter \"Name=vpc-id,Values=\" --query \"RouteTables[*].{RouteTableId:RouteTableId, VpcId:VpcId, Routes:Routes, AssociatedSubnets:Associations[*].SubnetId}\" ```","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Being highly selective in peering routing tables is a very effective way of minimizing the impact of breach as resources outside of these routes are inaccessible to the peered VPC.","RemediationProcedure": "Remove and add route table entries to ensure that the least number of subnets or hosts as is required to accomplish the purpose for peering are routable.**From Command Line:**1. For each __ containing routes non compliant with your routing policy (which grants more than desired \"least access\"), delete the non compliant route: ``` aws ec2 delete-route --route-table-id  --destination-cidr-block  ```2. Create a new compliant route: ``` aws ec2 create-route --route-table-id  --destination-cidr-block  --vpc-peering-connection-id  ```","AdditionalInformation": "If an organization has AWS transit gateway implemented in their VPC architecture they should look to apply the recommendation above for \"least access\" routing architecture at the AWS transit gateway level in combination with what must be implemented at the standard VPC route table. More specifically, to route traffic between two or more VPCs via a transit gateway VPCs must have an attachment to a transit gateway route table as well as a route, therefore to avoid routing traffic between VPCs an attachment to the transit gateway route table should only be added where there is an intention to route traffic between the VPCs. As transit gateways are able to host multiple route tables it is possible to group VPCs by attaching them to a common route table."}],"description": "Ensure routing tables for VPC peering are \"least access\"","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"5.6": {"name": "5.6","checks": {"ec2_instance_imdsv2_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service/:https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html","Description": "When enabling the Metadata Service on AWS EC2 instances, users have the option of using either Instance Metadata Service Version 1 (IMDSv1; a request/response method) or Instance Metadata Service Version 2 (IMDSv2; a session-oriented method).","DefaultValue": null,"AuditProcedure": "From Console: 1. Sign in to the AWS Management Console and navigate to the EC2 dashboard at https://console.aws.amazon.com/ec2/. 2. In the left navigation panel, under the INSTANCES section, choose Instances. 3. Select the EC2 instance that you want to examine. 4. Check for the IMDSv2 status, and ensure that it is set to Required. From Command Line: 1. Run the describe-instances command using appropriate filtering to list the IDs of all the existing EC2 instances currently available in the selected region: aws ec2 describe-instances --region  --output table --query 'Reservations[*].Instances[*].InstanceId' 2. The command output should return a table with the requested instance IDs. 3. Now run the describe-instances command using an instance ID returned at the previous step and custom filtering to determine whether the selected instance has IMDSv2: aws ec2 describe-instances --region  --instance-ids  --query 'Reservations[*].Instances[*].MetadataOptions' --output table 4. Ensure for all ec2 instances HttpTokens is set to required and State is set to applied. 5. Repeat steps no. 3 and 4 to verify other EC2 instances provisioned within the current region. 6. Repeat steps no. 1 – 5 to perform the audit process for other AWS regions.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Instance metadata is data about your instance that you can use to configure or manage the running instance. Instance metadata is divided into categories, for example, host name, events, and security groups. When enabling the Metadata Service on AWS EC2 instances, users have the option of using either Instance Metadata Service Version 1 (IMDSv1; a request/response method) or Instance Metadata Service Version 2 (IMDSv2; a session-oriented method). With IMDSv2, every request is now protected by session authentication. A session begins and ends a series of requests that software running on an EC2 instance uses to access the locally-stored EC2 instance metadata and credentials. Allowing Version 1 of the service may open EC2 instances to Server-Side Request Forgery (SSRF) attacks, so Amazon recommends utilizing Version 2 for better instance security.","RemediationProcedure": "From Console: 1. Sign in to the AWS Management Console and navigate to the EC2 dashboard at https://console.aws.amazon.com/ec2/. 2. In the left navigation panel, under the INSTANCES section, choose Instances. 3. Select the EC2 instance that you want to examine. 4. Choose Actions > Instance Settings > Modify instance metadata options. 5. Ensure Instance metadata service is set to Enable and set IMDSv2 to Required. 6. Repeat steps no. 1 – 5 to perform the remediation process for other EC2 Instances in the all applicable AWS region(s). From Command Line: 1. Run the describe-instances command using appropriate filtering to list the IDs of all the existing EC2 instances currently available in the selected region: aws ec2 describe-instances --region  --output table -- query 'Reservations[*].Instances[*].InstanceId' 2. The command output should return a table with the requested instance IDs. 3. Now run the modify-instance-metadata-options command using an instance ID returned at the previous step to update the Instance Metadata Version: aws ec2 modify-instance-metadata-options --instance-id  --http-tokens required --region  4. Repeat steps no. 1 – 3 to perform the remediation process for other EC2 Instances in the same AWS region. 5. Change the region by updating --region and repeat the entire process for other regions.","AdditionalInformation": ""}],"description": "Ensure that EC2 Metadata Service only allows IMDSv2","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.10": {"name": "1.10","checks": {"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://tools.ietf.org/html/rfc6238:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#enable-mfa-for-privileged-users:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html:https://blogs.aws.amazon.com/security/post/Tx2SJJYE082KBUK/How-to-Delegate-Management-of-Multi-Factor-Authentication-to-AWS-IAM-Users","Description": "Multi-Factor Authentication (MFA) adds an extra layer of authentication assurance beyond traditional credentials. With MFA enabled, when a user signs in to the AWS Console, they will be prompted for their user name and password as well as for an authentication code from their physical or virtual MFA token. It is recommended that MFA be enabled for all accounts that have a console password.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if a MFA device is enabled for all IAM users having a console password:**From Console:**1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the left pane, select `Users`3. If the `MFA` or `Password age` columns are not visible in the table, click the gear icon at the upper right corner of the table and ensure a checkmark is next to both, then click `Close`. 4. Ensure that for each user where the `Password age` column shows a password age, the `MFA` column shows `Virtual`, `U2F Security Key`, or `Hardware`.**From Command Line:**1. Run the following command (OSX/Linux/UNIX) to generate a list of all IAM users along with their password and MFA status: ```aws iam generate-credential-report ``` ```aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,8``` 2. The output of this command will produce a table similar to the following: ```user,password_enabled,mfa_activeelise,false,falsebrandon,true,truerakesh,false,falsehelene,false,falseparas,true,trueanitha,false,false``` 3. For any column having `password_enabled` set to `true` , ensure `mfa_active` is also set to `true.`","ImpactStatement": "AWS will soon end support for SMS multi-factor authentication (MFA). New customers are not allowed to use this feature. We recommend that existing customers switch to one of the following alternative methods of MFA.","AssessmentStatus": "Automated","RationaleStatement": "Enabling MFA provides increased security for console access as it requires the authenticating principal to possess a device that displays a time-sensitive key and have knowledge of a credential.","RemediationProcedure": "Perform the following to enable MFA:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at 'https://console.aws.amazon.com/iam/' 2. In the left pane, select `Users`. 3. In the `User Name` list, choose the name of the intended MFA user. 4. Choose the `Security Credentials` tab, and then choose `Manage MFA Device`. 5. In the `Manage MFA Device wizard`, choose `Virtual MFA` device, and then choose `Continue`. IAM generates and displays configuration information for the virtual MFA device, including a QR code graphic. The graphic is a representation of the 'secret configuration key' that is available for manual entry on devices that do not support QR codes.6. Open your virtual MFA application. (For a list of apps that you can use for hosting virtual MFA devices, see Virtual MFA Applications at https://aws.amazon.com/iam/details/mfa/#Virtual_MFA_Applications). If the virtual MFA application supports multiple accounts (multiple virtual MFA devices), choose the option to create a new account (a new virtual MFA device). 7. Determine whether the MFA app supports QR codes, and then do one of the following: - Use the app to scan the QR code. For example, you might choose the camera icon or choose an option similar to Scan code, and then use the device's camera to scan the code.- In the Manage MFA Device wizard, choose Show secret key for manual configuration, and then type the secret configuration key into your MFA application. When you are finished, the virtual MFA device starts generating one-time passwords.8. In the `Manage MFA Device wizard`, in the `MFA Code 1 box`, type the `one-time password` that currently appears in the virtual MFA device. Wait up to 30 seconds for the device to generate a new one-time password. Then type the second `one-time password` into the `MFA Code 2 box`.9. Click `Assign MFA`.","AdditionalInformation": "**Forced IAM User Self-Service Remediation**Amazon has published a pattern that forces users to self-service setup MFA before they have access to their complete permissions set. Until they complete this step, they cannot access their full permissions. This pattern can be used on new AWS accounts. It can also be used on existing accounts - it is recommended users are given instructions and a grace period to accomplish MFA enrollment before active enforcement on existing AWS accounts."}],"description": "Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.11": {"name": "1.11","checks": {"iam_user_no_setup_initial_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/cli/latest/reference/iam/delete-access-key.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html","Description": "AWS console defaults to no check boxes selected when creating a new IAM user. When cerating the IAM User credentials you have to determine what type of access they require. Programmatic access: The IAM user might need to make API calls, use the AWS CLI, or use the Tools for Windows PowerShell. In that case, create an access key (access key ID and a secret access key) for that user. AWS Management Console access: If the user needs to access the AWS Management Console, create a password for the user.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if access keys were created upon user creation and are being used and rotated as prescribed:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on a User where column `Password age` and `Access key age` is not set to `None` 5. Click on `Security credentials` Tab 6. Compare the user 'Creation time` to the Access Key `Created` date. 6. For any that match, the key was created during initial user setup.- Keys that were created at the same time as the user profile and do not have a last used date should be deleted. Refer to the remediation below.**From Command Line:**1. Run the following command (OSX/Linux/UNIX) to generate a list of all IAM users along with their access keys utilization: ```aws iam generate-credential-report ``` ```aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,9,11,14,16 ``` 2. The output of this command will produce a table similar to the following: ``` user,password_enabled,access_key_1_active,access_key_1_last_used_date,access_key_2_active,access_key_2_last_used_dateelise,false,true,2015-04-16T15:14:00+00:00,false,N/Abrandon,true,true,N/A,false,N/Arakesh,false,false,N/A,false,N/Ahelene,false,true,2015-11-18T17:47:00+00:00,false,N/Aparas,true,true,2016-08-28T12:04:00+00:00,true,2016-03-04T10:11:00+00:00anitha,true,true,2016-06-08T11:43:00+00:00,true,N/A``` 3. For any user having `password_enabled` set to `true` AND `access_key_last_used_date` set to `N/A` refer to the remediation below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Requiring the additional steps be taken by the user for programmatic access after their profile has been created will give a stronger indication of intent that access keys are [a] necessary for their work and [b] once the access key is established on an account that the keys may be in use somewhere in the organization.**Note**: Even if it is known the user will need access keys, require them to create the keys themselves or put in a support ticket to have them created as a separate step from user creation.","RemediationProcedure": "Perform the following to delete access keys that do not pass the audit:**From Console:**1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. As an Administrator - Click on the X `(Delete)` for keys that were created at the same time as the user profile but have not been used. 7. As an IAM User- Click on the X `(Delete)` for keys that were created at the same time as the user profile but have not been used.**From Command Line:** ``` aws iam delete-access-key --access-key-id  --user-name  ```","AdditionalInformation": "Credential report does not appear to contain \"Key Creation Date\""}],"description": "Do not setup access keys during initial user setup for all IAM users that have a console password","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.12": {"name": "1.12","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#remove-credentials:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_admin-change-user.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "AWS IAM users can access AWS resources using different types of credentials, such as passwords or access keys. It is recommended that all credentials that have been unused in 45 or greater days be deactivated or removed.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if unused credentials exist:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM` 4. Click on `Users` 5. Click the `Settings` (gear) icon. 6. Select `Console last sign-in`, `Access key last used`, and `Access Key Id` 7. Click on `Close`8. Check and ensure that `Console last sign-in` is less than 45 days ago.**Note** - `Never` means the user has never logged in.9. Check and ensure that `Access key age` is less than 45 days and that `Access key last used` does not say `None`If the user hasn't signed into the Console in the last 45 days or Access keys are over 45 days old refer to the remediation.**From Command Line:****Download Credential Report:**1. Run the following commands: ```aws iam generate-credential-report aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,5,6,9,10,11,14,15,16 | grep -v '^' ```**Ensure unused credentials do not exist:**2. For each user having `password_enabled` set to `TRUE` , ensure `password_last_used_date` is less than `45` days ago.- When `password_enabled` is set to `TRUE` and `password_last_used` is set to `No_Information` , ensure `password_last_changed` is less than 45 days ago.3. For each user having an `access_key_1_active` or `access_key_2_active` to `TRUE` , ensure the corresponding `access_key_n_last_used_date` is less than `45` days ago.- When a user having an `access_key_x_active` (where x is 1 or 2) to `TRUE` and corresponding access_key_x_last_used_date is set to `N/A', ensure `access_key_x_last_rotated` is less than 45 days ago.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Disabling or removing unnecessary credentials will reduce the window of opportunity for credentials associated with a compromised or abandoned account to be used.","RemediationProcedure": "**From Console:**Perform the following to manage Unused Password (IAM user console access)1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. Select user whose `Console last sign-in` is greater than 45 days 7. Click `Security credentials` 8. In section `Sign-in credentials`, `Console password` click `Manage`9. Under Console Access select `Disable` 10.Click `Apply`Perform the following to deactivate Access Keys:1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. Select any access keys that are over 45 days old and that have been used and - Click on `Make Inactive` 7. Select any access keys that are over 45 days old and that have not been used and - Click the X to `Delete`","AdditionalInformation": " is excluded in the audit since the root account should not be used for day to day business and would likely be unused for more than 45 days."}],"description": "Ensure credentials unused for 45 days or greater are disabled","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1.13": {"name": "1.13","checks": {"iam_user_two_active_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html","Description": "Access keys are long-term credentials for an IAM user or the AWS account 'root' user. You can use access keys to sign programmatic requests to the AWS CLI or AWS API (directly or using the AWS SDK)","DefaultValue": null,"AuditProcedure": "**From Console:**1. Sign in to the AWS Management Console and navigate to IAM dashboard at `https://console.aws.amazon.com/iam/`. 2. In the left navigation panel, choose `Users`. 3. Click on the IAM user name that you want to examine. 4. On the IAM user configuration page, select `Security Credentials` tab. 5. Under `Access Keys` section, in the Status column, check the current status for each access key associated with the IAM user. If the selected IAM user has more than one access key activated then the users access configuration does not adhere to security best practices and the risk of accidental exposures increases. - Repeat steps no. 3 – 5 for each IAM user in your AWS account.**From Command Line:**1. Run `list-users` command to list all IAM users within your account: ``` aws iam list-users --query \"Users[*].UserName\" ``` The command output should return an array that contains all your IAM user names.2. Run `list-access-keys` command using the IAM user name list to return the current status of each access key associated with the selected IAM user: ``` aws iam list-access-keys --user-name  ``` The command output should expose the metadata `(\"Username\", \"AccessKeyId\", \"Status\", \"CreateDate\")` for each access key on that user account.3. Check the `Status` property value for each key returned to determine each keys current state. If the `Status` property value for more than one IAM access key is set to `Active`, the user access configuration does not adhere to this recommendation, refer to the remediation below.- Repeat steps no. 2 and 3 for each IAM user in your AWS account.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Access keys are long-term credentials for an IAM user or the AWS account 'root' user. You can use access keys to sign programmatic requests to the AWS CLI or AWS API. One of the best ways to protect your account is to not allow users to have multiple access keys.","RemediationProcedure": "**From Console:**1. Sign in to the AWS Management Console and navigate to IAM dashboard at `https://console.aws.amazon.com/iam/`. 2. In the left navigation panel, choose `Users`. 3. Click on the IAM user name that you want to examine. 4. On the IAM user configuration page, select `Security Credentials` tab. 5. In `Access Keys` section, choose one access key that is less than 90 days old. This should be the only active key used by this IAM user to access AWS resources programmatically. Test your application(s) to make sure that the chosen access key is working. 6. In the same `Access Keys` section, identify your non-operational access keys (other than the chosen one) and deactivate it by clicking the `Make Inactive` link. 7. If you receive the `Change Key Status` confirmation box, click `Deactivate` to switch off the selected key. 8. Repeat steps no. 3 – 7 for each IAM user in your AWS account.**From Command Line:**1. Using the IAM user and access key information provided in the `Audit CLI`, choose one access key that is less than 90 days old. This should be the only active key used by this IAM user to access AWS resources programmatically. Test your application(s) to make sure that the chosen access key is working.2. Run the `update-access-key` command below using the IAM user name and the non-operational access key IDs to deactivate the unnecessary key(s). Refer to the Audit section to identify the unnecessary access key ID for the selected IAM user**Note** - the command does not return any output: ``` aws iam update-access-key --access-key-id  --status Inactive --user-name  ``` 3. To confirm that the selected access key pair has been successfully `deactivated` run the `list-access-keys` audit command again for that IAM User: ``` aws iam list-access-keys --user-name  ``` - The command output should expose the metadata for each access key associated with the IAM user. If the non-operational key pair(s) `Status` is set to `Inactive`, the key has been successfully deactivated and the IAM user access configuration adheres now to this recommendation.4. Repeat steps no. 1 – 3 for each IAM user in your AWS account.","AdditionalInformation": ""}],"description": "Ensure there is only one active access key available for any single IAM user","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.14": {"name": "1.14","checks": {"iam_rotate_access_key_90_days": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#rotate-credentials:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html:https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "Access keys consist of an access key ID and secret access key, which are used to sign programmatic requests that you make to AWS. AWS users need their own access keys to make programmatic calls to AWS from the AWS Command Line Interface (AWS CLI), Tools for Windows PowerShell, the AWS SDKs, or direct HTTP calls using the APIs for individual AWS services. It is recommended that all access keys be regularly rotated.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if access keys are rotated as prescribed:**From Console:**1. Go to Management Console (https://console.aws.amazon.com/iam) 2. Click on `Users` 3. Click `setting` icon 4. Select `Console last sign-in` 5. Click `Close` 6. Ensure that `Access key age` is less than 90 days ago. note) `None` in the `Access key age` means the user has not used the access key.**From Command Line:**``` aws iam generate-credential-report aws iam get-credential-report --query 'Content' --output text | base64 -d ``` The `access_key_1_last_rotated` field in this file notes The date and time, in ISO 8601 date-time format, when the user's access key was created or last changed. If the user does not have an active access key, the value in this field is N/A (not applicable).","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Rotating access keys will reduce the window of opportunity for an access key that is associated with a compromised or terminated account to be used.Access keys should be rotated to ensure that data cannot be accessed with an old key which might have been lost, cracked, or stolen.","RemediationProcedure": "Perform the following to rotate access keys:**From Console:**1. Go to Management Console (https://console.aws.amazon.com/iam) 2. Click on `Users` 3. Click on `Security Credentials`4. As an Administrator - Click on `Make Inactive` for keys that have not been rotated in `90` Days 5. As an IAM User- Click on `Make Inactive` or `Delete` for keys which have not been rotated or used in `90` Days 6. Click on `Create Access Key`7. Update programmatic call with new Access Key credentials**From Command Line:**1. While the first access key is still active, create a second access key, which is active by default. Run the following command: ``` aws iam create-access-key ```At this point, the user has two active access keys.2. Update all applications and tools to use the new access key. 3. Determine whether the first access key is still in use by using this command: ``` aws iam get-access-key-last-used ``` 4. One approach is to wait several days and then check the old access key for any use before proceeding.Even if step Step 3 indicates no use of the old key, it is recommended that you do not immediately delete the first access key. Instead, change the state of the first access key to Inactive using this command: ``` aws iam update-access-key ``` 5. Use only the new access key to confirm that your applications are working. Any applications and tools that still use the original access key will stop working at this point because they no longer have access to AWS resources. If you find such an application or tool, you can switch its state back to Active to reenable the first access key. Then return to step Step 2 and update this application to use the new key.6. After you wait some period of time to ensure that all applications and tools have been updated, you can delete the first access key with this command: ``` aws iam delete-access-key ```","AdditionalInformation": ""}],"description": "Ensure access keys are rotated every 90 days or less","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.15": {"name": "1.15","checks": {"iam_policy_attached_only_to_group_or_roles": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html","Description": "IAM users are granted access to services, functions, and data through IAM policies. There are three ways to define policies for a user: 1) Edit the user policy directly, aka an inline, or user, policy; 2) attach a policy directly to a user; 3) add the user to an IAM group that has an attached policy. Only the third implementation is recommended.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if an inline policy is set or a policy is directly attached to users:1. Run the following to get a list of IAM users: ```aws iam list-users --query 'Users[*].UserName' --output text``` 2. For each user returned, run the following command to determine if any policies are attached to them: ```aws iam list-attached-user-policies --user-name aws iam list-user-policies --user-name ``` 3. If any policies are returned, the user has an inline policy or direct policy attachment.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Assigning IAM policy only through groups unifies permissions management to a single, flexible layer consistent with organizational functional roles. By unifying permissions management, the likelihood of excessive permissions is reduced.","RemediationProcedure": "Perform the following to create an IAM group and assign a policy to it:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click `Groups` and then click `Create New Group` . 3. In the `Group Name` box, type the name of the group and then click `Next Step` . 4. In the list of policies, select the check box for each policy that you want to apply to all members of the group. Then click `Next Step` . 5. Click `Create Group` Perform the following to add a user to a given group:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click `Groups`3. Select the group to add a user to 4. Click `Add Users To Group`5. Select the users to be added to the group 6. Click `Add Users` Perform the following to remove a direct association between a user and policy:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the left navigation pane, click on Users 3. For each user:- Select the user- Click on the `Permissions` tab- Expand `Permissions policies` - Click `X` for each policy; then click Detach or Remove (depending on policy type)","AdditionalInformation": ""}],"description": "Ensure IAM Users Receive Permissions Only Through Groups","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.16": {"name": "1.16","checks": {"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html:https://docs.aws.amazon.com/cli/latest/reference/iam/index.html#cli-aws-iam","Description": "IAM policies are the means by which privileges are granted to users, groups, or roles. It is recommended and considered a standard security advice to grant _least privilege_ -that is, granting only the permissions required to perform a task. Determine what users need to do and then craft policies for them that let the users perform _only_ those tasks, instead of allowing full administrative privileges.","DefaultValue": null,"AuditProcedure": "Perform the following to determine what policies are created:**From Command Line:**1. Run the following to get a list of IAM policies: ```aws iam list-policies --only-attached --output text ``` 2. For each policy returned, run the following command to determine if any policies is allowing full administrative privileges on the account: ```aws iam get-policy-version --policy-arn  --version-id  ``` 3. In output ensure policy should not have any Statement block with `\"Effect\": \"Allow\"` and `Action` set to `\"*\"` and `Resource` set to `\"*\"`","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "It's more secure to start with a minimum set of permissions and grant additional permissions as necessary, rather than starting with permissions that are too lenient and then trying to tighten them later.Providing full administrative privileges instead of restricting to the minimum set of permissions that the user is required to do exposes the resources to potentially unwanted actions.IAM policies that have a statement with \"Effect\": \"Allow\" with \"Action\": \"\\*\" over \"Resource\": \"\\*\" should be removed.","RemediationProcedure": "From Console: Perform the following to detach the policy that has full administrative privileges: 1. Sign in to the AWS Management Console and open the IAM console at https://console.aws.amazon.com/iam/. 2. In the navigation pane, click Policies and then search for the policy name found in the audit step. 3. Select the policy that needs to be deleted. 4. In the policy action menu, select first Detach 5. Select all Users, Groups, Roles that have this policy attached 6. Click Detach Policy 7. In the policy action menu, select Detach 8. Select the newly detached policy and select Delete From Command Line: Perform the following to detach the policy that has full administrative privileges as found in the audit step: 1. Lists all IAM users, groups, and roles that the specified managed policy is attached to. aws iam list-entities-for-policy --policy-arn  2. Detach the policy from all IAM Users: aws iam detach-user-policy --user-name  --policy-arn  3. Detach the policy from all IAM Groups: aws iam detach-group-policy --group-name  --policy-arn  4. Detach the policy from all IAM Roles: aws iam detach-role-policy --role-name  --policy-arn ","AdditionalInformation": ""}],"description": "Ensure IAM policies that allow full \"*:*\" administrative privileges are not attached","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1.17": {"name": "1.17","checks": {"iam_support_role_created": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html:https://aws.amazon.com/premiumsupport/pricing/:https://docs.aws.amazon.com/cli/latest/reference/iam/list-policies.html:https://docs.aws.amazon.com/cli/latest/reference/iam/attach-role-policy.html:https://docs.aws.amazon.com/cli/latest/reference/iam/list-entities-for-policy.html","Description": "AWS provides a support center that can be used for incident notification and response, as well as technical support and customer services. Create an IAM Role to allow authorized users to manage incidents with AWS Support.","DefaultValue": null,"AuditProcedure": "**From Command Line:**1. List IAM policies, filter for the 'AWSSupportAccess' managed policy, and note the \"Arn\" element value: ``` aws iam list-policies --query \"Policies[?PolicyName == 'AWSSupportAccess']\" ``` 2. Check if the 'AWSSupportAccess' policy is attached to any role:``` aws iam list-entities-for-policy --policy-arn arn:aws:iam::aws:policy/AWSSupportAccess ```3. In Output, Ensure `PolicyRoles` does not return empty. 'Example: Example: PolicyRoles: [ ]'If it returns empty refer to the remediation below.","ImpactStatement": "All AWS Support plans include an unlimited number of account and billing supportcases, with no long-term contracts. Support billing calculations are performed on a per-account basis for all plans. Enterprise Support plan customers have the option toinclude multiple enabled accounts in an aggregated monthly billing calculation. Monthlycharges for the Business and Enterprise support plans are based on each month's AWSusage charges, subject to a monthly minimum, billed in advance.When assigning rights, keep in mind that other policies may grant access to Support aswell. This may include AdministratorAccess and other policies including customermanaged policies. Utilizing the AWS managed 'AWSSupportAccess' role is one simpleway of ensuring that this permission is properly granted.To better support the principle of separation of duties, it would be best to only attach thisrole where necessary.","AssessmentStatus": "Automated","RationaleStatement": "By implementing least privilege for access control, an IAM Role will require an appropriate IAM Policy to allow Support Center Access in order to manage Incidents with AWS Support.","RemediationProcedure": "**From Command Line:**1. Create an IAM role for managing incidents with AWS:- Create a trust relationship policy document that allows  to manage AWS incidents, and save it locally as /tmp/TrustPolicy.json: ```{\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"\"},\"Action\": \"sts:AssumeRole\"}]} ``` 2. Create the IAM role using the above trust policy: ``` aws iam create-role --role-name  --assume-role-policy-document file:///tmp/TrustPolicy.json ``` 3. Attach 'AWSSupportAccess' managed policy to the created IAM role: ``` aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AWSSupportAccess --role-name  ```","AdditionalInformation": "AWSSupportAccess policy is a global AWS resource. It has same ARN as `arn:aws:iam::aws:policy/AWSSupportAccess` for every account."}],"description": "Ensure a support role has been created to manage incidents with AWS Support","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.18": {"name": "1.18","checks": {"ec2_instance_profile_attached": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html","Description": "AWS access from within AWS instances can be done by either encoding AWS keys into AWS API calls or by assigning the instance to a role which has an appropriate permissions policy for the required access. \"AWS Access\" means accessing the APIs of AWS in order to access AWS resources or manage AWS account resources.","DefaultValue": null,"AuditProcedure": "Where an instance is associated with a Role:For instances that are known to perform AWS actions, ensure that they belong to an instance role that has the necessary permissions:1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Open the EC2 Dashboard and choose \"Instances\" 3. Click the EC2 instance that performs AWS actions, in the lower pane details find \"IAM Role\" 4. If the Role is blank, the instance is not assigned to one. 5. If the Role is filled in, it does not mean the instance might not \\*also\\* have credentials encoded on it for some activities.Where an Instance Contains Embedded Credentials:- On the instance that is known to perform AWS actions, audit all scripts and environment variables to ensure that none of them contain AWS credentials.Where an Instance Application Contains Embedded Credentials:- Applications that run on an instance may also have credentials embedded. This is a bad practice, but even worse if the source code is stored in a public code repository such as github. When an application contains credentials can be determined by eliminating all other sources of credentials and if the application can still access AWS resources - it likely contains embedded credentials. Another method is to examine all source code and configuration files of the application.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "AWS IAM roles reduce the risks associated with sharing and rotating credentials that can be used outside of AWS itself. If credentials are compromised, they can be used from outside of the AWS account they give access to. In contrast, in order to leverage role permissions an attacker would need to gain and maintain access to a specific instance to use the privileges associated with it.Additionally, if credentials are encoded into compiled applications or other hard to change mechanisms, then they are even more unlikely to be properly rotated due to service disruption risks. As time goes on, credentials that cannot be rotated are more likely to be known by an increasing number of individuals who no longer work for the organization owning the credentials.","RemediationProcedure": "IAM roles can only be associated at the launch of an instance. To remediate an instance to add it to a role you must create a new instance.If the instance has no external dependencies on its current private ip or public addresses are elastic IPs:1. In AWS IAM create a new role. Assign a permissions policy if needed permissions are already known. 2. In the AWS console launch a new instance with identical settings to the existing instance, and ensure that the newly created role is selected. 3. Shutdown both the existing instance and the new instance. 4. Detach disks from both instances. 5. Attach the existing instance disks to the new instance. 6. Boot the new instance and you should have the same machine, but with the associated role.**Note:** if your environment has dependencies on a dynamically assigned PRIVATE IP address you can create an AMI from the existing instance, destroy the old one and then when launching from the AMI, manually assign the previous private IP address.**Note: **if your environment has dependencies on a dynamically assigned PUBLIC IP address there is not a way ensure the address is retained and assign an instance role. Dependencies on dynamically assigned public IP addresses are a bad practice and, if possible, you may wish to rebuild the instance with a new elastic IP address and make the investment to remediate affected systems while assigning the system to a role.","AdditionalInformation": ""}],"description": "Ensure IAM instance roles are used for AWS resource access from instances","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.19": {"name": "1.19","checks": {"iam_no_expired_server_certificates_stored": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_server-certs.html:https://docs.aws.amazon.com/cli/latest/reference/iam/delete-server-certificate.html","Description": "To enable HTTPS connections to your website or application in AWS, you need an SSL/TLS server certificate. You can use ACM or IAM to store and deploy server certificates.Use IAM as a certificate manager only when you must support HTTPS connections in a region that is not supported by ACM. IAM securely encrypts your private keys and stores the encrypted version in IAM SSL certificate storage. IAM supports deploying server certificates in all regions, but you must obtain your certificate from an external provider for use with AWS. You cannot upload an ACM certificate to IAM. Additionally, you cannot manage your certificates from the IAM Console.","DefaultValue": null,"AuditProcedure": "**From Console:**Getting the certificates expiration information via AWS Management Console is not currently supported.To request information about the SSL/TLS certificates stored in IAM via the AWS API use the Command Line Interface (CLI).**From Command Line:**Run list-server-certificates command to list all the IAM-stored server certificates:``` aws iam list-server-certificates ```The command output should return an array that contains all the SSL/TLS certificates currently stored in IAM and their metadata (name, ID, expiration date, etc):``` {\"ServerCertificateMetadataList\": [{\"ServerCertificateId\": \"EHDGFRW7EJFYTE88D\",\"ServerCertificateName\": \"MyServerCertificate\",\"Expiration\": \"2018-07-10T23:59:59Z\",\"Path\": \"/\",\"Arn\": \"arn:aws:iam::012345678910:server-certificate/MySSLCertificate\",\"UploadDate\": \"2018-06-10T11:56:08Z\"}] } ```Verify the `ServerCertificateName` and `Expiration` parameter value (expiration date) for each SSL/TLS certificate returned by the list-server-certificates command and determine if there are any expired server certificates currently stored in AWS IAM. If so, use the AWS API to remove them.If this command returns: ``` { { \"ServerCertificateMetadataList\": [] } ``` This means that there are no expired certificates, It DOES NOT mean that no certificates exist.","ImpactStatement": "Deleting the certificate could have implications for your application if you are using an expired server certificate with Elastic Load Balancing, CloudFront, etc. One has to make configurations at respective services to ensure there is no interruption in application functionality.","AssessmentStatus": "Automated","RationaleStatement": "Removing expired SSL/TLS certificates eliminates the risk that an invalid certificate will be deployed accidentally to a resource such as AWS Elastic Load Balancer (ELB), which can damage the credibility of the application/website behind the ELB. As a best practice, it is recommended to delete expired certificates.","RemediationProcedure": "**From Console:**Removing expired certificates via AWS Management Console is not currently supported. To delete SSL/TLS certificates stored in IAM via the AWS API use the Command Line Interface (CLI).**From Command Line:**To delete Expired Certificate run following command by replacing  with the name of the certificate to delete:``` aws iam delete-server-certificate --server-certificate-name  ```When the preceding command is successful, it does not return any output.","AdditionalInformation": ""}],"description": "Ensure that all the expired SSL/TLS certificates stored in AWS IAM are removed","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.20": {"name": "1.20","checks": {"accessanalyzer_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-getting-started.html:https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/get-analyzer.html:https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/create-analyzer.html","Description": "Enable IAM Access analyzer for IAM policies about all resources in each region.IAM Access Analyzer is a technology introduced at AWS reinvent 2019. After the Analyzer is enabled in IAM, scan results are displayed on the console showing the accessible resources. Scans show resources that other accounts and federated users can access, such as KMS keys and IAM roles. So the results allow you to determine if an unintended user is allowed, making it easier for administrators to monitor least privileges access. Access Analyzer analyzes only policies that are applied to resources in the same AWS Region.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Open the IAM console at `https://console.aws.amazon.com/iam/` 2. Choose `Access analyzer` 3. Click 'Analyzers' 4. Ensure that at least one analyzer is present 5. Ensure that the `STATUS` is set to `Active` 6. Repeat these step for each active region**From Command Line:**1. Run the following command: ``` aws accessanalyzer list-analyzers | grep status ``` 2. Ensure that at least one Analyzer the `status` is set to `ACTIVE`3. Repeat the steps above for each active region.If an Access analyzer is not listed for each region or the status is not set to active refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "AWS IAM Access Analyzer helps you identify the resources in your organization and accounts, such as Amazon S3 buckets or IAM roles, that are shared with an external entity. This lets you identify unintended access to your resources and data. Access Analyzer identifies resources that are shared with external principals by using logic-based reasoning to analyze the resource-based policies in your AWS environment. IAM Access Analyzer continuously monitors all policies for S3 bucket, IAM roles, KMS(Key Management Service) keys, AWS Lambda functions, and Amazon SQS(Simple Queue Service) queues.","RemediationProcedure": "**From Console:**Perform the following to enable IAM Access analyzer for IAM policies:1. Open the IAM console at `https://console.aws.amazon.com/iam/.` 2. Choose `Access analyzer`. 3. Choose `Create analyzer`. 4. On the `Create analyzer` page, confirm that the `Region` displayed is the Region where you want to enable Access Analyzer. 5. Enter a name for the analyzer. `Optional as it will generate a name for you automatically`. 6. Add any tags that you want to apply to the analyzer. `Optional`.7. Choose `Create Analyzer`. 8. Repeat these step for each active region**From Command Line:**Run the following command: ``` aws accessanalyzer create-analyzer --analyzer-name  --type  ``` Repeat this command above for each active region.**Note:** The IAM Access Analyzer is successfully configured only when the account you use has the necessary permissions.","AdditionalInformation": ""}],"description": "Ensure that IAM Access analyzer is enabled for all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.21": {"name": "1.21","checks": {"iam_check_saml_providers_sts": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "","Description": "In multi-account environments, IAM user centralization facilitates greater user control. User access beyond the initial account is then provided via role assumption. Centralization of users can be accomplished through federation with an external identity provider or through the use of AWS Organizations.","DefaultValue": null,"AuditProcedure": "For multi-account AWS environments with an external identity provider: 1. Determine the master account for identity federation or IAM user management 2. Login to that account through the AWS Management Console 3. Click Services 4. Click IAM 5. Click Identity providers 6. Verify the configuration Then, determine all accounts that should not have local users present. For each account: 1. Determine all accounts that should not have local users present 2. Log into the AWS Management Console 3. Switch role into each identified account 4. Click Services 5. Click IAM 6. Click Users 7. Confirm that no IAM users representing individuals are present For multi-account AWS environments implementing AWS Organizations without an external identity provider: 1. Determine all accounts that should not have local users present 2. Log into the AWS Management Console 3. Switch role into each identified account 4. Click Services 5. Click IAM 6. Click Users 7. Confirm that no IAM users representing individuals are present","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Centralizing IAM user management to a single identity store reduces complexity and thus the likelihood of access management errors.","RemediationProcedure": "The remediation procedure will vary based on the individual organization's implementation of identity federation and/or AWS Organizations with the acceptance criteria that no non-service IAM users, and non-root accounts, are present outside the account providing centralized IAM user management.","AdditionalInformation": ""}],"description": "Ensure IAM users are managed centrally via identity federation or AWS Organizations for multi-account environments","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.22": {"name": "1.22","checks": {},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/cloudshell/latest/userguide/sec-auth-with-identities.html","Description": "AWS CloudShell is a convenient way of running CLI commands against AWS services; a managed IAM policy ('AWSCloudShellFullAccess') provides full access to CloudShell, which allows file upload and download capability between a user's local system and the CloudShell environment. Within the CloudShell environment a user has sudo permissions, and can access the internet. So it is feasible to install file transfer software (for example) and move data from CloudShell to external internet servers.","DefaultValue": null,"AuditProcedure": "**From Console** 1. Open the IAM console at https://console.aws.amazon.com/iam/2. In the left pane, select Policies3. Search for and select AWSCloudShellFullAccess4. On the Entities attached tab, ensure that there are no entities using this policy **From Command Line**1. List IAM policies, filter for the 'AWSCloudShellFullAccess' managed policy, and note the \"\"Arn\"\" element value:```aws iam list-policies --query \"\"Policies[?PolicyName == 'AWSCloudShellFullAccess']\"\"``` 2. Check if the 'AWSCloudShellFullAccess' policy is attached to any role: ```aws iam list-entities-for-policy --policy-arn arn:aws:iam::aws:policy/AWSCloudShellFullAccess```3. In Output, Ensure PolicyRoles returns empty. 'Example: Example: PolicyRoles: [ ]'If it does not return empty refer to the remediation below.Note: Keep in mind that other policies may grant access.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Access to this policy should be restricted as it presents a potential channel for data exfiltration by malicious cloud admins that are given full permissions to the service. AWS documentation describes how to create a more restrictive IAM policy which denies file transfer permissions.","RemediationProcedure": "**From Console**1. Open the IAM console at https://console.aws.amazon.com/iam/2. In the left pane, select Policies 3. Search for and select AWSCloudShellFullAccess4. On the Entities attached tab, for each item, check the box and select Detach","AdditionalInformation": ""}],"description": "Ensure access to AWSCloudShellFullAccess is restricted","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"4.10": {"name": "4.10","checks": {"cloudwatch_log_metric_filter_security_group_changes": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Security Groups are a stateful packet filter that controls ingress and egress traffic within a VPC. It is recommended that a metric filter and alarm be established for detecting changes to Security Groups.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query \"MetricAlarms[?MetricName== '']\" ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to security group will help ensure that resources and services are not unintentionally exposed.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for security groups changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name \"\" --filter-name \"\" --metric-transformations metricName= \"\" ,metricNamespace=\"CISBenchmark\",metricValue=1 --filter-pattern \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\" ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name \"\" ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn \"\" --protocol  --notification-endpoint \"\" ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name \"\" --metric-name \"\" --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace \"CISBenchmark\" --alarm-actions \"\" ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for security group changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.11": {"name": "4.11","checks": {"cloudwatch_changes_to_network_acls_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. NACLs are used as a stateless packet filter to control ingress and egress traffic for subnets within a VPC. It is recommended that a metric filter and alarm be established for changes made to NACLs.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to NACLs will help ensure that AWS resources and services are not unintentionally exposed.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for NACL changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL)","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.12": {"name": "4.12","checks": {"cloudwatch_changes_to_network_gateways_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Network gateways are required to send/receive traffic to a destination outside of a VPC. It is recommended that a metric filter and alarm be established for changes to network gateways.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to network gateways will help ensure that all ingress/egress traffic traverses the VPC border via a controlled path.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for network gateways changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for changes to network gateways","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.13": {"name": "4.13","checks": {"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Routing tables are used to route network traffic between subnets and to network gateways. It is recommended that a metric filter and alarm be established for changes to route tables.","DefaultValue": null,"AuditProcedure": "If you are using CloudTrails and CloudWatch , perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarmsconfigured:1. Identify the log group name configured for use with active multi-region CloudTrail:• List all CloudTrails: aws cloudtrail describe-trails• Identify Multi region Cloudtrails: Trails with 'IsMultiRegionTrail' set totrue• From value associated with CloudWatchLogsLogGroupArn noteExample: for CloudWatchLogsLogGroupArn that looks likearn:aws:logs:::log-group:NewGroup:*, would be NewGroup• Ensure Identified Multi region CloudTrail is activeaws cloudtrail get-trail-status --name ensure IsLogging is set to TRUE• Ensure identified Multi-region Cloudtrail captures all Management Eventsaws cloudtrail get-event-selectors --trail-name Ensure there is at least one Event Selector for a Trail with IncludeManagementEvents setto true and ReadWriteType set to All2. Get a list of all associated metric filters for this :aws logs describe-metric-filters --log-group-name''3. Ensure the output from the above command contains the following:'filterPattern': '{($.eventSource = ec2.amazonaws.com) && ($.eventName =CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName =ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName= DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName =DisassociateRouteTable) }'4. Note the  value associated with thefilterPattern found in step 3.5. Get a list of CloudWatch alarms and filter on the captured in step 4.aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName==``]'6. Note the AlarmActions value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topicaws sns list-subscriptions-by-topic --topic-arn at least one subscription should have 'SubscriptionArn' with valid aws ARN.Example of valid 'SubscriptionArn':'arn:aws:sns::::'","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "CloudWatch is an AWS native service that allows you to observe and monitor resources and applications. CloudTrail Logs can also be sent to an external Security informationand event management (SIEM) environment for monitoring and alerting.Monitoring changes to route tables will help ensure that all VPC traffic flows through anexpected path and prevent any accidental or intentional modifications that may lead touncontrolled network traffic. An alarm should be triggered every time an AWS API call isperformed to create, replace, delete, or disassociate a Route Table.","RemediationProcedure": "If you are using CloudTrails and CloudWatch, perform the following to setup the metric filter, alarm, SNS topic, and subscription: 1. Create a metric filter based on filter pattern provided which checks for route table changes and the  taken from audit step 1. aws logs put-metric-filter --log-group-name  -- filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }' Note: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together. 2. Create an SNS topic that the alarm will notify aws sns create-topic --name  Note: you can execute this command once and then re-use the same topic for all monitoring alarms. 3. Create an SNS subscription to the topic created in step 2 aws sns subscribe --topic-arn  --protocol  - -notification-endpoint  Note: you can execute this command once and then re-use the SNS subscription for all monitoring alarms. 4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 - -threshold 1 --comparison-operator GreaterThanOrEqualToThreshold -- evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions ","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure route table changes are monitored","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.14": {"name": "4.14","checks": {"cloudwatch_changes_to_vpcs_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is possible to have more than 1 VPC within an account, in addition it is also possible to create a peer connection between 2 VPCs enabling network traffic to route between VPCs. It is recommended that a metric filter and alarm be established for changes made to VPCs.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to VPC will help ensure VPC traffic flow is not getting impacted.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for VPC changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for VPC changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.15": {"name": "4.15","checks": {"cloudwatch_log_metric_filter_aws_organizations_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/organizations/latest/userguide/orgs_security_incident-response.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for AWS Organizations changes made in the master AWS Account.","DefaultValue": null,"AuditProcedure": "1. Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured: - Identify the log group name configured for use with active multi-region CloudTrail: - List all CloudTrails:``` aws cloudtrail describe-trails ``` - Identify Multi region Cloudtrails, Trails with `\"IsMultiRegionTrail\"` set to true - From value associated with CloudWatchLogsLogGroupArn note **Example:** for CloudWatchLogsLogGroupArn that looks like arn:aws:logs:::log-group:NewGroup:*,  would be NewGroup- Ensure Identified Multi region CloudTrail is active: ``` aws cloudtrail get-trail-status --name  ``` Ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events: ``` aws cloudtrail get-event-selectors --trail-name  ``` - Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to true and `ReadWriteType` set to `All`.2. Get a list of all associated metric filters for this : ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdatePolicy\") || ($.eventName = \"UpdateOrganizationalUnit\")) }\" ``` 4. Note the `` value associated with the filterPattern found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4: ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the AlarmActions value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic: ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. Example of valid \"SubscriptionArn\":``` \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring AWS Organizations changes can help you prevent any unwanted, accidental or intentional modifications that may lead to unauthorized access or other security breaches. This monitoring technique helps you to ensure that any unexpected changes performed within your AWS Organizations can be investigated and any unwanted changes can be rolled back.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Organizations changes and the `` taken from audit step 1: ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdatePolicy\") || ($.eventName = \"UpdateOrganizationalUnit\")) }' ``` **Note:** You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify: ``` aws sns create-topic --name  ``` **Note:** you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2: ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note:** you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2: ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": ""}],"description": "Ensure a log metric filter and alarm exists for AWS Organizations changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.16": {"name": "4.16","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-get-started.html:https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-enable.html#securityhub-enable-api:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/securityhub/enable-security-hub.html","Description": "Security Hub collects security data from across AWS accounts, services, and supported third-party partner products and helps you analyze your security trends and identify the highest priority security issues. When you enable Security Hub, it begins to consume, aggregate, organize, and prioritize findings from AWS services that you have enabled, such as Amazon GuardDuty, Amazon Inspector, and Amazon Macie. You can also enable integrations with AWS partner security products.","DefaultValue": null,"AuditProcedure": "The process to evaluate AWS Security Hub configuration per region **From Console:**1. Sign in to the AWS Management Console and open the AWS Security Hub console at https://console.aws.amazon.com/securityhub/. 2. On the top right of the console, select the target Region. 3. If presented with the Security Hub > Summary page then Security Hub is set-up for the selected region. 4. If presented with Setup Security Hub or Get Started With Security Hub - follow the online instructions. 5. Repeat steps 2 to 4 for each region.","ImpactStatement": "It is recommended AWS Security Hub be enabled in all regions. AWS Security Hub requires AWS Config to be enabled.","AssessmentStatus": "Automated","RationaleStatement": "AWS Security Hub provides you with a comprehensive view of your security state in AWS and helps you check your environment against security industry standards and best practices - enabling you to quickly assess the security posture across your AWS accounts.","RemediationProcedure": "To grant the permissions required to enable Security Hub, attach the Security Hub managed policy AWSSecurityHubFullAccess to an IAM user, group, or role.Enabling Security Hub**From Console:**1. Use the credentials of the IAM identity to sign in to the Security Hub console. 2. When you open the Security Hub console for the first time, choose Enable AWS Security Hub. 3. On the welcome page, Security standards list the security standards that Security Hub supports. 4. Choose Enable Security Hub.**From Command Line:**1. Run the enable-security-hub command. To enable the default standards, include `--enable-default-standards`. ``` aws securityhub enable-security-hub --enable-default-standards ```2. To enable the security hub without the default standards, include `--no-enable-default-standards`. ``` aws securityhub enable-security-hub --no-enable-default-standards ```","AdditionalInformation": ""}],"description": "Ensure AWS Security Hub is enabled","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.1": {"name": "2.1.1","checks": {"s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-policy-for-config-rule/:https://aws.amazon.com/blogs/security/how-to-use-bucket-policies-and-apply-defense-in-depth-to-help-secure-your-amazon-s3-data/:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-bucket-policy.html","Description": "At the Amazon S3 bucket level, you can configure permissions through a bucket policy making the objects accessible only through HTTPS.","DefaultValue": null,"AuditProcedure": "To allow access to HTTPS you can use a condition that checks for the key `\"aws:SecureTransport: true\"`. This means that the request is sent through HTTPS but that HTTP can still be used. So to make sure you do not allow HTTP access confirm that there is a bucket policy that explicitly denies access for HTTP requests and that it contains the key \"aws:SecureTransport\": \"false\".**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/ 2. Select the Check box next to the Bucket. 3. Click on 'Permissions', then Click on `Bucket Policy`. 4. Ensure that a policy is listed that matches: ``` '{\"Sid\": ,\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}' ``` `` and `` will be specific to your account5. Repeat for all the buckets in your AWS account.**From Command Line:**1. List all of the S3 Buckets``` aws s3 ls ``` 2. Using the list of buckets run this command on each of them: ``` aws s3api get-bucket-policy --bucket  | grep aws:SecureTransport ``` 3. Confirm that `aws:SecureTransport` is set to false `aws:SecureTransport:false` 4. Confirm that the policy line has Effect set to Deny 'Effect:Deny'","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "By default, Amazon S3 allows both HTTP and HTTPS requests. To achieve only allowing access to Amazon S3 objects through HTTPS you also have to explicitly deny access to HTTP requests. Bucket policies that allow HTTPS requests without explicitly denying HTTP requests will not comply with this recommendation.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/ 2. Select the Check box next to the Bucket. 3. Click on 'Permissions'. 4. Click 'Bucket Policy' 5. Add this to the existing policy filling in the required information ``` {\"Sid\": \",\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}}} ``` 6. Save 7. Repeat for all the buckets in your AWS account that contain sensitive data.**From Console** using AWS Policy Generator:1. Repeat steps 1-4 above. 2. Click on `Policy Generator` at the bottom of the Bucket Policy Editor 3. Select Policy Type `S3 Bucket Policy` 4. Add Statements - `Effect` = Deny - `Principal` = * - `AWS Service` = Amazon S3 - `Actions` = * - `Amazon Resource Name` =  5. Generate Policy 6. Copy the text and add it to the Bucket Policy.**From Command Line:**1. Export the bucket policy to a json file. ``` aws s3api get-bucket-policy --bucket  --query Policy --output text > policy.json ```2. Modify the policy.json file by adding in this statement: ``` {\"Sid\": \",\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}}} ``` 3. Apply this modified policy back to the S3 bucket: ``` aws s3api put-bucket-policy --bucket  --policy file://policy.json ```","AdditionalInformation": ""}],"description": "Ensure S3 Bucket Policy is set to deny HTTP requests","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.1.2": {"name": "2.1.2","checks": {"s3_bucket_no_mfa_delete": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html#MultiFactorAuthenticationDelete:https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMFADelete.html:https://aws.amazon.com/blogs/security/securing-access-to-aws-using-mfa-part-3/:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_lost-or-broken.html","Description": "Once MFA Delete is enabled on your sensitive and classified S3 bucket it requires the user to have two forms of authentication.","DefaultValue": null,"AuditProcedure": "Perform the steps below to confirm MFA delete is configured on an S3 Bucket**From Console:**1. Login to the S3 console at `https://console.aws.amazon.com/s3/`2. Click the `Check` box next to the Bucket name you want to confirm3. In the window under `Properties`4. Confirm that Versioning is `Enabled`5. Confirm that MFA Delete is `Enabled`**From Command Line:**1. Run the `get-bucket-versioning` ``` aws s3api get-bucket-versioning --bucket my-bucket ```Output example: ```  EnabledEnabled ```If the Console or the CLI output does not show Versioning and MFA Delete `enabled` refer to the remediation below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Adding MFA delete to an S3 bucket, requires additional authentication when you change the version state of your bucket or you delete and object version adding another layer of security in the event your security credentials are compromised or unauthorized access is granted.","RemediationProcedure": "Perform the steps below to enable MFA delete on an S3 bucket.Note: -You cannot enable MFA Delete using the AWS Management Console. You must use the AWS CLI or API. -You must use your 'root' account to enable MFA Delete on S3 buckets.**From Command line:**1. Run the s3api put-bucket-versioning command``` aws s3api put-bucket-versioning --profile my-root-profile --bucket Bucket_Name --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa ā€œarn:aws:iam::aws_account_id:mfa/root-account-mfa-device passcodeā€ ```","AdditionalInformation": ""}],"description": "Ensure MFA Delete is enabled on S3 buckets","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.1.3": {"name": "2.1.3","checks": {"macie_is_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://aws.amazon.com/macie/getting-started/:https://docs.aws.amazon.com/workspaces/latest/adminguide/data-protection.html:https://docs.aws.amazon.com/macie/latest/user/data-classification.html","Description": "Amazon S3 buckets can contain sensitive data, that for security purposes should be discovered, monitored, classified and protected. Macie along with other 3rd party tools can automatically provide an inventory of Amazon S3 buckets.","DefaultValue": null,"AuditProcedure": "Perform the following steps to determine if Macie is running:**From Console:** 1. Login to the Macie console at https://console.aws.amazon.com/macie/ 2. In the left hand pane click on By job under findings. 3. Confirm that you have a Job setup for your S3 BucketsWhen you log into the Macie console if you aren't taken to the summary page and you don't have a job setup and running then refer to the remediation procedure below.If you are using a 3rd Party tool to manage and protect your s3 data you meet this recommendation.","ImpactStatement": "There is a cost associated with using Amazon Macie. There is also typically a cost associated with 3rd Party tools that perform similar processes and protection.","AssessmentStatus": "Manual","RationaleStatement": "Using a Cloud service or 3rd Party software to continuously monitor and automate the process of data discovery and classification for S3 buckets using machine learning and pattern matching is a strong defense in protecting that information.Amazon Macie is a fully managed data security and data privacy service that uses machine learning and pattern matching to discover and protect your sensitive data in AWS.","RemediationProcedure": "Perform the steps below to enable and configure Amazon Macie**From Console:**1. Log on to the Macie console at `https://console.aws.amazon.com/macie/`2. Click `Get started`.3. Click `Enable Macie`.Setup a repository for sensitive data discovery results1. In the Left pane, under Settings, click `Discovery results`.2. Make sure `Create bucket` is selected.3. Create a bucket, enter a name for the bucket. The name must be unique across all S3 buckets. In addition, the name must start with a lowercase letter or a number.4. Click on `Advanced`.5. Block all public access, make sure `Yes` is selected.6. KMS encryption, specify the AWS KMS key that you want to use to encrypt the results. The key must be a symmetric, customer master key (CMK) that's in the same Region as the S3 bucket.7. Click on `Save`Create a job to discover sensitive data1. In the left pane, click `S3 buckets`. Macie displays a list of all the S3 buckets for your account.2. Select the `check box` for each bucket that you want Macie to analyze as part of the job3. Click `Create job`.3. Click `Quick create`.4. For the Name and description step, enter a name and, optionally, a description of the job.5. Then click `Next`.6. For the Review and create step, click `Submit`.Review your findings1. In the left pane, click `Findings`.2. To view the details of a specific finding, choose any field other than the check box for the finding.If you are using a 3rd Party tool to manage and protect your s3 data, follow the Vendor documentation for implementing and configuring that tool.","AdditionalInformation": ""}],"description": "Ensure all data in Amazon S3 has been discovered, classified and secured when required.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.4": {"name": "2.1.4","checks": {"s3_bucket_level_public_access_block": "PASS","s3_account_level_public_access_blocks": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/block-public-access-account.html","Description": "Amazon S3 provides `Block public access (bucket settings)` and `Block public access (account settings)` to help you manage public access to Amazon S3 resources. By default, S3 buckets and objects are created with public access disabled. However, an IAM principal with sufficient S3 permissions can enable public access at the bucket and/or object level. While enabled, `Block public access (bucket settings)` prevents an individual bucket, and its contained objects, from becoming publicly accessible. Similarly, `Block public access (account settings)` prevents all buckets, and contained objects, from becoming publicly accessible across the entire account.","DefaultValue": null,"AuditProcedure": "**If utilizing Block Public Access (bucket settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select the Check box next to the Bucket. 3. Click on 'Edit public access settings'. 4. Ensure that block public access settings are set appropriately for this bucket 5. Repeat for all the buckets in your AWS account.**From Command Line:**1. List all of the S3 Buckets ``` aws s3 ls ``` 2. Find the public access setting on that bucket ``` aws s3api get-public-access-block --bucket  ``` Output if Block Public access is enabled:``` {\"PublicAccessBlockConfiguration\": {\"BlockPublicAcls\": true,\"IgnorePublicAcls\": true,\"BlockPublicPolicy\": true,\"RestrictPublicBuckets\": true} } ```If the output reads `false` for the separate configuration settings then proceed to the remediation.**If utilizing Block Public Access (account settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Choose `Block public access (account settings)` 3. Ensure that block public access settings are set appropriately for your AWS account.**From Command Line:**To check Public access settings for this account status, run the following command, `aws s3control get-public-access-block --account-id  --region `Output if Block Public access is enabled:``` {\"PublicAccessBlockConfiguration\": {\"IgnorePublicAcls\": true, \"BlockPublicPolicy\": true, \"BlockPublicAcls\": true, \"RestrictPublicBuckets\": true} } ```If the output reads `false` for the separate configuration settings then proceed to the remediation.","ImpactStatement": "When you apply Block Public Access settings to an account, the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously, but they eventually propagate to all Regions.","AssessmentStatus": "Automated","RationaleStatement": "Amazon S3 `Block public access (bucket settings)` prevents the accidental or malicious public exposure of data contained within the respective bucket(s). Amazon S3 `Block public access (account settings)` prevents the accidental or malicious public exposure of data contained within all buckets of the respective AWS account.Whether blocking public access to all or some buckets is an organizational decision that should be based on data sensitivity, least privilege, and use case.","RemediationProcedure": "**If utilizing Block Public Access (bucket settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select the Check box next to the Bucket. 3. Click on 'Edit public access settings'. 4. Click 'Block all public access' 5. Repeat for all the buckets in your AWS account that contain sensitive data.**From Command Line:**1. List all of the S3 Buckets ``` aws s3 ls ``` 2. Set the Block Public Access to true on that bucket ``` aws s3api put-public-access-block --bucket  --public-access-block-configuration \"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true\" ```**If utilizing Block Public Access (account settings)****From Console:**If the output reads `true` for the separate configuration settings then it is set on the account.1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Choose `Block Public Access (account settings)` 3. Choose `Edit` to change the block public access settings for all the buckets in your AWS account 4. Choose the settings you want to change, and then choose `Save`. For details about each setting, pause on the `i` icons. 5. When you're asked for confirmation, enter `confirm`. Then Click `Confirm` to save your changes.**From Command Line:**To set Block Public access settings for this account, run the following command: ``` aws s3control put-public-access-block --public-access-block-configuration BlockPublicAcls=true, IgnorePublicAcls=true, BlockPublicPolicy=true, RestrictPublicBuckets=true --account-id  ```","AdditionalInformation": ""}],"description": "Ensure that S3 Buckets are configured with 'Block public access (bucket settings)'","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"2.2.1": {"name": "2.2.1","checks": {"ec2_ebs_volume_encryption": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.2. Elastic Compute Cloud (EC2)","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html:https://aws.amazon.com/blogs/aws/new-opt-in-to-default-encryption-for-new-ebs-volumes/","Description": "Elastic Compute Cloud (EC2) supports encryption at rest when using the Elastic Block Store (EBS) service. While disabled by default, forcing encryption at EBS volume creation is supported.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under `Account attributes`, click `EBS encryption`. 3. Verify `Always encrypt new EBS volumes` displays `Enabled`. 4. Review every region in-use.**Note:** EBS volume encryption is configured per region.**From Command Line:**1. Run``` aws --region  ec2 get-ebs-encryption-by-default ``` 2. Verify that `\"EbsEncryptionByDefault\": true` is displayed. 3. Review every region in-use.**Note:** EBS volume encryption is configured per region.","ImpactStatement": "Losing access or removing the KMS key in use by the EBS volumes will result in no longer being able to access the volumes.","AssessmentStatus": "Automated","RationaleStatement": "Encrypting data at rest reduces the likelihood that it is unintentionally exposed and can nullify the impact of disclosure if the encryption remains unbroken.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under `Account attributes`, click `EBS encryption`. 3. Click `Manage`. 4. Click the `Enable` checkbox. 5. Click `Update EBS encryption` 6. Repeat for every region requiring the change.**Note:** EBS volume encryption is configured per region.**From Command Line:**1. Run``` aws --region  ec2 enable-ebs-encryption-by-default ``` 2. Verify that `\"EbsEncryptionByDefault\": true` is displayed. 3. Repeat every region requiring the change.**Note:** EBS volume encryption is configured per region.","AdditionalInformation": "Default EBS volume encryption only applies to newly created EBS volumes. Existing EBS volumes are **not** converted automatically."}],"description": "Ensure EBS Volume Encryption is Enabled in all Regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.3.1": {"name": "2.3.1","checks": {"rds_instance_storage_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Encryption.html:https://aws.amazon.com/blogs/database/selecting-the-right-encryption-options-for-amazon-rds-and-amazon-aurora-database-engines/#:~:text=With%20RDS%2Dencrypted%20resources%2C%20data,transparent%20to%20your%20database%20engine.:https://aws.amazon.com/rds/features/security/","Description": "Amazon RDS encrypted DB instances use the industry standard AES-256 encryption algorithm to encrypt your data on the server that hosts your Amazon RDS DB instances. After your data is encrypted, Amazon RDS handles authentication of access and decryption of your data transparently with a minimal impact on performance.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and open the RDS dashboard at https://console.aws.amazon.com/rds/ 2. In the navigation pane, under RDS dashboard, click `Databases`. 3. Select the RDS Instance that you want to examine 4. Click `Instance Name` to see details, then click on `Configuration` tab. 5. Under Configuration Details section, In Storage pane search for the `Encryption Enabled` Status. 6. If the current status is set to `Disabled`, Encryption is not enabled for the selected RDS Instance database instance. 7. Repeat steps 3 to 7 to verify encryption status of other RDS Instance in same region. 8. Change region from the top of the navigation bar and repeat audit for other regions.**From Command Line:**1. Run `describe-db-instances` command to list all RDS Instance database names, available in the selected AWS region, Output will return each Instance database identifier-name.``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. Run again `describe-db-instances` command using the RDS Instance identifier returned earlier, to determine if the selected database instance is encrypted, The command output should return the encryption status `True` Or `False`. ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].StorageEncrypted' ``` 3. If the StorageEncrypted parameter value is `False`, Encryption is not enabled for the selected RDS database instance. 4. Repeat steps 1 to 3 for auditing each RDS Instance and change Region to verify for other regions","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Databases are likely to hold sensitive and critical data, it is highly recommended to implement encryption in order to protect your data from unauthorized access or disclosure. With RDS encryption enabled, the data stored on the instance's underlying storage, the automated backups, read replicas, and snapshots, are all encrypted.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and open the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases` 3. Select the Database instance that needs to be encrypted. 4. Click on `Actions` button placed at the top right and select `Take Snapshot`. 5. On the Take Snapshot page, enter a database name of which you want to take a snapshot in the `Snapshot Name` field and click on `Take Snapshot`. 6. Select the newly created snapshot and click on the `Action` button placed at the top right and select `Copy snapshot` from the Action menu. 7. On the Make Copy of DB Snapshot page, perform the following:- In the New DB Snapshot Identifier field, Enter a name for the `new snapshot`. - Check `Copy Tags`, New snapshot must have the same tags as the source snapshot. - Select `Yes` from the `Enable Encryption` dropdown list to enable encryption, You can choose to use the AWS default encryption key or custom key from Master Key dropdown list.8. Click `Copy Snapshot` to create an encrypted copy of the selected instance snapshot. 9. Select the new Snapshot Encrypted Copy and click on the `Action` button placed at the top right and select `Restore Snapshot` button from the Action menu, This will restore the encrypted snapshot to a new database instance. 10. On the Restore DB Instance page, enter a unique name for the new database instance in the DB Instance Identifier field. 11. Review the instance configuration details and click `Restore DB Instance`. 12. As the new instance provisioning process is completed can update application configuration to refer to the endpoint of the new Encrypted database instance Once the database endpoint is changed at the application level, can remove the unencrypted instance.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names available in the selected AWS region, The command output should return the database instance identifier. ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. Run `create-db-snapshot` command to create a snapshot for the selected database instance, The command output will return the `new snapshot` with name DB Snapshot Name. ``` aws rds create-db-snapshot --region  --db-snapshot-identifier  --db-instance-identifier  ``` 3. Now run `list-aliases` command to list the KMS keys aliases available in a specified region, The command output should return each `key alias currently available`. For our RDS encryption activation process, locate the ID of the AWS default KMS key. ``` aws kms list-aliases --region  ``` 4. Run `copy-db-snapshot` command using the default KMS key ID for RDS instances returned earlier to create an encrypted copy of the database instance snapshot, The command output will return the `encrypted instance snapshot configuration`. ``` aws rds copy-db-snapshot --region  --source-db-snapshot-identifier  --target-db-snapshot-identifier  --copy-tags --kms-key-id  ``` 5. Run `restore-db-instance-from-db-snapshot` command to restore the encrypted snapshot created at the previous step to a new database instance, If successful, the command output should return the new encrypted database instance configuration. ``` aws rds restore-db-instance-from-db-snapshot --region  --db-instance-identifier  --db-snapshot-identifier  ``` 6. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region, Output will return database instance identifier name Select encrypted database name that we just created DB-Name-Encrypted. ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 7. Run again `describe-db-instances` command using the RDS instance identifier returned earlier, to determine if the selected database instance is encrypted, The command output should return the encryption status `True`. ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].StorageEncrypted' ```","AdditionalInformation": ""}],"description": "Ensure that encryption is enabled for RDS Instances","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.3.2": {"name": "2.3.2","checks": {"rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_RDS_Managing.html:https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.Upgrading.html:https://aws.amazon.com/rds/faqs/","Description": "Ensure that RDS database instances have the Auto Minor Version Upgrade flag enabled in order to receive automatically minor engine upgrades during the specified maintenance window. So, RDS instances can get the new features, bug fixes, and security patches for their database engines.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases`. 3. Select the RDS instance that wants to examine. 4. Click on the `Maintenance and backups` panel. 5. Under the `Maintenance` section, search for the Auto Minor Version Upgrade status. - If the current status is set to `Disabled`, means the feature is not set and the minor engine upgrades released will not be applied to the selected RDS instance**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance identifier. 3. Run again `describe-db-instances` command using the RDS instance identifier returned earlier to determine the Auto Minor Version Upgrade status for the selected instance: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].AutoMinorVersionUpgrade' ``` 4. The command output should return the feature current status. If the current status is set to `true`, the feature is enabled and the minor engine upgrades will be applied to the selected RDS instance.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "AWS RDS will occasionally deprecate minor engine versions and provide new ones for an upgrade. When the last version number within the release is replaced, the version changed is considered minor. With Auto Minor Version Upgrade feature enabled, the version upgrades will occur automatically during the specified maintenance window so your RDS instances can get the new features, bug fixes, and security patches for their database engines.","RemediationProcedure": "**From Console:**1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases`. 3. Select the RDS instance that wants to update. 4. Click on the `Modify` button placed on the top right side. 5. On the `Modify DB Instance: ` page, In the `Maintenance` section, select `Auto minor version upgrade` click on the `Yes` radio button. 6. At the bottom of the page click on `Continue`, check to Apply Immediately to apply the changes immediately, or select `Apply during the next scheduled maintenance window` to avoid any downtime. 7. Review the changes and click on `Modify DB Instance`. The instance status should change from available to modifying and back to available. Once the feature is enabled, the `Auto Minor Version Upgrade` status should change to `Yes`.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database instance names, available in the selected AWS region: ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. The command output should return each database instance identifier. 3. Run the `modify-db-instance` command to modify the selected RDS instance configuration this command will apply the changes immediately, Remove `--apply-immediately` to apply changes during the next scheduled maintenance window and avoid any downtime: ``` aws rds modify-db-instance --region  --db-instance-identifier  --auto-minor-version-upgrade --apply-immediately ``` 4. The command output should reveal the new configuration metadata for the RDS instance and check `AutoMinorVersionUpgrade` parameter value. 5. Run `describe-db-instances` command to check if the Auto Minor Version Upgrade feature has been successfully enable: ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].AutoMinorVersionUpgrade' ``` 6. The command output should return the feature current status set to `true`, the feature is `enabled` and the minor engine upgrades will be applied to the selected RDS instance.","AdditionalInformation": ""}],"description": "Ensure Auto Minor Version Upgrade feature is Enabled for RDS Instances","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.3.3": {"name": "2.3.3","checks": {"rds_instance_no_public_access": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "1. https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.html:https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario2.html:https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html:https://aws.amazon.com/rds/faqs/","Description": "Ensure and verify that RDS database instances provisioned in your AWS account do restrict unauthorized access in order to minimize security risks. To restrict access to anypublicly accessible RDS database instance, you must disable the database PubliclyAccessible flag and update the VPC security group associated with the instance","DefaultValue": null,"AuditProcedure": "From Console: 1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. Under the navigation panel, On RDS Dashboard, click Databases. 3. Select the RDS instance that you want to examine. 4. Click Instance Name from the dashboard, Under `Connectivity and Security. 5. On the Security, check if the Publicly Accessible flag status is set to Yes, follow the below-mentioned steps to check database subnet access. • In the networking section, click the subnet link available under Subnets • The link will redirect you to the VPC Subnets page. • Select the subnet listed on the page and click the Route Table tab from the dashboard bottom panel. If the route table contains any entries with the destination CIDR block set to 0.0.0.0/0 and with an Internet Gateway attached. • The selected RDS database instance was provisioned inside a public subnet, therefore is not running within a logically isolated environment and can be accessible from the Internet. 6. Repeat steps no. 4 and 5 to determine the type (public or private) and subnet for other RDS database instances provisioned in the current region. 7. Change the AWS region from the navigation bar and repeat the audit process for other regions. From Command Line: 1. Run describe-db-instances command to list all RDS database names, available in the selected AWS region: aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' 2. The command output should return each database instance identifier. 3. Run again describe-db-instances command using the PubliclyAccessible parameter as query filter to reveal the database instance Publicly Accessible flag status: aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].PubliclyAccessible' 4. Check for the Publicly Accessible parameter status, If the Publicly Accessible flag is set to Yes. Then selected RDS database instance is publicly accessible and insecure, follow the below-mentioned steps to check database subnet access 5. Run again describe-db-instances command using the RDS database instance identifier that you want to check and appropriate filtering to describe the VPC subnet(s) associated with the selected instance: aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].DBSubnetGroup.Subnets[]' • The command output should list the subnets available in the selected database subnet group. 6. Run describe-route-tables command using the ID of the subnet returned at the previous step to describe the routes of the VPC route table associated with the selected subnet: aws ec2 describe-route-tables --region  --filters 'Name=association.subnet-id,Values=' --query 'RouteTables[*].Routes[]' • If the command returns the route table associated with database instance subnet ID. Check the GatewayId and DestinationCidrBlock attributes values returned in the output. If the route table contains any entries with the GatewayId value set to igw-xxxxxxxx and the DestinationCidrBlock value set to 0.0.0.0/0, the selected RDS database instance was provisioned inside a public subnet. • Or • If the command returns empty results, the route table is implicitly associated with subnet, therefore the audit process continues with the next step 7. Run again describe-db-instances command using the RDS database instance identifier that you want to check and appropriate filtering to describe the VPC ID associated with the selected instance: aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].DBSubnetGroup.VpcId' • The command output should show the VPC ID in the selected database subnet group 8. Now run describe-route-tables command using the ID of the VPC returned at the previous step to describe the routes of the VPC main route table implicitly associated with the selected subnet: aws ec2 describe-route-tables --region  --filters 'Name=vpc- id,Values=' 'Name=association.main,Values=true' --query 'RouteTables[*].Routes[]' • The command output returns the VPC main route table implicitly associated with database instance subnet ID. Check the GatewayId and DestinationCidrBlock attributes values returned in the output. If the route table contains any entries with the GatewayId value set to igw-xxxxxxxx and the DestinationCidrBlock value set to 0.0.0.0/0, the selected RDS database instance was provisioned inside a public subnet, therefore is not running within a logically isolated environment and does not adhere to AWS security best practices.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Ensure that no public-facing RDS database instances are provisioned in your AWS account and restrict unauthorized access in order to minimize security risks. When the RDS instance allows unrestricted access (0.0.0.0/0), everyone and everything on the Internet can establish a connection to your database and this can increase the opportunity for malicious activities such as brute force attacks, PostgreSQL injections, or DoS/DDoS attacks.","RemediationProcedure": "From Console: 1. Log in to the AWS management console and navigate to the RDS dashboard at https://console.aws.amazon.com/rds/. 2. Under the navigation panel, On RDS Dashboard, click Databases. 3. Select the RDS instance that you want to update. 4. Click Modify from the dashboard top menu. 5. On the Modify DB Instance panel, under the Connectivity section, click on Additional connectivity configuration and update the value for Publicly Accessible to Not publicly accessible to restrict public access. Follow the below steps to update subnet configurations: • Select the Connectivity and security tab, and click on the VPC attribute value inside the Networking section. • Select the Details tab from the VPC dashboard bottom panel and click on Route table configuration attribute value. • On the Route table details page, select the Routes tab from the dashboard bottom panel and click on Edit routes. • On the Edit routes page, update the Destination of Target which is set to igw- xxxxx and click on Save routes. 6. On the Modify DB Instance panel Click on Continue and In the Scheduling of modifications section, perform one of the following actions based on your requirements: • Select Apply during the next scheduled maintenance window to apply the changes automatically during the next scheduled maintenance window. • Select Apply immediately to apply the changes right away. With this option, any pending modifications will be asynchronously applied as soon as possible, regardless of the maintenance window setting for this RDS database instance. Note that any changes available in the pending modifications queue are also applied. If any of the pending modifications require downtime, choosing this option can cause unexpected downtime for the application. 7. Repeat steps 3 to 6 for each RDS instance available in the current region. 8. Change the AWS region from the navigation bar to repeat the process for other regions. From Command Line: 1. Run describe-db-instances command to list all RDS database names identifiers, available in the selected AWS region: aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' 2. The command output should return each database instance identifier. 3. Run modify-db-instance command to modify the selected RDS instance configuration. Then use the following command to disable the Publicly Accessible flag for the selected RDS instances. This command use the apply- immediately flag. If you want to avoid any downtime --no-apply-immediately flag can be used: aws rds modify-db-instance --region  --db-instance-identifier  --no-publicly-accessible --apply-immediately 4. The command output should reveal the PubliclyAccessible configuration under pending values and should get applied at the specified time. 5. Updating the Internet Gateway Destination via AWS CLI is not currently supported To update information about Internet Gateway use the AWS Console Procedure. 6. Repeat steps 1 to 5 for each RDS instance provisioned in the current region. 7. Change the AWS region by using the --region filter to repeat the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that public access is not given to RDS Instance","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.4.1": {"name": "2.4.1","checks": {"efs_encryption_at_rest_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.4 Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/efs/index.html#efs","Description": "EFS data should be encrypted at rest using AWS KMS (Key Management Service).","DefaultValue": null,"AuditProcedure": "**From Console:** 1. Login to the AWS Management Console and Navigate to `Elastic File System (EFS) dashboard. 2. Select `File Systems` from the left navigation panel. 3. Each item on the list has a visible Encrypted field that displays data at rest encryption status. 4. Validate that this field reads `Encrypted` for all EFS file systems in all AWS regions.**From CLI:** 1. Run describe-file-systems command using custom query filters to list the identifiers of all AWS EFS file systems currently available within the selected region: ``` aws efs describe-file-systems --region  --output table --query 'FileSystems[*].FileSystemId' ``` 2. The command output should return a table with the requested file system IDs. 3. Run describe-file-systems command using the ID of the file system that you want to examine as identifier and the necessary query filters: ``` aws efs describe-file-systems --region  --file-system-id  --query 'FileSystems[*].Encrypted' ``` 4. The command output should return the file system encryption status true or false. If the returned value is `false`, the selected AWS EFS file system is not encrypted and if the returned value is `true`, the selected AWS EFS file system is encrypted.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Data should be encrypted at rest to reduce the risk of a data breach via direct access to the storage device.","RemediationProcedure": "**It is important to note that EFS file system data at rest encryption must be turned on when creating the file system.**If an EFS file system has been created without data at rest encryption enabled then you must create another EFS file system with the correct configuration and transfer the data.**Steps to create an EFS file system with data encrypted at rest:****From Console:** 1. Login to the AWS Management Console and Navigate to `Elastic File System (EFS)` dashboard. 2. Select `File Systems` from the left navigation panel. 3. Click `Create File System` button from the dashboard top menu to start the file system setup process. 4. On the `Configure file system access` configuration page, perform the following actions. - Choose the right VPC from the VPC dropdown list. - Within Create mount targets section, select the checkboxes for all of the Availability Zones (AZs) within the selected VPC. These will be your mount targets. - Click `Next step` to continue.5. Perform the following on the `Configure optional settings` page. - Create `tags` to describe your new file system. - Choose `performance mode` based on your requirements. - Check `Enable encryption` checkbox and choose `aws/elasticfilesystem` from Select KMS master key dropdown list to enable encryption for the new file system using the default master key provided and managed by AWS KMS. - Click `Next step` to continue.6. Review the file system configuration details on the `review and create` page and then click `Create File System` to create your new AWS EFS file system. 7. Copy the data from the old unencrypted EFS file system onto the newly create encrypted file system. 8. Remove the unencrypted file system as soon as your data migration to the newly create encrypted file system is completed. 9. Change the AWS region from the navigation bar and repeat the entire process for other aws regions.**From CLI:** 1. Run describe-file-systems command to describe the configuration information available for the selected (unencrypted) file system (see Audit section to identify the right resource): ``` aws efs describe-file-systems --region  --file-system-id  ``` 2. The command output should return the requested configuration information. 3. To provision a new AWS EFS file system, you need to generate a universally unique identifier (UUID) in order to create the token required by the create-file-system command. To create the required token, you can use a randomly generated UUID from \"https://www.uuidgenerator.net\". 4. Run create-file-system command using the unique token created at the previous step. ``` aws efs create-file-system --region  --creation-token  --performance-mode generalPurpose --encrypted ``` 5. The command output should return the new file system configuration metadata. 6. Run create-mount-target command using the newly created EFS file system ID returned at the previous step as identifier and the ID of the Availability Zone (AZ) that will represent the mount target: ``` aws efs create-mount-target --region  --file-system-id  --subnet-id  ``` 7. The command output should return the new mount target metadata. 8. Now you can mount your file system from an EC2 instance. 9. Copy the data from the old unencrypted EFS file system onto the newly create encrypted file system. 10. Remove the unencrypted file system as soon as your data migration to the newly create encrypted file system is completed. ``` aws efs delete-file-system --region  --file-system-id  ``` 11. Change the AWS region by updating the --region and repeat the entire process for other aws regions.","AdditionalInformation": ""}],"description": "Ensure that encryption is enabled for EFS file systems","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 51,"requirements_failed": 10,"requirements_manual": 1,"total_requirements": 62,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "a349f7c9-fce3-4ac4-821a-d0c974496c2b","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "nist_800_53_revision_5_aws","framework": "NIST-800-53-Revision-5","version": "","description": "The NIST 800-53 (Rev. 5) Low-Moderate-High framework represents the security controls and the associated assessment procedures that are defined in NIST SP 800-53 Revision 5 Recommended Security Controls for Federal Information Systems and Organizations. For any discrepancies that are noted in the content between this NIST SP 800-53 framework and the latest published NIST Special Publication SP 800-53 Revision 5, refer to the official published documents that are available at the NIST Computer Security Resource Center.","region": "eu-west-1","requirements": {"ac_3": {"name": "Access Enforcement (AC-3)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"ec2_instance_profile_attached": "PASS","rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Enforce approved authorizations for logical access to information and system resources in accordance with applicable access control policies.","checks_status": {"fail": 1,"pass": 7,"total": 21,"manual": 0}},"ac_4": {"name": "Information Flow Enforcement (AC-4)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_4","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Enforce approved authorizations for controlling the flow of information within the system and between connected systems based on [Assignment: organization-defined information flow control policies].","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"ac_6": {"name": "Least Privilege (AC-6)","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_6","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Employ the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) that are necessary to accomplish assigned organizational tasks.","checks_status": {"fail": 1,"pass": 6,"total": 21,"manual": 0}},"ca_7": {"name": "Continuous Monitoring (CA-7)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ca_7","Section": "Assessment, Authorization, And Monitoring (CA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Continuously monitor configuration management processes. Determine security impact, environment and operational risks.","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"cm_6": {"name": "Configuration Settings (CM-6)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_6","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization: (i) establishes mandatory configuration settings for information technology products employed within the information system; (ii) configures the security settings of information technology products to the most restrictive mode consistent with operational requirements; (iii) documents the configuration settings; and (iv) enforces the configuration settings in all components of the information system.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"ia_2": {"name": "Identification and Authentication (Organizational users) (IA-2)","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": null}],"description": "The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5": {"name": "Authenticator Management (IA-5)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5","Section": "Identification and Authentication (IA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Authenticate users and devices. Automate administrative control. Enforce restrictions. Protect against unauthorized use.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"mp_2": {"name": "Media Access (MP-2)","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "mp_2","Section": "Media Protection (MP)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Restrict access to [Assignment: organization-defined types of digital and/or non-digital media] to [Assignment: organization-defined personnel or roles].","checks_status": {"fail": 1,"pass": 6,"total": 21,"manual": 0}},"sc_6": {"name": "Resource Availability (SC-6)","checks": {"rds_instance_multi_az": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_6","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Protect the availability of resources by allocating [Assignment: organization-defined resources] by [Selection (one or more): priority; quota; [Assignment: organization-defined controls]].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sc_8": {"name": "Transmission Confidentiality And Integrity (SC-8)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_8","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Protect the [Selection (one or more): confidentiality; integrity] of transmitted information.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"ac_24": {"name": "Access Control Decisions (AC-24)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_24","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "[Selection: Establish procedures; Implement mechanisms] to ensure [Assignment: organization-defined access control decisions] are applied to each access request prior to access enforcement.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"au_10": {"name": "Non-Repudiation (AU-10)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","opensearch_service_domains_cloudwatch_logging_enabled": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_10","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Provide irrefutable evidence that an individual (or process acting on behalf of an individual) has performed [Assignment: organization-defined actions to be covered by non-repudiation].","checks_status": {"fail": 6,"pass": 2,"total": 13,"manual": 0}},"au_11": {"name": "Audit Record Retention (AU-11)","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_11","Section": "Audit and Accountability (AU)","Service": "cloudwatch","SubGroup": null,"SubSection": null}],"description": "Retain audit records for [Assignment: organization-defined time period consistent with records retention policy] to provide support for after-the-fact investigations of incidents and to meet regulatory and organizational information retention requirements.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"au_16": {"name": "Cross-Organizational Audit Logging (AU-16)","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_16","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Employ [Assignment: organization-defined methods] for coordinating [Assignment: organization-defined audit information] among external organizations when audit information is transmitted across organizational boundaries.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cp_10": {"name": "System Recovery And Reconstitution (CP-10)","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_10","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Provide for the recovery and reconstitution of the system to a known state within [Assignment: organization-defined time period consistent with recovery time and recovery point objectives] after a disruption, compromise, or failure.","checks_status": {"fail": 3,"pass": 1,"total": 7,"manual": 0}},"pm_16": {"name": "Threat Awareness Program (PM-16)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "pm_16","Section": "Program Management (PM)","Service": "guarduty","SubGroup": null,"SubSection": null}],"description": "Implement a threat awareness program that includes a cross-organization information-sharing capability for threat intelligence.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"pm_31": {"name": "Continuous Monitoring Strategy (PM-31)","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pm_31","Section": "Program Management (PM)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Develop an organization-wide continuous monitoring strategy and implement continuous monitoring programs that include: a. Establishing the following organization-wide metrics to be monitored: [Assignment: organization-defined metrics]; b. Establishing [Assignment: organization-defined frequencies] for monitoring and [Assignment: organization-defined frequencies] for assessment of control effectiveness; c. Ongoing monitoring of organizationally-defined metrics in accordance with the continuous monitoring strategy; d. Correlation and analysis of information generated by control assessments and monitoring; e. Response actions to address results of the analysis of control assessment and monitoring information; and f. Reporting the security and privacy status of organizational systems to [Assignment: organization-defined personnel or roles] [Assignment: organization-defined frequency].","checks_status": {"fail": 8,"pass": 4,"total": 20,"manual": 0}},"sc_12": {"name": "Cryptographic Key Establishment And Management (SC-12)","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_12","Section": "System and Communications Protection (SC)","Service": "kms","SubGroup": null,"SubSection": null}],"description": "Establish and manage cryptographic keys when cryptography is employed within the system in accordance with the following key management requirements: [Assignment: organization-defined requirements for key generation, distribution, storage, access, and destruction].","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"sc_22": {"name": "Architecture And Provisioning For Name/Address Resolution Service (SC-22)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_22","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Ensure the systems that collectively provide name/address resolution service for an organization are fault-tolerant and implement internal and external role separation.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"sc_23": {"name": "Session Authenticity (SC-23)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_23","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Protect the authenticity of communications sessions.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"sc_25": {"name": "Thin Nodes (SC-25)","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_25","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Employ minimal functionality and information storage on the following system components: [Assignment: organization-defined system components].","checks_status": {"fail": 1,"pass": 5,"total": 17,"manual": 0}},"sc_36": {"name": "Distributed Processing And Storage (SC-36)","checks": {"rds_instance_multi_az": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_36","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Distribute the following processing and storage components across multiple [Selection: physical locations; logical domains]: [Assignment: organization-defined processing and storage components].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"si_12": {"name": "Information Management and Retention (SI-12)","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_12","Section": "System and Information integrity (SI)","Service": "cloudwatch","SubGroup": null,"SubSection": null}],"description": "Manage and retain information within the system and information output from the system in accordance with applicable laws, executive orders, directives, regulations, policies, standards, guidelines and operational requirements.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ac_2_1": {"name": "AC-2(1) Automated System Account Management","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_2_1","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "Support the management of system accounts using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 1,"pass": 0,"total": 14,"manual": 0}},"ac_2_3": {"name": "AC-2(3) Disable Accounts","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_3","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "Disable accounts within [Assignment: organization-defined time period] when the accounts: (a) Have expired; (b) Are no longer associated with a user or individual; (c) Are in violation of organizational policy; or (d) Have been inactive for [Assignment: organization-defined time period].","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"ac_2_4": {"name": "AC-2(4) Automated Audit Actions","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_2_4","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "Automatically audit account creation, modification, enabling, disabling, and removal actions.","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"ac_2_6": {"name": "AC-2(6) Dynamic Privilege Management","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_2_6","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "Implement [Assignment: organization-defined dynamic privilege management capabilities].","checks_status": {"fail": 1,"pass": 6,"total": 21,"manual": 0}},"ac_2_g": {"name": "AC-2(g)","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_g","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The organization: g. Monitors the use of information system accounts.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"ac_2_j": {"name": "AC-2(j)","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_j","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The organization: j. Reviews accounts for compliance with account management requirements [Assignment: organization-defined frequency].","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"ac_3_1": {"name": "AC-3(1) Restricted Access To Privileged Functions","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_1","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Access Enforcement (AC-3)"}],"description": "Employ an audited override of automated access control mechanisms under [Assignment: organization-defined conditions] by [Assignment: organization-defined roles].","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"ac_3_2": {"name": "AC-3(2) Dual Authorization","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_3_2","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce dual authorization for [Assignment: organization-defined privileged commands and/or other organization-defined actions].","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ac_3_3": {"name": "AC-3(3) Mandatory Access Control","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_3","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access control policy] over the set of covered subjects and objects specified in the policy, and where the policy: (a) Is uniformly enforced across the covered subjects and objects within the system; (b) Specifies that a subject that has been granted access to information is constrained from doing any of the following; (1) Passing the information to unauthorized subjects or objects; (2) Granting its privileges to other subjects; (3) Changing one or more security attributes (specified by the policy) on subjects, objects, the system, or system components; (4) Choosing the security attributes and attribute values (specified by the policy) to be associated with newly created or modified objects; and (5) Changing the rules governing access control; and (c) Specifies that [Assignment: organization-defined subjects] may explicitly be granted [Assignment: organization-defined privileges] such that they are not limited by any defined subset (or all) of the above constraints.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_4": {"name": "AC-3(4) Discretionary Access Control","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_4","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined discretionary access control policy] over the set of covered subjects and objects specified in the policy, and where the policy specifies that a subject that has been granted access to information can do one or more of the following: (a) Pass the information to any other subjects or objects; (b) Grant its privileges to other subjects; (c) Change security attributes on subjects, objects, the system, or the system’s components; (d) Choose the security attributes to be associated with newly created or revised objects; or (e) Change the rules governing access control.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_7": {"name": "AC-3(7) Role-Based Access Control","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_7","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce a role-based access control policy over defined subjects and objects and control access based upon [Assignment: organization-defined roles and users authorized to assume such roles].","checks_status": {"fail": 1,"pass": 6,"total": 21,"manual": 0}},"ac_3_8": {"name": "AC-3(8) Revocation Of Access Authorizations","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_8","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce the revocation of access authorizations resulting from changes to the security attributes of subjects and objects based on [Assignment: organization-defined rules governing the timing of revocations of access authorizations].","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_5_b": {"name": "AC-5(b)","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_5_b","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Separation Of Duties (AC-5)"}],"description": "Define system access authorizations to support separation of duties.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"ac_6_2": {"name": "AC-6(2)","checks": {"iam_no_root_access_key": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_6_2","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Least Privilege (AC-6)"}],"description": "Require that users of system accounts (or roles) with access to [Assignment: organization-defined security functions or security-relevant information] use non-privileged accounts or roles, when accessing nonsecurity functions.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ac_6_3": {"name": "AC-6(3)","checks": {"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_6_3","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Least Privilege (AC-6)"}],"description": "Authorize network access to [Assignment: organization-defined privileged commands] only for [Assignment: organization-defined compelling operational needs] and document the rationale for such access in the security plan for the system.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ac_6_9": {"name": "AC-6(9)","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_6_9","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Least Privilege (AC-6)"}],"description": "Log the execution of privileged functions.","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"ac_7_4": {"name": "AC-7(4) Use Of Alternate Authentication Factor","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_7_4","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Unsuccessful Logon Attempts (AC-7)"}],"description": "Prevent non-privileged users from executing privileged functions.","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"au_2_b": {"name": "AU-2(b)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_2_b","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Event Logging (AU-2)"}],"description": "Coordinate the event logging function with other organizational entities requiring audit-related information to guide and inform the selection criteria for events to be logged.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_3_1": {"name": "AU-3(1) Additional Audit Information","checks": {"guardduty_is_enabled": "PASS","cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "au_3_1","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Content of Audit Records (AU-3)"}],"description": "Generate audit records containing the following additional information: [Assignment: organization-defined additional information].","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"au_3_a": {"name": "AU-3(a)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_3_a","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Content of Audit Records (AU-3)"}],"description": "Ensure that audit records contain information that establishes the following: a. What type of event occurred.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_3_b": {"name": "AU-3(b)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_3_b","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Content of Audit Records (AU-3)"}],"description": "Ensure that audit records contain information that establishes the following: b. When the event occurred.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_3_c": {"name": "AU-3(c)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_3_c","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Content of Audit Records (AU-3)"}],"description": "Ensure that audit records contain information that establishes the following: c. Where the event occurred.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_3_d": {"name": "AU-3(d)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_3_d","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Content of Audit Records (AU-3)"}],"description": "Ensure that audit records contain information that establishes the following: d. Source of the event.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_3_e": {"name": "AU-3(e)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_3_e","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Content of Audit Records (AU-3)"}],"description": "Ensure that audit records contain information that establishes the following: e. Outcome of the event.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_3_f": {"name": "AU-3(f)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_3_f","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Content of Audit Records (AU-3)"}],"description": "Ensure that audit records contain information that establishes the following: e. Outcome of the event.","checks_status": {"fail": 5,"pass": 2,"total": 11,"manual": 0}},"au_4_1": {"name": "AU-4(1) Transfer To Alternate Storage","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_4_1","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Log Stprage Capacity (AU-4)"}],"description": "Transfer audit logs [Assignment: organization-defined frequency] to a different system, system component, or media other than the system or system component conducting the logging.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"au_6_1": {"name": "AU-6(1) Automated Process Integration","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_6_1","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Review, Analysis And Reporting (AU-6)"}],"description": "Integrate audit record review, analysis, and reporting processes using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"au_6_3": {"name": "AU-6(3) Correlate Audit Record Repositories","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_6_3","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Review, Analysis And Reporting (AU-6)"}],"description": "Analyze and correlate audit records across different repositories to gain organization-wide situational awareness.","checks_status": {"fail": 7,"pass": 2,"total": 13,"manual": 0}},"au_6_4": {"name": "AU-6(4) Central Review And Analysis","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_6_4","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Review, Analysis And Reporting (AU-6)"}],"description": "Provide and implement the capability to centrally review and analyze audit records from multiple components within the system.","checks_status": {"fail": 7,"pass": 2,"total": 13,"manual": 0}},"au_6_5": {"name": "AU-6(5) Central Review And Analysis","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_6_5","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Review, Analysis And Reporting (AU-6)"}],"description": "Integrate analysis of audit records with analysis of [Selection (one or more): vulnerability scanning information; performance data; system monitoring information; [Assignment: organization-defined data/information collected from other sources]] to further enhance the ability to identify inappropriate or unusual activity.","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"au_6_6": {"name": "AU-6(6) Correletion With Physical Monitoring","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_6_6","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Review, Analysis And Reporting (AU-6)"}],"description": "Correlate information from audit records with information obtained from monitoring physical access to further enhance the ability to identify suspicious, inappropriate, unusual, or malevolent activity.","checks_status": {"fail": 7,"pass": 2,"total": 13,"manual": 0}},"au_6_9": {"name": "AU-6(9) Correletion With From Nontechnical Sources","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_6_9","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Review, Analysis And Reporting (AU-6)"}],"description": "Correlate information from nontechnical sources with audit record information to enhance organization-wide situational awareness.","checks_status": {"fail": 7,"pass": 2,"total": 13,"manual": 0}},"au_7_1": {"name": "AU-7(1) Automatic Processing","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_7_1","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Reduction And Report Generation (AU-7)"}],"description": "Provide and implement the capability to process, sort, and search audit records for events of interest based on the following content: [Assignment: organization-defined fields within audit records].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"au_8_b": {"name": "AU-8(b)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_8_b","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Time Stamps (AU-8)"}],"description": "Record time stamps for audit records that meet [Assignment: organization-defined granularity of time measurement] and that use Coordinated Universal Time, have a fixed local time offset from Coordinated Universal Time, or that include the local time offset as part of the time stamp.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_9_2": {"name": "AU-9(2) Store On Separate Physical Systems Or Components","checks": {"s3_bucket_object_versioning": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_9_2","Section": "Audit and Accountability (AU)","Service": "s3","SubGroup": null,"SubSection": "Protection of Audit Information (AU-9)"}],"description": "Store audit records [Assignment: organization-defined frequency] in a repository that is part of a physically different system or system component than the system or component being audited.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"au_9_3": {"name": "AU-9(3) Cryptographic Protection","checks": {"elb_ssl_listeners": "FAIL","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_9_3","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Protection of Audit Information (AU-9)"}],"description": "Implement cryptographic mechanisms to protect the integrity of audit information and audit tools.","checks_status": {"fail": 8,"pass": 3,"total": 17,"manual": 0}},"au_9_7": {"name": "AU-9(7) Store On Component With Different Operation Systems","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_9_7","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Protection of Audit Information (AU-9)"}],"description": "Store audit information on a component running a different operating system than the system or component being audited.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"au_9_a": {"name": "AU-9(a)","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_9_a","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Protection of Audit Information (AU-9)"}],"description": "Protect audit information and audit logging tools from unauthorized access, modification, and deletion.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ca_2_2": {"name": "CA-2(2) Specialized Assessments","checks": {"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ca_2_2","Section": "Assessment, Authorization, And Monitoring (CA)","Service": "aws","SubGroup": null,"SubSection": "Control Assessments (CA-2)"}],"description": "Include as part of control assessments, [Assignment: organization-defined frequency], [Selection: announced; unannounced], [Selection (one or more): in-depth monitoring; security instrumentation; automated security test cases; vulnerability scanning; malicious user testing; insider threat assessment; performance and load testing; data leakage or data loss assessment; [Assignment: organization-defined other forms of assessment]].","checks_status": {"fail": 1,"pass": 0,"total": 5,"manual": 0}},"ca_2_d": {"name": "CA-2(d)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ca_2_d","Section": "Assessment, Authorization, And Monitoring (CA)","Service": "aws","SubGroup": null,"SubSection": "Control Assessments (CA-2)"}],"description": "Assess the controls in the system and its environment of operation [Assignment: organization-defined frequency] to determine the extent to which the controls are implemented correctly, operating as intended, and producing the desired outcome with respect to meeting established security and privacy requirements.","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"ca_7_b": {"name": "CA-7(b)","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ca_7_b","Section": "Assessment, Authorization, And Monitoring (CA)","Service": "aws","SubGroup": null,"SubSection": "Continuous Monitoring (CA-7)"}],"description": "Develop a system-level continuous monitoring strategy and implement continuous monitoring in accordance with the organization-level continuous monitoring strategy that includes: b. Establishing [Assignment: organization-defined frequencies] for monitoring and [Assignment: organization-defined frequencies] for assessment of control effectiveness.","checks_status": {"fail": 8,"pass": 4,"total": 20,"manual": 0}},"ca_9_b": {"name": "CA-9(b)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ca_9_b","Section": "Assessment, Authorization, And Monitoring (CA)","Service": "aws","SubGroup": null,"SubSection": "Internal System Connections (CA-9)"}],"description": "Document, for each internal connection, the interface characteristics, security and privacy requirements, and the nature of the information communicated.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"cm_2_2": {"name": "CM-2(2) Automation Support For Accuracy And Currency","checks": {"elbv2_deletion_protection": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_2_2","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Baseline Configuration (CM-2)"}],"description": "Maintain the currency, completeness, accuracy, and availability of the baseline configuration of the system using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 5,"pass": 0,"total": 5,"manual": 0}},"cm_2_a": {"name": "CM-2(a)","checks": {"elbv2_deletion_protection": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_2_a","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Baseline Configuration (CM-2)"}],"description": "Develop, document, and maintain under configuration control, a current baseline configuration of the system.","checks_status": {"fail": 5,"pass": 0,"total": 5,"manual": 0}},"cm_2_b": {"name": "CM-2(b)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_2_b","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Baseline Configuration (CM-2)"}],"description": "Review and update the baseline configuration of the system: 1. [Assignment: organization-defined frequency]; 2. When required due to [Assignment: organization-defined circumstances]; and 3. When system components are installed or upgraded.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"cm_3_3": {"name": "CM-3(3) Automated Change Implementation","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_3_3","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Configuration Change Control (CM-3)"}],"description": "Implement changes to the current system baseline and deploy the updated baseline across the installed base using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"cm_3_a": {"name": "CM-3(a)","checks": {"elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_3_a","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Configuration Change Control (CM-3)"}],"description": "Determine and document the types of changes to the system that are configuration-controlled.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_6_a": {"name": "CM-6(a)","checks": {"iam_root_mfa_enabled": null,"vpc_flow_logs_enabled": "FAIL","iam_no_root_access_key": null,"s3_bucket_public_access": null,"kms_cmk_rotation_enabled": null,"ec2_ebs_volume_encryption": "PASS","iam_user_accesskey_unused": null,"ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","ec2_instance_profile_attached": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","iam_user_mfa_enabled_console_access": null,"s3_bucket_policy_public_write_access": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","iam_password_policy_minimum_length_14": null,"s3_account_level_public_access_blocks": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_6_a","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Configuration Settings (CM-6)"}],"description": "Establish and document configuration settings for components employed within the system that reflect the most restrictive mode consistent with operational requirements using [Assignment: organization-defined common secure configurations].","checks_status": {"fail": 8,"pass": 6,"total": 31,"manual": 0}},"cm_7_b": {"name": "CM-7(b)","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_7_b","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Least Functionality (CM-7)"}],"description": "Prohibit or restrict the use of the following functions, ports, protocols, software, and/or services: [Assignment: organization-defined prohibited or restricted functions, system ports, protocols, software, and/or services].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cm_8_1": {"name": "CM-8(1) Updates During Installation And Removals","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_1","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "System Component Inventory (CM-8)"}],"description": "Update the inventory of system components as part of component installations, removals, and system updates.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_8_2": {"name": "CM-8(2) Automated Maintenance","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_2","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "System Component Inventory (CM-8)"}],"description": "Maintain the currency, completeness, accuracy, and availability of the inventory of system components using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cm_8_6": {"name": "CM-8(6) Assessed Configurations And Approved Deviations","checks": {"elbv2_deletion_protection": "FAIL","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_6","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "System Component Inventory (CM-8)"}],"description": "Include assessed component configurations and any approved deviations to current deployed configurations in the system component inventory.","checks_status": {"fail": 5,"pass": 0,"total": 5,"manual": 0}},"cm_8_a": {"name": "CM-8(a)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_a","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "System Component Inventory (CM-8)"}],"description": "Develop and document an inventory of system components that: 1. Accurately reflects the system; 2. Includes all components within the system; 3. Does not include duplicate accounting of components or components assigned to any other system; 4. Is at the level of granularity deemed necessary for tracking and reporting; and 5. Includes the following information to achieve system component accountability: [Assignment: organization-defined information deemed necessary to achieve effective system component accountability].","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_8_b": {"name": "CM-8(b)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_b","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "System Component Inventory (CM-8)"}],"description": "Review and update the system component inventory [Assignment: organization-defined frequency].","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_9_b": {"name": "CM-9(b)","checks": {"iam_root_mfa_enabled": null,"vpc_flow_logs_enabled": "FAIL","iam_no_root_access_key": null,"s3_bucket_public_access": null,"kms_cmk_rotation_enabled": null,"ec2_ebs_volume_encryption": "PASS","iam_user_accesskey_unused": null,"ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","iam_user_mfa_enabled_console_access": null,"s3_bucket_policy_public_write_access": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","iam_password_policy_minimum_length_14": null,"s3_account_level_public_access_blocks": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_9_b","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Configuration Management Plan (CM-9)"}],"description": "Develop, document, and implement a configuration management plan for the system that: b. Establishes a process for identifying configuration items throughout the system development life cycle and for managing the configuration of the configuration items.","checks_status": {"fail": 8,"pass": 6,"total": 31,"manual": 0}},"cp_1_2": {"name": "CP-1(2)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_1_2","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Policy And Procedures (CP-1)"}],"description": "Implement transaction recovery for systems that are transaction-based.","checks_status": {"fail": 2,"pass": 1,"total": 6,"manual": 0}},"cp_2_5": {"name": "CP-2(5) Continue Mission And Business Functions","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL","redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_2_5","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Contingency Plan (CP-2)"}],"description": "Plan for the continuance of [Selection: all; essential] mission and business functions with minimal or no loss of operational continuity and sustains that continuity until full system restoration at primary processing and/or storage sites.","checks_status": {"fail": 5,"pass": 1,"total": 9,"manual": 0}},"cp_2_6": {"name": "CP-2(6) Alternate Processing And Storage Sites","checks": {"rds_instance_multi_az": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_2_6","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Contingency Plan (CP-2)"}],"description": "Plan for the transfer of [Selection: all; essential] mission and business functions to alternate processing and/or storage sites with minimal or no loss of operational continuity and sustain that continuity through system restoration to primary processing and/or storage sites.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cp_2_a": {"name": "CP-2(a)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_2_a","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Contingency Plan (CP-2)"}],"description": "a. Develop a contingency plan for the system that: 1. Identifies essential mission and business functions and associated contingency requirements; 2. Provides recovery objectives, restoration priorities, and metrics; 3. Addresses contingency roles, responsibilities, assigned individuals with contact information; 4. Addresses maintaining essential mission and business functions despite a system disruption, compromise, or failure; 5. Addresses eventual, full system restoration without deterioration of the controls originally planned and implemented; 6. Addresses the sharing of contingency information; and 7. Is reviewed and approved by [Assignment: organization-defined personnel or roles]","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"cp_2_d": {"name": "CP-2(d)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_2_d","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Contingency Plan (CP-2)"}],"description": "Review the contingency plan for the system [Assignment: organization-defined frequency]","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"cp_2_e": {"name": "CP-2(e)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_2_e","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Contingency Plan (CP-2)"}],"description": "Update the contingency plan to address changes to the organization, system, or environment of operation and problems encountered during contingency plan implementation, execution, or testing.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"cp_6_1": {"name": "CP-6(1) Separation From Primary Site","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_6_1","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Alternate Storage Sites (CP-6)"}],"description": "Identify an alternate storage site that is sufficiently separated from the primary storage site to reduce susceptibility to the same threats.","checks_status": {"fail": 2,"pass": 1,"total": 5,"manual": 0}},"cp_6_2": {"name": "CP-6(2) Recovery Time And Recovery Point Objectives","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_6_2","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Alternate Storage Sites (CP-6)"}],"description": "Configure the alternate storage site to facilitate recovery operations in accordance with recovery time and recovery point objectives.","checks_status": {"fail": 3,"pass": 1,"total": 7,"manual": 0}},"cp_6_a": {"name": "CP-6(a)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_6_a","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Alternate Storage Sites (CP-6)"}],"description": "Establish an alternate storage site, including necessary agreements to permit the storage and retrieval of system backup information.","checks_status": {"fail": 2,"pass": 1,"total": 5,"manual": 0}},"cp_9_8": {"name": "CP-9(8) Cryptographic Protection","checks": {"s3_bucket_default_encryption": "PASS","rds_instance_storage_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_9_8","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "System Backup (CP-9)"}],"description": "Implement cryptographic mechanisms to prevent unauthorized disclosure and modification of [Assignment: organization-defined backup information].","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"cp_9_a": {"name": "CP-9(a)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null,"redshift_cluster_automatic_upgrades": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_9_a","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "System Backup (CP-9)"}],"description": "Conduct backups of user-level information contained in [Assignment: organization-defined system components] [Assignment: organization-defined frequency consistent with recovery time and recovery point objectives].","checks_status": {"fail": 2,"pass": 1,"total": 7,"manual": 0}},"cp_9_b": {"name": "CP-9(b)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null,"redshift_cluster_automatic_upgrades": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_9_b","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "System Backup (CP-9)"}],"description": "Conduct backups of system-level information contained in the system [Assignment: organization-defined frequency consistent with recovery time and recovery point objectives].","checks_status": {"fail": 2,"pass": 1,"total": 7,"manual": 0}},"cp_9_c": {"name": "CP-9(c)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null,"redshift_cluster_automatic_upgrades": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_9_c","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "System Backup (CP-9)"}],"description": "Conduct backups of system documentation, including security- and privacy-related documentation [Assignment: organization-defined frequency consistent with recovery time and recovery point objectives].","checks_status": {"fail": 2,"pass": 1,"total": 7,"manual": 0}},"cp_9_d": {"name": "CP-9(d)","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_9_d","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "System Backup (CP-9)"}],"description": "Protect the confidentiality, integrity, and availability of backup information.","checks_status": {"fail": 5,"pass": 3,"total": 13,"manual": 0}},"ia_2_1": {"name": "IA-2(1) Multi-Factor Authentication To Privileged Accounts","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2_1","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "Implement multi-factor authentication for access to privileged accounts.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ia_2_2": {"name": "IA-2(2) Multi-Factor Authentication To Non-Privileged Accounts","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2_2","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "Implement multi-factor authentication for access to non-privileged accounts.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ia_2_6": {"name": "IA-2(6) Acces To Accounts — Separate Device","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2_6","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "Implement multi-factor authentication for [Selection (one or more): local; network; remote] access to [Selection (one or more): privileged accounts; non-privileged accounts] such that: (a) One of the factors is provided by a device separate from the system gaining access; and (b) The device meets [Assignment: organization-defined strength of mechanism requirements].","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ia_2_8": {"name": "IA-2(8) Access To Accounts — Replay Resistant","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2_8","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "Implement replay-resistant authentication mechanisms for access to [Selection (one or more): privileged accounts; non-privileged accounts].","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ia_4_4": {"name": "IA-4(4)","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_4_4","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identifier Management (IA-4)"}],"description": "Manage individual identifiers by uniquely identifying each individual as [Assignment: organization-defined characteristic identifying individual status].","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_4_8": {"name": "IA-4(8)","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_4_8","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identifier Management (IA-4)"}],"description": "Generate pairwise pseudonymous identifiers.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_4_b": {"name": "IA-4(b)","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_4_b","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identifier Management (IA-4)"}],"description": "Manage system identifiers by: b. Selecting an identifier that identifies an individual, group, role, service, or device.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_4_d": {"name": "IA-4(d)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_4_d","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identifier Management (IA-4)"}],"description": "Manage system identifiers by: d. Preventing reuse of identifiers for [Assignment: organization-defined time period].","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_8": {"name": "IA-5(8) Multiple System Accounts","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_8","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": null}],"description": "Implement [Assignment: organization-defined security controls] to manage the risk of compromise due to individuals having accounts on multiple systems.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_b": {"name": "IA-5(b)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_b","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "Manage system authenticators by: b. Establishing initial authenticator content for any authenticators issued by the organization.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_c": {"name": "IA-5(c)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_c","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "Manage system authenticators by: c. Ensuring that authenticators have sufficient strength of mechanism for their intended use.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_d": {"name": "IA-5(d)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_d","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "Manage system authenticators by: d. Establishing and implementing administrative procedures for initial authenticator distribution, for lost or compromised or damaged authenticators, and for revoking authenticators.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_f": {"name": "IA-5(f)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_f","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "Manage system authenticators by: f. Changing or refreshing authenticators [Assignment: organization-defined time period by authenticator type] or when [Assignment: organization-defined events] occur.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_h": {"name": "IA-5(h)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_h","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "Manage system authenticators by: h. Requiring individuals to take, and having devices implement, specific controls to protect authenticators.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ir_4_a": {"name": "IR-4(a)","checks": {"guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ir_4_a","Section": "Incident Response (IR)","Service": "guarduty","SubGroup": null,"SubSection": "Incident Handling (IR-4)"}],"description": "Implement an incident handling capability for incidents that is consistent with the incident response plan and includes preparation, detection and analysis, containment, eradication, and recovery.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ma_4_c": {"name": "MA-4(c)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ma_4_c","Section": "Maintenance (MA)","Service": "iam","SubGroup": null,"SubSection": "Nonlocal Maintenance (MA-4)"}],"description": "Employ strong authentication in the establishment of nonlocal maintenance and diagnostic sessions.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"pe_6_2": {"name": "PE-6(2) Monitoring Physical Access","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "pe_6_2","Section": "Physical And Environmental Protection (PE)","Service": "guarduty","SubGroup": null,"SubSection": "Monitoring Physical Access (PE-6)"}],"description": "Recognize [Assignment: organization-defined classes or types of intrusions] and initiate [Assignment: organization-defined response actions] using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"pe_6_4": {"name": "PE-6(4) Monitoring Physical Access","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "pe_6_4","Section": "Physical And Environmental Protection (PE)","Service": "guarduty","SubGroup": null,"SubSection": "Monitoring Physical Access (PE-6)"}],"description": "Monitor physical access to the system in addition to the physical access monitoring of the facility at [Assignment: organization-defined physical spaces containing one or more components of the system].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ra_1_a": {"name": "RA-1(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_1_a","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": null,"SubSection": "Policy And Procedures (RA-1)"}],"description": "Establish and maintain a cyber threat hunting capability to: 1. Search for indicators of compromise in organizational systems; and 2. Detect, track, and disrupt threats that evade existing controls.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ra_3_4": {"name": "RA-3(4) Predictive Cyber Analytics","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_3_4","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": null,"SubSection": "Risk Assessment (RA-3)"}],"description": "Employ the following advanced automation and analytics capabilities to predict and identify risks to [Assignment: organization-defined systems or system components]: [Assignment: organization-defined advanced automation and analytics capabilities].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ra_5_4": {"name": "RA-5(4) Discoverable Information","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_5_4","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": null,"SubSection": "Vulnerability Monitoring And Scanning (RA-5)"}],"description": "Determine information about the system that is discoverable and take [Assignment: organization-defined corrective actions].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ra_5_a": {"name": "RA-5(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_5_a","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": null,"SubSection": "Vulnerability Monitoring And Scanning (RA-5)"}],"description": "Monitor and scan for vulnerabilities in the system and hosted applications [Assignment: organization-defined frequency and/or randomly in accordance with organization-defined process] and when new vulnerabilities potentially affecting the system are identified and reported.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sa_1_1": {"name": "SA-1(1)","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sa_1_1","Section": "System and Services Acquisition (SA)","Service": "cloudtrail","SubGroup": null,"SubSection": "Policy And Procedures (SA-1)"}],"description": "Require the developer of the system, system component, or system service to enable integrity verification of software and firmware components.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sa_9_6": {"name": "SA-9(6) Organization-Controlled Cryptographic Keys","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sa_9_6","Section": "System and Services Acquisition (SA)","Service": "kms","SubGroup": null,"SubSection": "External System Services (SA-9)"}],"description": "Maintain exclusive control of cryptographic keys for encrypted material stored or transmitted through an external system.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"sc_5_1": {"name": "SC-5(1) Restrict Ability TO Attack Other Systems","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_5_1","Section": "System and Communications Protection (SC)","Service": "guarduty","SubGroup": null,"SubSection": "Denial Of Service Protection (SC-5)"}],"description": "Restrict the ability of individuals to launch the following denial-of-service attacks against other systems: [Assignment: organization-defined denial-of-service attacks].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sc_5_2": {"name": "SC-5(2) Capacity, Bandwidth, And Redundancy","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL","redshift_cluster_automated_snapshot": null,"redshift_cluster_automatic_upgrades": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_5_2","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Denial Of Service Protection (SC-5)"}],"description": "Manage capacity, bandwidth, or other redundancy to limit the effects of information flooding denial-of-service attacks.","checks_status": {"fail": 5,"pass": 1,"total": 10,"manual": 0}},"sc_5_a": {"name": "SC-5(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_5_a","Section": "System and Communications Protection (SC)","Service": "guarduty","SubGroup": null,"SubSection": "Denial Of Service Protection (SC-5)"}],"description": "[Selection: Protect against; Limit] the effects of the following types of denial-of-service events: [Assignment: organization-defined types of denial-of-service events].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sc_5_b": {"name": "SC-5(b)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_5_b","Section": "System and Communications Protection (SC)","Service": "guarduty","SubGroup": null,"SubSection": "Denial Of Service Protection (SC-5)"}],"description": "Employ the following controls to achieve the denial-of-service objective: [Assignment: organization-defined controls by type of denial-of-service event].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sc_7_2": {"name": "SC-7(2) Public Access","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_2","Section": "System and Communications Protection (SC)","Service": "guarduty","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Provide the capability to dynamically isolate [Assignment: organization-defined system components] from other system components.","checks_status": {"fail": 1,"pass": 5,"total": 13,"manual": 0}},"sc_7_3": {"name": "SC-7(3) Access Points","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_3","Section": "System and Communications Protection (SC)","Service": "guarduty","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Limit the number of external network connections to the system.","checks_status": {"fail": 1,"pass": 5,"total": 13,"manual": 0}},"sc_7_5": {"name": "SC-7(5) Deny By Default — Allow By Exception","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_5","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Deny network communications traffic by default and allow network communications traffic by exception [Selection (one or more): at managed interfaces; for [Assignment: organization-defined systems]].","checks_status": {"fail": 5,"pass": 0,"total": 6,"manual": 0}},"sc_7_7": {"name": "SC-7(7) Split Tunneling For Remote Devices","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_7","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Prevent split tunneling for remote devices connecting to organizational systems unless the split tunnel is securely provisioned using [Assignment: organization-defined safeguards].","checks_status": {"fail": 3,"pass": 5,"total": 16,"manual": 0}},"sc_7_a": {"name": "SC-7(a)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_a","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Monitor and control communications at the external managed interfaces to the system and at key internal managed interfaces within the system.","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"sc_7_b": {"name": "SC-7(b)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_b","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Implement subnetworks for publicly accessible system components that are [Selection: physically; logically] separated from internal organizational networks.","checks_status": {"fail": 1,"pass": 5,"total": 13,"manual": 0}},"sc_7_c": {"name": "SC-7(c)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_c","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Connect to external networks or systems only through managed interfaces consisting of boundary protection devices arranged in accordance with an organizational security and privacy architecture.","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"sc_8_1": {"name": "SC-8(1) Cryptographic Protection","checks": {"elb_ssl_listeners": "FAIL","elbv2_insecure_ssl_ciphers": "PASS","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_8_1","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Transmission Confidentiality And Integrity (SC-8)"}],"description": "Implement cryptographic mechanisms to [Selection (one or more): prevent unauthorized disclosure of information; detect changes to information] during transmission.","checks_status": {"fail": 3,"pass": 1,"total": 5,"manual": 0}},"sc_8_2": {"name": "SC-8(2) Pre- And Post-Transmission Handling","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_8_2","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Transmission Confidentiality And Integrity (SC-8)"}],"description": "Maintain the [Selection (one or more): confidentiality; integrity] of information during preparation for transmission and during reception.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"sc_8_3": {"name": "SC-8(3) Cryptographic Protection For Message Externals","checks": {"elb_ssl_listeners": "FAIL","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_8_3","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Transmission Confidentiality And Integrity (SC-8)"}],"description": "Implement cryptographic mechanisms to protect message externals unless otherwise protected by [Assignment: organization-defined alternative physical controls].","checks_status": {"fail": 8,"pass": 3,"total": 18,"manual": 0}},"sc_8_4": {"name": "SC-8(4) Conceal Or Ramdomize Communications","checks": {"elb_ssl_listeners": "FAIL","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_8_4","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Transmission Confidentiality And Integrity (SC-8)"}],"description": "Implement cryptographic mechanisms to conceal or randomize communication patterns unless otherwise protected by [Assignment: organization-defined alternative physical controls].","checks_status": {"fail": 8,"pass": 3,"total": 18,"manual": 0}},"sc_8_5": {"name": "SC-8(5) Protected Distribution System","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_8_5","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Transmission Confidentiality And Integrity (SC-8)"}],"description": "Implement [Assignment: organization-defined protected distribution system] to [Selection (one or more): prevent unauthorized disclosure of information; detect changes to information] during transmission.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"si_2_2": {"name": "SI-2(2) Automated Flaw Remediation Status","checks": {"ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_2_2","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Flaw Remediation (SI-2)"}],"description": "Determine if system components have applicable security-relevant software and firmware updates installed using [Assignment: organization-defined automated mechanisms] [Assignment: organization-defined frequency].","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"si_2_5": {"name": "SI-2(5) Automatic Software And Firmware Updated","checks": {"ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_2_5","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Flaw Remediation (SI-2)"}],"description": "Install [Assignment: organization-defined security-relevant software and firmware updates] automatically to [Assignment: organization-defined system components].","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"si_2_a": {"name": "SI-2(a)","checks": {"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_2_a","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Flaw Remediation (SI-2)"}],"description": "Identify, report, and correct system flaws.","checks_status": {"fail": 1,"pass": 0,"total": 5,"manual": 0}},"si_2_c": {"name": "SI-2(c)","checks": {"ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_2_c","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Flaw Remediation (SI-2)"}],"description": "Install security-relevant software and firmware updates within [Assignment: organization-defined time period] of the release of the updates.","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"si_2_d": {"name": "SI-2(d)","checks": {"ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_2_d","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Flaw Remediation (SI-2)"}],"description": "Incorporate flaw remediation into the organizational configuration management process.","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"si_4_1": {"name": "SI-4(1) System-Wide Intrusion Detection System","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_1","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Connect and configure individual intrusion detection tools into a system-wide intrusion detection system.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_2": {"name": "SI-4(2) Automated Tools For Real-Time Analysis","checks": {"guardduty_is_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_4_2","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Implement the following additional monitoring of privileged users: [Assignment: organization-defined additional monitoring]. Employ automated tools and mechanisms to support near real-time analysis of events.","checks_status": {"fail": 3,"pass": 2,"total": 9,"manual": 0}},"si_4_3": {"name": "SI-4(3) Automated Tools And Mechanism Integration","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_3","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Employ automated tools and mechanisms to integrate intrusion detection tools and mechanisms into access control and flow control mechanisms.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_a": {"name": "SI-4(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_a","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Monitor the system to detect: 1. Attacks and indicators of potential attacks in accordance with the following monitoring objectives: [Assignment: organization-defined monitoring objectives]; and 2. Unauthorized local, network, and remote connections.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_b": {"name": "SI-4(b)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_b","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Identify unauthorized use of the system through the following techniques and methods: [Assignment: organization-defined techniques and methods].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_c": {"name": "SI-4(c)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_c","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "c. Invoke internal monitoring capabilities or deploy monitoring devices: 1. Strategically within the system to collect organization-determined essential information; and 2. At ad hoc locations within the system to track specific types of transactions of interest to the organization.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_d": {"name": "SI-4(d)","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_4_d","Section": "System and Information integrity (SI)","Service": "cloudtrail","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Analyze detected events and anomalies.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"si_5_1": {"name": "SI-5(1) Automated Alerts And Advisories","checks": {"guardduty_is_enabled": "PASS","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_5_1","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Secuity Alerts, Advisories, And Directives (SI-5)"}],"description": "Broadcast security alert and advisory information throughout the organization using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 0,"pass": 1,"total": 5,"manual": 0}},"si_5_b": {"name": "SI-5(b)","checks": {"guardduty_is_enabled": "PASS","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_5_b","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Secuity Alerts, Advisories, And Directives (SI-5)"}],"description": "Generate internal security alerts, advisories, and directives as deemed necessary.","checks_status": {"fail": 0,"pass": 1,"total": 5,"manual": 0}},"si_7_1": {"name": "SI-7(1) Integrity Checks","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_7_1","Section": "System and Information integrity (SI)","Service": "cloudtrail","SubGroup": null,"SubSection": "Software, Firmware, and Information Integrity (SI-7)"}],"description": "Perform an integrity check of [Assignment: organization-defined software, firmware, and information] [Selection (one or more): at startup; at [Assignment: organization-defined transitional states or security-relevant events]; [Assignment: organization-defined frequency]].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"si_7_3": {"name": "SI-7(3) Centrally Managed Integrity Tools","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_7_3","Section": "System and Information integrity (SI)","Service": "cloudtrail","SubGroup": null,"SubSection": "Software, Firmware, and Information Integrity (SI-7)"}],"description": "Employ centrally managed integrity verification tools.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"si_7_7": {"name": "SI-7(7) Integration Of Detection And Response","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_7_7","Section": "System and Information integrity (SI)","Service": "cloudtrail","SubGroup": null,"SubSection": "Software, Firmware, and Information Integrity (SI-7)"}],"description": "Incorporate the detection of the following unauthorized changes into the organizational incident response capability: [Assignment: organization-defined security-relevant changes to the system].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"si_7_8": {"name": "SI-7(8) Auditing Capability For Significant Events","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_7_8","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Software, Firmware, and Information Integrity (SI-7)"}],"description": "Upon detection of a potential integrity violation, provide the capability to audit the event and initiate the following actions: [Selection (one or more): generate an audit record; alert current user; alert [Assignment: organization-defined personnel or roles]; [Assignment: organization-defined other actions]].","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"si_7_a": {"name": "SI-7(a)","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_7_a","Section": "System and Information integrity (SI)","Service": "cloudtrail","SubGroup": null,"SubSection": "Software, Firmware, and Information Integrity (SI-7)"}],"description": "Employ integrity verification tools to detect unauthorized changes to the following software, firmware, and information: [Assignment: organization-defined software, firmware, and information].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ac_16_b": {"name": "AC-16(b)","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_16_b","Section": "Access Control (AC)","Service": "cloudwatch","SubGroup": null,"SubSection": "Security And Privacy Attributes (AC-16)"}],"description": "Ensure that the attribute associations are made and retained with the information.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ac_17_1": {"name": "AC-17(1) Monitoring And Control","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_17_1","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Remote Access (AC-17)"}],"description": "Employ automated mechanisms to monitor and control remote access methods.","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"ac_17_2": {"name": "AC-17(2) Protection Of Confidentiality And Integrity Using Encryption","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_17_2","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Remote Access (AC-17)"}],"description": "Implement cryptographic mechanisms to protect the confidentiality and integrity of remote access sessions.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"ac_17_9": {"name": "AC-17(9) Disconnect Or Disable Access","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_17_9","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Remote Access (AC-17)"}],"description": "Provide the capability to disconnect or disable remote access to the system within [Assignment: organization-defined time period].","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"ac_17_b": {"name": "AC-17(b)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_17_b","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Remote Access (AC-17)"}],"description": "Authorize each type of remote access to the system prior to allowing such connections.","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"ac_24_1": {"name": "AC-24(1)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_24_1","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Access Control Decisions (AC-24)"}],"description": "Transmit [Assignment: organization-defined access authorization information] using [Assignment: organization-defined controls] to [Assignment: organization-defined systems] that enforce access control decisions.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"ac_3_10": {"name": "AC-3(10) Audited Override Of Access Control Mechanisms","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_10","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Access Enforcement (AC-3)"}],"description": "Employ an audited override of automated access mechanisms under [Assignment: organization-defined conditions] by [Assignment: organization-defined roles].","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"ac_3_13": {"name": "AC-3(13) Attribute-Based Access Control","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_13","Section": "Access Control (AC)","Service": "guarduty","SubGroup": null,"SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce attribute-based access control policy over defined subjects and objects and control access based upon [Assignment: organization-defined attributes to assume access permissions].","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_4_21": {"name": "AC-4(21) Physical Or Logical Separation Of Infomation Flows","checks": {"ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"apigateway_restapi_waf_acl_attached": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_4_21","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Information Flow Enforcement (AC-4)"}],"description": "Separate information flows logically or physically using [Assignment: organization-defined mechanisms and/or techniques] to accomplish [Assignment: organization-defined required separations by types of information].","checks_status": {"fail": 5,"pass": 5,"total": 18,"manual": 0}},"ac_4_22": {"name": "AC-4(22) Access Only","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_4_22","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Information Flow Enforcement (AC-4)"}],"description": "Provide access from a single device to computing platforms, applications, or data residing in multiple different security domains, while preventing information flow between the different security domains.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"ac_4_26": {"name": "AC-4(26) Audit Filtering Actions","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_4_26","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Information Flow Enforcement (AC-4)"}],"description": "When transferring information between different security domains, record and audit content filtering actions and results for the information being filtered.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"ac_4_28": {"name": "AC-4(28) Linear Filter Pipelines","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_4_28","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Information Flow Enforcement (AC-4)"}],"description": "When transferring information between different security domains, implement a linear content filter pipeline that is enforced with discretionary and mandatory access controls.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_6_10": {"name": "AC-6(10)","checks": {"iam_no_root_access_key": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_6_10","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Least Privilege (AC-6)"}],"description": "Prevent non-privileged users from executing privileged functions.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"au_11_1": {"name": "AU-11(1) Long-Term Retrieval Capability","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_11_1","Section": "Audit and Accountability (AU)","Service": "cloudwatch","SubGroup": null,"SubSection": "Audit Record Retention (AU-11)"}],"description": "Employ [Assignment: organization-defined measures] to ensure that long-term audit records generated by the system can be retrieved.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"au_12_1": {"name": "AU-12(1) System-Wide And Time-Correlated Audit Trial","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_12_1","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Generation (AU-12)"}],"description": "Compile audit records from [Assignment: organization-defined system components] into a system-wide (logical or physical) audit trail that is time-correlated to within [Assignment: organization-defined level of tolerance for the relationship between time stamps of individual records in the audit trail].","checks_status": {"fail": 7,"pass": 2,"total": 13,"manual": 0}},"au_12_2": {"name": "AU-12(2) Standardized Formats","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_12_2","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Generation (AU-12)"}],"description": "Produce a system-wide (logical or physical) audit trail composed of audit records in a standardized format.","checks_status": {"fail": 7,"pass": 2,"total": 13,"manual": 0}},"au_12_3": {"name": "AU-12(3) Changes By Authorized Individuals","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_12_3","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Generation (AU-12)"}],"description": "Provide and implement the capability for [Assignment: organization-defined individuals or roles] to change the logging to be performed on [Assignment: organization-defined system components] based on [Assignment: organization-defined selectable event criteria] within [Assignment: organization-defined time thresholds].","checks_status": {"fail": 8,"pass": 4,"total": 20,"manual": 0}},"au_12_4": {"name": "AU-12(4) Query Parameter Audits Of Personally Identifiable Information","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_12_4","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Generation (AU-12)"}],"description": "Provide and implement the capability for auditing the parameters of user query events for data sets containing personally identifiable information.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_12_a": {"name": "AU-12(a)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_12_a","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Generation (AU-12)"}],"description": "Provide audit record generation capability for the event types the system is capable of auditing as defined in AU-2a on [Assignment: organization-defined system components].","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_12_c": {"name": "AU-12(c)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_12_c","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Record Generation (AU-12)"}],"description": "Generate audit records for the event types defined in AU-2c that include the audit record content defined in AU-3.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_14_3": {"name": "AU-14(3) Remote Viewing And Listening","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_14_3","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Session Audit (AU-14)"}],"description": "Provide and implement the capability for authorized users to remotely view and hear content related to an established user session in real time.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au_14_a": {"name": "AU-14(a)","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_14_a","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Session Audit (AU-14)"}],"description": "Provide and implement the capability for [Assignment: organization-defined users or roles] to [Selection (one or more): record; view; hear; log] the content of a user session under [Assignment: organization-defined circumstances].","checks_status": {"fail": 8,"pass": 4,"total": 20,"manual": 0}},"au_14_b": {"name": "AU-14(b)","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au_14_b","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Session Audit (AU-14)"}],"description": "Develop, integrate, and use session auditing activities in consultation with legal counsel and in accordance with applicable laws, executive orders, directives, regulations, policies, standards, and guidelines.","checks_status": {"fail": 8,"pass": 4,"total": 20,"manual": 0}},"cm_12_b": {"name": "CM-12(b)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "cm_12_b","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Information Location (CM-12)"}],"description": "Identify and document the users who have access to the system and system components where the information is processed and stored.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"cp_10_2": {"name": "CP-10(2) Transaction Recovery","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_10_2","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "System Recovery And Reconstitution (CP-10)"}],"description": "Implement transaction recovery for systems that are transaction-based.","checks_status": {"fail": 2,"pass": 1,"total": 6,"manual": 0}},"pm_11_b": {"name": "PM-11(b)","checks": {"s3_bucket_object_versioning": "FAIL","s3_bucket_default_encryption": "PASS","s3_bucket_secure_transport_policy": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pm_11_b","Section": "Program Management (PM)","Service": "aws","SubGroup": null,"SubSection": "Mission And Business Process Defination (PM-11)"}],"description": "Determine information protection and personally identifiable information processing needs arising from the defined mission and business processes.","checks_status": {"fail": 3,"pass": 1,"total": 4,"manual": 0}},"pm_14_b": {"name": "PM-14(b)","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pm_14_b","Section": "Program Management (PM)","Service": "aws","SubGroup": null,"SubSection": "Testing, Training, And Monitoring (PM-14)"}],"description": "Review testing, training, and monitoring plans for consistency with the organizational risk management strategy and organization-wide priorities for risk response actions.","checks_status": {"fail": 8,"pass": 4,"total": 20,"manual": 0}},"pm_17_b": {"name": "PM-17(b)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_object_versioning": "FAIL","s3_bucket_secure_transport_policy": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pm_17_b","Section": "Program Management (PM)","Service": "aws","SubGroup": null,"SubSection": "Protecting Controlled Unclassified Information On External Systems (PM-17)"}],"description": "Review and update the policy and procedures [Assignment: organization-defined frequency].","checks_status": {"fail": 5,"pass": 0,"total": 6,"manual": 0}},"pm_21_b": {"name": "PM-21(b)","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pm_21_b","Section": "Program Management (PM)","Service": "cloudwatch","SubGroup": null,"SubSection": "Accounting Of Disclosures (PM-21)"}],"description": "Retain the accounting of disclosures for the length of the time the personally identifiable information is maintained or five years after the disclosure is made, whichever is longer.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"ra_10_a": {"name": "RA-10(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_10_a","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": null,"SubSection": "Threat Hunting (RA-10)"}],"description": "Establish and maintain a cyber threat hunting capability to: 1. Search for indicators of compromise in organizational systems; and 2. Detect, track, and disrupt threats that evade existings.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sa_10_1": {"name": "SA-10(1) Software And Firmware Integrity Verification","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sa_10_1","Section": "System and Services Acquisition (SA)","Service": "kms","SubGroup": null,"SubSection": "Developer Configuration Management (SA-10)"}],"description": "Require the developer of the system, system component, or system service to enable integrity verification of software and firmware components.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sc_12_2": {"name": "SC-12(2) Symmetric Keys","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_12_2","Section": "System and Communications Protection (SC)","Service": "kms","SubGroup": null,"SubSection": "Cryptographic Key Establishment And Management (SC-12)"}],"description": "Produce, control, and distribute symmetric cryptographic keys using [Selection: NIST FIPS-validated; NSA-approved] key management technology and processes.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"sc_12_6": {"name": "SC-12(6) Physical Control Of Keys","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_12_6","Section": "System and Communications Protection (SC)","Service": "kms","SubGroup": null,"SubSection": "Cryptographic Key Establishment And Management (SC-12)"}],"description": "Maintain physical control of cryptographic keys when stored information is encrypted by external service providers.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"sc_13_a": {"name": "SC-13(a)","checks": {"elb_ssl_listeners": "FAIL","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_13_a","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Cryptographic Protection (SC-13)"}],"description": "Determine the [Assignment: organization-defined cryptographic uses].","checks_status": {"fail": 8,"pass": 3,"total": 18,"manual": 0}},"sc_16_1": {"name": "SC-16(1) Integrity Verification","checks": {"s3_bucket_object_versioning": "FAIL","s3_bucket_default_encryption": "PASS","s3_bucket_secure_transport_policy": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_16_1","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Transmission Of Security And Privacy Attributes (SC-16)"}],"description": "Verify the integrity of transmitted security and privacy attributes.","checks_status": {"fail": 3,"pass": 1,"total": 4,"manual": 0}},"sc_23_3": {"name": "SC-23(3) Unique System-Generated Session Identifiers","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_23_3","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Session Authenticity (SC-23)"}],"description": "Generate a unique session identifier for each session with [Assignment: organization-defined randomness requirements] and recognize only session identifiers that are system-generated.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"sc_23_5": {"name": "SC-23(5) Allowed Certificate Authorities","checks": {"elb_ssl_listeners": "FAIL","elbv2_insecure_ssl_ciphers": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_23_5","Section": "System and Communications Protection (SC)","Service": "elb","SubGroup": null,"SubSection": "Session Authenticity (SC-23)"}],"description": "Only allow the use of [Assignment: organization-defined certificate authorities] for verification of the establishment of protected sessions.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"sc_28_1": {"name": "SC-28(1) Cryptographic Protection","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_28_1","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Protection Of Information At Rest (SC-28)"}],"description": "Implement cryptographic mechanisms to prevent unauthorized disclosure and modification of the following information at rest on [Assignment: organization-defined system components or media]: [Assignment: organization-defined information].","checks_status": {"fail": 5,"pass": 3,"total": 14,"manual": 0}},"sc_28_2": {"name": "SC-28(2) Offline Storage","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_28_2","Section": "System and Communications Protection (SC)","Service": "cloudwatch","SubGroup": null,"SubSection": "Protection Of Information At Rest (SC-28)"}],"description": "Remove the following information from online storage and store offline in a secure location: [Assignment: organization-defined information].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sc_43_b": {"name": "SC-43(b)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_43_b","Section": "System and Communications Protection (SC)","Service": "guarduty","SubGroup": null,"SubSection": "Usage Restrictions (SC-43)"}],"description": "Authorize, monitor, and control the use of such components within the system.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sc_7_11": {"name": "SC-7(11) Restrict Incoming communications Traffic","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_11","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Only allow incoming communications from [Assignment: organization-defined authorized sources] to be routed to [Assignment: organization-defined authorized destinations].","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"sc_7_12": {"name": "SC-7(12) Host-Based Protection","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"acm_certificates_expiration_check": "PASS","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_12","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Implement [Assignment: organization-defined host-based boundary protection mechanisms] at [Assignment: organization-defined system components].","checks_status": {"fail": 3,"pass": 7,"total": 17,"manual": 0}},"sc_7_16": {"name": "SC-7(16) Prevent Discovery Of System Components","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"acm_certificates_expiration_check": "PASS","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_16","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Prevent the discovery of specific system components that represent a managed interface.","checks_status": {"fail": 3,"pass": 7,"total": 17,"manual": 0}},"sc_7_20": {"name": "SC-7(20) Prevent Discovery Of System Components","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_20","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Prevent the discovery of specific system components that represent a managed interface.","checks_status": {"fail": 1,"pass": 5,"total": 13,"manual": 0}},"sc_7_21": {"name": "SC-7(21) Isolation Of System Components","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_21","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Employ boundary protection mechanisms to isolate [Assignment: organization-defined system components] supporting [Assignment: organization-defined missions and/or business functions].","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"sc_7_25": {"name": "SC-7(25) Unclassified National Security System Connections","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_25","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Prohibit the direct connection of [Assignment: organization-defined unclassified national security system] to an external network without the use of [Assignment: organization-defined boundary protection device].","checks_status": {"fail": 3,"pass": 5,"total": 15,"manual": 0}},"sc_7_26": {"name": "SC-7(26) Classified National Security System Connections","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_26","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Prohibit the direct connection of a classified national security system to an external network without the use of [Assignment: organization-defined boundary protection device].","checks_status": {"fail": 3,"pass": 5,"total": 15,"manual": 0}},"sc_7_27": {"name": "SC-7(27) Unclassified Non-National Security System Connections","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_27","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Prohibit the direct connection of [Assignment: organization-defined unclassified non-national security system] to an external network without the use of [Assignment: organization-defined boundary protection device].","checks_status": {"fail": 3,"pass": 5,"total": 15,"manual": 0}},"sc_7_28": {"name": "SC-7(28) Connections To Public Networks","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_28","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "Prohibit the direct connection of [Assignment: organization-defined system] to a public network.","checks_status": {"fail": 3,"pass": 5,"total": 15,"manual": 0}},"si_13_5": {"name": "SI-13(5) Failover Capability","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL","redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_13_5","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Predictable Failure Prevention (SI-13)"}],"description": "Provide [Selection: real-time; near real-time] [Assignment: organization-defined failover capability] for the system.","checks_status": {"fail": 4,"pass": 1,"total": 8,"manual": 0}},"si_19_4": {"name": "SI-19(4) Removal, Masking, Encryption, Hashing, Or Replacement Of Direct Identifiers","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_19_4","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "De-Identification (SI-19)"}],"description": "Remove, mask, encrypt, hash, or replace direct identifiers in a dataset.","checks_status": {"fail": 4,"pass": 3,"total": 13,"manual": 0}},"si_4_10": {"name": "SI-4(10) Visibility Of Encrypted Communications","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_10","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Make provisions so that [Assignment: organization-defined encrypted communications traffic] is visible to [Assignment: organization-defined system monitoring tools and mechanisms].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_12": {"name": "SI-4(12) Automated Organization-Generated Alerts","checks": {"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_12","Section": "System and Information integrity (SI)","Service": "cloudwatch","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Alert [Assignment: organization-defined personnel or roles] using [Assignment: organization-defined automated mechanisms] when the following indications of inappropriate or unusual activities with security or privacy implications occur: [Assignment: organization-defined activities that trigger alerts].","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"si_4_14": {"name": "SI-4(14) Wireless Intrusion Detection","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_14","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Employ a wireless intrusion detection system to identify rogue wireless devices and to detect attack attempts and potential compromises or breaches to the system.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_17": {"name": "SI-4(17) Integrated Situational Awareness","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_4_17","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Correlate information from monitoring physical, cyber, and supply chain activities to achieve integrated, organization-wide situational awareness.","checks_status": {"fail": 7,"pass": 2,"total": 13,"manual": 0}},"si_4_20": {"name": "SI-4(20) Privileged Users","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_4_20","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Implement the following additional monitoring of privileged users: [Assignment: organization-defined additional monitoring].","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"si_4_23": {"name": "SI-4(23) Host-Based Devices","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_23","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Implement the following host-based monitoring mechanisms at [Assignment: organization-defined system components]: [Assignment: organization-defined host-based monitoring mechanisms].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_25": {"name": "SI-4(25) Optimize Network Traffic Analysis","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_25","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "System Monitoring (SI-4)"}],"description": "Provide visibility into network traffic at external and key internal system interfaces to optimize the effectiveness of monitoring devices.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ac_17_10": {"name": "AC-17(10) Authenticate Remote Commands","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_17_10","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Remote Access (AC-17)"}],"description": "Provide the capability to disconnect or disable remote access to the system within [Assignment: organization-defined time period].","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"ac_2_3_a": {"name": "AC-2(3)(a)","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_3_a","Section": "Access Control (AC)","Service": "iam","SubGroup": "AC-2(3) Disable Accounts","SubSection": "Account Management (AC-2)"}],"description": "Support the management of system accounts using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"ac_2_3_b": {"name": "AC-2(3)(b)","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_3_b","Section": "Access Control (AC)","Service": "iam","SubGroup": "AC-2(3) Disable Accounts","SubSection": "Account Management (AC-2)"}],"description": "Disable accounts within [Assignment: organization-defined time period] when the accounts: (b) Are no longer associated with a user or individual.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"ac_2_3_c": {"name": "AC-2(3)(c)","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_3_c","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-2(3) Disable Accounts","SubSection": "Account Management (AC-2)"}],"description": "Disable accounts within [Assignment: organization-defined time period] when the accounts: (c) Are in violation of organizational policy.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"ac_2_3_d": {"name": "AC-2(3)(d)","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_3_d","Section": "Access Control (AC)","Service": "iam","SubGroup": "AC-2(3) Disable Accounts","SubSection": "Account Management (AC-2)"}],"description": "Disable accounts within [Assignment: organization-defined time period] when the accounts: (d) Have been inactive for [Assignment: organization-defined time period].","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"ac_2_d_1": {"name": "AC-2(d)(1)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_d_1","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "d. Specify: 1. Authorized users of the system;personnel termination and transfer processes.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ac_2_i_2": {"name": "AC-2(i)(2)","checks": {"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_Ā”_2","Section": "Access Control (AC)","Service": "iam","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "i. Authorize access to the system based on: 2. Intended system usage.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ac_3_3_a": {"name": "AC-3(3)(a)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_3_a","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(3) Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access policy] over the set of covered subjects and objects specified in the policy, and where the policy: (a) Is uniformly enforced across the covered subjects and objects within the system.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_3_c": {"name": "AC-3(3)(c)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_3_c","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(3) Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access policy] over the set of covered subjects and objects specified in the policy, and where the policy: (c) Specifies that [Assignment: organization-defined subjects] may explicitly be granted [Assignment: organization-defined privileges] such that they are not limited by any defined subset (or all) of the above constraints.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_4_a": {"name": "AC-3(4)(a)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_4_a","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(4) Discretionary Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined discretionary access policy] over the set of covered subjects and objects specified in the policy, and where the policy specifies that a subject that has been granted access to information can do one or more of the following: (a) Pass the information to any other subjects or objects.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_4_b": {"name": "AC-3(4)(b)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_4_b","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(4) Discretionary Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined discretionary access policy] over the set of covered subjects and objects specified in the policy, and where the policy specifies that a subject that has been granted access to information can do one or more of the following: (b) Grant its privileges to other subjects.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_4_c": {"name": "AC-3(4)(c)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_4_c","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(4) Discretionary Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined discretionary access policy] over the set of covered subjects and objects specified in the policy, and where the policy specifies that a subject that has been granted access to information can do one or more of the following: (c) Change security attributes on subjects, objects, the system, or the system’s components.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_4_d": {"name": "AC-3(4)(d)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_4_d","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(4) Discretionary Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined discretionary access policy] over the set of covered subjects and objects specified in the policy, and where the policy specifies that a subject that has been granted access to information can do one or more of the following: (d) Choose the security attributes to be associated with newly created or revised objects.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_4_e": {"name": "AC-3(4)(e)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_4_e","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(4) Discretionary Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined discretionary access policy] over the set of covered subjects and objects specified in the policy, and where the policy specifies that a subject that has been granted access to information can do one or more of the following: (e) Change the rules governing access.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_7_4_a": {"name": "AC-7(4)(a)","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_7_4_a","Section": "Access Control (AC)","Service": "iam","SubGroup": "AC-7(4) Use Of Alternate Authentication Factor","SubSection": "Unsuccessful Logon Attempts (AC-7)"}],"description": "Allow the use of [Assignment: organization-defined authentication factors] that are different from the primary authentication factors after the number of organization-defined consecutive invalid logon attempts have been exceeded.","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"ca_7_4_c": {"name": "CA-7(4)(c)","checks": {"elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ca_7_4_c","Section": "Assessment, Authorization, And Monitoring (CA)","Service": "aws","SubGroup": "CA-7(4) Risk Monitoring","SubSection": "Continuous Monitoring (CA-7)"}],"description": "Ensure risk monitoring is an integral part of the continuous monitoring strategy that includes the following: (c) Change monitoring.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_2_b_1": {"name": "CM-2(b)(1)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_2_b_1","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-2(b)","SubSection": "Baseline Configuration (CM-2)"}],"description": "Review and update the baseline configuration of the system: 1. [Assignment: organization-defined frequency].","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"cm_2_b_2": {"name": "CM-2(b)(2)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_2_b_2","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-2(b)","SubSection": "Baseline Configuration (CM-2)"}],"description": "Review and update the baseline configuration of the system: 2. When required due to [Assignment: organization-defined circumstances].","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"cm_2_b_3": {"name": "CM-2(b)(3)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"ec2_instance_older_than_specific_days": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_2_b_3","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-2(b)","SubSection": "Baseline Configuration (CM-2)"}],"description": "Review and update the baseline configuration of the system: 3 When system components are installed or upgraded.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"cm_5_1_a": {"name": "CM-5(1)(a)","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","ec2_instance_profile_attached": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_5_1_a","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-5(1) Automated Access Enforcement And Audit Records","SubSection": "Access Restrictions For Change (CM-5)"}],"description": "Enforce access restrictions using [Assignment: organization-defined automated mechanisms].","checks_status": {"fail": 1,"pass": 2,"total": 15,"manual": 0}},"cm_5_1_b": {"name": "CM-5(1)(b)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_5_1_b","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-5(1) Automated Access Enforcement And Audit Records","SubSection": "Access Restrictions For Change (CM-5)"}],"description": "Automatically generate audit records of the enforcement actions.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"cm_8_3_a": {"name": "CM-8(3)(a)","checks": {"guardduty_is_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_3_a","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-8(3) Automated Unauthorized Component Detection","SubSection": "System Component Inventory (CM-8)"}],"description": "Detect the presence of unauthorized hardware, software, and firmware components within the system using [Assignment: organization-defined automated mechanisms] [Assignment: organization-defined frequency].","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"cm_8_a_1": {"name": "CM-8(a)(1)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_a_1","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-8(a)","SubSection": "System Component Inventory (CM-8)"}],"description": "Develop and document an inventory of system components that: 1. Accurately reflects the system.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_8_a_2": {"name": "CM-8(a)(2)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_a_2","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-8(a)","SubSection": "System Component Inventory (CM-8)"}],"description": "Develop and document an inventory of system components that: 2. Includes all components within the system.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_8_a_3": {"name": "CM-8(a)(3)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_a_3","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-8(a)","SubSection": "System Component Inventory (CM-8)"}],"description": "Develop and document an inventory of system components that: 3. Does not include duplicate accounting of components or components assigned to any other system.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_8_a_4": {"name": "CM-8(a)(4)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_a_4","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-8(a)","SubSection": "System Component Inventory (CM-8)"}],"description": "Develop and document an inventory of system components that: 4. Is at the level of granularity deemed necessary for tracking and reporting.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm_8_a_5": {"name": "CM-8(a)(5)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm_8_a_5","Section": "Configuration Management (CM)","Service": "aws","SubGroup": "CM-8(a)","SubSection": "System Component Inventory (CM-8)"}],"description": "Develop and document an inventory of system components that: 5. Includes the following information to achieve system component accountability: [Assignment: organization-defined information deemed necessary to achieve effective system component accountability].","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cp_1_a_2": {"name": "CP-1(a)(2)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_1_a_2","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": "CP-1(a)","SubSection": "Policy And Procedures (CP-1)"}],"description": "a. Develop, document, and disseminate to [Assignment: organization-defined personnel or roles]: 2. Procedures to facilitate the implementation of the contingency planning policy and the associated contingency planning controls.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"cp_2_a_6": {"name": "CP-2(a)(6)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_2_a_6","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": "CP-2(a)","SubSection": "Contingency Plan (CP-2)"}],"description": "Develop a contingency plan for the system that: 6. Addresses the sharing of contingency information.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"cp_2_a_7": {"name": "CP-2(a)(7)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_2_a_7","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": "CP-2(a)","SubSection": "Contingency Plan (CP-2)"}],"description": "Develop a contingency plan for the system that: 7. Is reviewed and approved by [Assignment: organization-defined personnel or roles].","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"ia_2_6_a": {"name": "IA-2(6)(a)","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_2_6_a","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": "IA-2(6) Acces To Accounts — Separate Device","SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "Implement multi-factor authentication for [Selection (one or more): local; network; remote] access to [Selection (one or more): privileged accounts; non-privileged accounts] such that: (a) One of the factors is provided by a device separate from the system gaining access.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ia_3_3_b": {"name": "IA-3(3)(b)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ia_3_3_b","Section": "Identification and Authentication (IA)","Service": "aws","SubGroup": "IA-3(3) Dynamic Address Allocation","SubSection": "Device Identification And Authentication (IA-3)"}],"description": "Audit lease information when assigned to a device.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"ia_5_1_c": {"name": "IA-5(1)(c)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ia_5_1_c","Section": "Identification and Authentication (IA)","Service": "aws","SubGroup": "IA-5(1) Password-Based Authentication","SubSection": "Authenticator Management (IA-5)"}],"description": "For password-based authentication: (c) Transmit passwords only over cryptographically-protected channels.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"ia_5_1_f": {"name": "IA-5(1)(f)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_1_f","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": "IA-5(1) Password-Based Authentication","SubSection": "Authenticator Management (IA-5)"}],"description": "For password-based authentication: (f) Allow user selection of long passwords and passphrases, including spaces and all printable characters.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_1_g": {"name": "IA-5(1)(g)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_1_g","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": "IA-5(1) Password-Based Authentication","SubSection": "Authenticator Management (IA-5)"}],"description": "For password-based authentication: (g) Employ automated tools to assist the user in selecting strong password authenticators.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_1_h": {"name": "IA-5(1)(h)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_1_h","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": "IA-5(1) Password-Based Authentication","SubSection": "Authenticator Management (IA-5)"}],"description": "For password-based authentication: (h) Enforce the following composition and complexity rules: [Assignment: organization-defined composition and complexity rules].","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_8_2_b": {"name": "IA-8(2)(b)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_8_2_b","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": "IA-8(2) Acceptance Of External Authenticators","SubSection": "Identification And Authentication (Non-Organizational Users) (IA-8)"}],"description": "Document and maintain a list of accepted external authenticators.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ma_4_1_a": {"name": "MA-4(1)(a)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ma_4_1_a","Section": "Maintenance (MA)","Service": "aws","SubGroup": "MA-4(1) Logging And Review","SubSection": "Nonlocal Maintenance (MA-4)"}],"description": "Log [Assignment: organization-defined audit events] for nonlocal maintenance and diagnostic sessions.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"ra_1_a_1": {"name": "RA-1(a)(1)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_1_a_1","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": "RA-1(a)","SubSection": "Policy And Procedures (RA-1)"}],"description": "Establish and maintain a cyber threat hunting capability to: 1. Search for indicators of compromise in organizational systems.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ra_1_a_2": {"name": "RA-1(a)(2)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_1_a_2","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": "RA-1(a)","SubSection": "Policy And Procedures (RA-1)"}],"description": "a. Establish and maintain a cyber threat hunting capability to: 2. Detect, track, and disrupt threats that evade existing controls.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ra_3_a_1": {"name": "RA-3(a)(1)","checks": {"guardduty_is_enabled": "PASS","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ra_3_a_1","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": null,"SubSection": "Risk Assessment (RA-3)"}],"description": "a. Conduct a risk assessment, including: 1. Identifying threats to and vulnerabilities in the system.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"sc_5_3_a": {"name": "SC-5(3)(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_5_3_a","Section": "System and Communications Protection (SC)","Service": "guarduty","SubGroup": "SC-5(3) Detection And Monitoring","SubSection": "Denial Of Service Protection (SC-5)"}],"description": "Employ the following monitoring tools to detect indicators of denial-of-service attacks against, or launched from, the system: [Assignment: organization-defined monitoring tools].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sc_5_3_b": {"name": "SC-5(3)(b)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc_5_3_b","Section": "System and Communications Protection (SC)","Service": "guarduty","SubGroup": "SC-5(3) Detection And Monitoring","SubSection": "Denial Of Service Protection (SC-5)"}],"description": "Monitor the following system resources to determine if sufficient resources exist to prevent effective denial-of-service attacks: [Assignment: organization-defined system resources].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sc_7_4_b": {"name": "SC-7(4)(b)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_4_b","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": "SC-7(4) External Telecommunications Services","SubSection": "Boundary Protection (SC-7)"}],"description": "Establish a traffic flow policy for each managed interface.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"sc_7_4_g": {"name": "SC-7(4)(g)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_4_g","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": "SC-7(4) External Telecommunications Services","SubSection": "Boundary Protection (SC-7)"}],"description": "Publish information to enable remote networks to detect unauthorized control plane traffic from internal networks.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"sc_7_9_a": {"name": "SC-7(9)(a)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_9_a","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": "SC-7(9) Restrict Threatening Outgoing Communications Traffic","SubSection": "Boundary Protection (SC-7)"}],"description": "Detect and deny outgoing communications traffic posing a threat to external systems.","checks_status": {"fail": 1,"pass": 5,"total": 13,"manual": 0}},"sc_7_9_b": {"name": "SC-7(9)(b)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_9_b","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": "SC-7(9) Restrict Threatening Outgoing Communications Traffic","SubSection": "Boundary Protection (SC-7)"}],"description": "Audit the identity of internal users associated with denied communications.","checks_status": {"fail": 5,"pass": 2,"total": 11,"manual": 0}},"si_1_1_c": {"name": "SI-1(1)(c)","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_1_1_c","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Policy And Procedures (SI-1)"}],"description": "Audit the use of the manual override capability.","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"si_1_a_2": {"name": "SI-1(a)(2)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_object_versioning": "FAIL","s3_bucket_secure_transport_policy": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_1_a_2","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Policy And Procedures (SI-1)"}],"description": "a. Develop, document, and disseminate to [Assignment: organization-defined personnel or roles]: 2. Procedures to facilitate the implementation of the system and information integrity policy and the associated system and information integrity controls;.","checks_status": {"fail": 5,"pass": 0,"total": 6,"manual": 0}},"si_3_8_a": {"name": "SI-3(8)(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_3_8_a","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": "SI-3(8) Detect Unauthorized Commands","SubSection": "Malicious Code Protection (SI-3)"}],"description": "Detect the following unauthorized operating system commands through the kernel application programming interface on [Assignment: organization-defined system hardware components]: [Assignment: organization-defined unauthorized operating system commands].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_3_8_b": {"name": "SI-3(8)(b)","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_3_8_b","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": "SI-3(8) Detect Unauthorized Commands","SubSection": "Malicious Code Protection (SI-3)"}],"description": "[Selection (one or more): issue a warning; audit the command execution; prevent the execution of the command].","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"si_3_c_2": {"name": "SI-3(c)(2)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_3_c_2","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Malicious Code Protection (SI-3)"}],"description": "c. Configure malicious code protection mechanisms to: 2. [Selection (one or more): block malicious code; quarantine malicious code; take [Assignment: organization-defined action]]; and send alert to [Assignment: organization-defined personnel or roles] in response to malicious code detection.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"si_4_4_a": {"name": "SI-4(4)(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_4_a","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": "SI-4(4) Inbound and Outbound Communications Traffic","SubSection": "System Monitoring (SI-4)"}],"description": "Determine criteria for unusual or unauthorized activities or conditions for inbound and outbound communications traffic.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_4_b": {"name": "SI-4(4)(b)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_4_b","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": "SI-4(4) Inbound and Outbound Communications Traffic","SubSection": "System Monitoring (SI-4)"}],"description": "Monitor inbound and outbound communications traffic [Assignment: organization-defined frequency] for [Assignment: organization-defined unusual or unauthorized activities or conditions].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_a_1": {"name": "SI-4(a)(1)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_a_1","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": "SI-4(a)","SubSection": "System Monitoring (SI-4)"}],"description": "a. Monitor the system to detect: 1. Attacks and indicators of potential attacks in accordance with the following monitoring objectives: [Assignment: organization-defined monitoring objectives]; and 2. Unauthorized local, network, and remote connections.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si_4_a_2": {"name": "SI-4(a)(2)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_a_2","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": "SI-4(a)","SubSection": "System Monitoring (SI-4)"}],"description": "a. Monitor the system to detect: 2. Unauthorized local, network, and remote connections.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ac_17_4_a": {"name": "AC-17(4)(a)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_17_4_a","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-17(4) Privileged Commands And Access","SubSection": "Remote Access (AC-17)"}],"description": "Authorize the execution of privileged commands and access to security-relevant information via remote access only in a format that provides assessable evidence and for the following needs: [Assignment: organization-defined needs];","checks_status": {"fail": 3,"pass": 5,"total": 16,"manual": 0}},"ac_2_12_a": {"name": "AC-2(12)(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_2_12_a","Section": "Access Control (AC)","Service": "guarduty","SubGroup": "AC-2(12) Account Monitoring","SubSection": "Account Management (AC-2)"}],"description": "Monitor system accounts for [Assignment: organization-defined atypical usage].","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ac_3_12_a": {"name": "AC-3(12)(a)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_12_a","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(12)Assert And Enforce Application Access","SubSection": "Access Enforcement (AC-3)"}],"description": "Require applications to assert, as part of the installation process, the access needed to the following system applications and functions: [Assignment: organization-defined system applications and functions].","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_12_b": {"name": "AC-3(12)(b)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac_3_12_b","Section": "Access Control (AC)","Service": "guarduty","SubGroup": "AC-3(12) Assert And Enforce Application Access","SubSection": "Access Enforcement (AC-3)"}],"description": "Provide an enforcement mechanism to prevent unauthorized access;","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ac_3_15_a": {"name": "AC-3(15)(a)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_15_a","Section": "Access Control (AC)","Service": "guarduty","SubGroup": "AC-3(15) Discretionary And Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access control policy] over the set of covered subjects and objects specified in the policy.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_15_b": {"name": "AC-3(15)(b)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_15_b","Section": "Access Control (AC)","Service": "guarduty","SubGroup": "AC-3(15) Discretionary And Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined discretionary access control policy] over the set of covered subjects and objects specified in the policy.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ia_5_18_a": {"name": "IA-5(18)(a)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_18_a","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": "IA-5(18) Password Managers","SubSection": "Authenticator Management (IA-5)"}],"description": "Employ [Assignment: organization-defined password managers] to generate and manage passwords.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia_5_18_b": {"name": "IA-5(18)(b)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia_5_18_b","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": "IA-5(18) Password Managers","SubSection": "Authenticator Management (IA-5)"}],"description": "Protect the passwords using [Assignment: organization-defined controls].","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"pm_14_a_1": {"name": "PM-14(a)(1)","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "pm_14_a_1","Section": "Program Management (PM)","Service": "aws","SubGroup": null,"SubSection": "Testing, Training, And Monitoring (PM-14)"}],"description": "a. Implement a process for ensuring that organizational plans for conducting security and privacy testing, training, and monitoring activities associated with organizational systems: 1. Are developed and maintained.","checks_status": {"fail": 8,"pass": 4,"total": 20,"manual": 0}},"ra_10_a_1": {"name": "RA-10(a)(1)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_10_a_1","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": "RA-10(a)","SubSection": "Threat Hunting (RA-10)"}],"description": "Establish and maintain a cyber threat hunting capability to: 1. Search for indicators of compromise in organizational systems; and 2. Detect, track, and disrupt threats that evade existings.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ra_10_a_2": {"name": "RA-10(a)(2)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ra_10_a_2","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": "RA-10(a)","SubSection": "Threat Hunting (RA-10)"}],"description": "a. Establish and maintain a cyber threat hunting capability to: 2. Detect, track, and disrupt threats that evade existings.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sa_15_a_4": {"name": "SA-15(a)(4)","checks": {"elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sa_15_a_4","Section": "System and Services Acquisition (SA)","Service": "aws","SubGroup": null,"SubSection": "Development Process, Standards, And Tools (SA-15)"}],"description": "a. Require the developer of the system, system component, or system service to follow a documented development process that: 4. Documents, manages, and ensures the integrity of changes to the process and/or tools used in development.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"sc_36_1_a": {"name": "SC-36(1)(a)","checks": {"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_36_1_a","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Distributed Processing And Storage (SC-36)"}],"description": "Employ polling techniques to identify potential faults, errors, or compromises to the following processing and storage components: [Assignment: organization-defined distributed processing and storage components].","checks_status": {"fail": 1,"pass": 0,"total": 5,"manual": 0}},"sc_7_24_b": {"name": "SC-7(24)(b)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc_7_24_b","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": "SC-7(24) Personally Identifiable Information","SubSection": "Boundary Protection (SC-7)"}],"description": "For systems that process personally identifiable information: (b) Monitor for permitted processing at the external interfaces to the system and at key internal boundaries within the system.","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"si_10_1_c": {"name": "SI-10(1)(c)","checks": {"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si_10_1_c","Section": "System and Information integrity (SI)","Service": "aws","SubGroup": "SI-10(1) Manual Override Capability","SubSection": "Information Input Validation (SI-10)"}],"description": "Audit the use of the manual override capability.","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"si_4_13_a": {"name": "SI-4(13)(a)","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si_4_13_a","Section": "System and Information integrity (SI)","Service": "guarduty","SubGroup": "SI-4(13) Analyze Traffic And Event Patterns","SubSection": "System Monitoring (SI-4)"}],"description": "Analyze communications traffic and event patterns for the system.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ac_3_3_b_1": {"name": "AC-3(3)(b)(1)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_3_b_1","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(3) Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access policy] over the set of covered subjects and objects specified in the policy, and where the policy: (b) Specifies that a subject that has been granted access to information is constrained from doing any of the following; (1) Passing the information to unauthorized subjects or objects.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_3_b_2": {"name": "AC-3(3)(b)(2)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_3_b_2","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(3) Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access policy] over the set of covered subjects and objects specified in the policy, and where the policy: (b) Specifies that a subject that has been granted access to information is constrained from doing any of the following; (2) Granting its privileges to other subjects.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_3_b_3": {"name": "AC-3(3)(b)(3)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_3_b_3","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(3) Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access policy] over the set of covered subjects and objects specified in the policy, and where the policy: (b) Specifies that a subject that has been granted access to information is constrained from doing any of the following; (3) Changing one or more security attributes (specified by the policy) on subjects, objects, the system, or system components.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_3_b_4": {"name": "AC-3(3)(b)(4)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_3_b_4","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(3) Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access policy] over the set of covered subjects and objects specified in the policy, and where the policy: (b) Specifies that a subject that has been granted access to information is constrained from doing any of the following; (4) Choosing the security attributes and attribute values (specified by the policy) to be associated with newly created or modified objects.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"ac_3_3_b_5": {"name": "AC-3(3)(b)(5)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac_3_3_b_5","Section": "Access Control (AC)","Service": "aws","SubGroup": "AC-3(3) Mandatory Access Control","SubSection": "Access Enforcement (AC-3)"}],"description": "Enforce [Assignment: organization-defined mandatory access policy] over the set of covered subjects and objects specified in the policy, and where the policy: (b) Specifies that a subject that has been granted access to information is constrained from doing any of the following; (5) Changing the rules governing access.","checks_status": {"fail": 1,"pass": 1,"total": 15,"manual": 0}},"cp_1_a_1_b": {"name": "CP-1(a)(1)(b)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp_1_a_1_b","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": "CP-1(a)","SubSection": "Policy And Procedures (CP-1)"}],"description": "a. Develop, document, and disseminate to [Assignment: organization-defined personnel or roles]: 1. [Selection (one or more): Organization-level; Mission/business process-level; System-level] contingency planning policy that: (b) Is consistent with applicable laws, executive orders, directives, regulations, policies, standards, and guidelines.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}}},"requirements_passed": 86,"requirements_failed": 202,"requirements_manual": 0,"total_requirements": 288,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "c7fda251-1b8b-4668-be6e-6929da58d6af","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "rbi_cyber_security_framework_aws","framework": "RBI-Cyber-Security-Framework","version": "","description": "The Reserve Bank had prescribed a set of baseline cyber security controls for primary (Urban) cooperative banks (UCBs) in October 2018. On further examination, it has been decided to prescribe a comprehensive cyber security framework for the UCBs, as a graded approach, based on their digital depth and interconnectedness with the payment systems landscape, digital products offered by them and assessment of cyber security risk. The framework would mandate implementation of progressively stronger security measures based on the nature, variety and scale of digital product offerings of banks.","region": "eu-west-1","requirements": {"annex_i_6": {"name": "Annex I (6)","checks": {"ssm_managed_compliant_patching": "FAIL","guardduty_no_high_severity_findings": "FAIL","redshift_cluster_automatic_upgrades": null,"rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "annex_i_6","Section": null,"Service": "aws","SubGroup": null,"SubSection": null}],"description": "Put in place systems and processes to identify, track, manage and monitor the status of patches to servers, operating system and application software running at the systems used by the UCB officials (end-users). Implement and update antivirus protection for all servers and applicable end points preferably through a centralised system.","checks_status": {"fail": 2,"pass": 1,"total": 6,"manual": 0}},"annex_i_12": {"name": "Annex I (12)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "annex_i_12","Section": null,"Service": "aws","SubGroup": null,"SubSection": null}],"description": "Take periodic back up of the important data and store this data ā€˜off line’ (i.e., transferring important files to a storage device that can be detached from a computer/system after copying all the files).","checks_status": {"fail": 2,"pass": 1,"total": 5,"manual": 0}},"annex_i_1_1": {"name": "Annex I (1.1)","checks": {"ec2_instance_managed_by_ssm": "FAIL","organizations_account_part_of_organizations": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "annex_i_1_1","Section": null,"Service": "aws","SubGroup": null,"SubSection": null}],"description": "UCBs should maintain an up-to-date business IT Asset Inventory Register containing the following fields, as a minimum: a) Details of the IT Asset (viz., hardware/software/network devices, key personnel, services, etc.), b. Details of systems where customer data are stored, c. Associated business applications, if any, d. Criticality of the IT asset (For example, High/Medium/Low).","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"annex_i_1_3": {"name": "Annex I (1.3)","checks": {"elb_ssl_listeners": "FAIL","elbv2_ssl_listeners": "FAIL","ec2_instance_public_ip": "FAIL","backup_vaults_encrypted": "PASS","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"kms_cmk_rotation_enabled": null,"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","elbv2_insecure_ssl_ciphers": "PASS","rds_snapshots_public_access": "PASS","ssm_documents_set_as_public": "PASS","s3_bucket_default_encryption": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"redshift_cluster_public_access": null,"acm_certificates_expiration_check": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","vpc_subnet_no_public_ip_by_default": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"sns_topics_kms_encryption_at_rest_enabled": "FAIL","awslambda_function_not_publicly_accessible": "PASS","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_https_communications_enforced": null,"opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "annex_i_1_3","Section": null,"Service": "aws","SubGroup": null,"SubSection": null}],"description": "Appropriately manage and provide protection within and outside UCB/network, keeping in mind how the data/information is stored, transmitted, processed, accessed and put to use within/outside the UCB’s network, and level of risk they are exposed to depending on the sensitivity of the data/information.","checks_status": {"fail": 12,"pass": 15,"total": 40,"manual": 0}},"annex_i_5_1": {"name": "Annex I (5.1)","checks": {"elbv2_waf_acl_attached": "FAIL","apigateway_restapi_waf_acl_attached": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "annex_i_5_1","Section": null,"Service": "aws","SubGroup": null,"SubSection": null}],"description": "The firewall configurations should be set to the highest security level and evaluation of critical device (such as firewall, network switches, security devices, etc.) configurations should be done periodically.","checks_status": {"fail": 4,"pass": 1,"total": 5,"manual": 0}},"annex_i_7_1": {"name": "Annex I (7.1)","checks": {"iam_no_root_access_key": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "annex_i_7_1","Section": null,"Service": "iam","SubGroup": null,"SubSection": null}],"description": "Disallow administrative rights on end-user workstations/PCs/laptops and provide access rights on a ā€˜need to know’ and ā€˜need to do’ basis.","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"annex_i_7_2": {"name": "Annex I (7.2)","checks": {"iam_password_policy_reuse_24": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "annex_i_7_2","Section": null,"Service": "iam","SubGroup": null,"SubSection": null}],"description": "Passwords should be set as complex and lengthy and users should not use same passwords for all the applications/systems/devices.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"annex_i_7_3": {"name": "Annex I (7.3)","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "annex_i_7_3","Section": null,"Service": "vpc","SubGroup": null,"SubSection": null}],"description": "Remote Desktop Protocol (RDP) which allows others to access the computer remotely over a network or over the internet should be always disabled and should be enabled only with the approval of the authorised officer of the UCB. Logs for such remote access shall be enabled and monitored for suspicious activities.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"annex_i_7_4": {"name": "Annex I (7.4)","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","opensearch_service_domains_audit_logging_enabled": null,"opensearch_service_domains_cloudwatch_logging_enabled": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "annex_i_7_4","Section": null,"Service": "aws","SubGroup": null,"SubSection": null}],"description": "Implement appropriate (e.g. centralised) systems and controls to allow, manage, log and monitor privileged/super user/administrative access to critical systems (servers/databases, applications, network devices etc.)","checks_status": {"fail": 7,"pass": 3,"total": 15,"manual": 0}}},"requirements_passed": 3,"requirements_failed": 6,"requirements_manual": 0,"total_requirements": 9,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "c9352bc9-2107-40a5-8dc6-c67817863253","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "fedramp_moderate_revision_4_aws","framework": "FedRamp-Moderate-Revision-4","version": "","description": "The Federal Risk and Authorization Management Program (FedRAMP) was established in 2011. It provides a cost-effective, risk-based approach for the adoption and use of cloud services by the U.S. federal government. FedRAMP empowers federal agencies to use modern cloud technologies, with an emphasis on the security and protection of federal information.","region": "eu-west-1","requirements": {"ac-3": {"name": "Access Enforcement (AC-3)","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-3","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system enforces approved authorizations for logical access to information and system resources in accordance with applicable access control policies.","checks_status": {"fail": 1,"pass": 6,"total": 21,"manual": 0}},"ac-4": {"name": "Information Flow Enforcement (AC-4)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"acm_certificates_expiration_check": "PASS","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-4","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system enforces approved authorizations for controlling the flow of information within the system and between interconnected systems based on organization-defined information flow control policies.","checks_status": {"fail": 3,"pass": 7,"total": 16,"manual": 0}},"ac-6": {"name": "Least Privilege (AC-6)","checks": {"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-6","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks in accordance with organizational missions and business functions.","checks_status": {"fail": 1,"pass": 6,"total": 20,"manual": 0}},"au-3": {"name": "Content of Audit Records (AU-3)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-3","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system generates audit records containing information that establishes what type of event occurred, when the event occurred, where the event occurred, the source of the event, the outcome of the event, and the identity of any individuals or subjects associated with the event.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au-9": {"name": "Protection of Audit Information (AU-9)","checks": {"cloudtrail_kms_encryption_enabled": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-9","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects audit information and audit tools from unauthorized access, modification, and deletion.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"cm-2": {"name": "Baseline Configuration (CM-2)","checks": {"ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"ec2_instance_managed_by_ssm": "FAIL","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"ssm_managed_compliant_patching": "FAIL","apigateway_restapi_waf_acl_attached": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm-2","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization develops, documents, and maintains under configuration control, a current baseline configuration of the information system.","checks_status": {"fail": 8,"pass": 6,"total": 22,"manual": 0}},"ia-2": {"name": "Identification and Authentication (Organizational users) (IA-2)","checks": {"iam_no_root_access_key": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia-2","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": null}],"description": "The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"ra-5": {"name": "Vulnerability Scanning (RA-5)","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ra-5","Section": "Risk Assessment (RA)","Service": "guarduty","SubGroup": null,"SubSection": null}],"description": "Scan for system vulnerabilities. Share vulnerability information and security controls that eliminate vulnerabilities.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"sc-2": {"name": "Application Partitioning (SC-2)","checks": {"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc-2","Section": "System and Communications Protection (SC)","Service": "iam","SubGroup": null,"SubSection": null}],"description": "The information system separates user functionality (including user interface services) from information system management functionality.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"sc-4": {"name": "Information In Shared Resources (SC-4)","checks": {"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-4","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system prevents unauthorized and unintended information transfer via shared system resources.","checks_status": {"fail": 2,"pass": 5,"total": 14,"manual": 0}},"sc-5": {"name": "Denial Of Service Protection (SC-5)","checks": {"guardduty_is_enabled": "PASS","rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"rds_instance_deletion_protection": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-5","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects against or limits the effects of the following types of denial of service attacks: [Assignment: organization-defined types of denial of service attacks or references to sources for such information] by employing [Assignment: organization-defined security safeguards].","checks_status": {"fail": 4,"pass": 1,"total": 6,"manual": 0}},"sc-7": {"name": "Boundary Protection (SC-7)","checks": {"elb_ssl_listeners": "FAIL","ec2_instance_public_ip": "FAIL","elbv2_waf_acl_attached": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-7","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system: a. Monitors and controls communications at the external boundary of the system and at key internal boundaries within the system; b. Implements subnetworks for publicly accessible system components that are [Selection: physically; logically] separated from internal organizational networks; and c. Connects to external networks or information systems only through managed interfaces consisting of boundary protection devices arranged in accordance with an organizational security architecture.","checks_status": {"fail": 6,"pass": 6,"total": 21,"manual": 0}},"sc-8": {"name": "Transmission Integrity (SC-8)","checks": {"elb_ssl_listeners": "FAIL","elbv2_insecure_ssl_ciphers": "PASS","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-8","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects the confidentiality AND integrity of transmitted information.","checks_status": {"fail": 3,"pass": 1,"total": 5,"manual": 0}},"si-7": {"name": "Software, Firmware, and Information Integrity (SI-7)","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si-7","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization employs integrity verification tools to detect unauthorized changes to [Assignment: organization-defined software, firmware, and information].","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"au-11": {"name": "Audit Record Retention (AU-11)","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-11","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization retains audit records for at least 90 days to provide support for after-the-fact investigations of security incidents and to meet regulatory and organizational information retention requirements.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cp-10": {"name": "Information System Recovery And Reconstitution (CP-10)","checks": {"rds_instance_multi_az": "FAIL","efs_have_backup_enabled": "FAIL","elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp-10","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization provides for the recovery and reconstitution of the information system to a known state after a disruption, compromise, or failure.","checks_status": {"fail": 4,"pass": 1,"total": 9,"manual": 0}},"sa-10": {"name": "Developer Configuration Management (SA-10)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sa-10","Section": "System and Services Acquisition (SA)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization requires the developer of the information system, system component, or information system service to: a. Perform configuration management during system, component, or service [Selection (one or more): design; development; implementation; operation]; b. Document, manage, and control the integrity of changes to [Assignment: organization-defined configuration items under configuration management]; c. Implement only organization-approved changes to the system, component, or service; d. Document approved changes to the system, component, or service and the potential security impacts of such changes; and e. Track security flaws and flaw resolution within the system, component, or service and report findings to [Assignment: organization-defined personnel].","checks_status": {"fail": 2,"pass": 2,"total": 4,"manual": 0}},"sc-12": {"name": "Cryptographic Key Establishment And Management (SC-12)","checks": {"kms_cmk_rotation_enabled": null,"acm_certificates_expiration_check": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sc-12","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization establishes and manages cryptographic keys for required cryptography employed within the information system in accordance with [Assignment: organization-defined requirements for key generation, distribution, storage, access, and destruction].","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"sc-13": {"name": "Use of Cryptography (SC-13)","checks": {"s3_bucket_default_encryption": "PASS","sns_topics_kms_encryption_at_rest_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-13","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system implements FIPS-validated or NSA-approved cryptography in accordance with applicable federal laws, Executive Orders, directives, policies, regulations, and standards.","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"sc-23": {"name": "Session Authenticity (SC-23)","checks": {"elb_ssl_listeners": "FAIL","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-23","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects the authenticity of communications sessions.","checks_status": {"fail": 3,"pass": 0,"total": 4,"manual": 0}},"sc-28": {"name": "Protection of Information at Rest (SC-28)","checks": {"ec2_ebs_volume_encryption": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-28","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The information system protects the confidentiality AND integrity of [Assignment: organization-defined information at rest].","checks_status": {"fail": 5,"pass": 2,"total": 13,"manual": 0}},"si-12": {"name": "Information Handling and Retention (SI-12)","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si-12","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": null}],"description": "The organization handles and retains information within the information system and information output from the system in accordance with applicable federal laws, Executive Orders, directives, policies, regulations, standards, and operational requirements.","checks_status": {"fail": 3,"pass": 1,"total": 8,"manual": 0}},"ac-2-1": {"name": "AC-2(1) Automated System Account Management","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac-2-1","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The organization employs automated mechanisms to support the management of information system accounts.","checks_status": {"fail": 0,"pass": 2,"total": 15,"manual": 0}},"ac-2-3": {"name": "AC-2-3","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac-2-3","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The information system automatically disables inactive accounts after 90 days for user accounts.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"ac-2-4": {"name": "AC-2(4) Automated Audit Actions","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-2-4","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The information system automatically audits account creation, modification, enabling, disabling, and removal actions, and notifies [Assignment: organization-defined personnel or roles].","checks_status": {"fail": 3,"pass": 3,"total": 14,"manual": 0}},"ac-2-f": {"name": "AC-2(f)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac-2-f","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The organization: f. Creates, enables, modifies, disables, and removes information system accounts in accordance with [Assignment: organization-defined procedures or conditions].","checks_status": {"fail": 0,"pass": 0,"total": 13,"manual": 0}},"ac-2-g": {"name": "AC-2(g)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","opensearch_service_domains_cloudwatch_logging_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-2-g","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The organization: g. Monitors the use of information system accounts.","checks_status": {"fail": 3,"pass": 4,"total": 12,"manual": 0}},"ac-2-j": {"name": "AC-2(j)","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac-2-j","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The organization: j. Reviews accounts for compliance with account management requirements [Assignment: organization-defined frequency].","checks_status": {"fail": 0,"pass": 0,"total": 12,"manual": 0}},"ac-5-c": {"name": "AC-5(c)","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac-5-c","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Separation Of Duties (AC-5)"}],"description": "The organization: c. Defines information system access authorizations to support separation of duties.","checks_status": {"fail": 0,"pass": 0,"total": 8,"manual": 0}},"au-7-1": {"name": "AU-7(1) Automatic Processing","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-7-1","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Reduction And Report Generation (AU-7)"}],"description": "The information system provides the capability to process audit records for events of interest based on [Assignment: organization-defined audit fields within audit records].","checks_status": {"fail": 1,"pass": 0,"total": 5,"manual": 0}},"au-9-2": {"name": "AU-9(2) Audit Backup On Separate Physical Systems / Components","checks": {"s3_bucket_object_versioning": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-9-2","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Protection of Audit Information (AU-9)"}],"description": "The information system backs up audit records at least weekly onto a physically different system or system component than the system or component being audited.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"cm-7-a": {"name": "CM-7(a)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm-7-a","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Least Functionality (CM-7)"}],"description": "The organization: a. Configures the information system to provide only essential capabilities.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cm-8-1": {"name": "CM-8(1)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm-8-1","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Information System Component Inventory (CM-8)"}],"description": "The organization updates the inventory of information system components as an integral part of component installations, removals, and information system updates.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"cp-9-b": {"name": "CP-9(b))","checks": {"efs_have_backup_enabled": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"redshift_cluster_automated_snapshot": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cp-9-b","Section": "Contingency Planning (CP)","Service": "aws","SubGroup": null,"SubSection": "Information System Backup (CP-9)"}],"description": "The organization: b. Conducts backups of system-level information contained in the information system (daily incremental; weekly full).","checks_status": {"fail": 2,"pass": 1,"total": 7,"manual": 0}},"ia-2-1": {"name": "IA-2(1) Network Access To Privileged Accounts","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia-2-1","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Identification and Authentication (Organizational users) (IA-2)"}],"description": "The information system implements multi-factor authentication for network access to privileged accounts.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ia-5-4": {"name": "IA-5(4) Automated Support For Password Strength Determination","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia-5-4","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "The organization employs automated tools to determine if password authenticators are sufficiently strong to satisfy [Assignment: organization-defined requirements].","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"ia-5-7": {"name": "IA-5(7) No Embedded Unencrypted Static Authenticators","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia-5-7","Section": "Identification and Authentication (IA)","Service": "codebuild","SubGroup": null,"SubSection": "Authenticator Management (IA-5)"}],"description": "The organization ensures that unencrypted static authenticators are not embedded in applications or access scripts or stored on function keys.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ir-4-1": {"name": "IR-4(1) Automated Incident Handling Processes","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ir-4-1","Section": "Incident Response (IR)","Service": "aws","SubGroup": null,"SubSection": "Incident Handling (IR-4)"}],"description": "The organization employs automated mechanisms to support the incident handling process.","checks_status": {"fail": 1,"pass": 2,"total": 7,"manual": 0}},"ir-6-1": {"name": "IR-6(1) Automated Reporting","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ir-6-1","Section": "Incident Response (IR)","Service": "aws","SubGroup": null,"SubSection": "Incident Reporting (IR-6)"}],"description": "The organization employs automated mechanisms to assist in the reporting of security incidents.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"ir-7-1": {"name": "IR-7(1) Automation Support For Availability Of Information / Support","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ir-7-1","Section": "Incident Response (IR)","Service": "aws","SubGroup": null,"SubSection": "Incident Response Assistance (IR-7)"}],"description": "The organization employs automated mechanisms to increase the availability of incident response-related information and support.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"sa-3-a": {"name": "SA-3(a)","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sa-3-a","Section": "System and Services Acquisition (SA)","Service": "aws","SubGroup": null,"SubSection": "System Development Life Cycle (SA-3)"}],"description": "The organization: a. Manages the information system using [Assignment: organization-defined system development life cycle] that incorporates information security considerations.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sc-7-3": {"name": "SC-7(3) Access Points","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-7-3","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Boundary Protection (SC-7)"}],"description": "The organization limits the number of external network connections to the information system.","checks_status": {"fail": 3,"pass": 6,"total": 17,"manual": 0}},"sc-8-1": {"name": "SC-8(1) Cryptographic Or Alternate Physical Protection","checks": {"elb_ssl_listeners": "FAIL","elbv2_insecure_ssl_ciphers": "PASS","s3_bucket_secure_transport_policy": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sc-8-1","Section": "System and Communications Protection (SC)","Service": "aws","SubGroup": null,"SubSection": "Transmission Integrity (SC-8)"}],"description": "The information system implements cryptographic mechanisms to [Selection (one or more): prevent unauthorized disclosure of information; detect changes to information] during transmission unless otherwise protected by [Assignment: organization-defined alternative physical safeguards].","checks_status": {"fail": 3,"pass": 1,"total": 5,"manual": 0}},"si-2-2": {"name": "Automated Flaw Remediation Status (SI-2(2))","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si-2-2","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Flaw Remediation (SI-2)"}],"description": "The organization employs automated mechanisms at least monthly to determine the state of information system components with regard to flaw remediation.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"si-4-1": {"name": "SI-4(1) System-Wide Intrusion Detection System","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "si-4-1","Section": "System and Information Integrity (SI)","Service": "guarduty","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The organization connects and configures individual intrusion detection tools into an information system-wide intrusion detection system.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"si-4-2": {"name": "SI-4(2) Automated Tools For Real-Time Analysis","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "si-4-2","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The organization employs automated tools to support near real-time analysis of events.","checks_status": {"fail": 0,"pass": 4,"total": 12,"manual": 0}},"si-4-4": {"name": "SI-4(4) Inbound and Outbound Communications Traffic","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "si-4-4","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The information system monitors inbound and outbound communications traffic continuously for unusual or unauthorized activities or conditions.","checks_status": {"fail": 0,"pass": 4,"total": 12,"manual": 0}},"si-4-5": {"name": "SI-4(5) System-Generated Alerts","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "si-4-5","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The information system alerts organization-defined personnel or roles when the following indications of compromise or potential compromise occur: [Assignment: organization-defined compromise indicators].","checks_status": {"fail": 0,"pass": 4,"total": 12,"manual": 0}},"si-7-1": {"name": "SI-7(1) Integrity Checks","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si-7-1","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Software, Firmware, and Information Integrity (SI-7)"}],"description": "The information system performs an integrity check of security relevant events at least monthly.","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"ac-17-1": {"name": "AC-17(1) Automated Monitoring/Control","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-17-1","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Remote Access (AC-17)"}],"description": "The information system monitors and controls remote access methods.","checks_status": {"fail": 3,"pass": 8,"total": 19,"manual": 0}},"ac-17-2": {"name": "AC-17(2) Protection Of Confidentiality/Integrity Using Encryption","checks": {"elb_ssl_listeners": "FAIL","acm_certificates_expiration_check": "PASS","s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-17-2","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Remote Access (AC-17)"}],"description": "The information system implements cryptographic mechanisms to protect the confidentiality and integrity of remote access sessions.","checks_status": {"fail": 2,"pass": 1,"total": 3,"manual": 0}},"ac-21-b": {"name": "AC-21(b)","checks": {"ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ac-21-b","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Information Sharing (AC-21)"}],"description": "The organization: b. Employs [Assignment: organization-defined automated mechanisms or manual processes] to assist users in making information sharing/collaboration decisions.","checks_status": {"fail": 3,"pass": 4,"total": 15,"manual": 0}},"ac-6-10": {"name": "AC-6(10) Prohibit Non-Privileged Users From Executing Privileged Functions","checks": {"iam_no_root_access_key": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac-6-10","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Least Privilege (AC-6)"}],"description": "The information system prevents non-privileged users from executing privileged functions to include disabling, circumventing, or altering implemented security safeguards/countermeasures.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"si-4-16": {"name": "SI-4(16) Correlate Monitoring Information","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "si-4-16","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The organization correlates information from monitoring tools employed throughout the information system.","checks_status": {"fail": 0,"pass": 3,"total": 7,"manual": 0}},"au-2-a-d": {"name": "AU-2(a)(d)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-2-a-d","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Events (AU-2)"}],"description": "The organization: a. Determines that the information system is capable of auditing the following events: Successful and unsuccessful account logon events, account management events, object access, policy change, privilege functions, process tracking, and system events. For Web applications: all administrator activity, authentication checks, authorization checks, data deletions, data access, data changes, and permission changes. d. Determines that the following events are to be audited within the information system: [organization-defined subset of the auditable events defined in AU-2 a to be audited continually for each identified event].","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"au-6-1-3": {"name": "AU-6(1)(3)","checks": {"elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-6-1-3","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Review, Analysis And Reporting (AU-6)"}],"description": "(1) The organization employs automated mechanisms to integrate audit review, analysis, and reporting processes to support organizational processes for investigation and response to suspicious activities. (3) The organization analyzes and correlates audit records across different repositories to gain organization-wide situational awareness.","checks_status": {"fail": 7,"pass": 4,"total": 19,"manual": 0}},"ca-7-a-b": {"name": "CA-7(a)(b)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ec2_instance_imdsv2_enabled": "PASS","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"rds_instance_enhanced_monitoring_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ca-7-a-b","Section": "Security Assessment And Authorization (CA)","Service": "aws","SubGroup": null,"SubSection": "Continuous Monitoring (CA-7)"}],"description": "The organization develops a continuous monitoring strategy and implements a continuous monitoring program that includes: a. Establishment of [Assignment: organization-defined metrics] to be monitored; b. Establishment of [Assignment: organization-defined frequencies] for monitoring and [Assignment: organization-defined frequencies] for assessments supporting such monitoring.","checks_status": {"fail": 1,"pass": 4,"total": 13,"manual": 0}},"cm-8-3-a": {"name": "CM-8(3)(a)","checks": {"guardduty_is_enabled": "PASS","ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cm-8-3-a","Section": "Configuration Management (CM)","Service": "aws","SubGroup": null,"SubSection": "Information System Component Inventory (CM-8)"}],"description": "The organization: a. Employs automated mechanisms continuously, using automated mechanisms with a maximum five-minute delay in detection, to detect the presence of unauthorized hardware, software, and firmware components within the information system","checks_status": {"fail": 2,"pass": 1,"total": 4,"manual": 0}},"ia-2-1-2": {"name": "IA-2(1)(2)","checks": {"iam_root_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia-2-1-2","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "IA-2(1) Network Access To Privileged Accounts"}],"description": "(1) The information system implements multifactor authentication for network access to privileged accounts. (2) The information system implements multifactor authentication for network access to non- privileged accounts.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"ac-2-12-a": {"name": "AC-2(12)(a)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ac-2-12-a","Section": "Access Control (AC)","Service": "aws","SubGroup": null,"SubSection": "Account Management (AC-2)"}],"description": "The organization: a. Monitors information system accounts for [Assignment: organization-defined atypical use].","checks_status": {"fail": 0,"pass": 2,"total": 2,"manual": 0}},"au-12-a-c": {"name": "AU-12(a)(c)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "au-12-a-c","Section": "Audit and Accountability (AU)","Service": "aws","SubGroup": null,"SubSection": "Audit Generation (AU-12)"}],"description": "The information system: a. Provides audit record generation capability for the auditable events defined in AU-2 a. at all information system and network components where audit capability is deployed/available c. Generates audit records for the events defined in AU-2 d. with the content defined in AU-3.","checks_status": {"fail": 6,"pass": 2,"total": 12,"manual": 0}},"si-4-a-b-c": {"name": "SI-4(a)(b)(c)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_waf_acl_attached": "FAIL","ec2_instance_imdsv2_enabled": "PASS","apigateway_restapi_waf_acl_attached": "FAIL","guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "si-4-a-b-c","Section": "System and Information Integrity (SI)","Service": "aws","SubGroup": null,"SubSection": "Information System Monitoring (SI-4)"}],"description": "The organization: a. Monitors the information system to detect: 1. Attacks and indicators of potential attacks in accordance with [Assignment: organization- defined monitoring objectives]; and 2. Unauthorized local, network, and remote connections; b. Identifies unauthorized use of the information system through [Assignment: organization- defined techniques and methods]; c. Deploys monitoring devices: i. strategically within the information system to collect organization-determined essential information; and (ii) at ad hoc locations within the system to track specific types of transactions of interest to the organization.","checks_status": {"fail": 4,"pass": 3,"total": 11,"manual": 0}},"ia-5-1-a-d-e": {"name": "IA-5(1)(a)(d)(e)","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "ia-5-1-a-d-e","Section": "Identification and Authentication (IA)","Service": "iam","SubGroup": null,"SubSection": "IA-5(1) Password-Based Authentication"}],"description": "The information system, for password-based authentication: a. Enforces minimum password complexity of [Assignment: organization-defined requirements for case sensitivity, number of characters, mix of upper-case letters, lower-case letters, numbers, and special characters, including minimum requirements for each type]; d. Enforces password minimum and maximum lifetime restrictions of [Assignment: organization- defined numbers for lifetime minimum, lifetime maximum]; e. Prohibits password reuse for 24 generations","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 20,"requirements_failed": 43,"requirements_manual": 1,"total_requirements": 64,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "d7024b7f-64c1-4d70-8f9d-7844c9194c42","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "gdpr_aws","framework": "GDPR","version": "","description": "The General Data Protection Regulation (GDPR) is a new European privacy law that became enforceable on May 25, 2018. The GDPR replaces the EU Data Protection Directive, also known as Directive 95/46/EC. It's intended to harmonize data protection laws throughout the European Union (EU). It does this by applying a single data protection law that's binding throughout each EU member state.","region": "eu-west-1","requirements": {"article_25": {"name": "Article 25 Data protection by design and by default","checks": {"iam_root_mfa_enabled": null,"vpc_flow_logs_enabled": "FAIL","iam_no_root_access_key": null,"iam_support_role_created": null,"kms_cmk_rotation_enabled": null,"iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","config_recorder_all_regions_enabled": null,"iam_user_mfa_enabled_console_access": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","iam_password_policy_minimum_length_14": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_log_metric_filter_policy_changes": null,"iam_inline_policy_no_administrative_privileges": null,"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL","cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS","cloudwatch_log_metric_filter_authentication_failures": null,"iam_aws_attached_policy_no_administrative_privileges": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"iam_customer_attached_policy_no_administrative_privileges": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "article_25","Section": "Article 25 Data protection by design and by default","Service": "aws","SubGroup": null,"SubSection": null}],"description": "To obtain the latest version of the official guide, please visit https://gdpr-info.eu/art-25-gdpr/. Taking into account the state of the art, the cost of implementation and the nature, scope, context and purposes of processing as well as the risks of varying likelihood and severity for rights and freedoms of natural persons posed by the processing, the controller shall, both at the time of the determination of the means for processing and at the time of the processing itself, implement appropriate technical and organisational measures, such as pseudonymisation, which are designed to implement data-protection principles, such as data minimisation, in an effective manner and to integrate the necessary safeguards into the processing in order to meet the requirements of this Regulation and protect the rights of data subjects. The controller shall implement appropriate technical and organisational measures for ensuring that, by default, only personal data which are necessary for each specific purpose of the processing are processed. That obligation applies to the amount of personal data collected, the extent of their processing, the period of their storage and their accessibility. In particular, such measures shall ensure that by default personal data are not made accessible without the individual's intervention to an indefinite number of natural persons. An approved certification mechanism pursuant to Article 42 may be used as an element to demonstrate compliance with the requirements set out in paragraphs 1 and 2 of this Article.","checks_status": {"fail": 5,"pass": 2,"total": 42,"manual": 0}},"article_30": {"name": "Article 30 Records of processing activities","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","kms_cmk_rotation_enabled": null,"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","config_recorder_all_regions_enabled": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "article_30","Section": "Article 30 Records of processing activities","Service": "aws","SubGroup": null,"SubSection": null}],"description": " To obtain the latest version of the official guide, please visit https://www.privacy-regulation.eu/en/article-30-records-of-processing-activities-GDPR.htm. Each controller and, where applicable, the controller's representative, shall maintain a record of processing activities under its responsibility. That record shall contain all of the following information like the name and contact details of the controller and where applicable, the joint controller, the controller's representative and the data protection officer, the purposes of the processing etc. Each processor and where applicable, the processor's representative shall maintain a record of all categories of processing activities carried out on behalf of a controller, containing the name and contact details of the processor or processors and of each controller on behalf of which the processor is acting, and, where applicable of the controller's or the processor's representative, and the data protection officer, where applicable, transfers of personal data to a third country or an international organisation, including the identification of that third country or international organisation and, in the case of transfers referred to in the second subparagraph of Article 49(1), the documentation of suitable safeguards. The records referred to in paragraphs 1 and 2 shall be in writing, including in electronic form. The controller or the processor and, where applicable, the controller's or the processor's representative, shall make the record available to the supervisory authority on request. The obligations referred to in paragraphs 1 and 2 shall not apply to an enterprise or an organisation employing fewer than 250 persons unless the processing it carries out is likely to result in a risk to the rights and freedoms of data subjects, the processing is not occasional, or the processing includes special categories of data as referred to in Article 9(1) or personal data relating to criminal convictions and offences referred to in Article 10.","checks_status": {"fail": 5,"pass": 1,"total": 12,"manual": 0}},"article_32": {"name": "Article 32 Security of processing","checks": {"elb_ssl_listeners": "FAIL","ec2_ebs_volume_encryption": "PASS","rds_instance_backup_enabled": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"acm_certificates_expiration_check": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","redshift_cluster_automated_snapshot": null,"cloudfront_distributions_https_enabled": null,"cloudtrail_log_file_validation_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "article_32","Section": "Article 32 Security of processing","Service": "aws","SubGroup": null,"SubSection": null}],"description": " To obtain the latest version of the official guide, please visit https://gdpr-info.eu/art-32-gdpr/. Taking into account the state of the art, the costs of implementation and the nature, scope, context and purposes of processing as well as the risk of varying likelihood and severity for the rights and freedoms of natural persons, the controller and the processor shall implement appropriate technical and organisational measures to ensure a level of security appropriate to the risk, including inter alia as appropriate. In assessing the appropriate level of security account shall be taken in particular of the risks that are presented by processing, in particular from accidental or unlawful destruction, loss, alteration, unauthorised disclosure of, or access to personal data transmitted, stored or otherwise processed. Adherence to an approved code of conduct as referred to in Article 40 or an approved certification mechanism as referred to in Article 42 may be used as an element by which to demonstrate compliance with the requirements set out in paragraph 1 of this Article. The controller and processor shall take steps to ensure that any natural person acting under the authority of the controller or the processor who has access to personal data does not process them except on instructions from the controller, unless he or she is required to do so by Union or Member State law.","checks_status": {"fail": 9,"pass": 4,"total": 25,"manual": 0}}},"requirements_passed": 0,"requirements_failed": 3,"requirements_manual": 0,"total_requirements": 3,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "df010cc1-e468-42d1-8b7c-37d614adf364","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "aws_well_architected_framework_security_pillar_aws","framework": "AWS-Well-Architected-Framework-Security-Pillar","version": "","description": "Best Practices for AWS Well-Architected Framework Security Pillar. The focus of this framework is the security pillar of the AWS Well-Architected Framework. It provides guidance to help you apply best practices, current recommendations in the design, delivery, and maintenance of secure AWS workloads.","region": "eu-west-1","requirements": {"SEC01-BP01": {"name": "SEC01-BP01","checks": {"organizations_account_part_of_organizations": null},"status": "PASS","attributes": [{"Name": "SEC01-BP01 Separate workloads using accounts","Section": "Security foundations","SubSection": "AWS account management and separation","Description": "Establish common guardrails and isolation between environments (such as production, development, and test) and workloads through a multi-account strategy. Account-level separation is strongly recommended, as it provides a strong isolation boundary for security, billing, and access.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_multi_accounts.html#implementation-guidance.","WellArchitectedPracticeId": "sec_securely_operate_multi_accounts","WellArchitectedQuestionId": "securely-operate"}],"description": "Establish common guardrails and isolation between environments (such as production, development, and test) and workloads through a multi-account strategy. Account-level separation is strongly recommended, as it provides a strong isolation boundary for security, billing, and access.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"SEC01-BP02": {"name": "SEC01-BP02","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_root_hardware_mfa_enabled": null},"status": "PASS","attributes": [{"Name": "SEC01-BP02 Secure account root user and properties","Section": "Security foundations","SubSection": "AWS account management and separation","Description": "The root user is the most privileged user in an AWS account, with full administrative access to all resources within the account, and in some cases cannot be constrained by security policies. Deactivating programmatic access to the root user, establishing appropriate controls for the root user, and avoiding routine use of the root user helps reduce the risk of inadvertent exposure of the root credentials and subsequent compromise of the cloud environment.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_aws_account.html#implementation-guidance.","WellArchitectedPracticeId": "sec_securely_operate_aws_account","WellArchitectedQuestionId": "securely-operate"}],"description": "The root user is the most privileged user in an AWS account, with full administrative access to all resources within the account, and in some cases cannot be constrained by security policies. Deactivating programmatic access to the root user, establishing appropriate controls for the root user, and avoiding routine use of the root user helps reduce the risk of inadvertent exposure of the root credentials and subsequent compromise of the cloud environment.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"SEC01-BP03": {"name": "SEC01-BP03","checks": {},"status": "PASS","attributes": [{"Name": "SEC01-BP03 Identify and validate control objectives","Section": "Security foundations","SubSection": "Operating your workloads securely","Description": "Based on your compliance requirements and risks identified from your threat model, derive and validate the control objectives and controls that you need to apply to your workload. Ongoing validation of control objectives and controls help you measure the effectiveness of risk mitigation.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_control_objectives.html#implementation-guidance.","WellArchitectedPracticeId": "sec_securely_operate_control_objectives","WellArchitectedQuestionId": "securely-operate"}],"description": "Based on your compliance requirements and risks identified from your threat model, derive and validate the control objectives and controls that you need to apply to your workload. Ongoing validation of control objectives and controls help you measure the effectiveness of risk mitigation.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC01-BP04": {"name": "SEC01-BP04","checks": {},"status": "PASS","attributes": [{"Name": "SEC01-BP04 Keep up-to-date with security threats","Section": "Security foundations","SubSection": "Operating your workloads securely","Description": "To help you define and implement appropriate controls, recognize attack vectors by staying up to date with the latest security threats. Consume AWS Managed Services to make it easier to receive notification of unexpected or unusual behavior in your AWS accounts. Investigate using AWS Partner tools or third-party threat information feeds as part of your security information flow. The Common Vulnerabilities and Exposures (CVE) Listlist contains publicly disclosed cyber security vulnerabilities that you can use to stay up to date.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_updated_threats.html#implementation-guidance.","WellArchitectedPracticeId": "sec_securely_operate_updated_threats","WellArchitectedQuestionId": "securely-operate"}],"description": "To help you define and implement appropriate controls, recognize attack vectors by staying up to date with the latest security threats. Consume AWS Managed Services to make it easier to receive notification of unexpected or unusual behavior in your AWS accounts. Investigate using AWS Partner tools or third-party threat information feeds as part of your security information flow. The Common Vulnerabilities and Exposures (CVE) Listlist contains publicly disclosed cyber security vulnerabilities that you can use to stay up to date.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC01-BP05": {"name": "SEC01-BP05","checks": {},"status": "PASS","attributes": [{"Name": "SEC01-BP05 Keep up-to-date with security recommendations","Section": "Security foundations","SubSection": "Operating your workloads securely","Description": "Stay up-to-date with both AWS and industry security recommendations to evolve the security posture of your workload. AWS Security Bulletins contain important information about security and privacy notifications.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_updated_recommendations.html#implementation-guidance.","WellArchitectedPracticeId": "sec_securely_operate_updated_recommendations","WellArchitectedQuestionId": "securely-operate"}],"description": "Stay up-to-date with both AWS and industry security recommendations to evolve the security posture of your workload. AWS Security Bulletins contain important information about security and privacy notifications.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC01-BP06": {"name": "SEC01-BP06","checks": {"ec2_instance_managed_by_ssm": "FAIL","ecr_repositories_scan_images_on_push_enabled": "FAIL","ecr_repositories_scan_vulnerabilities_in_latest_image": null},"status": "FAIL","attributes": [{"Name": "SEC01-BP06 Automate testing and validation of security controls in pipelines","Section": "Security foundations","SubSection": "Operating your workloads securely","Description": "Establish secure baselines and templates for security mechanisms that are tested and validated as part of your build, pipelines, and processes. Use tools and automation to test and validate all security controls continuously. For example, scan items such as machine images and infrastructure-as-code templates for security vulnerabilities, irregularities, and drift from an established baseline at each stage. AWS CloudFormation Guard can help you verify that CloudFormation templates are safe, save you time, and reduce the risk of configuration error.Reducing the number of security misconfigurations introduced into a production environment is critical—the more quality control and reduction of defects you can perform in the build process, the better. Design continuous integration and continuous deployment (CI/CD) pipelines to test for security issues whenever possible. CI/CD pipelines offer the opportunity to enhance security at each stage of build and delivery. CI/CD security tooling must also be kept updated to mitigate evolving threats.Track changes to your workload configuration to help with compliance auditing, change management, and investigations that may apply to you. You can use AWS Config to record and evaluate your AWS and third-party resources. It allows you to continuously audit and assess the overall compliance with rules and conformance packs, which are collections of rules with remediation actions.Change tracking should include planned changes, which are part of your organization's change control process (sometimes referred to as MACD—Move, Add, Change, Delete), unplanned changes, and unexpected changes, such as incidents. Changes might occur on the infrastructure, but they might also be related to other categories, such as changes in code repositories, machine images and application inventory changes, process and policy changes, or documentation changes.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_test_validate_pipeline.html#implementation-guidance.","WellArchitectedPracticeId": "sec_securely_operate_test_validate_pipeline","WellArchitectedQuestionId": "securely-operate"}],"description": "Establish secure baselines and templates for security mechanisms that are tested and validated as part of your build, pipelines, and processes. Use tools and automation to test and validate all security controls continuously. For example, scan items such as machine images and infrastructure-as-code templates for security vulnerabilities, irregularities, and drift from an established baseline at each stage. AWS CloudFormation Guard can help you verify that CloudFormation templates are safe, save you time, and reduce the risk of configuration error.Reducing the number of security misconfigurations introduced into a production environment is critical—the more quality control and reduction of defects you can perform in the build process, the better. Design continuous integration and continuous deployment (CI/CD) pipelines to test for security issues whenever possible. CI/CD pipelines offer the opportunity to enhance security at each stage of build and delivery. CI/CD security tooling must also be kept updated to mitigate evolving threats.Track changes to your workload configuration to help with compliance auditing, change management, and investigations that may apply to you. You can use AWS Config to record and evaluate your AWS and third-party resources. It allows you to continuously audit and assess the overall compliance with rules and conformance packs, which are collections of rules with remediation actions.Change tracking should include planned changes, which are part of your organization's change control process (sometimes referred to as MACD—Move, Add, Change, Delete), unplanned changes, and unexpected changes, such as incidents. Changes might occur on the infrastructure, but they might also be related to other categories, such as changes in code repositories, machine images and application inventory changes, process and policy changes, or documentation changes.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"SEC01-BP07": {"name": "SEC01-BP07","checks": {"wellarchitected_workload_no_high_or_medium_risks": "FAIL"},"status": "FAIL","attributes": [{"Name": "SEC01-BP07 Identify threats and prioritize mitigations using a threat model","Section": "Security foundations","SubSection": "Operating your workloads securely","Description": "Perform threat modeling to identify and maintain an up-to-date register of potential threats and associated mitigations for your workload. Prioritize your threats and adapt your security control mitigations to prevent, detect, and respond. Revisit and maintain this in the context of your workload, and the evolving security landscape.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_threat_model.html#implementation-guidance.","WellArchitectedPracticeId": "sec_securely_operate_threat_model","WellArchitectedQuestionId": "securely-operate"}],"description": "Perform threat modeling to identify and maintain an up-to-date register of potential threats and associated mitigations for your workload. Prioritize your threats and adapt your security control mitigations to prevent, detect, and respond. Revisit and maintain this in the context of your workload, and the evolving security landscape.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"SEC01-BP08": {"name": "SEC01-BP08","checks": {},"status": "PASS","attributes": [{"Name": "SEC01-BP08 Evaluate and implement new security services and features regularly","Section": "Security foundations","SubSection": "Operating your workloads securely","Description": "Evaluate and implement security services and features from AWS and AWS Partners that allow you to evolve the security posture of your workload. The AWS Security Blog highlights new AWS services and features, implementation guides, and general security guidance. What's New with AWS? is a great way to stay up to date with all new AWS features, services, and announcements.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_implement_services_features.html#implementation-guidance.","WellArchitectedPracticeId": "sec_securely_operate_implement_services_features","WellArchitectedQuestionId": "securely-operate"}],"description": "Evaluate and implement security services and features from AWS and AWS Partners that allow you to evolve the security posture of your workload. The AWS Security Blog highlights new AWS services and features, implementation guides, and general security guidance. What's New with AWS? is a great way to stay up to date with all new AWS features, services, and announcements.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC02-BP01": {"name": "SEC02-BP01","checks": {"iam_avoid_root_usage": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_user_hardware_mfa_enabled": null,"iam_user_two_active_access_key": null,"iam_user_mfa_enabled_console_access": null,"iam_user_no_setup_initial_access_key": null,"iam_password_policy_minimum_length_14": null,"directoryservice_supported_mfa_radius_enabled": null,"directoryservice_radius_server_security_protocol": null,"sagemaker_notebook_instance_root_access_disabled": null,"opensearch_service_domains_use_cognito_authentication_for_kibana": null},"status": "PASS","attributes": [{"Name": "SEC02-BP01 Use strong sign-in mechanisms","Section": "Identity and access management","SubSection": "Identity management","Description": "Sign-ins (authentication using sign-in credentials) can present risks when not using mechanisms like multi-factor authentication (MFA), especially in situations where sign-in credentials have been inadvertently disclosed or are easily guessed. Use strong sign-in mechanisms to reduce these risks by requiring MFA and strong password policies.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_identities_enforce_mechanisms.html#implementation-guidance.","WellArchitectedPracticeId": "sec_identities_enforce_mechanisms","WellArchitectedQuestionId": "identities"}],"description": "Sign-ins (authentication using sign-in credentials) can present risks when not using mechanisms like multi-factor authentication (MFA), especially in situations where sign-in credentials have been inadvertently disclosed or are easily guessed. Use strong sign-in mechanisms to reduce these risks by requiring MFA and strong password policies.","checks_status": {"fail": 0,"pass": 0,"total": 15,"manual": 0}},"SEC02-BP02": {"name": "SEC02-BP02","checks": {"iam_rotate_access_key_90_days": null},"status": "PASS","attributes": [{"Name": "SEC02-BP02 Use temporary credentials","Section": "Identity and access management","SubSection": "Identity management","Description": "When doing any type of authentication, it’s best to use temporary credentials instead of long-term credentials to reduce or eliminate risks, such as credentials being inadvertently disclosed, shared, or stolen.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_identities_unique.html#implementation-guidance.","WellArchitectedPracticeId": "sec_identities_unique","WellArchitectedQuestionId": "identities"}],"description": "When doing any type of authentication, it’s best to use temporary credentials instead of long-term credentials to reduce or eliminate risks, such as credentials being inadvertently disclosed, shared, or stolen.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"SEC02-BP03": {"name": "SEC02-BP03","checks": {"ssm_document_secrets": "PASS","ec2_instance_secrets_user_data": "PASS","ec2_launch_template_no_secrets": "PASS","awslambda_function_no_secrets_in_code": "PASS","cloudformation_stack_outputs_find_secrets": "PASS","awslambda_function_no_secrets_in_variables": "PASS","ecs_task_definitions_no_environment_secrets": "PASS","autoscaling_find_secrets_ec2_launch_configuration": "PASS"},"status": "PASS","attributes": [{"Name": "SEC02-BP03 Store and use secrets securely","Section": "Identity and access management","SubSection": "Identity management","Description": "A workload requires an automated capability to prove its identity to databases, resources, and third-party services. This is accomplished using secret access credentials, such as API access keys, passwords, and OAuth tokens. Using a purpose-built service to store, manage, and rotate these credentials helps reduce the likelihood that those credentials become compromised.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_identities_secrets.html#implementation-guidance.","WellArchitectedPracticeId": "sec_identities_secrets","WellArchitectedQuestionId": "identities"}],"description": "A workload requires an automated capability to prove its identity to databases, resources, and third-party services. This is accomplished using secret access credentials, such as API access keys, passwords, and OAuth tokens. Using a purpose-built service to store, manage, and rotate these credentials helps reduce the likelihood that those credentials become compromised.","checks_status": {"fail": 0,"pass": 8,"total": 8,"manual": 0}},"SEC02-BP04": {"name": "SEC02-BP04","checks": {"iam_role_cross_service_confused_deputy_prevention": null},"status": "PASS","attributes": [{"Name": "SEC02-BP04 Rely on a centralized identity provider","Section": "Identity and access management","SubSection": "Identity management","Description": "For workforce identities, rely on an identity provider that enables you to manage identities in a centralized place. This makes it easier to manage access across multiple applications and services, because you are creating, managing, and revoking access from a single location. For example, if someone leaves your organization, you can revoke access for all applications and services (including AWS) from one location. This reduces the need for multiple credentials and provides an opportunity to integrate with existing human resources (HR) processes. For federation with individual AWS accounts, you can use centralized identities for AWS with a SAML 2.0-based provider with AWS Identity and Access Management. You can use any provider— whether hosted by you in AWS, external to AWS, or supplied by the AWS Partner—that is compatible with the SAML 2.0 protocol. You can use federation between your AWS account and your chosen provider to grant a user or application access to call AWS API operations by using a SAML assertion to get temporary security credentials. Web-based single sign-on is also supported, allowing users to sign in to the AWS Management Console from your sign in website. For federation to multiple accounts in your AWS Organizations, you can configure your identity source in AWS IAM Identity Center (successor to AWS Single Sign-On) (IAM Identity Center), and specify where your users and groups are stored. Once configured, your identity provider is your source of truth, and information can be synchronized using the System for Cross-domain Identity Management (SCIM) v2.0 protocol. You can then look up users or groups and grant them IAM Identity Center access to AWS accounts, cloud applications, or both. IAM Identity Center integrates with AWS Organizations, which enables you to configure your identity provider once and then grant access to existing and new accounts managed in your organization. IAM Identity Center provides you with a default store, which you can use to manage your users and groups. If you choose to use the IAM Identity Center store, create your users and groups and assign their level of access to your AWS accounts and applications, keeping in mind the best practice of least privilege. Alternatively, you can choose to Connect to Your External Identity Provider using SAML 2.0, or Connect to Your Microsoft AD Directory using AWS Directory Service. Once configured, you can sign into the AWS Management Console, or the AWS mobile app, by authenticating through your central identity provider. For managing end-users or consumers of your workloads, such as a mobile app, you can use Amazon Cognito. It provides authentication, authorization, and user management for your web and mobile apps. Your users can sign in directly with sign-in credentials, or through a third party, such as Amazon, Apple, Facebook, or Google.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_identities_identity_provider.html#implementation-guidance.","WellArchitectedPracticeId": "sec_identities_identity_provider","WellArchitectedQuestionId": "identities"}],"description": "For workforce identities, rely on an identity provider that enables you to manage identities in a centralized place. This makes it easier to manage access across multiple applications and services, because you are creating, managing, and revoking access from a single location. For example, if someone leaves your organization, you can revoke access for all applications and services (including AWS) from one location. This reduces the need for multiple credentials and provides an opportunity to integrate with existing human resources (HR) processes. For federation with individual AWS accounts, you can use centralized identities for AWS with a SAML 2.0-based provider with AWS Identity and Access Management. You can use any provider— whether hosted by you in AWS, external to AWS, or supplied by the AWS Partner—that is compatible with the SAML 2.0 protocol. You can use federation between your AWS account and your chosen provider to grant a user or application access to call AWS API operations by using a SAML assertion to get temporary security credentials. Web-based single sign-on is also supported, allowing users to sign in to the AWS Management Console from your sign in website. For federation to multiple accounts in your AWS Organizations, you can configure your identity source in AWS IAM Identity Center (successor to AWS Single Sign-On) (IAM Identity Center), and specify where your users and groups are stored. Once configured, your identity provider is your source of truth, and information can be synchronized using the System for Cross-domain Identity Management (SCIM) v2.0 protocol. You can then look up users or groups and grant them IAM Identity Center access to AWS accounts, cloud applications, or both. IAM Identity Center integrates with AWS Organizations, which enables you to configure your identity provider once and then grant access to existing and new accounts managed in your organization. IAM Identity Center provides you with a default store, which you can use to manage your users and groups. If you choose to use the IAM Identity Center store, create your users and groups and assign their level of access to your AWS accounts and applications, keeping in mind the best practice of least privilege. Alternatively, you can choose to Connect to Your External Identity Provider using SAML 2.0, or Connect to Your Microsoft AD Directory using AWS Directory Service. Once configured, you can sign into the AWS Management Console, or the AWS mobile app, by authenticating through your central identity provider. For managing end-users or consumers of your workloads, such as a mobile app, you can use Amazon Cognito. It provides authentication, authorization, and user management for your web and mobile apps. Your users can sign in directly with sign-in credentials, or through a third party, such as Amazon, Apple, Facebook, or Google.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"SEC02-BP05": {"name": "SEC02-BP05","checks": {"kms_cmk_rotation_enabled": null,"iam_rotate_access_key_90_days": null,"secretsmanager_automatic_rotation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Name": "SEC02-BP05 Audit and rotate credentials periodically","Section": "Identity and access management","SubSection": "Identity management","Description": "When you cannot rely on temporary credentials and require long-term credentials, audit credentials to ensure that the defined controls for example, multi-factor authentication (MFA), are enforced, rotated regularly, and have the appropriate access level. Periodic validation, preferably through an automated tool, is necessary to verify that the correct controls are enforced. For human identities, you should require users to change their passwords periodically and retire access keys in favor of temporary credentials. As you are moving from users to centralized identities, you can generate a credential report to audit your users. We also recommend that you enforce MFA settings in your identity provider. You can set up AWS Config Rules to monitor these settings. For machine identities, you should rely on temporary credentials using IAM roles. For situations where this is not possible, frequent auditing and rotating access keys is necessary.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_identities_audit.html#implementation-guidance.","WellArchitectedPracticeId": "sec_identities_audit","WellArchitectedQuestionId": "identities"}],"description": "When you cannot rely on temporary credentials and require long-term credentials, audit credentials to ensure that the defined controls for example, multi-factor authentication (MFA), are enforced, rotated regularly, and have the appropriate access level. Periodic validation, preferably through an automated tool, is necessary to verify that the correct controls are enforced. For human identities, you should require users to change their passwords periodically and retire access keys in favor of temporary credentials. As you are moving from users to centralized identities, you can generate a credential report to audit your users. We also recommend that you enforce MFA settings in your identity provider. You can set up AWS Config Rules to monitor these settings. For machine identities, you should rely on temporary credentials using IAM roles. For situations where this is not possible, frequent auditing and rotating access keys is necessary.","checks_status": {"fail": 1,"pass": 0,"total": 3,"manual": 0}},"SEC02-BP06": {"name": "SEC02-BP06","checks": {"iam_policy_allows_privilege_escalation": null,"iam_policy_attached_only_to_group_or_roles": null},"status": "PASS","attributes": [{"Name": "SEC02-BP06 Leverage user groups and attributes","Section": "Identity and access management","SubSection": "Identity management","Description": "As the number of users you manage grows, you will need to determine ways to organize them so that you can manage them at scale. Place users with common security requirements in groups defined by your identity provider, and put mechanisms in place to ensure that user attributes that may be used for access control (for example, department or location) are correct and updated. Use these groups and attributes to control access, rather than individual users. This allows you to manage access centrally by changing a user's group membership or attributes once with a permission set, rather than updating many individual policies when a user's access needs change. You can use AWS IAM Identity Center (successor to AWS Single Sign-On) (IAM Identity Center) to manage user groups and attributes. IAM Identity Center supports most commonly used attributes whether they are entered manually during user creation or automatically provisioned using a synchronization engine, such as defined in the System for Cross-Domain Identity Management (SCIM) specification.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_identities_groups_attributes.html#implementation-guidance.","WellArchitectedPracticeId": "sec_identities_groups_attributes","WellArchitectedQuestionId": "identities"}],"description": "As the number of users you manage grows, you will need to determine ways to organize them so that you can manage them at scale. Place users with common security requirements in groups defined by your identity provider, and put mechanisms in place to ensure that user attributes that may be used for access control (for example, department or location) are correct and updated. Use these groups and attributes to control access, rather than individual users. This allows you to manage access centrally by changing a user's group membership or attributes once with a permission set, rather than updating many individual policies when a user's access needs change. You can use AWS IAM Identity Center (successor to AWS Single Sign-On) (IAM Identity Center) to manage user groups and attributes. IAM Identity Center supports most commonly used attributes whether they are entered manually during user creation or automatically provisioned using a synchronization engine, such as defined in the System for Cross-Domain Identity Management (SCIM) specification.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"SEC03-BP01": {"name": "SEC03-BP01","checks": {"ec2_instance_imdsv2_enabled": "PASS","ec2_instance_profile_attached": "PASS","cloudwatch_cross_account_sharing_disabled": null},"status": "PASS","attributes": [{"Name": "SEC03-BP01 Define access requirements","Section": "Identity and access management","SubSection": "Permissions management","Description": "Each component or resource of your workload needs to be accessed by administrators, end users, or other components. Have a clear definition of who or what should have access to each component, choose the appropriate identity type and method of authentication and authorization.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_permissions_define.html#implementation-guidance.","WellArchitectedPracticeId": "sec_permissions_define","WellArchitectedQuestionId": "permissions"}],"description": "Each component or resource of your workload needs to be accessed by administrators, end users, or other components. Have a clear definition of who or what should have access to each component, choose the appropriate identity type and method of authentication and authorization.","checks_status": {"fail": 0,"pass": 2,"total": 3,"manual": 0}},"SEC03-BP02": {"name": "SEC03-BP02","checks": {"ec2_instance_profile_attached": "PASS","iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"opensearch_service_domains_internal_user_database_enabled": null,"iam_customer_unattached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Name": "SEC03-BP02 Grant least privilege access","Section": "Identity and access management","SubSection": "Permissions management","Description": "Grant only the access that identities require by allowing access to specific actions on specific AWS resources under specific conditions. Rely on groups and identity attributes to dynamically set permissions at scale, rather than defining permissions for individual users. For example, you can allow a group of developers access to manage only resources for their project. This way, when a developer is removed from the group, access for the developer is revoked everywhere that group was used for access control, without requiring any changes to the access policies.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_permissions_least_privileges.html#implementation-guidance.","WellArchitectedPracticeId": "sec_permissions_least_privileges","WellArchitectedQuestionId": "permissions"}],"description": "Grant only the access that identities require by allowing access to specific actions on specific AWS resources under specific conditions. Rely on groups and identity attributes to dynamically set permissions at scale, rather than defining permissions for individual users. For example, you can allow a group of developers access to manage only resources for their project. This way, when a developer is removed from the group, access for the developer is revoked everywhere that group was used for access control, without requiring any changes to the access policies.","checks_status": {"fail": 0,"pass": 1,"total": 6,"manual": 0}},"SEC03-BP03": {"name": "SEC03-BP03","checks": {"account_maintain_current_contact_details": null,"account_security_contact_information_is_registered": null,"account_security_questions_are_registered_in_the_aws_account": null},"status": "PASS","attributes": [{"Name": "SEC03-BP03 Establish emergency access process","Section": "Identity and access management","SubSection": "Permissions management","Description": "A process that allows emergency access to your workload in the unlikely event of an automated process or pipeline issue. This will help you rely on least privilege access, but ensure users can obtain the right level of access when they require it. For example, establish a process for administrators to verify and approve their request, such as an emergency AWS cross-account role for access, or a specific process for administrators to follow to validate and approve an emergency request.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_permissions_emergency_process.html#implementation-guidance.","WellArchitectedPracticeId": "sec_permissions_emergency_process","WellArchitectedQuestionId": "permissions"}],"description": "A process that allows emergency access to your workload in the unlikely event of an automated process or pipeline issue. This will help you rely on least privilege access, but ensure users can obtain the right level of access when they require it. For example, establish a process for administrators to verify and approve their request, such as an emergency AWS cross-account role for access, or a specific process for administrators to follow to validate and approve an emergency request.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"SEC03-BP04": {"name": "SEC03-BP04","checks": {"iam_customer_attached_policy_no_administrative_privileges": null,"iam_customer_unattached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Name": "SEC03-BP04 Reduce permissions continuously","Section": "Identity and access management","SubSection": "Permissions management","Description": "As your teams determine what access is required, remove unneeded permissions and establish review processes to achieve least privilege permissions. Continually monitor and remove unused identities and permissions for both human and machine access.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_permissions_continuous_reduction.html#implementation-guidance.","WellArchitectedPracticeId": "sec_permissions_continuous_reduction","WellArchitectedQuestionId": "permissions"}],"description": "As your teams determine what access is required, remove unneeded permissions and establish review processes to achieve least privilege permissions. Continually monitor and remove unused identities and permissions for both human and machine access.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"SEC03-BP05": {"name": "SEC03-BP05","checks": {"organizations_account_part_of_organizations": null},"status": "PASS","attributes": [{"Name": "SEC03-BP05 Define permission guardrails for your organization","Section": "Identity and access management","SubSection": "Permissions management","Description": "Establish common controls that restrict access to all identities in your organization. For example, you can restrict access to specific AWS Regions, or prevent your operators from deleting common resources, such as an IAM role used for your central security team.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_permissions_define_guardrails.html#implementation-guidance.","WellArchitectedPracticeId": "sec_permissions_define_guardrails","WellArchitectedQuestionId": "permissions"}],"description": "Establish common controls that restrict access to all identities in your organization. For example, you can restrict access to specific AWS Regions, or prevent your operators from deleting common resources, such as an IAM role used for your central security team.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"SEC03-BP06": {"name": "SEC03-BP06","checks": {"ec2_elastic_ip_unassigned": "FAIL","elbv2_listeners_underneath": "PASS","codebuild_project_older_90_days": "FAIL","appstream_fleet_maximum_session_duration": null,"ecr_repositories_lifecycle_policy_enabled": "FAIL","appstream_fleet_session_disconnect_timeout": null,"appstream_fleet_session_idle_disconnect_timeout": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "FAIL","attributes": [{"Name": "SEC03-BP06 Manage access based on lifecycle","Section": "Identity and access management","SubSection": "Permissions management","Description": "Integrate access controls with operator and application lifecycle and your centralized federation provider. For example, remove a user's access when they leave the organization or change roles. As you manage workloads using separate accounts, there will be cases where you need to share resources between those accounts. We recommend that you share resources using AWS Resource Access Manager (AWS RAM). This service enables you to easily and securely share AWS resources within your AWS Organizations and Organizational Units. Using AWS RAM, access to shared resources is automatically granted or revoked as accounts are moved in and out of the Organization or Organization Unit with which they are shared. This helps ensure that resources are only shared with the accounts that you intend.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_permissions_lifecycle.html#implementation-guidance.","WellArchitectedPracticeId": "sec_permissions_lifecycle","WellArchitectedQuestionId": "permissions"}],"description": "Integrate access controls with operator and application lifecycle and your centralized federation provider. For example, remove a user's access when they leave the organization or change roles. As you manage workloads using separate accounts, there will be cases where you need to share resources between those accounts. We recommend that you share resources using AWS Resource Access Manager (AWS RAM). This service enables you to easily and securely share AWS resources within your AWS Organizations and Organizational Units. Using AWS RAM, access to shared resources is automatically granted or revoked as accounts are moved in and out of the Organization or Organization Unit with which they are shared. This helps ensure that resources are only shared with the accounts that you intend.","checks_status": {"fail": 4,"pass": 1,"total": 9,"manual": 0}},"SEC03-BP07": {"name": "SEC03-BP07","checks": {"ec2_ami_public": null,"elb_internet_facing": "FAIL","elbv2_internet_facing": "PASS","ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"apigateway_restapi_public": "FAIL","efs_not_publicly_accessible": "FAIL","rds_snapshots_public_access": "PASS","ssm_documents_set_as_public": "PASS","awslambda_function_url_public": null,"rds_instance_no_public_access": "PASS","emr_cluster_publicly_accesible": null,"redshift_cluster_public_access": null,"kms_key_not_publicly_accessible": null,"awslambda_function_url_cors_policy": null,"sns_topics_not_publicly_accessible": "PASS","sqs_queues_not_publicly_accessible": "PASS","eks_cluster_not_publicly_accessible": null,"glacier_vaults_policy_public_access": null,"s3_bucket_policy_public_write_access": "PASS","emr_cluster_master_nodes_no_public_ip": null,"s3_account_level_public_access_blocks": null,"ecr_repositories_not_publicly_accessible": "PASS","emr_cluster_account_public_block_enabled": "PASS","awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","appstream_fleet_default_internet_access_disabled": null,"opensearch_service_domains_not_publicly_accessible": null,"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS","codeartifact_packages_external_public_publishing_disabled": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Name": "SEC03-BP07 Analyze public and cross-account access","Section": "Identity and access management","SubSection": "Permissions management","Description": "Continuously monitor findings that highlight public and cross-account access. Reduce public access and cross-account access to only resources that require this type of access.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_permissions_analyze_cross_account.html#implementation-guidance.","WellArchitectedPracticeId": "sec_permissions_analyze_cross_account","WellArchitectedQuestionId": "permissions"}],"description": "Continuously monitor findings that highlight public and cross-account access. Reduce public access and cross-account access to only resources that require this type of access.","checks_status": {"fail": 4,"pass": 13,"total": 35,"manual": 0}},"SEC03-BP08": {"name": "SEC03-BP08","checks": {"ssm_document_secrets": "PASS","awslambda_function_not_publicly_accessible": "PASS","codebuild_project_user_controlled_buildspec": "PASS","opensearch_service_domains_not_publicly_accessible": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "PASS","attributes": [{"Name": "SEC03-BP08 Share resources securely within your organization","Section": "Identity and access management","SubSection": "Permissions management","Description": "Govern the consumption of shared resources across accounts or within your AWS Organizations. Monitor shared resources and review shared resource access.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_permissions_share_securely.html#implementation-guidance.","WellArchitectedPracticeId": "sec_permissions_share_securely","WellArchitectedQuestionId": "permissions"}],"description": "Govern the consumption of shared resources across accounts or within your AWS Organizations. Monitor shared resources and review shared resource access.","checks_status": {"fail": 0,"pass": 3,"total": 5,"manual": 0}},"SEC04-BP01": {"name": "SEC04-BP01","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"apigatewayv2_api_access_logging_enabled": "FAIL","s3_bucket_server_access_logging_enabled": "FAIL","cloudfront_distributions_logging_enabled": null,"rds_instance_integration_cloudwatch_logs": "FAIL","acm_certificates_transparency_logs_enabled": "PASS","eks_control_plane_logging_all_types_enabled": null,"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL","opensearch_service_domains_audit_logging_enabled": null,"directoryservice_directory_log_forwarding_enabled": null,"opensearch_service_domains_cloudwatch_logging_enabled": null,"route53_public_hosted_zones_cloudwatch_logging_enabled": null,"awslambda_function_invoke_api_operations_cloudtrail_logging_enabled": "PASS"},"status": "FAIL","attributes": [{"Name": "SEC04-BP01 Configure service and application logging","Section": "Detection","SubSection": "Detection","Description": "Retain security event logs from services and applications. This is a fundamental principle of security for audit, investigations, and operational use cases, and a common security requirement driven by governance, risk, and compliance (GRC) standards, policies, and procedures.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_detect_investigate_events_app_service_logging.html#implementation-guidance.","WellArchitectedPracticeId": "sec_detect_investigate_events_app_service_logging","WellArchitectedQuestionId": "detect-investigate-events"}],"description": "Retain security event logs from services and applications. This is a fundamental principle of security for audit, investigations, and operational use cases, and a common security requirement driven by governance, risk, and compliance (GRC) standards, policies, and procedures.","checks_status": {"fail": 8,"pass": 3,"total": 21,"manual": 0}},"SEC04-BP02": {"name": "SEC04-BP02","checks": {"vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS","config_recorder_all_regions_enabled": null},"status": "FAIL","attributes": [{"Name": "SEC04-BP02 Analyze logs, findings, and metrics centrally","Section": "Detection","SubSection": "Detection","Description": "Security operations teams rely on the collection of logs and the use of search tools to discover potential events of interest, which might indicate unauthorized activity or unintentional change. However, simply analyzing collected data and manually processing information is insufficient to keep up with the volume of information flowing from complex architectures. Analysis and reporting alone don't facilitate the assignment of the right resources to work an event in a timely fashion. A best practice for building a mature security operations team is to deeply integrate the flow of security events and findings into a notification and workflow system such as a ticketing system, a bug or issue system, or other security information and event management (SIEM) system. This takes the workflow out of email and static reports, and allows you to route, escalate, and manage events or findings. Many organizations are also integrating security alerts into their chat or collaboration, and developer productivity platforms. For organizations embarking on automation, an API-driven, low-latency ticketing system offers considerable flexibility when planning what to automate first. This best practice applies not only to security events generated from log messages depicting user activity or network events, but also from changes detected in the infrastructure itself. The ability to detect change, determine whether a change was appropriate, and then route that information to the correct remediation workflow is essential in maintaining and validating a secure architecture, in the context of changes where the nature of their undesirability is sufficiently subtle that their execution cannot currently be prevented with a combination of AWS Identity and Access Management (IAM) and AWS Organizations configuration. Amazon GuardDuty and AWS Security Hub provide aggregation, deduplication, and analysis mechanisms for log records that are also made available to you via other AWS services. GuardDuty ingests, aggregates, and analyzes information from sources such as AWS CloudTrail management and data events, VPC DNS logs, and VPC Flow Logs. Security Hub can ingest, aggregate, and analyze output from GuardDuty, AWS Config, Amazon Inspector, Amazon Macie, AWS Firewall Manager, and a significant number of third-party security products available in the AWS Marketplace, and if built accordingly, your own code. Both GuardDuty and Security Hub have an Administrator-Member model that can aggregate findings and insights across multiple accounts, and Security Hub is often used by customers who have an on- premises SIEM as an AWS-side log and alert preprocessor and aggregator from which they can then ingest Amazon EventBridge through a AWS Lambda-based processor and forwarder.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_detect_investigate_events_analyze_all.html#implementation-guidance.","WellArchitectedPracticeId": "sec_detect_investigate_events_analyze_all","WellArchitectedQuestionId": "detect-investigate-events"}],"description": "Security operations teams rely on the collection of logs and the use of search tools to discover potential events of interest, which might indicate unauthorized activity or unintentional change. However, simply analyzing collected data and manually processing information is insufficient to keep up with the volume of information flowing from complex architectures. Analysis and reporting alone don't facilitate the assignment of the right resources to work an event in a timely fashion. A best practice for building a mature security operations team is to deeply integrate the flow of security events and findings into a notification and workflow system such as a ticketing system, a bug or issue system, or other security information and event management (SIEM) system. This takes the workflow out of email and static reports, and allows you to route, escalate, and manage events or findings. Many organizations are also integrating security alerts into their chat or collaboration, and developer productivity platforms. For organizations embarking on automation, an API-driven, low-latency ticketing system offers considerable flexibility when planning what to automate first. This best practice applies not only to security events generated from log messages depicting user activity or network events, but also from changes detected in the infrastructure itself. The ability to detect change, determine whether a change was appropriate, and then route that information to the correct remediation workflow is essential in maintaining and validating a secure architecture, in the context of changes where the nature of their undesirability is sufficiently subtle that their execution cannot currently be prevented with a combination of AWS Identity and Access Management (IAM) and AWS Organizations configuration. Amazon GuardDuty and AWS Security Hub provide aggregation, deduplication, and analysis mechanisms for log records that are also made available to you via other AWS services. GuardDuty ingests, aggregates, and analyzes information from sources such as AWS CloudTrail management and data events, VPC DNS logs, and VPC Flow Logs. Security Hub can ingest, aggregate, and analyze output from GuardDuty, AWS Config, Amazon Inspector, Amazon Macie, AWS Firewall Manager, and a significant number of third-party security products available in the AWS Marketplace, and if built accordingly, your own code. Both GuardDuty and Security Hub have an Administrator-Member model that can aggregate findings and insights across multiple accounts, and Security Hub is often used by customers who have an on- premises SIEM as an AWS-side log and alert preprocessor and aggregator from which they can then ingest Amazon EventBridge through a AWS Lambda-based processor and forwarder.","checks_status": {"fail": 1,"pass": 1,"total": 3,"manual": 0}},"SEC04-BP03": {"name": "SEC04-BP03","checks": {"elb_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","cloudtrail_multi_region_enabled": "PASS"},"status": "FAIL","attributes": [{"Name": "SEC04-BP03 Automate response to events","Section": "Detection","SubSection": "Detection","Description": "Using automation to investigate and remediate events reduces human effort and error, and enables you to scale investigation capabilities. Regular reviews will help you tune automation tools, and continuously iterate. In AWS, investigating events of interest and information on potentially unexpected changes into an automated workflow can be achieved using Amazon EventBridge. This service provides a scalable rules engine designed to broker both native AWS event formats (such as AWS CloudTrail events), as well as custom events you can generate from your application. Amazon GuardDuty also allows you to route events to a workflow system for those building incident response systems (AWS Step Functions), or to a central Security Account, or to a bucket for further analysis. Detecting change and routing this information to the correct workflow can also be accomplished using AWS Config Rules and Conformance Packs. AWS Config detects changes to in-scope services (though with higher latency than EventBridge) and generates events that can be parsed using AWS Config Rules for rollback, enforcement of compliance policy, and forwarding of information to systems, such as change management platforms and operational ticketing systems. As well as writing your own Lambda functions to respond to AWS Config events, you can also take advantage of the AWS Config Rules Development Kit, and a library of open source AWS Config Rules. Conformance packs are a collection of AWS Config Rules and remediation actions you deploy as a single entity authored as a YAML template. A sample conformance pack template is available for the Well-Architected Security Pillar.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_detect_investigate_events_auto_response.html#implementation-guidance.","WellArchitectedPracticeId": "sec_detect_investigate_events_auto_response","WellArchitectedQuestionId": "detect-investigate-events"}],"description": "Using automation to investigate and remediate events reduces human effort and error, and enables you to scale investigation capabilities. Regular reviews will help you tune automation tools, and continuously iterate. In AWS, investigating events of interest and information on potentially unexpected changes into an automated workflow can be achieved using Amazon EventBridge. This service provides a scalable rules engine designed to broker both native AWS event formats (such as AWS CloudTrail events), as well as custom events you can generate from your application. Amazon GuardDuty also allows you to route events to a workflow system for those building incident response systems (AWS Step Functions), or to a central Security Account, or to a bucket for further analysis. Detecting change and routing this information to the correct workflow can also be accomplished using AWS Config Rules and Conformance Packs. AWS Config detects changes to in-scope services (though with higher latency than EventBridge) and generates events that can be parsed using AWS Config Rules for rollback, enforcement of compliance policy, and forwarding of information to systems, such as change management platforms and operational ticketing systems. As well as writing your own Lambda functions to respond to AWS Config events, you can also take advantage of the AWS Config Rules Development Kit, and a library of open source AWS Config Rules. Conformance packs are a collection of AWS Config Rules and remediation actions you deploy as a single entity authored as a YAML template. A sample conformance pack template is available for the Well-Architected Security Pillar.","checks_status": {"fail": 2,"pass": 1,"total": 3,"manual": 0}},"SEC04-BP04": {"name": "SEC04-BP04","checks": {"macie_is_enabled": "PASS","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"directoryservice_directory_monitor_notifications": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Name": "SEC04-BP04 Implement actionable security events","Section": "Detection","SubSection": "Detection","Description": "Create alerts that are sent to and can be actioned by your team. Ensure that alerts include relevant information for the team to take action. For each detective mechanism you have, you should also have a process, in the form of a runbook or playbook, to investigate. For example, when you enable Amazon GuardDuty, it generates different findings. You should have a runbook entry for each finding type, for example, if a trojan is discovered, your runbook has simple instructions that instruct someone to investigate and remediate.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_detect_investigate_events_actionable_events.html#implementation-guidance.","WellArchitectedPracticeId": "sec_detect_investigate_events_actionable_events","WellArchitectedQuestionId": "detect-investigate-events"}],"description": "Create alerts that are sent to and can be actioned by your team. Ensure that alerts include relevant information for the team to take action. For each detective mechanism you have, you should also have a process, in the form of a runbook or playbook, to investigate. For example, when you enable Amazon GuardDuty, it generates different findings. You should have a runbook entry for each finding type, for example, if a trojan is discovered, your runbook has simple instructions that instruct someone to investigate and remediate.","checks_status": {"fail": 1,"pass": 3,"total": 20,"manual": 0}},"SEC05-BP01": {"name": "SEC05-BP01","checks": {"cloudfront_distributions_using_waf": null,"apigateway_restapi_waf_acl_attached": "FAIL","eks_cluster_not_publicly_accessible": null,"sagemaker_models_vpc_settings_configured": null,"vpc_endpoint_connections_trust_boundaries": "FAIL","awslambda_function_not_publicly_accessible": "PASS","sagemaker_models_network_isolation_enabled": null,"sagemaker_training_jobs_vpc_settings_configured": null,"sagemaker_training_jobs_network_isolation_enabled": null,"opensearch_service_domains_not_publicly_accessible": null,"sagemaker_notebook_instance_vpc_settings_configured": null,"vpc_endpoint_services_allowed_principals_trust_boundaries": null},"status": "FAIL","attributes": [{"Name": "SEC05-BP01 Create network layers","Section": "Infrastructure protection","SubSection": "Protecting networks","Description": "Group components that share reachability requirements into layers. For example, a database cluster in a virtual private cloud (VPC) with no need for internet access should be placed in subnets with no route to or from the internet. In a serverless workload operating without a VPC, similar layering and segmentation with microservices can achieve the same goal. Components such as Amazon Elastic Compute Cloud (Amazon EC2) instances, Amazon Relational Database Service (Amazon RDS) database clusters, and AWS Lambda functions that share reachability requirements can be segmented into layers formed by subnets. For example, an Amazon RDS database cluster in a VPC with no need for internet access should be placed in subnets with no route to or from the internet. This layered approach for the controls mitigates the impact of a single layer misconfiguration, which could allow unintended access. For Lambda, you can run your functions in your VPC to take advantage of VPC-based controls. For network connectivity that can include thousands of VPCs, AWS accounts, and on-premises networks, you should use AWS Transit Gateway. It acts as a hub that controls how traffic is routed among all the connected networks, which act like spokes. Traffic between an Amazon Virtual Private Cloud and AWS Transit Gateway remains on the AWS private network, which reduces external threat vectors such as distributed denial of service (DDoS) attacks and common exploits, such as SQL injection, cross-site scripting, cross-site request forgery, or abuse of broken authentication code. AWS Transit Gateway inter-region peering also encrypts inter-region traffic with no single point of failure or bandwidth bottleneck.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_network_protection_create_layers.html#implementation-guidance.","WellArchitectedPracticeId": "sec_network_protection_create_layers","WellArchitectedQuestionId": "network-protection"}],"description": "Group components that share reachability requirements into layers. For example, a database cluster in a virtual private cloud (VPC) with no need for internet access should be placed in subnets with no route to or from the internet. In a serverless workload operating without a VPC, similar layering and segmentation with microservices can achieve the same goal. Components such as Amazon Elastic Compute Cloud (Amazon EC2) instances, Amazon Relational Database Service (Amazon RDS) database clusters, and AWS Lambda functions that share reachability requirements can be segmented into layers formed by subnets. For example, an Amazon RDS database cluster in a VPC with no need for internet access should be placed in subnets with no route to or from the internet. This layered approach for the controls mitigates the impact of a single layer misconfiguration, which could allow unintended access. For Lambda, you can run your functions in your VPC to take advantage of VPC-based controls. For network connectivity that can include thousands of VPCs, AWS accounts, and on-premises networks, you should use AWS Transit Gateway. It acts as a hub that controls how traffic is routed among all the connected networks, which act like spokes. Traffic between an Amazon Virtual Private Cloud and AWS Transit Gateway remains on the AWS private network, which reduces external threat vectors such as distributed denial of service (DDoS) attacks and common exploits, such as SQL injection, cross-site scripting, cross-site request forgery, or abuse of broken authentication code. AWS Transit Gateway inter-region peering also encrypts inter-region traffic with no single point of failure or bandwidth bottleneck.","checks_status": {"fail": 2,"pass": 1,"total": 12,"manual": 0}},"SEC05-BP02": {"name": "SEC05-BP02","checks": {"ec2_ebs_public_snapshot": "PASS","s3_bucket_no_mfa_delete": "FAIL","s3_bucket_acl_prohibited": "FAIL","apigatewayv2_api_authorizers_enabled": "FAIL","apigateway_restapi_authorizers_enabled": "PASS","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Name": "SEC05-BP02 Control traffic at all layers","Section": "Infrastructure protection","SubSection": "Protecting networks","Description": "When architecting your network topology, you should examine the connectivity requirements of each component. For example, if a component requires internet accessibility (inbound and outbound), connectivity to VPCs, edge services, and external data centers. A VPC allows you to define your network topology that spans an AWS Region with a private IPv4 address range that you set, or an IPv6 address range AWS selects. You should apply multiple controls with a defense in depth approach for both inbound and outbound traffic, including the use of security groups (stateful inspection firewall), Network ACLs, subnets, and route tables. Within a VPC, you can create subnets in an Availability Zone. Each subnet can have an associated route table that defines routing rules for managing the paths that traffic takes within the subnet. You can define an internet routable subnet by having a route that goes to an internet or NAT gateway attached to the VPC, or through another VPC. When an instance, Amazon Relational Database Service(Amazon RDS) database, or other service is launched within a VPC, it has its own security group per network interface. This firewall is outside the operating system layer and can be used to define rules for allowed inbound and outbound traffic. You can also define relationships between security groups. For example, instances within a database tier security group only accept traffic from instances within the application tier, by reference to the security groups applied to the instances involved. Unless you are using non-TCP protocols, it shouldn't be necessary to have an Amazon Elastic Compute Cloud(Amazon EC2) instance directly accessible by the internet (even with ports restricted by security groups) without a load balancer, or CloudFront. This helps protect it from unintended access through an operating system or application issue. A subnet can also have a network ACL attached to it, which acts as a stateless firewall. You should configure the network ACL to narrow the scope of traffic allowed between layers, note that you need to define both inbound and outbound rules. Some AWS services require components to access the internet for making API calls, where AWS API endpoints are located. Other AWS services use VPC endpoints within your Amazon VPCs. Many AWS services, including Amazon S3 and Amazon DynamoDB, support VPC endpoints, and this technology has been generalized in AWS PrivateLink. We recommend you use this approach to access AWS services, third-party services, and your own services hosted in other VPCs securely. All network traffic on AWS PrivateLink stays on the global AWS backbone and never traverses the internet. Connectivity can only be initiated by the consumer of the service, and not by the provider of the service. Using AWS PrivateLink for external service access allows you to create air-gapped VPCs with no internet access and helps protect your VPCs from external threat vectors. Third-party services can use AWS PrivateLink to allow their customers to connect to the services from their VPCs over private IP addresses. For VPC assets that need to make outbound connections to the internet, these can be made outbound only (one-way) through an AWS managed NAT gateway, outbound only internet gateway, or web proxies that you create and manage.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_network_protection_layered.html#implementation-guidance.","WellArchitectedPracticeId": "sec_network_protection_layered","WellArchitectedQuestionId": "network-protection"}],"description": "When architecting your network topology, you should examine the connectivity requirements of each component. For example, if a component requires internet accessibility (inbound and outbound), connectivity to VPCs, edge services, and external data centers. A VPC allows you to define your network topology that spans an AWS Region with a private IPv4 address range that you set, or an IPv6 address range AWS selects. You should apply multiple controls with a defense in depth approach for both inbound and outbound traffic, including the use of security groups (stateful inspection firewall), Network ACLs, subnets, and route tables. Within a VPC, you can create subnets in an Availability Zone. Each subnet can have an associated route table that defines routing rules for managing the paths that traffic takes within the subnet. You can define an internet routable subnet by having a route that goes to an internet or NAT gateway attached to the VPC, or through another VPC. When an instance, Amazon Relational Database Service(Amazon RDS) database, or other service is launched within a VPC, it has its own security group per network interface. This firewall is outside the operating system layer and can be used to define rules for allowed inbound and outbound traffic. You can also define relationships between security groups. For example, instances within a database tier security group only accept traffic from instances within the application tier, by reference to the security groups applied to the instances involved. Unless you are using non-TCP protocols, it shouldn't be necessary to have an Amazon Elastic Compute Cloud(Amazon EC2) instance directly accessible by the internet (even with ports restricted by security groups) without a load balancer, or CloudFront. This helps protect it from unintended access through an operating system or application issue. A subnet can also have a network ACL attached to it, which acts as a stateless firewall. You should configure the network ACL to narrow the scope of traffic allowed between layers, note that you need to define both inbound and outbound rules. Some AWS services require components to access the internet for making API calls, where AWS API endpoints are located. Other AWS services use VPC endpoints within your Amazon VPCs. Many AWS services, including Amazon S3 and Amazon DynamoDB, support VPC endpoints, and this technology has been generalized in AWS PrivateLink. We recommend you use this approach to access AWS services, third-party services, and your own services hosted in other VPCs securely. All network traffic on AWS PrivateLink stays on the global AWS backbone and never traverses the internet. Connectivity can only be initiated by the consumer of the service, and not by the provider of the service. Using AWS PrivateLink for external service access allows you to create air-gapped VPCs with no internet access and helps protect your VPCs from external threat vectors. Third-party services can use AWS PrivateLink to allow their customers to connect to the services from their VPCs over private IP addresses. For VPC assets that need to make outbound connections to the internet, these can be made outbound only (one-way) through an AWS managed NAT gateway, outbound only internet gateway, or web proxies that you create and manage.","checks_status": {"fail": 4,"pass": 2,"total": 7,"manual": 0}},"SEC05-BP03": {"name": "SEC05-BP03","checks": {"elbv2_waf_acl_attached": "FAIL","ec2_securitygroup_not_used": "FAIL","elbv2_desync_mitigation_mode": "FAIL","ec2_securitygroup_from_launch_wizard": "FAIL","route53_domains_transferlock_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","route53_domains_privacy_protection_enabled": null,"ec2_securitygroup_with_many_ingress_egress_rules": "PASS","shield_advanced_protection_in_global_accelerators": null,"shield_advanced_protection_in_route53_hosted_zones": null,"shield_advanced_protection_in_associated_elastic_ips": null,"shield_advanced_protection_in_classic_load_balancers": null,"shield_advanced_protection_in_cloudfront_distributions": null,"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","shield_advanced_protection_in_internet_facing_load_balancers": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Name": "SEC05-BP03 Automate network protections","Section": "Infrastructure protection","SubSection": "Protecting networks","Description": "Automate protection mechanisms to provide a self-defending network based on threat intelligence and anomaly detection. For example, intrusion detection and prevention tools that can adapt to current threats and reduce their impact. A web application firewall is an example of where you can automate network protection, for example, by using the AWS WAF Security Automations solution (https://github.com/awslabs/aws-waf-security-automations) to automatically block requests originating from IP addresses associated with known threat actors.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_network_protection_auto_protect.html#implementation-guidance.","WellArchitectedPracticeId": "sec_network_protection_auto_protect","WellArchitectedQuestionId": "network-protection"}],"description": "Automate protection mechanisms to provide a self-defending network based on threat intelligence and anomaly detection. For example, intrusion detection and prevention tools that can adapt to current threats and reduce their impact. A web application firewall is an example of where you can automate network protection, for example, by using the AWS WAF Security Automations solution (https://github.com/awslabs/aws-waf-security-automations) to automatically block requests originating from IP addresses associated with known threat actors.","checks_status": {"fail": 8,"pass": 16,"total": 33,"manual": 0}},"SEC05-BP04": {"name": "SEC05-BP04","checks": {"guardduty_is_enabled": "PASS","vpc_flow_logs_enabled": "FAIL","apigateway_restapi_authorizers_enabled": "PASS"},"status": "FAIL","attributes": [{"Name": "SEC05-BP04 Implement inspection and protection","Section": "Infrastructure protection","SubSection": "Protecting networks","Description": "Inspect and filter your traffic at each layer. You can inspect your VPC configurations for potential unintended access using VPC Network Access Analyzer. You can specify your network access requirements and identify potential network paths that do not meet them. For components transacting over HTTP-based protocols, a web application firewall can help protect from common attacks. AWS WAF is a web application firewall that lets you monitor and block HTTP(s) requests that match your configurable rules that are forwarded to an Amazon API Gateway API, Amazon CloudFront, or an Application Load Balancer. To get started with AWS WAF, you can use AWS Managed Rules in combination with your own, or use existing partner integrations. For managing AWS WAF, AWS Shield Advanced protections, and Amazon VPC security groups across AWS Organizations, you can use AWS Firewall Manager. It allows you to centrally configure and manage firewall rules across your accounts and applications, making it easier to scale enforcement of common rules. It also enables you to rapidly respond to attacks, using AWS Shield Advanced, or solutions that can automatically block unwanted requests to your web applications. Firewall Manager also works with AWS Network Firewall. AWS Network Firewall is a managed service that uses a rules engine to give you fine-grained control over both stateful and stateless network traffic. It supports the Suricata compatible open source intrusion prevention system (IPS) specifications for rules to help protect your workload.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_network_protection_inspection.html#implementation-guidance.","WellArchitectedPracticeId": "sec_network_protection_inspection","WellArchitectedQuestionId": "network-protection"}],"description": "Inspect and filter your traffic at each layer. You can inspect your VPC configurations for potential unintended access using VPC Network Access Analyzer. You can specify your network access requirements and identify potential network paths that do not meet them. For components transacting over HTTP-based protocols, a web application firewall can help protect from common attacks. AWS WAF is a web application firewall that lets you monitor and block HTTP(s) requests that match your configurable rules that are forwarded to an Amazon API Gateway API, Amazon CloudFront, or an Application Load Balancer. To get started with AWS WAF, you can use AWS Managed Rules in combination with your own, or use existing partner integrations. For managing AWS WAF, AWS Shield Advanced protections, and Amazon VPC security groups across AWS Organizations, you can use AWS Firewall Manager. It allows you to centrally configure and manage firewall rules across your accounts and applications, making it easier to scale enforcement of common rules. It also enables you to rapidly respond to attacks, using AWS Shield Advanced, or solutions that can automatically block unwanted requests to your web applications. Firewall Manager also works with AWS Network Firewall. AWS Network Firewall is a managed service that uses a rules engine to give you fine-grained control over both stateful and stateless network traffic. It supports the Suricata compatible open source intrusion prevention system (IPS) specifications for rules to help protect your workload.","checks_status": {"fail": 1,"pass": 2,"total": 3,"manual": 0}},"SEC06-BP01": {"name": "SEC06-BP01","checks": {"ec2_instance_imdsv2_enabled": "PASS","ssm_managed_compliant_patching": "FAIL","redshift_cluster_automatic_upgrades": null,"cloudtrail_log_file_validation_enabled": "FAIL","rds_instance_minor_version_upgrade_enabled": "PASS","ec2_instance_internet_facing_with_instance_profile": "FAIL","opensearch_service_domains_updated_to_the_latest_service_software_version": null},"status": "FAIL","attributes": [{"Name": "SEC06-BP01 Perform vulnerability management","Section": "Infrastructure protection","SubSection": "Protecting compute","Description": "Frequently scan and patch for vulnerabilities in your code, dependencies, and in your infrastructure to help protect against new threats. Starting with the configuration of your compute infrastructure, you can automate creating and updating resources using AWS CloudFormation. CloudFormation allows you to create templates written in YAML or JSON, either using AWS examples or by writing your own. This allows you to create secure-by-default infrastructure templates that you can verify with CloudFormation Guard, to save you time and reduce the risk of configuration error. You can build your infrastructure and deploy your applications using continuous delivery, for example with AWS CodePipeline, to automate the building, testing, and release. You are responsible for patch management for your AWS resources, including Amazon Elastic Compute Cloud(Amazon EC2) instances, Amazon Machine Images (AMIs), and many other compute resources. For Amazon EC2 instances, AWS Systems Manager Patch Manager automates the process of patching managed instances with both security related and other types of updates. You can use Patch Manager to apply patches for both operating systems and applications. (On Windows Server, application support is limited to updates for Microsoft applications.) You can use Patch Manager to install Service Packs on Windows instances and perform minor version upgrades on Linux instances. You can patch fleets of Amazon EC2 instances or your on-premises servers and virtual machines (VMs) by operating system type. This includes supported versions of Windows Server, Amazon Linux, Amazon Linux 2, CentOS, Debian Server, Oracle Linux, Red Hat Enterprise Linux (RHEL), SUSE Linux Enterprise Server (SLES), and Ubuntu Server. You can scan instances to see only a report of missing patches, or you can scan and automatically install all missing patches.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_network_protection_inspection.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_compute_vulnerability_management","WellArchitectedQuestionId": "protect-compute"}],"description": "Frequently scan and patch for vulnerabilities in your code, dependencies, and in your infrastructure to help protect against new threats. Starting with the configuration of your compute infrastructure, you can automate creating and updating resources using AWS CloudFormation. CloudFormation allows you to create templates written in YAML or JSON, either using AWS examples or by writing your own. This allows you to create secure-by-default infrastructure templates that you can verify with CloudFormation Guard, to save you time and reduce the risk of configuration error. You can build your infrastructure and deploy your applications using continuous delivery, for example with AWS CodePipeline, to automate the building, testing, and release. You are responsible for patch management for your AWS resources, including Amazon Elastic Compute Cloud(Amazon EC2) instances, Amazon Machine Images (AMIs), and many other compute resources. For Amazon EC2 instances, AWS Systems Manager Patch Manager automates the process of patching managed instances with both security related and other types of updates. You can use Patch Manager to apply patches for both operating systems and applications. (On Windows Server, application support is limited to updates for Microsoft applications.) You can use Patch Manager to install Service Packs on Windows instances and perform minor version upgrades on Linux instances. You can patch fleets of Amazon EC2 instances or your on-premises servers and virtual machines (VMs) by operating system type. This includes supported versions of Windows Server, Amazon Linux, Amazon Linux 2, CentOS, Debian Server, Oracle Linux, Red Hat Enterprise Linux (RHEL), SUSE Linux Enterprise Server (SLES), and Ubuntu Server. You can scan instances to see only a report of missing patches, or you can scan and automatically install all missing patches.","checks_status": {"fail": 3,"pass": 2,"total": 7,"manual": 0}},"SEC06-BP02": {"name": "SEC06-BP02","checks": {"awslambda_function_not_publicly_accessible": "PASS","ecr_repositories_scan_images_on_push_enabled": "FAIL"},"status": "FAIL","attributes": [{"Name": "SEC06-BP02 Reduce attack surface","Section": "Infrastructure protection","SubSection": "Protecting compute","Description": "Reduce your exposure to unintended access by hardening operating systems and minimizing the components, libraries, and externally consumable services in use. Start by reducing unused components, whether they are operating system packages or applications, for Amazon Elastic Compute Cloud (Amazon EC2)-based workloads, or external software modules in your code, for all workloads. You can find many hardening and security configuration guides for common operating systems and server software. For example, you can start with the Center for Internet Security and iterate.In Amazon EC2, you can create your own Amazon Machine Images (AMIs), which you have patched and hardened, to help you meet the specific security requirements for your organization. The patches and other security controls you apply on the AMI are effective at the point in time in which they were created—they are not dynamic unless you modify after launching, for example, with AWS Systems Manager.You can simplify the process of building secure AMIs with EC2 Image Builder. EC2 Image Builder significantly reduces the effort required to create and maintain golden images without writing and maintaining automation. When software updates become available, Image Builder automatically produces a new image without requiring users to manually initiate image builds. EC2 Image Builder allows you to easily validate the functionality and security of your images before using them in production with AWS-provided tests and your own tests. You can also apply AWS-provided security settings to further secure your images to meet internal security criteria. For example, you can produce images that conform to the Security Technical Implementation Guide (STIG) standard using AWS-provided templates.Using third-party static code analysis tools, you can identify common security issues such as unchecked function input bounds, as well as applicable common vulnerabilities and exposures (CVEs). You can use Amazon CodeGuru for supported languages. Dependency checking tools can also be used to determine whether libraries your code links against are the latest versions, are themselves free of CVEs, and have licensing conditions that meet your software policy requirements.Using Amazon Inspector, you can perform configuration assessments against your instances for known CVEs, assess against security benchmarks, and automate the notification of defects. Amazon Inspector runs on production instances or in a build pipeline, and it notifies developers and engineers when findings are present. You can access findings programmatically and direct your team to backlogs and bug-tracking systems. EC2 Image Builder can be used to maintain server images (AMIs) with automated patching, AWS-provided security policy enforcement, and other customizations. When using containers implement ECR Image Scanning in your build pipeline and on a regular basis against your image repository to look for CVEs in your containers.While Amazon Inspector and other tools are effective at identifying configurations and any CVEs that are present, other methods are required to test your workload at the application level. Fuzzing is a well-known method of finding bugs using automation to inject malformed data into input fields and other areas of your application.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_compute_reduce_surface.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_compute_reduce_surface","WellArchitectedQuestionId": "protect-compute"}],"description": "Reduce your exposure to unintended access by hardening operating systems and minimizing the components, libraries, and externally consumable services in use. Start by reducing unused components, whether they are operating system packages or applications, for Amazon Elastic Compute Cloud (Amazon EC2)-based workloads, or external software modules in your code, for all workloads. You can find many hardening and security configuration guides for common operating systems and server software. For example, you can start with the Center for Internet Security and iterate.In Amazon EC2, you can create your own Amazon Machine Images (AMIs), which you have patched and hardened, to help you meet the specific security requirements for your organization. The patches and other security controls you apply on the AMI are effective at the point in time in which they were created—they are not dynamic unless you modify after launching, for example, with AWS Systems Manager.You can simplify the process of building secure AMIs with EC2 Image Builder. EC2 Image Builder significantly reduces the effort required to create and maintain golden images without writing and maintaining automation. When software updates become available, Image Builder automatically produces a new image without requiring users to manually initiate image builds. EC2 Image Builder allows you to easily validate the functionality and security of your images before using them in production with AWS-provided tests and your own tests. You can also apply AWS-provided security settings to further secure your images to meet internal security criteria. For example, you can produce images that conform to the Security Technical Implementation Guide (STIG) standard using AWS-provided templates.Using third-party static code analysis tools, you can identify common security issues such as unchecked function input bounds, as well as applicable common vulnerabilities and exposures (CVEs). You can use Amazon CodeGuru for supported languages. Dependency checking tools can also be used to determine whether libraries your code links against are the latest versions, are themselves free of CVEs, and have licensing conditions that meet your software policy requirements.Using Amazon Inspector, you can perform configuration assessments against your instances for known CVEs, assess against security benchmarks, and automate the notification of defects. Amazon Inspector runs on production instances or in a build pipeline, and it notifies developers and engineers when findings are present. You can access findings programmatically and direct your team to backlogs and bug-tracking systems. EC2 Image Builder can be used to maintain server images (AMIs) with automated patching, AWS-provided security policy enforcement, and other customizations. When using containers implement ECR Image Scanning in your build pipeline and on a regular basis against your image repository to look for CVEs in your containers.While Amazon Inspector and other tools are effective at identifying configurations and any CVEs that are present, other methods are required to test your workload at the application level. Fuzzing is a well-known method of finding bugs using automation to inject malformed data into input fields and other areas of your application.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"SEC06-BP03": {"name": "SEC06-BP03","checks": {},"status": "PASS","attributes": [{"Name": "SEC06-BP03 Implement managed services","Section": "Infrastructure protection","SubSection": "Protecting compute","Description": "Implement services that manage resources, such as Amazon Relational Database Service (Amazon RDS), AWS Lambda, and Amazon Elastic Container Service (Amazon ECS), to reduce your security maintenance tasks as part of the shared responsibility model. For example, Amazon RDS helps you set up, operate, and scale a relational database, automates administration tasks such as hardware provisioning, database setup, patching, and backups. This means you have more free time to focus on securing your application in other ways described in the AWS Well-Architected Framework. Lambda lets you run code without provisioning or managing servers, so you only need to focus on the connectivity, invocation, and security at the code level–not the infrastructure or operating system.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_compute_implement_managed_services.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_compute_implement_managed_services","WellArchitectedQuestionId": "protect-compute"}],"description": "Implement services that manage resources, such as Amazon Relational Database Service (Amazon RDS), AWS Lambda, and Amazon Elastic Container Service (Amazon ECS), to reduce your security maintenance tasks as part of the shared responsibility model. For example, Amazon RDS helps you set up, operate, and scale a relational database, automates administration tasks such as hardware provisioning, database setup, patching, and backups. This means you have more free time to focus on securing your application in other ways described in the AWS Well-Architected Framework. Lambda lets you run code without provisioning or managing servers, so you only need to focus on the connectivity, invocation, and security at the code level–not the infrastructure or operating system.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC06-BP04": {"name": "SEC06-BP04","checks": {"ec2_instance_managed_by_ssm": "FAIL","ec2_instance_profile_attached": "PASS"},"status": "FAIL","attributes": [{"Name": "SEC06-BP04 Automate compute protection","Section": "Infrastructure protection","SubSection": "Protecting compute","Description": "Automate your protective compute mechanisms including vulnerability management, reduction in attack surface, and management of resources. The automation will help you invest time in securing other aspects of your workload, and reduce the risk of human error.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_compute_auto_protection.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_compute_auto_protection","WellArchitectedQuestionId": "protect-compute"}],"description": "Automate your protective compute mechanisms including vulnerability management, reduction in attack surface, and management of resources. The automation will help you invest time in securing other aspects of your workload, and reduce the risk of human error.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"SEC06-BP05": {"name": "SEC06-BP05","checks": {"ec2_instance_managed_by_ssm": "FAIL","ec2_instance_profile_attached": "PASS"},"status": "FAIL","attributes": [{"Name": "SEC06-BP05 Enable people to perform actions at a distance","Section": "Infrastructure protection","SubSection": "Protecting compute","Description": "Removing the ability for interactive access reduces the risk of human error, and the potential for manual configuration or management. For example, use a change management workflow to deploy Amazon Elastic Compute Cloud (Amazon EC2) instances using infrastructure-as-code, then manage Amazon EC2 instances using tools such as AWS Systems Manager instead of allowing direct access or through a bastion host. AWS Systems Manager can automate a variety of maintenance and deployment tasks, using features including automation workflows, documents (playbooks), and the run command. AWS CloudFormation stacks build from pipelines and can automate your infrastructure deployment and management tasks without using the AWS Management Console or APIs directly.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_compute_actions_distance.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_compute_actions_distance","WellArchitectedQuestionId": "protect-compute"}],"description": "Removing the ability for interactive access reduces the risk of human error, and the potential for manual configuration or management. For example, use a change management workflow to deploy Amazon Elastic Compute Cloud (Amazon EC2) instances using infrastructure-as-code, then manage Amazon EC2 instances using tools such as AWS Systems Manager instead of allowing direct access or through a bastion host. AWS Systems Manager can automate a variety of maintenance and deployment tasks, using features including automation workflows, documents (playbooks), and the run command. AWS CloudFormation stacks build from pipelines and can automate your infrastructure deployment and management tasks without using the AWS Management Console or APIs directly.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"SEC06-BP06": {"name": "SEC06-BP06","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Name": "SEC06-BP06 Validate software integrity","Section": "Infrastructure protection","SubSection": "Protecting compute","Description": "Implement mechanisms (for example, code signing) to validate that the software, code and libraries used in the workload are from trusted sources and have not been tampered with. For example, you should verify the code signing certificate of binaries and scripts to confirm the author, and ensure it has not been tampered with since created by the author. AWS Signer can help ensure the trust and integrity of your code by centrally managing the code- signing lifecycle, including signing certification and public and private keys. You can learn how to use advanced patterns and best practices for code signing with AWS Lambda. Additionally, a checksum of software that you download, compared to that of the checksum from the provider, can help ensure it has not been tampered with.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_compute_validate_software_integrity.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_compute_validate_software_integrity","WellArchitectedQuestionId": "protect-compute"}],"description": "Implement mechanisms (for example, code signing) to validate that the software, code and libraries used in the workload are from trusted sources and have not been tampered with. For example, you should verify the code signing certificate of binaries and scripts to confirm the author, and ensure it has not been tampered with since created by the author. AWS Signer can help ensure the trust and integrity of your code by centrally managing the code- signing lifecycle, including signing certification and public and private keys. You can learn how to use advanced patterns and best practices for code signing with AWS Lambda. Additionally, a checksum of software that you download, compared to that of the checksum from the provider, can help ensure it has not been tampered with.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"SEC07-BP01": {"name": "SEC07-BP01","checks": {},"status": "PASS","attributes": [{"Name": "SEC07-BP01 Identify the data within your workload","Section": "Data protection","SubSection": "Data classification","Description": "It’s critical to understand the type and classification of data your workload is processing, the associated business processes, where the data is stored, and who is the data owner. You should also have an understanding of the applicable legal and compliance requirements of your workload, and what data controls need to be enforced. Identifying data is the first step in the data classification journey.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_data_classification_identify_data.html#implementation-guidance.","WellArchitectedPracticeId": "sec_data_classification_identify_data","WellArchitectedQuestionId": "data-classification"}],"description": "It’s critical to understand the type and classification of data your workload is processing, the associated business processes, where the data is stored, and who is the data owner. You should also have an understanding of the applicable legal and compliance requirements of your workload, and what data controls need to be enforced. Identifying data is the first step in the data classification journey.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC07-BP02": {"name": "SEC07-BP02","checks": {},"status": "PASS","attributes": [{"Name": "SEC07-BP02 Define data protection controls","Section": "Data protection","SubSection": "Data classification","Description": "Protect data according to its classification level. For example, secure data classified as public by using relevant recommendations while protecting sensitive data with additional controls.By using resource tags, separate AWS accounts per sensitivity (and potentially also for each caveat, enclave, or community of interest), IAM policies, AWS Organizations SCPs, AWS Key Management Service (AWS KMS), and AWS CloudHSM, you can define and implement your policies for data classification and protection with encryption. For example, if you have a project with S3 buckets that contain highly critical data or Amazon Elastic Compute Cloud (Amazon EC2) instances that process confidential data, they can be tagged with a Project=ABC tag. Only your immediate team knows what the project code means, and it provides a way to use attribute-based access control. You can define levels of access to the AWS KMS encryption keys through key policies and grants to ensure that only appropriate services have access to the sensitive content through a secure mechanism. If you are making authorization decisions based on tags you should make sure that the permissions on the tags are defined appropriately using tag policies in AWS Organizations.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_data_classification_define_protection.html#implementation-guidance.","WellArchitectedPracticeId": "sec_data_classification_define_protection","WellArchitectedQuestionId": "data-classification"}],"description": "Protect data according to its classification level. For example, secure data classified as public by using relevant recommendations while protecting sensitive data with additional controls.By using resource tags, separate AWS accounts per sensitivity (and potentially also for each caveat, enclave, or community of interest), IAM policies, AWS Organizations SCPs, AWS Key Management Service (AWS KMS), and AWS CloudHSM, you can define and implement your policies for data classification and protection with encryption. For example, if you have a project with S3 buckets that contain highly critical data or Amazon Elastic Compute Cloud (Amazon EC2) instances that process confidential data, they can be tagged with a Project=ABC tag. Only your immediate team knows what the project code means, and it provides a way to use attribute-based access control. You can define levels of access to the AWS KMS encryption keys through key policies and grants to ensure that only appropriate services have access to the sensitive content through a secure mechanism. If you are making authorization decisions based on tags you should make sure that the permissions on the tags are defined appropriately using tag policies in AWS Organizations.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC07-BP03": {"name": "SEC07-BP03","checks": {},"status": "PASS","attributes": [{"Name": "SEC07-BP03 Automate identification and classification","Section": "Data protection","SubSection": "Data classification","Description": "Automating the identification and classification of data can help you implement the correct controls. Using automation for this instead of direct access from a person reduces the risk of human error and exposure. You should evaluate using a tool, such as Amazon Macie, that uses machine learning to automatically discover, classify, and protect sensitive data in AWS. Amazon Macie recognizes sensitive data, such as personally identifiable information (PII) or intellectual property, and provides you with dashboards and alerts that give visibility into how this data is being accessed or moved.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_data_classification_auto_classification.html#implementation-guidance.","WellArchitectedPracticeId": "sec_data_classification_auto_classification","WellArchitectedQuestionId": "data-classification"}],"description": "Automating the identification and classification of data can help you implement the correct controls. Using automation for this instead of direct access from a person reduces the risk of human error and exposure. You should evaluate using a tool, such as Amazon Macie, that uses machine learning to automatically discover, classify, and protect sensitive data in AWS. Amazon Macie recognizes sensitive data, such as personally identifiable information (PII) or intellectual property, and provides you with dashboards and alerts that give visibility into how this data is being accessed or moved.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC07-BP04": {"name": "SEC07-BP04","checks": {},"status": "PASS","attributes": [{"Name": "SEC07-BP04 Define data lifecycle management","Section": "Data protection","SubSection": "Data classification","Description": "Your defined lifecycle strategy should be based on sensitivity level as well as legal and organization requirements. Aspects including the duration for which you retain data, data destruction processes, data access management, data transformation, and data sharing should be considered. When choosing a data classification methodology, balance usability versus access. You should also accommodate the multiple levels of access and nuances for implementing a secure, but still usable, approach for each level. Always use a defense in depth approach and reduce human access to data and mechanisms for transforming, deleting, or copying data. For example, require users to strongly authenticate to an application, and give the application, rather than the users, the requisite access permission to perform action at a distance. In addition, ensure that users come from a trusted network path and require access to the decryption keys. Use tools, such as dashboards and automated reporting, to give users information from the data rather than giving them direct access to the data.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_data_classification_lifecycle_management.html#implementation-guidance.","WellArchitectedPracticeId": "sec_data_classification_lifecycle_management","WellArchitectedQuestionId": "data-classification"}],"description": "Your defined lifecycle strategy should be based on sensitivity level as well as legal and organization requirements. Aspects including the duration for which you retain data, data destruction processes, data access management, data transformation, and data sharing should be considered. When choosing a data classification methodology, balance usability versus access. You should also accommodate the multiple levels of access and nuances for implementing a secure, but still usable, approach for each level. Always use a defense in depth approach and reduce human access to data and mechanisms for transforming, deleting, or copying data. For example, require users to strongly authenticate to an application, and give the application, rather than the users, the requisite access permission to perform action at a distance. In addition, ensure that users come from a trusted network path and require access to the decryption keys. Use tools, such as dashboards and automated reporting, to give users information from the data rather than giving them direct access to the data.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC08-BP01": {"name": "SEC08-BP01","checks": {"kms_cmk_are_used": null},"status": "PASS","attributes": [{"Name": "SEC08-BP01 Implement secure key management","Section": "Data protection","SubSection": "Protecting data at rest","Description": "By defining an encryption approach that includes the storage, rotation, and access control of keys, you can help provide protection for your content against unauthorized users and against unnecessary exposure to authorized users. AWS Key Management Service (AWS KMS) helps you manage encryption keys and integrates with many AWS services. This service provides durable, secure, and redundant storage for your AWS KMS keys. You can define your key aliases as well as key-level policies. The policies help you define key administrators as well as key users. Additionally, AWS CloudHSM is a cloud-based hardware security module (HSM) that enables you to easily generate and use your own encryption keys in the AWS Cloud. It helps you meet corporate, contractual, and regulatory compliance requirements for data security by using FIPS 140-2 Level 3 validated HSMs.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_rest_key_mgmt.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_rest_key_mgmt","WellArchitectedQuestionId": "protect-data-rest"}],"description": "By defining an encryption approach that includes the storage, rotation, and access control of keys, you can help provide protection for your content against unauthorized users and against unnecessary exposure to authorized users. AWS Key Management Service (AWS KMS) helps you manage encryption keys and integrates with many AWS services. This service provides durable, secure, and redundant storage for your AWS KMS keys. You can define your key aliases as well as key-level policies. The policies help you define key administrators as well as key users. Additionally, AWS CloudHSM is a cloud-based hardware security module (HSM) that enables you to easily generate and use your own encryption keys in the AWS Cloud. It helps you meet corporate, contractual, and regulatory compliance requirements for data security by using FIPS 140-2 Level 3 validated HSMs.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"SEC08-BP02": {"name": "SEC08-BP02","checks": {"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","ec2_ebs_snapshots_encrypted": "FAIL","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","cloudtrail_kms_encryption_enabled": "FAIL","workspaces_volume_encryption_enabled": null,"glue_database_connections_ssl_enabled": null,"sqs_queues_server_side_encryption_enabled": "PASS","dynamodb_tables_kms_cmk_encryption_enabled": null,"glue_etl_jobs_amazon_s3_encryption_enabled": "PASS","cloudwatch_log_group_kms_encryption_enabled": "FAIL","glue_etl_jobs_job_bookmark_encryption_enabled": "FAIL","glue_data_catalogs_metadata_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"glue_development_endpoints_s3_encryption_enabled": null,"glue_etl_jobs_cloudwatch_logs_encryption_enabled": "FAIL","eks_cluster_kms_cmk_encryption_in_secrets_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"sagemaker_training_jobs_intercontainer_encryption_enabled": null,"glue_data_catalogs_connection_passwords_encryption_enabled": "FAIL","glue_development_endpoints_job_bookmark_encryption_enabled": null,"sagemaker_training_jobs_volume_and_output_encryption_enabled": null,"glue_development_endpoints_cloudwatch_logs_encryption_enabled": null},"status": "FAIL","attributes": [{"Name": "SEC08-BP02 Enforce encryption at rest","Section": "Data protection","SubSection": "Protecting data at rest","Description": "You should ensure that the only way to store data is by using encryption. AWS Key Management Service (AWS KMS) integrates seamlessly with many AWS services to make it easier for you to encrypt all your data at rest. For example, in Amazon Simple Storage Service (Amazon S3), you can set default encryption on a bucket so that all new objects are automatically encrypted. Additionally, Amazon Elastic Compute Cloud (Amazon EC2) and Amazon S3 support the enforcement of encryption by setting default encryption. You can use AWS Config Rules to check automatically that you are using encryption, for example, for Amazon Elastic Block Store (Amazon EBS) volumes, Amazon Relational Database Service (Amazon RDS) instances, and Amazon S3 buckets.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_rest_encrypt.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_rest_encrypt","WellArchitectedQuestionId": "protect-data-rest"}],"description": "You should ensure that the only way to store data is by using encryption. AWS Key Management Service (AWS KMS) integrates seamlessly with many AWS services to make it easier for you to encrypt all your data at rest. For example, in Amazon Simple Storage Service (Amazon S3), you can set default encryption on a bucket so that all new objects are automatically encrypted. Additionally, Amazon Elastic Compute Cloud (Amazon EC2) and Amazon S3 support the enforcement of encryption by setting default encryption. You can use AWS Config Rules to check automatically that you are using encryption, for example, for Amazon Elastic Block Store (Amazon EBS) volumes, Amazon Relational Database Service (Amazon RDS) instances, and Amazon S3 buckets.","checks_status": {"fail": 9,"pass": 4,"total": 25,"manual": 0}},"SEC08-BP03": {"name": "SEC08-BP03","checks": {"s3_bucket_default_encryption": "PASS","sagemaker_notebook_instance_encryption_enabled": null},"status": "PASS","attributes": [{"Name": "SEC08-BP03 Automate data at rest protection","Section": "Data protection","SubSection": "Protecting data at rest","Description": "Use automated tools to validate and enforce data at rest controls continuously, for example, verify that there are only encrypted storage resources. You can automate validation that all EBS volumes are encrypted using AWS Config Rules. AWS Security Hub can also verify several different controls through automated checks against security standards. Additionally, your AWS Config Rules can automatically remediate noncompliant resources.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_rest_automate_protection.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_rest_automate_protection","WellArchitectedQuestionId": "protect-data-rest"}],"description": "Use automated tools to validate and enforce data at rest controls continuously, for example, verify that there are only encrypted storage resources. You can automate validation that all EBS volumes are encrypted using AWS Config Rules. AWS Security Hub can also verify several different controls through automated checks against security standards. Additionally, your AWS Config Rules can automatically remediate noncompliant resources.","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"SEC08-BP04": {"name": "SEC08-BP04","checks": {"s3_bucket_object_versioning": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","organizations_account_part_of_organizations": null},"status": "FAIL","attributes": [{"Name": "SEC08-BP04 Enforce access control","Section": "Data protection","SubSection": "Protecting data at rest","Description": "To help protect your data at rest, enforce access control using mechanisms, such as isolation and versioning, and apply the principle of least privilege. Prevent the granting of public access to your data.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_rest_access_control.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_rest_access_control","WellArchitectedQuestionId": "protect-data-rest"}],"description": "To help protect your data at rest, enforce access control using mechanisms, such as isolation and versioning, and apply the principle of least privilege. Prevent the granting of public access to your data.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"SEC08-BP05": {"name": "SEC08-BP05","checks": {},"status": "PASS","attributes": [{"Name": "SEC08-BP05 Use mechanisms to keep people away from data","Section": "Data protection","SubSection": "Protecting data at rest","Description": "Keep all users away from directly accessing sensitive data and systems under normal operational circumstances. For example, use a change management workflow to manage Amazon Elastic Compute Cloud (Amazon EC2) instances using tools instead of allowing direct access or a bastion host. This can be achieved using AWS Systems Manager Automation, which uses automation documents that contain steps you use to perform tasks. These documents can be stored in source control, be peer reviewed before running, and tested thoroughly to minimize risk compared to shell access. Business users could have a dashboard instead of direct access to a data store to run queries. Where CI/CD pipelines are not used, determine which controls and processes are required to adequately provide a normally disabled break-glass access mechanism.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_rest_use_people_away.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_rest_use_people_away","WellArchitectedQuestionId": "protect-data-rest"}],"description": "Keep all users away from directly accessing sensitive data and systems under normal operational circumstances. For example, use a change management workflow to manage Amazon Elastic Compute Cloud (Amazon EC2) instances using tools instead of allowing direct access or a bastion host. This can be achieved using AWS Systems Manager Automation, which uses automation documents that contain steps you use to perform tasks. These documents can be stored in source control, be peer reviewed before running, and tested thoroughly to minimize risk compared to shell access. Business users could have a dashboard instead of direct access to a data store to run queries. Where CI/CD pipelines are not used, determine which controls and processes are required to adequately provide a normally disabled break-glass access mechanism.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC09-BP01": {"name": "SEC09-BP01","checks": {"acm_certificates_expiration_check": "PASS","directoryservice_ldap_certificate_expiration": null},"status": "PASS","attributes": [{"Name": "SEC09-BP01 Implement secure key and certificate management","Section": "Data protection","SubSection": "Protecting data in transit","Description": "Store encryption keys and certificates securely and rotate them at appropriate time intervals with strict access control. The best way to accomplish this is to use a managed service, such as AWS Certificate Manager (ACM). It lets you easily provision, manage, and deploy public and private Transport Layer Security (TLS) certificates for use with AWS services and your internal connected resources. TLS certificates are used to secure network communications and establish the identity of websites over the internet as well as resources on private networks. ACM integrates with AWS resources, such as Elastic Load Balancers (ELBs), AWS distributions, and APIs on API Gateway, also handling automatic certificate renewals. If you use ACM to deploy a private root CA, both certificates and private keys can be provided by it for use in Amazon Elastic Compute Cloud (Amazon EC2) instances, containers, and so on.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_transit_key_cert_mgmt.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_transit_key_cert_mgmt","WellArchitectedQuestionId": "protect-data-transit"}],"description": "Store encryption keys and certificates securely and rotate them at appropriate time intervals with strict access control. The best way to accomplish this is to use a managed service, such as AWS Certificate Manager (ACM). It lets you easily provision, manage, and deploy public and private Transport Layer Security (TLS) certificates for use with AWS services and your internal connected resources. TLS certificates are used to secure network communications and establish the identity of websites over the internet as well as resources on private networks. ACM integrates with AWS resources, such as Elastic Load Balancers (ELBs), AWS distributions, and APIs on API Gateway, also handling automatic certificate renewals. If you use ACM to deploy a private root CA, both certificates and private keys can be provided by it for use in Amazon Elastic Compute Cloud (Amazon EC2) instances, containers, and so on.","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"SEC09-BP02": {"name": "SEC09-BP02","checks": {"elb_ssl_listeners": "FAIL","elbv2_ssl_listeners": "FAIL","elb_insecure_ssl_ciphers": "PASS","elbv2_insecure_ssl_ciphers": "PASS","s3_bucket_secure_transport_policy": "FAIL","cloudfront_distributions_https_enabled": null,"apigateway_restapi_client_certificate_enabled": "FAIL","cloudfront_distributions_field_level_encryption_enabled": null,"cloudfront_distributions_using_deprecated_ssl_protocols": null,"opensearch_service_domains_https_communications_enforced": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Name": "SEC09-BP02 Enforce encryption in transit","Section": "Data protection","SubSection": "Protecting data in transit","Description": "Enforce your defined encryption requirements based on appropriate standards and recommendations to help you meet your organizational, legal, and compliance requirements. AWS services provide HTTPS endpoints using TLS for communication, thus providing encryption in transit when communicating with the AWS APIs. Insecure protocols, such as HTTP, can be audited and blocked in a VPC through the use of security groups. HTTP requests can also be automatically redirected to HTTPS in Amazon CloudFront or on an Application Load Balancer. You have full control over your computing resources to implement encryption in transit across your services. Additionally, you can use VPN connectivity into your VPC from an external network to facilitate encryption of traffic. Third-party solutions are available in the AWS Marketplace, if you have special requirements.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_transit_encrypt.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_transit_encrypt","WellArchitectedQuestionId": "protect-data-transit"}],"description": "Enforce your defined encryption requirements based on appropriate standards and recommendations to help you meet your organizational, legal, and compliance requirements. AWS services provide HTTPS endpoints using TLS for communication, thus providing encryption in transit when communicating with the AWS APIs. Insecure protocols, such as HTTP, can be audited and blocked in a VPC through the use of security groups. HTTP requests can also be automatically redirected to HTTPS in Amazon CloudFront or on an Application Load Balancer. You have full control over your computing resources to implement encryption in transit across your services. Additionally, you can use VPN connectivity into your VPC from an external network to facilitate encryption of traffic. Third-party solutions are available in the AWS Marketplace, if you have special requirements.","checks_status": {"fail": 4,"pass": 2,"total": 11,"manual": 0}},"SEC09-BP03": {"name": "SEC09-BP03","checks": {},"status": "PASS","attributes": [{"Name": "SEC09-BP03 Automate detection of unintended data access","Section": "Data protection","SubSection": "Protecting data in transit","Description": "Use tools such as Amazon GuardDuty to automatically detect suspicious activity or attempts to move data outside of defined boundaries. For example, GuardDuty can detect Amazon Simple Storage Service (Amazon S3) read activity that is unusual with the Exfiltration:S3/AnomalousBehavior finding. In addition to GuardDuty, Amazon VPC Flow Logs, which capture network traffic information, can be used with Amazon EventBridge to trigger detection of abnormal connections–both successful and denied. Amazon S3 Access Analyzer can help assess what data is accessible to who in your Amazon S3 buckets.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_transit_auto_unintended_access.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_transit_auto_unintended_access","WellArchitectedQuestionId": "protect-data-transit"}],"description": "Use tools such as Amazon GuardDuty to automatically detect suspicious activity or attempts to move data outside of defined boundaries. For example, GuardDuty can detect Amazon Simple Storage Service (Amazon S3) read activity that is unusual with the Exfiltration:S3/AnomalousBehavior finding. In addition to GuardDuty, Amazon VPC Flow Logs, which capture network traffic information, can be used with Amazon EventBridge to trigger detection of abnormal connections–both successful and denied. Amazon S3 Access Analyzer can help assess what data is accessible to who in your Amazon S3 buckets.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC09-BP04": {"name": "SEC09-BP04","checks": {"vpc_flow_logs_enabled": "FAIL"},"status": "FAIL","attributes": [{"Name": "SEC09-BP04 Authenticate network communications","Section": "Data protection","SubSection": "Protecting data in transit","Description": "Verify the identity of communications by using protocols that support authentication, such as Transport Layer Security (TLS) or IPsec. Using network protocols that support authentication, allows for trust to be established between the parties. This adds to the encryption used in the protocol to reduce the risk of communications being altered or intercepted. Common protocols that implement authentication include Transport Layer Security (TLS), which is used in many AWS services, and IPsec, which is used in AWS Virtual Private Network (AWS VPN).","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_protect_data_transit_authentication.html#implementation-guidance.","WellArchitectedPracticeId": "sec_protect_data_transit_authentication","WellArchitectedQuestionId": "protect-data-transit"}],"description": "Verify the identity of communications by using protocols that support authentication, such as Transport Layer Security (TLS) or IPsec. Using network protocols that support authentication, allows for trust to be established between the parties. This adds to the encryption used in the protocol to reduce the risk of communications being altered or intercepted. Common protocols that implement authentication include Transport Layer Security (TLS), which is used in many AWS services, and IPsec, which is used in AWS Virtual Private Network (AWS VPN).","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"SEC10-BP01": {"name": "SEC10-BP01","checks": {"iam_support_role_created": null,"account_maintain_current_contact_details": null,"account_security_contact_information_is_registered": null,"account_security_questions_are_registered_in_the_aws_account": null},"status": "PASS","attributes": [{"Name": "SEC10-BP01 Identify key personnel and external resources","Section": "Incident response","SubSection": "Prepare","Description": "Identify internal and external personnel, resources, and legal obligations that would help your organization respond to an incident.When you define your approach to incident response in the cloud, in unison with other teams (such as your legal counsel, leadership, business stakeholders, AWS Support Services, and others), you must identify key personnel, stakeholders, and relevant contacts. To reduce dependency and decrease response time, make sure that your team, specialist security teams, and responders are educated about the services that you use and have opportunities to practice hands-on.We encourage you to identify external AWS security partners that can provide you with outside expertise and a different perspective to augment your response capabilities. Your trusted security partners can help you identify potential risks or threats that you might not be familiar with.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_incident_response_identify_personnel.html#implementation-guidance.","WellArchitectedPracticeId": "sec_incident_response_identify_personnel","WellArchitectedQuestionId": "incident-response"}],"description": "Identify internal and external personnel, resources, and legal obligations that would help your organization respond to an incident.When you define your approach to incident response in the cloud, in unison with other teams (such as your legal counsel, leadership, business stakeholders, AWS Support Services, and others), you must identify key personnel, stakeholders, and relevant contacts. To reduce dependency and decrease response time, make sure that your team, specialist security teams, and responders are educated about the services that you use and have opportunities to practice hands-on.We encourage you to identify external AWS security partners that can provide you with outside expertise and a different perspective to augment your response capabilities. Your trusted security partners can help you identify potential risks or threats that you might not be familiar with.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"SEC10-BP02": {"name": "SEC10-BP02","checks": {},"status": "PASS","attributes": [{"Name": "SEC10-BP02 Develop incident management plans","Section": "Incident response","SubSection": "Prepare","Description": "Create plans to help you respond to, communicate during, and recover from an incident. For example, you can start an incident response plan with the most likely scenarios for your workload and organization. Include how you would communicate and escalate both internally and externally.","LevelOfRisk": "High","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_incident_response_develop_management_plans.html#implementation-guidance.","WellArchitectedPracticeId": "sec_incident_response_develop_management_plans","WellArchitectedQuestionId": "incident-response"}],"description": "Create plans to help you respond to, communicate during, and recover from an incident. For example, you can start an incident response plan with the most likely scenarios for your workload and organization. Include how you would communicate and escalate both internally and externally.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC10-BP03": {"name": "SEC10-BP03","checks": {},"status": "PASS","attributes": [{"Name": "SEC10-BP03 Prepare forensic capabilities","Section": "Incident response","SubSection": "Prepare","Description": "It's important for your incident responders to understand when and how the forensic investigation fits into your response plan. Your organization should define what evidence is collected and what tools are used in the process. Identify and prepare forensic investigation capabilities that are suitable, including external specialists, tools, and automation. A key decision that you should make upfront is if you will collect data from a live system. Some data, such as the contents of volatile memory or active network connections, will be lost if the system is powered off or rebooted.Your response team can combine tools, such as AWS Systems Manager, Amazon EventBridge, and AWS Lambda, to automatically run forensic tools within an operating system and VPC traffic mirroring to obtain a network packet capture, to gather non-persistent evidence. Conduct other activities, such as log analysis or analyzing disk images, in a dedicated security account with customized forensic workstations and tools accessible to your responders.Routinely ship relevant logs to a data store that provides high durability and integrity. Responders should have access to those logs. AWS offers several tools that can make log investigation easier, such as Amazon Athena, Amazon OpenSearch Service (OpenSearch Service), and Amazon CloudWatch Logs Insights. Additionally, preserve evidence securely using Amazon Simple Storage Service (Amazon S3) Object Lock. This service follows the WORM (write-once- read-many) model and prevents objects from being deleted or overwritten for a defined period. As forensic investigation techniques require specialist training, you might need to engage external specialists.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_incident_response_prepare_forensic.html#implementation-guidance.","WellArchitectedPracticeId": "sec_incident_response_prepare_forensic","WellArchitectedQuestionId": "incident-response"}],"description": "It's important for your incident responders to understand when and how the forensic investigation fits into your response plan. Your organization should define what evidence is collected and what tools are used in the process. Identify and prepare forensic investigation capabilities that are suitable, including external specialists, tools, and automation. A key decision that you should make upfront is if you will collect data from a live system. Some data, such as the contents of volatile memory or active network connections, will be lost if the system is powered off or rebooted.Your response team can combine tools, such as AWS Systems Manager, Amazon EventBridge, and AWS Lambda, to automatically run forensic tools within an operating system and VPC traffic mirroring to obtain a network packet capture, to gather non-persistent evidence. Conduct other activities, such as log analysis or analyzing disk images, in a dedicated security account with customized forensic workstations and tools accessible to your responders.Routinely ship relevant logs to a data store that provides high durability and integrity. Responders should have access to those logs. AWS offers several tools that can make log investigation easier, such as Amazon Athena, Amazon OpenSearch Service (OpenSearch Service), and Amazon CloudWatch Logs Insights. Additionally, preserve evidence securely using Amazon Simple Storage Service (Amazon S3) Object Lock. This service follows the WORM (write-once- read-many) model and prevents objects from being deleted or overwritten for a defined period. As forensic investigation techniques require specialist training, you might need to engage external specialists.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC10-BP04": {"name": "SEC10-BP04","checks": {},"status": "PASS","attributes": [{"Name": "SEC10-BP04 Automate containment capability","Section": "Incident response","SubSection": "Iterate","Description": "Automate containment and recovery of an incident to reduce response times and organizational impact.Once you create and practice the processes and tools from your playbooks, you can deconstruct the logic into a code-based solution, which can be used as a tool by many responders to automate the response and remove variance or guess-work by your responders. This can speed up the lifecycle of a response. The next goal is to enable this code to be fully automated by being invoked by the alerts or events themselves, rather than by a human responder, to create an event-driven response. These processes should also automatically add relevant data to your security systems. For example, an incident involving traffic from an unwanted IP address can automatically populate an AWS WAF block list or Network Firewall rule group to prevent further activity.With an event-driven response system, a detective mechanism triggers a responsive mechanism to automatically remediate the event. You can use event-driven response capabilities to reduce the time-to-value between detective mechanisms and responsive mechanisms. To create this event-driven architecture, you can use AWS Lambda, which is a serverless compute service that runs your code in response to events and automatically manages the underlying compute resources for you. For example, assume that you have an AWS account with the AWS CloudTrail service enabled. If CloudTrail is ever disabled (through the cloudtrail:StopLogging API call), you can use Amazon EventBridge to monitor for the specific cloudtrail:StopLogging event, and invoke a Lambda function to call cloudtrail:StartLogging to restart logging.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_incident_response_auto_contain.html#implementation-guidance.","WellArchitectedPracticeId": "sec_incident_response_auto_contain","WellArchitectedQuestionId": "incident-response"}],"description": "Automate containment and recovery of an incident to reduce response times and organizational impact.Once you create and practice the processes and tools from your playbooks, you can deconstruct the logic into a code-based solution, which can be used as a tool by many responders to automate the response and remove variance or guess-work by your responders. This can speed up the lifecycle of a response. The next goal is to enable this code to be fully automated by being invoked by the alerts or events themselves, rather than by a human responder, to create an event-driven response. These processes should also automatically add relevant data to your security systems. For example, an incident involving traffic from an unwanted IP address can automatically populate an AWS WAF block list or Network Firewall rule group to prevent further activity.With an event-driven response system, a detective mechanism triggers a responsive mechanism to automatically remediate the event. You can use event-driven response capabilities to reduce the time-to-value between detective mechanisms and responsive mechanisms. To create this event-driven architecture, you can use AWS Lambda, which is a serverless compute service that runs your code in response to events and automatically manages the underlying compute resources for you. For example, assume that you have an AWS account with the AWS CloudTrail service enabled. If CloudTrail is ever disabled (through the cloudtrail:StopLogging API call), you can use Amazon EventBridge to monitor for the specific cloudtrail:StopLogging event, and invoke a Lambda function to call cloudtrail:StartLogging to restart logging.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC10-BP05": {"name": "SEC10-BP05","checks": {},"status": "PASS","attributes": [{"Name": "SEC10-BP05 Pre-provision access","Section": "Incident response","SubSection": "Prepare","Description": "Verify that incident responders have the correct access pre-provisioned in AWS to reduce the time needed for investigation through to recovery.Common anti-patterns:Using the root account for incident response.Altering existing accounts.Manipulating IAM permissions directly when providing just-in-time privilege elevation.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_incident_response_pre_provision_access.html#implementation-guidance.","WellArchitectedPracticeId": "sec_incident_response_pre_provision_access","WellArchitectedQuestionId": "incident-response"}],"description": "Verify that incident responders have the correct access pre-provisioned in AWS to reduce the time needed for investigation through to recovery.Common anti-patterns:Using the root account for incident response.Altering existing accounts.Manipulating IAM permissions directly when providing just-in-time privilege elevation.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC10-BP06": {"name": "SEC10-BP06","checks": {},"status": "PASS","attributes": [{"Name": "SEC10-BP06 Pre-deploy tools","Section": "Incident response","SubSection": "Prepare","Description": "Ensure that security personnel have the right tools pre-deployed into AWS to reduce the time for investigation through to recovery.To automate security engineering and operations functions, you can use a comprehensive set of APIs and tools from AWS. You can fully automate identity management, network security, data protection, and monitoring capabilities and deliver them using popular software development methods that you already have in place. When you build security automation, your system can monitor, review, and initiate a response, rather than having people monitor your security position and manually react to events. An effective way to automatically provide searchable and relevant log data across AWS services to your incident responders is to enable Amazon Detective.If your incident response teams continue to respond to alerts in the same way, they risk alert fatigue. Over time, the team can become desensitized to alerts and can either make mistakes handling ordinary situations or miss unusual alerts. Automation helps avoid alert fatigue by using functions that process the repetitive and ordinary alerts, leaving humans to handle the sensitive and unique incidents. Integrating anomaly detection systems, such as Amazon GuardDuty, AWS CloudTrail Insights, and Amazon CloudWatch Anomaly Detection, can reduce the burden of common threshold-based alerts.You can improve manual processes by programmatically automating steps in the process. After you define the remediation pattern to an event, you can decompose that pattern into actionable logic, and write the code to perform that logic. Responders can then execute that code to remediate the issue. Over time, you can automate more and more steps, and ultimately automatically handle whole classes of common incidents.For tools that execute within the operating system of your Amazon Elastic Compute Cloud (Amazon EC2) instance, you should evaluate using the AWS Systems Manager Run Command, which enables you to remotely and securely administrate instances using an agent that you install on your Amazon EC2 instance operating system. It requires the Systems Manager Agent (SSM Agent), which is installed by default on many Amazon Machine Images (AMIs). Be aware, though, that once an instance has been compromised, no responses from tools or agents running on it should be considered trustworthy.","LevelOfRisk": "Low","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_incident_response_pre_deploy_tools.html#implementation-guidance.","WellArchitectedPracticeId": "sec_incident_response_pre_deploy_tools","WellArchitectedQuestionId": "incident-response"}],"description": "Ensure that security personnel have the right tools pre-deployed into AWS to reduce the time for investigation through to recovery.To automate security engineering and operations functions, you can use a comprehensive set of APIs and tools from AWS. You can fully automate identity management, network security, data protection, and monitoring capabilities and deliver them using popular software development methods that you already have in place. When you build security automation, your system can monitor, review, and initiate a response, rather than having people monitor your security position and manually react to events. An effective way to automatically provide searchable and relevant log data across AWS services to your incident responders is to enable Amazon Detective.If your incident response teams continue to respond to alerts in the same way, they risk alert fatigue. Over time, the team can become desensitized to alerts and can either make mistakes handling ordinary situations or miss unusual alerts. Automation helps avoid alert fatigue by using functions that process the repetitive and ordinary alerts, leaving humans to handle the sensitive and unique incidents. Integrating anomaly detection systems, such as Amazon GuardDuty, AWS CloudTrail Insights, and Amazon CloudWatch Anomaly Detection, can reduce the burden of common threshold-based alerts.You can improve manual processes by programmatically automating steps in the process. After you define the remediation pattern to an event, you can decompose that pattern into actionable logic, and write the code to perform that logic. Responders can then execute that code to remediate the issue. Over time, you can automate more and more steps, and ultimately automatically handle whole classes of common incidents.For tools that execute within the operating system of your Amazon Elastic Compute Cloud (Amazon EC2) instance, you should evaluate using the AWS Systems Manager Run Command, which enables you to remotely and securely administrate instances using an agent that you install on your Amazon EC2 instance operating system. It requires the Systems Manager Agent (SSM Agent), which is installed by default on many Amazon Machine Images (AMIs). Be aware, though, that once an instance has been compromised, no responses from tools or agents running on it should be considered trustworthy.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC10-BP07": {"name": "SEC10-BP07","checks": {},"status": "PASS","attributes": [{"Name": "SEC10-BP07 Run game days","Section": "Incident response","SubSection": "Simulate","Description": "Game days, also known as simulations or exercises, are internal events that provide a structured opportunity to practice your incident management plans and procedures during a realistic scenario. These events should exercise responders using the same tools and techniques that would be used in a real-world scenario - even mimicking real-world environments. Game days are fundamentally about being prepared and iteratively improving your response capabilities. Some of the reasons you might find value in performing game day activities include:Validating readinessDeveloping confidence – learning from simulations and training staffFollowing compliance or contractual obligationsGenerating artifacts for accreditationBeing agile – incremental improvementBecoming faster and improving toolsRefining communication and escalationDeveloping comfort with the rare and the unexpectedFor these reasons, the value derived from participating in a simulation activity increases an organization's effectiveness during stressful events. Developing a simulation activity that is both realistic and beneficial can be a difficult exercise. Although testing your procedures or automation that handles well-understood events has certain advantages, it is just as valuable to participate in creative Security Incident Response Simulations (SIRS) activities to test yourself against the unexpected and continuously improve.Create custom simulations tailored to your environment, team, and tools. Find an issue and design your simulation around it. This could be something like a leaked credential, a server communicating with unwanted systems, or a misconfiguration that results in unauthorized exposure. Identify engineers who are familiar with your organization to create the scenario and another group to participate. The scenario should be realistic and challenging enough to be valuable. It should include the opportunity to get hands on with logging, notifications, escalations, and executing runbooks or automation. During the simulation, your responders should exercise their technical and organizational skills, and leaders should be involved to build their incident management skills. At the end of the simulation, celebrate the efforts of the team and look for ways to iterate, repeat, and expand into further simulations.AWS has created Incident Response Runbook templates that you can use not only to prepare your response efforts, but also as a basis for a simulation. When planning, a simulation can be broken into five phases.Evidence gathering: In this phase, a team will get alerts through various means, such as an internal ticketing system, alerts from monitoring tooling, anonymous tips, or even public news. Teams then start to review infrastructure and application logs to determine the source of the compromise. This step should also involve internal escalations and incident leadership. Once identified, teams move on to containing the incidentContain the incident: Teams will have determined there has been an incident and established the source of the compromise. Teams now should take action to contain it, for example, by disabling compromised credentials, isolating a compute resource, or revoking a role's permission.Eradicate the incident: Now that they've contained the incident, teams will work towards mitigating any vulnerabilities in applications or infrastructure configurations that were susceptible to the compromise. This could include rotating all credentials used for a workload, modifying Access Control Lists (ACLs) or changing network configurations.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_incident_response_run_game_days.html#implementation-guidance.","WellArchitectedPracticeId": "sec_incident_response_run_game_days","WellArchitectedQuestionId": "incident-response"}],"description": "Game days, also known as simulations or exercises, are internal events that provide a structured opportunity to practice your incident management plans and procedures during a realistic scenario. These events should exercise responders using the same tools and techniques that would be used in a real-world scenario - even mimicking real-world environments. Game days are fundamentally about being prepared and iteratively improving your response capabilities. Some of the reasons you might find value in performing game day activities include:Validating readinessDeveloping confidence – learning from simulations and training staffFollowing compliance or contractual obligationsGenerating artifacts for accreditationBeing agile – incremental improvementBecoming faster and improving toolsRefining communication and escalationDeveloping comfort with the rare and the unexpectedFor these reasons, the value derived from participating in a simulation activity increases an organization's effectiveness during stressful events. Developing a simulation activity that is both realistic and beneficial can be a difficult exercise. Although testing your procedures or automation that handles well-understood events has certain advantages, it is just as valuable to participate in creative Security Incident Response Simulations (SIRS) activities to test yourself against the unexpected and continuously improve.Create custom simulations tailored to your environment, team, and tools. Find an issue and design your simulation around it. This could be something like a leaked credential, a server communicating with unwanted systems, or a misconfiguration that results in unauthorized exposure. Identify engineers who are familiar with your organization to create the scenario and another group to participate. The scenario should be realistic and challenging enough to be valuable. It should include the opportunity to get hands on with logging, notifications, escalations, and executing runbooks or automation. During the simulation, your responders should exercise their technical and organizational skills, and leaders should be involved to build their incident management skills. At the end of the simulation, celebrate the efforts of the team and look for ways to iterate, repeat, and expand into further simulations.AWS has created Incident Response Runbook templates that you can use not only to prepare your response efforts, but also as a basis for a simulation. When planning, a simulation can be broken into five phases.Evidence gathering: In this phase, a team will get alerts through various means, such as an internal ticketing system, alerts from monitoring tooling, anonymous tips, or even public news. Teams then start to review infrastructure and application logs to determine the source of the compromise. This step should also involve internal escalations and incident leadership. Once identified, teams move on to containing the incidentContain the incident: Teams will have determined there has been an incident and established the source of the compromise. Teams now should take action to contain it, for example, by disabling compromised credentials, isolating a compute resource, or revoking a role's permission.Eradicate the incident: Now that they've contained the incident, teams will work towards mitigating any vulnerabilities in applications or infrastructure configurations that were susceptible to the compromise. This could include rotating all credentials used for a workload, modifying Access Control Lists (ACLs) or changing network configurations.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"SEC11-BP02": {"name": "SEC11-BP02","checks": {"ecr_repositories_scan_images_on_push_enabled": "FAIL","ecr_repositories_scan_vulnerabilities_in_latest_image": null},"status": "FAIL","attributes": [{"Name": "SEC11-BP02 Automate testing throughout the development and release lifecycle","Section": "Application Security","SubSection": null,"Description": "Automate the testing for security properties throughout the development and release lifecycle. Automation makes it easier to consistently and repeatably identify potential issues in software prior to release, which reduces the risk of security issues in the software being provided. The goal of automated testing is to provide a programmatic way of detecting potential issues early and often throughout the development lifecycle. When you automate regression testing, you can rerun functional and non-functional tests to verify that previously tested software still performs as expected after a change. When you define security unit tests to check for common misconfigurations, such as broken or missing authentication, you can identify and fix these issues early in the development process. Test automation uses purpose-built test cases for application validation, based on the application’s requirements and desired functionality. The result of the automated testing is based on comparing the generated test output to its respective expected output, which expedites the overall testing lifecycle. Testing methodologies such as regression testing and unit test suites are best suited for automation. Automating the testing of security properties allows builders to receive automated feedback without having to wait for a security review. Automated tests in the form of static or dynamic code analysis can increase code quality and help detect potential software issues early in the development lifecycle.","LevelOfRisk": "Medium","AssessmentMethod": "Automated","ImplementationGuidanceUrl": "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_appsec_automate_testing_throughout_lifecycle.html#implementation-guidance.","WellArchitectedPracticeId": "sec_appsec_automate_testing_throughout_lifecycle","WellArchitectedQuestionId": "application-security"}],"description": "Automate the testing for security properties throughout the development and release lifecycle. Automation makes it easier to consistently and repeatably identify potential issues in software prior to release, which reduces the risk of security issues in the software being provided. The goal of automated testing is to provide a programmatic way of detecting potential issues early and often throughout the development lifecycle. When you automate regression testing, you can rerun functional and non-functional tests to verify that previously tested software still performs as expected after a change. When you define security unit tests to check for common misconfigurations, such as broken or missing authentication, you can identify and fix these issues early in the development process. Test automation uses purpose-built test cases for application validation, based on the application’s requirements and desired functionality. The result of the automated testing is based on comparing the generated test output to its respective expected output, which expedites the overall testing lifecycle. Testing methodologies such as regression testing and unit test suites are best suited for automation. Automating the testing of security properties allows builders to receive automated feedback without having to wait for a security review. Automated tests in the form of static or dynamic code analysis can increase code quality and help detect potential software issues early in the development lifecycle.","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}}},"requirements_passed": 17,"requirements_failed": 23,"requirements_manual": 17,"total_requirements": 57,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "e079e750-59b8-4d29-9e57-1a10a0e63be4","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "aws_foundational_security_best_practices_aws","framework": "AWS-Foundational-Security-Best-Practices","version": "","description": "The AWS Foundational Security Best Practices standard is a set of controls that detect when your deployed accounts and resources deviate from security best practices.","region": "eu-west-1","requirements": {"s3": {"name": "Benchmark: S3","checks": {"s3_bucket_public_access": null,"s3_bucket_acl_prohibited": "FAIL","s3_bucket_object_versioning": "FAIL","s3_bucket_default_encryption": "PASS","s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS","s3_account_level_public_access_blocks": null,"s3_bucket_server_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "s3","Section": "S3","Service": "s3","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS S3 resources and options.","checks_status": {"fail": 4,"pass": 2,"total": 9,"manual": 0}},"acm": {"name": "ACM","checks": {"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "acm","Section": "Acm","Service": "acm","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring ACM resources.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"dms": {"name": "Benchmark: DMS","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "dms","Section": "DMS","Service": "dms","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS DMS resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"ec2": {"name": "Benchmark: EC2","checks": {"vpc_flow_logs_enabled": "FAIL","ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","ec2_securitygroup_not_used": "FAIL","ec2_instance_imdsv2_enabled": "PASS","ec2_instance_older_than_specific_days": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ec2","Section": "EC2","Service": "ec2","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring EC2 resources and options.","checks_status": {"fail": 6,"pass": 4,"total": 10,"manual": 0}},"ecr": {"name": "Benchmark: Elastic Container Registry","checks": {"ecr_repositories_lifecycle_policy_enabled": "FAIL","ecr_repositories_scan_images_on_push_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ecr","Section": "ECR","Service": "ecr","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS ECR resources and options.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"ecs": {"name": "Benchmark: Elastic Container Service","checks": {"ecs_task_definitions_no_environment_secrets": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "ecs","Section": "ECS","Service": "ecs","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring ECS resources and options.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"efs": {"name": "Benchmark: EFS","checks": {"efs_have_backup_enabled": "FAIL","efs_encryption_at_rest_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "efs","Section": "EFS","Service": "efs","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS EFS resources and options.","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"eks": {"name": "Benchmark: EKS","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "eks","Section": "EKS","Service": "eks","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS EKS resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"elb": {"name": "Benchmark: ELB","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","elbv2_deletion_protection": "FAIL","elbv2_desync_mitigation_mode": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "elb","Section": "ELB","Service": "elb","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Elastic Load Balancer resources and options.","checks_status": {"fail": 4,"pass": 0,"total": 4,"manual": 0}},"emr": {"name": "Benchmark: EMR","checks": {"emr_cluster_master_nodes_no_public_ip": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "emr","Section": "EMR","Service": "emr","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring EMR resources.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"iam": {"name": "Benchmark: IAM","checks": {"iam_no_root_access_key": null,"iam_user_accesskey_unused": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "iam","Section": "IAM","Service": "iam","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS IAM resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 10,"manual": 0}},"kms": {"name": "Benchmark: KMS","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "kms","Section": "KMS","Service": "kms","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS KMS resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"rds": {"name": "Benchmark: RDS","checks": {"rds_instance_multi_az": "FAIL","rds_snapshots_public_access": "PASS","rds_instance_no_public_access": "PASS","rds_instance_storage_encrypted": "FAIL","rds_instance_deletion_protection": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","rds_instance_minor_version_upgrade_enabled": "PASS"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "rds","Section": "RDS","Service": "rds","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS RDS resources and options.","checks_status": {"fail": 5,"pass": 3,"total": 10,"manual": 0}},"sns": {"name": "Benchmark: SNS","checks": {"sns_topics_kms_encryption_at_rest_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "sns","Section": "SNS","Service": "sns","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS SNS resources and options.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"sqs": {"name": "Benchmark: SQS","checks": {"sqs_queues_server_side_encryption_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "sqs","Section": "SQS","Service": "sqs","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS SQS resources and options.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"ssm": {"name": "Benchmark: SSM","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "ssm","Section": "SSM","Service": "ssm","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Systems Manager resources and options.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"waf": {"name": "Benchmark: WAF","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "waf","Section": "WAF","Service": "waf","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS WAF resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"elbv2": {"name": "Benchmark: ELBv2","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "elbv2","Section": "ELBv2","Service": "elbv2","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Elastic Load Balancer resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"config": {"name": "Benchmark: Config","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "config","Section": "Config","Service": "config","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Config.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"lambda": {"name": "Benchmark: Lambda","checks": {"awslambda_function_url_public": null,"awslambda_function_using_supported_runtimes": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "lambda","Section": "Lambda","Service": "lambda","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Lambda resources and options.","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"account": {"name": "Account","checks": {"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "account","Section": "Account","Service": "account","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Account.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"kinesis": {"name": "Benchmark: Kinesis","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "kinesis","Section": "Kinesis","Service": "kinesis","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Kinesis resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"dynamodb": {"name": "Benchmark: DynamoDB","checks": {"dynamodb_tables_pitr_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "dynamodb","Section": "DynamoDB","Service": "dynamodb","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Dynamo DB resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"redshift": {"name": "Benchmark: Redshift","checks": {"redshift_cluster_public_access": null,"redshift_cluster_automated_snapshot": null,"redshift_cluster_automatic_upgrades": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "redshift","Section": "Redshift","Service": "redshift","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Redshift resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"codebuild": {"name": "Benchmark: CodeBuild","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "codebuild","Section": "CodeBuild","Service": "codebuild","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring CodeBuild resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"guardduty": {"name": "Benchmark: GuardDuty","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Type": null,"ItemId": "guardduty","Section": "GuardDuty","Service": "guardduty","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS GuardDuty resources and options.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"sagemaker": {"name": "Benchmark: SageMaker","checks": {"sagemaker_notebook_instance_root_access_disabled": null,"sagemaker_notebook_instance_vpc_settings_configured": null,"sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "sagemaker","Section": "SageMaker","Service": "sagemaker","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Sagemaker resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"cloudfront": {"name": "Benchmark: CloudFront","checks": {"cloudfront_distributions_using_waf": null,"cloudfront_distributions_https_enabled": null,"cloudfront_distributions_logging_enabled": null,"cloudfront_distributions_field_level_encryption_enabled": null,"cloudfront_distributions_using_deprecated_ssl_protocols": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "cloudfront","Section": "CloudFront","Service": "cloudfront","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring CloudFront resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"cloudtrail": {"name": "Benchmark: CloudTrail","checks": {"cloudtrail_multi_region_enabled": "PASS","cloudtrail_kms_encryption_enabled": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "cloudtrail","Section": "CloudTrail","Service": "cloudtrail","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring CloudTrail resources and options.","checks_status": {"fail": 3,"pass": 1,"total": 4,"manual": 0}},"opensearch": {"name": "Benchmark: OpenSearch","checks": {"opensearch_service_domains_not_publicly_accessible": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "opensearch","Section": "OpenSearch","Service": "opensearch","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring OpenSearch resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"api-gateway": {"name": "API Gateway","checks": {"apigateway_restapi_logging_enabled": "PASS","apigateway_restapi_waf_acl_attached": "FAIL","apigatewayv2_api_authorizers_enabled": "FAIL","apigatewayv2_api_access_logging_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "api-gateway","Section": "API Gateway","Service": "apigateway","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring API Gateway resources.","checks_status": {"fail": 4,"pass": 1,"total": 5,"manual": 0}},"auto-scaling": {"name": "Benchmark: Auto Scaling","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "auto-scaling","Section": "Auto Scaling","Service": "autoscaling","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Auto Scaling resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"elasticsearch": {"name": "Benchmark: Elasticsearch","checks": {"opensearch_service_domains_audit_logging_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_https_communications_enforced": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "elasticsearch","Section": "ElasticSearch","Service": "elasticsearch","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Elasticsearch resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"cloudformation": {"name": "Benchmark: CloudFormation","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "cloudformation","Section": "CloudFormation","Service": "cloudformation","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring CloudFormation resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"secretsmanager": {"name": "Benchmark: Secrets Manager","checks": {"secretsmanager_automatic_rotation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "secretsmanager","Section": "Secrets Manager","Service": "secretsmanager","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Secrets Manager resources.","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"network-firewall": {"name": "Benchmark: Network Firewall","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "network-firewall","Section": "Network Firewall","Service": "network-firewall","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring Network Firewall resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"elastic-beanstalk": {"name": "Benchmark: Elastic Beanstalk","checks": {},"status": "PASS","attributes": [{"Type": null,"ItemId": "elastic-beanstalk","Section": "Elastic Beanstalk","Service": "elasticbeanstalk","SubGroup": null,"SubSection": null}],"description": "This section contains recommendations for configuring AWS Elastic Beanstalk resources and options.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}}},"requirements_passed": 14,"requirements_failed": 12,"requirements_manual": 11,"total_requirements": 37,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "e23a4728-558b-4a92-8e7d-f1473c21cc6e","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "ens_rd2022_aws","framework": "ENS","version": "RD2022","description": "The accreditation scheme of the ENS (National Security Scheme) has been developed by the Ministry of Finance and Public Administrations and the CCN (National Cryptological Center). This includes the basic principles and minimum requirements necessary for the adequate protection of information.","region": "eu-west-1","requirements": {"mp.s.1.aws.wm.1": {"name": "mp.s.1.aws.wm.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los servicios","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.s.1","DescripcionControl": "Se deberĆ” hacer uso del cifrado de la información contenida en los correos electrónicos."}],"description": "Protección del correo electrónico","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.s.1.aws.wm.2": {"name": "mp.s.1.aws.wm.2","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los servicios","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.s.1","DescripcionControl": "Habilitar el registro de eventos de Workmail en CloudWatch para realizar el seguimiento de mensajes con spam."}],"description": "Protección del correo electrónico","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.s.1.aws.wm.3": {"name": "mp.s.1.aws.wm.3","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los servicios","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.s.1","DescripcionControl": "En SES, se debe hacer uso de la opción que permite a los usuarios enviar correo electrónico cifrado con S/MIME"}],"description": "Protección del correo electrónico","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.s.4.aws.as.1": {"name": "mp.s.4.aws.as.1","checks": {"autoscaling_group_multiple_az": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los servicios","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.s.4","DescripcionControl": "Activar la solución AWS Auto Scaling para dotar a los sistemas de la capacidad suficiente para atender la carga prevista con holgura y desplegar tecnologĆ­as para la prevención de ataques conocidos."}],"description": "Protección frente a la denegación de servicio ","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"mp.s.2.aws.waf.1": {"name": "mp.s.2.aws.waf.1","checks": {"cloudfront_distributions_using_waf": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los servicios","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.s.2","DescripcionControl": "Todas las aplicaciones web distribuidas por el servicio de AWS CloudFront deben estar integradas con el servicio de firewall de aplicaciones web AWS WAF."}],"description": "Protección de servicios y aplicaciones web","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"mp.s.2.aws.waf.2": {"name": "mp.s.2.aws.waf.2","checks": {"apigateway_restapi_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los servicios","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.s.2","DescripcionControl": "Los API gateways deben tener un ACL WAF asociado."}],"description": "Protección de servicios y aplicaciones web","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.s.2.aws.waf.3": {"name": "mp.s.2.aws.waf.3","checks": {"elbv2_waf_acl_attached": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los servicios","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.s.2","DescripcionControl": "Todos los balanceadores de aplicación deben estar integrados con el servicio de firewall de aplicación web para quedar protegidos ante ataques de la capa de aplicación"}],"description": "Protección de servicios y aplicaciones web","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.si.2.aws.es.1": {"name": "mp.si.2.aws.es.1","checks": {"opensearch_service_domains_encryption_at_rest_enabled": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.si.2","DescripcionControl": "Aplicar cifrado sobre todos los dominios del servicio Amazon Elasticsearch Service (ES). En caso de usar este servicio, deberĆ” asegurarse la activación del cifrado en reposo."}],"description": "CriptografĆ­a","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"mp.si.2.aws.s3.1": {"name": "mp.si.2.aws.s3.1","checks": {"s3_bucket_default_encryption": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.si.2","DescripcionControl": "Aplicar cifrado sobre los distintos buckets de S3, de los cuales se debe asegurar que tengan activado el cifrado en reposo."}],"description": "CriptografĆ­a","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.pl.4.aws.sq.1": {"name": "op.pl.4.aws.sq.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.4","DescripcionControl": "La entidad usuaria deberĆ” llevar a cabo el estudio de capacidades a las que hace referencia la medida de seguridad, si bien (…) deberĆ” tener especialmente en cuenta: * Las cuotas de los servicios a utilizar."}],"description": "Necesidades de procesamiento","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.com.1.aws.cf.1": {"name": "mp.com.1.aws.cf.1","checks": {"cloudfront_distributions_https_enabled": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Asegurar que la distribución entre frontales CloudFront y sus orĆ­genes Ćŗnicamente emplee trĆ”fico HTTPs "}],"description": "PerĆ­metro seguro","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"mp.com.1.aws.s3.1": {"name": "mp.com.1.aws.s3.1","checks": {"s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Asegurar que los Buckets S3 de almacenamiento apliquen cifrado para la transferencia de datos empleando Secure Sockets Layer (SSL)"}],"description": "PerĆ­metro seguro","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.com.1.aws.sg.1": {"name": "mp.com.1.aws.sg.1","checks": {"ec2_securitygroup_from_launch_wizard": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Asegurar que el Security Group restrinja todo el trĆ”fico. Para ello, se deberĆ”n agregar las reglas del Security Group que se aplica por defecto cuando se crea una VPC."}],"description": "PerĆ­metro seguro","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"mp.com.1.aws.sg.2": {"name": "mp.com.1.aws.sg.2","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Evitar la existencia de Security Groups que dejen abierto todo el trĆ”fico entrante."}],"description": "PerĆ­metro seguro","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"mp.com.1.aws.sg.3": {"name": "mp.com.1.aws.sg.3","checks": {"ec2_securitygroup_not_used": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Evitar tener un repositorio de Security Groups que no estĆ©n siendo usados."}],"description": "PerĆ­metro seguro","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.com.3.aws.cf.1": {"name": "mp.com.3.aws.cf.1","checks": {"cloudfront_distributions_https_enabled": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["integridad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.3","DescripcionControl": "Asegurar que la distribución entre frontales CloudFront y sus orĆ­genes Ćŗnicamente emplee trĆ”fico HTTPS."}],"description": "Protección de la integridad y de la autenticidad","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"mp.com.3.aws.s3.1": {"name": "mp.com.3.aws.s3.1","checks": {"s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["integridad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.3","DescripcionControl": "Asegurar que los Buckets de almacenamiento S3 apliquen cifrado para la transferencia de datos empleando TLS."}],"description": "Protección de la integridad y de la autenticidad","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.com.4.aws.ws.1": {"name": "mp.com.4.aws.ws.1","checks": {"workspaces_vpc_2private_1public_subnets_nat": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "segregación de redes","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.4","DescripcionControl": "Se deberĆ”n abrir solo los puertos necesarios para el uso del servicio AWS WorkSpaces."}],"description": "Separación de flujos de información en la red","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"mp.si.2.aws.elb.1": {"name": "mp.si.2.aws.elb.1","checks": {"ec2_ebs_snapshots_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "recomendacion","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.si.2","DescripcionControl": "Se recomienda dejar activada la opción de cifrado por defecto para nuevos volĆŗmenes."}],"description": "CriptografĆ­a","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.si.2.aws.kms.1": {"name": "mp.si.2.aws.kms.1","checks": {"ec2_ebs_volume_encryption": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.si.2","DescripcionControl": "Aplicar cifrado sobre el almacenamiento de las instancias en todos sus volĆŗmenes de datos."}],"description": "CriptografĆ­a","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"mp.si.2.aws.rds.1": {"name": "mp.si.2.aws.rds.1","checks": {"rds_instance_storage_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.si.2","DescripcionControl": "Aplicar cifrado sobre las bases de datos AWS RDS."}],"description": "CriptografĆ­a","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.si.2.aws.sqs.1": {"name": "mp.si.2.aws.sqs.1","checks": {"sqs_queues_server_side_encryption_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.si.2","DescripcionControl": "Aplicar cifrado sobre las colas de mensajes de AWS (Amazon SQS)."}],"description": "CriptografĆ­a","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.exp.1.aws.re.1": {"name": "op.exp.1.aws.re.1","checks": {"resourceexplorer2_indexes_found": "PASS"},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.1","DescripcionControl": "Se recomienda el uso de AWS Resource Explorer para la exploración de los recursos como instancias RDB, buckets S3o tablas de Amazon DynamoDB."}],"description": "Inventario de activos","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.exp.5.aws.cm.1": {"name": "op.exp.5.aws.cm.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.5","DescripcionControl": "La entidad usuaria puede hacer uso de la utilidad AWS Change Manager para mantener un registro actualizado de las plantillas y peticiones de cambio en las que se incluya información en detalle sobre estos."}],"description": "Gestión de cambios","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.5.aws.ct.1": {"name": "op.exp.5.aws.ct.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.5","DescripcionControl": "Asegurar que CloudTrail estĆ© activo para todas las regiones."}],"description": "Gestión de cambios","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.exp.6.aws.gd.1": {"name": "op.exp.6.aws.gd.1","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.6","DescripcionControl": "Activar la protección contra software malintencionado de GuardDuty en todas las regiones."}],"description": "Protección frente a código daƱino","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.exp.7.aws.cf.1": {"name": "op.exp.7.aws.cf.1","checks": {"cloudfront_distributions_logging_enabled": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.7","DescripcionControl": "Habilitar los logs de acceso de CloudFront"}],"description": "Gestión de incidentes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.7.aws.gd.1": {"name": "op.exp.7.aws.gd.1","checks": {"guardduty_is_enabled": "PASS","guardduty_no_high_severity_findings": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.7","DescripcionControl": "Habilitar GuardDuty para la detección de incidentes de seguridad"}],"description": "Gestión de incidentes","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"op.exp.7.aws.sh.1": {"name": "op.exp.7.aws.sh.1","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.7","DescripcionControl": "Habilitar Security Hub"}],"description": "Gestión de incidentes","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.exp.8.aws.ct.1": {"name": "op.exp.8.aws.ct.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8","DescripcionControl": "Habilitar la herramienta CloudTrail en todas las regiones. Este serviio estĆ” habilitado por defecto cuando se crea una nueva cuenta, pero es posible deshabilitarlo."}],"description": "Registro de actividad","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.exp.8.aws.ct.2": {"name": "op.exp.8.aws.ct.2","checks": {"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8","DescripcionControl": "Establecer un filtro de mĆ©tricas desde AWS CloudWatch para detectar cambios en las configuraciones de CloudTrail"}],"description": "Registro de actividad","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.aws.ct.3": {"name": "op.exp.8.aws.ct.3","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8","DescripcionControl": "Habilitar la validación de archivos en todos los trails, evitando asĆ­ que estos se vean modificados o eliminados."}],"description": "Registro de actividad","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.aws.ct.4": {"name": "op.exp.8.aws.ct.4","checks": {"cloudtrail_s3_dataevents_write_enabled": null,"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8","DescripcionControl": "Habilitar la entrega continua de eventos de CloudTrail a un bucket S3 dedicado con el fin de unificar los archivos de registro."}],"description": "Registro de actividad","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"op.exp.8.aws.ct.5": {"name": "op.exp.8.aws.ct.5","checks": {"cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8","DescripcionControl": "Se deberĆ”n habilitar alertas para los siguientes eventos: * Llamadas no permitidas a la API, * Accesos no permitidos a la consola, * Todos los intentos de acceso sin el correcto uso de MFA, * Toda la actividad realizada sobre y por la cuenta root, * Cualquier cambio en las polĆ­ticas IAM"}],"description": "Registro de actividad","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"op.exp.8.aws.ct.6": {"name": "op.exp.8.aws.ct.6","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "medida","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8","DescripcionControl": "Activar el servicio de AWS CloudTrail para registrar la actividad de los usuarios relativa a la configuración de los servicios VPN Site-to-Site y AWS DirectConnect"}],"description": "Registro de actividad","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.exp.8.aws.cw.1": {"name": "op.exp.8.aws.cw.1","checks": {"cloudwatch_log_metric_filter_root_usage": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8","DescripcionControl": "Crear alertas utilizando herramientas como Amazon CloudWatch Events para anunciar el inicio de sesión y el uso de las credenciales de usuario root de la cuenta de administración"}],"description": "Registro de actividad","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.9.aws.ct.1": {"name": "op.exp.9.aws.ct.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.9","DescripcionControl": "Habilitar AWS Incident Manager y AWS CloudTrail en todas las regiones con el fin de recopilar información para generar contenido prescriptivo para la creación de informes exigidos por la medida de seguridad."}],"description": "Registro de la gestión de incidentes","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.ext.7.aws.am.1": {"name": "op.ext.7.aws.am.1","checks": {"account_maintain_current_contact_details": null,"account_security_contact_information_is_registered": null,"account_security_questions_are_registered_in_the_aws_account": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.7","DescripcionControl": "DeberĆ” proveerse la información relacionada con contactos alternativos (de facturación, operaciones y seguridad), con correos que no dependan de la misma persona. DeberĆ” comprobarse regularmente que estas cuentas funcionan correctamente y mantener listas de correo para asegurar la recepción de avisos por personal disponible en cada momento. AdemĆ”s, deberĆ”n establecerse preguntas de desafĆ­o de seguridad y respuestas para el caso de que sea necesario autenticarse como propiterio de la cuenta para ponerse en contacto con el soporte de AWS."}],"description": "Gestión de incidentes","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"op.mon.1.aws.ct.1": {"name": "op.mon.1.aws.ct.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.1","DescripcionControl": "Activar el servicio de eventos AWS CloudTrail para todas las regiones."}],"description": "Detección de intrusión","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.mon.1.aws.gd.1": {"name": "op.mon.1.aws.gd.1","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.1","DescripcionControl": "En ausencia de otras herramientas de terceros, habilitar Amazon GuarDuty para la detección de amenazas e intrusiones."}],"description": "Detección de intrusión","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.mon.1.aws.gd.2": {"name": "op.mon.1.aws.gd.2","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.1","DescripcionControl": "DeberĆ” habilitarse Amazon GuardDuty para todas las regiones tanto en la cuenta raĆ­z como en las cuentas miembro de un entorno multi-cuenta."}],"description": "Detección de intrusión","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.mon.1.aws.gd.3": {"name": "op.mon.1.aws.gd.3","checks": {"guardduty_centrally_managed": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.1","DescripcionControl": "Todas las cuentas miembro deberĆ”n estar aƱadidas para la supervisión bajo la cuenta raĆ­z."}],"description": "Detección de intrusión","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.mon.1.aws.gd.4": {"name": "op.mon.1.aws.gd.4","checks": {},"status": "PASS","attributes": [{"Tipo": "medida","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.mon.1","DescripcionControl": "La administración de Amazon GuardDuty quedarĆ” delegada exclusivamente a la cuenta de seguridad para garantizar una correcta asignación de los roles para este servicio."}],"description": "Detección de intrusión","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.mon.2.aws.sh.1": {"name": "op.mon.2.aws.sh.1","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.2","DescripcionControl": "Utilizar Security Hub para obtener una vista consolidada de los hallazgos de seguridad en los servicios de AWS habilitados."}],"description": "Sistema de mĆ©tricas","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.pl.4.aws.ec2.1": {"name": "op.pl.4.aws.ec2.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.4","DescripcionControl": "La entidad usuaria deberĆ” llevar a cabo el estudio de capacidades a las que hace referencia la medida de seguridad, si bien (…) deberĆ” tener especialmente en cuenta: * Las capacidades de procesamiento, almacenamiento y comunicaciones de las instancais desplegadas en AWS."}],"description": "Necesidades de procesamiento","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.com.1.aws.elb.1": {"name": "mp.com.1.aws.elb.1","checks": {"elb_ssl_listeners": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Habilitar TLS en los balanceadores de carga ELB "}],"description": "PerĆ­metro seguro","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.com.1.aws.elb.2": {"name": "mp.com.1.aws.elb.2","checks": {"elb_insecure_ssl_ciphers": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Evitar el uso de protocolos de cifrado inseguros para las polĆ­ticas de seguridad de ELB. Esto podrĆ­a dejar la conexión SSL entre balanceadores y clientes vulnerables a ser explotados. En particular deberĆ” evitarse el uso de TLS 1.0. "}],"description": "PerĆ­metro seguro","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"mp.com.1.aws.nfw.1": {"name": "mp.com.1.aws.nfw.1","checks": {"networkfirewall_in_all_vpc": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Filtrar todo el trĆ”fico entrante y saliente de la VPC a travĆ©s de Firewalls de red."}],"description": "PerĆ­metro seguro","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.com.1.aws.nfw.2": {"name": "mp.com.1.aws.nfw.2","checks": {"fms_policy_compliant": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.1","DescripcionControl": "Incidir en la utilización de AWS Firewall Manager para gestionar los firewalls de forma centralizada."}],"description": "PerĆ­metro seguro","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"mp.com.2.aws.vpn.1": {"name": "mp.com.2.aws.vpn.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.com.2","DescripcionControl": "Garantizar que las conexiones entre la VPC y la red local (remota) se canalizan a travĆ©s de VPN Site-to-Site o bien a travĆ©s de Direct Connect."}],"description": "Protección de la confidencialidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.com.2.aws.vpn.2": {"name": "mp.com.2.aws.vpn.2","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.com.2","DescripcionControl": "Garantizar que las conexiones entre la VPC y la red local (remota) se canalizan a travĆ©s de VPN Site-to-Site o bien a travĆ©s de Direct Connect."}],"description": "Protección de la confidencialidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.com.3.aws.elb.1": {"name": "mp.com.3.aws.elb.1","checks": {"elbv2_insecure_ssl_ciphers": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["integridad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.3","DescripcionControl": "Habilitar TLS en los balanceadores de carga ELB."}],"description": "Protección de la integridad y de la autenticidad","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"mp.com.3.aws.elb.2": {"name": "mp.com.3.aws.elb.2","checks": {"elbv2_insecure_ssl_ciphers": "PASS"},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["integridad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.3","DescripcionControl": "Evitar el uso de protocolos de cifrado inseguros en la conexión TLS entre clientes y balanceadores de carga. En particular, se deberĆ” evitar el uso de TLS 1.0."}],"description": "Protección de la integridad y de la autenticidad","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"mp.com.4.aws.vpc.1": {"name": "mp.com.4.aws.vpc.1","checks": {"vpc_subnet_separate_private_public": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.4","DescripcionControl": "Los flujos de información de red se deben separar a travĆ©s de la utilización de diferentes subnets."}],"description": "Separación de flujos de información en la red","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.com.4.aws.vpc.2": {"name": "mp.com.4.aws.vpc.2","checks": {"ec2_instance_internet_facing_with_instance_profile": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.4","DescripcionControl": "Evitar el uso de subnets con la opción de asignación automĆ”tica de IPs (auto-assign Public IP)."}],"description": "Separación de flujos de información en la red","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.si.2.aws.dydb.1": {"name": "mp.si.2.aws.dydb.1","checks": {"dynamodb_tables_kms_cmk_encryption_enabled": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.si.2","DescripcionControl": "Aplicar cifrado sobre las bases de datos DynamoDB, que deben implementar cifrado seguro mediante el uso de claves de cliente (KMS)."}],"description": "CriptografĆ­a","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.acc.1.aws.iam.1": {"name": "op.acc.1.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.1","DescripcionControl": "Utilizar los grupos y roles, en lugar de los usuarios individuales, para controlar el acceso. Esto permitirĆ” implementar un conjunto de permisos en lugar de actualizar muchas polĆ­ticas individuales cuando el acceso de un usuario necesita cambiar."}],"description": "Identificador Ćŗnico","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.1.aws.iam.2": {"name": "op.acc.1.aws.iam.2","checks": {"iam_check_saml_providers_sts": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.1","DescripcionControl": "Es muy recomendable la utilización de un proveedor de identidades que permita administrar las identidades en un lugar centralizado, en vez de utilizar IAM para ello."}],"description": "Proveedor de identidad centralizado","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.acc.1.aws.iam.3": {"name": "op.acc.1.aws.iam.3","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.1","DescripcionControl": "El usuario raĆ­z actĆŗa como usuario IAM de seguridad (usuario \"breakglass\"), dado que no se encuentra sincronizado con el proveedor de identidades externo, lo que permite la recuperación de emergencia del acceso a AWS en caso de imposibilidad de autenticar a los usuarios a travĆ©s del proveedor de identidades."}],"description": "Proveedor de identidad centralizado","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.1.aws.iam.4": {"name": "op.acc.1.aws.iam.4","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.1","DescripcionControl": "Utilizar identificadores Ćŗnicos para los usuarios del sistema."}],"description": "Identificador Ćŗnico","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.1.aws.iam.5": {"name": "op.acc.1.aws.iam.5","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.1","DescripcionControl": "Cada cuenta estarĆ” asociada a un identificador Ćŗnico."}],"description": "Identificador Ćŗnico","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.1.aws.iam.6": {"name": "op.acc.1.aws.iam.6","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.1","DescripcionControl": "Las cuentas deben ser inhabilitadas en los siguientes casos: cuando el usuario deja la organización; cuando el usuario cesa en la función para la cual se requerĆ­a la cuenta de usuario; o, cuando la persona que la autorizó, da orden en sentido contrario."}],"description": "Cuentas de usuario","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.1.aws.iam.7": {"name": "op.acc.1.aws.iam.7","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.1","DescripcionControl": "Las cuentas se retendrĆ”n durante el periodo necesario para atender a las necesidades de trazabilidad de los registros de actividad asociados a las mismas. A este periodo se le denominarĆ” periodo de retención."}],"description": "Cuentas de usuario","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.2.aws.iam.1": {"name": "op.acc.2.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.2","DescripcionControl": "Hacer uso de las polĆ­ticas IAM para la asignación de privilegios de acceso. DeberĆ”n administrarse permisos para controlar el acceso de las identidades de personas y mĆ”quinas y sus cargas de trabajo."}],"description": "Requisitos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.2.aws.iam.2": {"name": "op.acc.2.aws.iam.2","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.2","DescripcionControl": "DeberĆ” definirse una polĆ­tica IAM que conceda permiso al usuario o rol de IAM para utilizar los recursos y las acciones de la API especĆ­ficos que necesita"}],"description": "Requisitos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.2.aws.iam.3": {"name": "op.acc.2.aws.iam.3","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.2","DescripcionControl": "De acuerdo con las medidas del Esquema Nacional de seguridad los derechos de acceso de cada recurso, se establecerĆ”n segĆŗn las decisiones de la persona responsable del recurso, ateniĆ©ndose a la polĆ­tica y normativa de seguridad del sistema"}],"description": "Requisitos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.2.aws.iam.4": {"name": "op.acc.2.aws.iam.4","checks": {"iam_avoid_root_usage": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.2","DescripcionControl": "Se deberĆ” delegar en cuentas administradoras la administración de la organización, dejando la cuenta maestra sin uso y con las medidas de seguridad pertinentes."}],"description": "Requisitos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.acc.2.aws.vpn.1": {"name": "op.acc.2.aws.vpn.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.2","DescripcionControl": "DeberĆ” definirse una correcta polĆ­tica de permisos IAM para operaciones de Amazon WorkSpaces segĆŗn las recomendaciónes establecidas en la sección 3.1.1 Control de Acceso de la guĆ­a CCN STIC-887A GuĆ­a de configuración segura AWS."}],"description": "Requisitos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.2.aws.vpn.2": {"name": "op.acc.2.aws.vpn.2","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.2","DescripcionControl": "DeberĆ”n restringirse los permisos a usuarios para utilizar la acción ec2:DescribeVpnConnections. Esta acción permite a los usuarios ver la información de configuración de la gateway de cliente sobre las conexiones Site-to-Site VPN de su cuenta."}],"description": "Requisitos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.2.aws.vpn.3": {"name": "op.acc.2.aws.vpn.3","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.2","DescripcionControl": "La rotación de certificados de VPN deberĆ” asignarse siguiendo las recomendaciónes de segregación de funciones tal y como se explica en la sección 3.1.1."}],"description": "Requisitos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.3.aws.iam.1": {"name": "op.acc.3.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.3","DescripcionControl": "Enumerar los recursos especĆ­ficos a los que puede obtener acceso una función de trabajo."}],"description": "Segregación de funciones y tareas","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.3.aws.iam.2": {"name": "op.acc.3.aws.iam.2","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.3","DescripcionControl": "Emplear correctamente el uso de RBAC/ABAC para separar las funciones de desarrollo y operación."}],"description": "Segregación de funciones y tareas","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.3.aws.iam.3": {"name": "op.acc.3.aws.iam.3","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.3","DescripcionControl": "Emplear correctamente el uso de RBAC/ABAC para separar las funciones de autorización y control de uso."}],"description": "Segregación de funciones y tareas","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.3.aws.iam.4": {"name": "op.acc.3.aws.iam.4","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.3","DescripcionControl": "Las polĆ­ticas IAM deberĆ­an estar asociadas solo a grupos y a roles."}],"description": "Segregación de funciones y tareas","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.4.aws.iam.1": {"name": "op.acc.4.aws.iam.1","checks": {"awslambda_function_url_public": null,"awslambda_function_url_cors_policy": null,"sqs_queues_not_publicly_accessible": "PASS","organizations_scp_check_deny_regions": null,"s3_bucket_policy_public_write_access": "PASS","iam_policy_allows_privilege_escalation": null,"cloudwatch_cross_account_sharing_disabled": null,"awslambda_function_not_publicly_accessible": "PASS","organizations_account_part_of_organizations": null,"iam_inline_policy_no_administrative_privileges": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.4","DescripcionControl": "Las polĆ­ticas IAM deben permitir sólo los privilegios necesarios para cada rol. Se recomienda comenzar con el mĆ­nimo nivel de permisos e ir aƱadiendo permisos adicionales segĆŗn vaya surgiendo la necesidad en lugar de comenzar con permisos administrativos."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 3,"total": 13,"manual": 0}},"op.acc.4.aws.iam.2": {"name": "op.acc.4.aws.iam.2","checks": {"iam_policy_allows_privilege_escalation": null,"iam_inline_policy_no_administrative_privileges": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.4","DescripcionControl": "Evitar polĆ­ticas con comodines (wildcards) en su definición, que puedan otorgar privilegios administrativos completos."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 5,"manual": 0}},"op.acc.4.aws.iam.3": {"name": "op.acc.4.aws.iam.3","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automatico","IdGrupoControl": "op.acc.4","DescripcionControl": "Para una correcta implementación de la estrategia de polĆ­ticas de acceso, se recomienda utilizar la herramienta Policy Simulator para probar y solucionar posibles problemas en la asignación de polĆ­ticas."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.acc.4.aws.iam.4": {"name": "op.acc.4.aws.iam.4","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.4","DescripcionControl": "Se puede utilizar Acces Analyzer para identificar recursos y cuentas, validar las polĆ­ticas contra las prĆ”cticas recomendadas y generar polĆ­ticas con base en la actividad de acceso de registros de CloudTrail."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.4.aws.iam.5": {"name": "op.acc.4.aws.iam.5","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.4","DescripcionControl": "En cuanto a los accesos a las instancias alojadas en AWS se recomienda emplear mecanismos para mantener a las personas alejadas de los datos. Es decir, limitar al mĆ”ximo el acceso directo a los datos por parte de los usuarios."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.4.aws.iam.6": {"name": "op.acc.4.aws.iam.6","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.4","DescripcionControl": "Con AWS Systems Manager Automation pueden utilizarse documentos de automatización y diseƱar flujos de trabajo para la administración de cambios o la ejecución de operaciones estĆ”ndar para administrar las instancias EC2 (p. ej., actualizar los sistemas operativos), en lugar de permitir el acceso directo. "}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.acc.4.aws.iam.7": {"name": "op.acc.4.aws.iam.7","checks": {"iam_avoid_root_usage": null,"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.4","DescripcionControl": "Se restringirĆ” todo acceso a las acciones especificadas para el usuario root de una cuenta."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"op.acc.4.aws.iam.8": {"name": "op.acc.4.aws.iam.8","checks": {"organizations_scp_check_deny_regions": null,"organizations_account_part_of_organizations": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.4","DescripcionControl": "Se restringirĆ” todo acceso a las acciones especificadas para el usuario root de una cuenta."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"op.acc.4.aws.iam.9": {"name": "op.acc.4.aws.iam.9","checks": {"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.4","DescripcionControl": "Se configurarĆ”n diferentes permisos a las cuentas de usuario, limitando la utilización de la cuenta ā€œrootā€ para tareas especĆ­ficas que necesiten un nivel de privilegios elevado, esta configuración debe entenderse como un mecanismo para impedir que el trabajo directo con usuarios con privilegios de administrador repercuta negativamente en la seguridad, a acometer todas las acciones con el mĆ”ximo privilegio cuando este no es siempre requerido."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"op.acc.4.aws.sys.1": {"name": "op.acc.4.aws.sys.1","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.4","DescripcionControl": "Habilitar systems manager automation para evitar acceso remoto humano a tareas automatizables."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.acc.4.aws.vpn.1": {"name": "op.acc.4.aws.vpn.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.4","DescripcionControl": "Las configuraciones de las polĆ­ticas de las AWS VPN deben tener las redes especĆ­ficas con las que se va a establecer la conectividad y evitar polĆ­ticas genĆ©ricas basadas en routing donde se pierde el control granular de las redes permitidas en los SA de la VPN."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.4.aws.vpn.2": {"name": "op.acc.4.aws.vpn.2","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.4","DescripcionControl": "En configuraciones de AWS DirectConnect, deberĆ”n controlarse los AS y el routing que se lleva por BGP, de modo que se propague el mĆ­nimo de rutas y se asegure que no exista redistribución de rutas/redes privadas de entornos del cliente hacia el ISP."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.6.aws.iam.1": {"name": "op.acc.6.aws.iam.1","checks": {"iam_user_two_active_access_key": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6","DescripcionControl": "Evitar el uso permanente de mĆŗltiples claves de acceso para un mismo usuario IAM."}],"description": "Mecanismo de autenticación (usuarios de la organización)","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.acc.6.aws.iam.2": {"name": "op.acc.6.aws.iam.2","checks": {"iam_user_accesskey_unused": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6","DescripcionControl": "Las claves de acceso deberĆ”n rotarse cada 90 dĆ­as o menos."}],"description": "Mecanismo de autenticación (usuarios de la organización)","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"op.acc.6.aws.iam.3": {"name": "op.acc.6.aws.iam.3","checks": {"iam_user_accesskey_unused": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6","DescripcionControl": "DeberĆ” habilitarse el vencimiento de las credenciales de los usuarios. (Bien a travĆ©s de la polĆ­tica de contraseƱas de IAM o del proveedor de identidades federado)."}],"description": "Mecanismo de autenticación (usuarios de la organización)","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"op.acc.6.aws.iam.4": {"name": "op.acc.6.aws.iam.4","checks": {"iam_user_no_setup_initial_access_key": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6","DescripcionControl": "Se deberĆ” evitar la asignación por defecto de claves de acceso para todos los usuarios que tengan acceso a la consola. Para cumplir con este requisito, se recomienda revisar quĆ© usuarios se encuentran dados de alta en la cuenta de AWS y disponen de acceso a la consola de administración y evitar la asignación de claves de acceso cuando no son necesarias."}],"description": "Mecanismo de autenticación (usuarios de la organización)","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.cont.2.aws.az.1": {"name": "op.cont.2.aws.az.1","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "continuidad del servicio","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.cont.2","DescripcionControl": "(Organizativo) DeberĆ” implementarse correctamente la distribución de servicios segĆŗn regiones y zonas de disponibilidad para limitar al mĆ”ximo los riesgos asociados a una Ćŗnica ubicación."}],"description": "Plan de continuidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.1.aws.cfg.1": {"name": "op.exp.1.aws.cfg.1","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.1","DescripcionControl": "En lo referente al inventariado de activos, asegurar que AWS Config estĆ” habilitado en todas las regiones y utilizar la herramienta para obtener una vista de los recursos existentes en las cuentas de AWS."}],"description": "Inventario de activos","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.1.aws.cfg.2": {"name": "op.exp.1.aws.cfg.2","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "bajo","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.1","DescripcionControl": "Configurar una regla de Config Rules que alerte sobre el despliegue de recursos sin las etiquetas correspondientes asociadas."}],"description": "Inventario de activos","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.1.aws.sys.1": {"name": "op.exp.1.aws.sys.1","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.1","DescripcionControl": "En el Ć”mbito del software desplegado en las instancias de EC2, habilitar AWS System Manager Inventory para todo el entorno de EC2 en caso de no utilizar herramientas de terceros."}],"description": "Inventario de activos","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"op.exp.1.aws.sys.2": {"name": "op.exp.1.aws.sys.2","checks": {"organizations_tags_policies_enabled_and_attached": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.1","DescripcionControl": "Asignar metadatos personalizados a cada nodo administrado con información sobre el responsable del activo."}],"description": "Inventario de activos","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.1.aws.tag.1": {"name": "op.exp.1.aws.tag.1","checks": {"organizations_tags_policies_enabled_and_attached": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.1","DescripcionControl": "Para la correcta identificación del responsable, asociar etiquetas para todos los activos."}],"description": "Inventario de activos","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.3.aws.cfg.1": {"name": "op.exp.3.aws.cfg.1","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "bajo","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.3","DescripcionControl": "El cumplimiento de los requisitos se puede apoyar en la utilización de los servicios Config, Config Rules y Conformance Packs para identificar lĆ­neas base de configuración para evaluar si los recursos de AWS se ajustan a las prĆ”cticas autorizadas por la organización."}],"description": "Gestión de la configuración de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.4.aws.ami.1": {"name": "op.exp.4.aws.ami.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.4","DescripcionControl": "Una forma eficiente de garantizar la instalación de las versiones actualizadas y aprobadas del software de los sistemas es la utilización de Golden AMIs."}],"description": "Mantenimiento y actualizaciones de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.4.aws.sys.2": {"name": "op.exp.4.aws.sys.2","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.4","DescripcionControl": "Utilizar AWS Systems Manager Patch Manager para planificar y gestionar la aplicación de parches minimizando los riesgos asociados a tener instancias con software desactualizado y expuesto a vulnerabilidades conocidas."}],"description": "Mantenimiento y actualizaciones de seguridad","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"op.exp.5.aws.cal.1": {"name": "op.exp.5.aws.cal.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.5","DescripcionControl": "Utilizar AWS Change Calendar para establecer una ventana de tiempo (fecha y hora) en la que realizar los cambios y las pruebas de preproducción en equipos equivalentes a los de producción sin riesgo a que estas afecten a la continuidad del servicio prestado."}],"description": "Gestión de cambios","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.9.aws.img.1": {"name": "op.exp.9.aws.img.1","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssmincidents_enabled_with_plans": null},"status": "FAIL","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.9","DescripcionControl": "Habilitar AWS Incident Manager y AWS CloudTrail en todas las regiones con el fin de recopilar información para generar contenido prescriptivo para la creación de informes exigidos por la medida de seguridad."}],"description": "Registro de la gestión de incidentes","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"op.mon.3.aws.cwl.1": {"name": "op.mon.3.aws.cwl.1","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automatico","IdGrupoControl": "op.mon.3","DescripcionControl": "DeberĆ” asegurarse que todos los servicios que se utilicen en la arquitectura de la aplicación desplegada en AWS estĆ©n generando logs"}],"description": "Vigilancia","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.info.6.aws.iam.1": {"name": "mp.info.6.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de la información","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.info.6","DescripcionControl": "La organización puede hacer uso de roles y polĆ­ticas IAM para la definición y asignación de permisos en cuanto a controles de acceso de las copias de respaldo."}],"description": "Copias de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.info.6.aws.tag.1": {"name": "mp.info.6.aws.tag.1","checks": {"organizations_tags_policies_enabled_and_attached": null},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de la información","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.info.6","DescripcionControl": "Los planes de respaldo se pueden integrar con AWS Tags, acotando con base en las etiquetas de los recursos el alcance de cada proceso de copiado."}],"description": "Copias de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.acc.4.aws.iam.10": {"name": "op.acc.4.aws.iam.10","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.4","DescripcionControl": "Se evitarĆ” que los usuarios puedan deshabilitar o modificar servicios relacionados con el Ć”rea de seguridad como AWS Config o AWS CloudWatch."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.4.aws.iam.11": {"name": "op.acc.4.aws.iam.11","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.4","DescripcionControl": "DeberĆ” definirse una polĆ­tica de IAM que conceda permiso al usuario o rol de IAMpara utilizar exclusivamente los recursos y las acciones de WorkSpace que necesita."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.4.aws.iam.12": {"name": "op.acc.4.aws.iam.12","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.4","DescripcionControl": "Las polĆ­ticas IAM Ćŗnicamente deben poder asignarse por el usuario que tenga la función de control de accesos expresamente atribuida."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.4.aws.iam.13": {"name": "op.acc.4.aws.iam.13","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.4","DescripcionControl": "No utilizar el usuario raĆ­z salvo necesidad expresa."}],"description": "Proceso de gestión de derechos de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.cont.3.aws.drs.1": {"name": "op.cont.3.aws.drs.1","checks": {"drs_job_exist": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "continuidad del servicio","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.cont.3","DescripcionControl": "La organización puede hacer uso del servicio AWS Elastic Disaster Recovery, programando y ejecutando pruebas no disruptivas (simulacros que no afectan ni al servidor de origen ni a la replicación de datos en curso) que prueben el correcto funcionamiento de las recuperaciones del plan de continuidad."}],"description": "Pruebas periódicas","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.10.aws.cmk.1": {"name": "op.exp.10.aws.cmk.1","checks": {"iam_policy_no_full_access_to_kms": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.10","DescripcionControl": "Los usuarios o roles con privilegios para la creación de claves deben ser diferentes a los que van a utilizar las claves para operaciones de cifrado."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.10.aws.cmk.2": {"name": "op.exp.10.aws.cmk.2","checks": {"iam_policy_no_full_access_to_kms": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.10","DescripcionControl": "Utilizar claves gestionadas por los clientes (CMK)."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.10.aws.cmk.3": {"name": "op.exp.10.aws.cmk.3","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.10","DescripcionControl": "Activar la rotación de las claves CMK."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.10.aws.cmk.4": {"name": "op.exp.10.aws.cmk.4","checks": {"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.10","DescripcionControl": "Para el archivo posterior a la explotación y destrucción de las claves se debe deshabilitar todas las claves CMK que no estĆ©n en uso."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.10.aws.cmk.5": {"name": "op.exp.10.aws.cmk.5","checks": {"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.10","DescripcionControl": "Eliminar las claves deshabilitadas que no estĆ©n en uso y no mantengan ningĆŗn objeto o recurso cifrado, completando el ciclo de vida de la clave."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.10.aws.cmk.6": {"name": "op.exp.10.aws.cmk.6","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.10","DescripcionControl": "Utilizar el principio de mĆ­nimos privilegios para las polĆ­ticas asociadas a claves."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.10.aws.cmk.7": {"name": "op.exp.10.aws.cmk.7","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.10","DescripcionControl": "Utilizar tags y alias para una mejor administración de las claves."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.10.aws.cmk.8": {"name": "op.exp.10.aws.cmk.8","checks": {},"status": "PASS","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.10","DescripcionControl": "Utilizar las polĆ­ticas IAM y las concesiones de claves para el acceso a las mismas."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.10.aws.tag.1": {"name": "op.exp.10.aws.tag.1","checks": {"organizations_tags_policies_enabled_and_attached": null},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.10","DescripcionControl": "Se recomienda utilizar tags y alias para una mejor gestión y administración de las claves."}],"description": "Protección de claves criptogrĆ”ficas","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.mon.1.aws.flow.1": {"name": "op.mon.1.aws.flow.1","checks": {"vpc_flow_logs_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "requisito","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.1","DescripcionControl": "Activar el servicio VPC FlowLogs."}],"description": "Detección de intrusión","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.pl.2.aws.warch.1": {"name": "op.pl.2.aws.warch.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.2.r3","DescripcionControl": "Es recomendable que la entidad usuaria se apoye en el marco de trabajo AWS Well-Architected Framework"}],"description": "Validación de datos","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.pl.4.r1.aws.cw.1": {"name": "op.pl.4.r1.aws.cw.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.4.r1","DescripcionControl": "En caso de no disponer de herramientas de terceros, se deberĆ”n utilizar las herramientas de monitorización de la capaciad indicadas para monitorizar las capacidades de la infraestructura y el grado de consumo de los servicios en función de las cuotas disponibles. (CloudWatch)"}],"description": "Mejora continua de la gestión de la capacidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.pl.4.r1.aws.sq.1": {"name": "op.pl.4.r1.aws.sq.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.4.r1","DescripcionControl": "En caso de no disponer de herramientas de terceros, se deberĆ”n utilizar las herramientas de monitorización de la capaciad indicadas para monitorizar las capacidades de la infraestructura y el grado de consumo de los servicios en función de las cuotas disponibles. (Service Quotas)"}],"description": "Mejora continua de la gestión de la capacidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.pl.4.r1.aws.sq.2": {"name": "op.pl.4.r1.aws.sq.2","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.4.r1","DescripcionControl": "En cuanto a la monitorización sobre el grado de consumo, utilizar la solución nativa Quota Monitor."}],"description": "Previsión y actualización de la capacidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.pl.4.r1.aws.sq.3": {"name": "op.pl.4.r1.aws.sq.3","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.4.r1","DescripcionControl": "Visualizar las cuotas de servicio y configurar alarmas a travĆ©s de la integración de AWS Service Quotas con CloudWatch."}],"description": "Monitorización de la capacidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.info.6.aws.bcku.1": {"name": "mp.info.6.aws.bcku.1","checks": {"backup_plans_exist": "PASS","backup_vaults_exist": null,"backup_reportplans_exist": null},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de la información","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.info.6","DescripcionControl": "Para los procedimientos de respaldo de cualquiera de los dos entornos (local y nube) y siempre y cuando se utilicen recursos compatibles en el entorno local, la entidad puede hacer uso de AWS Backup, que permite elaboración de planes de respaldo y la definición de reglas de frecuencia, ciclo de vida, lugar de almacenamiento y etiquetado de las copias de seguridad."}],"description": "Copias de seguridad","checks_status": {"fail": 0,"pass": 1,"total": 3,"manual": 0}},"mp.si.2.r1.aws.kms.1": {"name": "mp.si.2.r1.aws.kms.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.si.2.r1","DescripcionControl": "Utilizar productos certificados conforme a op.pl.5, si bien AWS KMS es un producto certificado cuyo uso satisface la exigencia de este control."}],"description": "Productos certificados","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.si.2.r2.aws.ebs.1": {"name": "mp.si.2.r2.aws.ebs.1","checks": {"ec2_ebs_snapshots_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los soportes de información","Dimensiones": ["confidencialidad","integridad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.si.2.r2","DescripcionControl": "Se deberĆ” asegurar el cifrado de las copias de seguridad (snapshots) de EBS."}],"description": "Copias de seguridad","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"mp.sw.2.r1.aws.acb.1": {"name": "mp.sw.2.r1.aws.acb.1","checks": {"codebuild_project_older_90_days": "FAIL","codebuild_project_user_controlled_buildspec": "PASS"},"status": "FAIL","attributes": [{"Tipo": "recomendacion","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de la información","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.sw.2.r1","DescripcionControl": "Habilitar Amazon CodeBuild para el apoyo de la realización de pruebas en entornos aisaldos."}],"description": "Aceptación y puesta en servicio","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"op.exp.8.r1.aws.ct.2": {"name": "op.exp.8.r1.aws.ct.2","checks": {"cloudtrail_insights_exist": null,"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r1","DescripcionControl": "Configurar la herramienta CloudTrail de manera que realice el registro de eventos de administración, eventos de datos y eventos anómalos (insights)."}],"description": "Revisión de los registros","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"op.exp.8.r1.aws.ct.3": {"name": "op.exp.8.r1.aws.ct.3","checks": {"cloudtrail_insights_exist": null,"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r1","DescripcionControl": "Registrar los eventos de lectura y escritura de datos."}],"description": "Revisión de los registros","checks_status": {"fail": 0,"pass": 0,"total": 4,"manual": 0}},"op.exp.8.r1.aws.ct.4": {"name": "op.exp.8.r1.aws.ct.4","checks": {"cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r1","DescripcionControl": "Registrar los eventos de lectura y escritura de datos."}],"description": "Revisión de los registros","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"op.exp.8.r1.aws.ct.6": {"name": "op.exp.8.r1.aws.ct.6","checks": {"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r1","DescripcionControl": "Habilitar la entrega continua de eventos de CloudTrail a un bucket de Amazon S3"}],"description": "Revisión de los registros","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.r1.aws.ct.7": {"name": "op.exp.8.r1.aws.ct.7","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r1","DescripcionControl": "Integrar CloudTrail con el servicio CloudWatch Logs"}],"description": "Revisión de los registros","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.r1.aws.cw.1": {"name": "op.exp.8.r1.aws.cw.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.8.r1","DescripcionControl": "Utilizar el servicio AWS CloudWatch para centralizar y revisar los registros de todos los sistemas independientemente de su origen."}],"description": "Revisión de los registros","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.8.r3.aws.ct.1": {"name": "op.exp.8.r3.aws.ct.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.8.r3","DescripcionControl": "Ejecutar la acción PutRetentionPolicy de Amazon CloudWatch, permitiendo asĆ­ establecer la retención del grupo de registros especificado y configurar el nĆŗmero de dĆ­as durante los cuales se conservarĆ”n los eventos de registro en el grupo seleccionado de acuerdo con el documento de seguridad correspondiente. Paralelamente, se debe definir un periodo de retención para los datos almacenados en CloudTrail Lakes."}],"description": "Retención de registros","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.8.r3.aws.cw.1": {"name": "op.exp.8.r3.aws.cw.1","checks": {"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r3","DescripcionControl": "Ejecutar la acción PutRetentionPolicy de Amazon CloudWatch, permitiendo asĆ­ establecer la retención del grupo de registros especificado y configurar el nĆŗmero de dĆ­as durante los cuales se conservarĆ”n los eventos de registro en el grupo seleccionado de acuerdo con el documento de seguridad correspondiente. Paralelamente, se debe definir un periodo de retención para los datos almacenados en CloudTrail Lakes."}],"description": "Retención de registros","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.r4.aws.ct.1": {"name": "op.exp.8.r4.aws.ct.1","checks": {"iam_policy_allows_privilege_escalation": null,"iam_policy_no_full_access_to_cloudtrail": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_role_cross_service_confused_deputy_prevention": null,"iam_customer_attached_policy_no_administrative_privileges": null,"iam_customer_unattached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r4","DescripcionControl": "Asignar correctamente las polĆ­ticas AWS IAM para el acceso y borrado de los registros y sus copias de seguridad haciendo uso del principio de mĆ­nimo privilegio."}],"description": "Control de acceso","checks_status": {"fail": 0,"pass": 0,"total": 7,"manual": 0}},"op.exp.8.r4.aws.ct.2": {"name": "op.exp.8.r4.aws.ct.2","checks": {"s3_bucket_public_access": null,"s3_bucket_policy_public_write_access": "PASS","cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r4","DescripcionControl": "Utilizar una polĆ­tica de bucket para restringir el acceso de forma pĆŗblica e imponer restricciones sobre cuĆ”les de los usuarios pueden eliminar objetos de Amazon S3."}],"description": "Control de acceso","checks_status": {"fail": 0,"pass": 2,"total": 3,"manual": 0}},"op.exp.8.r4.aws.ct.3": {"name": "op.exp.8.r4.aws.ct.3","checks": {"cloudtrail_bucket_requires_mfa_delete": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r4","DescripcionControl": "Activar el acceso por MFA al registro de actividad almacenado en los buckets de Amazon S3 dedicados para AWS CloudTrail."}],"description": "Control de acceso","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.r4.aws.ct.4": {"name": "op.exp.8.r4.aws.ct.4","checks": {"cloudtrail_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r4","DescripcionControl": "Configurar los archivos de logs de AWS CloudTrail para aprovechar el cifrado del lado del servidor (SSE – Server Side Encryption) y las claves maestras creadas por el cliente (CMK de KMS)."}],"description": "Control de acceso","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.r4.aws.ct.5": {"name": "op.exp.8.r4.aws.ct.5","checks": {"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r4","DescripcionControl": "El almacĆ©n de logs de CloudTrail no deberĆ­a ser accesible de forma pĆŗblica"}],"description": "Control de acceso","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.r4.aws.ct.6": {"name": "op.exp.8.r4.aws.ct.6","checks": {"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r4","DescripcionControl": "El almacĆ©n de logs de CloudTrail no deberĆ­a ser accesible de forma pĆŗblica(ACLs)"}],"description": "Control de acceso","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.exp.8.r4.aws.ct.7": {"name": "op.exp.8.r4.aws.ct.7","checks": {"cloudtrail_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r4","DescripcionControl": "Cifrado de los trails con KMS"}],"description": "Control de acceso","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.8.r4.aws.ct.8": {"name": "op.exp.8.r4.aws.ct.8","checks": {"iam_policy_allows_privilege_escalation": null,"iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_role_cross_service_confused_deputy_prevention": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["trazabilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.8.r4","DescripcionControl": "Asignar correctamente las polĆ­ticas IAM para el acceso y borrado de los registros y sus copias de seguridad haciendo uso del principio de mĆ­nimo privilegio."}],"description": "Control de acceso","checks_status": {"fail": 0,"pass": 0,"total": 7,"manual": 0}},"op.mon.3.r1.aws.gd.1": {"name": "op.mon.3.r1.aws.gd.1","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.3.r1","DescripcionControl": "Activar GuardDuty y Security Hub o bien disponer de un SIEM externo a AWS"}],"description": "Correlación de eventos","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.mon.3.r1.aws.sh.1": {"name": "op.mon.3.r1.aws.sh.1","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.3.r1","DescripcionControl": "Activar GuardDuty y Security Hub o bien disponer de un SIEM externo a AWS"}],"description": "Correlación de eventos","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.mon.3.r2.aws.sh.1": {"name": "op.mon.3.r2.aws.sh.1","checks": {"securityhub_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.3.r2","DescripcionControl": "Utilizar las herramientas AWS Config y Security hub"}],"description": "AnĆ”lisis dinĆ”mico","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.mon.3.r3.aws.gd.1": {"name": "op.mon.3.r3.aws.gd.1","checks": {"guardduty_is_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.3.r3","DescripcionControl": "Activar GuardDuty (ya cubierto)"}],"description": "Ciberamenazas avanzadas","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.pl.4.r1.aws.sns.1": {"name": "op.pl.4.r1.aws.sns.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.4.r1","DescripcionControl": "Para la creación de alarmas en materia de capacidad de las instancias, se debe configurar un tema de SNS que permita el envĆ­o de mails automĆ”ticos a la dirección de correo seleccionada."}],"description": "Monitorización de la capacidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.pl.4.r1.aws.sns.2": {"name": "op.pl.4.r1.aws.sns.2","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "planificación","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.pl.4.r1","DescripcionControl": "Configurar alarmas correspondientes a las diferentes capacidades (SNS) como uso de CPU, capacidad de almacenamiento o latencia."}],"description": "Monitorización de la capacidad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.com.3.r1.aws.vpn.1": {"name": "mp.com.3.r1.aws.vpn.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["integridad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.com.3.r1","DescripcionControl": "Utilizar VPN Site-to-Site para conectar las VPCs con las redes locales o externas."}],"description": "Redes privadas virtuales","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.com.4.r1.aws.vpc.1": {"name": "mp.com.4.r1.aws.vpc.1","checks": {"vpc_different_regions": null,"vpc_subnet_separate_private_public": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.4.r1","DescripcionControl": "Implementar la segmentación a travĆ©s de la utilización de diferentes VPCs."}],"description": "Segmentación lógica avanzada","checks_status": {"fail": 1,"pass": 0,"total": 2,"manual": 0}},"mp.com.4.r2.aws.vpc.1": {"name": "mp.com.4.r2.aws.vpc.1","checks": {"vpc_peering_routing_tables_with_least_privilege": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": ["mp.com.4.r3"],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.4.r2","DescripcionControl": "Implementar la segmentación a travĆ©s de la utilización de diferentes VPCs conectadas entre sĆ­ por VPN."}],"description": "Segmentación lógica avanzada","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"mp.com.4.r3.aws.vpc.1": {"name": "mp.com.4.r3.aws.vpc.1","checks": {"vpc_different_regions": null,"vpc_subnet_different_az": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de las comunicaciones","Dimensiones": ["confidencialidad","integridad"],"Dependencias": ["mp.com.4.r2"],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.com.4.r3","DescripcionControl": "Implementar la segmentación a travĆ©s de diferentes VPCs situadas en diferentes ubicaciones."}],"description": "Segmentación fĆ­sica","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"mp.sw.2.r1.aws.cfgd.1": {"name": "mp.sw.2.r1.aws.cfgd.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de la información","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.sw.2.r2","DescripcionControl": "Habilitar CloudFormation Guard para el apoyo en las tareas de inspección de recursos no conformes implementados en el código fuente."}],"description": "Aceptación y puesta en servicio","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.1.r1.aws.iam.1": {"name": "op.acc.1.r1.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.1.r1","DescripcionControl": "Los identificadores de usuario deberĆ”n ser asignados en el proveedor de identidades (o en IAM) de modo que se permita singularizar a la persona asociada a cada identificador y cumplir con el resto de requisitos del refuerzo"}],"description": "Identificación de usuario","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.2.r1.aws.iam.1": {"name": "op.acc.2.r1.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.2.r1","DescripcionControl": "Evitar el uso de asunción de roles para cualquier cuenta."}],"description": "Privilegios de acceso","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.3.r1.aws.iam.1": {"name": "op.acc.3.r1.aws.iam.1","checks": {"iam_support_role_created": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.3.r1","DescripcionControl": "En caso de ser de aplicación, la segregación deberĆ” tener en cuenta la separación de las funciones de configuración y mantenimiento y de auditorĆ­a de cualquier otra."}],"description": "Segregación rigurosa","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.acc.3.r2.aws.iam.1": {"name": "op.acc.3.r2.aws.iam.1","checks": {"iam_securityaudit_role_created": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "opcional","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.3.r2","DescripcionControl": "Disponer de cuentas con privilegios de auditorĆ­a estrictamente controladas y personalizadas."}],"description": "Privilegios de auditorĆ­a","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.acc.3.r3.aws.iam.1": {"name": "op.acc.3.r3.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "opcional","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.3.r3","DescripcionControl": "Limitar el acceso a la información de seguridad del sistema a los administradores de seguridad utilizando los mecanismos de acceso imprescindibles (consola, interfaz web, acceso remoto etc.)."}],"description": "Acceso a la información de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.6.r1.aws.iam.1": {"name": "op.acc.6.r1.aws.iam.1","checks": {"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": ["op.acc.6.r2","op.acc.6.r4"],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6.r1","DescripcionControl": "Las contraseƱas de los usuarios deberĆ”n tener normas de complejidad mĆ­nima y robustez."}],"description": "ContraseƱas","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"op.acc.6.r2.aws.iam.1": {"name": "op.acc.6.r2.aws.iam.1","checks": {"iam_root_mfa_enabled": null,"iam_administrator_access_with_mfa": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": ["op.acc.6.r1","op.acc.6.r4"],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6.r2","DescripcionControl": "MFA deberĆ” estar habilitado para todas las cuentas que tengan contraseƱa para acceder a la consola, incluyendo el usuario root."}],"description": "ContraseƱa + otro factor de autenticación","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"op.acc.6.r2.aws.iam.2": {"name": "op.acc.6.r2.aws.iam.2","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.6.r2","DescripcionControl": "Se recomienda que la organización determine quĆ© llamadas a la API deben tambiĆ©n contar con seguridad reforzada a travĆ©s de un doble factor de autenticación."}],"description": "ContraseƱa + otro factor de autenticación","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.6.r3.aws.iam.1": {"name": "op.acc.6.r3.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.6.r3","DescripcionControl": "Utilizar el servicio AWS IAM Roles Anywhere para crear un ancla de confianza en la que se haga referencia al servicio AWS Certificate Manager Private CA o registrar sus propias autoridades de certificación (CA), permitiendo usar el certificado emitido por la misma para obtener credenciales temporales para el acceso al entorno AWS. Estos certificados deberĆ”n estar protegidos por un segundo factor."}],"description": "Certificados","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.6.r4.aws.iam.1": {"name": "op.acc.6.r4.aws.iam.1","checks": {"iam_root_hardware_mfa_enabled": null,"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": ["op.acc.6.r1","op.acc.6.r3"],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6.r4","DescripcionControl": "Habilitar los dispositivos MFA fĆ­sicos para todos los usuarios IAM mediante la consola, lĆ­nea de comandos o la propia API de IAM. Del mismo modo, el uso de estos certificados deberĆ” estar protegido por un segundo factor de tipo PIN o biomĆ©trico."}],"description": "Certificados en dispositvo fĆ­sico","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"op.acc.6.r5.aws.iam.1": {"name": "op.acc.6.r5.aws.iam.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6.r5","DescripcionControl": "Para registrar los intentos de acceso, se deberĆ” habilitar CloudTrail en todas las regiones y activar el registro de acceso de usuarios."}],"description": "Registro","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"op.acc.6.r5.aws.iam.2": {"name": "op.acc.6.r5.aws.iam.2","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.6.r5","DescripcionControl": "Habilitar la información de usuario sobre la fecha de Ćŗltimo uso de sus claves de acceso."}],"description": "Registro","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.6.r7.aws.iam.1": {"name": "op.acc.6.r7.aws.iam.1","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6.r7","DescripcionControl": "Activar la deshabilitación de las credenciales de los usuarios IAM que no hayan sido empleadas durante un periodo de tiempo (o bien, se deberĆ” establecer la deshabilitación en el proveedor de identidades)."}],"description": "Suspensión por no utilización","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"op.acc.6.r8.aws.iam.1": {"name": "op.acc.6.r8.aws.iam.1","checks": {"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.acc.6.r8","DescripcionControl": "Se deberĆ” emplear como mecanismo de autenticación o bien una contraseƱa mĆ”s otro factor de autenticación, o bien un certificado cualificado (con o sin soporte fĆ­sico) protegido por un doble factor de autenticación."}],"description": "Doble factor para acceso desde o a travĆ©s de zonas no controladas","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.acc.6.r9.aws.iam.1": {"name": "op.acc.6.r9.aws.iam.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.6.9","DescripcionControl": "DeberĆ” asegurarse que se estĆ” haciendo uso de HTTPS en todas las llamadas a API. Esto se puede lograr a travĆ©s de una polĆ­tica IAM que rechace el trĆ”fico que no sea HTTPS."}],"description": "Acceso remoto (todos los niveles)","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.acc.6.r9.aws.iam.2": {"name": "op.acc.6.r9.aws.iam.2","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "control de acceso","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.acc.6.9","DescripcionControl": "En caso de que las llamadas a las APIs no se produzcan de manera constante, se recomienda condicionar su realización a aquellas franjas horarias en las que sean necesarias. "}],"description": "Acceso remoto (todos los niveles)","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.1.r3.aws.tag.1": {"name": "op.exp.1.r3.aws.tag.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "opcional","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.1.r4","DescripcionControl": "Mantener actualizada una relación de los componentes software de terceros utilizados en el despliegue del sistema. Listado equivalente a lo requerido en mp.sw.1.r5."}],"description": "Lista de componentes software","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.3.r3.aws.cfg.1": {"name": "op.exp.3.r3.aws.cfg.1","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.3.r3","DescripcionControl": "La entidad usuaria puede consultar el histórico de configuraciones de recursos en AWS Config."}],"description": "Copias de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.3.r4.aws.cfg.2": {"name": "op.exp.3.r4.aws.cfg.2","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.3.r3","DescripcionControl": "Desplegar toda la infraestructura de AWS a travĆ©s de código con el servicio AWS CloudFormation."}],"description": "Copias de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.4.r2.aws.sys.1": {"name": "op.exp.4.r2.aws.sys.1","checks": {"ec2_instance_managed_by_ssm": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.4.r2","DescripcionControl": "Utilizar la solución AWS Systems Manager Automation para automatizar las tareas de corrección en servicios de AWS como EC2 y RDS."}],"description": "Prevención de fallos","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"op.exp.6.r1.aws.sys.1": {"name": "op.exp.6.r1.aws.sys.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.6.r1","DescripcionControl": "Automatizar las operaciones estĆ”ndar a llevar a cabo para la respuesta en caso de incidente a travĆ©s de AWS System Manager"}],"description": "Escaneo periódico","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.6.r3.aws.sys.1": {"name": "op.exp.6.r3.aws.sys.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.6.r3","DescripcionControl": "Hacer uso de AWS System Manager Inventory para definir, a nivel de software, una lista blanca de aplicaciones."}],"description": "Lista blanca","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.6.r4.aws.sys.1": {"name": "op.exp.6.r4.aws.sys.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.6.r4","DescripcionControl": "Automatizar tareas estĆ”ndar a travĆ©s de AWS System Manager"}],"description": "Capacidad de respuesta en caso de incidente","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.mon.3.r2.aws.cfg.1": {"name": "op.mon.3.r2.aws.cfg.1","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.3.r2","DescripcionControl": "Utilizar las herramientas AWS Config y Security hub"}],"description": "AnĆ”lisis dinĆ”mico","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.mon.3.r6.aws.cfg.1": {"name": "op.mon.3.r6.aws.cfg.1","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.3.r6","DescripcionControl": "Utilizar Config Rules y AWS Inspector"}],"description": "Inspecciones de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"op.exp.4.r4.aws.insp.1": {"name": "op.exp.4.r4.aws.insp.1","checks": {"inspector2_is_enabled": "FAIL","inspector2_active_findings_exist": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "opcional","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.exp.4.r4","DescripcionControl": "Desplegar a nivel de sistema una estrategia de monitorización continua de amenazas y vulnerabilidades detallando: indicadores crĆ­ticos de seguridad, polĆ­tica de aplicación de parches y criterios de revisión regular y excepcional de amenazas del sistema."}],"description": "Monitorización continua","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"op.mon.3.r2.aws.insp.1": {"name": "op.mon.3.r2.aws.insp.1","checks": {"inspector2_is_enabled": "FAIL","inspector2_active_findings_exist": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.3.r2","DescripcionControl": "Utilizar la herramienta Inspector para la detección de posibles vulneerabilidades de las instancias EC2, las funciones Lambda y las imĆ”genes de contenedor."}],"description": "AnĆ”lisis dinĆ”mico","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"op.mon.3.r6.aws.insp.1": {"name": "op.mon.3.r6.aws.insp.1","checks": {"inspector2_is_enabled": "FAIL","inspector2_active_findings_exist": "FAIL"},"status": "FAIL","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "alto","Categoria": "monitorización del sistema","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "op.mon.3.r6","DescripcionControl": "Utilizar Config Rules y AWS Inspector."}],"description": "Inspecciones de seguridad","checks_status": {"fail": 2,"pass": 0,"total": 2,"manual": 0}},"mp.info.6.r2.aws.bcku.1": {"name": "mp.info.6.r2.aws.bcku.1","checks": {},"status": "PASS","attributes": [{"Tipo": "recomendacion","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de la información","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "mp.info.6.r2","DescripcionControl": "La organización puede hacer uso de la nube de AWS como ubicación diferente para el almacenamiento de la copia de seguridad separada del resto o, incluo, utilizar los servicios de ubicación para separar una copia de seguridad en una ubicación diferente dentro de la propia nube."}],"description": "Protección de las copias de seguridad","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"op.exp.1.r2.aws.sminv.1": {"name": "op.exp.1.r2.aws.sminv.1","checks": {},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "operacional","Nivel": "opcional","Categoria": "explotación","Dimensiones": ["confidencialidad","integridad","trazabilidad","autenticidad","disponibilidad"],"Dependencias": [],"ModoEjecucion": "manual","IdGrupoControl": "op.exp.1.r2","DescripcionControl": "Disponer de herramientas que permitan visualizar de forma continua el estado de todos los equipos en la red, en particular servidores y los dispositivos de red y comunicaciones."}],"description": "Identificación periódica de activos","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"mp.s.4.r1.aws.shieldadv.1": {"name": "mp.s.4.r1.aws.shieldadv.1","checks": {"shield_advanced_protection_in_global_accelerators": null,"shield_advanced_protection_in_route53_hosted_zones": null,"shield_advanced_protection_in_associated_elastic_ips": null,"shield_advanced_protection_in_classic_load_balancers": null,"shield_advanced_protection_in_cloudfront_distributions": null,"shield_advanced_protection_in_internet_facing_load_balancers": null},"status": "PASS","attributes": [{"Tipo": "refuerzo","Marco": "medidas de protección","Nivel": "alto","Categoria": "protección de los servicios","Dimensiones": ["disponibilidad"],"Dependencias": [],"ModoEjecucion": "automĆ”tico","IdGrupoControl": "mp.s.4.r1","DescripcionControl": "Activar AWS Shield Advanced con el fin de disponer de una herramienta de prevención, detección y mitigación de ataques de denegación de servicio."}],"description": "Detección y reacción","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}}},"requirements_passed": 83,"requirements_failed": 37,"requirements_manual": 69,"total_requirements": 189,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "eeee198e-1eda-48dc-aeb6-eb28e98f8dde","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "kisa_isms_p_2023_korean_aws","framework": "KISA-ISMS-P","version": "2023-korean","description": "ISMS-P ģøģ¦ģ€ ķ•œźµ­ģøķ„°ė„·ģ§„ķ„ģ›(KISA)ģ“ ģ œģ •ķ•œ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계넼 기반으딜, ė…ė¦½ģ ģø ģ‹¬ģ‚¬źø°ź“€ģ“ źø°ģ—…ģ“ė‚˜ ģ”°ģ§ģ˜ ė³“ģ•ˆ ė° ź°œģøģ •ė³“ 볓호 ķ™œė™ģ“ ģøģ¦ źø°ģ¤€ģ„ ģ¶©ģ”±ķ•˜ėŠ”ģ§€ ķ‰ź°€ķ•œ 후 ģøģ¦ģ„ ė¶€ģ—¬ķ•˜ėŠ” ģ œė„ģž…ė‹ˆė‹¤. ģ“ė„¼ 통핓 źø°ģ—…ź³¼ źø°ź“€ģ€ ģ œź³µķ•˜ėŠ” ģ„œė¹„ģŠ¤ģ— ėŒ€ķ•œ ėŒ€ģ¤‘ģ˜ 신뢰넼 ė†’ģ“ź³ , 점점 ė³µģž”ķ•“ģ§€ėŠ” ģ‚¬ģ“ė²„ ģœ„ķ˜‘ģ— 효과적으딜 ėŒ€ģ‘ķ•  수 ģžˆģŠµė‹ˆė‹¤. ė˜ķ•œ, ISMS-PėŠ” ģ •ė³“ė³“ķ˜øģ™€ ź°œģøģ •ė³“ 볓호넼 ģ²“ź³„ģ ģœ¼ė”œ ģˆ˜ė¦½ķ•˜ź³  ģš“ģ˜ķ•  수 ģžˆėŠ” ķ¬ź“„ģ ģø ģ§€ģ¹Øģ„ ģ œź³µķ•©ė‹ˆė‹¤.","region": "eu-west-1","requirements": {"1.1.1": {"name": "ź²½ģ˜ģ§„ģ˜ ģ°øģ—¬","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.1.1 ź²½ģ˜ģ§„ģ˜ ģ°øģ—¬","Subdomain": "1.1. ꓀리첓계","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 볓고 첓계(ģ˜ģ‚¬ģ†Œķ†µź³„ķš 등)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģœ„ģ›ķšŒ ķšŒģ˜ė”","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 정책·지침(ź²½ģ˜ģ§„ ģŠ¹ģøė‚“ģ—­ ķ¬ķ•Ø)","ģ •ė³“ė³“ķ˜øź³„ķš ė° ė‚“ė¶€ ź“€ė¦¬ź³„ķš(ź²½ģ˜ģ§„ ģŠ¹ģøė‚“ģ—­ ķ¬ķ•Ø)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ”°ģ§ė„"],"AuditChecklist": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ź“€ė¦¬ģ²“ź³„ģ˜ 수립 ė° ģš“ģ˜ķ™œė™ ģ „ė°˜ģ— ź²½ģ˜ģ§„ģ˜ 참여가 ģ“ė£Øģ–“ģ§ˆ 수 ģžˆė„ė” 볓고 ė° ģ˜ģ‚¬ź²°ģ • ė“±ģ˜ ģ±…ģž„ź³¼ ģ—­ķ• ģ„ ė¬øģ„œķ™”ķ•˜ź³  ģžˆėŠ”ź°€?","ź²½ģ˜ģ§„ģ“ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ģ— ź“€ķ•œ ģ˜ģ‚¬ź²°ģ •ģ— 적극적으딜 참여할 수 ģžˆėŠ” 볓고, 검토 ė° ģŠ¹ģø 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…ģ„œģ— ė¶„źø°ė³„ė”œ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ˜„ķ™©ģ„ ź²½ģ˜ģ§„ģ—ź²Œ ė³“ź³ ķ•˜ė„ė” ėŖ…ģ‹œķ•˜ģ˜€ģœ¼ė‚˜, ģž„źø°ź°„ ꓀련 볓고넼 ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģ¤‘ģš” ģ •ė³“ė³“ķ˜ø ķ™œė™(ģœ„ķ—˜ķ‰ź°€, ģœ„ķ—˜ģˆ˜ģš©ģˆ˜ģ¤€ ź²°ģ •, ģ •ė³“ė³“ķ˜øėŒ€ģ±… ė° ģ“ķ–‰ź³„ķš 검토, ģ •ė³“ė³“ķ˜øėŒ€ģ±… ģ“ķ–‰ź²°ź³¼ 검토, ė³“ģ•ˆź°ģ‚¬ 등)ģ„ ģˆ˜ķ–‰ķ•˜ė©“ģ„œ ꓀련 ķ™œė™ź“€ė Ø 볓고, ģŠ¹ģø 등 ģ˜ģ‚¬ź²°ģ •ģ— ź²½ģ˜ģ§„ ė˜ėŠ” ź²½ģ˜ģ§„ģ˜ ź¶Œķ•œģ„ ģœ„ģž„ė°›ģ€ ģžź°€ ģ°øģ—¬ķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜ ꓀련 ģ¦ź±°ģžė£Œź°€ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ģµœź³ ź²½ģ˜ģžėŠ” ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ź“€ė¦¬ģ²“ź³„ģ˜ 수립과 ģš“ģ˜ķ™œė™ ģ „ė°˜ģ— ź²½ģ˜ģ§„ģ˜ 참여가 ģ“ė£Øģ–“ģ§ˆ 수 ģžˆė„ė” 볓고 ė° ģ˜ģ‚¬ź²°ģ • 첓계넼 ģˆ˜ė¦½ķ•˜ģ—¬ ģš“ģ˜ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.2": {"name": "ģµœź³ ģ±…ģž„ģžģ˜ 지정","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.1.2 ģµœź³ ģ±…ģž„ģžģ˜ 지정","Subdomain": "1.1. ꓀리첓계","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģž ģž„ėŖ…ź“€ė Ø ģžė£Œ(ģøģ‚¬ėŖ…ė ¹, ģøģ‚¬ģ¹“ė“œ 등)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ”°ģ§ė„","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 정책·지침","ģ§ė¬“źø°ģˆ ģ„œ(ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ˜ ģ—­ķ•  ė° ģ±…ģž„ģ— ź“€ķ•œ 사항)","ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ģ‹ ź³  ė‚“ģ—­","ė‚“ė¶€ ź“€ė¦¬ź³„ķš(ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģž 지정에 ź“€ķ•œ 사항)"],"AuditChecklist": ["ģµœź³ ź²½ģ˜ģžėŠ” ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ²˜ė¦¬ģ— ź“€ķ•œ 업묓넼 ģ“ź“„ķ•˜ģ—¬ ģ±…ģž„ģ§ˆ ģµœź³ ģ±…ģž„ģžė„¼ ź³µģ‹ģ ģœ¼ė”œ ģ§€ģ •ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžėŠ” ģ˜ˆģ‚°, ģøė „ 등 ģžģ›ģ„ 할당할 수 ģžˆėŠ” ģž„ģ›źø‰ģœ¼ė”œ ģ§€ģ •ķ•˜ź³  ģžˆģœ¼ė©°, ꓀련 법령에 따넸 ģžź²©ģš”ź±“ģ„ ģ¶©ģ”±ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ķ†µģ‹ ė§ė²•ģ— 따넸 ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž 지정 ė° ģ‹ ź³  ģ˜ė¬“ ėŒ€ģƒģžģž„ģ—ė„ ė¶ˆźµ¬ķ•˜ź³  ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģžė„¼ 지정 ė° ģ‹ ź³ ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ź°œģøģ •ė³“ ė³“ķ˜øģ™€ ź“€ė Øėœ ģ‹¤ģ§ˆģ ģø ź¶Œķ•œ ė° ģ§€ģœ„ė„¼ ė³“ģœ ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ ģøģ›ģ„ ź°œģøģ •ė³“ 볓호 ģ±…ģž„ģžė”œ ģ§€ģ •ķ•˜ź³  ģžˆģ–“, ź°œģøģ •ė³“ ģ²˜ė¦¬ģ— ź“€ķ•œ 업묓넼 ģ“ź“„ķ•“ģ„œ ģ±…ģž„ģ§ˆ 수 ģžˆė‹¤ź³  볓기 ģ–“ė ¤ģš“ 경우","사딀 3 : ģ”°ģ§ė„ģƒģ— ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžė„¼ ėŖ…ģ‹œķ•˜ź³  ģžˆģœ¼ė‚˜, ģøģ‚¬ė°œė ¹ ė“±ģ˜ ź³µģ‹ģ ģø ģ§€ģ •ģ ˆģ°Øė„¼ ź±°ģ¹˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ISMS ģøģ¦ ģ˜ė¬“ėŒ€ģƒģžģ“ė©“ģ„œ ģ „ė…„ė„ 말 기준 ģžģ‚°ģ“ģ•”ģ“ 5ģ²œģ–µ ģ›ģ„ ģ“ˆź³¼ķ•œ ģ •ė³“ķ†µģ‹ ģ„œė¹„ģŠ¤ ģ œź³µģžģ“ģ§€ė§Œ ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģžź°€ CIO넼 ź²øģ§ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“), 제31ģ”°(ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ˜ 지정)","ģ •ė³“ķ†µģ‹ ė§ė²• 제45ģ”°ģ˜3(ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģžģ˜ 지정 등)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ģµœź³ ź²½ģ˜ģžėŠ” ģ •ė³“ė³“ķ˜ø 업묓넼 ģ“ź“„ķ•˜ėŠ” ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģžģ™€ ź°œģøģ •ė³“ė³“ķ˜ø 업묓넼 ģ“ź“„ķ•˜ėŠ” ź°œģøģ •ė³“ė³“ķ˜ø ģ±…ģž„ģžė„¼ ģ˜ˆģ‚°Ā·ģøė „ 등 ģžģ›ģ„ 할당할 수 ģžˆėŠ” ģž„ģ›źø‰ģœ¼ė”œ ģ§€ģ •ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.3": {"name": "씰직 구성","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.1.3 씰직 구성","Subdomain": "1.1. ꓀리첓계","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģœ„ģ›ķšŒ ź·œģ •Ā·ķšŒģ˜ė”","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 실묓 ķ˜‘ģ˜ģ²“ ź·œģ •Ā·ķšŒģ˜ė”","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ”°ģ§ė„","ė‚“ė¶€ ź“€ė¦¬ź³„ķš","ģ§ė¬“źø°ģˆ ģ„œ"],"AuditChecklist": ["ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ˜ 업묓넼 ģ§€ģ›ķ•˜ź³  ģ”°ģ§ģ˜ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ģ„ ģ²“ź³„ģ ģœ¼ė”œ ģ“ķ–‰ķ•˜źø° ģœ„ķ•˜ģ—¬ ģ „ė¬øģ„±ģ„ ź°–ģ¶˜ ģ‹¤ė¬“ģ”°ģ§ģ„ źµ¬ģ„±ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","씰직 ģ „ė°˜ģ— 걸친 ģ¤‘ģš”ķ•œ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련사항에 ėŒ€ķ•˜ģ—¬ 검토, ģŠ¹ģø ė° ģ˜ģ‚¬ź²°ģ •ģ„ ķ•  수 ģžˆėŠ” ģœ„ģ›ķšŒė„¼ źµ¬ģ„±ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","전사적 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ģ„ ģœ„ķ•˜ģ—¬ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ė‹“ė‹¹ģž ė° ė¶€ģ„œė³„ ė‹“ė‹¹ģžė”œ źµ¬ģ„±ėœ 실묓 ķ˜‘ģ˜ģ²“ė„¼ źµ¬ģ„±ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģœ„ģ›ķšŒė„¼ źµ¬ģ„±ķ•˜ģ˜€ģœ¼ė‚˜, ģž„ģ› 등 ź²½ģ˜ģ§„ģ“ ķ¬ķ•Øė˜ģ–“ ģžˆģ§€ ģ•Šź³  실묓 ė¶€ģ„œģ˜ ģž„ģœ¼ė”œ źµ¬ģ„±ė˜ģ–“ ģžˆģ–“ ģ”°ģ§ģ˜ ģ¤‘ģš” 정볓 ė° ź°œģøģ •ė³“ ė³“ķ˜øģ— ź“€ķ•œ ģ‚¬ķ•­ģ„ ź²°ģ •ķ•  수 ģ—†ėŠ” 경우","사딀 2 : ė‚“ė¶€ 지침에 ė”°ė¼ ģ¤‘ģš” ģ •ė³“ģ²˜ė¦¬ ė¶€ģ„œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ ė¶€ģ„œģ˜ ģž„(ķŒ€ģž„źø‰)으딜 źµ¬ģ„±ėœ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 실묓 ķ˜‘ģ˜ģ²“ė„¼ źµ¬ģ„±ķ•˜ģ˜€ģœ¼ė‚˜, ģž„źø°ź°„ 욓영 ģ‹¤ģ ģ“ ģ—†ėŠ” 경우","사딀 3 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģœ„ģ›ķšŒė„¼ ź°œģµœķ•˜ģ˜€ģœ¼ė‚˜, ģ—°ź°„ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ź³„ķš ė° 교윔 ź³„ķš, ģ˜ˆģ‚° ė° ģøė „ 등 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜øģ— ź“€ķ•œ ģ£¼ģš” ģ‚¬ķ•­ģ“ 검토 ė° ģ˜ģ‚¬ź²°ģ •ģ“ ė˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ‹¬ģ˜Ā·ģ˜ź²°ģ„ ģœ„ķ•“ ģ •ė³“ė³“ķ˜øģœ„ģ›ķšŒė„¼ źµ¬ģ„±ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, 욓영 ė° ITė³“ģ•ˆ ꓀련 씰직만 ģ°øģ—¬ķ•˜ź³  ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ”°ģ§ģ€ ģ°øģ—¬ķ•˜ģ§€ ģ•Šź³  ģžˆģ–“ ź°œģøģ •ė³“ė³“ķ˜øģ— ź“€ķ•œ ģ‚¬ķ•­ģ„ ź²°ģ •ķ•  수 ģ—†ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ģµœź³ ź²½ģ˜ģžėŠ” ģ •ė³“ė³“ķ˜øģ™€ ź°œģøģ •ė³“ė³“ķ˜øģ˜ 효과적 źµ¬ķ˜„ģ„ ģœ„ķ•œ 실묓씰직, 씰직 ģ „ė°˜ģ˜ ģ •ė³“ė³“ķ˜øģ™€ ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ£¼ģš” ģ‚¬ķ•­ģ„ 검토 ė° ģ˜ź²°ķ•  수 ģžˆėŠ” ģœ„ģ›ķšŒ, 전사적 ė³“ķ˜øķ™œė™ģ„ ģœ„ķ•œ ė¶€ģ„œė³„ ģ •ė³“ė³“ķ˜øģ™€ ź°œģøģ •ė³“ė³“ķ˜ø ė‹“ė‹¹ģžė”œ źµ¬ģ„±ėœ ķ˜‘ģ˜ģ²“ė„¼ źµ¬ģ„±ķ•˜ģ—¬ ģš“ģ˜ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.4": {"name": "ė²”ģœ„ 설정","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.1.4 ė²”ģœ„ 설정","Subdomain": "1.1. ꓀리첓계","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ė²”ģœ„ ģ •ģ˜ģ„œ","ģ •ė³“ģžģ‚° ė° ź°œģøģ •ė³“ ėŖ©ė”","ė¬øģ„œ ėŖ©ė”","ģ„œė¹„ģŠ¤ ķė¦„ė„","ź°œģøģ •ė³“ ķė¦„ė„","전사 ģ”°ģ§ė„","ģ‹œģŠ¤ķ…œ ė° ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„"],"AuditChecklist": ["ģ”°ģ§ģ˜ 핵심 ģ„œė¹„ģŠ¤ ė° ź°œģøģ •ė³“ ģ²˜ė¦¬ģ— ģ˜ķ–„ģ„ 줄 수 ģžˆėŠ” ķ•µģ‹¬ģžģ‚°ģ„ ķ¬ķ•Øķ•˜ė„ė” ꓀리첓계 ė²”ģœ„ė„¼ ģ„¤ģ •ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ģ˜ėœ ė²”ģœ„ ė‚“ģ—ģ„œ ģ˜ˆģ™øģ‚¬ķ•­ģ“ ģžˆģ„ 경우 ėŖ…ķ™•ķ•œ ģ‚¬ģœ  ė° ź“€ė Øģž ķ˜‘ģ˜Ā·ģ±…ģž„ģž ģŠ¹ģø 등 ꓀련 근거넼 źø°ė”Ā·ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ė²”ģœ„ė„¼ ėŖ…ķ™•ķžˆ ķ™•ģøķ•  수 ģžˆė„ė” ź“€ė Øėœ ė‚“ģš©(ģ£¼ģš” ģ„œė¹„ģŠ¤ ė° 업묓 ķ˜„ķ™©, ģ •ė³“ģ‹œģŠ¤ķ…œ ėŖ©ė”, ė¬øģ„œėŖ©ė” 등)ģ“ ķ¬ķ•Øėœ ė¬øģ„œė„¼ ģž‘ģ„±ķ•˜ģ—¬ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ź°œė°œģ—…ė¬“ģ— ź“€ė Øķ•œ 개발 ė° ģ‹œķ—˜ ģ‹œģŠ¤ķ…œ, 외주업첓직원, PC, ķ…ŒģŠ¤ķŠøģš© 단말기 ė“±ģ“ ꓀리첓계 ė²”ģœ„ģ—ģ„œ ėˆ„ė½ėœ 경우","사딀 2 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ė²”ģœ„ė”œ ģ„¤ģ •ėœ ģ„œė¹„ģŠ¤ ė˜ėŠ” 사업에 ėŒ€ķ•˜ģ—¬ ģ¤‘ģš” ģ˜ģ‚¬ź²°ģ •ģž ģ—­ķ• ģ„ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ” ģž„ģ§ģ›, ģ‚¬ģ—…ė¶€ģ„œ ė“±ģ˜ 핵심 씰직(ģøė „)ģ„ ģøģ¦ė²”ģœ„ģ— ķ¬ķ•Øķ•˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ź°œė°œģ—…ė¬“ģ— ź“€ė Øķ•œ 개발 ė° ģ‹œķ—˜ ģ‹œģŠ¤ķ…œ, ź°œė°œģž PC, ķ…ŒģŠ¤ķŠøģš© 단말기, 개발씰직 ė“±ģ“ ꓀리첓계 ė²”ģœ„ģ—ģ„œ ėˆ„ė½ėœ 경우"],"RelatedRegulations": []}],"description": "ģ”°ģ§ģ˜ 핵심 ģ„œė¹„ģŠ¤ģ™€ ź°œģøģ •ė³“ 처리 ķ˜„ķ™© ė“±ģ„ ź³ ė ¤ķ•˜ģ—¬ ꓀리첓계 ė²”ģœ„ė„¼ ģ„¤ģ •ķ•˜ź³ , ź“€ė Øėœ ģ„œė¹„ģŠ¤ė„¼ ė¹„ė”Æķ•˜ģ—¬ ź°œģøģ •ė³“ 처리 업묓와 씰직, ģžģ‚°, 물리적 ģœ„ģ¹˜ ė“±ģ„ ė¬øģ„œķ™”ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.5": {"name": "ģ •ģ±… 수립","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.1.5 ģ •ģ±… 수립","Subdomain": "1.1. ꓀리첓계","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…Ā·ģ§€ģ¹ØĀ·ģ ˆģ°Øģ„œ(ģ œĀ·ź°œģ • ė‚“ģ—­ ķ¬ķ•Ø)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…Ā·ģ§€ģ¹Øģ ˆģ°Øģ„œ ģ œĀ·ź°œģ • ģ‹œ ģ“ķ•“ź“€ź³„ģž 검토 ķšŒģ˜ė”","ź°œģøģ •ė³“ ė‚“ė¶€ ź“€ė¦¬ź³„ķš","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 정책·지침 ģ œĀ·ź°œģ • 공지낓역(그룹웨얓, ģ‚¬ė‚“ź²Œģ‹œķŒ 등)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģœ„ģ›ķšŒ ķšŒģ˜ė”"],"AuditChecklist": ["ģ”°ģ§ģ“ ģˆ˜ķ–‰ķ•˜ėŠ” ėŖØė“  ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ģ˜ 근거넼 ķ¬ķ•Øķ•˜ėŠ” ģµœģƒģœ„ ģˆ˜ģ¤€ģ˜ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…ģ˜ ģ‹œķ–‰ģ„ ģœ„ķ•˜ģ—¬ ķ•„ģš”ķ•œ ģ„øė¶€ģ ģø 방법, 절차, 주기 ė“±ģ„ ź·œģ •ķ•œ 지침, 절차, 매뉓얼 ė“±ģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…Ā·ģ‹œķ–‰ė¬øģ„œģ˜ ģ œĀ·ź°œģ • ģ‹œ ģµœź³ ź²½ģ˜ģž ė˜ėŠ” ģµœź³ ź²½ģ˜ģžė”œė¶€ķ„° ź¶Œķ•œģ„ ģœ„ģž„ė°›ģ€ ģžģ˜ ģŠ¹ģøģ„ 받고 ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…Ā·ģ‹œķ–‰ė¬øģ„œģ˜ ģµœģ‹ ė³øģ„ ꓀련 ģž„ģ§ģ›ģ—ź²Œ ģ“ķ•“ķ•˜źø° ģ‰¬ģš“ ķ˜•ķƒœė”œ ģ œź³µķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ ź·œģ •ģ— ė”°ė„“ė©“ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…ģ„œ ģ œĀ·ź°œģ • ģ‹œģ—ėŠ” ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģœ„ģ›ķšŒģ˜ ģ˜ź²°ģ„ ź±°ģ¹˜ė„ė” ķ•˜ź³  ģžˆģœ¼ė‚˜, 최근 ģ •ģ±…ģ„œ ź°œģ • ģ‹œ ģœ„ģ›ķšŒģ— ģ•ˆź±“ģœ¼ė”œ ģƒģ •ķ•˜ģ§€ ģ•Šź³  ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ˜ ģŠ¹ģøģ„ 근거딜만 ź°œģ •ķ•œ 경우","사딀 2 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±… ė° ģ§€ģ¹Øģ„œź°€ ģµœź·¼ģ— ź°œģ •ė˜ģ—ˆģœ¼ė‚˜, 핓당 ģ‚¬ķ•­ģ“ ꓀련 ė¶€ģ„œ ė° ģž„ģ§ģ›ģ—ź²Œ ź³µģœ Ā·ģ „ė‹¬ė˜ģ§€ ģ•Šģ•„ ģ¼ė¶€ ė¶€ģ„œģ—ģ„œėŠ” źµ¬ė²„ģ „ģ˜ ģ§€ģ¹Øģ„œė„¼ źø°ģ¤€ģœ¼ė”œ 업묓넼 ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±… ė° ģ§€ģ¹Øģ„œė„¼ ė³“ģ•ˆė¶€ģ„œģ—ģ„œė§Œ ź“€ė¦¬ķ•˜ź³  ģžˆź³ , ģž„ģ§ģ›ģ“ ģ—“ėžŒķ•  수 ģžˆė„ė” ź²Œģ‹œķŒ, ė¬øģ„œ ė“±ģ˜ ė°©ė²•ģœ¼ė”œ ģ œź³µķ•˜ģ§€ ģ•ŠėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ģ •ė³“ė³“ķ˜øģ™€ ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±… ė° ģ‹œķ–‰ė¬øģ„œė„¼ ģˆ˜ė¦½Ā·ģž‘ģ„±ķ•˜ė©°, ģ“ė•Œ ģ”°ģ§ģ˜ ģ •ė³“ė³“ķ˜øģ™€ ź°œģøģ •ė³“ė³“ķ˜ø 방침 ė° ė°©ķ–„ģ„ ėŖ…ķ™•ķ•˜ź²Œ ģ œģ‹œķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ė˜ķ•œ ģ •ģ±…ź³¼ ģ‹œķ–‰ė¬øģ„œėŠ” ź²½ģ˜ģ§„ģ˜ ģŠ¹ģøģ„ 받고, ģž„ģ§ģ› ė° ź“€ė Øģžģ—ź²Œ ģ“ķ•“ķ•˜źø° ģ‰¬ģš“ ķ˜•ķƒœė”œ ģ „ė‹¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.1.6": {"name": "ģžģ› 할당","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.1.6 ģžģ› 할당","Subdomain": "1.1. ꓀리첓계","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ ģ—°ź°„ ģ¶”ģ§„ź³„ķšģ„œ(ģ˜ˆģ‚° ė° ģøė „ģš“ģ˜ź³„ķš)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ ź²°ź³¼ ė³“ź³ ģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķˆ¬ģž ė‚“ģ—­","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ”°ģ§ė„"],"AuditChecklist": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 분야별 ģ „ė¬øģ„±ģ„ ź°–ģ¶˜ ģøė „ģ„ ķ™•ė³“ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ź“€ė¦¬ģ²“ź³„ģ˜ 효과적 źµ¬ķ˜„ź³¼ ģ§€ģ†ģ  ģš“ģ˜ģ„ ģœ„ķ•˜ģ—¬ ķ•„ģš”ķ•œ ģžģ›ģ„ ķ‰ź°€ķ•˜ģ—¬ ķ•„ģš”ķ•œ ģ˜ˆģ‚°ź³¼ ģøė „ģ„ ģ§€ģ›ķ•˜ź³  ģžˆėŠ”ź°€?","ģ—°ė„ė³„ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 업묓 세부추진 ź³„ķšģ„ ģˆ˜ė¦½Ā·ģ‹œķ–‰ķ•˜ź³ , ź·ø 추진결과에 ėŒ€ķ•œ ģ‹¬ģ‚¬ė¶„ģ„Ā·ķ‰ź°€ė„¼ ģ‹¤ģ‹œķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ”°ģ§ģ„ źµ¬ģ„±ķ•˜ėŠ”ė°, 분야별 ģ „ė¬øģ„±ģ„ ź°–ģ¶˜ ģøė „ģ“ ģ•„ė‹Œ ģ •ė³“ė³“ķ˜ø ꓀련 ė˜ėŠ” IT ꓀련 ģ „ė¬øģ„±ģ“ ģ—†ėŠ” ģøģ›ģœ¼ė”œė§Œ ė³“ģ•ˆģøė „ģ„ źµ¬ģ„±ķ•œ 경우","사딀 2 : ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ źø°ģˆ ģ Ā·ź“€ė¦¬ģ  ė³“ķ˜øģ”°ģ¹˜ģ˜ ģš”ź±“ģ„ 갖추기 ģœ„ķ•œ ģµœģ†Œķ•œģ˜ ė³“ģ•ˆ ģ†”ė£Øģ…˜ ė„ģž…, ģ•ˆģ „ģ”°ģ¹˜ 적용 ė“±ģ„ ģœ„ķ•œ ė¹„ģš©ģ„ ģµœź³ ź²½ģ˜ģžź°€ ģ§€ģ›ķ•˜ģ§€ ģ•Šź³  ģžˆėŠ” 경우","사딀 3 : ģøģ¦ģ„ ģ·Øė“ķ•œ ģ“ķ›„ģ— ģøė „ź³¼ ģ˜ˆģ‚° ģ§€ģ›ģ„ ėŒ€ķ­ ģ¤„ģ“ź³  기씓 ģøė „ģ„ 다넸 ė¶€ģ„œė”œ ė°°ģ¹˜ķ•˜ź±°ė‚˜ ģ¼ė¶€ ģ˜ˆģ‚°ģ„ 다넸 ģš©ė„ė”œ ģ‚¬ģš©ķ•˜ėŠ” 경우"],"RelatedRegulations": []}],"description": "ģµœź³ ź²½ģ˜ģžėŠ” ģ •ė³“ė³“ķ˜øģ™€ ź°œģøģ •ė³“ė³“ķ˜ø 분야별 ģ „ė¬øģ„±ģ„ ź°–ģ¶˜ ģøė „ģ„ ķ™•ė³“ķ•˜ź³ , ź“€ė¦¬ģ²“ź³„ģ˜ 효과적 źµ¬ķ˜„ź³¼ ģ§€ģ†ģ  ģš“ģ˜ģ„ ģœ„ķ•œ ģ˜ˆģ‚° ė° ģžģ›ģ„ ķ• ė‹¹ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.2.1": {"name": "ģ •ė³“ģžģ‚° ģ‹ė³„","checks": {"macie_is_enabled": "PASS","resourceexplorer2_indexes_found": "PASS","config_recorder_all_regions_enabled": null,"organizations_account_part_of_organizations": null,"organizations_tags_policies_enabled_and_attached": null},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.2.1 ģ •ė³“ģžģ‚° ģ‹ė³„","Subdomain": "1.2. ģœ„ķ—˜ ꓀리","AuditEvidence": ["ģ •ė³“ģžģ‚° ė° ź°œģøģ •ė³“ ģžģ‚°ė¶„ė„˜ 기준","ģ •ė³“ģžģ‚° ė° ź°œģøģ •ė³“ ģžģ‚°ėŖ©ė”(ģžģ‚°ź“€ė¦¬ģ‹œģŠ¤ķ…œ 화멓)","ģ •ė³“ģžģ‚° ė° ź°œģøģ •ė³“ ė³“ģ•ˆė“±źø‰","ģžģ‚°ģ‹¤ģ‚¬ ė‚“ģ—­","ģœ„ķ—˜ė¶„ģ„ ė³“ź³ ģ„œ(ģžģ‚°ģ‹ė³„ ė‚“ģ—­)"],"AuditChecklist": ["ģ •ė³“ģžģ‚°ģ˜ ė¶„ė„˜źø°ģ¤€ģ„ ģˆ˜ė¦½ķ•˜ź³  ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ė²”ģœ„ ė‚“ģ˜ ėŖØė“  ģžģ‚°ģ„ ģ‹ė³„ķ•˜ģ—¬ ėŖ©ė”ģœ¼ė”œ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ‹ė³„ėœ ģ •ė³“ģžģ‚°ģ— ėŒ€ķ•˜ģ—¬ 법적 ģš”źµ¬ģ‚¬ķ•­ ė° 업묓에 ėÆøģ¹˜ėŠ” ģ˜ķ–„ ė“±ģ„ ź³ ė ¤ķ•˜ģ—¬ ģ¤‘ģš”ė„ė„¼ ź²°ģ •ķ•˜ź³  ė³“ģ•ˆė“±źø‰ģ„ ė¶€ģ—¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •źø°ģ ģœ¼ė”œ ģ •ė³“ģžģ‚° ķ˜„ķ™©ģ„ ģ”°ģ‚¬ķ•˜ģ—¬ ģ •ė³“ģžģ‚°ėŖ©ė”ģ„ ģµœģ‹ ģœ¼ė”œ ģœ ģ§€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ė²”ģœ„ ė‚“ģ˜ ģžģ‚° ėŖ©ė”ģ—ģ„œ ģ¤‘ģš”ģ •ė³“ ģ·Øźø‰ģž ė° ź°œģøģ •ė³“ ģ·Øźø‰ģž PC넼 ķ†µģ œķ•˜ėŠ” ė° ģ‚¬ģš©ė˜ėŠ” 출렄물 ė³“ģ•ˆ, ė¬øģ„œģ•”ķ˜øķ™”, USBė§¤ģ²“ģ œģ–“ ė“±ģ˜ 낓부정볓 ģœ ģ¶œķ†µģ œ ģ‹œģŠ¤ķ…œģ“ ėˆ„ė½ėœ 경우","사딀 2 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ė²”ģœ„ ė‚“ģ—ģ„œ 제3ģžė”œė¶€ķ„° ģ œź³µė°›ģ€ ź°œģøģ •ė³“ź°€ ģžˆģœ¼ė‚˜, 핓당 ź°œģøģ •ė³“ģ— ėŒ€ķ•œ ģžģ‚° ģ‹ė³„ģ“ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우","사딀 3 : ė‚“ė¶€ 지침에 ėŖ…ģ‹œėœ ģ •ė³“ģžģ‚° ė° ź°œģøģ •ė³“ ė³“ģ•ˆė“±źø‰ ė¶„ė„˜ 기준과 ģžģ‚°ź“€ė¦¬ ėŒ€ģž„ģ˜ ė¶„ė„˜ źø°ģ¤€ģ“ ģ¼ģ¹˜ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ģ˜Øķ”„ė ˆėÆøģŠ¤ ģžģ‚°ģ— ėŒ€ķ•“ģ„œėŠ” ģ‹ė³„ģ“ ģ“ė£Øģ–“ģ”Œģœ¼ė‚˜, 외부에 ģœ„ķƒķ•œ IT ģ„œė¹„ģŠ¤(ģ›¹ķ˜øģŠ¤ķŒ…, ģ„œė²„ķ˜øģŠ¤ķŒ…, ķ“ė¼ģš°ė“œ 등)에 ėŒ€ķ•œ ģžģ‚° ģ‹ė³„ģ“ ėˆ„ė½ėœ 경우(단, ģøģ¦ė²”ģœ„ ė‚“)","사딀 5 : ź³ ģœ ģ‹ė³„ģ •ė³“ 등 ź°œģøģ •ė³“ė„¼ ģ €ģž„ķ•˜ź³  ģžˆėŠ” ė°±ģ—…ģ„œė²„ģ˜ 기밀성 ė“±źø‰ģ„ (ķ•˜)딜 ģ‚°ģ •ķ•˜ėŠ” 등 ģ •ė³“ģžģ‚° ģ¤‘ģš”ė„ ķ‰ź°€ģ˜ 합리성 ė° ģ‹ ė¢°ģ„±ģ“ ėÆøķ”ķ•œ 경우"],"RelatedRegulations": []}],"description": "ģ”°ģ§ģ˜ ģ—…ė¬“ķŠ¹ģ„±ģ— ė”°ė¼ ģ •ė³“ģžģ‚° ė¶„ė„˜źø°ģ¤€ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ꓀리첓계 ė²”ģœ„ ė‚“ ėŖØė“  ģ •ė³“ģžģ‚°ģ„ ģ‹ė³„Ā·ė¶„ė„˜ķ•˜ź³ , ģ¤‘ģš”ė„ė„¼ ģ‚°ģ •ķ•œ 후 ź·ø ėŖ©ė”ģ„ ģµœģ‹ ģœ¼ė”œ ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 2,"total": 5,"manual": 0}},"1.2.2": {"name": "ķ˜„ķ™© ė° ķė¦„ė¶„ģ„","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.2.2 ķ˜„ķ™© ė° ķė¦„ė¶„ģ„","Subdomain": "1.2. ģœ„ķ—˜ ꓀리","AuditEvidence": ["ģ •ė³“ģ„œė¹„ģŠ¤ ķ˜„ķ™©ķ‘œ","ģ •ė³“ģ„œė¹„ģŠ¤ ģ—…ė¬“ķė¦„ķ‘œĀ·ģ—…ė¬“ķė¦„ė„","ź°œģøģ •ė³“ 처리 ķ˜„ķ™©ķ‘œ(ISMS-P ģøģ¦ģø 경우)","ź°œģøģ •ė³“ ķė¦„ķ‘œĀ·ķė¦„ė„(ISMS-P ģøģ¦ģø 경우)"],"AuditChecklist": ["꓀리첓계 ģ „ ģ˜ģ—­ģ— ėŒ€ķ•œ ģ •ė³“ģ„œė¹„ģŠ¤ ķ˜„ķ™©ģ„ ģ‹ė³„ķ•˜ź³  업묓 ģ ˆģ°Øģ™€ ķė¦„ģ„ ķŒŒģ•…ķ•˜ģ—¬ ė¬øģ„œķ™”ķ•˜ź³  ģžˆėŠ”ź°€?","꓀리첓계 ė²”ģœ„ ė‚“ ź°œģøģ •ė³“ 처리 ķ˜„ķ™©ģ„ ģ‹ė³„ķ•˜ź³  ź°œģøģ •ė³“ģ˜ ķė¦„ģ„ ķŒŒģ•…ķ•˜ģ—¬ ź°œģøģ •ė³“ ķė¦„ė„ ė“±ģœ¼ė”œ ė¬øģ„œķ™”ķ•˜ź³  ģžˆėŠ”ź°€?","ģ„œė¹„ģŠ¤ ė° 업묓, ģ •ė³“ģžģ‚° ė“±ģ˜ 변화에 따넸 ģ—…ė¬“ģ ˆģ°Ø ė° ź°œģøģ •ė³“ ķė¦„ģ„ 주기적으딜 ź²€ķ† ķ•˜ģ—¬ ķė¦„ė„ 등 ꓀련 ė¬øģ„œģ˜ ģµœģ‹ ģ„±ģ„ ģœ ģ§€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ꓀리첓계 ė²”ģœ„ ė‚“ ģ£¼ģš” ģ„œė¹„ģŠ¤ģ˜ 업묓 ģ ˆģ°ØĀ·ķė¦„ ė° ķ˜„ķ™©ģ— ė¬øģ„œķ™”ź°€ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우","사딀 2 : ź°œģøģ •ė³“ ķė¦„ė„ė„¼ ģž‘ģ„±ķ•˜ģ˜€ģœ¼ė‚˜, ģ‹¤ģ œ ź°œģøģ •ė³“ģ˜ ķė¦„ź³¼ ģƒģ“ķ•œ ė¶€ė¶„ģ“ ė‹¤ģˆ˜ ģ”“ģž¬ķ•˜ź±°ė‚˜ ģ¤‘ģš”ķ•œ ź°œģøģ •ė³“ ķė¦„ģ“ ėˆ„ė½ė˜ģ–“ ģžˆėŠ” 경우","사딀 3 : 최쓈 ź°œģøģ •ė³“ ķė¦„ė„ ģž‘ģ„± ģ“ķ›„ģ— ķ˜„ķ–‰ķ™”ź°€ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ•„ ė³€ķ™”ėœ ź°œģøģ •ė³“ ķė¦„ģ“ ķė¦„ė„ģ— ė°˜ģ˜ė˜ģ§€ ģ•Šź³  ģžˆėŠ” 경우"],"RelatedRegulations": []}],"description": "꓀리첓계 ģ „ ģ˜ģ—­ģ— ėŒ€ķ•œ ģ •ė³“ģ„œė¹„ģŠ¤ ė° ź°œģøģ •ė³“ 처리 ķ˜„ķ™©ģ„ ė¶„ģ„ķ•˜ź³  업묓 ģ ˆģ°Øģ™€ ķė¦„ģ„ ķŒŒģ•…ķ•˜ģ—¬ ė¬øģ„œķ™”ķ•˜ė©°, ģ“ė„¼ 주기적으딜 ź²€ķ† ķ•˜ģ—¬ ģµœģ‹ ģ„±ģ„ ģœ ģ§€ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.2.3": {"name": "ģœ„ķ—˜ ķ‰ź°€","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.2.3 ģœ„ķ—˜ ķ‰ź°€","Subdomain": "1.2. ģœ„ķ—˜ ꓀리","AuditEvidence": ["ģœ„ķ—˜ź“€ė¦¬ 지침","ģœ„ķ—˜ź“€ė¦¬ ė§¤ė‰“ģ–¼Ā·ź°€ģ“ė“œ","ģœ„ķ—˜ź“€ė¦¬ ź³„ķšģ„œ","ģœ„ķ—˜ķ‰ź°€ ź²°ź³¼ė³“ź³ ģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģœ„ģ›ķšŒ ķšŒģ˜ė”","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 실묓 ķ˜‘ģ˜ķšŒ ķšŒģ˜ė”","ģ •ė³“ģžģ‚° ė° ź°œģøģ •ė³“ģžģ‚° ėŖ©ė”","ģ •ė³“ģ„œė¹„ģŠ¤ ė° ź°œģøģ •ė³“ ķė¦„ķ‘œĀ·ķė¦„ė„"],"AuditChecklist": ["씰직 ė˜ėŠ” ģ„œė¹„ģŠ¤ģ˜ ķŠ¹ģ„±ģ— ė”°ė¼ ė‹¤ģ–‘ķ•œ ģø”ė©“ģ—ģ„œ ė°œģƒķ•  수 ģžˆėŠ” ģœ„ķ—˜ģ„ ģ‹ė³„ķ•˜ź³  ķ‰ź°€ķ•  수 ģžˆėŠ” ė°©ė²•ģ„ ģ •ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ģœ„ķ—˜ź“€ė¦¬ 방법 ė° 절차(ģˆ˜ķ–‰ģøė „, źø°ź°„, ėŒ€ģƒ, 방법, ģ˜ˆģ‚° 등)넼 źµ¬ģ²“ķ™”ķ•œ ģœ„ķ—˜ź“€ė¦¬ź³„ķšģ„ 매년 ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ģœ„ķ—˜ź“€ė¦¬ź³„ķšģ— ė”°ė¼ ģ—° 1회 ģ“ģƒ ģ •źø°ģ ģœ¼ė”œ ė˜ėŠ” ķ•„ģš”ķ•œ ģ‹œģ ģ— ģœ„ķ—˜ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ”°ģ§ģ—ģ„œ 수용 ź°€ėŠ„ķ•œ ėŖ©ķ‘œ ģœ„ķ—˜ģˆ˜ģ¤€ģ„ ģ •ķ•˜ź³ , ź·ø ģˆ˜ģ¤€ģ„ ģ“ˆź³¼ķ•˜ėŠ” ģœ„ķ—˜ģ„ ģ‹ė³„ķ•˜ź³  ģžˆėŠ”ź°€?","ģœ„ķ—˜ģ‹ė³„ ė° ķ‰ź°€ 결과넼 ź²½ģ˜ģ§„ģ—ź²Œ ė³“ź³ ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 수립된 ģœ„ķ—˜ź“€ė¦¬ź³„ķšģ„œģ— ģœ„ķ—˜ķ‰ź°€ źø°ź°„ ė° ģœ„ķ—˜ź“€ė¦¬ ėŒ€ģƒź³¼ ė°©ė²•ģ“ ģ •ģ˜ė˜ģ–“ ģžˆģœ¼ė‚˜, ģœ„ķ—˜ź“€ė¦¬ ģˆ˜ķ–‰ ģøė „ź³¼ ģ†Œģš” ģ˜ˆģ‚° 등 źµ¬ģ²“ģ ģø ģ‹¤ķ–‰ź³„ķšģ“ ėˆ„ė½ė˜ģ–“ ģžˆėŠ” 경우","사딀 2 : ģ „ė…„ė„ģ—ėŠ” ģœ„ķ—˜ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•˜ģ˜€ģœ¼ė‚˜, źøˆė…„ė„ģ—ėŠ” ģžģ‚° ė³€ź²½ģ“ ģ—†ģ—ˆė‹¤ėŠ” ģ‚¬ģœ ė”œ ģœ„ķ—˜ ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ģœ„ķ—˜ź“€ė¦¬ ź³„ķšģ— ė”°ė¼ ģœ„ķ—˜ ģ‹ė³„ ė° ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•˜ź³  ģžˆģœ¼ė‚˜, ė²”ģœ„ ė‚“ ģ¤‘ģš” ģ •ė³“ģžģ‚°ģ— ėŒ€ķ•œ ģœ„ķ—˜ ģ‹ė³„ ė° ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜, ģ •ė³“ė³“ķ˜ø ꓀련 법적 ģš”źµ¬ 사항 ģ¤€ģˆ˜ 여부에 따넸 ģœ„ķ—˜ģ„ ģ‹ė³„ ė° ķ‰ź°€ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ģœ„ķ—˜ź“€ė¦¬ ź³„ķšģ— ė”°ė¼ ģœ„ķ—˜ ģ‹ė³„ ė° ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•˜ź³  수용 ź°€ėŠ„ķ•œ ėŖ©ķ‘œ ģœ„ķ—˜ģˆ˜ģ¤€ģ„ ģ„¤ģ •ķ•˜ģ˜€ģœ¼ė‚˜, ꓀련 ģ‚¬ķ•­ģ„ ź²½ģ˜ģ§„(ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž 등)에 ė³“ź³ ķ•˜ģ—¬ ģŠ¹ģøė°›ģ§€ ģ•Šģ€ 경우","사딀 5 : ė‚“ė¶€ 지침에 ģ •ģ˜ķ•œ ģœ„ķ—˜ ķ‰ź°€ 방법과 ģ‹¤ģ œ ģˆ˜ķ–‰ķ•œ ģœ„ķ—˜ ķ‰ź°€ ė°©ė²•ģ“ ģƒģ“ķ•  경우","사딀 6 : ģ •ė³“ė³“ķ˜ø ꓀리첓계와 ź“€ė Øėœ ꓀리적·물리적 ģ˜ģ—­ģ˜ ģœ„ķ—˜ ģ‹ė³„ ė° ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šź³ , ė‹Øģˆœķžˆ 기술적 취약점진단 결과넼 ģœ„ķ—˜ ķ‰ź°€ 결과딜 ź°ˆģŒķ•˜ź³  ģžˆėŠ” 경우","사딀 7 : 수용 ź°€ėŠ„ķ•œ ėŖ©ķ‘œ ģœ„ķ—˜ģˆ˜ģ¤€(DoA)ģ„ ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ģ—†ģ“ ź³¼ė„ķ•˜ź²Œ ė†’ģ“ėŠ” 것으딜 결정함에 ė”°ė¼, ģ‹¤ģ§ˆģ ģœ¼ė”œ ėŒ€ģ‘ģ“ ķ•„ģš”ķ•œ ģ£¼ģš” ģœ„ķ—˜ė“¤ģ“ ģ”°ģ¹˜ź°€ ė¶ˆķ•„ģš”ķ•œ ģœ„ķ—˜(수용 ź°€ėŠ„ķ•œ ģœ„ķ—˜)으딜 ģ§€ģ •ėœ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ģ”°ģ§ģ˜ ėŒ€ė‚“ģ™ø ķ™˜ź²½ė¶„ģ„ģ„ ķ†µķ•˜ģ—¬ ģœ ķ˜•ė³„ ģœ„ķ˜‘ģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ź³  씰직에 ģ ķ•©ķ•œ ģœ„ķ—˜ ķ‰ź°€ ė°©ė²•ģ„ ģ„ ģ •ķ•˜ģ—¬ ꓀리첓계 ģ „ ģ˜ģ—­ģ— ėŒ€ķ•˜ģ—¬ ģ—° 1회 ģ“ģƒ ģœ„ķ—˜ģ„ ķ‰ź°€ķ•˜ė©°, ģˆ˜ģš©ķ•  수 ģžˆėŠ” ģœ„ķ—˜ģ€ ź²½ģ˜ģ§„ģ˜ ģŠ¹ģøģ„ 받아 ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.2.4": {"name": "ė³“ķ˜øėŒ€ģ±… ģ„ ģ •","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.2.4 ė³“ķ˜øėŒ€ģ±… ģ„ ģ •","Subdomain": "1.2. ģœ„ķ—˜ ꓀리","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ“ķ–‰ź³„ķšģ„œĀ·ģœ„ķ—˜ź“€ė¦¬ź³„ķšģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ėŒ€ģ±…ģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ė§ˆģŠ¤ķ„°ķ”Œėžœ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ“ķ–‰ź³„ķš ź²½ģ˜ģ§„ 볓고 ė° ģŠ¹ģø ė‚“ģ—­"],"AuditChecklist": ["ģ‹ė³„ėœ ģœ„ķ—˜ģ— ėŒ€ķ•œ 처리 ģ „ėžµ(ź°ģ†Œ, ķšŒķ”¼, ģ „ź°€, 수용 등)ģ„ ģˆ˜ė¦½ķ•˜ź³  ģœ„ķ—˜ģ²˜ė¦¬ė„¼ ģœ„ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģ„ ģ •ķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ķ˜øėŒ€ģ±…ģ˜ ģš°ģ„ ģˆœģœ„ė„¼ ź³ ė ¤ķ•˜ģ—¬ ģ¼ģ •, ė‹“ė‹¹ė¶€ģ„œ ė° ė‹“ė‹¹ģž, ģ˜ˆģ‚° ė“±ģ˜ ķ•­ėŖ©ģ„ ķ¬ķ•Øķ•œ ė³“ķ˜øėŒ€ģ±… ģ“ķ–‰ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ź³  ź²½ģ˜ģ§„ģ— ė³“ź³ ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ėŒ€ģ±…ģ— ėŒ€ķ•œ ģ“ķ–‰ź³„ķšģ€ ģˆ˜ė¦½ķ•˜ģ˜€ģœ¼ė‚˜, ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ—ź²Œ 볓고가 ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우","사딀 2 : ģœ„ķ—˜ź°ģ†Œź°€ ģš”źµ¬ė˜ėŠ” ģ¼ė¶€ ģœ„ķ—˜ģ˜ 씰치 ģ“ķ–‰ź³„ķšģ“ ėˆ„ė½ė˜ģ–“ ģžˆėŠ” 경우","사딀 3 : 법에 ė”°ė¼ ģ˜ė¬“ģ ģœ¼ė”œ ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•  사항, ė³“ģ•ˆ ģ·Øģ•½ģ„±ģ“ ė†’ģ€ ģœ„ķ—˜ ė“±ģ„ ė³„ė„ģ˜ 볓호씰치 ź³„ķš ģ—†ģ“ ģœ„ķ—˜ģˆ˜ģš©ģœ¼ė”œ ź²°ģ •ķ•˜ģ—¬ ģ”°ģ¹˜ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ģœ„ķ—˜ģˆ˜ģš©ģ— ėŒ€ķ•œ 근거와 ķƒ€ė‹¹ģ„±ģ“ ėÆøķ”ķ•˜ź³ , ģ‹œźø‰ģ„± ė° źµ¬ķ˜„ ģš©ģ“ģ„± ė“±ģ˜ ģø”ė©“ģ—ģ„œ ģ¦‰ģ‹œ ė˜ėŠ” 단기 ģ”°ģ¹˜ź°€ ź°€ėŠ„ķ•œ ģœ„ķ—˜ģš”ģøģ— ėŒ€ķ•“ģ„œė„ ķŠ¹ė³„ķ•œ ģ‚¬ģœ  ģ—†ģ“ ģž„źø° ģ”°ģ¹˜ź³„ķšģœ¼ė”œ ė¶„ė„˜ķ•œ 경우"],"RelatedRegulations": []}],"description": "ģœ„ķ—˜ ķ‰ź°€ 결과에 ė”°ė¼ ģ‹ė³„ėœ ģœ„ķ—˜ģ„ ģ²˜ė¦¬ķ•˜źø° ģœ„ķ•˜ģ—¬ 씰직에 ģ ķ•©ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģ„ ģ •ķ•˜ź³ , ė³“ķ˜øėŒ€ģ±…ģ˜ ģš°ģ„ ģˆœģœ„ģ™€ ģ¼ģ •Ā·ė‹“ė‹¹ģžĀ·ģ˜ˆģ‚° ė“±ģ„ ķ¬ķ•Øķ•œ ģ“ķ–‰ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ź²½ģ˜ģ§„ģ˜ ģŠ¹ģøģ„ 받아야 ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.3.1": {"name": "ė³“ķ˜øėŒ€ģ±… źµ¬ķ˜„","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.3.1 ė³“ķ˜øėŒ€ģ±… źµ¬ķ˜„","Subdomain": "1.3. ꓀리첓계 욓영","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ“ķ–‰ź³„ķšģ„œĀ·ģœ„ķ—˜ź“€ė¦¬ź³„ķšģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ėŒ€ģ±…ģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ“ķ–‰ź³„ķš ź²½ź³¼ė³“ź³ ģ„œ(ź²½ģ˜ģ§„ 볓고 ķ¬ķ•Ø)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ“ķ–‰ ģ™„ė£Œ ė³“ź³ ģ„œ(ź²½ģ˜ģ§„ 볓고 ķ¬ķ•Ø)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģš“ģ˜ėŖ…ģ„øģ„œ"],"AuditChecklist": ["ģ“ķ–‰ź³„ķšģ— ė”°ė¼ ė³“ķ˜øėŒ€ģ±…ģ„ 효과적으딜 źµ¬ķ˜„ķ•˜ź³  ģ“ķ–‰ź²°ź³¼ģ˜ 정확성 ė° ķšØź³¼ģ„± 여부넼 ź²½ģ˜ģ§„ģ“ ķ™•ģøķ•  수 ģžˆė„ė” ė³“ź³ ķ•˜ź³  ģžˆėŠ”ź°€?","꓀리첓계 ģøģ¦źø°ģ¤€ė³„ė”œ ė³“ķ˜øėŒ€ģ±… źµ¬ķ˜„ ė° 욓영 ķ˜„ķ™©ģ„ źø°ė”ķ•œ ģš“ģ˜ėŖ…ģ„øģ„œė„¼ 구첓적으딜 ģž‘ģ„±ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ėŒ€ģ±…ģ— ėŒ€ķ•œ ģ“ķ–‰ģ™„ė£Œ 결과넼 ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ—ź²Œ ė³“ź³ ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģœ„ķ—˜ģ”°ģ¹˜ ģ“ķ–‰ź²°ź³¼ė³“ź³ ģ„œėŠ” ʻ씰치 ģ™„ė£ŒŹ¼ė”œ ėŖ…ģ‹œė˜ģ–“ ģžˆģœ¼ė‚˜, ź“€ė Øėœ ģœ„ķ—˜ģ“ ģ—¬ģ „ķžˆ ģ”“ģž¬ķ•˜ź±°ė‚˜ ģ“ķ–‰ź²°ź³¼ģ˜ 정확성 ė° ķšØź³¼ģ„±ģ“ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ģ „ė…„ė„ ģ •ė³“ė³“ķ˜øėŒ€ģ±… ģ“ķ–‰ź³„ķšģ— ė”°ė¼ ģ¤‘Ā·ģž„źø°ė”œ ė¶„ė„˜ėœ ģœ„ķ—˜ė“¤ģ“ ķ•“ė‹¹ģ—°ė„ģ— źµ¬ķ˜„ģ“ 되고 ģžˆģ§€ ģ•Šź±°ė‚˜ ģ“ķ–‰ź²°ź³¼ė„¼ ź²½ģ˜ģ§„ģ“ 검토 ė° ķ™•ģøķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ģš“ģ˜ėŖ…ģ„øģ„œģ— ģž‘ģ„±ėœ 욓영 ķ˜„ķ™©ģ“ ģ‹¤ģ œģ™€ ģ¼ģ¹˜ķ•˜ģ§€ ģ•Šź³ , ģš“ėŖ…ėŖ…ģ„øģ„œģ— źø°ė”ė˜ģ–“ ģžˆėŠ” ꓀련 ė¬øģ„œ, ź²°ģž¬ ė‚“ģš©, ķšŒģ˜ė” ė“±ģ“ ģ”“ģž¬ķ•˜ģ§€ ģ•ŠėŠ” 경우","사딀 5 : ģ“ķ–‰ź³„ķš ģ‹œķ–‰ģ— ėŒ€ķ•œ 결과넼 ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ—ź²Œ ė³“ź³ ķ•˜ģ˜€ģœ¼ė‚˜, ģ¼ė¶€ ėÆøģ“ķ–‰ėœ 걓에 ėŒ€ķ•œ ģ‚¬ģœ  볓고 ė° ķ›„ģ† ģ”°ģ¹˜ź°€ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ģ„ ģ •ķ•œ ė³“ķ˜øėŒ€ģ±…ģ€ ģ“ķ–‰ź³„ķšģ— ė”°ė¼ 효과적으딜 źµ¬ķ˜„ķ•˜ź³ , ź²½ģ˜ģ§„ģ€ ģ“ķ–‰ź²°ź³¼ģ˜ 정확성과 ķšØź³¼ģ„± 여부넼 ķ™•ģøķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.3.2": {"name": "ė³“ķ˜øėŒ€ģ±… 공유","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.3.2 ė³“ķ˜øėŒ€ģ±… 공유","Subdomain": "1.3. ꓀리첓계 욓영","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ėŒ€ģ±…ė³„ ģš“ģ˜ė¶€ģ„œ ė˜ėŠ” ģ‹œķ–‰ė¶€ģ„œ ķ˜„ķ™©","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ ź“€ė¦¬ź³„ķš ė‚“ė¶€ź³µģœ  ģ¦ź±°ģžė£Œ(공지 ė‚“ģ—­, źµģœ”ģžė£Œ, 공유 ģžė£Œ 등)"],"AuditChecklist": ["źµ¬ķ˜„ėœ ė³“ķ˜øėŒ€ģ±…ģ„ 욓영 ė˜ėŠ” ģ‹œķ–‰ķ•  ė¶€ģ„œ ė° ė‹“ė‹¹ģžė„¼ ėŖ…ķ™•ķ•˜ź²Œ ķŒŒģ•…ķ•˜ź³  ģžˆėŠ”ź°€?","źµ¬ķ˜„ėœ ė³“ķ˜øėŒ€ģ±…ģ„ 욓영 ė˜ėŠ” ģ‹œķ–‰ķ•  ė¶€ģ„œ ė° ė‹“ė‹¹ģžģ—ź²Œ ꓀련 ė‚“ģš©ģ„ 공유 ė˜ėŠ” źµģœ”ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜øėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ģ—¬ źµ¬ķ˜„ķ•˜ź³  ģžˆģœ¼ė‚˜, ꓀련 ė‚“ģš©ģ„ ģ¶©ė¶„ķžˆ ź³µģœ Ā·źµģœ”ķ•˜ģ§€ ģ•Šģ•„ ģ‹¤ģ œ 욓영 ė˜ėŠ” ģˆ˜ķ–‰ ė¶€ģ„œ ė° ė‹“ė‹¹ģžź°€ 핓당 ė‚“ģš©ģ„ ģøģ§€ķ•˜ģ§€ ėŖ»ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": []}],"description": "ė³“ķ˜øėŒ€ģ±…ģ˜ ģ‹¤ģ œ 욓영 ė˜ėŠ” ģ‹œķ–‰ķ•  ė¶€ģ„œ ė° ė‹“ė‹¹ģžė„¼ ķŒŒģ•…ķ•˜ģ—¬ ꓀련 ė‚“ģš©ģ„ ź³µģœ ķ•˜ź³  źµģœ”ķ•˜ģ—¬ ģ§€ģ†ģ ģœ¼ė”œ ģš“ģ˜ė˜ė„ė” ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.3.3": {"name": "ģš“ģ˜ķ˜„ķ™© ꓀리","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.3.3 ģš“ģ˜ķ˜„ķ™© ꓀리","Subdomain": "1.3. ꓀리첓계 욓영","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ—°ź°„ź³„ķšģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģš“ģ˜ķ˜„ķ™©ķ‘œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ ģˆ˜ķ–‰ 여부 점검 ź²°ź³¼"],"AuditChecklist": ["꓀리첓계 ģš“ģ˜ģ„ ģœ„ķ•˜ģ—¬ 주기적 ė˜ėŠ” ģƒģ‹œģ ģœ¼ė”œ ģˆ˜ķ–‰ķ•˜ģ—¬ģ•¼ ķ•˜ėŠ” ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ģ„ ė¬øģ„œķ™”ķ•˜ģ—¬ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ź²½ģ˜ģ§„ģ€ 주기적으딜 ꓀리첓계 ģš“ģ˜ķ™œė™ģ˜ ķšØź³¼ģ„±ģ„ ķ™•ģøķ•˜ź³  ģ“ė„¼ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ģš“ģ˜ķ˜„ķ™© 중 주기적 ė˜ėŠ” ģƒģ‹œģ ģø ķ™œė™ģ“ ģš”źµ¬ė˜ėŠ” ķ™œė™ ķ˜„ķ™©ģ„ ė¬øģ„œķ™”ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ģš“ģ˜ķ˜„ķ™©ģ— ėŒ€ķ•œ ė¬øģ„œķ™”ėŠ” ģ“ė£Øģ–“ģ”Œģœ¼ė‚˜, 핓당 ģš“ģ˜ķ˜„ķ™©ģ— ėŒ€ķ•œ ģ£¼źø°ģ ģø 검토가 ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ•„ 월별 ė° 분기별 ķ™œė™ģ“ ģš”źµ¬ė˜ėŠ” ģ¼ė¶€ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ™œė™ģ“ ėˆ„ė½ė˜ģ—ˆź³  ģ¼ė¶€ėŠ” ģ“ķ–‰ 여부넼 ķ™•ģøķ•  수 ģ—†ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제31ģ”°(ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ˜ 지정)","ģ •ė³“ķ†µģ‹ ė§ė²• 제45ģ”°ģ˜3(ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģžģ˜ 지정 등)"]}],"description": "ģ”°ģ§ģ“ ģˆ˜ė¦½ķ•œ ꓀리첓계에 ė”°ė¼ ģƒģ‹œģ  ė˜ėŠ” 주기적으딜 ģˆ˜ķ–‰ķ•˜ģ—¬ģ•¼ ķ•˜ėŠ” ģš“ģ˜ķ™œė™ ė° ģˆ˜ķ–‰ ė‚“ģ—­ģ€ ģ‹ė³„ ė° ģ¶”ģ ģ“ ź°€ėŠ„ķ•˜ė„ė” źø°ė”ķ•˜ģ—¬ ź“€ė¦¬ķ•˜ź³ , ź²½ģ˜ģ§„ģ€ 주기적으딜 ģš“ģ˜ķ™œė™ģ˜ ķšØź³¼ģ„±ģ„ ķ™•ģøķ•˜ģ—¬ ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.4.1": {"name": "법적 ģš”źµ¬ģ‚¬ķ•­ ģ¤€ģˆ˜ 검토","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.4.1 법적 ģš”źµ¬ģ‚¬ķ•­ ģ¤€ģˆ˜ 검토","Subdomain": "1.4. ꓀리첓계 점검 ė° ź°œģ„ ","AuditEvidence": ["법적 준거성 검토 ė‚“ģ—­","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 정책·지침 검토 ė° ź°œģ •ģ“ė „","정책·지침 ģ‹ źµ¬ėŒ€ģ”°ķ‘œ","법 ź°œģ •ģ‚¬ķ•­ ė‚“ė¶€ź³µģœ  ģžė£Œ","ź°œģøģ •ė³“ ģ†ķ•“ė°°ģƒ ģ±…ģž„ė³“ģž„ ģž…ģ¦ ģžė£Œ(ģ‚¬ģ“ė²„ė³“ķ—˜ ģ•½ģ •ģ„œ 등)","ģ •ė³“ė³“ķ˜ø ź³µģ‹œ ė‚“ģ—­"],"AuditChecklist": ["ģ”°ģ§ģ“ ģ¤€ģˆ˜ķ•˜ģ—¬ģ•¼ ķ•˜ėŠ” ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ķŒŒģ•…ķ•˜ģ—¬ ģµœģ‹ ģ„±ģ„ ģœ ģ§€ķ•˜ź³  ģžˆėŠ”ź°€?","법적 ģš”źµ¬ģ‚¬ķ•­ģ˜ ģ¤€ģˆ˜ 여부넼 ģ—° 1회 ģ“ģƒ ģ •źø°ģ ģœ¼ė”œ ź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ķ†µģ‹ ė§ė²• ė° ź°œģøģ •ė³“ ė³“ķ˜øė²•ģ“ 최근 ź°œģ •ė˜ģ—ˆģœ¼ė‚˜ ź°œģ •ģ‚¬ķ•­ģ“ 씰직에 ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ź²€ķ† ķ•˜ģ§€ ģ•Šģ•˜ģœ¼ė©°, ģ •ģ±…ģ„œĀ·ģ‹œķ–‰ė¬øģ„œ ė° 법적준거성 첓크리스트 ė“±ģ—ė„ 핓당 ė‚“ģš©ģ„ ė°˜ģ˜ķ•˜ģ§€ ģ•Šģ•„ ģ •ģ±…ģ„œĀ·ģ‹œķ–‰ė¬øģ„œ ė° 법적준거성 첓크리스트 ė“±ģ˜ ė‚“ģš©ģ“ 법령 ė‚“ģš©ź³¼ ģ¼ģ¹˜ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģ”°ģ§ģ—ģ„œ ģ¤€ģˆ˜ķ•˜ģ—¬ģ•¼ ķ•  ė²•ė„ ģ“ ź°œģ •ė˜ģ—ˆģœ¼ė‚˜, 핓당 법넠 준거성 검토넼 ģž„źø°ź°„ ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 3 : 법적 준거성 ģ¤€ģˆ˜ 여부에 ėŒ€ķ•œ 검토가 ģ ģ ˆķžˆ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ•„ ź°œģøģ •ė³“ ė³“ķ˜øė²• 등 ė²•ź·œ ģœ„ė°˜ ģ‚¬ķ•­ģ“ ė‹¤ģˆ˜ 발견된 경우","사딀 4 : ź°œģøģ •ė³“ ė³“ķ˜øė²•ģ— ė”°ė¼ ź°œģøģ •ė³“ ģ†ķ•“ė°°ģƒģ±…ģž„ ė³“ģž„ģ œė„ 적용 ėŒ€ģƒģ“ ė˜ģ—ˆģœ¼ė‚˜, ģ“ė„¼ ģøģ§€ķ•˜ģ§€ ėŖ»ķ•˜ģ—¬ ė³“ķ—˜ ź°€ģž…ģ“ė‚˜ ģ¤€ė¹„źøˆ ģ ė¦½ģ„ ķ•˜ģ§€ ģ•Šģ€ 경우 ė˜ėŠ” ė³“ķ—˜ ź°€ģž…ģ„ ķ•˜ģ˜€ģœ¼ė‚˜ ģ“ģš©ģž 수 ė° ė§¤ģ¶œģ•”ģ— 따넸 ģµœģ €ź°€ģž…źøˆģ•” źø°ģ¤€ģ„ ģ¤€ģˆ˜ķ•˜ģ§€ ėŖ»ķ•œ 경우","사딀 5 : ģ •ė³“ė³“ķ˜ø ź³µģ‹œ ģ˜ė¬“ėŒ€ģƒ ģ‚¬ģ—…ģžģ“ģ§€ė§Œ 법에 ģ •ķ•œ ģ‹œģ  낓에 ģ •ė³“ė³“ķ˜ø ź³µģ‹œź°€ ģ‹œķ–‰ė˜ģ§€ ģ•Šģ€ 경우","사딀 6 : ėŖØė°”ģ¼ģ•±ģ„ 통핓 ģœ„ģ¹˜ģ •ė³“ģ‚¬ģ—…ģžė”œė¶€ķ„° ģ“ģš©ģžģ˜ ź°œģøģœ„ģ¹˜ģ •ė³“ė„¼ 전솔받아 ģ„œė¹„ģŠ¤ģ— ģ“ģš©ķ•˜ź³  ģžˆģœ¼ė‚˜, ģœ„ģ¹˜źø°ė°˜ģ„œė¹„ģŠ¤ģ‚¬ģ—… 신고넼 ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 7 : 국낓에 ģ£¼ģ†Œ ė˜ėŠ” ģ˜ģ—…ģ†Œź°€ ģ—†ėŠ” ź°œģøģ •ė³“ģ²˜ė¦¬ģžė”œģ„œ ģ „ė…„ė„ 말 기준 직전 3ź°œģ›” ź°„ ź·ø ź°œģøģ •ė³“ź°€ ģ €ģž„Ā·ź“€ė¦¬ė˜ź³  ģžˆėŠ” źµ­ė‚“ ģ •ė³“ģ£¼ģ²“ģ˜ ģˆ˜ź°€ ģ¼ģ¼ķ‰ź·  100ė§ŒėŖ… ģ“ģƒģø ģžģ— ķ•“ė‹¹ė˜ģ–“ źµ­ė‚“ėŒ€ė¦¬ģø ģ§€ģ •ģ˜ė¬“ģ— ķ•“ė‹¹ėØģ—ė„ ė¶ˆźµ¬ķ•˜ź³ , źµ­ė‚“ėŒ€ė¦¬ģøģ„ ė¬øģ„œė”œ ģ§€ģ •ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ģ”°ģ§ģ“ ģ¤€ģˆ˜ķ•˜ģ—¬ģ•¼ ķ•  ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ 주기적으딜 ķŒŒģ•…ķ•˜ģ—¬ ź·œģ •ģ— ė°˜ģ˜ķ•˜ź³ , ģ¤€ģˆ˜ 여부넼 ģ§€ģ†ģ ģœ¼ė”œ ź²€ķ† ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.4.2": {"name": "꓀리첓계 점검","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.4.2 ꓀리첓계 점검","Subdomain": "1.4. ꓀리첓계 점검 ė° ź°œģ„ ","AuditEvidence": ["꓀리첓계 점검 ź³„ķšģ„œ(낓부점검 ź³„ķšģ„œ, 낓부감사 ź³„ķšģ„œ)","꓀리첓계 점검 ź²°ź³¼ė³“ź³ ģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģœ„ģ›ķšŒ ķšŒģ˜ė”"],"AuditChecklist": ["법적 ģš”źµ¬ģ‚¬ķ•­ ė° 수립된 정책에 ė”°ė¼ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계가 효과적으딜 ģš“ģ˜ė˜ėŠ”ģ§€ė„¼ ģ ź²€ķ•˜źø° ģœ„ķ•œ ꓀리첓계 점검기준, ė²”ģœ„, 주기, ģ ź²€ģøė „ ģžź²©ģš”ź±“ ė“±ģ„ ķ¬ķ•Øķ•œ ꓀리첓계 점검 ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","꓀리첓계 점검 ź³„ķšģ— ė”°ė¼ ė…ė¦½ģ„±, ź°ź“€ģ„± ė° ģ „ė¬øģ„±ģ“ ķ™•ė³“ėœ ģøė „ģ„ źµ¬ģ„±ķ•˜ģ—¬ ģ—° 1회 ģ“ģƒ ģ ź²€ģ„ ģˆ˜ķ–‰ķ•˜ź³  발견된 ė¬øģ œģ ģ„ ź²½ģ˜ģ§„ģ—ź²Œ ė³“ź³ ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ꓀리첓계 점검 ģøė „ģ— 점검 ėŒ€ģƒģœ¼ė”œ ģ‹ė³„ėœ ģ „ģ‚°ķŒ€ ģ§ģ›ģ“ ķ¬ķ•Øė˜ģ–“ ģ „ģ‚°ķŒ€ ꓀리 ģ˜ģ—­ģ— ėŒ€ķ•œ 점검에 ź“€ģ—¬ķ•˜ź³  ģžˆģ–“, ģ ź²€ģ˜ ė…ė¦½ģ„±ģ“ ķ›¼ģ†ėœ 경우","사딀 2 : źøˆė…„ė„ ꓀리첓계 ģ ź²€ģ„ ģ‹¤ģ‹œķ•˜ģ˜€ģœ¼ė‚˜, ģ ź²€ė²”ģœ„ź°€ ģ¼ė¶€ ģ˜ģ—­ģ— źµ­ķ•œė˜ģ–“ ģžˆģ–“ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 ė²”ģœ„ė„¼ ģ¶©ģ”±ķ•˜ģ§€ ėŖ»ķ•œ 경우","사딀 3 : ꓀리첓계 ģ ź²€ķŒ€ģ“ ģœ„ķ—˜ķ‰ź°€ ė˜ėŠ” 취약점 점검 등 ꓀리첓계 구축 과정에 ģ°øģ—¬ķ•œ ė‚“ė¶€ 직원 ė° 외부 ģ»Øģ„¤ķ„“ķŠøė”œė§Œ źµ¬ģ„±ė˜ģ–“, ģ ź²€ģ˜ ė…ė¦½ģ„±ģ“ ķ™•ė³“ė˜ģ—ˆė‹¤ź³  ė³¼ 수 ģ—†ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "꓀리첓계가 ė‚“ė¶€ ģ •ģ±… ė° 법적 ģš”źµ¬ģ‚¬ķ•­ģ— ė”°ė¼ 효과적으딜 욓영되고 ģžˆėŠ”ģ§€ ė…ė¦½ģ„±ź³¼ ģ „ė¬øģ„±ģ“ ķ™•ė³“ėœ ģøė „ģ„ źµ¬ģ„±ķ•˜ģ—¬ ģ—° 1회 ģ“ģƒ ģ ź²€ķ•˜ź³ , 발견된 ė¬øģ œģ ģ„ ź²½ģ˜ģ§„ģ—ź²Œ ė³“ź³ ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"1.4.3": {"name": "꓀리첓계 ź°œģ„ ","checks": {},"status": "PASS","attributes": [{"Domain": "1. ꓀리첓계 수립 ė° 욓영","Section": "1.4.3 ꓀리첓계 ź°œģ„ ","Subdomain": "1.4. ꓀리첓계 점검 ė° ź°œģ„ ","AuditEvidence": ["꓀리첓계 점검 ź²°ź³¼ė³“ź³ ģ„œ","꓀리첓계 점검 ģ”°ģ¹˜ź³„ķšģ„œĀ·ģ“ķ–‰ģ”°ģ¹˜ź²°ź³¼ģ„œ","ģž¬ė°œė°©ģ§€ ėŒ€ģ±…","ķšØź³¼ģ„± 츔정 ģ§€ķ‘œ ė° 츔정 ź²°ź³¼(ź²½ģ˜ģ§„ 볓고 ķ¬ķ•Ø)"],"AuditChecklist": ["법적 ģš”źµ¬ģ‚¬ķ•­ ģ¤€ģˆ˜ź²€ķ†  ė° ꓀리첓계 ģ ź²€ģ„ ķ†µķ•˜ģ—¬ ģ‹ė³„ėœ ź“€ė¦¬ģ²“ź³„ģƒģ˜ ė¬øģ œģ ģ— ėŒ€ķ•œ 근본 ģ›ģøģ„ ė¶„ģ„ķ•˜ģ—¬ ģž¬ė°œė°©ģ§€ ė° ź°œģ„  ėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģž¬ė°œė°©ģ§€ ė° ź°œģ„  ź²°ź³¼ģ˜ 정확성 ė° ķšØź³¼ģ„± 여부넼 ķ™•ģøķ•˜źø° ģœ„ķ•œ 기준과 절차넼 ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ģ ź²€ģ„ ķ†µķ•˜ģ—¬ 발견된 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀리첓계 욓영상 ė¬øģ œģ ģ“ 매번 ė™ģ¼ķ•˜ź²Œ ė°˜ė³µė˜ģ–“ ė°œģƒė˜ėŠ” 경우","사딀 2 : ė‚“ė¶€ ź·œģ •ģ—ėŠ” 낓부점검 ģ‹œ 발견된 ė¬øģ œģ ģ— ėŒ€ķ•“ģ„œėŠ” ź·¼ė³øģ›ģøģ— ėŒ€ķ•œ ė¶„ģ„ ė° ģž¬ė°œė°©ģ§€ ėŒ€ģ±…ģ„ ģˆ˜ė¦½ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ģµœź·¼ģ— ģˆ˜ķ–‰ėœ ė‚“ė¶€ģ ź²€ģ—ģ„œėŠ” 발견된 ė¬øģ œģ ģ— ėŒ€ķ•˜ģ—¬ ź·¼ė³øģ›ģø ė¶„ģ„ ė° ģž¬ė°œė°©ģ§€ ėŒ€ģ±…ģ“ ģˆ˜ė¦½ė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ź“€ė¦¬ģ²“ź³„ģƒ ė¬øģ œģ ģ— ėŒ€ķ•œ ģž¬ė°œė°©ģ§€ ėŒ€ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ķ•µģ‹¬ģ„±ź³¼ģ§€ķ‘œė„¼ ė§ˆė Øķ•˜ģ—¬ 주기적으딜 ģø”ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, ź·ø 결과에 ėŒ€ķ•˜ģ—¬ ź²½ģ˜ģ§„ 볓고가 ģž„źø°ź°„ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우","사딀 4 : ꓀리첓계 점검 ģ‹œ 발견된 ė¬øģ œģ ģ— ėŒ€ķ•˜ģ—¬ ģ”°ģ¹˜ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜ 씰치 ģ™„ė£Œ 여부넼 ķ™•ģøķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "법적 ģš”źµ¬ģ‚¬ķ•­ ģ¤€ģˆ˜ź²€ķ†  ė° ꓀리첓계 ģ ź²€ģ„ ķ†µķ•˜ģ—¬ ģ‹ė³„ėœ ź“€ė¦¬ģ²“ź³„ģƒģ˜ ė¬øģ œģ ģ— ėŒ€ķ•œ ģ›ģøģ„ ė¶„ģ„ķ•˜ź³  ģž¬ė°œė°©ģ§€ ėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•˜ė©°, ź²½ģ˜ģ§„ģ€ ź°œģ„  ź²°ź³¼ģ˜ 정확성과 ķšØź³¼ģ„± 여부넼 ķ™•ģøķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.1.1": {"name": "ģ •ģ±…ģ˜ ģœ ģ§€ź“€ė¦¬","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.1.1 ģ •ģ±…ģ˜ ģœ ģ§€ź“€ė¦¬","Subdomain": "2.1. ģ •ģ±…, 씰직, ģžģ‚° ꓀리","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±… ė° ģ‹œķ–‰ė¬øģ„œ(지침, 절차, ź°€ģ“ė“œ, 매뉓얼 등)","정책·지침 정기·비정기 ķƒ€ė‹¹ģ„± 검토 ź²°ź³¼","정책·지침 ꓀련 ė¶€ģ„œģ™€ģ˜ 검토 ķšŒģ˜ė”, ķšŒėžŒė‚“ģš©","정책·지침 ģ œĀ·ź°œģ • ģ“ė „"],"AuditChecklist": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ •ģ±… ė° ģ‹œķ–‰ė¬øģ„œģ— ėŒ€ķ•œ ģ •źø°ģ ģø ķƒ€ė‹¹ģ„± 검토 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ”°ģ§ģ˜ ėŒ€ė‚“ģ™ø ķ™˜ź²½ģ— ģ¤‘ėŒ€ķ•œ 변화 ė°œģƒ ģ‹œ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ •ģ±… ė° ģ‹œķ–‰ė¬øģ„œģ— ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ź²€ķ† ķ•˜ź³  ķ•„ģš”ģ‹œ ģ œĀ·ź°œģ •ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ •ģ±… ė° ģ‹œķ–‰ė¬øģ„œģ˜ ģ œĀ·ź°œģ • ģ‹œ ģ“ķ•“ ź“€ź³„ģžģ˜ 검토넼 받고 ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ •ģ±… ė° ģ‹œķ–‰ė¬øģ„œģ˜ ģ œĀ·ź°œģ • 낓역에 ėŒ€ķ•˜ģ—¬ ģ“ė „ź“€ė¦¬ė„¼ ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ§€ģ¹Øģ„œģ™€ ģ ˆģ°Øģ„œ ź°„ ķŒØģŠ¤ģ›Œė“œ 설정 ź·œģ¹™ģ— ģ¼ź“€ģ„±ģ“ ģ—†ėŠ” 경우","사딀 2 : ģ •ė³“ė³“ķ˜ø ķ™œė™(ģ •ė³“ė³“ķ˜ø 교윔, ģ•”ķ˜øķ™”, 백업 등)ģ˜ ėŒ€ģƒ, 주기, ģˆ˜ģ¤€, 방법 ė“±ģ“ ꓀련 ė‚“ė¶€ ź·œģ •, 지침, ģ ˆģ°Øģ— ģ„œė”œ ė‹¤ė„“ź²Œ ėŖ…ģ‹œė˜ģ–“ ģ¼ź“€ģ„±ģ“ ģ—†ėŠ” 경우","사딀 3 : ė°ģ“ķ„°ė² ģ“ģŠ¤ģ— ėŒ€ķ•œ ģ ‘ź·¼ ė° ģž‘ģ—…ģ“ė „ģ„ 효과적으딜 źø°ė” ė° ź“€ė¦¬ķ•˜źø° ģœ„ķ•˜ģ—¬ ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ķ†µģ œ ģ†”ė£Øģ…˜ģ„ ģ‹ ź·œė”œ ė„ģž…ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, ė³“ģ•ˆģ‹œģŠ¤ķ…œ ė³“ģ•ˆ ꓀리지침 ė° ė°ģ“ķ„°ė² ģ“ģŠ¤ ė³“ģ•ˆ ꓀리지침 등 ė‚“ė¶€ ė³“ģ•ˆģ§€ģ¹Øģ— ģ ‘ź·¼ķ†µģ œ, ģž‘ģ—…ģ“ė „, ė”œź¹…, 검토 등에 ź“€ķ•œ ģ‚¬ķ•­ģ“ ė°˜ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±…ģ“ ź°œģ •ė˜ģ—ˆģœ¼ė‚˜ ģ •ģ±… ģ‹œķ–‰ źø°ģ¤€ģ¼ģ“ ėŖ…ģ‹œė˜ģ–“ ģžˆģ§€ ģ•Šģœ¼ė©°, ꓀련 ģ •ģ±…ģ˜ ģž‘ģ„±ģ¼, ģž‘ģ„±ģž ė° ģŠ¹ģøģž ė“±ģ“ ėˆ„ė½ė˜ģ–“ ģžˆėŠ” 경우","사딀 5 : ź°œģøģ •ė³“ 볓호 ꓀련 법령, ź³ ģ‹œ 등에 ģ¤‘ėŒ€ķ•œ ė³€ź²½ģ‚¬ķ•­ģ“ ė°œģƒķ•˜ģ˜€ģœ¼ė‚˜, ģ“ėŸ¬ķ•œ ė³€ź²½ģ“ ź°œģøģ •ė³“ė³“ķ˜ø ģ •ģ±… ė° ģ‹œķ–‰ė¬øģ„œģ— ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ź²€ķ† ķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜ ė³€ź²½ģ‚¬ķ•­ģ„ ė°˜ģ˜ķ•˜ģ—¬ ź°œģ •ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ •ģ±…ź³¼ ģ‹œķ–‰ė¬øģ„œėŠ” 법령 ė° 규제, ģƒģœ„ 씰직 ė° ꓀련 źø°ź“€ ģ •ģ±…ź³¼ģ˜ 연계성, ģ”°ģ§ģ˜ ėŒ€ė‚“ģ™ø ķ™˜ź²½ė³€ķ™” 등에 ė”°ė¼ 주기적으딜 ź²€ķ† ķ•˜ģ—¬ ķ•„ģš”ķ•œ 경우 ģ œĀ·ź°œģ •ķ•˜ź³  ź·ø ė‚“ģ—­ģ„ ģ“ė „ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.1.2": {"name": "ģ”°ģ§ģ˜ ģœ ģ§€ź“€ė¦¬","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.1.2 ģ”°ģ§ģ˜ ģœ ģ§€ź“€ė¦¬","Subdomain": "2.1. ģ •ģ±…, 씰직, ģžģ‚° ꓀리","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ”°ģ§ė„","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 씰직 ģ§ė¬“źø°ģˆ ģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 업묓 ė¶„ģž„ķ‘œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 정책·지침, ė‚“ė¶€ ź“€ė¦¬ź³„ķš","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ˜ģ‚¬ģ†Œķ†µ ź“€ė¦¬ź³„ķš","ģ˜ģ‚¬ģ†Œķ†µ ģˆ˜ķ–‰ ģ“ė „(월간볓고, 주간볓고, 낓부공지 등)","ģ˜ģ‚¬ģ†Œķ†µ 채널(ģ •ė³“ė³“ķ˜øķ¬ķ„ø, ź²Œģ‹œķŒ 등)"],"AuditChecklist": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ±…ģž„ģžģ™€ ė‹“ė‹¹ģžģ˜ ģ—­ķ•  ė° ģ±…ģž„ģ„ ėŖ…ķ™•ķžˆ ģ •ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ±…ģž„ģžģ™€ ė‹“ė‹¹ģžģ˜ ķ™œė™ģ„ ķ‰ź°€ķ•  수 ģžˆėŠ” 첓계넼 ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 씰직 ė° ģ”°ģ§ģ˜ 구성원 ź°„ 상호 ģ˜ģ‚¬ģ†Œķ†µķ•  수 ģžˆėŠ” 첓계 ė° 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ 지침 ė° ģ§ė¬“źø°ģˆ ģ„œģ— ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž, ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģž ė° ꓀련 ė‹“ė‹¹ģžģ˜ ģ—­ķ• ź³¼ ģ±…ģž„ģ„ ģ •ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ‹¤ģ œ ģš“ģ˜ķ˜„ķ™©ź³¼ ģ¼ģ¹˜ķ•˜ģ§€ ģ•ŠėŠ” 경우","사딀 2 : ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ꓀련 ė‹“ė‹¹ģžģ˜ ķ™œė™ģ„ 주기적으딜 ķ‰ź°€ķ•  수 ģžˆėŠ” ėŖ©ķ‘œ, 기준, ģ§€ķ‘œ ė“±ģ˜ 첓계가 ė§ˆė Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ė‚“ė¶€ ģ§€ģ¹Øģ—ėŠ” ė¶€ģ„œė³„ ģ •ė³“ė³“ķ˜ø ė‹“ė‹¹ģžėŠ” ģ •ė³“ė³“ķ˜øģ™€ ź“€ė Øėœ KPI넼 ģ„¤ģ •ķ•˜ģ—¬ ģøģ‚¬ķ‰ź°€ ģ‹œ ė°˜ģ˜ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ė¶€ģ„œė³„ ģ •ė³“ė³“ķ˜ø ė‹“ė‹¹ģžģ˜ KPI에 ģ •ė³“ė³“ķ˜øģ™€ ź“€ė Øėœ ģ‚¬ķ•­ģ“ ģ „ķ˜€ ė°˜ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģž ė° ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžź°€ ģ§€ģ •ė˜ģ–“ ģžˆģœ¼ė‚˜, ꓀련 ė²•ė ¹ģ—ģ„œ ģš”źµ¬ķ•˜ėŠ” ģ—­ķ•  ė° ģ±…ģž„ģ“ ė‚“ė¶€ ģ§€ģ¹Øģ“ė‚˜ ģ§ė¬“źø°ģˆ ģ„œ 등에 구첓적으딜 ėŖ…ģ‹œė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“), 제31ģ”°(ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ˜ 지정)","ģ •ė³“ķ†µģ‹ ė§ė²• 제45ģ”°ģ˜3(ģ •ė³“ė³“ķ˜ø ģµœź³ ģ±…ģž„ģžģ˜ 지정 등)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ģ”°ģ§ģ˜ 각 źµ¬ģ„±ģ›ģ—ź²Œ ģ •ė³“ė³“ķ˜øģ™€ ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ—­ķ•  ė° ģ±…ģž„ģ„ ķ• ė‹¹ķ•˜ź³ , ź·ø ķ™œė™ģ„ ķ‰ź°€ķ•  수 ģžˆėŠ” 첓계와 씰직 ė° ģ”°ģ§ģ˜ 구성원 ź°„ 상호 ģ˜ģ‚¬ģ†Œķ†µķ•  수 ģžˆėŠ” 첓계넼 ģˆ˜ė¦½ķ•˜ģ—¬ ģš“ģ˜ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.1.3": {"name": "ģ •ė³“ģžģ‚° ꓀리","checks": {"macie_is_enabled": "PASS","resourceexplorer2_indexes_found": "PASS","config_recorder_all_regions_enabled": null,"account_maintain_current_contact_details": null,"organizations_account_part_of_organizations": null,"organizations_tags_policies_enabled_and_attached": null,"account_security_contact_information_is_registered": null,"account_security_questions_are_registered_in_the_aws_account": null,"account_maintain_different_contact_details_to_security_billing_and_operations": null},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.1.3 ģ •ė³“ģžģ‚° ꓀리","Subdomain": "2.1. ģ •ģ±…, 씰직, ģžģ‚° ꓀리","AuditEvidence": ["ģ •ė³“ģžģ‚° ėŖ©ė”(ģ±…ģž„ģž, ė‹“ė‹¹ģž 지정)","ģ •ė³“ģžģ‚° ģ·Øźø‰ 절차(ė¬øģ„œ, ģ •ė³“ģ‹œģŠ¤ķ…œ 등)","ģ •ė³“ģžģ‚° ꓀리 ģ‹œģŠ¤ķ…œ 화멓","ģ •ė³“ģžģ‚° ė³“ģ•ˆė“±źø‰ ķ‘œģ‹œ ė‚“ģ—­"],"AuditChecklist": ["ģ •ė³“ģžģ‚°ģ˜ ė³“ģ•ˆė“±źø‰ģ— 따넸 ģ·Øźø‰ģ ˆģ°Ø(ģƒģ„±Ā·ė„ģž…, ģ €ģž„, ģ“ģš©, 파기) ė° ė³“ķ˜øėŒ€ģ±…ģ„ ģ •ģ˜ķ•˜ź³  ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ‹ė³„ėœ ģ •ė³“ģžģ‚°ģ— ėŒ€ķ•˜ģ—¬ ģ±…ģž„ģž ė° ź“€ė¦¬ģžė„¼ ģ§€ģ •ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ 지침에 ė”°ė¼ ė¬øģ„œģ— ė³“ģ•ˆė“±źø‰ģ„ ķ‘œźø°ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ģ“ė„¼ ķ‘œģ‹œķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģ •ė³“ģžģ‚°ė³„ ė‹“ė‹¹ģž ė° ģ±…ģž„ģžė„¼ ģ‹ė³„ķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜, ģžģ‚°ėŖ©ė” ķ˜„ķ–‰ķ™”ź°€ ėÆøķ”ķ•˜ģ—¬ 퇓직, 전볓 등 ģøģ‚¬ģ“ė™ģ“ ė°œģƒķ•˜ģ—¬ ģ£¼ģš” ģ •ė³“ģžģ‚°ģ˜ ė‹“ė‹¹ģž ė° ģ±…ģž„ģžź°€ ė³€ź²½ė˜ģ—ˆģŒģ—ė„ ģ“ė„¼ ģ‹ė³„ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ģ‹ė³„ėœ ģ •ė³“ģžģ‚°ģ— ėŒ€ķ•œ ģ¤‘ģš”ė„ ķ‰ź°€ė„¼ ģ‹¤ģ‹œķ•˜ģ—¬ ė³“ģ•ˆė“±źø‰ģ„ ė¶€ģ—¬ķ•˜ź³  정볓 ģžģ‚°ėŖ©ė”ģ— źø°ė”ķ•˜ź³  ģžˆģœ¼ė‚˜, ė³“ģ•ˆė“±źø‰ģ— 따넸 ģ·Øźø‰ģ ˆģ°Øė„¼ ģ •ģ˜ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ģ •ė³“ģžģ‚°ģ˜ ģš©ė„ģ™€ ģ¤‘ģš”ė„ģ— 따넸 ģ·Øźø‰ 절차 ė° ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ , ģžģ‚°ė³„ ģ±…ģž„ģ†Œģž¬ė„¼ ėŖ…ķ™•ķžˆ ģ •ģ˜ķ•˜ģ—¬ ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 2,"total": 9,"manual": 0}},"2.2.1": {"name": "ģ£¼ģš” ģ§ė¬“ģž 지정 ė° ꓀리","checks": {"iam_support_role_created": null,"organizations_delegated_administrators": null,"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.2.1 ģ£¼ģš” ģ§ė¬“ģž 지정 ė° ꓀리","Subdomain": "2.2. ģøģ  ė³“ģ•ˆ","AuditEvidence": ["ģ£¼ģš” 직묓 기준","ģ£¼ģš”ģ§ė¬“ģž ėŖ©ė”","ź°œģøģ •ė³“ģ·Øźø‰ģž ėŖ©ė”","ģ¤‘ģš” ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ 계정 ė° ź¶Œķ•œ ꓀리 ėŒ€ģž„","ģ£¼ģš” ģ§ė¬“ģžģ— ėŒ€ķ•œ ꓀리 ķ˜„ķ™©(교윔 ź²°ź³¼, ė³“ģ•ˆģ„œģ•½ģ„œ 등)"],"AuditChecklist": ["ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ˜ ģ·Øźø‰, ģ£¼ģš” ģ‹œģŠ¤ķ…œ ģ ‘ź·¼ 등 ģ£¼ģš” ģ§ė¬“ģ˜ źø°ģ¤€ģ„ ėŖ…ķ™•ķžˆ ģ •ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ģ£¼ģš” 직묓넼 ģˆ˜ķ–‰ķ•˜ėŠ” ģž„ģ§ģ› ė° ģ™øė¶€ģžė„¼ ģ£¼ģš” ģ§ė¬“ģžė”œ ģ§€ģ •ķ•˜ź³  ź·ø ėŖ©ė”ģ„ ģµœģ‹ ģœ¼ė”œ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ—…ė¬“ģƒ ź°œģøģ •ė³“ė„¼ ģ·Øźø‰ķ•˜ėŠ” ģžė„¼ ź°œģøģ •ė³“ģ·Øźø‰ģžė”œ ģ§€ģ •ķ•˜ź³  ėŖ©ė”ģ„ ģµœģ‹ ģœ¼ė”œ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","업묓 ķ•„ģš”ģ„±ģ— ė”°ė¼ ģ£¼ģš” ģ§ė¬“ģž ė° ź°œģøģ •ė³“ģ·Øźø‰ģž ģ§€ģ •ģ„ ģµœģ†Œķ™”ķ•˜ėŠ” 등 ź“€ė¦¬ė°©ģ•ˆģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ£¼ģš” ģ§ė¬“ģž 명단(ź°œģøģ •ė³“ģ·Øźø‰ģž 명단, ė¹„ė°€ģ •ė³“ź“€ė¦¬ģž 명단 등)ģ„ ģž‘ģ„±ķ•˜ź³  ģžˆģœ¼ė‚˜, ėŒ€ėŸ‰ģ˜ ź°œģøģ •ė³“ 등 ģ¤‘ģš”ģ •ė³“ė„¼ ģ·Øźø‰ķ•˜ėŠ” ģ¼ė¶€ ģž„ģ§ģ›(DBA, DLP ź“€ė¦¬ģž 등)ģ„ 명단에 ėˆ„ė½ķ•œ 경우","사딀 2 : ģ£¼ģš” ģ§ė¬“ģž ė° ź°œģøģ •ė³“ģ·Øźø‰ģž ėŖ©ė”ģ„ ź“€ė¦¬ķ•˜ź³  ģžˆģœ¼ė‚˜, ķ‡“ģ‚¬ķ•œ ģž„ģ§ģ›ģ“ ķ¬ķ•Øė˜ģ–“ ģžˆź³  최근 ģ‹ ź·œ ģž…ģ‚¬ķ•œ ģøė „ģ“ ķ¬ķ•Øė˜ģ–“ ģžˆģ§€ ģ•ŠėŠ” 등 ķ˜„ķ–‰ķ™” ꓀리가 ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ė¶€ģ„œ ė‹Øģœ„ė”œ ź°œģøģ •ė³“ģ·Øźø‰ģž ź¶Œķ•œģ„ ģ¼ź“„ ė¶€ģ—¬ķ•˜ź³  ģžˆģ–“ ģ‹¤ģ œ ź°œģøģ •ė³“ė„¼ 취급할 ķ•„ģš”ź°€ ģ—†ėŠ” ģøģ›ź¹Œģ§€ ź³¼ė‹¤ķ•˜ź²Œ ź°œģøģ •ė³“ģ·Øźø‰ģžė”œ ģ§€ģ •ėœ 경우","사딀 4 : ė‚“ė¶€ ģ§€ģ¹Øģ—ėŠ” ģ£¼ģš” ģ§ė¬“ģž ź¶Œķ•œ 부여 ģ‹œģ—ėŠ” ė³“ģ•ˆķŒ€ģ˜ ģŠ¹ģøģ„ 받고 ģ£¼ģš” 직묓에 따넸 ė³“ģ•ˆģ„œģ•½ģ„œė„¼ ģž‘ģ„±ķ•˜ė„ė” ķ•˜ź³  ģžˆģœ¼ė‚˜, ė³“ģ•ˆķŒ€ ģŠ¹ģø ė° ė³“ģ•ˆģ„œģ•½ģ„œ ģž‘ģ„± ģ—†ģ“ ė“±ė”ėœ ģ£¼ģš” ģ§ė¬“ģžź°€ ė‹¤ģˆ˜ ģ”“ģž¬ķ•˜ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제28ģ”°(ź°œģøģ •ė³“ģ·Øźø‰ģžģ— ėŒ€ķ•œ ź°ė…), 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ˜ ģ·Øźø‰ģ“ė‚˜ ģ£¼ģš” ģ‹œģŠ¤ķ…œ ģ ‘ź·¼ 등 ģ£¼ģš” ģ§ė¬“ģ˜ 기준과 ź“€ė¦¬ė°©ģ•ˆģ„ ģˆ˜ė¦½ķ•˜ź³ , ģ£¼ģš” ģ§ė¬“ģžė„¼ ģµœģ†Œķ•œģœ¼ė”œ ģ§€ģ •ķ•˜ģ—¬ ź·ø ėŖ©ė”ģ„ ģµœģ‹ ģœ¼ė”œ ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 3,"manual": 0}},"2.2.2": {"name": "직묓 분리","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.2.2 직묓 분리","Subdomain": "2.2. ģøģ  ė³“ģ•ˆ","AuditEvidence": ["직묓 분리 ꓀련 지침(ģøģ  ė³“ģ•ˆ 지침 등)","ģ§ė¬“źø°ģˆ ģ„œ(ģ‹œģŠ¤ķ…œ ģš“ģ˜Ā·ź“€ė¦¬, 개발·욓영 등)","직묓 미분리 ģ‹œ ė³“ģ™„ķ†µģ œ ķ˜„ķ™©"],"AuditChecklist": ["ź¶Œķ•œ ģ˜¤Ā·ė‚Øģš© ė“±ģœ¼ė”œ ģøķ•œ ģž ģž¬ģ ģø 피핓 ģ˜ˆė°©ģ„ ģœ„ķ•˜ģ—¬ 직묓 분리 źø°ģ¤€ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?","직묓 분리가 ģ–“ė ¤ģš“ 경우 ģ§ė¬“ģž ź°„ 상호 검토, ģƒģœ„ź“€ė¦¬ģž ģ •źø° ėŖØė‹ˆķ„°ė§ ė° 변경사항 ģŠ¹ģø, ģ±…ģž„ģ¶”ģ ģ„± 확볓 ė°©ģ•ˆ ė“±ģ˜ ė³“ģ™„ķ†µģ œė„¼ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ”°ģ§ģ˜ ź·œėŖØģ™€ ģøģ›ģ“ ė‹“ė‹¹ģžė³„ 직묓 분리가 ģ¶©ė¶„ķžˆ ź°€ėŠ„ķ•œ ģ”°ģ§ģž„ģ—ė„ 업묓 ķŽøģ˜ģ„±ė§Œģ„ ģ‚¬ģœ ė”œ ė‚“ė¶€ ź·œģ •ģœ¼ė”œ ģ •ķ•œ 직묓 분리 źø°ģ¤€ģ„ ģ¤€ģˆ˜ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ģ”°ģ§ģ˜ ķŠ¹ģ„±ģƒ ź²½ģ˜ģ§„ģ˜ ģŠ¹ģøģ„ ė°›ģ€ 후 개발과 욓영 직묓넼 ė³‘ķ–‰ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ§ė¬“ģž ź°„ 상호 검토, ģƒģœ„ź“€ė¦¬ģžģ˜ ģ£¼źø°ģ ģø ģ§ė¬“ģˆ˜ķ–‰ ėŖØė‹ˆķ„°ė§ ė° 변경 사항 ź²€ķ† Ā·ģŠ¹ģø, ģ§ė¬“ģžģ˜ ģ±…ģž„ģ¶”ģ ģ„± 확볓 ė“±ģ˜ ė³“ģ™„ķ†µģ œ ģ ˆģ°Øź°€ ė§ˆė Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ź¶Œķ•œ ģ˜¤Ā·ė‚Øģš© ė“±ģœ¼ė”œ ģøķ•œ ģž ģž¬ģ ģø 피핓 ģ˜ˆė°©ģ„ ģœ„ķ•˜ģ—¬ 직묓 분리 źø°ģ¤€ģ„ ģˆ˜ė¦½ķ•˜ź³  ģ ģš©ķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ė‹¤ė§Œ ė¶ˆź°€ķ”¼ķ•˜ź²Œ 직묓 분리가 ģ–“ė ¤ģš“ 경우 ė³„ė„ģ˜ ė³“ģ™„ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ģ—¬ ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.2.3": {"name": "ė³“ģ•ˆ ģ„œģ•½","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.2.3 ė³“ģ•ˆ ģ„œģ•½","Subdomain": "2.2. ģøģ  ė³“ģ•ˆ","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ„œģ•½ģ„œ(ģž„ģ§ģ›, ģ™øė¶€ģøė „)","ė¹„ė°€ģœ ģ§€ģ„œģ•½ģ„œ(ķ‡“ģ§ģž)"],"AuditChecklist": ["ģ‹ ź·œ ģøė „ ģ±„ģš© ģ‹œ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ±…ģž„ģ“ ėŖ…ģ‹œėœ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ„œģ•½ģ„œė„¼ 받고 ģžˆėŠ”ź°€?","ģž„ģ‹œģ§ģ›, ģ™øģ£¼ģš©ģ—­ģ§ģ› 등 ģ™øė¶€ģžģ—ź²Œ ģ •ė³“ģžģ‚°ģ— ėŒ€ķ•œ ģ ‘ź·¼ź¶Œķ•œģ„ 부여할 경우 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜øģ— ėŒ€ķ•œ ģ±…ģž„, ė¹„ė°€ģœ ģ§€ ģ˜ė¬“ ė“±ģ“ ėŖ…ģ‹œėœ ģ„œģ•½ģ„œė„¼ 받고 ģžˆėŠ”ź°€?","ģž„ģ§ģ› 퇓직 ģ‹œ ė³„ė„ģ˜ ė¹„ė°€ģœ ģ§€ģ— ź“€ė Øķ•œ ģ„œģ•½ģ„œė„¼ 받고 ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø, ź°œģøģ •ė³“ė³“ķ˜ø ė° ė¹„ė°€ģœ ģ§€ ģ„œģ•½ģ„œėŠ” ģ•ˆģ „ķ•˜ź²Œ ė³“ź“€ķ•˜ź³  ķ•„ģš”ģ‹œ ģ‰½ź²Œ 찾아볼 수 ģžˆė„ė” ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ‹ ź·œ ģž…ģ‚¬ģžģ— ėŒ€ķ•“ģ„œėŠ” ģž…ģ‚¬ ģ ˆģ°Øģƒģ— ė³“ģ•ˆģ„œģ•½ģ„œė„¼ ė°›ė„ė” ź·œģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, ģµœź·¼ģ— ģž…ģ‚¬ķ•œ ģ¼ė¶€ ģ§ģ›ģ˜ ė³“ģ•ˆģ„œģ•½ģ„œ ģž‘ģ„±ģ“ ėˆ„ė½ėœ 경우","사딀 2 : ģž„ģ§ģ›ģ— ėŒ€ķ•“ģ„œėŠ” ė³“ģ•ˆģ„œģ•½ģ„œė„¼ 받고 ģžˆģœ¼ė‚˜, ģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— 직접 ģ ‘ģ†ģ“ ź°€ėŠ„ķ•œ 외주 ģøė „ģ— ėŒ€ķ•“ģ„œėŠ” ė³“ģ•ˆģ„œģ•½ģ„œė„¼ 받지 ģ•Šģ€ 경우","사딀 3 : 제출된 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ„œģ•½ģ„œė„¼ ėŖØģ•„ ė†“ģ€ ė¬øģ„œģ² ģ“ ė¹„ģøź°€ģžź°€ ģ ‘ź·¼ ź°€ėŠ„ķ•œ 상태딜 사묓실 ģ±…ģƒģ— ė°©ģ¹˜ė˜ģ–“ ģžˆėŠ” 등 ꓀리가 ėÆøķ”ķ•œ 경우","사딀 4 : ź°œģøģ •ė³“ģ·Øźø‰ģžģ— ėŒ€ķ•˜ģ—¬ ė³“ģ•ˆģ„œģ•½ģ„œė§Œ 받고 ģžˆģœ¼ė‚˜, ė³“ģ•ˆģ„œģ•½ģ„œ 낓에 ė¹„ė°€ģœ ģ§€ģ— ėŒ€ķ•œ ė‚“ģš©ė§Œ ģžˆź³  ź°œģøģ •ė³“ė³“ķ˜øģ— ź“€ķ•œ ģ±…ģž„ ė° ė‚“ģš©ģ“ ķ¬ķ•Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ģ •ė³“ģžģ‚°ģ„ ģ·Øźø‰ķ•˜ź±°ė‚˜ ģ ‘ź·¼ź¶Œķ•œģ“ ė¶€ģ—¬ėœ ģž„ģ§ģ›Ā·ģž„ģ‹œģ§ģ›Ā·ģ™øė¶€ģž ė“±ģ“ ė‚“ė¶€ ģ •ģ±… ė°","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.2.4": {"name": "ģøģ‹ģ œź³  ė° źµģœ”ķ›ˆė Ø","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.2.4 ģøģ‹ģ œź³  ė° źµģœ”ķ›ˆė Ø","Subdomain": "2.2. ģøģ  ė³“ģ•ˆ","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 교윔 ź³„ķšģ„œ","교윔 ź²°ź³¼ė³“ź³ ģ„œ","공통, 직묓별 źµģœ”ģžė£Œ","źµģœ”ģ°øģ„ģž ėŖ©ė”"],"AuditChecklist": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø źµģœ”ģ˜ ģ‹œźø°, źø°ź°„, ėŒ€ģƒ, ė‚“ģš©, 방법 ė“±ģ˜ ė‚“ģš©ģ“ ķ¬ķ•Øėœ ģ—°ź°„ 교윔 ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ź³  ź²½ģ˜ģ§„ģ˜ ģŠ¹ģøģ„ 받고 ģžˆėŠ”ź°€?","꓀리첓계 ė²”ģœ„ ė‚“ ėŖØė“  ģž„ģ§ģ›ź³¼ ģ™øė¶€ģžė„¼ ėŒ€ģƒģœ¼ė”œ ģ—°ź°„ 교윔 ź³„ķšģ— ė”°ė¼ ģ—° 1회 ģ“ģƒ ģ •źø°ģ ģœ¼ė”œ źµģœ”ģ„ ģˆ˜ķ–‰ķ•˜ź³ , ꓀련 ė²•ź·œ ė° ź·œģ •ģ˜ ģ¤‘ėŒ€ķ•œ 변경 ģ‹œ ģ“ģ— ėŒ€ķ•œ ģ¶”ź°€źµģœ”ģ„ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģž„ģ§ģ› ģ±„ģš© ė° ģ™øė¶€ģž ģ‹ ź·œ 계약 ģ‹œ 업묓 ģ‹œģž‘ 전에 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø źµģœ”ģ„ ģ‹œķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","IT ė° ģ •ė³“ė³“ķ˜ø, ź°œģøģ •ė³“ė³“ķ˜ø 씰직 ė‚“ ģž„ģ§ģ›ģ€ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜øģ™€ ź“€ė Øķ•˜ģ—¬ 직묓별 전문성 제고넼 ģœ„ķ•œ ė³„ė„ģ˜ źµģœ”ģ„ 받고 ģžˆėŠ”ź°€?","źµģœ”ģ‹œķ–‰ģ— ėŒ€ķ•œ źø°ė”ģ„ 남기고 교윔 ķšØź³¼ģ™€ ģ ģ •ģ„±ģ„ ķ‰ź°€ķ•˜ģ—¬ ė‹¤ģŒ 교윔 ź³„ķšģ— ė°˜ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ „ė…„ė„ģ—ėŠ” ģ—°ź°„ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 교윔 ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ģ“ķ–‰ķ•˜ģ˜€ģœ¼ė‚˜, 당핓 ģ—°ė„ģ— ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ģ—†ģ“ ģ—°ź°„ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 교윔 ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģ—°ź°„ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 교윔 ź³„ķšģ— 교윔 주기와 ėŒ€ģƒģ€ ėŖ…ģ‹œķ•˜ź³  ģžˆģœ¼ė‚˜, ģ‹œķ–‰ ģ¼ģ •, ė‚“ģš© ė° 방법 ė“±ģ˜ ė‚“ģš©ģ“ ķ¬ķ•Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģ—°ź°„ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 교윔 ź³„ķšģ— ģ „ ģ§ģ›ģ„ ėŒ€ģƒģœ¼ė”œ ķ•˜ėŠ” ź°œģøģ •ė³“ė³“ķ˜ø ģøģ‹ źµģœ”ģ€ ģ¼ģ •ģ‹œź°„ ź³„ķšė˜ģ–“ ģžˆģœ¼ė‚˜, ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģž ė° ź°œģøģ •ė³“ė‹“ė‹¹ģž 등 ģ§ė¬“ė³„ė”œ ķ•„ģš”ķ•œ ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 교윔 ź³„ķšģ“ ķ¬ķ•Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 교윔 ź³„ķšģ„œ ė° ź²°ź³¼ ė³“ź³ ģ„œė„¼ ķ™•ģøķ•œ ź²°ź³¼, ģøģ¦ė²”ģœ„ ė‚“ģ˜ ģ •ė³“ģžģ‚° ė° 설비에 ģ ‘ź·¼ķ•˜ėŠ” ģ™øģ£¼ģš©ģ—­ģ—…ģ²“ 직원(전산실 ģ¶œģž… ģ²­ģ†Œģ›, 경비원, ģ™øģ£¼ź°œė°œģž 등)ģ„ 교윔 ėŒ€ģƒģ—ģ„œ ėˆ„ė½ķ•œ 경우","사딀 5 : 당핓 ģ—°ė„ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø źµģœ”ģ„ ģ‹¤ģ‹œķ•˜ģ˜€ģœ¼ė‚˜, źµģœ”ģ‹œķ–‰ ė° ķ‰ź°€ģ— ź“€ķ•œ źø°ė”(교윔 ģžė£Œ, ģ¶œģ„ė¶€, ķ‰ź°€ 설문지, ź²°ź³¼ė³“ź³ ģ„œ 등) ģ¼ė¶€ė„¼ 남기지 ģ•Šź³  ģžˆėŠ” 경우","사딀 6 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 교윔 ėÆøģ“ģˆ˜ģžė„¼ ķŒŒģ•…ķ•˜ģ§€ ģ•Šź³  ģžˆź±°ė‚˜, 핓당 ėÆøģ“ģˆ˜ģžģ— ėŒ€ķ•œ ģ¶”ź°€źµģœ” 방법(ģ „ė‹¬źµģœ”, ģ¶”ź°€źµģœ”, ģ˜Øė¼ģøźµģœ” 등)ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제26ģ”°(ģ—…ė¬“ģœ„ķƒģ— 따넸 ź°œģøģ •ė³“ģ˜ 처리 ģ œķ•œ), 제28ģ”°(ź°œģøģ •ė³“ ģ·Øźø‰ģžģ— ėŒ€ķ•œ ź°ė…), 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검)"]}],"description": "ģž„ģ§ģ› ė° ꓀련 ģ™øė¶€ģžź°€ ģ”°ģ§ģ˜ ꓀리첓계와 ģ •ģ±…ģ„ ģ“ķ•“ķ•˜ź³  직묓별 ģ „ė¬øģ„±ģ„ 확볓할 수 ģžˆė„ė” ģ—°ź°„ ģøģ‹ģ œź³  ķ™œė™ ė° źµģœ”ķ›ˆė Ø ź³„ķšģ„ ģˆ˜ė¦½Ā·ģš“ģ˜ķ•˜ź³ , ź·ø 결과에 따넸 ķšØź³¼ģ„±ģ„ ķ‰ź°€ķ•˜ģ—¬ ė‹¤ģŒ ź³„ķšģ— ė°˜ģ˜ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.2.5": {"name": "퇓직 ė° 직묓변경 ꓀리","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.2.5 퇓직 ė° 직묓변경 ꓀리","Subdomain": "2.2. ģøģ  ė³“ģ•ˆ","AuditEvidence": ["퇓직 ė° 직묓변경 ģ ˆģ°Øģ„œ","퇓직 ģ‹œ ģžģ‚°(계정) ė°˜ė‚©ź“€ė¦¬ėŒ€ģž„","ķ‡“ģ§ģž ė³“ģ•ˆģ ź²€ 첓크리스트 ė° 점검 ė‚“ģ—­"],"AuditChecklist": ["퇓직, 직묓변경, ė¶€ģ„œģ“ė™, 휓직 ė“±ģœ¼ė”œ ģøķ•œ ģøģ‚¬ė³€ź²½ ė‚“ģš©ģ“ ģøģ‚¬ė¶€ģ„œ, ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ė¶€ģ„œ, ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ģš“ģ˜ė¶€ģ„œ ź°„ 공유되고 ģžˆėŠ”ź°€?","씰직 ė‚“ ģøė „(ģž„ģ§ģ›, ģž„ģ‹œģ§ģ›, ģ™øģ£¼ģš©ģ—­ģ§ģ› 등)ģ˜ 퇓직 ė˜ėŠ” 직묓변경 ģ‹œ 지첓 ģ—†ėŠ” ģ •ė³“ģžģ‚° ė°˜ė‚©, ģ ‘ź·¼ź¶Œķ•œ ķšŒģˆ˜Ā·ģ”°ģ •, ź²°ź³¼ ķ™•ģø ė“±ģ˜ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 직묓 ė³€ė™ģ— ė”°ė¼ ź°œģøģ •ė³“ģ·Øźø‰ģžģ—ģ„œ ģ œģ™øėœ ģøė „ģ˜ 계정과 ź¶Œķ•œģ“ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— ź·øėŒ€ė”œ 남아 ģžˆėŠ” 경우","사딀 2 : ģµœź·¼ģ— ķ‡“ģ§ķ•œ ģ£¼ģš”ģ§ė¬“ģž ė° ź°œģøģ •ė³“ģ·Øźø‰ģžģ— ėŒ€ķ•˜ģ—¬ ģžģ‚°ė°˜ė‚©, ź¶Œķ•œ 회수 ė“±ģ˜ ķ‡“ģ§ģ ˆģ°Ø ģ“ķ–‰ źø°ė”ģ“ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ģž„ģ§ģ› 퇓직 ģ‹œ ģžģ‚°ė°˜ė‚© ź“€ė¦¬ėŠ” ģž˜ ģ“ķ–‰ķ•˜ź³  ģžˆģœ¼ė‚˜, ģøģ‚¬ź·œģ •ģ—ģ„œ ģ •ķ•œ ķ‡“ģ§ģž ė³“ģ•ˆģ ź²€ ė° ķ‡“ģ§ķ™•ģøģ„œė„¼ ģž‘ģ„±ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ź°œģøģ •ė³“ģ·Øźø‰ģž 퇓직 ģ‹œ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ģ ‘ź·¼ ź¶Œķ•œģ€ 지첓 ģ—†ģ“ ķšŒģˆ˜ė˜ģ—ˆģ§€ė§Œ, ģ¶œģž…ķ†µģ œ ģ‹œģŠ¤ķ…œ ė° VPN 등 ģ¼ė¶€ ģ‹œģŠ¤ķ…œģ˜ ģ ‘ź·¼ ź¶Œķ•œģ“ ķšŒģˆ˜ė˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ ź¶Œķ•œģ˜ ꓀리)"]}],"description": "퇓직 ė° 직묓변경 ģ‹œ ģøģ‚¬Ā·ģ •ė³“ė³“ķ˜øĀ·ź°œģøģ •ė³“ė³“ķ˜øĀ·IT 등 ꓀련 ė¶€ģ„œė³„ ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•  ģžģ‚°ė°˜ė‚©, 계정 ė° ģ ‘ź·¼ź¶Œķ•œ ķšŒģˆ˜Ā·ģ”°ģ •, ź²°ź³¼ķ™•ģø ė“±ģ˜ 절차넼 ģˆ˜ė¦½Ā·ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.2.6": {"name": "ė³“ģ•ˆ ģœ„ė°˜ ģ‹œ 씰치","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.2.6 ė³“ģ•ˆ ģœ„ė°˜ ģ‹œ 씰치","Subdomain": "2.2. ģøģ  ė³“ģ•ˆ","AuditEvidence": ["ģøģ‚¬ ź·œģ •(ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ź·œģ • ģœ„ė°˜ģ— 따넸 ģ²˜ė²Œź·œģ •)","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø 지침 ģœ„ė°˜ģž 징계 ė‚“ģ—­","사고 사딀(전사 공지, 교윔 ė‚“ģš©)"],"AuditChecklist": ["ģž„ģ§ģ› ė° ꓀련 ģ™øė¶€ģžź°€ 법령과 규제 ė° 낓부정책에 따넸 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ±…ģž„ź³¼ ģ˜ė¬“ė„¼ ģœ„ė°˜ķ•œ ź²½ģš°ģ— ėŒ€ķ•œ 처벌 ź·œģ •ģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ 볓호 ģœ„ė°˜ ģ‚¬ķ•­ģ“ 적발된 경우 ė‚“ė¶€ ģ ˆģ°Øģ— 따넸 씰치넼 ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ź·œģ • ģœ„ė°˜ģžģ— ėŒ€ķ•œ 처리 기준 ė° ģ ˆģ°Øź°€ ė‚“ė¶€ ź·œģ •ģ— ģ „ķ˜€ ķ¬ķ•Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ė³“ģ•ˆģ‹œģŠ¤ķ…œ(DLP, ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ģ œģ–“ģ‹œģŠ¤ķ…œ, ė‚“ė¶€ģ •ė³“ģœ ģ¶œķ†µģ œģ‹œģŠ¤ķ…œ 등)ģ„ ķ†µķ•˜ģ—¬ ģ •ģ±… ģœ„ė°˜ģ“ ķƒģ§€ėœ ź“€ė Øģžģ—ź²Œ 경고 ė©”ģ‹œģ§€ė„¼ ģ „ė‹¬ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•œ ģ†ŒėŖ… ė° 추가 씰사, 징계 ģ²˜ė¶„ 등 ė‚“ė¶€ ź·œģ •ģ— 따넸 ķ›„ģ† ģ”°ģ¹˜ź°€ ģ“ķ–‰ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ģž„ģ§ģ› ė° ꓀련 ģ™øė¶€ģžź°€ 법령, 규제 ė° ė‚“ė¶€ģ •ģ±…ģ„ ģœ„ė°˜ķ•œ 경우 ģ“ģ— 따넸 씰치 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.3.1": {"name": "ģ™øė¶€ģž ķ˜„ķ™© ꓀리","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.3.1 ģ™øė¶€ģž ķ˜„ķ™© ꓀리","Subdomain": "2.3. ģ™øė¶€ģž ė³“ģ•ˆ","AuditEvidence": ["외부 ģœ„ķƒ ė° 외부 ģ‹œģ„¤Ā·ģ„œė¹„ģŠ¤ ķ˜„ķ™©","외부 ģœ„ķƒ ź³„ģ•½ģ„œ","ģœ„ķ—˜ė¶„ģ„ ė³“ź³ ģ„œ ė° ė³“ķ˜øėŒ€ģ±…","ģœ„ķƒ ė³“ģ•ˆź“€ė¦¬ 지침, 첓크리스트 등"],"AuditChecklist": ["꓀리첓계 ė²”ģœ„ ė‚“ģ—ģ„œ ė°œģƒķ•˜ź³  ģžˆėŠ” 업묓 ģœ„ķƒ ė° 외부 ģ‹œģ„¤Ā·ģ„œė¹„ģŠ¤ģ˜ ģ“ģš© ķ˜„ķ™©ģ„ ģ‹ė³„ķ•˜ź³  ģžˆėŠ”ź°€?","업묓 ģœ„ķƒ ė° 외부 ģ‹œģ„¤Ā·ģ„œė¹„ģŠ¤ģ˜ ģ“ģš©ģ— 따넸 법적 ģš”źµ¬ģ‚¬ķ•­ź³¼ ģœ„ķ—˜ģ„ ķŒŒģ•…ķ•˜ź³  ģ ģ ˆķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ ź·œģ •ģ— ė”°ė¼ 외부 ģœ„ķƒ ė° 외부 ģ‹œģ„¤Ā·ģ„œė¹„ģŠ¤ ķ˜„ķ™©ģ„ ėŖ©ė”ģœ¼ė”œ ź“€ė¦¬ķ•˜ź³  ģžˆģœ¼ė‚˜, ėŖ‡ ź°œģ›” 전에 ė³€ź²½ėœ ģœ„ķƒģ—…ģ²“ź°€ ėŖ©ė”ģ— ė°˜ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 등 ķ˜„ķ–‰ķ™” ꓀리가 ėÆøķ”ķ•œ 경우","사딀 2 : ꓀리첓계 ė²”ģœ„ ė‚“ ģ¼ė¶€ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ„ 외부 ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ė”œ ģ“ģ „ķ•˜ģ˜€ģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•œ ģ‹ė³„ ė° ģœ„ķ—˜ķ‰ź°€ź°€ ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제26ģ”°(ģ—…ė¬“ģœ„ķƒģ— 따넸 ź°œģøģ •ė³“ģ˜ 처리 ģ œķ•œ)","ģ •ė³“ķ†µģ‹ ė§ė²• 제50ģ”°ģ˜3(ģ˜ė¦¬ėŖ©ģ ģ˜ ꓑ고성 정볓 ģ „ģ†”ģ˜ ģœ„ķƒ 등)"]}],"description": "ģ—…ė¬“ģ˜ ģ¼ė¶€(ź°œģøģ •ė³“ģ·Øźø‰, ģ •ė³“ė³“ķ˜ø, ģ •ė³“ģ‹œģŠ¤ķ…œ 욓영 ė˜ėŠ” 개발 등)넼 외부에 ģœ„ķƒķ•˜ź±°ė‚˜ ģ™øė¶€ģ˜ ģ‹œģ„¤ ė˜ėŠ” ģ„œė¹„ģŠ¤(ģ§‘ģ ģ •ė³“ķ†µģ‹ ģ‹œģ„¤, ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤, ģ• ķ”Œė¦¬ģ¼€ģ“ģ…˜ ģ„œė¹„ģŠ¤ 등)넼 ģ“ģš©ķ•˜ėŠ” 경우 ź·ø ķ˜„ķ™©ģ„ ģ‹ė³„ķ•˜ź³  법적 ģš”źµ¬ģ‚¬ķ•­ ė° 외부 ģ”°ģ§Ā·ģ„œė¹„ģŠ¤ė”œė¶€ķ„° ė°œģƒė˜ėŠ” ģœ„ķ—˜ģ„ ķŒŒģ•…ķ•˜ģ—¬ ģ ģ ˆķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.3.2": {"name": "ģ™øė¶€ģž 계약 ģ‹œ ė³“ģ•ˆ","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.3.2 ģ™øė¶€ģž 계약 ģ‹œ ė³“ģ•ˆ","Subdomain": "2.3. ģ™øė¶€ģž ė³“ģ•ˆ","AuditEvidence": ["ģœ„ķƒ ź³„ģ•½ģ„œ","ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ķ˜‘ģ•½ģ„œ(ģ•½ģ •ģ„œ, ė¶€ģ†ķ•©ģ˜ģ„œ)","ģœ„ķƒ ꓀련 ė‚“ė¶€ 지침","ģœ„ķƒģ—…ģ²“ ģ„ ģ • ꓀련 RFP(ģ œģ•ˆģš”ģ²­ģ„œ), ķ‰ź°€ķ‘œ"],"AuditChecklist": ["ģ¤‘ģš”ģ •ė³“ ė° ź°œģøģ •ė³“ ģ²˜ė¦¬ģ™€ ź“€ė Øėœ 외부 ģ„œė¹„ģŠ¤ ė° ģœ„ķƒ 업첓넼 ģ„ ģ •ķ•˜ėŠ” 경우 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ 볓호 ģ—­ėŸ‰ģ„ ź³ ė ¤ķ•˜ė„ė” 절차넼 ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","외부 ģ„œė¹„ģŠ¤ ģ“ģš© ė° 업묓 ģœ„ķƒģ— 따넸 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģš”źµ¬ģ‚¬ķ•­ģ„ ģ‹ė³„ķ•˜ź³  ģ“ė„¼ ź³„ģ•½ģ„œ ė˜ėŠ” ķ˜‘ģ •ģ„œģ— ėŖ…ģ‹œķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ź°œė°œģ„ ģœ„ķƒķ•˜ėŠ” 경우 개발 ģ‹œ ģ¤€ģˆ˜ķ•˜ģ—¬ģ•¼ ķ•  ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģš”źµ¬ģ‚¬ķ•­ģ„ ź³„ģ•½ģ„œģ— ėŖ…ģ‹œķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : IT 욓영, 개발 ė° ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ė„¼ ģœ„ķƒķ•˜ėŠ” ģ™øģ£¼ģš©ģ—­ģ—…ģ²“ģ— ėŒ€ķ•œ ģœ„ķƒź³„ģ•½ģ„œź°€ ģ”“ģž¬ķ•˜ģ§€ ģ•ŠėŠ” 경우","사딀 2 : ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ė„¼ ģœ„ķƒķ•˜ėŠ” ģ™øė¶€ģ—…ģ²“ģ™€ģ˜ ģœ„ķƒź³„ģ•½ģ„œģƒģ— ź°œģøģ •ė³“ ė³“ķ˜øė²• 등 ė²•ė ¹ģ—ģ„œ ģš”źµ¬ķ•˜ėŠ” ģ¼ė¶€ ķ•­ėŖ©(ź“€ė¦¬Ā·ź°ė…ģ— ź“€ķ•œ 사항 등)ģ“ ķ¬ķ•Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģøķ”„ė¼ 욓영과 ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ ģ¼ė¶€ė„¼ 외부업첓에 ģœ„ķƒķ•˜ź³  ģžˆģœ¼ė‚˜, ź³„ģ•½ģ„œ ė“±ģ—ėŠ” ģœ„ķƒģ—…ė¬“ģ˜ ķŠ¹ģ„±ģ— 따넸 ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ģ„ ģ‹ė³„Ā·ė°˜ģ˜ķ•˜ģ§€ ģ•Šź³  ė¹„ė°€ģœ ģ§€ ė° ģ†ķ•“ė°°ģƒģ— ź“€ķ•œ ģ¼ė°˜ ģ‚¬ķ•­ė§Œ ź·œģ •ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제26ģ”°(ģ—…ė¬“ģœ„ķƒģ— 따넸 ź°œģøģ •ė³“ģ˜ 처리 ģ œķ•œ)"]}],"description": "외부 ģ„œė¹„ģŠ¤ė„¼ ģ“ģš©ķ•˜ź±°ė‚˜ ģ™øė¶€ģžģ—ź²Œ 업묓넼 ģœ„ķƒķ•˜ėŠ” 경우 ģ“ģ— 따넸 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģš”źµ¬ģ‚¬ķ•­ģ„ ģ‹ė³„ķ•˜ź³ , ꓀련 ė‚“ģš©ģ„ ź³„ģ•½ģ„œ ė˜ėŠ” ķ˜‘ģ •ģ„œ 등에 ėŖ…ģ‹œķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.3.3": {"name": "ģ™øė¶€ģž ė³“ģ•ˆ ģ“ķ–‰ ꓀리","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.3.3 ģ™øė¶€ģž ė³“ģ•ˆ ģ“ķ–‰ ꓀리","Subdomain": "2.3. ģ™øė¶€ģž ė³“ģ•ˆ","AuditEvidence": ["ģ™øė¶€ģž ė° ģˆ˜ķƒģž ė³“ģ•ˆģ ź²€ ź²°ź³¼","ģ™øė¶€ģž ė° ģˆ˜ķƒģž 교윔 ė‚“ģ—­(교윔 ź²°ź³¼, ģ°øģ„ģž 명단, źµģœ”źµģž¬ 등)","ź°œģøģ •ė³“ ģœ„ķƒ ź³„ģ•½ģ„œ","ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ ģž¬ģœ„ķƒ ģ‹œ ģœ„ķƒģž ė™ģ˜ ģ¦ź±°ģžė£Œ"],"AuditChecklist": ["ģ™øė¶€ģžź°€ ź³„ģ•½ģ„œ, ķ˜‘ģ •ģ„œ, 낓부정책에 ėŖ…ģ‹œėœ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģš”źµ¬ģ‚¬ķ•­ģ„ ģ¤€ģˆ˜ķ•˜ź³  ģžˆėŠ”ģ§€ 주기적으딜 점검 ė˜ėŠ” 감사넼 ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ™øė¶€ģžģ— ėŒ€ķ•œ 점검 ė˜ėŠ” 감사 ģ‹œ 발견된 ė¬øģ œģ ģ— ėŒ€ķ•˜ģ—¬ ź°œģ„ ź³„ķšģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ė„¼ ģœ„ķƒė°›ģ€ ģˆ˜ķƒģžź°€ ꓀련 업묓넼 제3ģžģ—ź²Œ ģž¬ģœ„ķƒķ•˜ėŠ” 경우 ģœ„ķƒģžģ˜ ė™ģ˜ė„¼ ė°›ė„ė” ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķšŒģ‚¬ 낓에 ģƒģ£¼ķ•˜ģ—¬ IT 개발 ė° 욓영 업묓넼 ģˆ˜ķ–‰ķ•˜ėŠ” 외주업첓에 ėŒ€ķ•“ģ„œėŠ” ģ •źø°ģ ģœ¼ė”œ ė³“ģ•ˆģ ź²€ģ„ ģˆ˜ķ–‰ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ź°œģøģ •ė³“ ģˆ˜ķƒģžģ— ėŒ€ķ•˜ģ—¬ ė³“ģ•ˆźµģœ”ģ„ ģ‹¤ģ‹œķ•˜ė¼ėŠ” ź³µė¬øģ„ ė°œģ†”ķ•˜ź³  ģžˆģœ¼ė‚˜, 교윔 ģˆ˜ķ–‰ 여부넼 ķ™•ģøķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģˆ˜ķƒģžź°€ ģžģ²“ģ ģœ¼ė”œ ė³“ģ•ˆģ ź²€ģ„ ģˆ˜ķ–‰ķ•œ 후 ź·ø 결과넼 ķ†µģ§€ķ•˜ė„ė” ķ•˜ź³  ģžˆģœ¼ė‚˜, ģˆ˜ķƒģžź°€ ė³“ģ•ˆ ģ ź²€ģ„ ģ¶©ģ‹¤ķžˆ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ģ§€ 여부에 ėŒ€ķ•˜ģ—¬ ķ™•ģøķ•˜ėŠ” ģ ˆģ°Øź°€ ģ”“ģž¬ķ•˜ģ§€ ģ•Šģ•„ ė³“ģ•ˆģ ź²€ ź²°ź³¼ģ˜ ģ‹ ė¢°ģ„±ģ“ 매우 ė–Øģ–“ģ§€ėŠ” 경우","사딀 4 : ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ ģˆ˜ķƒģž 중 ģ¼ė¶€ź°€ ģœ„ķƒģžģ˜ ė™ģ˜ ģ—†ģ“ 핓당 업묓넼 제3ģžģ—ź²Œ ģž¬ģœ„ķƒķ•œ 경우","사딀 5 : 영리 ėŖ©ģ ģ˜ ꓑ고성 정볓전솔 업묓넼 ķƒ€ģøģ—ź²Œ ģœ„ķƒķ•˜ė©“ģ„œ ģˆ˜ķƒģžģ— ėŒ€ķ•œ ź“€ė¦¬Ā·ź°ė…ģ„ ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제26ģ”°(ģ—…ė¬“ģœ„ķƒģ— 따넸 ź°œģøģ •ė³“ģ˜ 처리 ģ œķ•œ)","ģ •ė³“ķ†µģ‹ ė§ė²• 제50ģ”°ģ˜3(ģ˜ė¦¬ėŖ©ģ ģ˜ ꓑ고성 정볓 ģ „ģ†”ģ˜ ģœ„ķƒ 등)"]}],"description": "ź³„ģ•½ģ„œ, ķ˜‘ģ •ģ„œ, 낓부정책에 ėŖ…ģ‹œėœ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģš”źµ¬ģ‚¬ķ•­ģ— ė”°ė¼ ģ™øė¶€ģžģ˜ ė³“ķ˜øėŒ€ģ±… ģ“ķ–‰ 여부넼 ģ£¼źø°ģ ģø 점검 ė˜ėŠ” 감사 등 ź“€ė¦¬Ā·ź°ė…ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.3.4": {"name": "ģ™øė¶€ģž 계약 변경 ė° 만료 ģ‹œ ė³“ģ•ˆ","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.3.4 ģ™øė¶€ģž 계약 변경 ė° 만료 ģ‹œ ė³“ģ•ˆ","Subdomain": "2.3. ģ™øė¶€ģž ė³“ģ•ˆ","AuditEvidence": ["ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģ„œģ•½ģ„œ","ė¹„ė°€ģœ ģ§€ ķ™•ģ•½ģ„œ","정볓 ė° ź°œģøģ •ė³“ 파기 ķ™•ģ•½ģ„œ","ģ™øė¶€ģž 계약 ģ¢…ė£Œģ™€ ź“€ė Øėœ ė‚“ė¶€ ģ •ģ±…, 지침"],"AuditChecklist": ["ģ™øė¶€ģž ź³„ģ•½ė§Œė£Œ, 업묓 ģ¢…ė£Œ, ė‹“ė‹¹ģž 변경 ģ‹œ ź³µģ‹ģ ģø ģ ˆģ°Øģ— 따넸 ģ •ė³“ģžģ‚° ė°˜ė‚©, ģ •ė³“ģ‹œģŠ¤ķ…œ 접근계정 ģ‚­ģ œ, ė¹„ė°€ģœ ģ§€ ķ™•ģ•½ģ„œ 징구 ė“±ģ“ ģ“ė£Øģ–“ģ§ˆ 수 ģžˆė„ė” ė³“ģ•ˆėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ™øė¶€ģž 계약 만료 ģ‹œ ģœ„ķƒ 업묓와 ź“€ė Øķ•˜ģ—¬ ģ™øė¶€ģžź°€ ģ¤‘ģš”ģ •ė³“ ė° ź°œģøģ •ė³“ė„¼ ė³“ģœ ķ•˜ź³  ģžˆėŠ”ģ§€ ķ™•ģøķ•˜ź³  ģ“ė„¼ ķšŒģˆ˜Ā·ķŒŒźø°ķ•  수 ģžˆė„ė” 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ¼ė¶€ ģ •ė³“ģ‹œģŠ¤ķ…œģ—ģ„œ 계약 만료된 ģ™øė¶€ģžģ˜ 계정 ė° ź¶Œķ•œģ“ ģ‚­ģ œė˜ģ§€ ģ•Šź³  ģ”“ģž¬ķ•˜ėŠ” 경우","사딀 2 : ģ™øģ£¼ģš©ģ—­ģ‚¬ģ—… ģˆ˜ķ–‰ź³¼ģ •ģ—ģ„œ ģ¼ė¶€ ģš©ģ—­ģ—…ģ²“ ė‹“ė‹¹ģžź°€ źµģ²“ė˜ź±°ė‚˜ 계약 만료딜 ķ‡“ģ§ķ•˜ģ˜€ģœ¼ė‚˜, ꓀련 ģøė „ė“¤ģ— ėŒ€ķ•œ 퇓사 ģ‹œ ė³“ģ•ˆģ„œģ•½ģ„œ 등 ė‚“ė¶€ ź·œģ •ģ— 따넸 ģ”°ģ¹˜ź°€ ģ“ķ–‰ė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ź°œģøģ •ė³“ 처리 ģœ„ķƒķ•œ 업첓와 계약 ģ¢…ė£Œ ģ“ķ›„ ė³“ģœ ķ•˜ź³  ģžˆėŠ” ź°œģøģ •ė³“ė„¼ ķŒŒźø°ķ•˜ģ˜€ėŠ”ģ§€ 여부넼 ķ™•ģøĀ·ģ ź²€ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제26ģ”°(ģ—…ė¬“ģœ„ķƒģ— 따넸 ź°œģøģ •ė³“ģ˜ 처리 ģ œķ•œ)","ģ •ė³“ķ†µģ‹ ė§ė²• 제50ģ”°ģ˜3(ģ˜ė¦¬ėŖ©ģ ģ˜ ꓑ고성 정볓 ģ „ģ†”ģ˜ ģœ„ķƒ 등)"]}],"description": "ģ™øė¶€ģž ź³„ģ•½ė§Œė£Œ, ģ—…ė¬“ģ¢…ė£Œ, ė‹“ė‹¹ģž 변경 ģ‹œģ—ėŠ” ģ œź³µķ•œ ģ •ė³“ģžģ‚° ė°˜ė‚©, ģ •ė³“ģ‹œģŠ¤ķ…œ 접근계정 ģ‚­ģ œ, ģ¤‘ģš”ģ •ė³“ 파기, 업묓 ģˆ˜ķ–‰ 중 ģ·Øė“ģ •ė³“ģ˜ ė¹„ė°€ģœ ģ§€ ķ™•ģ•½ģ„œ 징구 ė“±ģ˜ ė³“ķ˜øėŒ€ģ±…ģ„ ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.1": {"name": "ė³“ķ˜øźµ¬ģ—­ 지정","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.4.1 ė³“ķ˜øźµ¬ģ—­ 지정","Subdomain": "2.4. 물리 ė³“ģ•ˆ","AuditEvidence": ["물리적 ė³“ģ•ˆ 지침(ė³“ķ˜øźµ¬ģ—­ 지정 기준)","ė³“ķ˜øźµ¬ģ—­ 지정 ķ˜„ķ™©","ė³“ķ˜øźµ¬ģ—­ ķ‘œģ‹œ","ė³“ķ˜øźµ¬ģ—­ė³„ ė³“ķ˜øėŒ€ģ±… ķ˜„ķ™©"],"AuditChecklist": ["ė¬¼ė¦¬ģ Ā·ķ™˜ź²½ģ  ģœ„ķ˜‘ģœ¼ė”œė¶€ķ„° ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“, ė¬øģ„œ, ģ €ģž„ė§¤ģ²“, ģ£¼ģš” 설비 ė° ģ‹œģŠ¤ķ…œ ė“±ģ„ ė³“ķ˜øķ•˜źø° ģœ„ķ•˜ģ—¬ ķ†µģ œźµ¬ģ—­, ģ œķ•œźµ¬ģ—­, 접견구역 등 물리적 ė³“ķ˜øźµ¬ģ—­ ģ§€ģ •źø°ģ¤€ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","물리적 ė³“ķ˜øźµ¬ģ—­ 지정기준에 ė”°ė¼ ė³“ķ˜øźµ¬ģ—­ģ„ ģ§€ģ •ķ•˜ź³  구역별 ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ ė¬¼ė¦¬ė³“ģ•ˆ ģ§€ģ¹Øģ—ėŠ” ź°œģøģ •ė³“ ė³“ź“€ģ‹œģ„¤ ė° ģ‹œģŠ¤ķ…œ źµ¬ģ—­ģ„ ķ†µģ œźµ¬ģ—­ģœ¼ė”œ ģ§€ģ •ķ•œė‹¤ź³  ėŖ…ģ‹œė˜ģ–“ ģžˆģœ¼ė‚˜, 멤버십 ź°€ģž…ģ‹ ģ²­ ģ„œė„˜ź°€ ė³“ź“€ė˜ģ–“ ģžˆėŠ” ė¬øģ„œź³  등 ģ¼ė¶€ ėŒ€ģƒ źµ¬ģ—­ģ“ ķ†µģ œźµ¬ģ—­ģ—ģ„œ ėˆ„ė½ėœ 경우","사딀 2 : ė‚“ė¶€ ė¬¼ė¦¬ė³“ģ•ˆ 지침에 ķ†µģ œźµ¬ģ—­ģ— ėŒ€ķ•“ģ„œėŠ” ģ§€ģ •ėœ ģ–‘ģ‹ģ˜ ķ†µģ œźµ¬ģ—­ ķ‘œģ§€ķŒģ„ ģ„¤ģ¹˜ķ•˜ė„ė” ėŖ…ģ‹œķ•˜ź³  ģžˆģœ¼ė‚˜, ģ¼ė¶€ ķ†µģ œźµ¬ģ—­ģ— ķ‘œģ‹œķŒģ„ ģ„¤ģ¹˜ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제10ģ”°(물리적 ģ•ˆģ „ģ”°ģ¹˜)"]}],"description": "ė¬¼ė¦¬ģ Ā·ķ™˜ź²½ģ  ģœ„ķ˜‘ģœ¼ė”œė¶€ķ„° ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“, ė¬øģ„œ, ģ €ģž„ė§¤ģ²“, ģ£¼ģš” 설비 ė° ģ‹œģŠ¤ķ…œ ė“±ģ„ ė³“ķ˜øķ•˜źø° ģœ„ķ•˜ģ—¬ ķ†µģ œźµ¬ģ—­Ā·ģ œķ•œźµ¬ģ—­Ā·ģ ‘ź²¬źµ¬ģ—­ 등 물리적 ė³“ķ˜øźµ¬ģ—­ģ„ ģ§€ģ •ķ•˜ź³  구역별 ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.2": {"name": "ģ¶œģž…ķ†µģ œ","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.4.2 ģ¶œģž…ķ†µģ œ","Subdomain": "2.4. 물리 ė³“ģ•ˆ","AuditEvidence": ["ģ¶œģž… ź“€ė¦¬ėŒ€ģž„ ė° ģ¶œģž…ė”œź·ø","ģ¶œģž… ė“±ė” ģ‹ ģ²­ģ„œ ė° ģŠ¹ģø ė‚“ģ—­","ģ¶œģž…źø°ė” ź²€ķ† ģ„œ","ģ¶œģž…ķ†µģ œģ‹œģŠ¤ķ…œ ꓀리화멓(ģ¶œģž…ģž ė“±ė” ķ˜„ķ™© 등)"],"AuditChecklist": ["ė³“ķ˜øźµ¬ģ—­ģ€ ģ¶œģž…ģ ˆģ°Øģ— ė”°ė¼ ģ¶œģž…ģ“ ķ—ˆź°€ėœ ģžė§Œ ģ¶œģž…ķ•˜ė„ė” ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?","각 ė³“ķ˜øźµ¬ģ—­ģ— ėŒ€ķ•œ ė‚“Ā·ģ™øė¶€ģž ģ¶œģž…źø°ė”ģ„ ģ¼ģ •źø°ź°„ ė³“ģ”“ķ•˜ź³  ģ¶œģž…źø°ė” ė° ģ¶œģž…ź¶Œķ•œģ„ 주기적으딜 ź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķ†µģ œźµ¬ģ—­ģ„ ģ •ģ˜ķ•˜ģ—¬ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ģ¶œģž… ź°€ėŠ„ķ•œ ģž„ģ§ģ›ģ„ ź“€ė¦¬ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ¶œģž…źø°ė”ģ„ 주기적으딜 ź²€ķ† ķ•˜ģ§€ ģ•Šģ•„ 퇓직, ģ „ė°° 등에 따넸 ģž„źø° ėÆøģ¶œģž…ģžź°€ ė‹¤ģˆ˜ ģ”“ģž¬ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : 전산실, ė¬øģ„œź³  등 ķ†µģ œźµ¬ģ—­ģ— ģ¶œģž…ķ†µģ œ ģž„ģ¹˜ź°€ ģ„¤ģ¹˜ė˜ģ–“ ģžˆģœ¼ė‚˜, ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ė˜ėŠ” ģŠ¹ģø ģ—†ģ“ ģž„ģ‹œź°„ 개방 상태딜 ģœ ģ§€ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : ģ¼ė¶€ 외부 ķ˜‘ė „ģ—…ģ²“ ģ§ģ›ģ—ź²Œ ź³¼ė„ķ•˜ź²Œ ģ „ źµ¬ģ—­ģ„ ģƒģ‹œ ģ¶œģž…ķ•  수 ģžˆėŠ” ģ¶œģž…ģ¹“ė“œė„¼ ė¶€ģ—¬ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제10ģ”°(물리적 ģ•ˆģ „ģ”°ģ¹˜)"]}],"description": "ė³“ķ˜øźµ¬ģ—­ģ€ ģøź°€ėœ ģ‚¬ėžŒė§Œģ“ ģ¶œģž…ķ•˜ė„ė” ķ†µģ œķ•˜ź³  ģ±…ģž„ģ¶”ģ ģ„±ģ„ 확볓할 수 ģžˆė„ė” ģ¶œģž… ė° ģ ‘ź·¼ ģ“ė „ģ„ 주기적으딜 ź²€ķ† ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.3": {"name": "ģ •ė³“ģ‹œģŠ¤ķ…œ 볓호","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.4.3 ģ •ė³“ģ‹œģŠ¤ķ…œ 볓호","Subdomain": "2.4. 물리 ė³“ģ•ˆ","AuditEvidence": ["ģ •ė³“ģ²˜ė¦¬ģ‹œģ„¤ ė„ė©“","ģ •ė³“ģ‹œģŠ¤ķ…œ ė°°ģ¹˜ė„","ģžģ‚°ėŖ©ė”"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ¤‘ģš”ė„, ģš©ė„, ķŠ¹ģ„± ė“±ģ„ ź³ ė ¤ķ•˜ģ—¬ 배치 ģž„ģ†Œė„¼ ė¶„ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ‹¤ģ œ 물리적 ģœ„ģ¹˜ė„¼ ģ†ģ‰½ź²Œ ķ™•ģøķ•  수 ģžˆėŠ” ė°©ģ•ˆģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","ģ „ė „ ė° ķ†µģ‹ ģ¼€ģ“ėø”ģ„ ģ™øė¶€ė”œė¶€ķ„°ģ˜ 물리적 ģ†ģƒ ė° 전기적 ģ˜ķ–„ģœ¼ė”œė¶€ķ„° ģ•ˆģ „ķ•˜ź²Œ ė³“ķ˜øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ‹œģŠ¤ķ…œ ė°°ģ¹˜ė„ź°€ ģµœģ‹  ė³€ź²½ģ‚¬ķ•­ģ„ ė°˜ģ˜ķ•˜ģ—¬ ģ—…ė°ģ“ķŠøė˜ģ§€ ģ•Šģ•„ ģž„ģ• ź°€ ė°œģƒėœ ģ •ė³“ģ‹œģŠ¤ķ…œģ„ ģ‹ ģ†ķ•˜ź²Œ ķ™•ģøķ•  수 ģ—†ėŠ” 경우","사딀 2 : ģ„œė²„ģ‹¤ 바닄 ė˜ėŠ” ėž™ģ— ė§Žģ€ ģ¼€ģ“ėø”ģ“ ģ •ė¦¬ė˜ģ§€ ģ•Šź³  ė’¤ģ—‰ģ¼œ ģžˆģ–“ ģ „źø°ģ ģœ¼ė”œ ź°„ģ„­, ģ†ģƒ, ėˆ„ģˆ˜, ė¶€ģ£¼ģ˜ 등에 ģ˜ķ•œ ģž„ģ•  ė°œģƒģ“ ģš°ė ¤ė˜ėŠ” 경우"],"RelatedRegulations": []}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œģ€ ķ™˜ź²½ģ  ģœ„ķ˜‘ź³¼ ģœ ķ•“ģš”ģ†Œ, ė¹„ģøź°€ ģ ‘ź·¼ ź°€ėŠ„ģ„±ģ„ ź°ģ†Œģ‹œķ‚¬ 수 ģžˆė„ė” ģ¤‘ģš”ė„ģ™€ ķŠ¹ģ„±ģ„ ź³ ė ¤ķ•˜ģ—¬ ė°°ģ¹˜ķ•˜ź³ , 통신 ė° ģ „ė „ ģ¼€ģ“ėø”ģ“ ģ†ģƒģ„ ģž…ģ§€ ģ•Šė„ė” ė³“ķ˜øķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.4": {"name": "ė³“ķ˜øģ„¤ė¹„ 욓영","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.4.4 ė³“ķ˜øģ„¤ė¹„ 욓영","Subdomain": "2.4. 물리 ė³“ģ•ˆ","AuditEvidence": ["물리적 ė³“ģ•ˆ 지침(ė³“ķ˜øģ„¤ė¹„ ꓀련)","전산실 설비 ķ˜„ķ™© ė° ģ ź²€ķ‘œ","IDC ģœ„ķƒģš“ģ˜ ź³„ģ•½ģ„œ, SLA 등"],"AuditChecklist": ["각 ė³“ķ˜øźµ¬ģ—­ģ˜ ģ¤‘ģš”ė„ ė° ķŠ¹ģ„±ģ— ė”°ė¼ ķ™”ģž¬, ģˆ˜ķ•“, ģ „ė „ ģ“ģƒ 등 ģøģž¬ ė° ģžģ—°ģž¬ķ•“ 등에 ėŒ€ė¹„ķ•˜ģ—¬ ķ•„ģš”ķ•œ 설비넼 갖추고 욓영절차넼 ģˆ˜ė¦½ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","외부 ģ§‘ģ ģ •ė³“ķ†µģ‹ ģ‹œģ„¤(IDC)에 ģœ„ķƒ ģš“ģ˜ķ•˜ėŠ” 경우 물리적 ė³“ķ˜øģ— ķ•„ģš”ķ•œ ģš”źµ¬ģ‚¬ķ•­ģ„ ź³„ģ•½ģ„œģ— ė°˜ģ˜ķ•˜ź³  욓영상태넼 주기적으딜 ź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 본사 전산실 등 ģ¼ė¶€ ė³“ķ˜øźµ¬ģ—­ģ— ė‚“ė¶€ 지침에 ģ •ķ•œ ė³“ķ˜øģ„¤ė¹„ė„¼ 갖추고 ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : 전산실 낓에 UPS, ģ†Œķ™”ģ„¤ė¹„ ė“±ģ˜ ė³“ķ˜øģ„¤ė¹„ėŠ” 갖추고 ģžˆģœ¼ė‚˜, ꓀련 설비에 ėŒ€ķ•œ 욓영 ė° 점검 źø°ģ¤€ģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģš“ģ˜ģ§€ģ¹Øģ— ė”°ė¼ 전산실 낓에 ģ˜ØĀ·ģŠµė„ 씰절기넼 ģ„¤ģ¹˜ķ•˜ģ˜€ģœ¼ė‚˜, ģš©ėŸ‰ ė¶€ģ”±ģœ¼ė”œ ģøķ•˜ģ—¬ ķ‘œģ¤€ ģ˜ØĀ·ģŠµė„ė„¼ ģœ ģ§€ķ•˜ģ§€ ėŖ»ķ•˜ģ—¬ ģž„ģ• ė°œģƒ ź°€ėŠ„ģ„±ģ“ ė†’ģ€ 경우"],"RelatedRegulations": ["ģ •ė³“ķ†µģ‹ ė§ė²• 제46ģ”°(ģ§‘ģ ėœ ģ •ė³“ķ†µģ‹ ģ‹œģ„¤ģ˜ 볓호)","집적정볓 ķ†µģ‹ ģ‹œģ„¤ ė³“ķ˜øģ§€ģ¹Ø","ģ†Œė°©ģ‹œģ„¤ ģ„¤ģ¹˜ ė° ꓀리에 ź“€ķ•œ 법넠(ģ†Œė°©ģ‹œģ„¤ė²•) 제12ģ”°(ķŠ¹ģ •ģ†Œė°©ėŒ€ģƒė¬¼ģ— ģ„¤ģ¹˜ķ•˜ėŠ” ģ†Œė°©ģ‹œģ„¤ģ˜ ꓀리 등), 제16ģ”°(ķ”¼ė‚œģ‹œģ„¤, 방화구역 ė° ė°©ķ™”ģ‹œģ„¤ģ˜ ꓀리)"]}],"description": "ė³“ķ˜øźµ¬ģ—­ģ— ģœ„ģ¹˜ķ•œ ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ¤‘ģš”ė„ ė° ķŠ¹ģ„±ģ— ė”°ė¼ ģ˜ØĀ·ģŠµė„ 씰절, ķ™”ģž¬ź°ģ§€, ģ†Œķ™”ģ„¤ė¹„, ėˆ„ģˆ˜ź°ģ§€, UPS, ė¹„ģƒė°œģ „źø°, ģ“ģ¤‘ģ „ģ›ģ„  ė“±ģ˜ ė³“ķ˜øģ„¤ė¹„ė„¼ 갖추고 욓영절차넼 ģˆ˜ė¦½Ā·ģš“ģ˜ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.5": {"name": "ė³“ķ˜øźµ¬ģ—­ ė‚“ ģž‘ģ—…","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.4.5 ė³“ķ˜øźµ¬ģ—­ ė‚“ ģž‘ģ—…","Subdomain": "2.4. 물리 ė³“ģ•ˆ","AuditEvidence": ["ģž‘ģ—… ģ‹ ģ²­ģ„œ, ģž‘ģ—… ģ¼ģ§€","ķ†µģ œźµ¬ģ—­ ģ¶œģž… ėŒ€ģž„","ķ†µģ œźµ¬ģ—­ģ— ėŒ€ķ•œ ģ¶œģž…źø°ė” ė° ģž‘ģ—… źø°ė” 검토 ė‚“ģ—­"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ė„ģž…, ģœ ģ§€ė³“ģˆ˜ ė“±ģœ¼ė”œ ė³“ķ˜øźµ¬ģ—­ ė‚“ ģž‘ģ—…ģ“ ķ•„ģš”ķ•œ ź²½ģš°ģ— ėŒ€ķ•œ ź³µģ‹ģ ģø ģž‘ģ—…ģ‹ ģ²­ ė° ģˆ˜ķ–‰ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ķ˜øźµ¬ģ—­ ė‚“ ģž‘ģ—…ģ“ ķ†µģ œ ģ ˆģ°Øģ— ė”°ė¼ ģ ģ ˆķžˆ ģˆ˜ķ–‰ė˜ģ—ˆėŠ”ģ§€ 여부넼 ķ™•ģøķ•˜źø° ģœ„ķ•˜ģ—¬ ģž‘ģ—… źø°ė”ģ„ 주기적으딜 ź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 전산실 ģ¶œģž…ė”œź·øģ—ėŠ” 외부 ģœ ģ§€ė³“ģˆ˜ 업첓 ģ§ģ›ģ˜ ģ¶œģž…źø°ė”ģ“ 남아 ģžˆģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•œ ė³“ķ˜øźµ¬ģ—­ ģž‘ģ—… ģ‹ ģ²­ ė° ģŠ¹ģø ė‚“ģ—­ģ“ ģ”“ģž¬ķ•˜ģ§€ ģ•Šģ€ 경우(ė‚“ė¶€ ź·œģ •ģ— 따넸 ė³“ķ˜øźµ¬ģ—­ ģž‘ģ—… ģ‹ ģ²­ ģ—†ģ“ ė³“ķ˜øźµ¬ģ—­ ģ¶œģž… ė° ģž‘ģ—…ģ“ ģ“ė£Øģ–“ģ§€ź³  ģžˆėŠ” 경우)","사딀 2 : ė‚“ė¶€ ź·œģ •ģ—ėŠ” ė³“ķ˜øźµ¬ģ—­ ė‚“ ģž‘ģ—… źø°ė”ģ— ėŒ€ķ•˜ģ—¬ 분기별 1회 ģ“ģƒ ģ ź²€ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ķŠ¹ė³„ķ•œ ģ‚¬ģœ  ģ—†ģ“ ģž„źø°ź°„ ė™ģ•ˆ ė³“ķ˜øźµ¬ģ—­ ė‚“ ģž‘ģ—… źø°ė”ģ— ėŒ€ķ•œ ģ ź²€ģ“ ģ“ė£Øģ–“ģ§€ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ė³“ķ˜øźµ¬ģ—­ ė‚“ģ—ģ„œģ˜ ė¹„ģøź°€ķ–‰ģœ„ ė° ź¶Œķ•œ ģ˜¤Ā·ė‚Øģš© ė“±ģ„ ė°©ģ§€ķ•˜źø° ģœ„ķ•œ ģž‘ģ—… 절차넼 수립 ė°ģ“ķ–‰ķ•˜ź³ , ģž‘ģ—… źø°ė”ģ„ 주기적으딜 ź²€ķ† ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.6": {"name": "ė°˜ģ¶œģž… źø°źø° ķ†µģ œ","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.4.6 ė°˜ģ¶œģž… źø°źø° ķ†µģ œ","Subdomain": "2.4. 물리 ė³“ģ•ˆ","AuditEvidence": ["ė³“ķ˜øźµ¬ģ—­ ė‚“ ė°˜ģ¶œģž… ģ‹ ģ²­ģ„œ","ė°˜ģ¶œģž… ź“€ė¦¬ėŒ€ģž„","ė°˜ģ¶œģž… ģ“ė „ 검토 ź²°ź³¼"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œ, ėŖØė°”ģ¼ źø°źø°, ģ €ģž„ė§¤ģ²“ ė“±ģ„ ė³“ķ˜øźµ¬ģ—­ģ— ė°˜ģž…ķ•˜ź±°ė‚˜ ė°˜ģ¶œķ•˜ėŠ” 경우 ģ •ė³“ģœ ģ¶œ, ģ•…ģ„±ģ½”ė“œ 감염 등 ė³“ģ•ˆģ‚¬ź³  ģ˜ˆė°©ģ„ ģœ„ķ•œ ķ†µģ œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ė°˜ģ¶œģž… ķ†µģ œģ ˆģ°Øģ— 따넸 źø°ė”ģ„ ģœ ģ§€Ā·ź“€ė¦¬ķ•˜ź³ , 절차 ģ¤€ģˆ˜ 여부넼 ķ™•ģøķ•  수 ģžˆė„ė” ė°˜ģ¶œģž… ģ“ė „ģ„ 주기적으딜 ģ ź²€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ“ė™ģ»“ķ“ØķŒ…źø°źø° ė°˜ģ¶œģž…ģ— ėŒ€ķ•œ ķ†µģ œ 절차넼 ģˆ˜ė¦½ķ•˜ź³  ģžˆģœ¼ė‚˜, ķ†µģ œźµ¬ģ—­ ė‚“ ģ“ė™ģ»“ķ“ØķŒ…źø°źø° ė°˜ģž…ģ— ėŒ€ķ•œ ķ†µģ œė„¼ ķ•˜ź³  ģžˆģ§€ ģ•Šģ•„ ģ¶œģž…ģ“ ķ—ˆģš©ėœ ė‚“Ā·ģ™øė¶€ģøģ“ ģ“ė™ģ»“ķ“ØķŒ…źø°źø°ė„¼ ģ œģ•½ ģ—†ģ“ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : ė‚“ė¶€ 지침에 ė”°ė¼ ģ „ģ‚°ģž„ė¹„ ė°˜ģ¶œģž…ģ“ ģžˆėŠ” 경우 ģž‘ģ—…ź³„ķšģ„œģ— ė°˜ģ¶œģž… ė‚“ģš©ģ„ źø°ģž¬ķ•˜ź³  ꓀리 ģ±…ģž„ģžģ˜ ģ„œėŖ…ģ„ ė°›ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ģž‘ģ—…ź³„ķšģ„œģ˜ ė°˜ģ¶œģž… źø°ė”ģ— ź“€ė¦¬ģ±…ģž„ģžģ˜ ģ„œėŖ…ģ“ ė‹¤ģˆ˜ ėˆ„ė½ė˜ģ–“ ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제10ģ”°(물리적 ģ•ˆģ „ģ”°ģ¹˜)"]}],"description": "ė³“ķ˜øźµ¬ģ—­ ė‚“ ģ •ė³“ģ‹œģŠ¤ķ…œ, ėŖØė°”ģ¼ źø°źø°, ģ €ģž„ė§¤ģ²“ 등에 ėŒ€ķ•œ ė°˜ģ¶œģž… ķ†µģ œģ ˆģ°Øė„¼ 수립 ė°ģ“ķ–‰ķ•˜ź³  주기적으딜 ź²€ķ† ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.4.7": {"name": "ģ—…ė¬“ķ™˜ź²½ ė³“ģ•ˆ","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.4.7 ģ—…ė¬“ķ™˜ź²½ ė³“ģ•ˆ","Subdomain": "2.4. 물리 ė³“ģ•ˆ","AuditEvidence": ["사묓실 ė° ź³µģš©ź³µź°„ ė³“ģ•ˆģ ź²€ ė³“ź³ ģ„œ","사묓실 ė° ź³µģš©ź³µź°„ ė³“ģ•ˆģ ź²€ķ‘œ","ėÆøģ¤€ģˆ˜ģžģ— ėŒ€ķ•œ 씰치 사항(교윔, 상벌 등)","ģ¶œė „Ā·ė³µģ‚¬ė¬¼ 볓호씰치 ķ˜„ķ™©"],"AuditChecklist": ["ė¬øģ„œź³ , 공용 PC, 복합기, ķŒŒģ¼ģ„œė²„ 등 공용으딜 ģ‚¬ģš©ķ•˜ėŠ” ģ‹œģ„¤ ė° ģ‚¬ė¬“ģš© 기기에 ėŒ€ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ—…ė¬“ģš© PC, ģ±…ģƒ, ģ„œėž 등 ź°œģøģ—…ė¬“ ķ™˜ź²½ģ„ ķ†µķ•œ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ˜ ģœ Ā·ė…øģ¶œģ„ ė°©ģ§€ķ•˜źø° ģœ„ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ź°€ ķ¬ķ•Øėœ ģ¢…ģ“ ģøģ‡„ė¬¼ 등 ź°œģøģ •ė³“ģ˜ ģ¶œė „Ā·ė³µģ‚¬ė¬¼ģ„ ģ•ˆģ „ķ•˜ź²Œ ź“€ė¦¬ķ•˜źø° ģœ„ķ•“ ķ•„ģš”ķ•œ 볓호씰치넼 ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģø ė° ź³µģš©ģ—…ė¬“ ķ™˜ź²½ģ—ģ„œģ˜ ģ •ė³“ė³“ķ˜ø ģ¤€ģˆ˜ 여부넼 주기적으딜 ź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ„œ ė‚“ ź°œģøģ •ė³“ė³“ķ˜øė„¼ ģœ„ķ•œ ģƒķ™œė³“ģ•ˆ 점검(ķ“ė¦°ė°ģŠ¤ķ¬ 욓영 등)ģ„ ģ •źø°ģ ģœ¼ė”œ ģˆ˜ķ–‰ķ•˜ė„ė” ėŖ…ģ‹œķ•˜ź³  ģžˆģœ¼ė‚˜, ģ“ė„¼ ģ“ķ–‰ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : 멤버십 ź°€ģž…ģ‹ ģ²­ģ„œ 등 ź°œģøģ •ė³“ź°€ ķ¬ķ•Øėœ ģ„œė„˜ė„¼ ģž źøˆģž„ģ¹˜ź°€ ģ—†ėŠ” 사묓실 ė¬øģ„œķ•Øģ— ė³“ź“€ķ•œ 경우","사딀 3 : ģ§ģ›ė“¤ģ˜ 컓퓨터 ķ™”ė©“ė³“ķ˜øźø° ė° ķŒØģŠ¤ģ›Œė“œź°€ ģ„¤ģ •ė˜ģ–“ ģžˆģ§€ ģ•Šź³ , ķœ“ź°€ģž ģ±…ģƒ ģœ„ģ— ģ¤‘ģš”ė¬øģ„œź°€ ģž„źø°ź°„ ė°©ģ¹˜ė˜ģ–“ ģžˆėŠ” 경우","사딀 4 : ķšŒģ˜ģ‹¤ 등 공용 사묓 공간에 ģ„¤ģ¹˜ėœ 공용PC에 ėŒ€ķ•œ ė³“ķ˜øėŒ€ģ±…ģ“ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ•„ ź°œģøģ •ė³“ź°€ ķ¬ķ•Øėœ ķŒŒģ¼ģ“ ģ•”ķ˜øķ™”ė˜ģ§€ ģ•Šģ€ ģ±„ė”œ ģ €ģž„ė˜ģ–“ ģžˆź±°ė‚˜, ė³“ģ•ˆ ģ—…ė°ģ“ķŠø 미적용, 백신 ėÆøģ„¤ģ¹˜ 등 ģ·Øģ•½ķ•œ 상태딜 ģœ ģ§€ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제10ģ”°(물리적 ģ•ˆģ „ģ”°ģ¹˜), 제12ģ”°(ģ¶œė „Ā·ė³µģ‚¬ģ‹œ ģ•ˆģ „ģ”°ģ¹˜)"]}],"description": "공용으딜 ģ‚¬ģš©ķ•˜ėŠ” ģ‚¬ė¬“ģš© źø°źø°(ė¬øģ„œź³ , 공용 PC, 복합기, ķŒŒģ¼ģ„œė²„ 등) ė° ź°œģø ģ—…ė¬“ķ™˜ź²½(ģ—…ė¬“ģš© PC, ģ±…ģƒ 등)ģ„ ķ†µķ•˜ģ—¬ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ź°€ ė¹„ģøź°€ģžģ—ź²Œ ė…øģ¶œ ė˜ėŠ” ģœ ģ¶œė˜ģ§€ ģ•Šė„ė” ķ“ė¦°ė°ģŠ¤ķ¬, 정기점검 등 ģ—…ė¬“ķ™˜ź²½ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.5.1": {"name": "ģ‚¬ģš©ģž 계정 ꓀리","checks": {"iam_user_accesskey_unused": null,"iam_securityaudit_role_created": null,"iam_user_console_access_unused": null,"iam_policy_no_full_access_to_kms": null,"iam_role_administratoraccess_policy": null,"iam_user_administrator_access_policy": null,"organizations_scp_check_deny_regions": null,"iam_group_administrator_access_policy": null,"iam_policy_allows_privilege_escalation": null,"iam_inline_policy_no_full_access_to_kms": null,"iam_policy_no_full_access_to_cloudtrail": null,"iam_policy_attached_only_to_group_or_roles": null,"cognito_user_pool_self_registration_disabled": null,"iam_role_cross_account_readonlyaccess_policy": null,"iam_inline_policy_allows_privilege_escalation": null,"iam_inline_policy_no_administrative_privileges": null,"iam_inline_policy_no_full_access_to_cloudtrail": null,"iam_no_custom_policy_permissive_role_assumption": null,"iam_role_cross_service_confused_deputy_prevention": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"iam_customer_unattached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.5.1 ģ‚¬ģš©ģž 계정 ꓀리","Subdomain": "2.5. ģøģ¦ ė° ź¶Œķ•œź“€ė¦¬","AuditEvidence": ["ģ‚¬ģš©ģž 계정 ė° ź¶Œķ•œ ģ‹ ģ²­ģ„œ","ģ‚¬ģš©ģž 계정 ė° ź¶Œķ•œ ź“€ė¦¬ėŒ€ģž„ ė˜ėŠ” 화멓","ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œė³„ ģ ‘ź·¼ź¶Œķ•œ ė¶„ė„˜ķ‘œ","ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œė³„ ģ‚¬ģš©ģž, ź“€ė¦¬ģž, ź°œģøģ •ė³“ģ·Øźø‰ģž ėŖ©ė”"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œź³¼ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ— 접근할 수 ģžˆėŠ” ģ‚¬ģš©ģž 계정 ė° ģ ‘ź·¼ź¶Œķ•œģ˜ ė“±ė”Ā·ė³€ź²½Ā·ģ‚­ģ œģ— ź“€ķ•œ ź³µģ‹ģ ģø 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œź³¼ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ— 접근할 수 ģžˆėŠ” ģ‚¬ģš©ģž 계정 ė° ģ ‘ź·¼ź¶Œķ•œ ģƒģ„± ė° ė“±ė”Ā·ė³€ź²½ ģ‹œ 직묓별 ģ ‘ź·¼ź¶Œķ•œ ė¶„ė„˜ 첓계에 ė”°ė¼ ģ—…ė¬“ģƒ ķ•„ģš”ķ•œ ģµœģ†Œķ•œģ˜ ź¶Œķ•œė§Œģ„ ė¶€ģ—¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ‚¬ģš©ģžģ—ź²Œ 계정 ė° ģ ‘ź·¼ź¶Œķ•œģ„ ė¶€ģ—¬ķ•˜ėŠ” 경우 핓당 계정에 ėŒ€ķ•œ ė³“ģ•ˆģ±…ģž„ģ“ ė³øģøģ—ź²Œ ģžˆģŒģ„ ėŖ…ķ™•ķžˆ ģøģ‹ģ‹œķ‚¤ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ‚¬ģš©ģž ė° ź°œģøģ •ė³“ģ·Øźø‰ģžģ— ėŒ€ķ•œ ź³„ģ •Ā·ź¶Œķ•œģ— ėŒ€ķ•œ ģ‚¬ģš©ģž ė“±ė”, ķ•“ģ§€ ė° ģŠ¹ģøģ ˆģ°Ø ģ—†ģ“ 구두 ģš”ģ²­, ģ“ė©”ģ¼ ė“±ģœ¼ė”œ ģ²˜ė¦¬ķ•˜ģ—¬ ģ“ģ— ėŒ€ķ•œ ģŠ¹ģø ė° 처리 ģ“ė „ģ“ ķ™•ģøė˜ģ§€ ģ•ŠėŠ” 경우","사딀 2 : ź°œģøģ •ė³“ģ·Øźø‰ģžź°€ ķœ“ź°€, ģ¶œģž„, 공가 등에 따넸 업묓 ė°±ģ—…ģ„ ģ‚¬ģœ ė”œ ź³µģ‹ģ ģø 절차넼 ź±°ģ¹˜ģ§€ ģ•Šź³  ź°œģøģ •ė³“ģ·Øźø‰ģžė”œ ģ§€ģ •ė˜ģ§€ ģ•Šģ€ ģøģ›ģ—ź²Œ ź°œģøģ •ė³“ģ·Øźø‰ģž ź³„ģ •ģ„ ģ•Œė ¤ģ£¼ėŠ” 경우","사딀 3 : ģ •ė³“ģ‹œģŠ¤ķ…œ ė˜ėŠ” ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ģ‚¬ģš©ģžģ—ź²Œ ķ•„ģš” ģ“ģƒģ˜ ź³¼ė„ķ•œ ź¶Œķ•œģ„ ė¶€ģ—¬ķ•˜ģ—¬ ģ—…ė¬“ģƒ ė¶ˆķ•„ģš”ķ•œ 정볓 ė˜ėŠ” ź°œģøģ •ė³“ģ— ģ ‘ź·¼ģ“ ź°€ėŠ„ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ ź¶Œķ•œģ˜ ꓀리)"]}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œź³¼ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ— ėŒ€ķ•œ ė¹„ģøź°€ ģ ‘ź·¼ģ„ ķ†µģ œķ•˜ź³  업묓 목적에 따넸 ģ ‘ź·¼ź¶Œķ•œģ„ ģµœģ†Œķ•œģœ¼ė”œ 부여할 수 ģžˆė„ė” ģ‚¬ģš©ģž ė“±ė”Ā·ķ•“ģ§€ ė° ģ ‘ź·¼ź¶Œķ•œ ė¶€ģ—¬Ā·ė³€ź²½Ā·ė§ģ†Œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ , ģ‚¬ģš©ģž ė“±ė” ė° ź¶Œķ•œė¶€ģ—¬ ģ‹œ ģ‚¬ģš©ģžģ—ź²Œ ė³“ģ•ˆģ±…ģž„ģ“ ģžˆģŒģ„ ź·œģ •ķ™”ķ•˜ź³  ģøģ‹ģ‹œģ¼œģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 22,"manual": 0}},"2.5.2": {"name": "ģ‚¬ģš©ģž ģ‹ė³„","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.5.2 ģ‚¬ģš©ģž ģ‹ė³„","Subdomain": "2.5. ģøģ¦ ė° ź¶Œķ•œź“€ė¦¬","AuditEvidence": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ė”œź·øģø 화멓","ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ź“€ė¦¬ģž, ģ‚¬ģš©ģž, ź°œģøģ •ė³“ģ·Øźø‰ģž 계정 ėŖ©ė”","ģ˜ˆģ™ø ģ²˜ė¦¬ģ— ėŒ€ķ•œ ģŠ¹ģø ė‚“ģ—­"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ—ģ„œ ģ‚¬ģš©ģž ė° ź°œģøģ •ė³“ģ·Øźø‰ģžė„¼ ģœ ģ¼ķ•˜ź²Œ 구분할 수 ģžˆėŠ” ģ‹ė³„ģžė„¼ ķ• ė‹¹ķ•˜ź³  추츔 ź°€ėŠ„ķ•œ ģ‹ė³„ģžģ˜ ģ‚¬ģš©ģ„ ģ œķ•œķ•˜ź³  ģžˆėŠ”ź°€?","ė¶ˆź°€ķ”¼ķ•œ ģ‚¬ģœ ė”œ ė™ģ¼ķ•œ ģ‹ė³„ģžė„¼ ź³µģœ ķ•˜ģ—¬ ģ‚¬ģš©ķ•˜ėŠ” 경우 ź·ø ģ‚¬ģœ ģ™€ ķƒ€ė‹¹ģ„±ģ„ ź²€ķ† ķ•˜ź³  ė³“ģ™„ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ģ—¬ ģ±…ģž„ģžģ˜ ģŠ¹ģøģ„ 받고 ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ģ‹œģŠ¤ķ…œ(ģ„œė²„, ė„¤ķŠøģ›Œķ¬, ģ¹Øģž…ģ°Øė‹Øģ‹œģŠ¤ķ…œ, DBMS 등)ģ˜ 계정 ķ˜„ķ™©ģ„ ķ™•ģøķ•œ ź²°ź³¼, ģ œģ”°ģ‚¬ģ—ģ„œ ģ œź³µķ•˜ėŠ” źø°ė³ø ź“€ė¦¬ģž ź³„ģ •ģ„ 기술적으딜 변경 ź°€ėŠ„ķ•Øģ—ė„ ė¶ˆźµ¬ķ•˜ź³  ė³€ź²½ķ•˜ģ§€ ģ•Šź³  ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : ź°œė°œģžź°€ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ź³„ģ •ģ„ 공용으딜 ģ‚¬ģš©ķ•˜ź³  ģžˆģœ¼ė‚˜, ķƒ€ė‹¹ģ„± 검토 ė˜ėŠ” ģ±…ģž„ģžģ˜ ģŠ¹ģø ė“±ģ“ ģ—†ģ“ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : ģ™øė¶€ģ§ģ›ģ“ ģœ ģ§€ė³“ģˆ˜ķ•˜ź³  ģžˆėŠ” ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģš“ģ˜ź³„ģ •ģ„ ė³„ė„ģ˜ ģŠ¹ģø 절차 ģ—†ģ“ ź°œģø ź³„ģ •ģ²˜ėŸ¼ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ ź¶Œķ•œģ˜ ꓀리)"]}],"description": "ģ‚¬ģš©ģž ź³„ģ •ģ€ ģ‚¬ģš©ģžė³„ė”œ ģœ ģ¼ķ•˜ź²Œ 구분할 수 ģžˆė„ė” ģ‹ė³„ģžė„¼ ķ• ė‹¹ķ•˜ź³  추츔 ź°€ėŠ„ķ•œ ģ‹ė³„ģž ģ‚¬ģš©ģ„ ģ œķ•œķ•˜ģ—¬ģ•¼ ķ•˜ė©°, ė™ģ¼ķ•œ ģ‹ė³„ģžė„¼ ź³µģœ ķ•˜ģ—¬ ģ‚¬ģš©ķ•˜ėŠ” 경우 ź·ø ģ‚¬ģœ ģ™€ ķƒ€ė‹¹ģ„±ģ„ ź²€ķ† ķ•˜ģ—¬ ģ±…ģž„ģžģ˜ ģŠ¹ģø ė° ģ±…ģž„ģ¶”ģ ģ„± 확볓 등 ė³“ģ™„ėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.5.3": {"name": "ģ‚¬ģš©ģž ģøģ¦","checks": {"iam_root_mfa_enabled": null,"iam_user_accesskey_unused": null,"iam_check_saml_providers_sts": null,"cognito_user_pool_mfa_enabled": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_hardware_mfa_enabled": null,"iam_user_two_active_access_key": null,"iam_administrator_access_with_mfa": null,"iam_user_mfa_enabled_console_access": null,"iam_user_with_temporary_credentials": null,"apigatewayv2_api_authorizers_enabled": "FAIL","iam_user_no_setup_initial_access_key": null,"apigateway_restapi_authorizers_enabled": "PASS","rds_cluster_iam_authentication_enabled": "FAIL","rds_instance_iam_authentication_enabled": "FAIL","kafka_cluster_unrestricted_access_disabled": null,"cognito_identity_pool_guest_access_disabled": "FAIL","cognito_user_pool_advanced_security_enabled": null,"cognito_user_pool_self_registration_disabled": null,"directoryservice_supported_mfa_radius_enabled": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cognito_user_pool_client_token_revocation_enabled": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cognito_user_pool_client_prevent_user_existence_errors": null,"opensearch_service_domains_internal_user_database_enabled": null,"cognito_user_pool_blocks_potential_malicious_sign_in_attempts": null,"opensearch_service_domains_use_cognito_authentication_for_kibana": null,"cognito_user_pool_blocks_compromised_credentials_sign_in_attempts": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.5.3 ģ‚¬ģš©ģž ģøģ¦","Subdomain": "2.5. ģøģ¦ ė° ź¶Œķ•œź“€ė¦¬","AuditEvidence": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ė”œź·øģø 화멓","ė”œź·øģø 횟수 ģ œķ•œ 설정 화멓","ė”œź·øģø ģ‹¤ķŒØ ė©”ģ‹œģ§€ 화멓","외부 ģ ‘ģ† ģ‹œ 절차(ģ™øė¶€ģ ‘ģ† ģ‹ ģ²­ģ„œ, ģ™øė¶€ģ ‘ģ†ģž ķ˜„ķ™© 등)"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ģ ‘ź·¼ģ€ ģ‚¬ģš©ģž ģøģ¦, ė”œź·øģø 횟수 ģ œķ•œ, ė¶ˆė²• ė”œź·øģø ģ‹œė„ 경고 등 ģ•ˆģ „ķ•œ ģ‚¬ģš©ģž ģøģ¦ ģ ˆģ°Øģ— ė”°ė¼ ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ķ†µģ‹ ė§ģ„ ķ†µķ•˜ģ—¬ ģ™øė¶€ģ—ģ„œ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— ģ ‘ģ†ķ•˜ė ¤ėŠ” ź²½ģš°ģ—ėŠ” 법적 ģš”źµ¬ģ‚¬ķ•­ģ— ė”°ė¼ ģ•ˆģ „ķ•œ ģøģ¦ģˆ˜ė‹Ø ė˜ėŠ” ģ•ˆģ „ķ•œ ģ ‘ģ†ģˆ˜ė‹Øģ„ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ģ·Øźø‰ģžź°€ 공개된 외부 ģøķ„°ė„·ė§ģ„ ķ†µķ•˜ģ—¬ ģ“ģš©ģžģ˜ ź°œģøģ •ė³“ė„¼ ģ²˜ė¦¬ķ•˜ėŠ” ź°œģøģ •ė³“ģ²˜ė¦¬ ģ‹œģŠ¤ķ…œģ— ģ ‘ź·¼ ģ‹œ ģ•ˆģ „ķ•œ ģøģ¦ģˆ˜ė‹Øģ„ ģ ģš©ķ•˜ģ§€ ģ•Šź³  IDĀ·ė¹„ė°€ė²ˆķ˜ø ė°©ģ‹ģœ¼ė”œė§Œ ģøģ¦ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ė”œź·øģø ģ‹¤ķŒØ ģ‹œ 핓당 IDź°€ ģ”“ģž¬ķ•˜ģ§€ ģ•Šź±°ė‚˜ ė¹„ė°€ė²ˆķ˜øź°€ ķ‹€ė¦¼ģ„ ģžģ„øķžˆ ķ‘œģ‹œķ•“ 주고 ģžˆģœ¼ė©°, ė”œź·øģø ģ‹¤ķŒØķšŸģˆ˜ģ— ėŒ€ķ•œ ģ œķ•œģ“ ģ—†ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ ź¶Œķ•œģ˜ ꓀리), 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œź³¼ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ— ėŒ€ķ•œ ģ‚¬ģš©ģžģ˜ ģ ‘ź·¼ģ€ ģ•ˆģ „ķ•œ ģøģ¦ģ ˆģ°Øģ™€ ķ•„ģš”ģ— ė”°ė¼ ź°•ķ™”ėœ ģøģ¦ė°©ģ‹ģ„ ģ ģš©ķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ė˜ķ•œ ė”œź·øģø 횟수 ģ œķ•œ, ė¶ˆė²• ė”œź·øģø ģ‹œė„ 경고 등 ė¹„ģøź°€ģž ģ ‘ź·¼ ķ†µģ œė°©ģ•ˆģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 4,"pass": 1,"total": 29,"manual": 0}},"2.5.4": {"name": "ė¹„ė°€ė²ˆķ˜ø ꓀리","checks": {"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_reuse_24": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_password_policy_minimum_length_14": null,"cognito_user_pool_password_policy_number": null,"cognito_user_pool_password_policy_symbol": null,"cognito_user_pool_password_policy_lowercase": null,"cognito_user_pool_password_policy_uppercase": null,"cognito_user_pool_temporary_password_expiration": null,"cognito_user_pool_password_policy_minimum_length_14": null,"iam_password_policy_expires_passwords_within_90_days_or_less": null},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.5.4 ė¹„ė°€ė²ˆķ˜ø ꓀리","Subdomain": "2.5. ģøģ¦ ė° ź¶Œķ•œź“€ė¦¬","AuditEvidence": ["ģ›¹ķŽ˜ģ“ģ§€, ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ė¹„ė°€ė²ˆķ˜ø 설정 화멓","ė¹„ė°€ė²ˆķ˜ø ꓀리 ģ •ģ±… ė° 절차"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ģ•ˆģ „ķ•œ ģ‚¬ģš©ģž ė¹„ė°€ė²ˆķ˜ø ź“€ė¦¬ģ ˆģ°Ø ė° ģž‘ģ„±ź·œģ¹™ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","정볓주첓(ģ“ģš©ģž)ź°€ ģ•ˆģ „ķ•œ ė¹„ė°€ė²ˆķ˜øė„¼ ģ“ģš©ķ•  수 ģžˆė„ė” ė¹„ė°€ė²ˆķ˜ø ģž‘ģ„±ź·œģ¹™ģ„ 수립 ė° ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ģ·Øźø‰ģž ė˜ėŠ” ģ •ė³“ģ£¼ģ²“ģ˜ ģøģ¦ģˆ˜ė‹Øģ„ ģ•ˆģ „ķ•˜ź²Œ ģ ģš©ķ•˜ź³  ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 ģ •ģ±…, 지침 ė“±ģ—ģ„œ ė¹„ė°€ė²ˆķ˜ø ģƒģ„±ź·œģ¹™ģ˜ źø°ģ¤€ģ„ ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ¼ė¶€ ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ—ģ„œ ė‚“ė¶€ 지침과 ģƒģ“ķ•œ ė¹„ė°€ė²ˆķ˜øė„¼ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : ė¹„ė°€ė²ˆķ˜ø ꓀련 ė‚“ė¶€ ź·œģ •ģ—ėŠ” ė¹„ė°€ė²ˆķ˜øė„¼ ģ“ˆźø°ķ™” ģ‹œ ģž„ģ‹œ ė¹„ė°€ė²ˆķ˜øė„¼ 부여받고 ź°•ģ œģ ģœ¼ė”œ ė³€ź²½ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ģ‹¤ģ œė”œėŠ” ģž„ģ‹œ ė¹„ė°€ė²ˆķ˜øė„¼ ź·øėŒ€ė”œ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : ė¹„ė°€ė²ˆķ˜ø ꓀련 ė‚“ė¶€ ź·œģ •ģ—ėŠ” ģ‚¬ģš©ģž ė° ź°œģøģ •ė³“ģ·Øźø‰ģžģ˜ ė¹„ė°€ė²ˆķ˜ø 변경주기넼 ģ •ķ•˜ź³  ģ“ķ–‰ķ•˜ė„ė” ķ•˜ź³  ģžˆģŒģ—ė„ ė¶ˆźµ¬ķ•˜ź³  ė³€ź²½ķ•˜ģ§€ ģ•Šź³  ź·øėŒ€ė”œ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ ź¶Œķ•œģ˜ ꓀리)"]}],"description": "법적 ģš”źµ¬ģ‚¬ķ•­, 외부 ģœ„ķ˜‘ģš”ģø ė“±ģ„ ź³ ė ¤ķ•˜ģ—¬ ģ •ė³“ģ‹œģŠ¤ķ…œ ģ‚¬ģš©ģž ė° ź³ ź°, ķšŒģ› 등 정볓주첓(ģ“ģš©ģž)ź°€ ģ‚¬ģš©ķ•˜ėŠ” ė¹„ė°€ė²ˆķ˜ø ź“€ė¦¬ģ ˆģ°Øė„¼ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 13,"manual": 0}},"2.5.5": {"name": "특수 계정 ė° ź¶Œķ•œ ꓀리","checks": {"iam_avoid_root_usage": null,"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_support_role_created": null,"rds_cluster_default_admin": "FAIL","rds_instance_default_admin": "FAIL","ec2_instance_profile_attached": "PASS","iam_root_hardware_mfa_enabled": null,"organizations_delegated_administrators": null,"cloudwatch_log_metric_filter_root_usage": null,"sagemaker_notebook_instance_root_access_disabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.5.5 특수 계정 ė° ź¶Œķ•œ ꓀리","Subdomain": "2.5. ģøģ¦ ė° ź¶Œķ•œź“€ė¦¬","AuditEvidence": ["ķŠ¹ģˆ˜ź¶Œķ•œ ꓀련 지침","ķŠ¹ģˆ˜ź¶Œķ•œ ģ‹ ģ²­Ā·ģŠ¹ģø ė‚“ģ—­","ķŠ¹ģˆ˜ź¶Œķ•œģž ėŖ©ė”","ķŠ¹ģˆ˜ź¶Œķ•œ 검토 ė‚“ģš©"],"AuditChecklist": ["ź“€ė¦¬ģž ź¶Œķ•œ 등 ķŠ¹ģˆ˜ź¶Œķ•œģ€ ģµœģ†Œķ•œģ˜ ģøģ›ģ—ź²Œė§Œ 부여될 수 ģžˆė„ė” ź³µģ‹ģ ģø ź¶Œķ•œ ģ‹ ģ²­ ė° ģŠ¹ģø 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","특수 ėŖ©ģ ģ„ ģœ„ķ•˜ģ—¬ ė¶€ģ—¬ķ•œ 계정 ė° ź¶Œķ•œģ„ ģ‹ė³„ķ•˜ź³  ė³„ė„ ėŖ©ė”ģœ¼ė”œ ź“€ė¦¬ķ•˜ėŠ” 등 ķ†µģ œģ ˆģ°Øė„¼ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ź“€ė¦¬ģž ė° ķŠ¹ģˆ˜ź¶Œķ•œ 부여 ė“±ģ˜ ģŠ¹ģø ģ“ė „ģ“ ģ‹œģŠ¤ķ…œģ“ė‚˜ ė¬øģ„œģƒģœ¼ė”œ ķ™•ģøģ“ ė˜ģ§€ ģ•Šź±°ė‚˜, ģŠ¹ģø ģ“ė „ź³¼ ķŠ¹ģˆ˜ź¶Œķ•œ ė‚“ģ—­ģ“ ģ„œė”œ ģ¼ģ¹˜ė˜ģ§€ ģ•ŠėŠ” 경우","사딀 2 : ė‚“ė¶€ ź·œģ •ģ—ėŠ” ź°œģøģ •ė³“ ź“€ė¦¬ģž ė° ķŠ¹ģˆ˜ź¶Œķ•œ ė³“ģœ ģžė„¼ ėŖ©ė”ģœ¼ė”œ ģž‘ģ„±Ā·ź“€ė¦¬ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜ ģ“ė„¼ ģž‘ģ„±Ā·ź“€ė¦¬ķ•˜ź³  ģžˆģ§€ ģ•Šź±°ė‚˜, ė³“ģ•ˆģ‹œģŠ¤ķ…œ ź“€ė¦¬ģž 등 ģ¼ė¶€ ķŠ¹ģˆ˜ź¶Œķ•œģ“ ģ‹ė³„Ā·ź“€ė¦¬ė˜ģ§€ ģ•ŠėŠ” 경우","사딀 3 : ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ģœ ģ§€ė³“ģˆ˜ė„¼ ģœ„ķ•˜ģ—¬ ė¶„źø° 1ķšŒģ— ė°©ė¬øķ•˜ėŠ” ģœ ģ§€ė³“ģˆ˜ģš© 특수 ź³„ģ •ģ“ ģ‚¬ģš©źø°ź°„ ģ œķ•œģ—†ģ“ ģƒģ‹œė”œ ķ™œģ„±ķ™”ė˜ģ–“ ģžˆėŠ” 경우","사딀 4 : ź“€ė¦¬ģž ė° ķŠ¹ģˆ˜ź¶Œķ•œģ˜ ģ‚¬ģš© 여부넼 ģ •źø°ģ ģœ¼ė”œ ź²€ķ† ķ•˜ģ§€ ģ•Šģ•„ ģ¼ė¶€ ķŠ¹ģˆ˜ź¶Œķ•œģžģ˜ 업묓가 ė³€ź²½ė˜ģ—ˆģŒģ—ė„ ė¶ˆźµ¬ķ•˜ź³  기씓 ź“€ė¦¬ģž ė° ķŠ¹ģˆ˜ź¶Œķ•œģ„ ź³„ģ† ė³“ģœ ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ ź¶Œķ•œģ˜ ꓀리)"]}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œ ꓀리, ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ ꓀리 등 특수 ėŖ©ģ ģ„ ģœ„ķ•˜ģ—¬ ģ‚¬ģš©ķ•˜ėŠ” 계정 ė° ź¶Œķ•œģ€ ģµœģ†Œķ•œģœ¼ė”œ ė¶€ģ—¬ķ•˜ź³  ė³„ė„ė”œ ģ‹ė³„ķ•˜ģ—¬ ķ†µģ œķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 2,"pass": 1,"total": 11,"manual": 0}},"2.5.6": {"name": "ģ ‘ź·¼ź¶Œķ•œ 검토","checks": {"accessanalyzer_enabled": "PASS","cloudtrail_insights_exist": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","accessanalyzer_enabled_without_findings": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_cross_account_sharing_disabled": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cloudtrail_multi_region_enabled_logging_management_events": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.5.6 ģ ‘ź·¼ź¶Œķ•œ 검토","Subdomain": "2.5. ģøģ¦ ė° ź¶Œķ•œź“€ė¦¬","AuditEvidence": ["ģ ‘ź·¼ź¶Œķ•œ 검토 기준 ė° 절차","ģ ‘ź·¼ź¶Œķ•œ 검토 ģ“ė „","ģ ‘ź·¼ź¶Œķ•œ 검토 ź²°ź³¼ė³“ź³ ģ„œ ė° ķ›„ģ†ģ”°ģ¹˜ ė‚“ģ—­"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œź³¼ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ— ėŒ€ķ•œ ģ‚¬ģš©ģž 계정 ė° ģ ‘ź·¼ź¶Œķ•œ ģƒģ„±Ā·ė“±ė”Ā·ė¶€ģ—¬ ė° ģ“ģš©Ā·ė³€ź²½Ā·ė§ģ†Œ ė“±ģ˜ ģ“ė „ģ„ 남기고 ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œź³¼ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ— ėŒ€ķ•œ ģ‚¬ģš©ģž 계정 ė° ģ ‘ź·¼ź¶Œķ•œģ˜ 적정성 검토 기준, 검토주첓, 검토방법, 주기 ė“±ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ 정기적 검토넼 ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ ‘ź·¼ź¶Œķ•œ 검토 ź²°ź³¼ ģ ‘ź·¼ź¶Œķ•œ 과다 부여, ź¶Œķ•œė¶€ģ—¬ 절차 ėÆøģ¤€ģˆ˜, ź¶Œķ•œ ģ˜¤Ā·ė‚Øģš© 등 ė¬øģ œģ ģ“ 발견된 경우 그에 따넸 씰치절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ ‘ź·¼ź¶Œķ•œ 검토와 ź“€ė Øėœ 방법, 점검주기, 볓고첓계, ģ˜¤Ā·ė‚Øģš© 기준 ė“±ģ“ ꓀련 지침에 구첓적으딜 ģ •ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ•„ ģ ‘ź·¼ź¶Œķ•œ 검토가 ģ •źø°ģ ģœ¼ė”œ ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ė‚“ė¶€ ģ •ģ±…, 지침 등에 ģž„źø° ėÆøģ‚¬ģš©ģž 계정에 ėŒ€ķ•œ ģž źøˆ(ė¹„ķ™œģ„±ķ™”) ė˜ėŠ” ģ‚­ģ œ ģ”°ģ¹˜ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, 6ź°œģ›” ģ“ģƒ ėÆøģ ‘ģ†ķ•œ ģ‚¬ģš©ģžģ˜ ź³„ģ •ģ“ ķ™œģ„±ķ™”ė˜ģ–“ ģžˆėŠ” 경우(ģ ‘ź·¼ź¶Œķ•œ 검토가 ģ¶©ģ‹¤ķžˆ ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ•„ 핓당 ź³„ģ •ģ“ ģ‹ė³„ė˜ģ§€ ģ•Šģ€ 경우)","사딀 3 : ģ ‘ź·¼ź¶Œķ•œ 검토 ģ‹œ ģ ‘ź·¼ź¶Œķ•œģ˜ 과다 부여 ė° ģ˜¤Ā·ė‚Øģš© ģ˜ģ‹¬ģ‚¬ė”€ź°€ ė°œź²¬ė˜ģ—ˆģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•œ ģƒģ„øģ”°ģ‚¬, 낓부볓고 ė“±ģ˜ ķ›„ģ†ģ”°ģ¹˜ź°€ ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ ź¶Œķ•œģ˜ ꓀리)"]}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œź³¼ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ— ģ ‘ź·¼ķ•˜ėŠ” ģ‚¬ģš©ģž ź³„ģ •ģ˜ ė“±ė”Ā·ģ“ģš©Ā·ģ‚­ģ œ ė° ģ ‘ź·¼ź¶Œķ•œģ˜ ė¶€ģ—¬Ā·ė³€ź²½Ā·ģ‚­ģ œ ģ“ė „ģ„ 남기고 주기적으딜 ź²€ķ† ķ•˜ģ—¬ 적정성 여부넼 ģ ź²€ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 2,"pass": 1,"total": 14,"manual": 0}},"2.6.1": {"name": "ė„¤ķŠøģ›Œķ¬ ģ ‘ź·¼","checks": {"ec2_ami_public": null,"elb_internet_facing": "FAIL","ec2_elastic_ip_shodan": null,"elbv2_internet_facing": "PASS","ec2_instance_public_ip": "FAIL","ec2_ebs_public_snapshot": "PASS","kafka_cluster_is_public": null,"s3_bucket_acl_prohibited": "FAIL","apigateway_restapi_public": "FAIL","lightsail_database_public": null,"lightsail_instance_public": null,"ec2_securitygroup_not_used": "FAIL","elbv2_listeners_underneath": "PASS","networkfirewall_in_all_vpc": "FAIL","s3_bucket_public_write_acl": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","ssm_documents_set_as_public": "PASS","awslambda_function_url_public": null,"dms_instance_no_public_access": null,"rds_instance_no_public_access": "PASS","emr_cluster_publicly_accesible": null,"redshift_cluster_public_access": null,"neptune_cluster_public_snapshot": null,"eks_cluster_private_nodes_enabled": null,"awslambda_function_url_cors_policy": null,"documentdb_cluster_public_snapshot": null,"eks_cluster_network_policy_enabled": null,"neptune_cluster_uses_public_subnet": null,"sns_topics_not_publicly_accessible": "PASS","sqs_queues_not_publicly_accessible": "PASS","vpc_subnet_no_public_ip_by_default": "FAIL","vpc_subnet_separate_private_public": "FAIL","eks_cluster_not_publicly_accessible": null,"glacier_vaults_policy_public_access": null,"iam_user_mfa_enabled_console_access": null,"s3_access_point_public_access_block": "PASS","s3_bucket_level_public_access_block": "PASS","iam_user_administrator_access_policy": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"iam_group_administrator_access_policy": null,"s3_account_level_public_access_blocks": null,"apigateway_restapi_authorizers_enabled": "PASS","elasticache_cluster_uses_public_subnet": "PASS","rds_instance_iam_authentication_enabled": "FAIL","appstream_fleet_maximum_session_duration": null,"ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ecr_repositories_not_publicly_accessible": "PASS","emr_cluster_account_public_block_enabled": "PASS","sagemaker_models_vpc_settings_configured": null,"apigateway_restapi_public_with_authorizer": "FAIL","ec2_instance_port_ftp_exposed_to_internet": "PASS","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","vpc_endpoint_connections_trust_boundaries": "FAIL","appstream_fleet_session_disconnect_timeout": null,"awslambda_function_not_publicly_accessible": "PASS","ec2_instance_port_cifs_exposed_to_internet": "PASS","ec2_instance_port_ldap_exposed_to_internet": "PASS","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","kafka_cluster_unrestricted_access_disabled": null,"sagemaker_models_network_isolation_enabled": null,"cognito_identity_pool_guest_access_disabled": "FAIL","ec2_instance_port_kafka_exposed_to_internet": "PASS","ec2_instance_port_mysql_exposed_to_internet": "PASS","ec2_instance_port_redis_exposed_to_internet": "PASS","workspaces_vpc_2private_1public_subnets_nat": null,"ec2_instance_port_oracle_exposed_to_internet": "PASS","ec2_instance_port_telnet_exposed_to_internet": "PASS","ec2_instance_port_mongodb_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_instance_port_kerberos_exposed_to_internet": "PASS","ec2_transitgateway_auto_accept_vpc_attachments": null,"appstream_fleet_session_idle_disconnect_timeout": null,"ec2_instance_port_cassandra_exposed_to_internet": "PASS","ec2_instance_port_memcached_exposed_to_internet": "PASS","ec2_instance_port_sqlserver_exposed_to_internet": "PASS","rds_instance_event_subscription_security_groups": "FAIL","sagemaker_training_jobs_vpc_settings_configured": null,"vpc_peering_routing_tables_with_least_privilege": "PASS","appstream_fleet_default_internet_access_disabled": null,"ec2_instance_port_postgresql_exposed_to_internet": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","cloudfront_distributions_geo_restrictions_enabled": null,"sagemaker_training_jobs_network_isolation_enabled": null,"opensearch_service_domains_not_publicly_accessible": null,"sagemaker_notebook_instance_vpc_settings_configured": null,"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","vpc_endpoint_services_allowed_principals_trust_boundaries": null,"ec2_instance_port_elasticsearch_kibana_exposed_to_internet": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","cognito_user_pool_blocks_potential_malicious_sign_in_attempts": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.6.1 ė„¤ķŠøģ›Œķ¬ ģ ‘ź·¼","Subdomain": "2.6. ģ ‘ź·¼ķ†µģ œ","AuditEvidence": ["ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„","IP ź“€ė¦¬ėŒ€ģž„","ģ •ė³“ģžģ‚° ėŖ©ė”","방화벽룰"],"AuditChecklist": ["ģ”°ģ§ģ˜ ė„¤ķŠøģ›Œķ¬ģ— 접근할 수 ģžˆėŠ” ėŖØė“  경딜넼 ģ‹ė³„ķ•˜ź³  ģ ‘ź·¼ķ†µģ œ 정책에 ė”°ė¼ ė‚“ė¶€ ė„¤ķŠøģ›Œķ¬ėŠ” ģøź°€ėœ ģ‚¬ģš©ģžė§Œģ“ 접근할 수 ģžˆė„ė” ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?","ģ„œė¹„ģŠ¤, ģ‚¬ģš©ģž 그룹, ģ •ė³“ģžģ‚°ģ˜ ģ¤‘ģš”ė„, 법적 ģš”źµ¬ģ‚¬ķ•­ģ— ė”°ė¼ ė„¤ķŠøģ›Œķ¬ ģ˜ģ—­ģ„ 물리적 ė˜ėŠ” ė…¼ė¦¬ģ ģœ¼ė”œ ė¶„ė¦¬ķ•˜ź³  각 ģ˜ģ—­ ź°„ ģ ‘ź·¼ķ†µģ œė„¼ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?","ė„¤ķŠøģ›Œķ¬ ėŒ€ģ—­ė³„ IPģ£¼ģ†Œ 부여 źø°ģ¤€ģ„ ė§ˆė Øķ•˜ź³  ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ„œė²„ 등 외부 ģ—°ź²°ģ“ ķ•„ģš”ķ•˜ģ§€ ģ•Šģ€ 경우 사설 IP딜 ķ• ė‹¹ķ•˜ėŠ” ė“±ģ˜ ėŒ€ģ±…ģ„ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?","물리적으딜 ė–Øģ–“ģ§„ IDC, 지사, ėŒ€ė¦¬ģ  ė“±ź³¼ģ˜ ė„¤ķŠøģ›Œķ¬ ģ—°ź²° ģ‹œ 전솔구간 ė³“ķ˜øėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„ģ™€ ģøķ„°ė·°ė„¼ ķ†µķ•˜ģ—¬ ķ™•ģøķ•œ ź²°ź³¼, 외부 ģ§€ģ ģ—ģ„œ ģ‚¬ģš©ķ•˜ėŠ” ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ź°œģøģ •ė³“ ģ²˜ė¦¬ģ‹œģŠ¤ķ…œź³¼ IDC에 ģœ„ģ¹˜ķ•œ ģ„œė²„ ź°„ ģ—°ź²° ģ‹œ ģ¼ė°˜ ģøķ„°ė„· ķšŒģ„ ģ„ ķ†µķ•˜ģ—¬ ė°ģ“ķ„° ģ†”ģˆ˜ģ‹ ģ„ ģ²˜ė¦¬ķ•˜ź³  ģžˆģ–“ ė‚“ė¶€ ź·œģ •ģ— ėŖ…ģ‹œėœ VPNģ“ė‚˜ ģ „ģš©ė§ ė“±ģ„ ģ“ģš©ķ•œ ķ†µģ‹ ģ“ ģ“ė£Øģ–“ģ§€ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ė‚“ė¶€ė§ģ— ģœ„ģ¹˜ķ•œ ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ„œė²„ 등 ģ¼ė¶€ ģ¤‘ģš” ģ„œė²„ģ˜ IPģ£¼ģ†Œź°€ ė‚“ė¶€ ź·œģ •ź³¼ 달리 ź³µģø IP딜 ģ„¤ģ •ė˜ģ–“ ģžˆź³ , ė„¤ķŠøģ›Œķ¬ ģ ‘ź·¼ ģ°Øė‹Øģ“ ģ ģš©ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģ„œė²„ķŒœģ“ źµ¬ģ„±ė˜ģ–“ ģžˆģœ¼ė‚˜, ė„¤ķŠøģ›Œķ¬ ģ ‘ź·¼ģ œģ–“ 설정 ėÆøķ”ģœ¼ė”œ ė‚“ė¶€ė§ģ—ģ„œ ģ„œė²„ķŒœģœ¼ė”œģ˜ ģ ‘ź·¼ģ“ ź³¼ė„ķ•˜ź²Œ ķ—ˆģš©ė˜ģ–“ ģžˆėŠ” 경우","사딀 4 : ģ™øė¶€ģž(외부 ź°œė°œģž, ė°©ė¬øģž 등)ģ—ź²Œ ģ œź³µė˜ėŠ” ė„¤ķŠøģ›Œķ¬ė„¼ ė³„ė„ģ˜ ķ†µģ œ ģ—†ģ“ ė‚“ė¶€ 업묓 ė„¤ķŠøģ›Œķ¬ģ™€ ė¶„ė¦¬ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 5 : ė‚“ė¶€ ź·œģ •ź³¼ėŠ” 달리 MACģ£¼ģ†Œ ģøģ¦, ķ•„ģˆ˜ ė³“ģ•ˆ ģ†Œķ”„ķŠøģ›Øģ–“ ģ„¤ģ¹˜ ė“±ģ˜ ė³“ķ˜øėŒ€ģ±…ģ„ ģ ģš©ķ•˜ģ§€ ģ•Šģ€ 상태딜 ė„¤ķŠøģ›Œķ¬ ģ¼€ģ“ėø” ģ—°ź²°ė§Œģœ¼ė”œ 사낓 ė„¤ķŠøģ›Œķ¬ģ— ģ ‘ź·¼ ė° ģ“ģš©ķ•  수 ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "ė„¤ķŠøģ›Œķ¬ģ— ėŒ€ķ•œ ė¹„ģøź°€ ģ ‘ź·¼ģ„ ķ†µģ œķ•˜źø° ģœ„ķ•˜ģ—¬ IP꓀리, ė‹Øė§ģøģ¦ 등 ź“€ė¦¬ģ ˆģ°Øė„¼ 수립 ė°ģ“ķ–‰ķ•˜ź³ , 업묓목적 ė° ģ¤‘ģš”ė„ģ— ė”°ė¼ ė„¤ķŠøģ›Œķ¬ 분리(DMZ, ģ„œė²„ķŒœ, DB씓, 개발씓 등)와 ģ ‘ź·¼ķ†µģ œė„¼ ģ ģš©ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 17,"pass": 54,"total": 112,"manual": 0}},"2.6.2": {"name": "ģ •ė³“ģ‹œģŠ¤ķ…œ ģ ‘ź·¼","checks": {"ec2_elastic_ip_shodan": null,"ec2_instance_public_ip": "FAIL","ec2_elastic_ip_unassigned": "FAIL","lightsail_instance_public": null,"lightsail_static_ip_unused": null,"ec2_instance_managed_by_ssm": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_instance_port_ftp_exposed_to_internet": "PASS","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_instance_port_telnet_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","ec2_instance_internet_facing_with_instance_profile": "FAIL","ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.6.2 ģ •ė³“ģ‹œģŠ¤ķ…œ ģ ‘ź·¼","Subdomain": "2.6. ģ ‘ź·¼ķ†µģ œ","AuditEvidence": ["ģ •ė³“ģ‹œģŠ¤ķ…œ 욓영첓제 계정 ėŖ©ė”","ģ„œė²„ ė³“ģ•ˆ 설정","ģ„œė²„ģ ‘ź·¼ģ œģ–“ ģ •ģ±…(SecureOS ꓀리화멓 등)","ģ„œė²„ ė° ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„","ģ •ė³“ģžģ‚° ėŖ©ė”"],"AuditChecklist": ["ģ„œė²„, ė„¤ķŠøģ›Œķ¬ģ‹œģŠ¤ķ…œ, ė³“ģ•ˆģ‹œģŠ¤ķ…œ 등 ģ •ė³“ģ‹œģŠ¤ķ…œė³„ 욓영첓제(OS)에 ģ ‘ź·¼ģ“ ķ—ˆģš©ė˜ėŠ” ģ‚¬ģš©ģž, ģ ‘ź·¼ ź°€ėŠ„ ģœ„ģ¹˜, ģ ‘ź·¼ ģˆ˜ė‹Ø ė“±ģ„ ģ •ģ˜ķ•˜ģ—¬ ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œģ— ģ ‘ģ† 후 ģ¼ģ •ģ‹œź°„ ģ—…ė¬“ģ²˜ė¦¬ė„¼ ķ•˜ģ§€ ģ•ŠėŠ” 경우 ģžė™ģœ¼ė”œ ģ‹œģŠ¤ķ…œ ģ ‘ģ†ģ“ ģ°Øė‹Øė˜ė„ė” ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ‚¬ģš©ėŖ©ģ ź³¼ ꓀계 ģ—†ėŠ” ģ„œė¹„ģŠ¤ė„¼ ģ œź±°ķ•˜ź³  ģžˆėŠ”ź°€?","ģ£¼ģš” ģ„œė¹„ģŠ¤ė„¼ ģ œź³µķ•˜ėŠ” ģ •ė³“ģ‹œģŠ¤ķ…œģ€ ė…ė¦½ėœ ģ„œė²„ė”œ ģš“ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ‚¬ė¬“ģ‹¤ģ—ģ„œ ģ„œė²„ź“€ė¦¬ģžź°€ IDC에 ģœ„ģ¹˜ķ•œ ģœˆė„ģš° ģ„œė²„ģ— ģ ‘ź·¼ ģ‹œ 터미널 ģ„œė¹„ģŠ¤ė„¼ ģ“ģš©ķ•˜ģ—¬ ģ ‘ź·¼ķ•˜ź³  ģžˆģœ¼ė‚˜, 터미널 ģ„œė¹„ģŠ¤ģ— ėŒ€ķ•œ ģ„øģ…˜ ķƒ€ģž„ģ•„ģ›ƒ ģ„¤ģ •ģ“ ė˜ģ–“ ģžˆģ§€ ģ•Šģ•„ ģž„ģ‹œź°„ ģ•„ė¬“ėŸ° ģž‘ģ—…ģ„ ķ•˜ģ§€ ģ•Šģ•„ė„ 핓당 ģ„øģ…˜ģ“ ģ°Øė‹Øė˜ģ§€ ģ•ŠėŠ” 경우","사딀 2 : ģ„œė²„ ź°„ ģ ‘ģ†ģ“ ģ ģ ˆķžˆ ģ œķ•œė˜ģ§€ ģ•Šģ•„ ķŠ¹ģ • ģ‚¬ģš©ģžź°€ ė³øģøģ—ź²Œ ģøź°€ėœ ģ„œė²„ģ— ģ ‘ģ†ķ•œ 후 핓당 ģ„œė²„ė„¼ ź²½ģœ ķ•˜ģ—¬ 다넸 ģøź°€ė°›ģ§€ ģ•Šģ€ ģ„œė²„ģ—ė„ ģ ‘ģ†ķ•  수 ģžˆėŠ” 경우","사딀 3 : ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ė˜ėŠ” 볓완 ėŒ€ģ±… ģ—†ģ“ ģ•ˆģ „ķ•˜ģ§€ ģ•Šģ€ ģ ‘ģ† ķ”„ė”œķ† ģ½œ(telnet, ftp 등)ģ„ ģ‚¬ģš©ķ•˜ģ—¬ ģ ‘ź·¼ķ•˜ź³  ģžˆģœ¼ė©°, ė¶ˆķ•„ģš”ķ•œ ģ„œė¹„ģŠ¤ ė° ķ¬ķŠøė„¼ ģ˜¤ķ”ˆķ•˜ź³  ģžˆėŠ” 경우","사딀 4 : ėŖØė“  ģ„œė²„ė”œģ˜ ģ ‘ź·¼ģ€ ģ„œė²„ģ ‘ź·¼ģ œģ–“ ģ‹œģŠ¤ķ…œģ„ ķ†µķ•˜ė„ė” ģ ‘ź·¼ķ†µģ œ ģ •ģ±…ģ„ 가져가고 ģžˆģœ¼ė‚˜, ģ„œė²„ģ ‘ź·¼ģ œģ–“ ģ‹œģŠ¤ķ…œģ„ ķ†µķ•˜ģ§€ ģ•Šź³  ģ„œė²„ģ— 접근할 수 ģžˆėŠ” 우회 ź²½ė”œź°€ ģ”“ģž¬ķ•˜ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "ģ„œė²„, ė„¤ķŠøģ›Œķ¬ģ‹œģŠ¤ķ…œ 등 ģ •ė³“ģ‹œģŠ¤ķ…œģ— ģ ‘ź·¼ģ„ ķ—ˆģš©ķ•˜ėŠ” ģ‚¬ģš©ģž, ģ ‘ź·¼ģ œķ•œ ė°©ģ‹, ģ•ˆģ „ķ•œ ģ ‘ź·¼ģˆ˜ė‹Ø ė“±ģ„ ģ •ģ˜ķ•˜ģ—¬ ķ†µģ œķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 8,"pass": 13,"total": 24,"manual": 0}},"2.6.3": {"name": "ģ‘ģš©ķ”„ė”œź·øėžØ ģ ‘ź·¼","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.6.3 ģ‘ģš©ķ”„ė”œź·øėžØ ģ ‘ź·¼","Subdomain": "2.6. ģ ‘ź·¼ķ†µģ œ","AuditEvidence": ["ģ‘ģš©ķ”„ė”œź·øėžØ ģ ‘ź·¼ź¶Œķ•œ ė¶„ė„˜ 첓계","ģ‘ģš©ķ”„ė”œź·øėžØ ź³„ģ •Ā·ź¶Œķ•œ ꓀리 화멓","ģ‘ģš©ķ”„ė”œź·øėžØ ģ‚¬ģš©ģžĀ·ź“€ė¦¬ģž 화멓(ź°œģøģ •ė³“ 씰회 등)","ģ‘ģš©ķ”„ė”œź·øėžØ ģ„øģ…˜ ķƒ€ģž„ ė° ė™ģ‹œģ ‘ģ† ķ—ˆģš© 여부 ė‚“ģ—­","ģ‘ģš©ķ”„ė”œź·øėžØ ź“€ė¦¬ģž ģ ‘ģ†ė”œź·ø ėŖØė‹ˆķ„°ė§ ė‚“ģ—­","ģ •ė³“ģžģ‚° ėŖ©ė”","ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ź°œģøģ •ė³“ 씰회, ź²€ģƒ‰ 화멓","ź°œģøģ •ė³“ ė§ˆģŠ¤ķ‚¹ ķ‘œģ¤€","ź°œģøģ •ė³“ ė§ˆģŠ¤ķ‚¹ 적용 화멓"],"AuditChecklist": ["ģ¤‘ģš”ģ •ė³“ ģ ‘ź·¼ģ„ ķ†µģ œķ•˜źø° ģœ„ķ•˜ģ—¬ ģ‚¬ģš©ģžģ˜ 업묓에 ė”°ė¼ ģ‘ģš©ķ”„ė”œź·øėžØ ģ ‘ź·¼ź¶Œķ•œģ„ 차등 ė¶€ģ—¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ¼ģ •ģ‹œź°„ ė™ģ•ˆ ģž…ė „ģ“ ģ—†ėŠ” ģ„øģ…˜ģ€ ģžė™ ģ°Øė‹Øķ•˜ź³ , ė™ģ¼ ģ‚¬ģš©ģžģ˜ ė™ģ‹œ ģ„øģ…˜ 수넼 ģ œķ•œķ•˜ź³  ģžˆėŠ”ź°€?","ź“€ė¦¬ģž ģ „ģš© ģ‘ģš©ķ”„ė”œź·øėžØ(ź“€ė¦¬ģž ģ›¹ķŽ˜ģ“ģ§€, ź“€ė¦¬ģ½˜ģ†” 등)ģ€ ė¹„ģøź°€ģžź°€ 접근할 수 ģ—†ė„ė” ģ ‘ź·¼ģ„ ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ˜ ķ‘œģ‹œģ œķ•œ ė³“ķ˜øģ”°ģ¹˜ģ˜ ģ¼ź“€ģ„±ģ„ 확볓할 수 ģžˆė„ė” ꓀련 źø°ģ¤€ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ˜ ė¶ˆķ•„ģš”ķ•œ ė…øģ¶œ(씰회, ķ™”ė©“ķ‘œģ‹œ, ģøģ‡„, ė‹¤ģš“ė”œė“œ 등)ģ„ ģµœģ†Œķ™”ķ•  수 ģžˆė„ė” ģ‘ģš©ķ”„ė”œź·øėžØģ„ źµ¬ķ˜„ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ‘ģš©ķ”„ė”œź·øėžØģ˜ ź°œģøģ •ė³“ ģ²˜ė¦¬ķ™”ė©“ 중 ģ¼ė¶€ ķ™”ė©“ģ˜ ź¶Œķ•œ ģ œģ–“ źø°ėŠ„ģ— ģ˜¤ė„˜ź°€ ģ”“ģž¬ķ•˜ģ—¬ ź°œģøģ •ė³“ ģ—“ėžŒ ź¶Œķ•œģ“ ģ—†ėŠ” ģ‚¬ģš©ģžģ—ź²Œė„ ź°œģøģ •ė³“ź°€ ė…øģ¶œė˜ź³  ģžˆėŠ” 경우","사딀 2 : ģ‘ģš©ķ”„ė”œź·øėžØģ˜ ź“€ė¦¬ģž ķŽ˜ģ“ģ§€ź°€ ģ™øė¶€ģøķ„°ė„·ģ— ģ˜¤ķ”ˆė˜ģ–“ ģžˆģœ¼ė©“ģ„œ ģ•ˆģ „ķ•œ ģøģ¦ģˆ˜ė‹Øģ“ ģ ģš©ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģ‘ģš©ķ”„ė”œź·øėžØģ— ėŒ€ķ•˜ģ—¬ ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ģ—†ģ“ ģ„øģ…˜ ķƒ€ģž„ģ•„ģ›ƒ ė˜ėŠ” ė™ģ¼ ģ‚¬ģš©ģž ź³„ģ •ģ˜ ė™ģ‹œ ģ ‘ģ†ģ„ ģ œķ•œķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ģ‘ģš©ķ”„ė”œź·øėžØģ„ ķ†µķ•˜ģ—¬ ź°œģøģ •ė³“ė„¼ ė‹¤ģš“ė”œė“œė°›ėŠ” 경우 핓당 ķŒŒģ¼ 낓에 ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø 등 ģ—…ė¬“ģƒ ė¶ˆķ•„ģš”ķ•œ 정볓가 ź³¼ė„ķ•˜ź²Œ ķ¬ķ•Øė˜ģ–“ ģžˆėŠ” 경우","사딀 5 : ģ‘ģš©ķ”„ė”œź·øėžØģ˜ ź°œģøģ •ė³“ ģ”°ķšŒķ™”ė©“ģ—ģ„œ like ź²€ģƒ‰ģ„ ź³¼ė„ķ•˜ź²Œ ķ—ˆģš©ķ•˜ź³  ģžˆģ–“, ėŖØė“  ģ‚¬ģš©ģžź°€ ė³øģøģ˜ 업묓 ė²”ģœ„ė„¼ ģ“ˆź³¼ķ•˜ģ—¬ ģ„±ģ”Øė§Œģœ¼ė”œė„ 전첓 ź³ ź° 정볓넼 ģ”°ķšŒķ•  수 ģžˆėŠ” 경우","사딀 6 : ź°œģøģ •ė³“ ķ‘œģ‹œģ œķ•œ 씰치 źø°ģ¤€ģ“ ė§ˆė Øė˜ģ–“ ģžˆģ§€ ģ•Šź±°ė‚˜ ģ“ė„¼ ģ¤€ģˆ˜ķ•˜ģ§€ ģ•ŠėŠ” ė“±ģ˜ ģ‚¬ģœ ė”œ ė™ģ¼ķ•œ ź°œģøģ •ė³“ 항목에 ėŒ€ķ•˜ģ—¬ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ķ™”ė©“ė³„ė”œ ģ„œė”œ 다넸 ė§ˆģŠ¤ķ‚¹ źø°ģ¤€ģ“ 적용된 경우","사딀 7 : ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ķ™”ė©“ģƒģ—ėŠ” ź°œģøģ •ė³“ź°€ ė§ˆģŠ¤ķ‚¹ė˜ģ–“ ķ‘œģ‹œė˜ģ–“ ģžˆģœ¼ė‚˜, ģ›¹ėøŒė¼ģš°ģ € ģ†ŒģŠ¤ė³“źø°ė„¼ ķ†µķ•˜ģ—¬ ė§ˆģŠ¤ķ‚¹ė˜ģ§€ ģ•Šģ€ 전첓 ź°œģøģ •ė³“ź°€ ė…øģ¶œė˜ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ź¶Œķ•œģ˜ ꓀리), 제6ģ”°(ģ ‘ź·¼ķ†µģ œ), 제12ģ”°(ģ¶œė „Ā·ė³µģ‚¬ģ‹œ ģ•ˆģ „ģ”°ģ¹˜)"]}],"description": "ģ‚¬ģš©ģžė³„ 업묓 ė° ģ ‘ź·¼ ģ •ė³“ģ˜ ģ¤‘ģš”ė„ 등에 ė”°ė¼ ģ‘ģš©ķ”„ė”œź·øėžØ ģ ‘ź·¼ź¶Œķ•œģ„ ģ œķ•œķ•˜ź³ , ė¶ˆķ•„ģš”ķ•œ 정볓 ė˜ėŠ” ģ¤‘ģš”ģ •ė³“ ė…øģ¶œģ„ ģµœģ†Œķ™”ķ•  수 ģžˆė„ė” źø°ģ¤€ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ģ ģš©ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.6.4": {"name": "ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼","checks": {"accessanalyzer_enabled": "PASS","lightsail_database_public": null,"rds_snapshots_public_access": "PASS","dms_instance_no_public_access": null,"rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"neptune_cluster_public_snapshot": null,"rds_instance_transport_encrypted": "FAIL","documentdb_cluster_public_snapshot": null,"neptune_cluster_uses_public_subnet": null,"vpc_subnet_separate_private_public": "FAIL","dynamodb_table_cross_account_access": null,"rds_cluster_iam_authentication_enabled": "FAIL","accessanalyzer_enabled_without_findings": "FAIL","rds_instance_iam_authentication_enabled": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","neptune_cluster_iam_authentication_enabled": null,"ec2_instance_port_mysql_exposed_to_internet": "PASS","ec2_instance_port_redis_exposed_to_internet": "PASS","ec2_instance_port_oracle_exposed_to_internet": "PASS","ec2_instance_port_mongodb_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_instance_port_cassandra_exposed_to_internet": "PASS","ec2_instance_port_sqlserver_exposed_to_internet": "PASS","opensearch_service_domains_not_publicly_accessible": null,"opensearch_service_domains_https_communications_enforced": null,"opensearch_service_domains_internal_user_database_enabled": null,"ec2_instance_port_elasticsearch_kibana_exposed_to_internet": "PASS","opensearch_service_domains_use_cognito_authentication_for_kibana": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.6.4 ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼","Subdomain": "2.6. ģ ‘ź·¼ķ†µģ œ","AuditEvidence": ["ė°ģ“ķ„°ė² ģ“ģŠ¤ ķ˜„ķ™©(ķ…Œģ“ėø”, 컬럼 등)","ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ģ†ģž ź³„ģ •Ā·ź¶Œķ•œ ėŖ©ė”","ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ģ œģ–“ ģ •ģ±…(ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ģ œģ–“ģ‹œģŠ¤ķ…œ ꓀리화멓 등)","ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„(ė°ģ“ķ„°ė² ģ“ģŠ¤ģ”“ 등)","ģ •ė³“ģžģ‚° ėŖ©ė”"],"AuditChecklist": ["ė°ģ“ķ„°ė² ģ“ģŠ¤ģ˜ ķ…Œģ“ėø” ėŖ©ė” 등 ģ €ģž„Ā·ź“€ė¦¬ė˜ź³  ģžˆėŠ” 정볓넼 ģ‹ė³„ķ•˜ź³  ģžˆėŠ”ź°€?","ė°ģ“ķ„°ė² ģ“ģŠ¤ ė‚“ 정볓에 ģ ‘ź·¼ģ“ ķ•„ģš”ķ•œ ģ‘ģš©ķ”„ė”œź·øėžØ, ģ •ė³“ģ‹œģŠ¤ķ…œ(ģ„œė²„) ė° ģ‚¬ģš©ģžė„¼ ėŖ…ķ™•ķžˆ ģ‹ė³„ķ•˜ź³  ģ ‘ź·¼ķ†µģ œ 정책에 ė”°ė¼ ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ėŒ€ėŸ‰ģ˜ ź°œģøģ •ė³“ė„¼ ė³“ź“€Ā·ģ²˜ė¦¬ķ•˜ź³  ģžˆėŠ” ė°ģ“ķ„°ė² ģ“ģŠ¤ė„¼ ģøķ„°ė„·ģ„ ķ†µķ•˜ģ—¬ ģ ‘ź·¼ ź°€ėŠ„ķ•œ 웹 ģ‘ģš©ķ”„ė”œź·øėžØź³¼ ė¶„ė¦¬ķ•˜ģ§€ ģ•Šź³  물리적으딜 ė™ģ¼ķ•œ ģ„œė²„ģ—ģ„œ ģš“ģ˜ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : ź°œė°œģž ė° ģš“ģ˜ģžė“¤ģ“ ģ‘ģ‘ ķ”„ė”œź·øėžØģ—ģ„œ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” ź³„ģ •ģ„ ź³µģœ ķ•˜ģ—¬ 욓영 ė°ģ“ķ„°ė² ģ“ģŠ¤ģ— ģ ‘ģ†ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : ė‚“ė¶€ ź·œģ •ģ—ėŠ” ė°ģ“ķ„°ė² ģ“ģŠ¤ģ˜ ģ ‘ģ†ź¶Œķ•œģ„ ģ˜¤ėøŒģ ķŠøė³„ė”œ ģ œķ•œķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ź¶Œķ•œģ„ ģš“ģ˜ģžģ—ź²Œ ģ¼ź“„ ė¶€ģ—¬ķ•˜ź³  ģžˆģ–“ ź°œģøģ •ė³“ ķ…Œģ“ėø”ģ— 접근할 ķ•„ģš”ź°€ ģ—†ėŠ” ģš“ģ˜ģžģ—ź²Œė„ ź³¼ė„ķ•˜ź²Œ ģ ‘ź·¼ ź¶Œķ•œģ“ ė¶€ģ—¬ėœ 경우","사딀 4 : ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ģ œģ–“ ģ†”ė£Øģ…˜ģ„ ė„ģž…ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ģ†ģžģ— ėŒ€ķ•œ IPģ£¼ģ†Œ ė“±ģ“ ģ ģ ˆķžˆ ģ œķ•œė˜ģ–“ ģžˆģ§€ ģ•Šģ•„ ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ģ œģ–“ ģ†”ė£Øģ…˜ģ„ ģš°ķšŒķ•˜ģ—¬ ė°ģ“ķ„°ė² ģ“ģŠ¤ģ— ģ ‘ģ†ķ•˜ź³  ģžˆėŠ” 경우","사딀 5 : ź°œģøģ •ė³“ė„¼ ģ €ģž„ķ•˜ź³  ģžˆėŠ” ė°ģ“ķ„°ė² ģ“ģŠ¤ģ˜ ķ…Œģ“ėø” ķ˜„ķ™©ģ“ ķŒŒģ•…ė˜ģ§€ ģ•Šģ•„, ģž„ģ‹œė”œ ģƒģ„±ėœ ķ…Œģ“ėø”ģ— ė¶ˆķ•„ģš”ķ•œ ź°œģøģ •ė³“ź°€ ķŒŒźø°ė˜ģ§€ ģ•Šź³  ėŒ€ėŸ‰ģœ¼ė”œ ģ €ģž„ė˜ģ–“ ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제5ģ”°(ģ ‘ź·¼ź¶Œķ•œģ˜ ꓀리), 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "ķ…Œģ“ėø” ėŖ©ė” 등 ė°ģ“ķ„°ė² ģ“ģŠ¤ ė‚“ģ—ģ„œ ģ €ģž„Ā·ź“€ė¦¬ė˜ź³  ģžˆėŠ” 정볓넼 ģ‹ė³„ķ•˜ź³ , ģ •ė³“ģ˜ ģ¤‘ģš”ė„ģ™€ ģ‘ģš©ķ”„ė”œź·øėžØ ė° ģ‚¬ģš©ģž ģœ ķ˜• 등에 따넸 ģ ‘ź·¼ķ†µģ œ ģ •ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 6,"pass": 19,"total": 37,"manual": 0}},"2.6.5": {"name": "묓선 ė„¤ķŠøģ›Œķ¬ ģ ‘ź·¼","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.6.5 묓선 ė„¤ķŠøģ›Œķ¬ ģ ‘ź·¼","Subdomain": "2.6. ģ ‘ź·¼ķ†µģ œ","AuditEvidence": ["ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„","AP ė³“ģ•ˆ 설정 ė‚“ģ—­","ė¹„ģøź°€ 묓선 ė„¤ķŠøģ›Œķ¬ 점검 ģ“ė „","ė¬“ģ„ ė„¤ķŠøģ›Œķ¬ ģ‚¬ģš© ģ‹ ģ²­Ā·ģŠ¹ģø ģ“ė „"],"AuditChecklist": ["ė¬“ģ„ ė„¤ķŠøģ›Œķ¬ė„¼ ģ—…ė¬“ģ ģœ¼ė”œ ģ‚¬ģš©ķ•˜ėŠ” 경우 묓선 AP ė° ė„¤ķŠøģ›Œķ¬ 구간 ė³“ģ•ˆģ„ ģœ„ķ•˜ģ—¬ ģøģ¦, ģ†”ģˆ˜ģ‹  ė°ģ“ķ„° ģ•”ķ˜øķ™” 등 ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģøź°€ėœ ģž„ģ§ģ›ė§Œģ“ ė¬“ģ„ ė„¤ķŠøģ›Œķ¬ė„¼ ģ‚¬ģš©ķ•  수 ģžˆė„ė” ģ‚¬ģš© ģ‹ ģ²­ ė° ķ•“ģ§€ 절차넼 수립 ė° ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","AD Hoc ģ ‘ģ† ė° 씰직 ė‚“ ķ—ˆź°€ė°›ģ§€ ģ•Šģ€ 묓선 AP ķƒģ§€Ā·ģ°Øė‹Ø 등 ė¹„ģøź°€ėœ ė¬“ģ„ ė„¤ķŠøģ›Œķ¬ģ— ėŒ€ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ™øė¶€ģøģš© 묓선 ė„¤ķŠøģ›Œķ¬ģ™€ ė‚“ė¶€ 묓선 ė„¤ķŠøģ›Œķ¬ ģ˜ģ—­ėŒ€ź°€ ė™ģ¼ķ•˜ģ—¬ ģ™øė¶€ģøė„ ė¬“ģ„ ė„¤ķŠøģ›Œķ¬ė„¼ ķ†µķ•˜ģ—¬ ė³„ė„ģ˜ ķ†µģ œ ģ—†ģ“ ė‚“ė¶€ ė„¤ķŠøģ›Œķ¬ģ— ģ ‘ź·¼ģ“ ź°€ėŠ„ķ•œ 경우","사딀 2 : 묓선 AP 설정 ģ‹œ 정볓 ģ†”ģˆ˜ģ‹  ģ•”ķ˜øķ™” źø°ėŠ„ģ„ ģ„¤ģ •ķ•˜ģ˜€ģœ¼ė‚˜, ģ•ˆģ „ķ•˜ģ§€ ģ•Šģ€ ė°©ģ‹ģœ¼ė”œ ģ„¤ģ •ķ•œ 경우","사딀 3 : 업묓 목적으딜 ė‚“ė¶€ė§ģ— ģ—°ź²°ėœ 묓선AP에 ėŒ€ķ•˜ģ—¬ 묓선AP ź“€ė¦¬ģž ė¹„ė°€ė²ˆķ˜ø ė…øģ¶œ(ė””ķ“ķŠø ė¹„ė°€ė²ˆķ˜ø ģ‚¬ģš©), ģ ‘ź·¼ģ œģ–“ 미적용 등 ė³“ģ•ˆ ģ„¤ģ •ģ“ ėÆøķ”ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "묓선 ė„¤ķŠøģ›Œķ¬ė„¼ ģ‚¬ģš©ķ•˜ėŠ” 경우 ģ‚¬ģš©ģž ģøģ¦, ģ†”ģˆ˜ģ‹  ė°ģ“ķ„° ģ•”ķ˜øķ™”, AP ķ†µģ œ 등 묓선 ė„¤ķŠøģ›Œķ¬ ė³“ķ˜øėŒ€ģ±…ģ„ ģ ģš©ķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ė˜ķ•œ AD Hoc ģ ‘ģ†, ė¹„ģøź°€ AP ģ‚¬ģš© 등 ė¹„ģøź°€ 묓선 ė„¤ķŠøģ›Œķ¬ ģ ‘ģ†ģœ¼ė”œė¶€ķ„° ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.6.6": {"name": "원격접근 ķ†µģ œ","checks": {"vpc_flow_logs_enabled": "FAIL","networkfirewall_in_all_vpc": "FAIL","cognito_user_pool_mfa_enabled": null,"iam_user_console_access_unused": null,"vpc_subnet_no_public_ip_by_default": "FAIL","vpc_subnet_separate_private_public": "FAIL","iam_user_mfa_enabled_console_access": null,"workspaces_volume_encryption_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","appstream_fleet_maximum_session_duration": null,"ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","appstream_fleet_session_disconnect_timeout": null,"ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","cognito_identity_pool_guest_access_disabled": "FAIL","workspaces_vpc_2private_1public_subnets_nat": null,"cognito_user_pool_self_registration_disabled": null,"appstream_fleet_session_idle_disconnect_timeout": null,"appstream_fleet_default_internet_access_disabled": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"ec2_client_vpn_endpoint_connection_logging_enabled": null,"cloudwatch_log_metric_filter_authentication_failures": null,"ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.6.6 원격접근 ķ†µģ œ","Subdomain": "2.6. ģ ‘ź·¼ķ†µģ œ","AuditEvidence": ["VPN 등 ģ‚¬ģ™øģ ‘ģ† ģ‹ ģ²­ģ„œ","VPN 계정 ėŖ©ė”","VPN ģ ‘ź·¼ģ œģ–“ ģ •ģ±… 설정 ķ˜„ķ™©","IP ź“€ė¦¬ėŒ€ģž„","원격 ģ ‘ź·¼ģ œģ–“ 설정(ģ„œė²„ 설정, ė³“ģ•ˆģ‹œģŠ¤ķ…œ 설정 등)","ź“€ė¦¬ģš© 단말기 지정 ė° ꓀리 ķ˜„ķ™©","ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„"],"AuditChecklist": ["ģøķ„°ė„·ź³¼ ź°™ģ€ 외부 ė„¤ķŠøģ›Œķ¬ė„¼ ķ†µķ•œ ģ •ė³“ģ‹œģŠ¤ķ…œ ģ›ź²©ģš“ģ˜ģ€ ģ›ģ¹™ģ ģœ¼ė”œ źøˆģ§€ķ•˜ź³  ģž„ģ• ėŒ€ģ‘ 등 ė¶€ė“ģ“ķ•˜ź²Œ ķ—ˆģš©ķ•˜ėŠ” 경우 ė³“ģ™„ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","ė‚“ė¶€ ė„¤ķŠøģ›Œķ¬ė„¼ ķ†µķ•˜ģ—¬ ģ›ź²©ģœ¼ė”œ ģ •ė³“ģ‹œģŠ¤ķ…œģ„ ģš“ģ˜ķ•˜ėŠ” 경우 ķŠ¹ģ • 단말에 ķ•œķ•“ģ„œė§Œ ģ ‘ź·¼ģ„ ķ—ˆģš©ķ•˜ź³  ģžˆėŠ”ź°€?","ģž¬ķƒź·¼ė¬“, ģ›ź²©ķ˜‘ģ—…, ģŠ¤ė§ˆķŠøģ›Œķ¬ 등과 ź°™ģ€ 원격업묓 ģˆ˜ķ–‰ ģ‹œ ģ¤‘ģš”ģ •ė³“ 유출, 핓킹 등 침핓사고 ģ˜ˆė°©ģ„ ģœ„ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ꓀리, 욓영, 개발, ė³“ģ•ˆ ė“±ģ„ 목적으딜 ģ›ź²©ģœ¼ė”œ ź°œģøģ •ė³“ģ²˜ė¦¬ ģ‹œģŠ¤ķ…œģ— ģ ‘ģ†ķ•˜ėŠ” ė‹Øė§źø°ėŠ” ź“€ė¦¬ģš© ė‹Øė§źø°ė”œ ģ§€ģ •ķ•˜ź³  ģž„ģ˜ģ”°ģž‘ ė° 목적 외 ģ‚¬ģš© źøˆģ§€ 등 ģ•ˆģ „ģ”°ģ¹˜ė„¼ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ ź·œģ •ģ—ėŠ” ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ 원격 ģ ‘ź·¼ģ€ ģ›ģ¹™ģ ģœ¼ė”œ źøˆģ§€ķ•˜ź³  ė¶ˆź°€ķ”¼ķ•œ 경우 IP źø°ė°˜ģ˜ ģ ‘ź·¼ķ†µģ œė„¼ ķ†µķ•˜ģ—¬ ģŠ¹ģøėœ ģ‚¬ģš©ģžė§Œ 접근할 수 ģžˆė„ė” ėŖ…ģ‹œķ•˜ź³  ģžˆģœ¼ė‚˜, ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ 원격 ė°ģŠ¤ķ¬ķ†± ģ—°ź²°, SSH ģ ‘ģ†ģ“ IPģ£¼ģ†Œ ė“±ģœ¼ė”œ ģ œķ•œė˜ģ–“ ģžˆģ§€ ģ•Šģ•„ ėŖØė“  PCģ—ģ„œ 원격 ģ ‘ģ†ģ“ ź°€ėŠ„ķ•œ 경우","사딀 2 : ģ›ź²©ģš“ģ˜ź“€ė¦¬ė„¼ ģœ„ķ•˜ģ—¬ VPNģ„ źµ¬ģ¶•ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, VPN에 ėŒ€ķ•œ ģ‚¬ģš© ģŠ¹ģø ė˜ėŠ” ģ ‘ģ† źø°ź°„ ģ œķ•œ ģ—†ģ“ ģƒģ‹œ ķ—ˆģš©ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : 외부 ź·¼ė¬“ģžė„¼ ģœ„ķ•˜ģ—¬ ź°œģø 스마트 기기에 ģ—…ė¬“ģš© ėŖØė°”ģ¼ ģ•±ģ„ ģ„¤ģ¹˜ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ•…ģ„±ģ½”ė“œ, ė¶„ģ‹¤Ā·ė„ė‚œ 등에 ģ˜ķ•œ ź°œģøģ •ė³“ ģœ ģ¶œģ„ ė°©ģ§€ķ•˜źø° ģœ„ķ•œ ģ ģ ˆķ•œ ė³“ķ˜øėŒ€ģ±…(백신, ģ“ˆźø°ķ™”, ģ•”ķ˜øķ™” 등)ģ„ ģ ģš©ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : 외부 ģ ‘ģ†ģš© VPNģ—ģ„œ ģ‚¬ģš©ģžė³„ė”œ ģ›ź²©ģ ‘ź·¼ģ“ ź°€ėŠ„ķ•œ ė„¤ķŠøģ›Œķ¬ 구간 ė° ģ •ė³“ģ‹œģŠ¤ķ…œģ„ ģ œķ•œķ•˜ģ§€ ģ•Šģ•„ 원격접근 ģøģ¦ģ„ ė°›ģ€ ģ‚¬ģš©ģžź°€ 전첓 ė‚“ė¶€ė§ ė° ģ •ė³“ģ‹œģŠ¤ķ…œģ— ź³¼ė„ķ•˜ź²Œ ģ ‘ź·¼ģ“ ź°€ėŠ„ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "ė³“ķ˜øźµ¬ģ—­ ģ“ģ™ø ģž„ģ†Œģ—ģ„œģ˜ ģ •ė³“ģ‹œģŠ¤ķ…œ ꓀리 ė° ź°œģøģ •ė³“ ģ²˜ė¦¬ėŠ” ģ›ģ¹™ģ ģœ¼ė”œ źøˆģ§€ķ•˜ź³ , ģž¬ķƒź·¼ė¬“Ā·ģž„ģ• ėŒ€ģ‘Ā·ģ›ź²©ķ˜‘ģ—… 등 ė¶ˆź°€ķ”¼ķ•œ ģ‚¬ģœ ė”œ ģ›ź²©ģ ‘ź·¼ģ„ ķ—ˆģš©ķ•˜ėŠ” 경우 ģ±…ģž„ģž ģŠ¹ģø, ģ ‘ź·¼ 단말 지정, ģ ‘ź·¼ ķ—ˆģš©ė²”ģœ„ ė° źø°ź°„ 설정, ź°•ķ™”ėœ ģøģ¦, 구간 ģ•”ķ˜øķ™”, ģ ‘ģ†ė‹Øė§ ė³“ģ•ˆ(백신, 패치 등) 등 ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 8,"pass": 5,"total": 26,"manual": 0}},"2.6.7": {"name": "ģøķ„°ė„· ģ ‘ģ† ķ†µģ œ","checks": {"ec2_elastic_ip_shodan": null,"vpc_flow_logs_enabled": "FAIL","ec2_instance_public_ip": "FAIL","ec2_elastic_ip_unassigned": "FAIL","networkfirewall_in_all_vpc": "FAIL","vpc_subnet_no_public_ip_by_default": "FAIL","vpc_subnet_separate_private_public": "FAIL","workspaces_volume_encryption_enabled": null,"route53_dangling_ip_subdomain_takeover": null,"appstream_fleet_maximum_session_duration": null,"appstream_fleet_session_disconnect_timeout": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"workspaces_vpc_2private_1public_subnets_nat": null,"ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","appstream_fleet_session_idle_disconnect_timeout": null,"appstream_fleet_default_internet_access_disabled": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.6.7 ģøķ„°ė„· ģ ‘ģ† ķ†µģ œ","Subdomain": "2.6. ģ ‘ź·¼ķ†µģ œ","AuditEvidence": ["ė¹„ģ—…ė¬“ģ‚¬ģ“ķŠø(P2P 등) 차단정책(ė¹„ģ—…ė¬“ģ‚¬ģ“ķŠø ģ°Øė‹Øģ‹œģŠ¤ķ…œ ꓀리화멓 등)","ģøķ„°ė„· ģ ‘ģ†ė‚“ģ—­ ėŖØė‹ˆķ„°ė§ ģ“ė „","ģøķ„°ė„·ė§ ģ°Øė‹Øģ”°ģ¹˜ ėŒ€ģƒģž ėŖ©ė”","ė§ź°„ ģžė£Œ 전솔 절차 ė° ģ²˜ė¦¬ė‚“ģ—­(ģ‹ ģ²­Ā·ģŠ¹ģøė‚“ģ—­ 등)","ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„"],"AuditChecklist": ["ģ£¼ģš” 직묓 ģˆ˜ķ–‰ ė° ź°œģøģ •ė³“ ģ·Øźø‰ 단말기 등 ģ—…ė¬“ģš© PCģ˜ ģøķ„°ė„· ģ ‘ģ†ģ— ėŒ€ķ•œ ķ†µģ œģ •ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ£¼ģš” ģ •ė³“ģ‹œģŠ¤ķ…œ(DBģ„œė²„ 등)ģ—ģ„œ ė¶ˆķ•„ģš”ķ•œ 외부 ģøķ„°ė„· ģ ‘ģ†ģ„ ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?","꓀련 법령에 ė”°ė¼ ģøķ„°ė„·ė§ 차단 ģ˜ė¬“ź°€ ė¶€ź³¼ėœ 경우 ėŒ€ģƒģžė„¼ ģ‹ė³„ķ•˜ģ—¬ ģ•ˆģ „ķ•œ ė°©ģ‹ģœ¼ė”œ ģøķ„°ė„·ė§ 차단 씰치넼 ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ ė³“ķ˜øė²•ģ— ė”°ė¼ ģøķ„°ė„·ė§ 차단 씰치넼 ģ ģš©ķ•˜ģ˜€ģœ¼ė‚˜, ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ģ ‘ź·¼ź¶Œķ•œ 설정 ź°€ėŠ„ģž 등 ģ¼ė¶€ ģ˜ė¬“ėŒ€ģƒģžģ— ėŒ€ķ•˜ģ—¬ ģøķ„°ė„·ė§ 차단 씰치 ģ ģš©ģ“ ėˆ„ė½ėœ 경우","사딀 2 : ź°œģøģ •ė³“ ė³“ķ˜øė²•ģ— 따넸 ģøķ„°ė„·ė§ 차단 씰치 ģ˜ė¬“ėŒ€ģƒģœ¼ė”œģ„œ ģøķ„°ė„·ė§ 차단 씰치넼 ģ ģš©ķ•˜ģ˜€ģœ¼ė‚˜, 다넸 ģ„œė²„ė„¼ ź²½ģœ ķ•œ ģš°ķšŒģ ‘ģ†ģ“ ź°€ėŠ„ķ•˜ģ—¬ ģøķ„°ė„·ė§ 차단 ģ”°ģ¹˜ź°€ ģ ģš©ė˜ģ§€ ģ•Šģ€ ķ™˜ź²½ģ—ģ„œ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— ģ ‘ģ†ķ•˜ģ—¬ ź°œģøģ •ė³“ģ˜ ė‹¤ģš“ė”œė“œ, 파기 ė“±ģ“ ź°€ėŠ„ķ•œ 경우","사딀 3 : DMZ ė° ė‚“ė¶€ė§ģ— ģœ„ģ¹˜ķ•œ ģ¼ė¶€ ģ„œė²„ģ—ģ„œ ė¶ˆķ•„ģš”ķ•˜ź²Œ ģøķ„°ė„·ģœ¼ė”œģ˜ 직접 ģ ‘ģ†ģ“ ź°€ėŠ„ķ•œ 경우","사딀 4 : ģøķ„°ė„· PC와 ė‚“ė¶€ ģ—…ė¬“ģš© PC넼 물리적 ė§ė¶„ė¦¬ ė°©ģ‹ģœ¼ė”œ ģøķ„°ė„·ė§ 차단 씰치넼 ģ ģš©ķ•˜ź³  ė§ź°„ ģžė£Œģ „ģ†”ģ‹œģŠ¤ķ…œģ„ źµ¬ģ¶•Ā·ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, ģžė£Œ 전솔에 ėŒ€ķ•œ ģŠ¹ģø ģ ˆģ°Øź°€ ė¶€ģž¬ķ•˜ź³  ģžė£Œ 전솔 낓역에 ėŒ€ķ•œ 주기적 검토가 ģ“ė£Øģ–“ģ§€ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 5 : ė‚“ė¶€ ź·œģ •ģ—ėŠ” ź°œģøģ •ė³“ģ·Øźø‰ģžź°€ P2P ė° ģ›¹ķ•˜ė“œ ģ‚¬ģ“ķŠø ģ ‘ģ† ģ‹œ ģ±…ģž„ģž ģŠ¹ģøģ„ 거쳐 ķŠ¹ģ • źø°ź°„ ė™ģ•ˆė§Œ ķ—ˆģš©ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ģŠ¹ģøģ ˆģ°Øė„¼ ź±°ģ¹˜ģ§€ ģ•Šź³  ģ˜ˆģ™ø ģ ‘ģ†ģ“ ķ—ˆģš©ėœ 사딀가 ė‹¤ģˆ˜ ģ”“ģž¬ķ•˜ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "ģøķ„°ė„·ģ„ ķ†µķ•œ 정볓 유출, ģ•…ģ„±ģ½”ė“œ 감염, ė‚“ė¶€ė§ 침투 ė“±ģ„ ģ˜ˆė°©ķ•˜źø° ģœ„ķ•˜ģ—¬ ģ£¼ģš” ģ •ė³“ģ‹œģŠ¤ķ…œ, ģ£¼ģš” 직묓 ģˆ˜ķ–‰ ė° ź°œģøģ •ė³“ ģ·Øźø‰ 단말기 등에 ėŒ€ķ•œ ģøķ„°ė„· ģ ‘ģ† ė˜ėŠ” ģ„œė¹„ģŠ¤(P2P, ģ›¹ķ•˜ė“œ, 메신저 등)넼 ģ œķ•œķ•˜ėŠ” 등 ģøķ„°ė„· ģ ‘ģ† ķ†µģ œ ģ •ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 6,"pass": 1,"total": 19,"manual": 0}},"2.7.1": {"name": "ģ•”ķ˜øģ •ģ±… 적용","checks": {"elb_ssl_listeners": "FAIL","backup_vaults_exist": null,"elbv2_ssl_listeners": "FAIL","ssm_document_secrets": "PASS","backup_vaults_encrypted": "PASS","rds_snapshots_encrypted": "FAIL","elb_insecure_ssl_ciphers": "PASS","s3_bucket_kms_encryption": "FAIL","ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","elbv2_insecure_ssl_ciphers": "PASS","athena_workgroup_encryption": null,"ec2_ebs_snapshots_encrypted": "FAIL","s3_bucket_default_encryption": "PASS","ec2_instance_secrets_user_data": "PASS","ec2_launch_template_no_secrets": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","rds_instance_transport_encrypted": "FAIL","cloudtrail_kms_encryption_enabled": "FAIL","neptune_cluster_storage_encrypted": null,"s3_bucket_secure_transport_policy": "FAIL","documentdb_cluster_storage_encrypted": null,"workspaces_volume_encryption_enabled": null,"awslambda_function_no_secrets_in_code": "PASS","glue_database_connections_ssl_enabled": null,"athena_workgroup_enforce_configuration": null,"cloudfront_distributions_https_enabled": null,"cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudformation_stack_outputs_find_secrets": "PASS","codebuild_project_no_secrets_in_variables": "PASS","kafka_cluster_encryption_at_rest_uses_cmk": null,"sns_subscription_not_using_http_endpoints": "PASS","sns_topics_kms_encryption_at_rest_enabled": "FAIL","sqs_queues_server_side_encryption_enabled": "PASS","awslambda_function_no_secrets_in_variables": "PASS","dynamodb_tables_kms_cmk_encryption_enabled": null,"glue_etl_jobs_amazon_s3_encryption_enabled": "PASS","acm_certificates_with_secure_key_algorithms": "PASS","cloudwatch_log_group_kms_encryption_enabled": "FAIL","ecs_task_definitions_no_environment_secrets": "PASS","kafka_cluster_in_transit_encryption_enabled": null,"storagegateway_fileshare_encryption_enabled": null,"apigateway_restapi_client_certificate_enabled": "FAIL","glue_etl_jobs_job_bookmark_encryption_enabled": "FAIL","glue_data_catalogs_metadata_encryption_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"dynamodb_accelerator_cluster_encryption_enabled": null,"kafka_cluster_mutual_tls_authentication_enabled": null,"directoryservice_radius_server_security_protocol": null,"glue_development_endpoints_s3_encryption_enabled": null,"glue_etl_jobs_cloudwatch_logs_encryption_enabled": "FAIL","autoscaling_find_secrets_ec2_launch_configuration": "PASS","eks_cluster_kms_cmk_encryption_in_secrets_enabled": null,"elasticache_redis_cluster_rest_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"cloudfront_distributions_field_level_encryption_enabled": null,"cloudfront_distributions_using_deprecated_ssl_protocols": null,"elasticache_redis_cluster_in_transit_encryption_enabled": null,"opensearch_service_domains_https_communications_enforced": null,"sagemaker_training_jobs_intercontainer_encryption_enabled": null,"glue_data_catalogs_connection_passwords_encryption_enabled": "FAIL","glue_development_endpoints_job_bookmark_encryption_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null,"sagemaker_training_jobs_volume_and_output_encryption_enabled": null,"glue_development_endpoints_cloudwatch_logs_encryption_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.7.1 ģ•”ķ˜øģ •ģ±… 적용","Subdomain": "2.7. ģ•”ķ˜øķ™” 적용","AuditEvidence": ["ģ•”ķ˜øķ†µģ œ ģ •ģ±…(ėŒ€ģƒ, ė°©ģ‹, ģ•Œź³ ė¦¬ģ¦˜ 등)","ģ•”ķ˜øķ™” ģ ģš©ķ˜„ķ™©(ģ €ģž„ ė° 전솔 ģ‹œ)","ģœ„ķ—˜ė„ ė¶„ģ„ ź²°ź³¼(ė‚“ė¶€ė§ģ—ģ„œ ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø ģ“ģ™øģ˜ ź³ ģœ ģ‹ė³„ģ •ė³“ ģ•”ķ˜øķ™” 미적용 ģ‹œ)","ģ•”ķ˜øķ™” ģ†”ė£Øģ…˜ ꓀리 화멓"],"AuditChecklist": ["ź°œģøģ •ė³“ ė° ģ£¼ģš”ģ •ė³“ģ˜ 볓호넼 ģœ„ķ•˜ģ—¬ 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ė°˜ģ˜ķ•œ ģ•”ķ˜øķ™” ėŒ€ģƒ, ģ•”ķ˜øź°•ė„, ģ•”ķ˜øģ‚¬ģš© ė“±ģ“ ķ¬ķ•Øėœ ģ•”ķ˜øģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ģ•”ķ˜øģ •ģ±…ģ— ė”°ė¼ ź°œģøģ •ė³“ ė° ģ£¼ģš”ģ •ė³“ģ˜ ģ €ģž„, 전솔, 전달 ģ‹œ ģ•”ķ˜øķ™”ė„¼ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ 정책·지침에 ģ•”ķ˜øķ†µģ œ ꓀련 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ź³ ė ¤ķ•œ ģ•”ķ˜øķ™” ėŒ€ģƒ, ģ•”ķ˜ø ź°•ė„, ģ €ģž„ ė° 전솔 ģ‹œ ģ•”ķ˜øķ™” 방법, ģ•”ķ˜øķ™” ꓀련 ė‹“ė‹¹ģžģ˜ ģ—­ķ•  ė° ģ±…ģž„ 등에 ź“€ķ•œ ģ‚¬ķ•­ģ“ ģ ģ ˆķžˆ ėŖ…ģ‹œė˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģ•”ķ˜øģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ė©“ģ„œ 핓당 źø°ģ—…ģ“ ģ ģš©ė°›ėŠ” ė²•ź·œė„¼ ģž˜ėŖ» ģ ģš©ķ•˜ģ—¬ ģ•”ķ˜øķ™” ꓀련 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ģ¤€ģˆ˜ķ•˜ģ§€ ėŖ»ķ•˜ź³  ģžˆėŠ” 경우(예넼 들얓, ģ“ģš©ģžģ˜ ź³„ģ¢Œė²ˆķ˜øė„¼ ģ €ģž„ķ•˜ė©“ģ„œ ģ•”ķ˜øķ™” 미적용)","사딀 3 : ź°œģøģ •ė³“ģ·Øźø‰ģž ė° ģ •ė³“ģ£¼ģ²“ģ˜ ė¹„ė°€ė²ˆķ˜øģ— ėŒ€ķ•˜ģ—¬ ģ¼ė°©ķ–„ ģ•”ķ˜øķ™”ė„¼ ģ ģš©ķ•˜ģ˜€ģœ¼ė‚˜, ģ•ˆģ „ķ•˜ģ§€ ģ•Šģ€ MD5 ģ•Œź³ ė¦¬ģ¦˜ģ„ ģ‚¬ģš©ķ•œ 경우","사딀 4 : ź°œģøģ •ė³“ģ²˜ė¦¬ģžź°€ ꓀련 ė²•ź·œ ė° ė‚“ė¶€ ź·œģ •ģ— ė”°ė¼ ģøķ„°ė„· 쇼핑몰에 ėŒ€ķ•˜ģ—¬ ė³“ģ•ˆģ„œė²„ė„¼ ģ ģš©ķ•˜ģ˜€ģœ¼ė‚˜, ķšŒģ›ģ •ė³“ 씰회 ė° 변경, ė¹„ė°€ė²ˆķ˜ø 찾기, ė¹„ė°€ė²ˆķ˜ø 변경 등 ģ“ģš©ģžģ˜ ź°œģøģ •ė³“ź°€ ģ „ģ†”ė˜ėŠ” ģ¼ė¶€ 구간에 ģ•”ķ˜øķ™” ģ”°ģ¹˜ź°€ ėˆ„ė½ėœ 경우","사딀 5 : ģ •ė³“ģ‹œģŠ¤ķ…œ ģ ‘ģ†ģš© ė¹„ė°€ė²ˆķ˜ø, ģøģ¦ķ‚¤ ź°’ ė“±ģ“ ģ‹œģŠ¤ķ…œ ģ„¤ģ •ķŒŒģ¼ ė° ģ†ŒģŠ¤ģ½”ė“œ 낓에 ķ‰ė¬øģœ¼ė”œ ģ €ģž„ė˜ģ–“ ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제24ģ”°ģ˜2(ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø ģ²˜ė¦¬ģ˜ ģ œķ•œ), 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제7ģ”°(ź°œģøģ •ė³“ģ˜ ģ•”ķ˜øķ™”)"]}],"description": "ź°œģøģ •ė³“ ė° ģ£¼ģš”ģ •ė³“ 볓호넼 ģœ„ķ•˜ģ—¬ 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ė°˜ģ˜ķ•œ ģ•”ķ˜øķ™” ėŒ€ģƒ, ģ•”ķ˜ø ź°•ė„, ģ•”ķ˜ø ģ‚¬ģš© ģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ź°œģøģ •ė³“ ė° ģ£¼ģš”ģ •ė³“ģ˜ ģ €ģž„Ā·ģ „ģ†”Ā·ģ „ė‹¬ ģ‹œ ģ•”ķ˜øķ™”ė„¼ ģ ģš©ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 18,"pass": 19,"total": 66,"manual": 0}},"2.7.2": {"name": "ģ•”ķ˜øķ‚¤ ꓀리","checks": {"kms_cmk_are_used": null,"kms_cmk_rotation_enabled": null,"kms_key_not_publicly_accessible": null,"kms_cmk_not_deleted_unintentionally": null,"rds_instance_certificate_expiration": "PASS","secretsmanager_automatic_rotation_enabled": "FAIL","acm_certificates_transparency_logs_enabled": "PASS","directoryservice_ldap_certificate_expiration": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.7.2 ģ•”ķ˜øķ‚¤ ꓀리","Subdomain": "2.7. ģ•”ķ˜øķ™” 적용","AuditEvidence": ["ģ•”ķ˜øķ‚¤ ꓀리정책","ģ•”ķ˜øķ‚¤ ź“€ė¦¬ėŒ€ģž„ ė° ź“€ė¦¬ģ‹œģŠ¤ķ…œ 화멓"],"AuditChecklist": ["ģ•”ķ˜øķ‚¤ ģƒģ„±, ģ“ģš©, 볓꓀, ė°°ķ¬, 변경, 복구, 파기 등에 ź“€ķ•œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ•”ķ˜øķ‚¤ėŠ” ķ•„ģš”ģ‹œ 복구가 ź°€ėŠ„ķ•˜ė„ė” ė³„ė„ģ˜ ģ•ˆģ „ķ•œ ģž„ģ†Œģ— ė³“ź“€ķ•˜ź³  ģ•”ķ˜øķ‚¤ ģ‚¬ģš©ģ— ź“€ķ•œ ģ ‘ź·¼ź¶Œķ•œģ„ ģµœģ†Œķ™”ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ•”ķ˜ø ģ •ģ±… 낓에 ģ•”ķ˜øķ‚¤ ꓀리와 ź“€ė Øėœ 절차, 방법 ė“±ģ“ ėŖ…ģ‹œė˜ģ–“ ģžˆģ§€ ģ•Šģ•„ ė‹“ė‹¹ģžė³„ė”œ ģ•”ķ˜øķ‚¤ ꓀리 ģˆ˜ģ¤€ ė° 방법 ģƒģ“ 등 ģ•”ķ˜øķ‚¤ ꓀리에 ģ·Øģ•½ģ‚¬ķ•­ģ“ ģ”“ģž¬ķ•˜ėŠ” 경우","사딀 2 : ė‚“ė¶€ ź·œģ •ģ— ģ¤‘ģš” 정볓넼 ģ•”ķ˜øķ™” ķ•  경우 ꓀련 ģ±…ģž„ģž ģŠ¹ģø ķ•˜ģ— ģ•”ķ˜øķ™” 키넼 ģƒģ„±ķ•˜ź³  ģ•”ķ˜øķ‚¤ ź“€ė¦¬ėŒ€ģž„ģ„ ģž‘ģ„±ķ•˜ė„ė” ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ•”ķ˜øķ‚¤ ź“€ė¦¬ėŒ€ģž„ģ— ģ¼ė¶€ ģ•”ķ˜øķ‚¤ź°€ ėˆ„ė½ė˜ģ–“ ģžˆź±°ė‚˜ ķ˜„ķ–‰ķ™”ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ź°œė°œģ‹œģŠ¤ķ…œģ— ģ ģš©ė˜ģ–“ ģžˆėŠ” ģ•”ķ˜øķ‚¤ģ™€ ģš“ģ˜ģ‹œģŠ¤ķ…œģ— 적용된 ģ•”ķ˜øķ‚¤ź°€ ė™ģ¼ķ•˜ģ—¬, ģ•”ķ˜øķ™”ėœ ģ‹¤ė°ģ“ķ„°ź°€ ź°œė°œģ‹œģŠ¤ķ…œģ„ 통핓 ģ‰½ź²Œ ė³µķ˜øķ™”ź°€ ź°€ėŠ„ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제7ģ”°(ź°œģøģ •ė³“ģ˜ ģ•”ķ˜øķ™”)"]}],"description": "ģ•”ķ˜øķ‚¤ģ˜ ģ•ˆģ „ķ•œ ģƒģ„±Ā·ģ“ģš©Ā·ė³“ź“€Ā·ė°°ķ¬Ā·ķŒŒźø°ė„¼ ģœ„ķ•œ ꓀리 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ , ķ•„ģš” ģ‹œ ė³µźµ¬ė°©ģ•ˆģ„ ė§ˆė Øķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 1,"pass": 2,"total": 9,"manual": 0}},"2.8.1": {"name": "ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ ģ •ģ˜","checks": {"macie_is_enabled": "PASS","securityhub_enabled": "PASS","fms_policy_compliant": null,"guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","accessanalyzer_enabled": "PASS","networkfirewall_in_all_vpc": "FAIL","guardduty_centrally_managed": "FAIL","wafv2_webacl_logging_enabled": "FAIL","config_recorder_all_regions_enabled": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","codebuild_project_no_secrets_in_variables": "PASS","codebuild_project_user_controlled_buildspec": "PASS","wellarchitected_workload_no_high_or_medium_risks": "FAIL","codebuild_project_source_repo_url_no_sensitive_credentials": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.8.1 ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ ģ •ģ˜","Subdomain": "2.8. ģ •ė³“ģ‹œģŠ¤ķ…œ ė„ģž… ė° 개발 ė³“ģ•ˆ","AuditEvidence": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ģøģˆ˜ 기준 ė° 절차","ģ •ė³“ģ‹œģŠ¤ķ…œ ė„ģž… RFP(ģ œģ•ˆģš”ģ²­ģ„œ) ė° źµ¬ė§¤ź³„ģ•½ģ„œ","개발 ģ‚°ģ¶œė¬¼(ģ‚¬ģ—…ģˆ˜ķ–‰ź³„ķšģ„œ, ģš”źµ¬ģ‚¬ķ•­ģ •ģ˜ģ„œ, ķ™”ė©“ģ„¤ź³„ģ„œ, ė³“ģ•ˆģ•„ķ‚¤ķ…ģ²˜ ģ„¤ź³„ģ„œ, ģ‹œķ—˜ź³„ķšģ„œ 등)","ģ‹œķģ–“ 코딩 ķ‘œģ¤€"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œģ„ ģ‹ ź·œė”œ ė„ģž…Ā·ź°œė°œ ė˜ėŠ” ė³€ź²½ķ•˜ėŠ” 경우 ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ģø”ė©“ģ˜ ķƒ€ė‹¹ģ„± 검토 ė° ģøģˆ˜ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œģ„ ģ‹ ź·œė”œ ė„ģž…Ā·ź°œė°œ ė˜ėŠ” ė³€ź²½ķ•˜ėŠ” 경우 법적 ģš”źµ¬ģ‚¬ķ•­, ģµœģ‹  취약점 ė“±ģ„ ķ¬ķ•Øķ•œ ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ģ„ ėŖ…ķ™•ķžˆ ģ •ģ˜ķ•˜ź³  설계 ė‹Øź³„ģ—ģ„œė¶€ķ„° ė°˜ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ•ˆģ „ķ•œ źµ¬ķ˜„ģ„ ģœ„ķ•œ 코딩 ķ‘œģ¤€ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ģ‹œģŠ¤ķ…œ ģøģˆ˜ ģ „ ė³“ģ•ˆģ„± ź²€ģ¦ 기준 ė° ģ ˆģ°Øź°€ ė§ˆė Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ģ‹ ź·œ ģ‹œģŠ¤ķ…œ ė„ģž… ģ‹œ 기씓 ģš“ģ˜ķ™˜ź²½ģ— ėŒ€ķ•œ ģ˜ķ–„ ė° ė³“ģ•ˆģ„±ģ„ ź²€ķ† ķ•˜ė„ė” ė‚“ė¶€ ź·œģ •ģ„ ė§ˆė Øķ•˜ź³  ģžˆģœ¼ė‚˜, 최근 ė„ģž…ķ•œ ģ¼ė¶€ ģ •ė³“ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•˜ģ—¬ ģøģˆ˜ ģ‹œ ė³“ģ•ˆģš”ź±“ģ— ėŒ€ķ•“ 세부 기준 ė° ź³„ķšģ“ ģˆ˜ė¦½ė˜ģ§€ ģ•Šģ•˜ģœ¼ė©°, ģ“ģ— ė”°ė¼ ģøģˆ˜ ģ‹œ ė³“ģ•ˆģ„±ź²€ķ† ź°€ ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : 개발 ꓀련 ė‚“ė¶€ 지침에 개발과 ź“€ė Øėœ ģ£¼ģš” ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­(ģøģ¦ ė° ģ•”ķ˜øķ™”, ė³“ģ•ˆė”œź·ø 등)ģ“ ģ •ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : Ź»ź°œė°œķ‘œģ¤€ģ •ģ˜ģ„œŹ¼ģ— ģ‚¬ģš©ģž ķŒØģŠ¤ģ›Œė“œė„¼ ģ•ˆģ „ķ•˜ģ§€ ģ•Šģ€ ģ•”ķ˜øķ™” ģ•Œź³ ė¦¬ģ¦˜(MD5, SHA1)으딜 ģ‚¬ģš©ķ•˜ė„ė” ė˜ģ–“ ģžˆģ–“ ꓀련 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ģ ģ ˆķžˆ ė°˜ģ˜ķ•˜ģ§€ ģ•ŠėŠ” 경우"],"RelatedRegulations": []}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ė„ģž…Ā·ź°œė°œĀ·ė³€ź²½ ģ‹œ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜ø ꓀련 법적 ģš”źµ¬ģ‚¬ķ•­, ģµœģ‹  ė³“ģ•ˆģ·Øģ•½ģ , ģ•ˆģ „ķ•œ 코딩방법 등 ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ģ„ ģ •ģ˜ķ•˜ź³  ģ ģš©ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 7,"pass": 7,"total": 16,"manual": 0}},"2.8.2": {"name": "ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ 검토 ė° ģ‹œķ—˜","checks": {"macie_is_enabled": "PASS","securityhub_enabled": "PASS","fms_policy_compliant": null,"guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","accessanalyzer_enabled": "PASS","networkfirewall_in_all_vpc": "FAIL","guardduty_centrally_managed": "FAIL","wafv2_webacl_logging_enabled": "FAIL","inspector2_active_findings_exist": "FAIL","config_recorder_all_regions_enabled": null,"guardduty_no_high_severity_findings": "FAIL","cloudtrail_cloudwatch_logging_enabled": "FAIL","accessanalyzer_enabled_without_findings": "FAIL","codebuild_project_no_secrets_in_variables": "PASS","codebuild_project_user_controlled_buildspec": "PASS","wellarchitected_workload_no_high_or_medium_risks": "FAIL","codebuild_project_source_repo_url_no_sensitive_credentials": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.8.2 ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ 검토 ė° ģ‹œķ—˜","Subdomain": "2.8. ģ •ė³“ģ‹œģŠ¤ķ…œ ė„ģž… ė° 개발 ė³“ģ•ˆ","AuditEvidence": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ģøģˆ˜ ģ‹œķ—˜ ź²°ź³¼","ģš”źµ¬ģ‚¬ķ•­ 추적 매트릭스","ģ‹œķ—˜ ź³„ķšģ„œ, ģ‹œķ—˜ ź²°ź³¼ģ„œ","취약점 점검 ź²°ź³¼ģ„œ","ź°œģøģ •ė³“ ģ˜ķ–„ķ‰ź°€ģ„œ","ź°œģøģ •ė³“ ģ˜ķ–„ķ‰ź°€ ź°œģ„ ź³„ķš ģ“ķ–‰ģ ź²€ ķ™•ģøģ„œ"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ė„ģž…, 개발, 변경 ģ‹œ ė¶„ģ„ ė° 설계 ė‹Øź³„ģ—ģ„œ ģ •ģ˜ķ•œ ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ģ“ 효과적으딜 ģ ģš©ė˜ģ—ˆėŠ”ģ§€ė„¼ ķ™•ģøķ•˜źø° ģœ„ķ•œ ģ‹œķ—˜ģ„ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œģ“ ģ•ˆģ „ķ•œ 코딩 기준 등에 ė”°ė¼ ģ•ˆģ „ķ•˜ź²Œ ź°œė°œė˜ģ—ˆėŠ”ģ§€ė„¼ ķ™•ģøķ•˜źø° ģœ„ķ•œ 취약점 ģ ź²€ģ“ ģˆ˜ķ–‰ė˜ź³  ģžˆėŠ”ź°€?","ģ‹œķ—˜ ė° 취약점 점검 ź³¼ģ •ģ—ģ„œ 발견된 ė¬øģ œģ ģ“ ģ‹ ģ†ķ•˜ź²Œ ź°œģ„ ė  수 ģžˆė„ė” ź°œģ„ ź³„ķš 수립, ģ“ķ–‰ģ ź²€ ė“±ģ˜ 절차넼 ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ź³µź³µźø°ź“€ģ€ ꓀련 법령에 ė”°ė¼ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ģ‹ ź·œ 개발 ė° 변경 ģ‹œ ė¶„ģ„Ā·ģ„¤ź³„ ė‹Øź³„ģ—ģ„œ ģ˜ķ–„ķ‰ź°€źø°ź“€ģ„ ķ†µķ•˜ģ—¬ ģ˜ķ–„ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•˜ź³  ź·ø 결과넼 개발 ė° 변경 ģ‹œ ė°˜ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ •ė³“ģ‹œģŠ¤ķ…œ źµ¬ķ˜„ ģ“ķ›„ 개발 ꓀련 ė‚“ė¶€ 지침 ė° ė¬øģ„œģ— ģ •ģ˜ėœ ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ģ„ ģ‹œķ—˜ķ•˜ģ§€ ģ•Šź³  ģžˆėŠ” 경우","사딀 2 : ģ‘ģš©ķ”„ė”œź·øėžØ ķ…ŒģŠ¤ķŠø ģ‹œė‚˜ė¦¬ģ˜¤ ė° 기술적 취약점 점검항목에 ģž…ė „ź°’ ģœ ķšØģ„± 첓크 ė“±ģ˜ ģ¤‘ģš” 점검항목 ģ¼ė¶€ź°€ ėˆ„ė½ėœ 경우","사딀 3 : źµ¬ķ˜„ ė˜ėŠ” ģ‹œķ—˜ ź³¼ģ •ģ—ģ„œ ģ•Œė ¤ģ§„ 기술적 ģ·Øģ•½ģ ģ“ ģ”“ģž¬ķ•˜ėŠ”ģ§€ 여부넼 ģ ź²€ķ•˜ģ§€ ģ•Šź±°ė‚˜, ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ė˜ėŠ” ģŠ¹ģø ģ—†ģ“ ķ™•ģøėœ 취약점에 ėŒ€ķ•œ ź°œģ„ ģ”°ģ¹˜ė„¼ ģ“ķ–‰ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ź³µź³µźø°ź“€ģ“ 5만 ėŖ… ģ“ģƒ ģ •ė³“ģ£¼ģ²“ģ˜ ź³ ģœ ģ‹ė³„ģ •ė³“ė„¼ ģ²˜ė¦¬ķ•˜ėŠ” 등 ģ˜ķ–„ķ‰ź°€ ģ˜ė¬“ ėŒ€ģƒ ź°œģøģ •ė³“ ķŒŒģ¼ ė° ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ„ ģ‹ ź·œė”œ źµ¬ģ¶•ķ•˜ė©“ģ„œ ģ˜ķ–„ķ‰ź°€ė„¼ ģ‹¤ģ‹œķ•˜ģ§€ ģ•Šģ€ 경우","사딀 5 : ź³µź³µźø°ź“€ģ“ ģ˜ķ–„ķ‰ź°€ė„¼ ģˆ˜ķ–‰ķ•œ 후 ģ˜ķ–„ķ‰ź°€źø°ź“€ģœ¼ė”œė¶€ķ„° ģ˜ķ–„ķ‰ź°€ģ„œė„¼ ė°›ģ€ ģ§€ 2ź°œģ›”ģ“ ģ§€ė‚¬ģŒģ—ė„ ė¶ˆźµ¬ķ•˜ź³  ģ˜ķ–„ķ‰ź°€ģ„œė„¼ ź°œģøģ •ė³“ ė³“ķ˜øģœ„ģ›ķšŒģ— ģ œģ¶œķ•˜ģ§€ ģ•Šģ€ 경우","사딀 6 : ģ‹ ź·œ ģ‹œģŠ¤ķ…œ ė„ģž… ģ‹œ 기씓 ģš“ģ˜ķ™˜ź²½ģ— ėŒ€ķ•œ ģ˜ķ–„ ė° ė³“ģ•ˆģ„±ģ„ 검토(취약점 점검 등)ķ•˜ė„ė” ė‚“ė¶€ ģ§€ģ¹Øģ„ ė§ˆė Øķ•˜ź³  ģžˆģœ¼ė‚˜, 최근 ė„ģž…ķ•œ ģ¼ė¶€ ģ •ė³“ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•˜ģ—¬ ģøģˆ˜ ģ‹œ 취약점 점검 등 ė³“ģ•ˆģ„±ź²€ķ† ź°€ ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제33ģ”°(ź°œģøģ •ė³“ ģ˜ķ–„ķ‰ź°€)","ź°œģøģ •ė³“ ģ˜ķ–„ķ‰ź°€ģ— ź“€ķ•œ ź³ ģ‹œ"]}],"description": "사전 ģ •ģ˜ėœ ė³“ģ•ˆ ģš”źµ¬ģ‚¬ķ•­ģ— ė”°ė¼ ģ •ė³“ģ‹œģŠ¤ķ…œģ“ ė„ģž… ė˜ėŠ” źµ¬ķ˜„ė˜ģ—ˆėŠ”ģ§€ė„¼ ź²€ķ† ķ•˜źø° ģœ„ķ•˜ģ—¬ 법적 ģš”źµ¬ģ‚¬ķ•­ ģ¤€ģˆ˜, ģµœģ‹  ė³“ģ•ˆģ·Øģ•½ģ  점검, ģ•ˆģ „ķ•œ 코딩 źµ¬ķ˜„, ź°œģøģ •ė³“ ģ˜ķ–„ķ‰ź°€ ė“±ģ˜ 검토 기준과 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ , 발견된 ė¬øģ œģ ģ— ėŒ€ķ•œ ź°œģ„ ģ”°ģ¹˜ė„¼ ģˆ˜ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 10,"pass": 7,"total": 19,"manual": 0}},"2.8.3": {"name": "ģ‹œķ—˜ź³¼ 욓영 ķ™˜ź²½ 분리","checks": {"codebuild_project_user_controlled_buildspec": "PASS"},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.8.3 ģ‹œķ—˜ź³¼ 욓영 ķ™˜ź²½ 분리","Subdomain": "2.8. ģ •ė³“ģ‹œģŠ¤ķ…œ ė„ģž… ė° 개발 ė³“ģ•ˆ","AuditEvidence": ["ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„(ģ‹œķ—˜ķ™˜ź²½ 구성 ķ¬ķ•Ø)","욓영 ķ™˜ź²½ź³¼ ź°œė°œĀ·ģ‹œķ—˜ ķ™˜ź²½ ź°„ ģ ‘ź·¼ķ†µģ œ 적용 ķ˜„ķ™©"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ 개발 ė° ģ‹œķ—˜ ģ‹œģŠ¤ķ…œģ„ ģš“ģ˜ģ‹œģŠ¤ķ…œź³¼ ė¶„ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ė¶ˆź°€ķ”¼ķ•œ ģ‚¬ģœ ė”œ 개발과 ģš“ģ˜ķ™˜ź²½ģ˜ 분리가 ģ–“ė ¤ģš“ 경우 ģƒķ˜øź²€ķ† , ģƒźø‰ģž ėŖØė‹ˆķ„°ė§, 변경 ģŠ¹ģø, ģ±…ģž„ģ¶”ģ ģ„± 확볓 ė“±ģ˜ ė³“ģ•ˆėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ė˜ėŠ” ģŠ¹ģø ģ—†ģ“ ė³„ė„ģ˜ ź°œė°œķ™˜ź²½ģ„ źµ¬ģ„±ķ•˜ģ§€ ģ•Šź³  ģš“ģ˜ķ™˜ź²½ģ—ģ„œ 직접 ģ†ŒģŠ¤ģ½”ė“œ ė³€ź²½ģ„ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : ė¶ˆź°€ķ”¼ķ•˜ź²Œ ź°œė°œģ‹œģŠ¤ķ…œź³¼ ģš“ģ˜ģ‹œģŠ¤ķ…œģ„ ė¶„ė¦¬ķ•˜ģ§€ ģ•Šź³  욓영 중에 ģžˆģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•œ 상호 검토 ė‚“ģ—­, ėŖØė‹ˆķ„°ė§ ė‚“ģ—­ ė“±ģ“ ėˆ„ė½ė˜ģ–“ ģžˆėŠ” 경우","사딀 3 : ź°œė°œģ‹œģŠ¤ķ…œģ“ ė³„ė„ė”œ źµ¬ģ„±ė˜ģ–“ ģžˆģœ¼ė‚˜, ź°œė°œķ™˜ź²½ģœ¼ė”œė¶€ķ„° ģš“ģ˜ķ™˜ź²½ģœ¼ė”œģ˜ ģ ‘ź·¼ģ“ ķ†µģ œė˜ģ§€ ģ•Šģ•„ ź°œė°œģžė“¤ģ“ ź°œė°œģ‹œģŠ¤ķ…œģ„ ź²½ģœ ķ•˜ģ—¬ ė¶ˆķ•„ģš”ķ•˜ź²Œ ģš“ģ˜ģ‹œģŠ¤ķ…œ ģ ‘ź·¼ģ“ ź°€ėŠ„ķ•œ 경우"],"RelatedRegulations": []}],"description": "개발 ė° ģ‹œķ—˜ ģ‹œģŠ¤ķ…œģ€ ģš“ģ˜ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ė¹„ģøź°€ ģ ‘ź·¼ ė° ė³€ź²½ģ˜ ģœ„ķ—˜ģ„ ź°ģ†Œģ‹œķ‚¤źø° ģœ„ķ•˜ģ—¬ ģ›ģ¹™ģ ģœ¼ė”œ ė¶„ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.8.4": {"name": "ģ‹œķ—˜ ė°ģ“ķ„° ė³“ģ•ˆ","checks": {"codebuild_project_no_secrets_in_variables": "PASS"},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.8.4 ģ‹œķ—˜ ė°ģ“ķ„° ė³“ģ•ˆ","Subdomain": "2.8. ģ •ė³“ģ‹œģŠ¤ķ…œ ė„ģž… ė° 개발 ė³“ģ•ˆ","AuditEvidence": ["ģ‹œķ—˜ė°ģ“ķ„° ķ˜„ķ™©","ģ‹œķ—˜ė°ģ“ķ„° ģƒģ„± ź·œģ¹™","ģš“ģ˜ė°ģ“ķ„°ė„¼ ģ‹œķ—˜ķ™˜ź²½ģ— ģ‚¬ģš©ķ•œ 경우, ꓀련 ģŠ¹ģø ģ“ė „"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ 개발 ė° ģ‹œķ—˜ ź³¼ģ •ģ—ģ„œ ģ‹¤ģ œ 욓영 ė°ģ“ķ„°ģ˜ ģ‚¬ģš©ģ„ ģ œķ•œķ•˜ź³  ģžˆėŠ”ź°€?","ė¶ˆź°€ķ”¼ķ•˜ź²Œ ģš“ģ˜ė°ģ“ķ„°ė„¼ ģ‹œķ—˜ ķ™˜ź²½ģ—ģ„œ ģ‚¬ģš©ķ•  경우 ģ±…ģž„ģž ģŠ¹ģø, ģ ‘ź·¼ ė° ģœ ģ¶œėŖØė‹ˆķ„°ė§, ģ‹œķ—˜ 후 ė°ģ“ķ„° ģ‚­ģ œ ė“±ģ˜ ķ†µģ œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 개발 ģ„œė²„ģ—ģ„œ ģ‚¬ģš©ķ•  ģ‹œķ—˜ ė°ģ“ķ„° ģƒģ„±ģ— ėŒ€ķ•œ 구첓적 기준 ė° ģ ˆģ°Øź°€ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ė° ģ±…ģž„ģž ģŠ¹ģø ģ—†ģ“ 실 ģš“ģ˜ė°ģ“ķ„°ė„¼ ź°€ź³µķ•˜ģ§€ ģ•Šź³  ģ‹œķ—˜ ė°ģ“ķ„°ė”œ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : ė¶ˆź°€ķ”¼ķ•œ ģ‚¬ģœ ė”œ 사전 ģŠ¹ģøģ„ 받아 실 ģš“ģ˜ė°ģ“ķ„°ė„¼ ģ‹œķ—˜ ģš©ė„ė”œ ģ‚¬ģš©ķ•˜ė©“ģ„œ, ķ…ŒģŠ¤ķŠø ė°ģ“ķ„°ė² ģ“ģŠ¤ģ— ėŒ€ķ•˜ģ—¬ 욓영 ė°ģ“ķ„°ė² ģ“ģŠ¤ģ™€ ė™ģ¼ķ•œ ģˆ˜ģ¤€ģ˜ ģ ‘ź·¼ķ†µģ œė„¼ ģ ģš©ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : 실 ģš“ģ˜ė°ģ“ķ„°ė„¼ ķ…ŒģŠ¤ķŠø ģš©ė„ė”œ ģ‚¬ģš©ķ•œ 후 ķ…ŒģŠ¤ķŠøź°€ ģ™„ė£Œė˜ģ—ˆģŒģ—ė„ 실 ģš“ģ˜ė°ģ“ķ„°ė„¼ ķ…ŒģŠ¤ķŠø ė°ģ“ķ„°ė² ģ“ģŠ¤ģ—ģ„œ ģ‚­ģ œķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ģ‹œģŠ¤ķ…œ ģ‹œķ—˜ ź³¼ģ •ģ—ģ„œ ģš“ģ˜ė°ģ“ķ„°ģ˜ ģœ ģ¶œģ„ ģ˜ˆė°©ķ•˜źø° ģœ„ķ•˜ģ—¬ ģ‹œķ—˜ ė°ģ“ķ„°ģ˜ ģƒģ„±ź³¼ ģ“ģš© ė° ꓀리, 파기, 기술적 ė³“ķ˜øģ”°ģ¹˜ģ— ź“€ķ•œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.8.5": {"name": "ģ†ŒģŠ¤ ķ”„ė”œź·øėžØ ꓀리","checks": {"ecr_repositories_not_publicly_accessible": "PASS","codeartifact_packages_external_public_publishing_disabled": null},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.8.5 ģ†ŒģŠ¤ ķ”„ė”œź·øėžØ ꓀리","Subdomain": "2.8. ģ •ė³“ģ‹œģŠ¤ķ…œ ė„ģž… ė° 개발 ė³“ģ•ˆ","AuditEvidence": ["SVN 등 ķ˜•ģƒź“€ė¦¬ģ‹œģŠ¤ķ…œ 욓영 ķ˜„ķ™©(ģ ‘ź·¼ź¶Œķ•œģž ėŖ©ė” 등)","ģ†ŒģŠ¤ ķ”„ė”œź·øėžØ 변경 ģ“ė „"],"AuditChecklist": ["ė¹„ģøź°€ģžģ— ģ˜ķ•œ ģ†ŒģŠ¤ ķ”„ė”œź·øėžØ ģ ‘ź·¼ģ„ ķ†µģ œķ•˜źø° ģœ„ķ•œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ†ŒģŠ¤ ķ”„ė”œź·øėžØģ€ ģž„ģ•  등 ė¹„ģƒģ‹œė„¼ ėŒ€ė¹„ķ•˜ģ—¬ ģš“ģ˜ķ™˜ź²½ģ“ ģ•„ė‹Œ 곳에 ģ•ˆģ „ķ•˜ź²Œ ė³“ź“€ķ•˜ź³  ģžˆėŠ”ź°€?","ģ†ŒģŠ¤ ķ”„ė”œź·øėžØģ— ėŒ€ķ•œ ė³€ź²½ģ“ė „ģ„ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė³„ė„ģ˜ ģ†ŒģŠ¤ ķ”„ė”œź·øėžØ 백업 ė° ķ˜•ģƒź“€ė¦¬ģ‹œģŠ¤ķ…œģ“ źµ¬ģ¶•ė˜ģ–“ ģžˆģ§€ ģ•Šģœ¼ė©°, ģ“ģ „ ė²„ģ „ģ˜ ģ†ŒģŠ¤ ģ½”ė“œė„¼ 욓영 ģ„œė²„ ė˜ėŠ” ź°œė°œģž PC에 ģŠ¹ģø ė° ģ“ė „ź“€ė¦¬ ģ—†ģ“ ė³“ź“€ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : ķ˜•ģƒź“€ė¦¬ģ‹œģŠ¤ķ…œģ„ źµ¬ģ¶•ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜ ķ˜•ģƒź“€ė¦¬ģ‹œģŠ¤ķ…œ ė˜ėŠ” ķ˜•ģƒź“€ė¦¬ģ‹œģŠ¤ķ…œģ— ģ €ģž„ėœ ģ†ŒģŠ¤ģ½”ė“œģ— ėŒ€ķ•œ ģ ‘ź·¼ģ œķ•œ, ģ ‘ź·¼ ė° ė³€ź²½ģ“ė „ģ“ ģ ģ ˆķžˆ ź“€ė¦¬ė˜ģ§€ ģ•Šź³  ģžˆėŠ” 경우","사딀 3 : ė‚“ė¶€ ź·œģ •ģ—ėŠ” ķ˜•ģƒź“€ė¦¬ģ‹œģŠ¤ķ…œģ„ ķ†µķ•˜ģ—¬ ģ†ŒģŠ¤ ķ”„ė”œź·øėžØ 버전꓀리넼 ķ•˜ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ģµœģ‹  ė²„ģ „ģ˜ ģ†ŒģŠ¤ ķ”„ė”œź·øėžØģ€ ź°œė°œģž PCģ—ė§Œ ė³“ź“€ė˜ģ–“ ģžˆź³  ģ“ģ— ėŒ€ķ•œ ė³„ė„ģ˜ ė°±ģ—…ģ“ ģˆ˜ķ–‰ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ģ†ŒģŠ¤ ķ”„ė”œź·øėžØģ€ ģøź°€ėœ ģ‚¬ģš©ģžė§Œģ“ 접근할 수 ģžˆė„ė” ź“€ė¦¬ķ•˜ź³ , ģš“ģ˜ķ™˜ź²½ģ— ė³“ź“€ķ•˜ģ§€ ģ•ŠėŠ” ź²ƒģ„ ģ›ģ¹™ģœ¼ė”œ ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"2.8.6": {"name": "ģš“ģ˜ķ™˜ź²½ ģ“ź“€","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.8.6 ģš“ģ˜ķ™˜ź²½ ģ“ź“€","Subdomain": "2.8. ģ •ė³“ģ‹œģŠ¤ķ…œ ė„ģž… ė° 개발 ė³“ģ•ˆ","AuditEvidence": ["ģ“ź“€ 절차","ģ“ź“€ ė‚“ģ—­(ģ‹ ģ²­Ā·ģŠ¹ģø, ģ‹œķ—˜, ģ“ź“€ 등)"],"AuditChecklist": ["ģ‹ ź·œ ė„ģž…Ā·ź°œė°œ ė° ė³€ź²½ėœ ģ‹œģŠ¤ķ…œģ„ ģš“ģ˜ķ™˜ź²½ģœ¼ė”œ ģ•ˆģ „ķ•˜ź²Œ ģ“ź“€ķ•˜źø° ģœ„ķ•œ ķ†µģ œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģš“ģ˜ķ™˜ź²½ģœ¼ė”œ ģ“ź“€ ģ‹œ ė°œģƒķ•  수 ģžˆėŠ” ė¬øģ œģ— ėŒ€ķ•œ ėŒ€ģ‘ ė°©ģ•ˆģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","ģš“ģ˜ķ™˜ź²½ģ—ėŠ” ģ„œė¹„ģŠ¤ 실행에 ķ•„ģš”ķ•œ ķŒŒģ¼ė§Œģ„ ģ„¤ģ¹˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œė°œĀ·ė³€ź²½ģ“ ģ™„ė£Œėœ ģ†ŒģŠ¤ ķ”„ė”œź·øėžØģ„ ģš“ģ˜ķ™˜ź²½ģœ¼ė”œ ģ“ź“€ ģ‹œ ź²€ķ† Ā·ģŠ¹ģøķ•˜ėŠ” ģ ˆģ°Øź°€ ė§ˆė Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ģš“ģ˜ģ„œė²„ģ— ģ„œė¹„ģŠ¤ 실행에 ė¶ˆķ•„ģš”ķ•œ ķŒŒģ¼(ģ†ŒģŠ¤ģ½”ė“œ ė˜ėŠ” ė°°ķ¬ėŖØė“ˆ, 백업본, 개발 ꓀련 ė¬øģ„œ, 매뉓얼 등)ģ“ ģ”“ģž¬ķ•˜ėŠ” 경우","사딀 3 : ė‚“ė¶€ 지침에 ģš“ģ˜ķ™˜ź²½ ģ“ź“€ ģ‹œ ģ•ˆģ „ķ•œ ģ“ź“€Ā·ė³µźµ¬ė„¼ ģœ„ķ•˜ģ—¬ ė³€ź²½ģž‘ģ—… ģš”ģ²­ģ„œ ė° ź²°ź³¼ģ„œė„¼ ģž‘ģ„±ķ•˜ė„ė” ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, ꓀련 ė¬øģ„œź°€ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ė‚“ė¶€ ģ§€ģ¹Øģ—ėŠ” ėŖØė°”ģ¼ ģ•±ģ„ ģ•±ė§ˆģ¼“ģ— ė°°ķ¬ķ•˜ėŠ” 경우 ė‚“ė¶€ 검토 ė° ģŠ¹ģøģ„ ė°›ė„ė” ķ•˜ź³  ģžˆģœ¼ė‚˜, ź°œė°œģžź°€ 핓당 절차넼 ź±°ģ¹˜ģ§€ ģ•Šź³  ģž„ģ˜ė”œ ģ•±ė§ˆģ¼“ģ— ė°°ķ¬ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": []}],"description": "ģ‹ ź·œ ė„ģž…Ā·ź°œė°œ ė˜ėŠ” ė³€ź²½ėœ ģ‹œģŠ¤ķ…œģ„ ģš“ģ˜ķ™˜ź²½ģœ¼ė”œ ģ“ź“€ķ•  ė•ŒėŠ” ķ†µģ œėœ 절차넼 ė”°ė¼ģ•¼ ķ•˜ź³ , ģ‹¤ķ–‰ģ½”ė“œėŠ” ģ‹œķ—˜ ė° ģ‚¬ģš©ģž ģøģˆ˜ ģ ˆģ°Øģ— ė”°ė¼ ģ‹¤ķ–‰ė˜ģ–“ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.9.1": {"name": "변경꓀리","checks": {"codebuild_project_older_90_days": "FAIL","config_recorder_all_regions_enabled": null,"cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.9.1 변경꓀리","Subdomain": "2.9. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ģš“ģ˜ź“€ė¦¬","AuditEvidence": ["변경꓀리 절차","변경꓀리 ģˆ˜ķ–‰ ė‚“ģ—­(ģ‹ ģ²­Ā·ģŠ¹ģø, 변경 ė‚“ģ—­ 등)","변경에 따넸 ģ˜ķ–„ė¶„ģ„ ź²°ź³¼"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ꓀련 ģžģ‚°(ķ•˜ė“œģ›Øģ–“, 욓영첓제, 상용 ģ†Œķ”„ķŠøģ›Øģ–“ ķŒØķ‚¤ģ§€ 등) 변경에 ź“€ķ•œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œ ꓀련 ģžģ‚° ė³€ź²½ģ„ ģˆ˜ķ–‰ķ•˜źø° ģ „ ģ„±ėŠ„ ė° ė³“ģ•ˆģ— ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ė¶„ģ„ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 최근 DMZ 구간 ģ“ģ¤‘ķ™”ģ— 따넸 변경 ģž‘ģ—…ģ„ ģˆ˜ķ–‰ķ•˜ģ˜€ģœ¼ė‚˜, 변경 후 ė°œģƒķ•  수 ģžˆėŠ” ė³“ģ•ˆģœ„ķ—˜ģ„± ė° ģ„±ėŠ„ ķ‰ź°€ģ— ėŒ€ķ•œ ģˆ˜ķ–‰Ā·ģŠ¹ģø ģ¦ź±°ģžė£Œź°€ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우","사딀 2 : 최근 ė„¤ķŠøģ›Œķ¬ 변경 ģž‘ģ—…ģ„ ģˆ˜ķ–‰ķ•˜ģ˜€ģœ¼ė‚˜ ꓀련 검토 ė° 공지가 ģ¶©ė¶„ķžˆ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ•„ ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„ ė° ģ¼ė¶€ ģ ‘ź·¼ķ†µģ œģ‹œģŠ¤ķ…œ(ģ¹Øģž…ģ°Øė‹Øģ‹œģŠ¤ķ…œ, ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ģ œģ–“ģ‹œģŠ¤ķ…œ 등)ģ˜ ģ ‘ź·¼ķ†µģ œ 리스트(ACL)에 ģ ģ ˆķžˆ ė°˜ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ė³€ź²½ź“€ė¦¬ģ‹œģŠ¤ķ…œģ„ źµ¬ģ¶•ķ•˜ģ—¬ ģ •ė³“ģ‹œģŠ¤ķ…œ ģž…ź³  ė˜ėŠ” 변경 ģ‹œ ģ„±ėŠ„ ė° ė³“ģ•ˆģ— ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ė¶„ģ„ ė°ķ˜‘ģ˜ķ•˜ź³  ꓀련 ģ“ė „ģ„ ź“€ė¦¬ķ•˜ė„ė” ķ•˜ź³  ģžˆģœ¼ė‚˜, 핓당 ģ‹œģŠ¤ķ…œģ„ ķ†µķ•˜ģ§€ ģ•Šź³ ė„ ģ‹œģŠ¤ķ…œ ė³€ź²½ģ“ ź°€ėŠ„ķ•˜ė©°, ꓀련 ė³€ź²½ģ‚¬ķ•­ģ“ ģ ģ ˆķžˆ ź²€ķ† ė˜ģ§€ ģ•ŠėŠ” 경우"],"RelatedRegulations": []}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œ ꓀련 ģžģ‚°ģ˜ ėŖØė“  ė³€ź²½ė‚“ģ—­ģ„ ꓀리할 수 ģžˆė„ė” 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ , 변경 ģ „ ģ‹œģŠ¤ķ…œģ˜ ģ„±ėŠ„ ė° ė³“ģ•ˆģ— ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ė¶„ģ„ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 2,"pass": 0,"total": 14,"manual": 0}},"2.9.2": {"name": "ģ„±ėŠ„ ė° ģž„ģ• ź“€ė¦¬","checks": {"rds_cluster_multi_az": "FAIL","elb_is_in_multiple_az": "FAIL","rds_instance_multi_az": "FAIL","elbv2_is_in_multiple_az": "PASS","s3_bucket_no_mfa_delete": "FAIL","vpc_subnet_different_az": "PASS","neptune_cluster_multi_az": null,"elbv2_deletion_protection": "FAIL","autoscaling_group_multiple_az": null,"dms_instance_multi_az_enabled": null,"rds_cluster_backtrack_enabled": null,"cloudtrail_multi_region_enabled": "PASS","rds_cluster_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL","acm_certificates_expiration_check": "PASS","s3_bucket_cross_region_replication": "FAIL","trustedadvisor_errors_and_warnings": null,"config_recorder_all_regions_enabled": null,"kms_cmk_not_deleted_unintentionally": null,"neptune_cluster_deletion_protection": null,"networkfirewall_deletion_protection": null,"rds_instance_certificate_expiration": "PASS","route53_domains_transferlock_enabled": null,"cloudtrail_bucket_requires_mfa_delete": null,"elb_cross_zone_load_balancing_enabled": "PASS","documentdb_cluster_deletion_protection": null,"documentdb_cluster_cloudwatch_log_export": null,"ec2_instance_detailed_monitoring_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","iam_no_expired_server_certificates_stored": null,"kafka_cluster_enhanced_monitoring_enabled": null,"elasticache_redis_cluster_multi_az_enabled": null,"directoryservice_ldap_certificate_expiration": null,"cognito_user_pool_deletion_protection_enabled": null,"trustedadvisor_premium_support_plan_subscribed": null,"directoryservice_directory_monitor_notifications": null,"cloudformation_stacks_termination_protection_enabled": "FAIL","cloudtrail_multi_region_enabled_logging_management_events": null,"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.9.2 ģ„±ėŠ„ ė° ģž„ģ• ź“€ė¦¬","Subdomain": "2.9. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ģš“ģ˜ź“€ė¦¬","AuditEvidence": ["ģ„±ėŠ„ ė° ģš©ėŸ‰ ėŖØė‹ˆķ„°ė§ 절차","ģ„±ėŠ„ ė° ģš©ėŸ‰ ėŖØė‹ˆķ„°ė§ ģ¦ź±°ģžė£Œ(낓부볓고 ź²°ź³¼ 등)","ģž„ģ• ėŒ€ģ‘ 절차","ģž„ģ• ģ”°ģ¹˜ė³“ź³ ģ„œ"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ź°€ģš©ģ„± ė³“ģž„ģ„ ģœ„ķ•˜ģ—¬ ģ„±ėŠ„ ė° ģš©ėŸ‰ģ„ ģ§€ģ†ģ ģœ¼ė”œ ėŖØė‹ˆķ„°ė§ķ•  수 ģžˆėŠ” 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œ ģ„±ėŠ„ ė° ģš©ėŸ‰ ģš”źµ¬ģ‚¬ķ•­(ģž„ź³„ģ¹˜)ģ„ ģ“ˆź³¼ķ•˜ėŠ” ź²½ģš°ģ— ėŒ€ķ•œ ėŒ€ģ‘ģ ˆģ°Øė„¼ 수립 ė° ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œ ģž„ģ• ė„¼ ģ¦‰ģ‹œ ģøģ§€ķ•˜ź³  ėŒ€ģ‘ķ•˜źø° ģœ„ķ•œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģž„ģ•  ė°œģƒ ģ‹œ ģ ˆģ°Øģ— ė”°ė¼ ģ”°ģ¹˜ķ•˜ź³  ģž„ģ• ģ”°ģ¹˜ė³“ź³ ģ„œ ė“±ģ„ ķ†µķ•˜ģ—¬ ģž„ģ• ģ”°ģ¹˜ė‚“ģ—­ģ„ źø°ė”ķ•˜ģ—¬ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ‹¬ź°ė„ź°€ ė†’ģ€ ģž„ģ• ģ˜ 경우 ģ›ģøė¶„ģ„ģ„ ķ†µķ•œ ģž¬ė°œė°©ģ§€ ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ„±ėŠ„ ė° ģš©ėŸ‰ ꓀리넼 ģœ„ķ•œ ėŒ€ģƒė³„ ģš”źµ¬ģ‚¬ķ•­(ģž„ź³„ģ¹˜ 등)ģ„ ģ •ģ˜ķ•˜ź³  ģžˆģ§€ ģ•Šź±°ė‚˜ ģ •źø° ģ ź²€ė³“ź³ ģ„œ 등에 źø°ė”ķ•˜ź³  ģžˆģ§€ ģ•Šģ•„ ķ˜„ķ™©ģ„ ķŒŒģ•…ķ•  수 ģ—†ėŠ” 경우","사딀 2 : ģ„±ėŠ„ ė˜ėŠ” ģš©ėŸ‰ źø°ģ¤€ģ„ ģ“ˆź³¼ķ•˜ģ˜€ģœ¼ė‚˜ ꓀련 검토 ė° ķ›„ģ†ģ”°ģ¹˜ė°©ģ•ˆ ģˆ˜ė¦½Ā·ģ“ķ–‰ģ“ ģ“ė£Øģ–“ģ§€ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģ „ģ‚°ģž„ė¹„ ģž„ģ• ėŒ€ģ‘ģ ˆģ°Øė„¼ ģˆ˜ė¦½ķ•˜ź³  ģžˆģœ¼ė‚˜ ė„¤ķŠøģ›Œķ¬ 구성 ė° 외주업첓 변경 ė“±ģ˜ 낓·외부 ķ™˜ź²½ė³€ķ™”ź°€ ģ ģ ˆķžˆ ė°˜ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ģž„ģ• ģ²˜ė¦¬ģ ˆģ°Øģ™€ ģž„ģ• ģœ ķ˜•ė³„ ģ”°ģ¹˜ė°©ė²• ź°„ ģ¼ź“€ģ„±ģ“ ģ—†ź±°ė‚˜ ģ˜ˆģƒģ†Œģš”ģ‹œź°„ 산정에 ėŒ€ķ•œ 근거가 ė¶€ģ”±ķ•˜ģ—¬ ģ‹ ģ†Ā·ģ •ķ™•ķ•˜ź³  ģ²“ź³„ģ ģø ėŒ€ģ‘ģ“ ģ–“ė ¤ģš“ 경우"],"RelatedRegulations": []}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ź°€ģš©ģ„± ė³“ģž„ģ„ ģœ„ķ•˜ģ—¬ ģ„±ėŠ„ ė° ģš©ėŸ‰ ģš”źµ¬ģ‚¬ķ•­ģ„ ģ •ģ˜ķ•˜ź³  ķ˜„ķ™©ģ„ ģ§€ģ†ģ ģœ¼ė”œ ėŖØė‹ˆķ„°ė§ķ•˜ģ—¬ģ•¼ ķ•˜ė©°, ģž„ģ•  ė°œģƒ ģ‹œ 효과적으딜 ėŒ€ģ‘ķ•˜źø° ģœ„ķ•œ ķƒģ§€Ā·źø°ė”Ā·ė¶„ģ„Ā·ė³µźµ¬Ā·ė³“ź³  ė“±ģ˜ 절차넼 ģˆ˜ė¦½Ā·ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 11,"pass": 6,"total": 39,"manual": 0}},"2.9.3": {"name": "백업 ė° 복구꓀리","checks": {"ec2_ami_public": null,"backup_plans_exist": "PASS","backup_vaults_exist": null,"backup_vaults_encrypted": "PASS","ec2_ebs_public_snapshot": "PASS","efs_have_backup_enabled": "FAIL","s3_bucket_public_access": null,"backup_reportplans_exist": null,"s3_bucket_kms_encryption": "FAIL","s3_bucket_public_list_acl": null,"s3_bucket_public_write_acl": null,"ec2_ebs_snapshots_encrypted": "FAIL","rds_instance_backup_enabled": "PASS","rds_snapshots_public_access": "PASS","s3_bucket_lifecycle_enabled": "FAIL","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"s3_bucket_default_encryption": "PASS","rds_cluster_backtrack_enabled": null,"neptune_cluster_backup_enabled": null,"ec2_ebs_volume_snapshots_exists": "FAIL","neptune_cluster_public_snapshot": null,"documentdb_cluster_backup_enabled": null,"documentdb_cluster_public_snapshot": null,"rds_cluster_copy_tags_to_snapshots": "FAIL","s3_bucket_cross_region_replication": "FAIL","rds_instance_copy_tags_to_snapshots": null,"redshift_cluster_automated_snapshot": null,"s3_access_point_public_access_block": "PASS","s3_bucket_policy_public_write_access": "PASS","lightsail_instance_automated_snapshots": null,"dlm_ebs_snapshot_lifecycle_policy_exists": "FAIL","elasticache_redis_cluster_backup_enabled": null,"ecr_repositories_lifecycle_policy_enabled": "FAIL","directoryservice_directory_snapshots_limit": null,"ec2_ebs_snapshot_account_block_public_access": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.9.3 백업 ė° 복구꓀리","Subdomain": "2.9. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ģš“ģ˜ź“€ė¦¬","AuditEvidence": ["백업 ė° 복구 절차","ė³µźµ¬ķ…ŒģŠ¤ķŠø ź²°ź³¼","ģ†Œģ‚°ė°±ģ—… ķ˜„ķ™©"],"AuditChecklist": ["백업 ėŒ€ģƒ, 주기, 방법, 절차 ė“±ģ“ ķ¬ķ•Øėœ 백업 ė° 복구절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ė°±ģ—…ėœ ģ •ė³“ģ˜ 완전성과 정확성, ė³µźµ¬ģ ˆģ°Øģ˜ ģ ģ ˆģ„±ģ„ ķ™•ģøķ•˜źø° ģœ„ķ•˜ģ—¬ ģ •źø°ģ ģœ¼ė”œė³µźµ¬ ķ…ŒģŠ¤ķŠøė„¼ ģ‹¤ģ‹œķ•˜ź³  ģžˆėŠ”ź°€?","ģ¤‘ģš”ģ •ė³“ź°€ ģ €ģž„ėœ ė°±ģ—…ė§¤ģ²“ģ˜ 경우 ģž¬ķ•“Ā·ģž¬ė‚œģ— ėŒ€ģ²˜ķ•  수 ģžˆė„ė” ė°±ģ—…ė§¤ģ²“ė„¼ė¬¼ė¦¬ģ ģœ¼ė”œ ė–Øģ–“ģ§„ ģž„ģ†Œģ— ģ†Œģ‚°ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 백업 ėŒ€ģƒ, 주기, 방법, 절차 ė“±ģ“ ķ¬ķ•Øėœ 백업 ė° 복구 ģ ˆģ°Øź°€ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ė°±ģ—…ģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆģœ¼ė‚˜ 법적 ģš”źµ¬ģ‚¬ķ•­ģ— ė”°ė¼ ģž„źø°ź°„(6ź°œģ›”, 3ė…„, 5ė…„ 등) ė³“ź“€ģ“ ķ•„ģš”ķ•œ 백업 ėŒ€ģƒ 정볓가 백업 정책에 ė”°ė¼ ė³“ź“€ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģƒģœ„ 지침 ė˜ėŠ” ė‚“ė¶€ 지침에 ė”°ė¼ ė³„ė„ė”œ ė°±ģ—…ķ•˜ģ—¬ ź“€ė¦¬ķ•˜ė„ė” ėŖ…ģ‹œėœ ģ¼ė¶€ ģ‹œģŠ¤ķ…œ(ė³“ģ•ˆģ‹œģŠ¤ķ…œ ģ •ģ±… ė° 딜그 등)에 ėŒ€ķ•œ ė°±ģ—…ģ“ ģ“ķ–‰ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ģƒģœ„ 지침 ė˜ėŠ” ė‚“ė¶€ ģ§€ģ¹Øģ—ėŠ” 주기적으딜 백업매첓에 ėŒ€ķ•œ 복구 ķ…ŒģŠ¤ķŠøė„¼ ģˆ˜ķ–‰ķ•˜ė„ė” ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜ ė³µźµ¬ķ…ŒģŠ¤ķŠøė„¼ ģž„źø°ź°„ ģ‹¤ģ‹œķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제11ģ”°(ģž¬ķ•“Ā·ģž¬ė‚œ ėŒ€ė¹„ ģ•ˆģ „ģ”°ģ¹˜)"]}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ź°€ģš©ģ„±ź³¼ ė°ģ“ķ„° ė¬“ź²°ģ„±ģ„ ģœ ģ§€ķ•˜źø° ģœ„ķ•˜ģ—¬ 백업 ėŒ€ģƒ, 주기, 방법, ė³“ź“€ģž„ģ†Œ, 볓꓀기간, ģ†Œģ‚° ė“±ģ˜ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ģ•„ģšøėŸ¬ 사고 ė°œģƒ ģ‹œ ģ ģ‹œģ— 복구할 수 ģžˆė„ė” ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 11,"pass": 8,"total": 37,"manual": 0}},"2.9.4": {"name": "딜그 ė° ģ ‘ģ†źø°ė” ꓀리","checks": {"macie_is_enabled": "PASS","elb_logging_enabled": "FAIL","securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","elbv2_logging_enabled": "FAIL","inspector2_is_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","ec2_ebs_public_snapshot": "PASS","eventbridge_bus_exposed": "PASS","rds_snapshots_encrypted": "FAIL","s3_bucket_public_access": null,"s3_bucket_kms_encryption": "FAIL","cloudtrail_insights_exist": null,"s3_bucket_public_list_acl": null,"s3_bucket_public_write_acl": null,"ec2_ebs_snapshots_encrypted": "FAIL","ec2_instance_managed_by_ssm": "FAIL","efs_not_publicly_accessible": "FAIL","guardduty_centrally_managed": "FAIL","rds_snapshots_public_access": "PASS","s3_bucket_default_encryption": "PASS","wafv2_webacl_logging_enabled": "FAIL","iam_securityaudit_role_created": null,"redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","config_recorder_all_regions_enabled": null,"s3_access_point_public_access_block": "PASS","s3_bucket_level_public_access_block": "PASS","eventbridge_bus_cross_account_access": "FAIL","s3_bucket_policy_public_write_access": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"s3_account_level_public_access_blocks": null,"cloudtrail_log_file_validation_enabled": "FAIL","cloudtrail_s3_dataevents_write_enabled": null,"apigatewayv2_api_access_logging_enabled": "FAIL","cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"s3_bucket_server_access_logging_enabled": "FAIL","cloudfront_distributions_logging_enabled": null,"documentdb_cluster_cloudwatch_log_export": null,"ec2_instance_detailed_monitoring_enabled": "FAIL","rds_instance_enhanced_monitoring_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","cloudwatch_cross_account_sharing_disabled": null,"kafka_cluster_enhanced_monitoring_enabled": null,"acm_certificates_transparency_logs_enabled": "PASS","cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","cloudwatch_log_metric_filter_policy_changes": null,"eks_control_plane_logging_all_types_enabled": null,"ec2_ebs_snapshot_account_block_public_access": null,"iam_inline_policy_no_full_access_to_cloudtrail": null,"trustedadvisor_premium_support_plan_subscribed": null,"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL","cloudwatch_log_metric_filter_sign_in_without_mfa": null,"directoryservice_directory_monitor_notifications": null,"eventbridge_schema_registry_cross_account_access": "FAIL","glue_etl_jobs_cloudwatch_logs_encryption_enabled": "FAIL","opensearch_service_domains_audit_logging_enabled": null,"directoryservice_directory_log_forwarding_enabled": null,"ec2_client_vpn_endpoint_connection_logging_enabled": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS","cloudwatch_log_metric_filter_authentication_failures": null,"opensearch_service_domains_cloudwatch_logging_enabled": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"route53_public_hosted_zones_cloudwatch_logging_enabled": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudtrail_multi_region_enabled_logging_management_events": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","glue_development_endpoints_cloudwatch_logs_encryption_enabled": null,"awslambda_function_invoke_api_operations_cloudtrail_logging_enabled": "PASS","cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.9.4 딜그 ė° ģ ‘ģ†źø°ė” ꓀리","Subdomain": "2.9. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ģš“ģ˜ź“€ė¦¬","AuditEvidence": ["ė”œź·øź“€ė¦¬ 절차","ė”œź·øźø°ė” ė‚“ģ—­","딜그 ģ €ģž„ģž„ģ¹˜ģ— ėŒ€ķ•œ ģ ‘ź·¼ķ†µģ œ ė‚“ģ—­","ź°œģøģ •ė³“ ģ ‘ģ†źø°ė” ė‚“ģ—­"],"AuditChecklist": ["ģ„œė²„, ģ‘ģš©ķ”„ė”œź·øėžØ, ė³“ģ•ˆģ‹œģŠ¤ķ…œ, ė„¤ķŠøģ›Œķ¬ģ‹œģŠ¤ķ…œ 등 ģ •ė³“ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ė”œź·øź“€ė¦¬ 절차넼 ģˆ˜ė¦½ķ•˜ź³  ģ“ģ— ė”°ė¼ ķ•„ģš”ķ•œ 딜그넼 ģƒģ„±ķ•˜ģ—¬ ė³“ź“€ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ė”œź·øźø°ė”ģ€ ģœ„Ā·ė³€ģ”° ė° ė„ė‚œ, ė¶„ģ‹¤ė˜ģ§€ ģ•Šė„ė” ģ•ˆģ „ķ•˜ź²Œ ė³“ź“€ķ•˜ź³  ė”œź·øźø°ė”ģ— ėŒ€ķ•œ ģ ‘ź·¼ź¶Œķ•œģ€ ģµœģ†Œķ™”ķ•˜ģ—¬ ė¶€ģ—¬ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ģ ‘ģ†źø°ė”ģ€ 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ģ¤€ģˆ˜ķ•  수 ģžˆė„ė” ķ•„ģš”ķ•œ ķ•­ėŖ©ģ„ 모두 ķ¬ķ•Øķ•˜ģ—¬ ģ¼ģ •źø°ź°„ ģ•ˆģ „ķ•˜ź²Œ ė³“ź“€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 딜그 źø°ė” ėŒ€ģƒ, 방법, 볓씓기간, 검토 주기, ė‹“ė‹¹ģž 등에 ėŒ€ķ•œ 세부 기준 ė° ģ ˆģ°Øź°€ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ė³“ģ•ˆ ģ“ė²¤ķŠø 딜그, ģ‘ģš©ķ”„ė”œź·øėžØ ė° ģ„œė¹„ģŠ¤ 딜그(ģœˆė„ģš° 2008 ģ„œė²„ ģ“ģƒ) 등 ģ¤‘ģš” ė”œź·øģ— ėŒ€ķ•œ ģµœėŒ€ 크기넼 ģ¶©ė¶„ķ•˜ź²Œ ģ„¤ģ •ķ•˜ģ§€ ģ•Šģ•„ ė‚“ė¶€ 기준에 ģ •ķ•œ źø°ź°„ ė™ģ•ˆ źø°ė”Ā·ė³“ź“€ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģ¤‘ģš” Linux/UNIX 계엓 ģ„œė²„ģ— ėŒ€ķ•œ 딜그 źø°ė”ģ„ ė³„ė„ė”œ ė°±ģ—…ķ•˜ź±°ė‚˜ ģ ģ ˆķžˆ ė³“ķ˜øķ•˜ģ§€ ģ•Šģ•„ ģ‚¬ģš©ģžģ˜ ėŖ…ė ¹ 실행 źø°ė” ė° ģ ‘ģ† ģ“ė „ ė“±ģ„ ģž„ģ˜ė”œ ģ‚­ģ œķ•  수 ģžˆėŠ” 경우","사딀 4 : ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— ģ ‘ģ†ķ•œ źø°ė”ģ„ ķ™•ģøķ•œ ź²°ź³¼ ģ ‘ģ†ģžģ˜ 계정, ģ ‘ģ† ģ¼ģ‹œ, ģ ‘ģ†ģž IPģ£¼ģ†Œ ģ •ė³“ėŠ” 남기고 ģžˆģœ¼ė‚˜, ģ²˜ė¦¬ķ•œ 정볓주첓 정볓 ė° ģˆ˜ķ–‰ģ—…ė¬“(씰회, 변경, ģ‚­ģ œ, ė‹¤ģš“ė”œė“œ 등)와 ź“€ė Øėœ 정볓넼 남기고 ģžˆģ§€ ģ•Šģ€ 경우","사딀 5 : 딜그 ģ„œė²„ģ˜ ģš©ėŸ‰ģ˜ ģ¶©ė¶„ķ•˜ģ§€ ģ•Šģ•„ģ„œ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ģ ‘ģ†źø°ė”ģ“ 2ź°œģ›” 밖에 남아 ģžˆģ§€ ģ•Šģ€ 경우","사딀 6 : ź°œģøģ •ė³“ģ²˜ė¦¬ģžź°€ 정볓주첓 10만 ėŖ…ģ˜ ź°œģøģ •ė³“ė„¼ ģ²˜ė¦¬ķ•˜ėŠ” ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ź°œģøģ •ė³“ģ·Øźø‰ģž ģ ‘ģ†źø°ė”ģ„ 1ė…„ź°„ė§Œ ė³“ź“€ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제8ģ”°(ģ ‘ģ†źø°ė”ģ˜ 볓꓀ ė° 점검)"]}],"description": "ģ„œė²„, ģ‘ģš©ķ”„ė”œź·øėžØ, ė³“ģ•ˆģ‹œģŠ¤ķ…œ, ė„¤ķŠøģ›Œķ¬ģ‹œģŠ¤ķ…œ 등 ģ •ė³“ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ģ‚¬ģš©ģž ģ ‘ģ†źø°ė”, ģ‹œģŠ¤ķ…œė”œź·ø, ź¶Œķ•œė¶€ģ—¬ ė‚“ģ—­ ė“±ģ˜ ė”œź·øģœ ķ˜•, 볓씓기간, 볓씓방법 ė“±ģ„ ģ •ķ•˜ź³  ģœ„Ā·ė³€ģ”°, ė„ė‚œ, ė¶„ģ‹¤ė˜ģ§€ ģ•Šė„ė” ģ•ˆģ „ķ•˜ź²Œ ė³“ģ”“Ā·ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 25,"pass": 15,"total": 81,"manual": 0}},"2.9.5": {"name": "딜그 ė° ģ ‘ģ†źø°ė” 점검","checks": {"cloudtrail_insights_exist": null,"inspector2_active_findings_exist": "FAIL","trustedadvisor_errors_and_warnings": null,"guardduty_no_high_severity_findings": "FAIL","accessanalyzer_enabled_without_findings": "FAIL","cloudtrail_threat_detection_enumeration": null,"cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_cross_account_sharing_disabled": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cognito_user_pool_client_prevent_user_existence_errors": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.9.5 딜그 ė° ģ ‘ģ†źø°ė” 점검","Subdomain": "2.9. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ģš“ģ˜ź“€ė¦¬","AuditEvidence": ["딜그 검토 ė° ėŖØė‹ˆķ„°ė§ 절차","딜그 검토 ė° ėŖØė‹ˆķ„°ė§ ź²°ź³¼(검토 ė‚“ģ—­, ė³“ź³ ģ„œ 등)","ź°œģøģ •ė³“ ģ ‘ģ†źø°ė” 점검 ė‚“ģ—­","ź°œģøģ •ė³“ ė‹¤ģš“ė”œė“œ ģ‹œ ģ‚¬ģœ  ķ™•ģø 기준 ė° ź²°ź³¼","ģ“ģƒģ§•ķ›„ 발견 ģ‹œ ėŒ€ģ‘ ģ¦ź±°ģžė£Œ"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œ ꓀련 오넘, ģ˜¤Ā·ė‚Øģš©(ė¹„ģøź°€ģ ‘ģ†, ź³¼ė‹¤ģ”°ķšŒ 등), ė¶€ģ •ķ–‰ģœ„ 등 ģ“ģƒģ§•ķ›„ė„¼ ģøģ§€ķ•  수 ģžˆė„ė” 딜그 검토 주기, ėŒ€ģƒ, 방법 ė“±ģ„ ķ¬ķ•Øķ•œ 딜그 검토 ė° ėŖØė‹ˆķ„°ė§ģ ˆģ°Øė„¼ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","딜그 검토 ė° ėŖØė‹ˆķ„°ė§ 결과넼 ģ±…ģž„ģžģ—ź²Œ ė³“ź³ ķ•˜ź³  ģ“ģƒģ§•ķ›„ 발견 ģ‹œ ģ ˆģ°Øģ— ė”°ė¼ ėŒ€ģ‘ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ģ ‘ģ†źø°ė”ģ€ ꓀련 ė²•ė ¹ģ—ģ„œ ģ •ķ•œ 주기에 ė”°ė¼ ģ •źø°ģ ģœ¼ė”œ ģ ź²€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ¤‘ģš” 정볓넼 ģ²˜ė¦¬ķ•˜ź³  ģžˆėŠ” ģ •ė³“ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ģ“ģƒģ ‘ģ†(ķœ“ģ¼ 새벽 ģ ‘ģ†, 우회경딜 ģ ‘ģ† 등) ė˜ėŠ” ģ“ģƒķ–‰ģœ„(ėŒ€ėŸ‰ ė°ģ“ķ„° 씰회 ė˜ėŠ” ģ†ŒėŸ‰ ė°ģ“ķ„°ģ˜ ģ§€ģ†ģ Ā·ģ—°ģ†ģ  씰회 등)에 ėŒ€ķ•œ ėŖØė‹ˆķ„°ė§ ė° ź²½ź³ Ā·ģ•Œė¦¼ ģ •ģ±…(기준)ģ“ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ė‚“ė¶€ 지침 ė˜ėŠ” ģ‹œģŠ¤ķ…œ 등에 ģ ‘ź·¼ ė° ģ‚¬ģš©ģ— ėŒ€ķ•œ ģ£¼źø°ģ ģø ģ ź²€Ā·ėŖØė‹ˆķ„°ė§ źø°ģ¤€ģ„ ė§ˆė Øķ•˜ź³  ģžˆģœ¼ė‚˜ ģ‹¤ģ œ ģ“ģƒģ ‘ģ† ė° ģ“ģƒķ–‰ģœ„ģ— ėŒ€ķ•œ 검토 ė‚“ģ—­ģ“ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ź°œģøģ •ė³“ģ²˜ė¦¬ģžź°€ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ˜ ģ ‘ģ†źø°ė” 점검 주기넼 ė¶„źø° 1회딜 ģ •ķ•˜ź³  ģžˆėŠ” 경우","사딀 4 : ź°œģøģ •ė³“ģ²˜ė¦¬ģžģ˜ ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ—ėŠ” 1,000ėŖ… ģ“ģƒģ˜ 정볓주첓에 ėŒ€ķ•œ ź°œģøģ •ė³“ė„¼ ė‹¤ģš“ė”œė“œķ•œ ź²½ģš°ģ—ėŠ” ģ‚¬ģœ ė„¼ ķ™•ģøķ•˜ė„ė” źø°ģ¤€ģ“ ģ±…ģ •ė˜ģ–“ ģžˆėŠ” ģƒķƒœģ—ģ„œ 1,000걓 ģ“ģƒģ˜ ź°œģøģ •ė³“ ė‹¤ģš“ė”œė“œź°€ ė°œģƒķ•˜ģ˜€ģœ¼ė‚˜ ź·ø ģ‚¬ģœ ė„¼ ķ™•ģøķ•˜ģ§€ ģ•Šź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제8ģ”°(ģ ‘ģ†źø°ė”ģ˜ 볓꓀ ė° 점검)"]}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ •ģƒģ ģø ģ‚¬ģš©ģ„ ė³“ģž„ķ•˜ź³  ģ‚¬ģš©ģž ģ˜¤Ā·ė‚Øģš©(ė¹„ģøź°€ģ ‘ģ†, ź³¼ė‹¤ģ”°ķšŒ 등)ģ„ ė°©ģ§€ķ•˜źø° ģœ„ķ•˜ģ—¬ ģ ‘ź·¼ ė° ģ‚¬ģš©ģ— ėŒ€ķ•œ 딜그 ź²€ķ† źø°ģ¤€ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ 주기적으딜 ģ ź²€ķ•˜ė©°, 문제 ė°œģƒ ģ‹œ ģ‚¬ķ›„ģ”°ģ¹˜ė„¼ ģ ģ‹œģ— ģˆ˜ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 6,"pass": 0,"total": 26,"manual": 0}},"2.9.6": {"name": "ģ‹œź°„ ė™źø°ķ™”","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.9.6 ģ‹œź°„ ė™źø°ķ™”","Subdomain": "2.9. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ģš“ģ˜ź“€ė¦¬","AuditEvidence": ["ģ‹œź°„ ė™źø°ķ™” 설정","ģ£¼ģš” ģ‹œģŠ¤ķ…œ ģ‹œź°„ ė™źø°ķ™” ģ¦ź±°ģžė£Œ"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ‹œź°„ģ„ ķ‘œģ¤€ģ‹œź°„ģœ¼ė”œ ė™źø°ķ™”ķ•˜ź³  ģžˆėŠ”ź°€?","ģ‹œź°„ ė™źø°ķ™”ź°€ ģ •ģƒģ ģœ¼ė”œ ģ“ė£Øģ–“ģ§€ź³  ģžˆėŠ”ģ§€ 주기적으딜 ģ ź²€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ¼ė¶€ ģ¤‘ģš” ģ‹œģŠ¤ķ…œ(ė³“ģ•ˆģ‹œģŠ¤ķ…œ, CCTV 등)ģ˜ ģ‹œź°ģ“ ķ‘œģ¤€ģ‹œģ™€ ė™źø°ķ™”ė˜ģ–“ ģžˆģ§€ ģ•Šģœ¼ė©°, ꓀련 ė™źø°ķ™” 여부에 ėŒ€ķ•œ 주기적 ģ ź²€ģ“ ģ“ķ–‰ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ė‚“ė¶€ NTP ģ„œė²„ģ™€ ģ‹œź°ģ„ ė™źø°ķ™”ķ•˜ė„ė” ģ„¤ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜ ģ¼ė¶€ ģ‹œģŠ¤ķ…œģ˜ ģ‹œź°ģ“ ė™źø°ķ™”ė˜ģ§€ ģ•Šź³  ģžˆź³ , ģ“ģ— ėŒ€ķ•œ ģ›ģøė¶„ģ„ ė° ėŒ€ģ‘ģ“ ģ“ė£Øģ–“ģ§€ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "딜그 ė° ģ ‘ģ†źø°ė”ģ˜ ģ •ķ™•ģ„±ģ„ ė³“ģž„ķ•˜ź³  신뢰성 ģžˆėŠ” ė”œź·øė¶„ģ„ģ„ ģœ„ķ•˜ģ—¬ ꓀련 ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ‹œź°ģ„ ķ‘œģ¤€ģ‹œź°ģœ¼ė”œ ė™źø°ķ™”ķ•˜ź³  주기적으딜 ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.9.7": {"name": "ģ •ė³“ģžģ‚°ģ˜ ģž¬ģ‚¬ģš© ė° ķźø°","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.9.7 ģ •ė³“ģžģ‚°ģ˜ ģž¬ģ‚¬ģš© ė° ķźø°","Subdomain": "2.9. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ģš“ģ˜ź“€ė¦¬","AuditEvidence": ["ģ •ė³“ģžģ‚° ķźø° ė° ģž¬ģ‚¬ģš© 절차","ģ €ģž„ė§¤ģ²“ ź“€ė¦¬ėŒ€ģž„","ģ •ė³“ģžģ‚° ė° ģ €ģž„ė§¤ģ²“ ķźø° ģ¦ź±°ģžė£Œ","ģ •ė³“ģžģ‚° ė° ģ €ģž„ė§¤ģ²“ ķźø° ꓀련 ģœ„ķƒź³„ģ•½ģ„œ"],"AuditChecklist": ["ģ •ė³“ģžģ‚°ģ˜ ģ•ˆģ „ķ•œ ģž¬ģ‚¬ģš© ė° ķźø°ģ— ėŒ€ķ•œ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģžģ‚° ė° ģ €ģž„ė§¤ģ²“ė„¼ ģž¬ģ‚¬ģš© ė° ķźø°ķ•˜ėŠ” 경우 ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ė„¼ ė³µźµ¬ė˜ģ§€ ģ•ŠėŠ” ė°©ė²•ģœ¼ė”œ ģ²˜ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģžģ²“ģ ģœ¼ė”œ ģ •ė³“ģžģ‚° ė° ģ €ģž„ė§¤ģ²“ė„¼ ķźø°ķ•  경우 ź“€ė¦¬ėŒ€ģž„ģ„ ķ†µķ•˜ģ—¬ ķźø°ģ“ė „ģ„ 남기고 ķźø°ķ™•ģø ģ¦ģ ģ„ ķ•Øź»˜ ė³“ź“€ķ•˜ź³  ģžˆėŠ”ź°€?","외부업첓넼 ķ†µķ•˜ģ—¬ ģ •ė³“ģžģ‚° ė° ģ €ģž„ė§¤ģ²“ė„¼ ķźø°ķ•  경우 ķźø° 절차넼 ź³„ģ•½ģ„œģ— ėŖ…ģ‹œķ•˜ź³  ģ™„ģ „ķžˆ ķźø°ķ•˜ģ˜€ėŠ”ģ§€ 여부넼 ķ™•ģøķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ‹œģŠ¤ķ…œ, PC 등 ģœ ģ§€ė³“ģˆ˜, 수리 ź³¼ģ •ģ—ģ„œ ģ €ģž„ė§¤ģ²“ 교첓, 복구 등 ė°œģƒ ģ‹œ ģ €ģž„ė§¤ģ²“ ė‚“ 정볓넼 ė³“ķ˜øķ•˜źø° ģœ„ķ•œ ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ģ·Øźø‰ģž PC넼 ģž¬ģ‚¬ģš©ķ•  경우 ė°ģ“ķ„° ģ‚­ģ œķ”„ė”œź·øėžØģ„ ģ“ģš©ķ•˜ģ—¬ ģ™„ģ „ģ‚­ģ œ ķ•˜ė„ė” ģ •ģ±… ė° ģ ˆģ°Øź°€ ģˆ˜ė¦½ė˜ģ–“ ģžˆģœ¼ė‚˜, ģ‹¤ģ œė”œėŠ” ģ™„ģ „ģ‚­ģ œ 씰치 ģ—†ģ“ ģž¬ģ‚¬ģš©ķ•˜ź±°ė‚˜ źø°ė³ø ķ¬ė§·ė§Œ ķ•˜ź³  ģž¬ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 등 ꓀련 ģ ˆģ°Øź°€ ģ“ķ–‰ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : 외부업첓넼 ķ†µķ•˜ģ—¬ ģ €ģž„ė§¤ģ²“ė„¼ ķźø°ķ•˜ź³  ģžˆģœ¼ė‚˜, 계약 ė‚“ģš©ģƒ ģ•ˆģ „ķ•œ ķźø° 절차 ė° ė³“ķ˜øėŒ€ģ±…ģ— ėŒ€ķ•œ ė‚“ģš©ģ“ ėˆ„ė½ė˜ģ–“ ģžˆź³  ķźø° ģ“ķ–‰ ģ¦ź±°ģžė£Œ ķ™•ģø ė° 실사 ė“±ģ˜ ź“€ė¦¬Ā·ź°ė…ģ“ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우","사딀 3 : ķźø°ėœ HDDģ˜ ģ¼ė Øė²ˆķ˜øź°€ ģ•„ė‹Œ ģ‹œģŠ¤ķ…œėŖ…ģ„ źø°ė”ķ•˜ź±°ė‚˜ ķźø° ėŒ€ģž„ģ„ ģž‘ģ„±ķ•˜ģ§€ ģ•Šģ•„ ķźø° ģ“ė „ ė° 추적할 수 ģžˆėŠ” ģ¦ź±°ģžė£Œė„¼ ķ™•ģøķ•  수 ģ—†ėŠ” 경우","사딀 4 : ķšŒģˆ˜ķ•œ ķźø° ėŒ€ģƒ ķ•˜ė“œė””ģŠ¤ķ¬ź°€ ģ™„ģ „ģ‚­ģ œ ė˜ģ§€ ģ•Šģ€ 상태딜 ģž źøˆģž„ģ¹˜ź°€ ė˜ģ§€ ģ•Šģ€ ģž„ģ†Œģ— 방치되고 ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제21ģ”°(ź°œģøģ •ė³“ģ˜ 파기)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제13ģ”°(ź°œģøģ •ė³“ģ˜ 파기)"]}],"description": "ģ •ė³“ģžģ‚°ģ˜ ģž¬ģ‚¬ģš©ź³¼ ķźø° ź³¼ģ •ģ—ģ„œ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ź°€ ė³µźµ¬Ā·ģž¬ģƒė˜ģ§€ ģ•Šė„ė” ģ•ˆģ „ķ•œ ģž¬ģ‚¬ģš© ė° ķźø° 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.1": {"name": "ź°œģøģ •ė³“ ģˆ˜ģ§‘Ā·ģ“ģš©","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.1.1 ź°œģøģ •ė³“ ģˆ˜ģ§‘Ā·ģ“ģš©","Subdomain": "3.1. ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ‹œ 볓호씰치","AuditEvidence": ["ģ˜Øė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ķ™ˆķŽ˜ģ“ģ§€ ķšŒģ›ź°€ģž… 화멓, ėŖØė°”ģ¼ģ•± ķšŒģ›ź°€ģž… 화멓, ģ“ė²¤ķŠø ģ°øģ—¬ 등)","ģ˜¤ķ”„ė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ķšŒģ›ź°€ģž…ģ‹ ģ²­ģ„œ 등)","ź°œģøģ •ė³“ ģˆ˜ģ§‘ ė™ģ˜ źø°ė”(ķšŒģ› ė°ģ“ķ„°ė² ģ“ģŠ¤ 등)","ė²•ģ •ėŒ€ė¦¬ģø ė™ģ˜ źø°ė”","ź°œģøģ •ė³“ 처리방침"],"AuditChecklist": ["ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ėŠ” 경우 정볓주첓 ė™ģ˜, ė²•ė ¹ģƒ ģ˜ė¬“ģ¤€ģˆ˜, 계약 ģ²“ź²°Ā·ģ“ķ–‰ 등 적법 ģš”ź±“ģ— ė”°ė¼ ģˆ˜ģ§‘ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ź°œģøģ •ė³“ ģˆ˜ģ§‘ ė™ģ˜ė„¼ ė°›ėŠ” 경우 ė™ģ˜ė°©ė²• ė° ģ‹œģ ģ€ ģ ģ ˆķ•˜ź²Œ ė˜ģ–“ ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ź°œģøģ •ė³“ ģˆ˜ģ§‘ ė™ģ˜ė„¼ ė°›ėŠ” 경우 ꓀련 ė‚“ģš©ģ„ ėŖ…ķ™•ķ•˜ź²Œ ź³ ģ§€ķ•˜ź³  ė²•ė ¹ģ—ģ„œ ģ •ķ•œ ģ¤‘ģš”ķ•œ ė‚“ģš©ģ— ėŒ€ķ•“ ģ•Œģ•„ė³“źø° ģ‰½ź²Œ ķ‘œģ‹œķ•˜ź³  ģžˆėŠ”ź°€?","만 14세 미만 ģ•„ė™ģ˜ ź°œģøģ •ė³“ģ— ėŒ€ķ•“ ģˆ˜ģ§‘Ā·ģ“ģš©Ā·ģ œź³µ ė“±ģ˜ ė™ģ˜ė„¼ ė°›ėŠ” 경우 ė²•ģ •ėŒ€ė¦¬ģøģ—ź²Œ ķ•„ģš”ķ•œ 사항에 ėŒ€ķ•˜ģ—¬ ź³ ģ§€ķ•˜ź³  ė™ģ˜ė„¼ 받고 ģžˆėŠ”ź°€?","ė²•ģ •ėŒ€ė¦¬ģøģ˜ ė™ģ˜ė„¼ 받기 ģœ„ķ•˜ģ—¬ ķ•„ģš”ķ•œ ģµœģ†Œķ•œģ˜ ź°œģøģ •ė³“ė§Œģ„ ģˆ˜ģ§‘ķ•˜ź³  ģžˆģœ¼ė©°, ė²•ģ •ėŒ€ė¦¬ģøģ“ ģžź²© ģš”ź±“ģ„ 갖추고 ģžˆėŠ”ģ§€ ķ™•ģøķ•˜ėŠ” ģ ˆģ°Øģ™€ ė°©ė²•ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","만 14세 ėÆøė§Œģ˜ ģ•„ė™ģ—ź²Œ ź°œģøģ •ė³“ ģ²˜ė¦¬ģ™€ ź“€ė Øķ•œ 사항 ė“±ģ˜ ź³ ģ§€ ģ‹œ ģ“ķ•“ķ•˜źø° ģ‰¬ģš“ ģ–‘ģ‹ź³¼ ėŖ…ķ™•ķ•˜ź³  ģ•Œźø° ģ‰¬ģš“ ģ–øģ–“ė”œ ķ‘œķ˜„ķ•˜ź³  ģžˆėŠ”ź°€?","정볓주첓 ė° ė²•ģ •ėŒ€ė¦¬ģøģ—ź²Œ ė™ģ˜ė„¼ ė°›ģ€ źø°ė”ģ„ ė³“ź“€ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ ģ—†ģ“ ģ²˜ė¦¬ķ•  수 ģžˆėŠ” ź°œģøģ •ė³“ģ— ėŒ€ķ•“ģ„œėŠ” ź·ø ķ•­ėŖ©ź³¼ ģ²˜ė¦¬ģ˜ 법적 근거넼 ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ė„¼ 받아 ģ²˜ė¦¬ķ•˜ėŠ” ź°œģøģ •ė³“ģ™€ źµ¬ė¶„ķ•˜ģ—¬ ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ—ź³µź°œķ•˜ź±°ė‚˜ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ ģ—†ģ“ ź°œģøģ •ė³“ģ˜ ģ¶”ź°€ģ ģø ģ“ģš© ģ‹œ ė‹¹ģ“ˆ ģˆ˜ģ§‘ ėŖ©ģ ź³¼ģ˜ ꓀련성, 예츔 ź°€ėŠ„ģ„±, ģ“ģµ 침핓 여부, ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ ė“±ģ˜ 고려사항에 ėŒ€ķ•œ ķŒė‹Øźø°ģ¤€ģ„ 수립 ė° ģ“ķ–‰ķ•˜ź³ , ģ¶”ź°€ģ ģø ģ“ģš©ģ“ ģ§€ģ†ģ ģœ¼ė”œ ė°œģƒķ•˜ėŠ” 경우 고려사항에 ėŒ€ķ•œ ķŒė‹Øźø°ģ¤€ģ„ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź³µź°œķ•˜ź³  ģ“ė„¼ ģ ź²€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ ė³“ķ˜øė²•ģ„ ģ ģš©ė°›ėŠ” ź°œģøģ •ė³“ģ²˜ė¦¬ģžź°€ ź°œģøģ •ė³“ ģˆ˜ģ§‘ ė™ģ˜ ģ‹œ ź³ ģ§€ 사항에 Ź»ė™ģ˜ ź±°ė¶€ 권리 ė° ė™ģ˜ 거부에 따넸 ė¶ˆģ“ģµ ė‚“ģš©Ź¼ģ„ ėˆ„ė½ķ•œ 경우","사딀 2 : ź°œģøģ •ė³“ ģˆ˜ģ§‘ ė™ģ˜ ģ‹œ ģˆ˜ģ§‘ķ•˜ėŠ” ź°œģøģ •ė³“ ķ•­ėŖ©ģ„ 구첓적으딜 ėŖ…ģ‹œķ•˜ģ§€ ģ•Šź³  Ź»~ 등ʼ과 ź°™ģ“ ķ¬ź“„ģ ģœ¼ė”œ ģ•ˆė‚“ķ•˜ėŠ” 경우","사딀 3 : 쇼핑몰 ķ™ˆķŽ˜ģ“ģ§€ģ—ģ„œ ķšŒģ›ź°€ģž… ģ‹œ ķšŒģ›ź°€ģž…ģ— ķ•„ģš”ķ•œ ź°œģøģ •ė³“ 외에 추후 ė¬¼ķ’ˆ 구매 ģ‹œ ķ•„ģš”ķ•œ ź²°ģ œĀ·ė°°ģ†” 정볓넼 미리 ķ•„ģˆ˜ ķ•­ėŖ©ģœ¼ė”œ ģˆ˜ģ§‘ķ•˜ėŠ” 경우","사딀 4 : Q&A, ź²Œģ‹œķŒģ„ ķ†µķ•˜ģ—¬ ė¹„ķšŒģ›ģ˜ ź°œģøģ •ė³“(ģ“ė¦„, ģ“ė©”ģ¼, ķœ“ėŒ€ķ°ė²ˆķ˜ø)넼 ģˆ˜ģ§‘ķ•˜ė©“ģ„œ ź°œģøģ •ė³“ ģˆ˜ģ§‘ ė™ģ˜ 절차넼 ź±°ģ¹˜ģ§€ ģ•Šģ€ 경우","사딀 5 : 만 14세 미만 ģ•„ė™ģ˜ ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ė©“ģ„œ ė²•ģ •ėŒ€ė¦¬ģøģ˜ ė™ģ˜ė„¼ 받지 ģ•Šģ€ 경우","사딀 6 : 만 14세 미만 ģ•„ė™ģ— ėŒ€ķ•˜ģ—¬ ģ„œė¹„ģŠ¤ė„¼ ģ œź³µķ•˜ź³  ģžˆģ§€ ģ•Šģ§€ė§Œ, ķšŒģ›ź°€ģž… ė‹Øź³„ģ—ģ„œ ģž…ė „ė°›ėŠ” ģƒė…„ģ›”ģ¼ģ„ ķ†µķ•˜ģ—¬ ė‚˜ģ“ 첓크넼 ķ•˜ģ§€ ģ•Šģ•„ ė²•ģ •ėŒ€ė¦¬ģø ė™ģ˜ ģ—†ģ“ ź°€ģž…ėœ 만 14세 미만 ģ•„ė™ ķšŒģ›ģ“ ģ”“ģž¬ķ•œ 경우","사딀 7 : ė²•ģ •ėŒ€ė¦¬ģøģ˜ ģ§„ģœ„ 여부넼 ķ™•ģøķ•˜ėŠ” ģ ˆģ°Øź°€ ėÆøķ”ķ•˜ģ—¬ ėÆøģ„±ė…„ģž 등 ģ•„ė™ģ˜ ė²•ģ •ėŒ€ė¦¬ģøģœ¼ė”œ 볓기 ģ–“ė ¤ģš“ė°ė„ ė²•ģ •ėŒ€ė¦¬ģø ė™ģ˜ź°€ ź°€ėŠ„ķ•œ 경우","사딀 8 : 만 14세 미만 ģ•„ė™ģœ¼ė”œė¶€ķ„° ė²•ģ •ėŒ€ė¦¬ģø ė™ģ˜ė„¼ ė°›ėŠ” 목적으딜 ė²•ģ •ėŒ€ė¦¬ģøģ˜ ź°œģøģ •ė³“(ģ“ė¦„, ķœ“ėŒ€ķ°ė²ˆķ˜ø)넼 ģˆ˜ģ§‘ķ•œ ģ“ķ›„ ė²•ģ •ėŒ€ė¦¬ģøģ˜ ė™ģ˜ź°€ ģž„źø°ź°„ ķ™•ģøė˜ģ§€ ģ•Šģ•˜ģŒģ—ė„ ģ“ė„¼ ķŒŒźø°ķ•˜ģ§€ ģ•Šź³  ź³„ģ† ė³“ģœ ķ•˜ź³  ģžˆėŠ” 경우","사딀 9 : ė²•ģ •ėŒ€ė¦¬ģø ė™ģ˜ģ— ź·¼ź±°ķ•˜ģ—¬ 만 14세 미만 ģ•„ė™ģ˜ ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ģ˜€ģœ¼ė‚˜, ꓀련 źø°ė”ģ„ ė³“ģ”“ķ•˜ģ§€ ģ•Šģ•„ ė²•ģ •ėŒ€ė¦¬ģø ė™ģ˜ģ™€ ź“€ė Øėœ 사항(ė²•ģ •ėŒ€ė¦¬ģø ģ“ė¦„, ė™ģ˜ ģ¼ģ‹œ 등)ģ„ ķ™•ģøķ•  수 ģ—†ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제15ģ”°(ź°œģøģ •ė³“ģ˜ ģˆ˜ģ§‘Ā·ģ“ģš©), 제22ģ”°(ė™ģ˜ė„¼ ė°›ėŠ” 방법), 제22ģ”°ģ˜2(ģ•„ė™ģ˜ ź°œģøģ •ė³“ 볓호)","ź°œģøģ •ė³“ 처리 방법에 ź“€ķ•œ ź³ ģ‹œ"]}],"description": "ź°œģøģ •ė³“ėŠ” ģ ė²•ķ•˜ź³  ģ •ė‹¹ķ•˜ź²Œ ģˆ˜ģ§‘Ā·ģ“ģš©ķ•˜ģ—¬ģ•¼ ķ•˜ė©°, ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ė„¼ 근거딜 ģˆ˜ģ§‘ķ•˜ėŠ” ź²½ģš°ģ—ėŠ” ģ ė²•ķ•œ ė°©ė²•ģœ¼ė”œ ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ė„¼ 받아야 ķ•œė‹¤. ė˜ķ•œ 만 14세 미만 ģ•„ė™ģ˜ ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ėŠ” ź²½ģš°ģ—ėŠ” ź·ø ė²•ģ •ėŒ€ė¦¬ģøģ˜ ė™ģ˜ė„¼ 받아야 ķ•˜ė©° ė²•ģ •ėŒ€ė¦¬ģøģ“ ė™ģ˜ķ•˜ģ˜€ėŠ”ģ§€ė„¼ ķ™•ģøķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.2": {"name": "ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ œķ•œ","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.1.2 ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ œķ•œ","Subdomain": "3.1. ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ‹œ 볓호씰치","AuditEvidence": ["ģ˜Øė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ķ™ˆķŽ˜ģ“ģ§€ ķšŒģ›ź°€ģž… 화멓, ģ“ė²¤ķŠø ģ°øģ—¬ 화멓 등)","ģ˜¤ķ”„ė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(멤버십 ź°€ģž…ģ‹ ģ²­ģ„œ 등)","ź°œģøģ •ė³“ 처리방침"],"AuditChecklist": ["ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ėŠ” 경우 ź·ø 목적에 ķ•„ģš”ķ•œ ė²”ģœ„ģ—ģ„œ ģµœģ†Œķ•œģ˜ ģ •ė³“ė§Œģ„ ģˆ˜ģ§‘ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ė„¼ 받아 ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ėŠ” 경우 ķ•„ģš”ķ•œ ģµœģ†Œķ•œģ˜ 정볓 ģ™øģ˜ ź°œģøģ •ė³“ģˆ˜ģ§‘ģ—ėŠ” ė™ģ˜ķ•˜ģ§€ ģ•Šģ„ 수 ģžˆė‹¤ėŠ” ģ‚¬ģ‹¤ģ„ 구첓적으딜 ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?","정볓주첓가 ģˆ˜ģ§‘ 목적에 ķ•„ģš”ķ•œ ģµœģ†Œķ•œģ˜ 정볓 ģ“ģ™øģ˜ ź°œģøģ •ė³“ ģˆ˜ģ§‘ģ— ė™ģ˜ķ•˜ģ§€ģ•ŠėŠ”ė‹¤ėŠ” ģ“ģœ ė”œ ģ„œė¹„ģŠ¤ ė˜ėŠ” ģž¬ķ™”ģ˜ ģ œź³µģ„ ź±°ė¶€ķ•˜ģ§€ ģ•Šė„ė” ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź³„ģ•½ģ˜ 첓결 ė° ģ“ķ–‰ģ„ 근거딜 정볓주첓 ė™ģ˜ ģ—†ģ“ ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ė©“ģ„œ ź³„ģ•½ģ˜ 첓결 ė° ģ“ķ–‰ģ„ ģœ„ķ•“ ė°˜ė“œģ‹œ ķ•„ģš”ķ•˜ģ§€ ģ•Šģ€ ź°œģøģ •ė³“ ķ•­ėŖ©ź¹Œģ§€ ź³¼ė„ķ•˜ź²Œ ģˆ˜ģ§‘ķ•˜ėŠ” 경우","사딀 2 : ģ •ė³“ģ£¼ģ²“ė”œė¶€ķ„° ģ„ ķƒģ‚¬ķ•­ģ— ėŒ€ķ•œ ė™ģ˜ė„¼ ė°›ģœ¼ė©“ģ„œ 핓당 ź°œģøģ •ė³“ ģˆ˜ģ§‘ģ—ėŠ” ė™ģ˜ķ•˜ģ§€ ģ•„ė‹ˆķ•  수 ģžˆė‹¤ėŠ” ģ‚¬ģ‹¤ģ„ 구첓적으딜 ģ•Œė¦¬ģ§€ ģ•Šģ€ 경우","사딀 3 : ķšŒģ›ź°€ģž… ģ–‘ģ‹ģ—ģ„œ ķ•„ģˆ˜ģ™€ ģ„ ķƒ 정볓넼 źµ¬ė¶„ķ•˜ģ—¬ ė³„ė„ ė™ģ˜ė„¼ ė°›ė„ė” ė˜ģ–“ ģžˆģ—ˆģœ¼ė‚˜, ģ„ ķƒģ •ė³“ģ— ėŒ€ķ•˜ģ—¬ ė™ģ˜ķ•˜ģ§€ ģ•Šģ•„ė„ ķšŒģ›ź°€ģž…ģ“ ź°€ėŠ„ķ•Øģ„ 정볓주첓가 ģøģ§€ķ•  수 ģžˆė„ė” 구첓적으딜 ģ•Œė¦¬ģ§€ ģ•Šģ€ 경우(ź°œģøģ •ė³“ ģž…ė „ ģ–‘ģ‹ģ— ź°œģøģ •ė³“ ķ•­ėŖ©ė³„ė”œ ķ•„ģˆ˜, ģ„ ķƒ 여부가 ķ‘œģ‹œė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우 등)","사딀 4 : ķ™ˆķŽ˜ģ“ģ§€ ķšŒģ›ź°€ģž… ķ™”ė©“ģ—ģ„œ ģ„ ķƒģ‚¬ķ•­ģ— ėŒ€ķ•˜ģ—¬ ė™ģ˜ķ•˜ģ§€ ģ•Šź±°ė‚˜ ģ„ ķƒģ •ė³“ė„¼ ģž…ė „ķ•˜ģ§€ ģ•Šģœ¼ė©“ ė‹¤ģŒ ė‹Øź³„ė”œ ė„˜ģ–“ź°€ģ§€ ģ•Šź±°ė‚˜ ķšŒģ›ź°€ģž…ģ“ ģ°Øė‹Øė˜ėŠ” 경우","사딀 5 : ģ±„ģš© 계약 ģ‹œ ģ±„ģš© ģ˜ˆģ • 직묓와 직접 ź“€ė Øģ“ ģ—†ėŠ” 가씱사항 등 ź³¼ė„ķ•œ ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제16ģ”°(ź°œģøģ •ė³“ģ˜ ģˆ˜ģ§‘ģ œķ•œ), 제22ģ”°(ė™ģ˜ė„¼ ė°›ėŠ” 방법)"]}],"description": "ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ėŠ” 경우 처리 목적에 ķ•„ģš”ķ•œ ģµœģ†Œķ•œģ˜ ź°œģøģ •ė³“ė§Œģ„ ģˆ˜ģ§‘ķ•˜ģ—¬ģ•¼ ķ•˜ė©°, 정볓주첓가 ģ„ ķƒģ ģœ¼ė”œ ė™ģ˜ķ•  수 ģžˆėŠ” 사항 등에 ė™ģ˜ķ•˜ģ§€ ģ•„ė‹ˆķ•œė‹¤ėŠ” ģ“ģœ ė”œ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģž¬ķ™” ė˜ėŠ” ģ„œė¹„ģŠ¤ģ˜ ģ œź³µģ„ ź±°ė¶€ķ•˜ģ§€ ģ•Šģ•„ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.3": {"name": "ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø 처리 ģ œķ•œ","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.1.3 ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø 처리 ģ œķ•œ","Subdomain": "3.1. ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ķ™ˆķŽ˜ģ“ģ§€ ķšŒģ›ź°€ģž… 화멓, ģ“ė²¤ķŠø ģ°øģ—¬, 멤버십 ź°€ģž…ģ‹ ģ²­ģ„œ 등)","ģ˜Øė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ė³øģøķ™•ģø 등 ėŒ€ģ²“ź°€ģž…ģˆ˜ė‹Ø 제공 화멓)","ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øė„¼ ģ²˜ė¦¬ķ•˜ėŠ” 경우 ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø 처리 근거 ģ¦ź±°ģžė£Œ","ź°œģøģ •ė³“ 처리방침"],"AuditChecklist": ["ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øėŠ” ėŖ…ķ™•ķ•œ 법적 근거가 ģžˆėŠ” ź²½ģš°ģ—ė§Œ ģ²˜ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øģ˜ ģˆ˜ģ§‘ 근거가 ė˜ėŠ” ė²•ģ”°ķ•­ģ„ 구첓적으딜 ģ‹ė³„ķ•˜ź³  ģžˆėŠ”ź°€?","법적 근거에 ė”°ė¼ ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øė„¼ ģ²˜ė¦¬ķ•˜ėŠ” ź²½ģš°ģ—ė„ 정볓주첓가 ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ė„¼ ķ†µķ•˜ģ—¬ ķšŒģ›ģœ¼ė”œ ź°€ģž…ķ•˜ėŠ” ė‹Øź³„ģ—ģ„œėŠ” ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øė„¼ ģ‚¬ģš©ķ•˜ģ§€ ģ•„ė‹ˆķ•˜ź³ ė„ ķšŒģ›ģœ¼ė”œ ź°€ģž…ķ•  수 ģžˆėŠ” ė°©ė²•ģ„ ģ œź³µķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķ™ˆķŽ˜ģ“ģ§€ ź°€ģž…ź³¼ ź“€ė Øķ•˜ģ—¬ ģ‹¤ėŖ…ķ™•ģø 등 ė‹Øģˆœ ķšŒģ›ź“€ė¦¬ ėŖ©ģ ģ„ ģœ„ķ•˜ģ—¬ ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ģ— ź·¼ź±°ķ•˜ģ—¬ ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øė„¼ ģˆ˜ģ§‘ķ•œ 경우","사딀 2 : ģ •ė³“ģ£¼ģ²“ģ˜ ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øė„¼ ģ‹œķ–‰ź·œģ¹™ģ“ė‚˜ ģ§€ė°©ģžģ¹˜ė‹Øģ²“ģ˜ 씰딀에 ź·¼ź±°ķ•˜ģ—¬ ģˆ˜ģ§‘ķ•œ 경우","사딀 3 : ė¹„ė°€ė²ˆķ˜ø 분실 ģ‹œ ė³øģøķ™•ģø ė“±ģ˜ 목적으딜 ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø ė’¤ 6ģžė¦¬ė„¼ ģˆ˜ģ§‘ķ•˜ģ§€ė§Œ, ź“€ė Øėœ 법적 근거가 ģ—†ėŠ” 경우","사딀 4 : ģ±„ģš©ģ „ķ˜• ģ§„ķ–‰ė‹Øź³„ģ—ģ„œ 법적 근거 ģ—†ģ“ ģž…ģ‚¬ģ§€ģ›ģžģ˜ ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øė„¼ ģˆ˜ģ§‘ķ•œ 경우","사딀 5 : ģ½œģ„¼ķ„°ģ— ģƒķ’ˆ, ģ„œė¹„ģŠ¤ ꓀련 ė¬øģ˜ ģ‹œ ė³øģøķ™•ģøģ„ ģœ„ķ•˜ģ—¬ ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øė„¼ ģˆ˜ģ§‘ķ•œ 경우","사딀 6 : ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø ģˆ˜ģ§‘ģ˜ 법적 근거가 ģžˆė‹¤ėŠ” ģ‚¬ģœ ė”œ ķ™ˆķŽ˜ģ“ģ§€ ķšŒģ›ź°€ģž… ė‹Øź³„ģ—ģ„œ ėŒ€ģ²“ź°€ģž…ģˆ˜ė‹Øģ„ ģ œź³µķ•˜ģ§€ ģ•Šź³  ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øė„¼ ģž…ė „ė°›ėŠ” ė³øģøķ™•ģø ė° ķšŒģ›ź°€ģž… ė°©ė²•ė§Œģ„ ģ œź³µķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제24ģ”°ģ˜2(ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø ģ²˜ė¦¬ģ˜ ģ œķ•œ)","ģ •ė³“ķ†µģ‹ ė§ė²• 제23ģ”°ģ˜2(ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øģ˜ ģ‚¬ģš© ģ œķ•œ)"]}],"description": "ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øėŠ” 법적 근거가 ģžˆėŠ” 경우넼 ģ œģ™øķ•˜ź³ ėŠ” ģˆ˜ģ§‘Ā·ģ“ģš© 등 ģ²˜ė¦¬ķ•  수 ģ—†ģœ¼ė©°, ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜øģ˜ ģ²˜ė¦¬ź°€ ķ—ˆģš©ėœ ź²½ģš°ė¼ ķ•˜ė”ė¼ė„ ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ ė“±ģ—ģ„œ ėŒ€ģ²“ģˆ˜ė‹Øģ„ ģ œź³µķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.4": {"name": "민감정볓 ė° ź³ ģœ ģ‹ė³„ģ •ė³“ģ˜ 처리 ģ œķ•œ","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.1.4 민감정볓 ė° ź³ ģœ ģ‹ė³„ģ •ė³“ģ˜ 처리 ģ œķ•œ","Subdomain": "3.1. ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ‹œ 볓호씰치","AuditEvidence": ["ģ˜Øė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ķ™ˆķŽ˜ģ“ģ§€ ķšŒģ›ź°€ģž… 화멓, ģ“ė²¤ķŠø ģ°øģ—¬ 등)","ģ˜¤ķ”„ė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ķšŒģ›ź°€ģž…ģ‹ ģ²­ģ„œ 등)","ź°œģøģ •ė³“ 처리방침"],"AuditChecklist": ["ėÆ¼ź°ģ •ė³“ėŠ” ģ •ė³“ģ£¼ģ²“ė”œė¶€ķ„° ė³„ė„ģ˜ ė™ģ˜ė„¼ ė°›ź±°ė‚˜ ꓀련 법령에 근거가 ģžˆėŠ” ź²½ģš°ģ—ė§Œģ²˜ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ź³ ģœ ģ‹ė³„ģ •ė³“(ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø ģ œģ™ø)ėŠ” ģ •ė³“ģ£¼ģ²“ė”œė¶€ķ„° ė³„ė„ģ˜ ė™ģ˜ė„¼ ė°›ź±°ė‚˜ ꓀련 법령에 źµ¬ģ²“ģ ģø 근거가 ģžˆėŠ” ź²½ģš°ģ—ė§Œ ģ²˜ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģž¬ķ™” ė˜ėŠ” ģ„œė¹„ģŠ¤ė„¼ ģ œź³µķ•˜ėŠ” ź³¼ģ •ģ—ģ„œ ź³µź°œė˜ėŠ” 정볓에 ģ •ė³“ģ£¼ģ²“ģ˜ 민감정볓가 ķ¬ķ•ØėØģœ¼ė”œģØ ģ‚¬ģƒķ™œ ģ¹Øķ•“ģ˜ ģœ„ķ—˜ģ„±ģ“ ģžˆė‹¤ź³  ķŒė‹Øķ•˜ėŠ” ė•Œģ—ėŠ” ģž¬ķ™” ė˜ėŠ” ģ„œė¹„ģŠ¤ģ˜ 제공 전에 ėÆ¼ź°ģ •ė³“ģ˜ 공개 ź°€ėŠ„ģ„± ė° ė¹„ź³µź°œė„¼ ģ„ ķƒķ•˜ėŠ” ė°©ė²•ģ„ 정볓주첓가 ģ•Œģ•„ė³“źø° ģ‰½ź²Œ ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģž„ģ• ģøģ— ėŒ€ķ•œ ģš”źøˆź°ė©“ 등 ķ˜œķƒ 부여넼 ģœ„ķ•˜ģ—¬ ģž„ģ•  여부 등 걓강에 ź“€ķ•œ 민감정볓넼 ģˆ˜ģ§‘ķ•˜ė©“ģ„œ 다넸 ź°œģøģ •ė³“ 항목에 ķ¬ķ•Øķ•˜ģ—¬ ģ¼ź“„ ė™ģ˜ė„¼ ė°›ģ€ 경우","사딀 2 : ķšŒģ›ź°€ģž… ģ‹œ ģ™øźµ­ģøģ— ķ•œķ•˜ģ—¬ ģ™øźµ­ģøė“±ė”ė²ˆķ˜øė„¼ ģˆ˜ģ§‘ķ•˜ė©“ģ„œ 다넸 ź°œģøģ •ė³“ 항목에 ķ¬ķ•Øķ•˜ģ—¬ ģ¼ź“„ ė™ģ˜ė„¼ ė°›ģ€ 경우","사딀 3 : 민감정볓 ė˜ėŠ” ź³ ģœ ģ‹ė³„ģ •ė³“ģ˜ ģˆ˜ģ§‘ģ— ėŒ€ķ•“ ė³„ė„ģ˜ ė™ģ˜ė„¼ ė°›ģœ¼ė©“ģ„œ ź³ ģ§€ķ•˜ģ—¬ģ•¼ ķ•  4가지 사항 중에 ģ¼ė¶€ė„¼ ėˆ„ė½ķ•˜ź±°ė‚˜ ģž˜ėŖ»ėœ ė‚“ģš©ģœ¼ė”œ ź³ ģ§€ķ•˜ėŠ” 경우(ė™ģ˜ ź±°ė¶€ 권리 ė° ė™ģ˜ 거부에 따넸 ė¶ˆģ“ģµ ģ‚¬ķ•­ģ„ ź³ ģ§€ķ•˜ģ§€ ģ•Šģ€ 경우 등)"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제23ģ”°(ėÆ¼ź°ģ •ė³“ģ˜ ģ²˜ė¦¬ģ œķ•œ), 제24ģ”°(ź³ ģœ ģ‹ė³„ģ •ė³“ģ˜ 처리 ģ œķ•œ)"]}],"description": "민감정볓와 ź³ ģœ ģ‹ė³„ģ •ė³“(ģ£¼ėÆ¼ė“±ė”ė²ˆķ˜ø ģ œģ™ø)넼 ģ²˜ė¦¬ķ•˜źø° ģœ„ķ•“ģ„œėŠ” ė²•ė ¹ģ—ģ„œ 구첓적으딜 처리넼 ģš”źµ¬ķ•˜ź±°ė‚˜ ķ—ˆģš©ķ•˜ėŠ” 경우넼 ģ œģ™øķ•˜ź³ ėŠ” ģ •ė³“ģ£¼ģ²“ģ˜ ė³„ė„ ė™ģ˜ė„¼ 받아야 ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.5": {"name": "ź°œģøģ •ė³“ ź°„ģ ‘ģˆ˜ģ§‘","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.1.5 ź°œģøģ •ė³“ ź°„ģ ‘ģˆ˜ģ§‘","Subdomain": "3.1. ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ 제공 ꓀련 ź³„ģ•½ģ„œ(ģ œź³µķ•˜ėŠ” ģžģ™€ģ˜ 계약 사항)","ź°œģøģ •ė³“ ģˆ˜ģ§‘ģ¶œģ²˜ģ— ėŒ€ķ•œ 정볓주첓 통지 ė‚“ģ—­","ź°œģøģ •ė³“ 처리방침"],"AuditChecklist": ["정볓주첓 ģ“ģ™øģ˜ 제3ģžė”œė¶€ķ„° ź°œģøģ •ė³“ė„¼ ģ œź³µė°›ėŠ” 경우 ź°œģøģ •ė³“ ģˆ˜ģ§‘ģ— ėŒ€ķ•œ ė™ģ˜ķšė“ ģ±…ģž„ģ“ ź°œģøģ •ė³“ė„¼ ģ œź³µķ•˜ėŠ” ģžģ—ź²Œ ģžˆģŒģ„ ź³„ģ•½ģ„ ķ†µķ•˜ģ—¬ ėŖ…ģ‹œķ•˜ź³  ģžˆėŠ”ź°€?","공개된 매첓 ė° ģž„ģ†Œģ—ģ„œ ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ėŠ” 경우 ģ •ė³“ģ£¼ģ²“ģ˜ 공개 ėŖ©ģ Ā·ė²”ģœ„ ė° ģ‚¬ķšŒ ķ†µė…ģƒ ė™ģ˜ ģ˜ģ‚¬ź°€ ģžˆė‹¤ź³  ģøģ •ė˜ėŠ” ė²”ģœ„ ė‚“ģ—ģ„œė§Œ ģˆ˜ģ§‘Ā·ģ“ģš©ķ•˜ź³  ģžˆėŠ”ź°€?","ģ„œė¹„ģŠ¤ 계약 ģ“ķ–‰ģ„ ģœ„ķ•“ ķ•„ģš”ķ•œ ź²½ģš°ė”œģ„œ, ģ„œė¹„ģŠ¤ 제공 ź³¼ģ •ģ—ģ„œ ģžė™ģˆ˜ģ§‘ģž„ģ¹˜ 등에 ģ˜ķ•˜ģ—¬ ģˆ˜ģ§‘Ā·ģƒģ„±ķ•˜ėŠ” ź°œģøģ •ė³“ģ˜ ź²½ģš°ģ—ė„ ģµœģ†Œģˆ˜ģ§‘ ģ›ģ¹™ģ„ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?","정볓주첓 ģ“ģ™øė”œė¶€ķ„° ģˆ˜ģ§‘ķ•˜ėŠ” ź°œģøģ •ė³“ģ— ėŒ€ķ•“ ģ •ė³“ģ£¼ģ²“ģ˜ ģš”źµ¬ź°€ ģžˆėŠ” 경우 ģ¦‰ģ‹œ ķ•„ģš”ķ•œ ģ‚¬ķ•­ģ„ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?","정볓주첓 ģ“ģ™øė”œė¶€ķ„° ģˆ˜ģ§‘ķ•œ ź°œģøģ •ė³“ė„¼ ģ²˜ė¦¬ķ•˜ėŠ” 경우 ź°œģøģ •ė³“ģ˜ ģ¢…ė„˜Ā·ź·œėŖØ ė“±ģ“ 법적 ģš”ź±“ģ— ķ•“ė‹¹ķ•˜ėŠ” 경우 ķ•„ģš”ķ•œ ģ‚¬ķ•­ģ„ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģˆ˜ģ§‘ ģ¶œģ²˜ģ— ėŒ€ķ•“ ģ•Œė¦° źø°ė”ģ„ 핓당 ź°œģøģ •ė³“ģ˜ 파기 ģ‹œź¹Œģ§€ 볓꓀ ė° ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€, SNS에 공개된 ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ź³  ģžˆėŠ” ģƒķƒœģ—ģ„œ ģ •ė³“ģ£¼ģ²“ģ˜ ģˆ˜ģ§‘ 출처 ģš”źµ¬ģ— ėŒ€ķ•œ ģ²˜ė¦¬ģ ˆģ°Øź°€ ģ”“ģž¬ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ź°œģøģ •ė³“ ė³“ķ˜øė²• 제17씰제1ķ•­ģ œ1ķ˜øģ— ė”°ė¼ 다넸 ģ‚¬ģ—…ģžė”œė¶€ķ„° ź°œģøģ •ė³“ ģ œź³µė™ģ˜ė„¼ 근거딜 ź°œģøģ •ė³“ė„¼ ģ œź³µė°›ģ•˜ģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•˜ģ—¬ 핓당 ģ •ė³“ģ£¼ģ²“ģ—ź²Œ 3ź°œģ›” 낓에 ķ†µģ§€ķ•˜ģ§€ ģ•Šģ€ 경우(ė‹¤ė§Œ ģ œź³µė°›ģ€ ģžź°€ 5만 ėŖ… ģ“ģƒ ģ •ė³“ģ£¼ģ²“ģ˜ 민감정볓 ė˜ėŠ” ź³ ģœ ģ‹ė³„ģ •ė³“ė„¼ ģ²˜ė¦¬ķ•˜ź±°ė‚˜ 100만 ėŖ… ģ“ģƒ ģ •ė³“ģ£¼ģ²“ģ˜ ź°œģøģ •ė³“ė„¼ ģ²˜ė¦¬ķ•˜ėŠ” 경우)","사딀 3 : 법적 ģ˜ė¬“ ėŒ€ģƒģžģ— ķ•“ė‹¹ė˜ģ–“ ź°œģøģ •ė³“ ģˆ˜ģ§‘ 출처넼 ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ķ†µģ§€ķ•˜ė©“ģ„œ ź°œģøģ •ė³“ģ˜ 처리목적 ė˜ėŠ” ė™ģ˜ė„¼ ģ² ķšŒķ•  ź¶Œė¦¬ź°€ ģžˆė‹¤ėŠ” 사실 등 ķ•„ģˆ˜ ķ†µģ§€ģ‚¬ķ•­ģ„ ģ¼ė¶€ ėˆ„ė½ķ•œ 경우","사딀 4 : 법적 ģ˜ė¬“ ėŒ€ģƒģžģ— ķ•“ė‹¹ė˜ģ–“ ź°œģøģ •ė³“ ģˆ˜ģ§‘ 출처넼 ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ķ†µģ§€ķ•˜ģ˜€ģœ¼ė‚˜, ģˆ˜ģ§‘ 출처 통지에 ź“€ķ•œ źø°ė”ģ„ 핓당 ź°œģøģ •ė³“ģ˜ 파기 ģ‹œź¹Œģ§€ ė³“ź“€ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제16ģ”°(ź°œģøģ •ė³“ģ˜ ģˆ˜ģ§‘ ģ œķ•œ), 제19ģ”°(ź°œģøģ •ė³“ė„¼ ģ œź³µė°›ģ€ ģžģ˜ ģ“ģš©Ā·ģ œź³µ ģ œķ•œ), 제20ģ”°(정볓주첓 ģ“ģ™øė”œė¶€ķ„° ģˆ˜ģ§‘ķ•œ ź°œģøģ •ė³“ģ˜ ģˆ˜ģ§‘ 출처 등 통지)"]}],"description": "정볓주첓 ģ“ģ™øė”œė¶€ķ„° ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ź±°ė‚˜ 제3ģžė”œė¶€ķ„° ģ œź³µė°›ėŠ” ź²½ģš°ģ—ėŠ” 업묓에 ķ•„ģš”ķ•œ ģµœģ†Œķ•œģ˜ ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ź±°ė‚˜ ģ œź³µė°›ģ•„ģ•¼ ķ•˜ė©°, 법령에 ź·¼ź±°ķ•˜ź±°ė‚˜ ģ •ė³“ģ£¼ģ²“ģ˜ ģš”źµ¬ź°€ ģžˆģœ¼ė©“ ź°œģøģ •ė³“ģ˜ ģˆ˜ģ§‘ 출처, 처리목적, ģ²˜ė¦¬ģ •ģ§€ģ˜ ģš”źµ¬ź¶Œė¦¬ė„¼ ģ•Œė ¤ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.6": {"name": "ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģ„¤ģ¹˜Ā·ģš“ģ˜","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.1.6 ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģ„¤ģ¹˜Ā·ģš“ģ˜","Subdomain": "3.1. ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ‹œ 볓호씰치","AuditEvidence": ["ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° 욓영 ķ˜„ķ™©","ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģ•ˆė‚“ķŒ","ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģš“ģ˜Ā·ź“€ė¦¬ė°©ģ¹Ø","ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ꓀리화멓(ź³„ģ •Ā·ź¶Œķ•œ ė‚“ģ—­, ģ˜ģƒģ •ė³“ 볓씓기간 등)","ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° 욓영 ģˆ˜ķƒģžģ™€ģ˜ ź³„ģ•½ģ„œ ė° 점검 ģ“ė „"],"AuditChecklist": ["공개된 ģž„ģ†Œģ— ź³ ģ •ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ė„¼ ģ„¤ģ¹˜Ā·ģš“ģ˜ķ•  경우 법적 ķ—ˆģš© ģš”ź±“ģ— ķ•“ė‹¹ķ•˜ėŠ”ģ§€ė„¼ ź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?","공공기꓀ ė“±ģ“ 공개된 ģž„ģ†Œģ— ź³ ģ •ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ė„¼ ģ„¤ģ¹˜Ā·ģš“ģ˜ķ•˜ė ¤ėŠ” 경우 ź³µģ²­ķšŒĀ·ģ„¤ėŖ…ķšŒ 개최 ė“±ģ˜ 법령에 따넸 절차넼 거쳐 ꓀계 전문가 ė° ģ“ķ•“ź“€ź³„ģžģ˜ ģ˜ź²¬ģ„ ģˆ˜ė “ķ•˜ź³  ģžˆėŠ”ź°€?","ź³ ģ •ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģ„¤ģ¹˜Ā·ģš“ģ˜ ģ‹œ 정볓주첓가 ģ‰½ź²Œ ģøģ‹ķ•  수 ģžˆė„ė” ģ•ˆė‚“ķŒ ģ„¤ģ¹˜ 등 ķ•„ģš”ķ•œ 씰치넼 ķ•˜ź³  ģžˆėŠ”ź°€?","업묓넼 목적으딜 공개된 ģž„ģ†Œģ—ģ„œ ģ“ė™ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ė„¼ ģš“ģ˜ķ•˜ėŠ” 경우 법적 ķ—ˆģš© ģš”ź±“ģ— ķ•“ė‹¹ķ•˜ėŠ”ģ§€ė„¼ ź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?","업묓넼 목적으딜 공개된 ģž„ģ†Œģ—ģ„œ ģ“ė™ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ė”œ ģ‚¬ėžŒ ė˜ėŠ” ź·ø ģ‚¬ėžŒź³¼ ź“€ė Øėœ ģ‚¬ė¬¼ģ˜ ģ˜ģƒģ„ ģ“¬ģ˜ķ•˜ėŠ” 경우 ė¶ˆė¹›, ģ†Œė¦¬, ģ•ˆė‚“ķŒ ė“±ģ˜ ė°©ė²•ģœ¼ė”œ 쓬영 ģ‚¬ģ‹¤ģ„ ķ‘œģ‹œķ•˜ź³  ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?","ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ė° ģ˜ģƒģ •ė³“ģ˜ ģ•ˆģ „ķ•œ ꓀리넼 ģœ„ķ•œ ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģš“ģ˜Ā·ź“€ė¦¬ ė°©ģ¹Øģ„ ė§ˆė Øķ•˜ģ—¬ ģ‹œķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ˜ģƒģ •ė³“ģ˜ 볓꓀ źø°ź°„ģ„ ģ •ķ•˜ź³  ģžˆģœ¼ė©°, 볓꓀ źø°ź°„ 만료 ģ‹œ 지첓 ģ—†ģ“ ķŒŒźø°ķ•˜ź³  ģžˆėŠ”ź°€?","ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģ„¤ģ¹˜Ā·ģš“ģ˜ģ— ź“€ķ•œ 사묓넼 ģœ„ķƒķ•˜ėŠ” 경우 ꓀련 절차 ė° ģš”ź±“ģ— ė”°ė¼ ź³„ģ•½ģ„œģ— ė°˜ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģ•ˆė‚“ķŒģ˜ ź³ ģ§€ 문구가 ģ¼ė¶€ ėˆ„ė½ė˜ģ–“ 욓영되고 ģžˆź±°ė‚˜, ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° 욓영 ė° ꓀리 ė°©ģ¹Øģ„ ģˆ˜ė¦½Ā·ģš“ģ˜ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģš“ģ˜Ā·ź“€ė¦¬ ė°©ģ¹Øģ„ 수립 ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, 방침 ė‚“ģš©ź³¼ 달리 ė³“ź“€źø°ź°„ģ„ ģ¤€ģˆ˜ķ•˜ģ§€ ģ•Šź³  ģš“ģ˜ė˜ź±°ė‚˜, ģ˜ģƒģ •ė³“ 볓호넼 ģœ„ķ•œ ģ ‘ź·¼ķ†µģ œ ė° ė”œź¹… 등 방침에 źø°ģˆ ķ•œ ģ‚¬ķ•­ģ“ ģ¤€ģˆ˜ė˜ģ§€ ģ•ŠėŠ” 등 ꓀리가 ėÆøķ”ķ•œ 경우","사딀 3 : ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ģ˜ ģ„¤ģ¹˜Ā·ģš“ģ˜ 사묓넼 외부업첓에 ģœ„ķƒķ•˜ź³  ģžˆģœ¼ė‚˜, ģ˜ģƒģ •ė³“ģ˜ ꓀리 ķ˜„ķ™© 점검에 ź“€ķ•œ 사항, ģ†ķ•“ė°°ģƒ ģ±…ģž„ģ— ź“€ķ•œ 사항 등 ė²•ė ¹ģ—ģ„œ ģš”źµ¬ķ•˜ėŠ” ė‚“ģš©ģ„ ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° 업묓 ģœ„ķƒ ź³„ģ•½ģ„œģ— ėŖ…ģ‹œķ•˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ģ˜ ģ„¤ģ¹˜Ā·ģš“ģ˜ 사묓넼 외부업첓에 ģœ„ķƒķ•˜ź³  ģžˆģœ¼ė‚˜, ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø° ģ•ˆė‚“ķŒģ— ģˆ˜ķƒģžģ˜ ėŖ…ģ¹­ź³¼ ģ—°ė½ģ²˜ė„¼ ėˆ„ė½ķ•˜ģ—¬ ź³ ģ§€ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제25ģ”°(ź³ ģ •ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ģ˜ ģ„¤ģ¹˜Ā·ģš“ģ˜ ģ œķ•œ), 제25ģ”°ģ˜2(ģ“ė™ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ģ˜ 욓영 ģ œķ•œ)"]}],"description": "ź³ ģ •ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ė„¼ 공개된 ģž„ģ†Œģ— ģ„¤ģ¹˜Ā·ģš“ģ˜ķ•˜ź±°ė‚˜ ģ“ė™ķ˜• ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ė„¼ 공개된 ģž„ģ†Œģ—ģ„œ 업묓넼 목적으딜 ģš“ģ˜ķ•˜ėŠ” 경우 ģ„¤ģ¹˜ 목적 ė° ģœ„ģ¹˜ģ— ė”°ė¼ 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ģ¤€ģˆ˜ķ•˜ź³ , ģ ģ ˆķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.1.7": {"name": "ė§ˆģ¼€ķŒ… ėŖ©ģ ģ˜ ź°œģøģ •ė³“ ģˆ˜ģ§‘Ā·ģ“ģš©","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.1.7 ė§ˆģ¼€ķŒ… ėŖ©ģ ģ˜ ź°œģøģ •ė³“ ģˆ˜ģ§‘Ā·ģ“ģš©","Subdomain": "3.1. ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ‹œ 볓호씰치","AuditEvidence": ["ģ˜Øė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ķ™ˆķŽ˜ģ“ģ§€ ķšŒģ›ź°€ģž… 화멓, ėŖØė°”ģ¼ģ•± ķšŒģ›ź°€ģž… 화멓, ģ“ė²¤ķŠø ģ°øģ—¬ 등)","ģ˜¤ķ”„ė¼ģø ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹(ķšŒģ›ź°€ģž…ģ‹ ģ²­ģ„œ 등)","ė§ˆģ¼€ķŒ… ė™ģ˜ źø°ė”","ꓑ고성 정볓전솔 ģˆ˜ģ‹ ė™ģ˜ źø°ė” ė° ģˆ˜ģ‹ ė™ģ˜ ģ˜ģ‚¬ķ™•ģø źø°ė”","ꓑ고성 정볓 ė°œģ†” ģ‹œģŠ¤ķ…œ ź“€ė¦¬ģž 화멓(ė©”ģ¼, SMS, 앱 ķ‘øģ‹œ 등)","ꓑ고성 정볓 ė°œģ†” 문구","ź°œģøģ •ė³“ 처리방침"],"AuditChecklist": ["ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģž¬ķ™”ė‚˜ ģ„œė¹„ģŠ¤ė„¼ ķ™ė³“ķ•˜ź±°ė‚˜ 판매넼 ź¶Œģœ ķ•˜źø° ģœ„ķ•˜ģ—¬ ź°œģøģ •ė³“ ģ²˜ė¦¬ģ— ėŒ€ķ•œ ė™ģ˜ė„¼ ė°›ėŠ” 경우 정볓주첓가 ģ“ė„¼ ėŖ…ķ™•ķ•˜ź²Œ ģøģ§€ķ•  수 ģžˆė„ė” ģ•Œė¦¬ź³  ė³„ė„ģ˜ ė™ģ˜ė„¼ 받고 ģžˆėŠ”ź°€?","ģ „ģžģ  전솔매첓넼 ģ“ģš©ķ•˜ģ—¬ ģ˜ė¦¬ėŖ©ģ ģ˜ ꓑ고성 정볓넼 ģ „ģ†”ķ•˜ėŠ” 경우 ģˆ˜ģ‹ ģžģ˜ ėŖ…ģ‹œģ ģø 사전 ė™ģ˜ė„¼ 받고 ģžˆģœ¼ė©°, 2ė…„ė§ˆė‹¤ ģ •źø°ģ ģœ¼ė”œ ģˆ˜ģ‹ ģžģ˜ ģˆ˜ģ‹ ė™ģ˜ 여부넼 ķ™•ģøķ•˜ź³  ģžˆėŠ”ź°€?","ģ „ģžģ  전솔매첓넼 ģ“ģš©ķ•œ ģ˜ė¦¬ėŖ©ģ ģ˜ ꓑ고성 정볓 전솔에 ėŒ€ķ•˜ģ—¬ ģˆ˜ģ‹ ģžź°€ ģˆ˜ģ‹ ź±°ė¶€ģ˜ģ‚¬ė„¼ ķ‘œģ‹œķ•˜ź±°ė‚˜ 사전 ė™ģ˜ė„¼ ģ² ķšŒķ•œ 경우 ģ˜ė¦¬ėŖ©ģ ģ˜ ꓑ고성 정볓 ģ „ģ†”ģ„ ģ¤‘ė‹Øķ•˜ė„ė” ķ•˜ź³  ģžˆėŠ”ź°€?","ģ˜ė¦¬ėŖ©ģ ģ˜ ꓑ고성 정볓넼 ģ „ģ†”ķ•˜ėŠ” 경우 ģ „ģ†”ģžģ˜ ėŖ…ģ¹­, ģˆ˜ģ‹ ź±°ė¶€ 방법 ė“±ģ„ 구첓적으딜 ė°ķžˆź³  ģžˆģœ¼ė©°, ģ•¼ź°„ģ‹œź°„ģ—ėŠ” ģ „ģ†”ķ•˜ģ§€ ģ•Šė„ė” ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : Ź»ķ™ė³“ ė° ė§ˆģ¼€ķŒ…Ź¼ 목적으딜 ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ķ•˜ė©“ģ„œ Ź»ė¶€ź°€ģ„œė¹„ģŠ¤ 제공ʼ, ʻ제휓 ģ„œė¹„ģŠ¤ 제공ʼ 등과 ź°™ģ“ ėŖ©ģ ģ„ ėŖØķ˜øķ•˜ź²Œ ģ•ˆė‚“ķ•˜ėŠ” 경우 ė˜ėŠ” 다넸 목적으딜 ģˆ˜ģ§‘ķ•˜ėŠ” ź°œģøģ •ė³“ģ™€ źµ¬ė¶„ķ•˜ģ§€ ģ•Šź³  ķ¬ź“„ ė™ģ˜ė„¼ ė°›ėŠ” 경우","사딀 2 : ėŖØė°”ģ¼ ģ•±ģ—ģ„œ ꓑ고성 정볓전솔(앱 ķ‘øģ‹œ)에 ėŒ€ķ•˜ģ—¬ ź±°ė¶€ ģ˜ģ‚¬ė„¼ ė°ķ˜”ģœ¼ė‚˜, ķ”„ė”œź·øėžØ 오넘 ė“±ģ˜ ģ“ģœ ė”œ ꓑ고성 앱 ķ‘øģ‹œź°€ ģ“ė£Øģ–“ģ§€ėŠ” 경우","사딀 3 : ģ˜Øė¼ģø ķšŒģ›ź°€ģž… ķ™”ė©“ģ—ģ„œ ė¬øģž, ģ“ė©”ģ¼ģ— ģ˜ķ•œ ꓑ고성 정볓 전솔에 ėŒ€ķ•˜ģ—¬ ė””ķ“ķŠøė”œ ģ²“ķ¬ė˜ģ–“ ģžˆėŠ” 경우","사딀 4 : ꓑ고성 정볓 ģˆ˜ģ‹ ė™ģ˜ 여부에 ėŒ€ķ•˜ģ—¬ 2ė…„ė§ˆė‹¤ ķ™•ģøķ•˜ģ§€ ģ•Šģ€ 경우","사딀 5 : ģ˜ė¦¬ėŖ©ģ ģ˜ ꓑ고성 정볓넼 ģ „ģžģš°ķŽøģœ¼ė”œ ģ „ģ†”ķ•˜ė©“ģ„œ ģ œėŖ©ģ“ ģ‹œģž‘ė˜ėŠ” 부분에 Ź»(ź“‘ź³ )ʼ ķ‘œģ‹œė„¼ ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제22ģ”°(ė™ģ˜ė„¼ ė°›ėŠ” 방법)","ģ •ė³“ķ†µģ‹ ė§ė²• 제50ģ”°(ꓑ고성 정볓 전솔 ģ œķ•œ)"]}],"description": "ģž¬ķ™”ė‚˜ ģ„œė¹„ģŠ¤ģ˜ ķ™ė³“, 판매 권유, ꓑ고성 정볓전솔 등 ė§ˆģ¼€ķŒ… 목적으딜 ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ ė°ģ“ģš©ķ•˜ėŠ” 경우 ź·ø ėŖ©ģ ģ„ 정볓주첓가 ėŖ…ķ™•ķ•˜ź²Œ ģøģ§€ķ•  수 ģžˆė„ė” ź³ ģ§€ķ•˜ź³  ė™ģ˜ė„¼ 받아야 ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.2.1": {"name": "ź°œģøģ •ė³“ ķ˜„ķ™©ź“€ė¦¬","checks": {"macie_is_enabled": "PASS","s3_bucket_lifecycle_enabled": "FAIL"},"status": "FAIL","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.2.1 ź°œģøģ •ė³“ ķ˜„ķ™©ź“€ė¦¬","Subdomain": "3.2. ź°œģøģ •ė³“ 볓유 ė° ģ“ģš© ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ ķ˜„ķ™©ķ‘œ","ź°œģøģ •ė³“ ķė¦„ķ‘œĀ·ķė¦„ė„","ź°œģøģ •ė³“ķŒŒģ¼ ė“±ė” ķ˜„ķ™©","ź°œģøģ •ė³“ķŒŒģ¼ ź“€ė¦¬ėŒ€ģž„","ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź“€ķ•œ ģ‚¬ķ•­ģ„ źø°ė”ķ•œ ź°œģøģ •ė³“ķŒŒģ¼","ļ½¢ģ”°ģ„øė²”ģ²˜ė²Œė²•ļ½£ģ— 따넸 ė²”ģ¹™ķ–‰ģœ„ 씰사 ė° 「꓀세법」에 따넸 ė²”ģ¹™ķ–‰ģœ„ 씰사에 ź“€ķ•œ ģ‚¬ķ•­ģ„ źø°ė”ķ•œ ź°œģøģ •ė³“ķŒŒģ¼","ģ¼ķšŒģ„±ģœ¼ė”œ ģš“ģ˜ė˜ėŠ” ķŒŒģ¼ 등 ģ§€ģ†ģ ģœ¼ė”œ ꓀리할 ķ•„ģš”ź°€ 낮다고 ģøģ •ė˜ģ–“ ėŒ€ķ†µė ¹ė ¹ģœ¼ė”œ ģ •ķ•˜ėŠ” ź°œģøģ •ė³“ķŒŒģ¼","ķšŒģ˜ ģ°øģ„ ģˆ˜ė‹¹ 지급, ģžė£ŒĀ·ė¬¼ķ’ˆģ˜ 솔부, źøˆģ „ģ˜ ģ •ģ‚° 등 ė‹Øģˆœ 업묓 ģˆ˜ķ–‰ģ„ ģœ„ķ•“ ģš“ģ˜ė˜ėŠ” ź°œģøģ •ė³“ķŒŒģ¼ė”œģ„œ ģ§€ģ†ģ  ꓀리 ķ•„ģš”ģ„±ģ“ ė‚®ģ€ ź°œģøģ •ė³“ķŒŒģ¼","ź³µģ¤‘ģœ„ģƒ 등 ź³µź³µģ˜ ģ•ˆģ „ź³¼ ģ•ˆė…•ģ„ ģœ„ķ•˜ģ—¬ źø“źø‰ķžˆ ķ•„ģš”ķ•œ ź²½ģš°ė”œģ„œ ģ¼ģ‹œģ ģœ¼ė”œ ģ²˜ė¦¬ė˜ėŠ” ź°œģøģ •ė³“ķŒŒģ¼","ź·ø 밖에 ģ¼ķšŒģ  업묓 ģ²˜ė¦¬ė§Œģ„ ģœ„ķ•“ ģˆ˜ģ§‘ėœ ź°œģøģ •ė³“ķŒŒģ¼ė”œģ„œ ģ €ģž„ė˜ź±°ė‚˜ źø°ė”ė˜ģ§€ ģ•ŠėŠ” ź°œģøģ •ė³“ķŒŒģ¼","다넸 법령에 ė”°ė¼ ė¹„ė°€ė”œ ė¶„ė„˜ėœ ź°œģøģ •ė³“ķŒŒģ¼","źµ­ź°€ģ•ˆģ „ė³“ģž„ź³¼ ź“€ė Øėœ 정볓 ė¶„ģ„ģ„ 목적으딜 ģˆ˜ģ§‘ ė˜ėŠ” 제공 ģš”ģ²­ė˜ėŠ” ź°œģøģ •ė³“ķŒŒģ¼","ģ˜ģƒģ •ė³“ģ²˜ė¦¬źø°źø°ė„¼ ķ†µķ•˜ģ—¬ ģ²˜ė¦¬ė˜ėŠ” ź°œģøģ˜ģƒģ •ė³“ķŒŒģ¼","ļ½¢źøˆģœµģ‹¤ėŖ…ź±°ėž˜ ė° ė¹„ė°€ė³“ģž„ģ— ź“€ķ•œ 법넠」에 따넸 źøˆģœµźø°ź“€ģ“ źøˆģœµģ—…ė¬“ ģ·Øźø‰ģ„ ģœ„ķ•˜ģ—¬ ė³“ģœ ķ•˜ėŠ” ź°œģøģ •ė³“ķŒŒģ¼"],"AuditChecklist": ["ģˆ˜ģ§‘Ā·ė³“ģœ ķ•˜ź³  ģžˆėŠ” ź°œģøģ •ė³“ģ˜ ķ•­ėŖ©, ė³“ģœ ėŸ‰, 처리 목적 ė° 방법, ė³“ģœ źø°ź°„ 등 ķ˜„ķ™©ģ„ ģ •źø°ģ ģœ¼ė”œ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ź³µź³µźø°ź“€ģ“ ź°œģøģ •ė³“ķŒŒģ¼ģ„ ģš“ģš©ķ•˜ź±°ė‚˜ ė³€ź²½ķ•˜ėŠ” 경우 ź“€ė Øėœ ģ‚¬ķ•­ģ„ ė²•ė„ ģ—ģ„œ ģ •ķ•œ ź“€ź³„źø°ź“€ģ˜ ģž„ģ—ź²Œ ė“±ė”ķ•˜ź³  ģžˆėŠ”ź°€?","ź³µź³µźø°ź“€ģ€ ź°œģøģ •ė³“ķŒŒģ¼ģ˜ 볓유 ķ˜„ķ™©ģ„ ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź³µź°œķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ķŒŒģ¼ģ„ ķ™ˆķŽ˜ģ“ģ§€ģ˜ ź°œģøģ •ė³“ķŒŒģ¼ ė“±ė” 메뉓넼 ķ†µķ•˜ģ—¬ ėŖ©ė”ģ„ ź“€ė¦¬ķ•˜ź³  ģžˆģœ¼ė‚˜, ź·ø 중 ģ¼ė¶€ ķ™ˆķŽ˜ģ“ģ§€ ģ„œė¹„ģŠ¤ģ™€ ź“€ė Øėœ ź°œģøģ •ė³“ķŒŒģ¼ģ˜ ė‚“ģš©ģ“ ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ėˆ„ė½ė˜ģ–“ ģžˆėŠ” 경우","사딀 2 : ģ‹ ź·œ ź°œģøģ •ė³“ķŒŒģ¼ģ„ źµ¬ģ¶•ķ•œ ģ§€ 2ź°œģ›”ģ“ ź²½ź³¼ķ•˜ģ˜€ģœ¼ė‚˜, 핓당 ź°œģøģ •ė³“ķŒŒģ¼ģ„ ź°œģøģ •ė³“ ė³“ķ˜øģœ„ģ›ķšŒģ— ė“±ė”ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ź°œģøģ •ė³“ ė³“ķ˜øģœ„ģ›ķšŒģ— ė“±ė”ė˜ģ–“ 공개된 ź°œģøģ •ė³“ķŒŒģ¼ģ˜ ė‚“ģš©(ģˆ˜ģ§‘ķ•˜ėŠ” ź°œģøģ •ė³“ģ˜ ķ•­ėŖ© 등)ģ“ ģ‹¤ģ œ ģ²˜ė¦¬ķ•˜ź³  ģžˆėŠ” ź°œģøģ •ė³“ķŒŒģ¼ ķ˜„ķ™©ź³¼ ģƒģ“ķ•œ 경우","사딀 4 : ź³µź³µźø°ź“€ģ“ ģž„ģ§ģ›ģ˜ ź°œģøģ •ė³“ķŒŒģ¼, 통계법에 ė”°ė¼ ģˆ˜ģ§‘ė˜ėŠ” ź°œģøģ •ė³“ķŒŒģ¼ģ— ėŒ€ķ•“ ź°œģøģ •ė³“ķŒŒģ¼ ė“±ė” ģ˜ˆģ™øģ‚¬ķ•­ģ— ķ•“ė‹¹ė˜ģ§€ ģ•ŠģŒģ—ė„ ė¶ˆźµ¬ķ•˜ź³  핓당 ź°œģøģ •ė³“ķŒŒģ¼ģ„ ź°œģøģ •ė³“ ė³“ķ˜øģœ„ģ›ķšŒģ— ė“±ė”ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제32ģ”°(ź°œģøģ •ė³“ķŒŒģ¼ģ˜ ė“±ė” ė° 공개)"]}],"description": "ģˆ˜ģ§‘Ā·ė³“ģœ ķ•˜ėŠ” ź°œģøģ •ė³“ģ˜ ķ•­ėŖ©, ė³“ģœ ėŸ‰, 처리 목적 ė° 방법, ė³“ģœ źø°ź°„ 등 ķ˜„ķ™©ģ„ ģ •źø°ģ ģœ¼ė”œ ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•˜ė©°, ź³µź³µźø°ź“€ģ˜ 경우 ģ“ė„¼ ė²•ė„ ģ—ģ„œ ģ •ķ•œ ź“€ź³„źø°ź“€ģ˜ ģž„ģ—ź²Œ ė“±ė”ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 1,"pass": 1,"total": 2,"manual": 0}},"3.2.2": {"name": "ź°œģøģ •ė³“ ķ’ˆģ§ˆė³“ģž„","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.2.2 ź°œģøģ •ė³“ ķ’ˆģ§ˆė³“ģž„","Subdomain": "3.2. ź°œģøģ •ė³“ 볓유 ė° ģ“ģš© ģ‹œ 볓호씰치","AuditEvidence": ["정볓주첓 ź°œģøģ •ė³“ ģˆ˜ģ •Ā·ė³€ź²½ ģ–‘ģ‹(ģ˜Øė¼ģø, ģ˜¤ķ”„ė¼ģø)","ź°œģøģ •ė³“ ģµœģ‹ ģ„± ģœ ģ§€ 절차"],"AuditChecklist": ["ź°œģøģ •ė³“ė„¼ ģµœģ‹ ģ˜ 상태딜 ģ •ķ™•ķ•˜ź²Œ ģœ ģ§€ķ•˜źø° ģœ„ķ•œ 절차 ė° ė°©ģ•ˆģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ ģžˆėŠ”ź°€?","정볓주첓가 ė³øģøģ˜ ź°œģøģ •ė³“ģ— ėŒ€ķ•˜ģ—¬ 정확성, 완전성 ė° ģµœģ‹ ģ„±ģ„ ģœ ģ§€ķ•  수 ģžˆėŠ” ė°©ė²•ģ„ ģ œź³µķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ė„¼ ķ†µķ•˜ģ—¬ ķšŒģ›ģ •ė³“ė„¼ 변경할 ė•ŒėŠ” ė³øģøķ™•ģø 절차넼 거치고 ģžˆģœ¼ė‚˜, ź³ ź°ģ„¼ķ„° ģƒė‹“ģ›ź³¼ģ˜ 통화넼 ķ†µķ•œ ķšŒģ› 정볓 변경 ģ‹œģ—ėŠ” ė³øģøķ™•ģø ģ ˆģ°Øź°€ ėÆøķ”ķ•˜ģ—¬ ķšŒģ›ģ •ė³“ģ˜ ė¶ˆė²•ģ ģø ė³€ź²½ģ“ ź°€ėŠ„ķ•œ 경우","사딀 2 : ģ˜Øė¼ģø ķšŒģ›ģ— ėŒ€ķ•“ģ„œėŠ” ź°œģøģ •ė³“ė„¼ 변경할 수 ģžˆėŠ” ė°©ė²•ģ„ ģ œź³µķ•˜ź³  ģžˆģœ¼ė‚˜, ģ˜¤ķ”„ė¼ģø ķšŒģ›ģ— ėŒ€ķ•“ģ„œėŠ” ź°œģøģ •ė³“ė„¼ 변경할 수 ģžˆėŠ” ė°©ė²•ģ„ ģ œź³µķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제3ģ”°(ź°œģøģ •ė³“ 볓호 원칙)"]}],"description": "ģˆ˜ģ§‘ėœ ź°œģøģ •ė³“ėŠ” 처리 목적에 ķ•„ģš”ķ•œ ė²”ģœ„ģ—ģ„œ ź°œģøģ •ė³“ģ˜ ģ •ķ™•ģ„±Ā·ģ™„ģ „ģ„±Ā·ģµœģ‹ ģ„±ģ“ ė³“ģž„ė˜ė„ė” ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ź“€ė¦¬ģ ˆģ°Øė„¼ ģ œź³µķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.2.3": {"name": "ģ“ģš©ģž 단말기 ģ ‘ź·¼ 볓호","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.2.3 ģ“ģš©ģž 단말기 ģ ‘ź·¼ 볓호","Subdomain": "3.2. ź°œģøģ •ė³“ 볓유 ė° ģ“ģš© ģ‹œ 볓호씰치","AuditEvidence": ["앱 ģ ‘ź·¼ź¶Œķ•œ ė™ģ˜ 화멓","앱 ģ ‘ź·¼ź¶Œķ•œ 설정 ķ˜„ķ™©"],"AuditChecklist": ["정볓주첓(ģ“ģš©ģž)ģ˜ ģ“ė™ķ†µģ‹ ė‹Øė§ģž„ģ¹˜ 낓에 ģ €ģž„ė˜ģ–“ ģžˆėŠ” 정볓 ė° ģ“ė™ķ†µģ‹ ė‹Øė§ģž„ģ¹˜ģ— ģ„¤ģ¹˜ėœ źø°ėŠ„ģ— ėŒ€ķ•˜ģ—¬ 접근할 수 ģžˆėŠ” ź¶Œķ•œģ“ ķ•„ģš”ķ•œ 경우 ėŖ…ķ™•ķ•˜ź²Œ ģøģ§€ķ•  수 ģžˆė„ė” ģ•Œė¦¬ź³  정볓주첓(ģ“ģš©ģž)ģ˜ ė™ģ˜ė„¼ 받고 ģžˆėŠ”ź°€?","ģ“ė™ķ†µģ‹ ė‹Øė§ģž„ģ¹˜ ė‚“ģ—ģ„œ 핓당 ģ„œė¹„ģŠ¤ė„¼ ģ œź³µķ•˜źø° ģœ„ķ•˜ģ—¬ ė°˜ė“œģ‹œ ķ•„ģš”ķ•œ ģ ‘ź·¼ź¶Œķ•œģ“ ģ•„ė‹Œ 경우, 정볓주첓(ģ“ģš©ģž)ź°€ ė™ģ˜ķ•˜ģ§€ ģ•Šģ•„ė„ ģ„œė¹„ģŠ¤ ģ œź³µģ„ ź±°ė¶€ķ•˜ģ§€ ģ•Šė„ė” ķ•˜ź³  ģžˆėŠ”ź°€?","ģ“ė™ķ†µģ‹ ė‹Øė§ģž„ģ¹˜ ė‚“ģ—ģ„œ 핓당 ģ ‘ź·¼ź¶Œķ•œģ— ėŒ€ķ•œ 정볓주첓(ģ“ģš©ģž)ģ˜ ė™ģ˜ ė° ģ² ķšŒė°©ė²•ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģŠ¤ė§ˆķŠøķ° ģ•±ģ—ģ„œ ģ„œė¹„ģŠ¤ģ— ė¶ˆķ•„ģš”ķ•Øģ—ė„ ė¶ˆźµ¬ķ•˜ź³  ģ£¼ģ†Œė”, 사진, ė¬øģž 등 ģŠ¤ė§ˆķŠøķ° ė‚“ ź°œģøģ •ė³“ ģ˜ģ—­ģ— 접근할 수 ģžˆėŠ” ź¶Œķ•œģ„ ź³¼ė„ķ•˜ź²Œ ģ„¤ģ •ķ•œ 경우","사딀 2 : ģ •ė³“ķ†µģ‹ ģ„œė¹„ģŠ¤ ģ œź³µģžģ˜ ģŠ¤ė§ˆķŠøķ° ģ•±ģ—ģ„œ ģŠ¤ė§ˆķŠøķ° 낓에 ģ €ģž„ė˜ģ–“ ģžˆėŠ” 정볓 ė° ģ„¤ģ¹˜ėœ źø°ėŠ„ģ— ģ ‘ź·¼ķ•˜ė©“ģ„œ ģ ‘ź·¼ź¶Œķ•œģ— ėŒ€ķ•œ ź³ ģ§€ ė° ė™ģ˜ė„¼ 받지 ģ•Šź³  ģžˆėŠ” 경우","사딀 3 : ģŠ¤ė§ˆķŠøķ° ģ•±ģ˜ ģ ‘ź·¼ź¶Œķ•œģ— ėŒ€ķ•œ ė™ģ˜ė„¼ ė°›ģœ¼ė©“ģ„œ ģ„ ķƒģ‚¬ķ•­ģ— ķ•“ė‹¹ķ•˜ėŠ” ź¶Œķ•œģ„ ķ•„ģˆ˜ź¶Œķ•œģœ¼ė”œ ź³ ģ§€ķ•˜ģ—¬ ė™ģ˜ė„¼ ė°›ėŠ” 경우","사딀 4 : ģ ‘ź·¼ź¶Œķ•œģ— ėŒ€ķ•œ ź°œė³„ė™ģ˜ź°€ ė¶ˆź°€ėŠ„ķ•œ ģ•ˆė“œė”œģ“ė“œ 6.0 미만 ė²„ģ „ģ„ ģ§€ģ›ķ•˜ėŠ” ģŠ¤ė§ˆķŠøķ° ģ•±ģ„ ė°°ķ¬ķ•˜ė©“ģ„œ ģ„ ķƒģ  ģ ‘ź·¼ź¶Œķ•œģ„ ķ•Øź»˜ ģ„¤ģ •ķ•˜ģ—¬, ģ„ ķƒģ  ģ ‘ź·¼ź¶Œķ•œģ— ėŒ€ķ•˜ģ—¬ 거부할 수 ģ—†ė„ė” ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ģ •ė³“ķ†µģ‹ ė§ė²• 제22ģ”°ģ˜2(ģ ‘ź·¼ź¶Œķ•œģ— ėŒ€ķ•œ ė™ģ˜)"]}],"description": "정볓주첓(ģ“ģš©ģž)ģ˜ ģ“ė™ķ†µģ‹ ė‹Øė§ģž„ģ¹˜ 낓에 ģ €ģž„ė˜ģ–“ ģžˆėŠ” 정볓 ė° ģ“ė™ķ†µģ‹ ė‹Øė§ģž„ģ¹˜ģ— ģ„¤ģ¹˜ėœ źø°ėŠ„ģ— ģ ‘ź·¼ģ“ ķ•„ģš”ķ•œ 경우 ģ“ė„¼ ėŖ…ķ™•ķ•˜ź²Œ ģøģ§€ķ•  수 ģžˆė„ė” ģ•Œė¦¬ź³  정볓주첓(ģ“ģš©ģž)ģ˜ ė™ģ˜ė„¼ 받아야 ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.2.4": {"name": "ź°œģøģ •ė³“ 목적 외 ģ“ģš© ė° 제공","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.2.4 ź°œģøģ •ė³“ 목적 외 ģ“ģš© ė° 제공","Subdomain": "3.2. ź°œģøģ •ė³“ 볓유 ė° ģ“ģš© ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ 목적 외 ģ“ģš© ė° 제3ģž 제공 ė‚“ģ—­(ģš”ģ²­ģ„œ 등 ꓀련 ģ¦ź±°ģžė£Œ ķ¬ķ•Ø)","ź°œģøģ •ė³“ 목적 외 ģ“ģš© ė° 제3ģž 제공 ėŒ€ģž„(ź³µź³µźø°ź“€ģø 경우)","ķ™ˆķŽ˜ģ“ģ§€ ė˜ėŠ” ꓀볓 ź²Œģž¬ ė‚“ģ—­(ź³µź³µźø°ź“€ģø 경우)","ģžė£Œ 제공 ģš”ģ²­ ėŒ€ģ‘ 지침","ģžė£Œ 제공 ģš”ģ²­ 공문 ė° ź°œģøģ •ė³“ ģ œź³µė‚“ģ—­, ėŒ€ģž„ 등"],"AuditChecklist": ["ź°œģøģ •ė³“ėŠ” 최쓈 ģˆ˜ģ§‘ ģ‹œ ģ •ė³“ģ£¼ģ²“ė”œė¶€ķ„° ė™ģ˜ė°›ģ€ 목적 ė˜ėŠ” 법령에 ź·¼ź±°ķ•œ ė²”ģœ„ ė‚“ģ—ģ„œė§Œ ģ“ģš©Ā·ģ œź³µķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ģ²˜ė¦¬ģžė”œė¶€ķ„° ź°œģøģ •ė³“ė„¼ ģ œź³µė°›ģ€ 경우 ģ œź³µė°›ģ€ ėŖ©ģ ģ˜ ė²”ģœ„ ė‚“ģ—ģ„œė§Œ ģ“ģš©Ā·ģ œź³µķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ ģˆ˜ģ§‘ 목적 ė˜ėŠ” ź°œģøģ •ė³“ģ²˜ė¦¬ģžė”œė¶€ķ„° ģ œź³µė°›ģ€ ėŖ©ģ ģ˜ ė²”ģœ„ė„¼ ģ“ˆź³¼ķ•˜ģ—¬ ģ“ģš©ķ•˜ź±°ė‚˜ ģ œź³µķ•˜ėŠ” 경우 ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ė³„ė„ģ˜ ė™ģ˜ė„¼ ė°›ź±°ė‚˜ 법적 근거가 ģžˆėŠ” 경우딜 ģ œķ•œķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ 목적 ģ™øģ˜ ģš©ė„ė”œ 제3ģžģ—ź²Œ ģ œź³µķ•˜ėŠ” 경우 ģ œź³µė°›ėŠ” ģžģ—ź²Œ ģ“ģš©ėŖ©ģ  ė° 방법 ė“±ģ„ ģ œķ•œķ•˜ź±°ė‚˜ ģ•ˆģ „ģ„± 확볓넼 ģœ„ķ•˜ģ—¬ ķ•„ģš”ķ•œ 씰치넼 ė§ˆė Øķ•˜ė„ė” ģš”ģ²­ķ•˜ź³  ģžˆėŠ”ź°€?","ź³µź³µźø°ź“€ģ“ ź°œģøģ •ė³“ė„¼ 목적 ģ™øģ˜ ģš©ė„ė”œ ģ“ģš©ķ•˜ź±°ė‚˜ 제3ģžģ—ź²Œ ģ œź³µķ•˜ėŠ” 경우 ź·ø ģ“ģš© ė˜ėŠ” ģ œź³µģ˜ 법적 근거, 목적 ė° ė²”ģœ„ 등에 ź“€ķ•˜ģ—¬ ķ•„ģš”ķ•œ ģ‚¬ķ•­ģ„ ꓀볓 ė˜ėŠ” ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ 등에 ź²Œģž¬ķ•˜ź³  ģžˆėŠ”ź°€?","공공기꓀ ė“±ģ“ ź°œģøģ •ė³“ė„¼ 목적 ģ™øģ˜ ģš©ė„ė”œ ģ“ģš©ķ•˜ź±°ė‚˜ 제3ģžģ—ź²Œ ģ œź³µķ•˜ėŠ” 경우 목적 외 ģ“ģš© ė° 제3ģž ģ œź³µėŒ€ģž„ģ— źø°ė”Ā·ź“€ė¦¬ķ•˜ėŠ” 등 절차넼 ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģƒķ’ˆė°°ģ†”ģ„ 목적으딜 ģˆ˜ģ§‘ķ•œ ź°œģøģ •ė³“ė„¼ 사전에 ė™ģ˜ 받지 ģ•Šģ€ ģžģ‚¬ ģƒķ’ˆģ˜ ķ†µģ‹ ķŒė§¤ ꓑ고에 ģ“ģš©ķ•œ 경우","사딀 2 : ź³ ź° ė§Œģ”±ė„ 씰사, ź²½ķ’ˆ 행사에 ģ‘ėŖØķ•˜źø° ģœ„ķ•˜ģ—¬ ģˆ˜ģ§‘ķ•œ ź°œģøģ •ė³“ė„¼ ģžģ‚¬ģ˜ ķ• ģøķŒė§¤ķ–‰ģ‚¬ ģ•ˆė‚“ģš© ź“‘ź³  ė°œģ†”ģ— ģ“ģš©ķ•œ 경우","사딀 3 : ź³µź³µźø°ź“€ģ“ 다넸 법넠에 ź·¼ź±°ķ•˜ģ—¬ ėÆ¼ģ›ģøģ˜ ź°œģøģ •ė³“ė„¼ 목적 ģ™øė”œ ķƒ€ 기꓀에 ģ œź³µķ•˜ė©“ģ„œ ꓀련 ģ‚¬ķ•­ģ„ ꓀볓 ė˜ėŠ” ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ģ— ź²Œģ‹œķ•˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ź³µź³µźø°ź“€ģ“ 범죄 ģˆ˜ģ‚¬ģ˜ 목적으딜 ź²½ģ°°ģ„œģ— ź°œģøģ •ė³“ė„¼ ģ œź³µķ•˜ė©“ģ„œ Ź»ź°œģøģ •ė³“ 목적 외 ģ“ģš© ė° 제3ģž 제공 ėŒ€ģž„Ź¼ģ— ꓀련 ģ‚¬ķ•­ģ„ źø°ė”ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제18ģ”°(ź°œģøģ •ė³“ģ˜ 목적 외 ģ“ģš©Ā·ģ œź³µ ģ œķ•œ), 제19ģ”°(ź°œģøģ •ė³“ė„¼ ģ œź³µė°›ģ€ ģžģ˜ ģ“ģš©Ā·ģ œź³µ ģ œķ•œ)"]}],"description": "ź°œģøģ •ė³“ėŠ” ģˆ˜ģ§‘ ģ‹œģ˜ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ź³ ģ§€Ā·ė™ģ˜ė„¼ ė°›ģ€ 목적 ė˜ėŠ” 법령에 ź·¼ź±°ķ•œ ė²”ģœ„ ė‚“ģ—ģ„œė§Œ ģ“ģš© ė˜ėŠ” ģ œź³µķ•˜ģ—¬ģ•¼ ķ•˜ė©°, ģ“ė„¼ ģ“ˆź³¼ķ•˜ģ—¬ ģ“ģš©Ā·ģ œź³µķ•˜ė ¤ėŠ” ė•Œģ—ėŠ” ģ •ė³“ģ£¼ģ²“ģ˜ 추가 ė™ģ˜ė„¼ ė°›ź±°ė‚˜ ꓀계 법령에 따넸 ģ ė²•ķ•œ ź²½ģš°ģøģ§€ ķ™•ģøķ•˜ź³  ģ ģ ˆķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.2.5": {"name": "가명정볓 처리","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.2.5 가명정볓 처리","Subdomain": "3.2. ź°œģøģ •ė³“ 볓유 ė° ģ“ģš© ģ‹œ 볓호씰치","AuditEvidence": ["ź°€ėŖ…ģ²˜ė¦¬Ā·ģµėŖ…ģ²˜ė¦¬ 적정성 ķ‰ź°€ 절차 ė° ź²°ź³¼","가명정볓 처리 źø°ė”","ź°œģøģ •ė³“ 처리방침(가명정볓 ģ“ģš©Ā·ģ œź³µģ— ź“€ķ•œ 사항) 등"],"AuditChecklist": ["가명정볓넼 ģ²˜ė¦¬ķ•˜ėŠ” 경우 목적 ģ œķ•œ, ź°€ėŖ…ģ²˜ė¦¬ 방법 ė° 기준, 적정성 검토, ģž¬ģ‹ė³„ źøˆģ§€ ė° ģž¬ģ‹ė³„ ė°œģƒ ģ‹œ ģ”°ģ¹˜ģ‚¬ķ•­ 등 가명정볓넼 ģ ģ •ķ•˜ź²Œ ģ²˜ė¦¬ķ•˜źø° ģœ„ķ•œ 절차넼 ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ ź°€ėŖ…ģ²˜ė¦¬ķ•˜ģ—¬ ģ“ģš©Ā·ģ œź³µ ģ‹œ 추가 ģ •ė³“ģ˜ ģ‚¬ģš©Ā·ź²°ķ•© ģ—†ģ“ėŠ” ź°œģøģ„ ģ•Œģ•„ė³¼ 수 ģ—†ė„ė” ģ ģ •ķ•œ ģˆ˜ģ¤€ģœ¼ė”œ ź°€ėŖ…ģ²˜ė¦¬ė„¼ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","다넸 ź°œģøģ •ė³“ģ²˜ė¦¬ģžģ™€ 가명정볓넼 ź²°ķ•©ķ•˜ėŠ” 경우 결합전문기꓀ ė˜ėŠ” ė°ģ“ķ„°ģ „ė¬øźø°ź“€ģ„ 통핓 ź²°ķ•©ķ•˜ź³  ģžˆėŠ”ź°€?","가명정볓넼 ģ²˜ė¦¬ķ•˜ėŠ” 경우 추가 정볓넼 ģ‚­ģ œ ė˜ėŠ” ė³„ė„ė”œ ė¶„ė¦¬ķ•˜ģ—¬ 볓꓀·꓀리, ꓀련 źø°ė”ģ˜ ģž‘ģ„±Ā·ė³“ź“€ 등 ģ•ˆģ „ģ„± 확볓에 ķ•„ģš”ķ•œ źø°ģˆ ģ Ā·ź“€ė¦¬ģ  ė° 물리적 씰치넼 ķ•˜ź³  ģžˆėŠ”ź°€?","가명정볓 처리목적 ė“±ģ„ ź³ ė ¤ķ•˜ģ—¬ ź°€ėŖ…ģ •ė³“ģ˜ 처리 źø°ź°„ģ„ ģ ģ •ķ•œ źø°ź°„ģœ¼ė”œ ģ •ķ•˜ź³  ģžˆģœ¼ė©°, 핓당 źø°ź°„ģ“ ź²½ź³¼ķ•œ 경우 지첓 ģ—†ģ“ ķŒŒźø°ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ ģµėŖ…ģ²˜ė¦¬ķ•˜ėŠ” 경우 ģ‹œź°„Ā·ė¹„ģš©Ā·źø°ģˆ  ė“±ģ„ ķ•©ė¦¬ģ ģœ¼ė”œ 고려할 ė•Œ 다넸 정볓넼 ģ‚¬ģš©ķ•˜ģ—¬ė„ ė” ģ“ģƒ ķŠ¹ģ • ź°œģøģ„ ģ•Œģ•„ė³¼ 수 ģ—†ė„ė” ģ ģ •ķ•œ ģˆ˜ģ¤€ģœ¼ė”œ ģµėŖ…ģ²˜ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķ†µź³„ģž‘ģ„± ė° 과학적 연구넼 ģœ„ķ•˜ģ—¬ 정볓주첓 ė™ģ˜ ģ—†ģ“ 가명정볓넼 ģ²˜ė¦¬ķ•˜ė©“ģ„œ 가명정볓 ģ²˜ė¦¬ģ— ź“€ķ•œ źø°ė”ģ„ 남기고 ģžˆģ§€ ģ•Šź±°ė‚˜, ė˜ėŠ” ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ꓀련 ģ‚¬ķ•­ģ„ ź³µź°œķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : 가명정볓와 ė™ģ¼ķ•œ ė°ģ“ķ„°ė² ģ“ģŠ¤ 낓에 추가 정볓넼 ė¶„ė¦¬ķ•˜ģ§€ ģ•Šź³  ė³“ź“€ķ•˜ź³  ģžˆź±°ė‚˜, ė˜ėŠ” 가명 정볓와 추가 정볓에 ėŒ€ķ•œ ģ ‘ź·¼ź¶Œķ•œģ“ ģ ģ ˆķžˆ ė¶„ė¦¬ė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ź°œģøģ •ė³“ė„¼ ź°€ėŖ…ģ²˜ė¦¬ķ•˜ģ—¬ ķ™œģš©ķ•˜ź³  ģžˆģœ¼ė‚˜ ģ ģ •ķ•œ ģˆ˜ģ¤€ģ˜ ź°€ėŖ…ģ²˜ė¦¬ź°€ ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ•„ 추가 ģ •ė³“ģ˜ ģ‚¬ģš© ģ—†ģ“ė„ 다넸 ģ •ė³“ģ™€ģ˜ ź²°ķ•© ė“±ģ„ ķ†µķ•˜ģ—¬ ķŠ¹ģ • ź°œģøģ„ ģ•Œģ•„ė³¼ 수 ģžˆėŠ” ź°€ėŠ„ģ„±ģ“ ģ”“ģž¬ķ•˜ėŠ” 경우","사딀 4 : ķ…ŒģŠ¤ķŠø ė°ģ“ķ„° ģƒģ„±, 외부 공개 ė“±ģ„ ģœ„ķ•˜ģ—¬ ź°œģøģ •ė³“ė„¼ ģµėŖ…ģ²˜ė¦¬ķ•˜ģ˜€ģœ¼ė‚˜, ķŠ¹ģ“ģ¹˜ ė“±ģœ¼ė”œ ģøķ•˜ģ—¬ ķŠ¹ģ • ź°œģøģ— ėŒ€ķ•œ ģ‹ė³„ź°€ėŠ„ģ„±ģ“ ģ”“ģž¬ķ•˜ėŠ” 등 ģµėŖ…ģ²˜ė¦¬ź°€ ģ ģ •ķ•˜ź²Œ ģˆ˜ķ–‰ė˜ģ—ˆė‹¤ź³  볓기 ģ–“ė ¤ģš“ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제2ģ”°(ģ •ģ˜), 제28ģ”°ģ˜2(ź°€ėŖ…ģ •ė³“ģ˜ 처리 등), 제28ģ”°ģ˜3(ź°€ėŖ…ģ •ė³“ģ˜ ź²°ķ•© ģ œķ•œ), 제28ģ”°ģ˜4(가명정볓에 ėŒ€ķ•œ ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“ 등), 제28ģ”°ģ˜5(가명정볓 처리 ģ‹œ źøˆģ§€ģ˜ė¬“ 등), 제28ģ”°ģ˜7(ģ ģš©ė²”ģœ„), 제58ģ”°ģ˜2(ģ ģš©ģ œģ™ø)"]}],"description": "가명정볓넼 ģ²˜ė¦¬ķ•˜ėŠ” 경우 ėŖ©ģ ģ œķ•œ, ź²°ķ•©ģ œķ•œ, ģ•ˆģ „ģ”°ģ¹˜, źøˆģ§€ģ˜ė¬“ 등 법적 ģš”ź±“ģ„ ģ¤€ģˆ˜ķ•˜ź³  적정 ģˆ˜ģ¤€ģ˜ ź°€ėŖ…ģ²˜ė¦¬ė„¼ ė³“ģž„ķ•  수 ģžˆė„ė” ź°€ėŖ…ģ²˜ė¦¬ 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.3.1": {"name": "ź°œģøģ •ė³“ 제3ģž 제공","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.3.1 ź°œģøģ •ė³“ 제3ģž 제공","Subdomain": "3.3. ź°œģøģ •ė³“ 제공 ģ‹œ 볓호씰치","AuditEvidence": ["ģ˜Øė¼ģø ź°œģøģ •ė³“ 제3ģž 제공 ꓀련 ģ–‘ģ‹(ķ™ˆķŽ˜ģ“ģ§€ ķšŒģ›ź°€ģž… 화멓, ź°œģøģ •ė³“ 제3ģž 제공 ė™ģ˜ 화멓 등)","ģ˜¤ķ”„ė¼ģø ź°œģøģ •ė³“ 제3ģž 제공 ꓀련 ģ–‘ģ‹(ķšŒģ›ź°€ģž…ģ‹ ģ²­ģ„œ, ź°œģøģ •ė³“ 제3ģž 제공 ė™ģ˜ģ„œ 등)","제3ģž 제공 ė‚“ģ—­","ź°œģøģ •ė³“ 처리방침"],"AuditChecklist": ["ź°œģøģ •ė³“ė„¼ 제3ģžģ—ź²Œ ģ œź³µķ•˜ėŠ” 경우 정볓주첓 ė™ģ˜, ė²•ė ¹ģƒ ģ˜ė¬“ģ¤€ģˆ˜ 등 적법 ģš”ź±“ģ„ ėŖ…ķ™•ķžˆ ģ‹ė³„ķ•˜ź³  ģ“ė„¼ ģ¤€ģˆ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ź°œģøģ •ė³“ 제3ģž 제공 ė™ģ˜ė„¼ ė°›ėŠ” 경우 ꓀련 ģ‚¬ķ•­ģ„ ėŖ…ķ™•ķ•˜ź²Œ ź³ ģ§€ķ•˜ź³  다넸 ė™ģ˜ģ‚¬ķ•­ź³¼ źµ¬ė¶„ķ•˜ģ—¬ ģ ė²•ķ•˜ź²Œ ė™ģ˜ė„¼ 받고 ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ź°œģøģ •ė³“ 제3ģž 제공 ė™ģ˜ė„¼ ė°›ėŠ” 경우 ꓀련 ė‚“ģš©ģ„ ėŖ…ķ™•ķ•˜ź²Œ ź³ ģ§€ķ•˜ź³  ė²•ė ¹ģ—ģ„œ ģ •ķ•œ ģ¤‘ģš”ķ•œ ė‚“ģš©ģ— ėŒ€ķ•“ ėŖ…ķ™•ķžˆ ķ‘œģ‹œķ•˜ģ—¬ ģ•Œģ•„ė³“źø° ģ‰½ź²Œ ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ 제3ģžģ—ź²Œ ģ œź³µķ•˜ėŠ” 경우 제공 목적에 ė§žėŠ” ģµœģ†Œķ•œģ˜ ź°œģøģ •ė³“ ķ•­ėŖ©ģœ¼ė”œ ģ œķ•œķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ 제3ģžģ—ź²Œ ģ œź³µķ•˜ėŠ” 경우 ģ•ˆģ „ķ•œ ģ ˆģ°Øģ™€ ė°©ė²•ģ„ 통핓 ģ œź³µķ•˜ź³  제공 ė‚“ģ—­ģ„ źø°ė”ķ•˜ģ—¬ ė³“ź“€ķ•˜ź³  ģžˆėŠ”ź°€?","제3ģžģ—ź²Œ ź°œģøģ •ė³“ģ˜ ģ ‘ź·¼ģ„ ķ—ˆģš©ķ•˜ėŠ” 경우 ź°œģøģ •ė³“ė„¼ ģ•ˆģ „ķ•˜ź²Œ ė³“ķ˜øķ•˜źø° ģœ„ķ•œ ė³“ķ˜øģ ˆģ°Øģ— ė”°ė¼ ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ ģ—†ģ“ ź°œģøģ •ė³“ģ˜ ģ¶”ź°€ģ ģø 제공 ģ‹œ ė‹¹ģ“ˆ ģˆ˜ģ§‘ ėŖ©ģ ź³¼ģ˜ ꓀련성, ģ˜ˆģø”ź°€ėŠ„ģ„±, ģ“ģµ 침핓 여부, ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ ė“±ģ˜ 고려사항에 ėŒ€ķ•œ ķŒė‹Øźø°ģ¤€ģ„ 수립 ė° ģ“ķ–‰ķ•˜ź³ , ģ¶”ź°€ģ ģø ģ œź³µģ“ ģ§€ģ†ģ ģœ¼ė”œ ė°œģƒķ•˜ėŠ” 경우 고려사항에 ėŒ€ķ•œ ķŒė‹Øźø°ģ¤€ģ„ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź³µź°œķ•˜ź³  ģ“ė„¼ ģ ź²€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ģ²˜ė¦¬ģžź°€ ź°œģøģ •ė³“ 제3ģž 제공 ė™ģ˜ė„¼ ė°›ģ„ ė•Œ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ź³ ģ§€ķ•˜ėŠ” 사항 중에 ģ¼ė¶€ 사항(ė™ģ˜ ź±°ė¶€ź¶Œ, ģ œź³µķ•˜ėŠ” ķ•­ėŖ© 등)ģ„ ėˆ„ė½ķ•œ 경우","사딀 2 : ź°œģøģ •ė³“ė„¼ 제3ģžģ—ź²Œ ģ œź³µķ•˜ėŠ” ź³¼ģ •ģ—ģ„œ 제3ģž 제공 ė™ģ˜ 여부넼 ģ ģ ˆķžˆ ķ™•ģøķ•˜ģ§€ ėŖ»ķ•˜ģ—¬ ė™ģ˜ķ•˜ģ§€ ģ•Šģ€ ģ •ė³“ģ£¼ģ²“ģ˜ ź°œģøģ •ė³“ź°€ ķ•Øź»˜ 제공된 경우","사딀 3 : ź°œģøģ •ė³“ė„¼ 제공 ė™ģ˜ė„¼ ė°›ģ„ ė•Œ, ģ œź³µė°›ėŠ” ģžė„¼ ķŠ¹ģ •ķ•˜ģ§€ ģ•Šź³  Ź»~ 등ʼ과 ź°™ģ“ ķ¬ź“„ģ ģœ¼ė”œ ģ•ˆė‚“ķ•˜ź³  ė™ģ˜ė„¼ ė°›ģ€ 경우","사딀 4 : ķšŒģ› ź°€ģž… ė‹Øź³„ģ—ģ„œ ģ„ ķƒģ‚¬ķ•­ģœ¼ė”œ 제3ģž 제공 ė™ģ˜ė„¼ 받고 ģžˆģœ¼ė‚˜, 제3ģž ģ œź³µģ— ė™ģ˜ķ•˜ģ§€ ģ•Šģœ¼ė©“ ķšŒģ› ź°€ģž… ģ ˆģ°Øź°€ ė” ģ“ģƒ ģ§„ķ–‰ė˜ģ§€ ģ•Šė„ė” ė˜ģ–“ ģžˆėŠ” 경우","사딀 5 : ģ œź³µė°›ėŠ” ģžģ˜ ģ“ģš© 목적과 ꓀련 ģ—†ģ“ ģ§€ė‚˜ģ¹˜ź²Œ ė§Žģ€ ź°œģøģ •ė³“ė„¼ ģ œź³µķ•˜ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제17ģ”°(ź°œģøģ •ė³“ģ˜ 제공), 제22ģ”°(ė™ģ˜ė„¼ ė°›ėŠ” 방법)","ź°œģøģ •ė³“ 처리 방법에 ź“€ķ•œ ź³ ģ‹œ"]}],"description": "ź°œģøģ •ė³“ė„¼ 제3ģžģ—ź²Œ ģ œź³µķ•˜ėŠ” 경우 법적 근거에 ģ˜ķ•˜ź±°ė‚˜ ģ •ė³“ģ£¼ģ²“ģ˜ ė™ģ˜ė„¼ 받아야 ķ•˜ė©°, 제3ģžģ—ź²Œ ź°œģøģ •ė³“ģ˜ ģ ‘ź·¼ģ„ ķ—ˆģš©ķ•˜ėŠ” 등 제공 ź³¼ģ •ģ—ģ„œ ź°œģøģ •ė³“ė„¼ ģ•ˆģ „ķ•˜ź²Œ ė³“ķ˜øķ•˜źø° ģœ„ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.3.2": {"name": "ź°œģøģ •ė³“ 처리 업묓 ģœ„ķƒ","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.3.2 ź°œģøģ •ė³“ 처리 업묓 ģœ„ķƒ","Subdomain": "3.3. ź°œģøģ •ė³“ 제공 ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ 처리방침(ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ ģœ„ķƒ ꓀련 공개 ė‚“ģ—­)","ź°œģøģ •ė³“ ģˆ˜ģ§‘ ģ–‘ģ‹","ź°œģøģ •ė³“ 처리 ģœ„ķƒ ź³„ģ•½ģ„œ","ģž¬ķ™” ė˜ėŠ” ģ„œė¹„ģŠ¤ ķ™ė³“Ā·ķŒė§¤ 권유 업묓 ģœ„ķƒ ꓀련 정볓주첓 통지 ė‚“ģ—­"],"AuditChecklist": ["ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ė„¼ 제3ģžģ—ź²Œ ģœ„ķƒ(ģž¬ģœ„ķƒ ķ¬ķ•Ø)ķ•˜ėŠ” 경우 ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ 등에 ģœ„ķƒķ•˜ėŠ” ģ—…ė¬“ģ˜ ė‚“ģš©ź³¼ ģˆ˜ķƒģžė„¼ ķ˜„ķ–‰ķ™”ķ•˜ģ—¬ ź³µź°œķ•˜ź³  ģžˆėŠ”ź°€?","ģž¬ķ™” ė˜ėŠ” ģ„œė¹„ģŠ¤ė„¼ ķ™ė³“ķ•˜ź±°ė‚˜ 판매넼 ź¶Œģœ ķ•˜ėŠ” 업묓넼 ģœ„ķƒķ•˜ėŠ” ź²½ģš°ģ—ėŠ” ģ„œė©“, ģ „ģžģš°ķŽø, ė¬øģžģ „ģ†” ė“±ģ˜ ė°©ė²•ģœ¼ė”œ ģœ„ķƒķ•˜ėŠ” ģ—…ė¬“ģ˜ ė‚“ģš©ź³¼ ģˆ˜ķƒģžė„¼ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķ™ˆķŽ˜ģ“ģ§€ ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ ģœ„ķƒ ģ‚¬ķ•­ģ„ ź³µź°œķ•˜ź³  ģžˆģœ¼ė‚˜, ģ¼ė¶€ ģˆ˜ķƒģžģ™€ ģœ„ķƒķ•˜ėŠ” ģ—…ė¬“ģ˜ ė‚“ģš©ģ“ ėˆ„ė½ėœ 경우","사딀 2 : ģž¬ķ™” ė˜ėŠ” ģ„œė¹„ģŠ¤ė„¼ ķ™ė³“ķ•˜ź±°ė‚˜ 판매넼 ź¶Œģœ ķ•˜ėŠ” 업묓넼 ģœ„ķƒķ•˜ė©“ģ„œ, ģœ„ķƒķ•˜ėŠ” ģ—…ė¬“ģ˜ ė‚“ģš©ź³¼ ģˆ˜ķƒģžė„¼ ģ„œė©“ė“±ģ˜ ė°©ė²•ģœ¼ė”œ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ģ§€ ģ•Šź³  ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź³µź°œķ•˜ėŠ” 것으딜 ź°ˆģŒķ•œ 경우","사딀 3 : 기씓 ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ ģˆ˜ķƒģžģ™€ģ˜ 계약 핓지에 ė”°ė¼ ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ ģˆ˜ķƒģžź°€ ė³€ź²½ė˜ģ—ˆģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•˜ģ—¬ ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— 지첓 ģ—†ģ“ ė°˜ģ˜ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 4 : ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ė„¼ ģœ„ķƒė°›ģ€ ģžź°€ 핓당 업묓넼 제3ģžģ—ź²Œ ģž¬ģœ„ķƒģ„ ķ•˜ź³  ģžˆģ§€ė§Œ, ģž¬ģœ„ķƒģ— ź“€ķ•œ ģ‚¬ķ•­ģ„ ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ 등에 ź³µź°œķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제26ģ”°(ģ—…ė¬“ģœ„ķƒģ— 따넸 ź°œģøģ •ė³“ģ˜ 처리 ģ œķ•œ)"]}],"description": "ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ė„¼ 제3ģžģ—ź²Œ ģœ„ķƒķ•˜ėŠ” 경우 ģœ„ķƒķ•˜ėŠ” ģ—…ė¬“ģ˜ ė‚“ģš©ź³¼ ģˆ˜ķƒģž 등 ź“€ė Øģ‚¬ķ•­ģ„ ź³µź°œķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ė˜ķ•œ ģž¬ķ™” ė˜ėŠ” ģ„œė¹„ģŠ¤ė„¼ ķ™ė³“ķ•˜ź±°ė‚˜ 판매넼 ź¶Œģœ ķ•˜ėŠ” 업묓넼 ģœ„ķƒķ•˜ėŠ” 경우 ģœ„ķƒķ•˜ėŠ” ģ—…ė¬“ģ˜ ė‚“ģš©ź³¼ ģˆ˜ķƒģžė„¼ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė ¤ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.3.3": {"name": "ģ˜ģ—…ģ˜ ģ–‘ė„ 등에 따넸 ź°œģøģ •ė³“ ģ“ģ „","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.3.3 ģ˜ģ—…ģ˜ ģ–‘ė„ 등에 따넸 ź°œģøģ •ė³“ ģ“ģ „","Subdomain": "3.3. ź°œģøģ •ė³“ 제공 ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ ģ“ģ „ ꓀련 정볓주첓 ź³ ģ§€ ė‚“ģ—­(ģ˜ģ—… ģ–‘ģˆ˜ė„ ģ‹œ)","ź°œģøģ •ė³“ 처리방침"],"AuditChecklist": ["ģ˜ģ—…ģ˜ ģ „ė¶€ ė˜ėŠ” ģ¼ė¶€ģ˜ ģ–‘ė„Ā·ķ•©ė³‘ ė“±ģœ¼ė”œ ź°œģøģ •ė³“ė„¼ 다넸 ģ‚¬ėžŒģ—ź²Œ ģ“ģ „ķ•˜ėŠ” 경우 ķ•„ģš”ķ•œ ģ‚¬ķ•­ģ„ 사전에 ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ ģ“ģ „ė°›ėŠ” ģžėŠ” 법적 통지 ģš”ź±“ģ— 핓당될 경우 ź°œģøģ •ė³“ė„¼ ģ“ģ „ė°›ģ€ 사실 등 ķ•„ģš”ķ•œ ģ‚¬ķ•­ģ„ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ 지첓 ģ—†ģ“ ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ ģ“ģ „ė°›ėŠ” ģžėŠ” ģ“ģ „ ė‹¹ģ‹œģ˜ ė³øėž˜ 목적으딜만 ź°œģøģ •ė³“ė„¼ ģ“ģš©ķ•˜ź±°ė‚˜ 제3ģžģ—ź²Œ ģ œź³µķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ģ²˜ė¦¬ģžź°€ ģ˜ģ—… ģ–‘ģˆ˜ė„¼ ķ†µķ•˜ģ—¬ ź°œģøģ •ė³“ė„¼ ģ“ģ „ė°›ģœ¼ė©“ģ„œ ģ–‘ė„ģžź°€ ź°œģøģ •ė³“ ģ“ģ „ ģ‚¬ģ‹¤ģ„ ģ•Œė¦¬ģ§€ ģ•Šģ•˜ģŒģ—ė„ ź°œģøģ •ė³“ ģ“ģ „ ģ‚¬ģ‹¤ģ„ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ģ§€ ģ•Šģ€ 경우","사딀 2 : ģ˜ģ—… ģ–‘ģˆ˜ė„ 등에 ģ˜ķ•˜ģ—¬ ź°œģøģ •ė³“ė„¼ ģ“ģ „ė°›ģœ¼ė©“ģ„œ 정볓주첓가 ģ“ģ „ģ„ ģ›ķ•˜ģ§€ ģ•Šģ€ 경우 ģ”°ģ¹˜ķ•  수 ģžˆėŠ” 방법과 절차넼 ė§ˆė Øķ•˜ģ§€ ģ•Šź±°ė‚˜, ģ“ė„¼ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제27ģ”°(ģ˜ģ—…ģ–‘ė„ 등에 따넸 ź°œģøģ •ė³“ģ˜ ģ“ģ „ ģ œķ•œ)"]}],"description": "ģ˜ģ—…ģ˜ ģ–‘ė„Ā·ķ•©ė³‘ ė“±ģœ¼ė”œ ź°œģøģ •ė³“ė„¼ ģ“ģ „ķ•˜ź±°ė‚˜ ģ“ģ „ė°›ėŠ” 경우 정볓주첓 통지 등 ģ ģ ˆķ•œ 볓호씰치넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.3.4": {"name": "ź°œģøģ •ė³“ źµ­ģ™øģ“ģ „","checks": {"s3_bucket_cross_region_replication": "FAIL"},"status": "FAIL","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.3.4 ź°œģøģ •ė³“ źµ­ģ™øģ“ģ „","Subdomain": "3.3. ź°œģøģ •ė³“ 제공 ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ 국외 ģ“ģ „ ꓀련 ė™ģ˜ ģ–‘ģ‹","ź°œģøģ •ė³“ 국외 ģ“ģ „ ꓀련 ź³„ģ•½ģ„œ","ź°œģøģ •ė³“ 처리방침","ź°œģøģ •ė³“ 국외 ģ²˜ė¦¬ģœ„ķƒĀ·ė³“ź“€ ꓀련 통지 ė˜ėŠ” 공개 ė‚“ģ—­"],"AuditChecklist": ["ź°œģøģ •ė³“ė„¼ źµ­ģ™øė”œ ģ“ģ „ķ•˜ėŠ” 경우 ģ •ė³“ģ£¼ģ²“ģ—ź²Œ 국외 ģ“ģ „ģ— ź“€ķ•œ ź³ ģ§€ ģ‚¬ķ•­ģ„ 모두 ģ•Œė¦¬ź³  ė³„ė„ ė™ģ˜ė„¼ ė°›ź±°ė‚˜, ģøģ¦ ė˜ėŠ” ģøģ • 등 적법 ģš”ź±“ģ„ ģ¤€ģˆ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ™€ģ˜ ź³„ģ•½ģ˜ 첓결 ė° ģ“ķ–‰ģ„ ģœ„ķ•œ ź°œģøģ •ė³“ģ˜ 국외 ģ²˜ė¦¬ģœ„ķƒĀ·ė³“ź“€ģ— ėŒ€ķ•“ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ėŠ” 경우 ķ•„ģš”ķ•œ ģ‚¬ķ•­ģ„ 모두 ķ¬ķ•Øķ•˜ģ—¬ ģ ģ ˆķ•œ ė°©ė²•ģœ¼ė”œ ģ•Œė¦¬ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ 볓호 ꓀련 법령 ģ¤€ģˆ˜ ė° ź°œģøģ •ė³“ 볓호 등에 ź“€ķ•œ ģ‚¬ķ•­ģ„ ķ¬ķ•Øķ•˜ģ—¬ 국외 ģ“ģ „ģ— ź“€ķ•œ ź³„ģ•½ģ„ ģ²“ź²°ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ źµ­ģ™øė”œ ģ“ģ „ķ•˜ėŠ” 경우 ź°œģøģ •ė³“ 볓호넼 ģœ„ķ•˜ģ—¬ ķ•„ģš”ķ•œ 씰치넼 ģ·Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ė„¼ ģ²˜ė¦¬ķ•˜ėŠ” ź³¼ģ •ģ—ģ„œ 국외 ģ‚¬ģ—…ģžģ—ź²Œ ź°œģøģ •ė³“ 제3ģž ģ œź³µģ“ ė°œģƒķ•˜ģ˜€ģœ¼ė‚˜, ģøģ¦, ėŒ€ģƒźµ­ ģøģ • 등 ė™ģ˜ ģ˜ˆģ™ø ģš”ź±“ģ— ķ•“ė‹¹ė˜ģ§€ ģ•ŠģŒģ—ė„ ė¶ˆźµ¬ķ•˜ź³  ź°œģøģ •ė³“ 국외 ģ“ģ „ģ— ėŒ€ķ•œ ė³„ė„ ė™ģ˜ė„¼ 받지 ģ•Šģ€ 경우","사딀 2 : 국외 ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤(국외 리전)넼 ģ“ģš©ķ•˜ģ—¬ ź°œģøģ •ė³“ ģ²˜ė¦¬ģœ„ķƒ ė° ė³“ź“€ģ„ ķ•˜ė©“ģ„œ ģ“ģ „ė˜ėŠ” źµ­ź°€, ģ“ģ „ 방법 등 ꓀련 ģ‚¬ķ•­ģ„ ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź³µź°œķ•˜ź±°ė‚˜ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ•Œė¦¬ģ§€ ģ•Šģ€ 경우","사딀 3 : ź°œģøģ •ė³“ 국외 ģ“ģ „ģ— ėŒ€ķ•œ ė™ģ˜ė„¼ ė°›ģœ¼ė©“ģ„œ ģ“ģ „ė°›ėŠ” ģžģ˜ ėŖ…ģ¹­(업첓명)만 ź³ ģ§€ķ•˜ź³  ģ“ģ „ė˜ėŠ” źµ­ź°€ 등에 ėŒ€ķ•˜ģ—¬ ģ•Œė¦¬ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제28ģ”°ģ˜8(ź°œģøģ •ė³“ģ˜ 국외 ģ“ģ „), 제28ģ”°ģ˜9(ź°œģøģ •ė³“ģ˜ 국외 ģ“ģ „ 중지 ėŖ…ė ¹), 제28ģ”°ģ˜10(ģƒķ˜øģ£¼ģ˜), 제28ģ”°ģ˜11(ģ¤€ģš©ź·œģ •)","ź°œģøģ •ė³“ 국외 ģ“ģ „ 욓영 등에 ź“€ķ•œ ź·œģ •"]}],"description": "ź°œģøģ •ė³“ė„¼ źµ­ģ™øė”œ ģ“ģ „ķ•˜ėŠ” 경우 국외 ģ“ģ „ģ— ėŒ€ķ•œ ė™ģ˜, ꓀련 사항에 ėŒ€ķ•œ 공개 등 ģ ģ ˆķ•œ 볓호씰치넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.4.1": {"name": "ź°œģøģ •ė³“ 파기","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.4.1 ź°œģøģ •ė³“ 파기","Subdomain": "3.4. ź°œģøģ •ė³“ 파기 ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ ė³“ģœ źø°ź°„ ė° 파기 ꓀련 ź·œģ •","ź°œģøģ •ė³“ 파기 ź²°ź³¼(ķšŒģ› ė°ģ“ķ„°ė² ģ“ģŠ¤ 등)","ź°œģøģ •ė³“ ķŒŒźø°ź“€ė¦¬ėŒ€ģž„"],"AuditChecklist": ["ź°œģøģ •ė³“ģ˜ ė³“ģœ źø°ź°„ ė° ķŒŒźø°ģ™€ ź“€ė Øėœ ė‚“ė¶€ ģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ģ˜ ģ²˜ė¦¬ėŖ©ģ ģ“ ė‹¬ģ„±ė˜ź±°ė‚˜ ė³“ģœ źø°ź°„ģ“ ź²½ź³¼ķ•œ 경우 지첓 ģ—†ģ“ 핓당 ź°œģøģ •ė³“ė„¼ ķŒŒźø°ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ė„¼ ķŒŒźø°ķ•  ė•Œģ—ėŠ” ė³µźµ¬Ā·ģž¬ģƒė˜ģ§€ ģ•Šė„ė” ģ•ˆģ „ķ•œ ė°©ė²•ģœ¼ė”œ ķŒŒźø°ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ ķŒŒźø°ģ— ėŒ€ķ•œ źø°ė”ģ„ 남기고 ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķšŒģ› ķƒˆķ‡“ 등 ėŖ©ģ ģ“ ė‹¬ģ„±ė˜ź±°ė‚˜ ė³“ģœ źø°ź°„ģ“ 경과된 경우 ķšŒģ› ė°ģ“ķ„°ė² ģ“ģŠ¤ģ—ģ„œėŠ” 핓당 ź°œģøģ •ė³“ė„¼ ķŒŒźø°ķ•˜ģ˜€ģœ¼ė‚˜, CRMĀ·DW 등 ģ—°ź³„ėœ ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— ė³µģ œė˜ģ–“ ģ €ģž„ė˜ģ–“ ģžˆėŠ” ź°œģøģ •ė³“ė„¼ ķŒŒźø°ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ķŠ¹ģ • źø°ź°„ ė™ģ•ˆ ģ“ė²¤ķŠøė„¼ ķ•˜ė©“ģ„œ ģˆ˜ģ§‘ėœ ź°œģøģ •ė³“ģ— ėŒ€ķ•˜ģ—¬ ģ“ė²¤ķŠøź°€ ģ¢…ė£Œėœ ģ“ķ›„ģ—ė„ 파기 źø°ģ¤€ģ“ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šź±°ė‚˜ ķŒŒźø°ź°€ ģ“ė£Øģ–“ģ§€ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ģ½œģ„¼ķ„°ģ—ģ„œ ģˆ˜ģ§‘ė˜ėŠ” ėÆ¼ģ›ģ²˜ė¦¬ ꓀련 ź°œģøģ •ė³“(ģƒė‹“ģ“ė „, 녹취 등)넼 ģ „ģžģƒź±°ėž˜ė²•ģ„ 근거딜 3ė…„ź°„ ė³“ģ”“ķ•˜ź³  ģžˆģœ¼ė‚˜, 3ė…„ģ“ ź²½ź³¼ķ•œ ķ›„ģ—ė„ ķŒŒźø°ķ•˜ģ§€ ģ•Šź³  ė³“ź“€ķ•˜ź³  ģžˆėŠ” 경우","사딀 4 : ėø”ė”ģ²“ģø 등 기술적 ķŠ¹ģ„±ģœ¼ė”œ ģøķ•˜ģ—¬ ėŖ©ģ ģ“ ė‹¬ģ„±ėœ ź°œģøģ •ė³“ģ˜ 완전 ķŒŒźø°ź°€ ģ–“ė ¤ģ›Œ ģ™„ģ „ķŒŒźø° ėŒ€ģ‹  ģµėŖ…ģ²˜ė¦¬ė„¼ ķ•˜ģ˜€ģœ¼ė‚˜, ģµėŖ…ģ²˜ė¦¬ź°€ ģ ģ ˆķ•˜ź²Œ ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ•„ ģ¼ė¶€ ź°œģøģ •ė³“ģ˜ ģž¬ģ‹ė³„ 등 ė³µģ›ģ“ ź°€ėŠ„ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제21ģ”°(ź°œģøģ •ė³“ģ˜ 파기)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제13ģ”°(ź°œģøģ •ė³“ģ˜ 파기)"]}],"description": "ź°œģøģ •ė³“ģ˜ ė³“ģœ źø°ź°„ ė° 파기 ꓀련 ė‚“ė¶€ ģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ź°œģøģ •ė³“ģ˜ ė³“ģœ źø°ź°„ 경과, 처리목적 달성 등 파기 ģ‹œģ ģ“ ė„ė‹¬ķ•œ ė•Œģ—ėŠ” ķŒŒźø°ģ˜ ģ•ˆģ „ģ„± ė° ģ™„ģ „ģ„±ģ“ ė³“ģž„ė  수 ģžˆėŠ” ė°©ė²•ģœ¼ė”œ 지첓 ģ—†ģ“ ķŒŒźø°ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.4.2": {"name": "처리목적 달성 후 볓유 ģ‹œ 씰치","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.4.2 처리목적 달성 후 볓유 ģ‹œ 씰치","Subdomain": "3.4. ź°œģøģ •ė³“ 파기 ģ‹œ 볓호씰치","AuditEvidence": ["ź°œģøģ •ė³“ ė³“ģœ źø°ź°„ ė° 파기 ꓀련 ź·œģ •","분리 ė°ģ“ķ„°ė² ģ“ģŠ¤ ķ˜„ķ™©(ķ…Œģ“ėø” 구씰 등)","분리 ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ ‘ź·¼ź¶Œķ•œ ķ˜„ķ™©"],"AuditChecklist": ["ź°œģøģ •ė³“ģ˜ ė³“ģœ źø°ź°„ 경과 ė˜ėŠ” 처리목적 달성 ķ›„ģ—ė„ ꓀련 법령 등에 ė”°ė¼ ķŒŒźø°ķ•˜ģ§€ ģ•Šź³  ė³“ģ”“ķ•˜ėŠ” 경우, ꓀련 법령에 따넸 ģµœģ†Œķ•œģ˜ źø°ź°„ģœ¼ė”œ ķ•œģ •ķ•˜ģ—¬ ģµœģ†Œķ•œģ˜ ģ •ė³“ė§Œģ„ ė³“ģ”“ķ•˜ė„ė” ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ģ˜ ė³“ģœ źø°ź°„ 경과 ė˜ėŠ” 처리목적 달성 ķ›„ģ—ė„ ꓀련 법령 등에 ė”°ė¼ ķŒŒźø°ķ•˜ģ§€ ģ•Šź³  ė³“ģ”“ķ•˜ėŠ” 경우 핓당 ź°œģøģ •ė³“ ė˜ėŠ” ź°œģøģ •ė³“ķŒŒģ¼ģ„ 다넸 ź°œģøģ •ė³“ģ™€ ė¶„ė¦¬ķ•˜ģ—¬ ģ €ģž„Ā·ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","분리 ė³“ź“€ķ•˜ź³  ģžˆėŠ” ź°œģøģ •ė³“ģ— ėŒ€ķ•˜ģ—¬ ė²•ė ¹ģ—ģ„œ ģ •ķ•œ 목적 ė²”ģœ„ ė‚“ģ—ģ„œė§Œ 처리 ź°€ėŠ„ķ•˜ė„ė” ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","분리 ė³“ź“€ķ•˜ź³  ģžˆėŠ” ź°œģøģ •ė³“ģ— ėŒ€ķ•˜ģ—¬ ģ ‘ź·¼ź¶Œķ•œģ„ ģµœģ†Œķ•œģ˜ ģøģ›ģœ¼ė”œ ģ œķ•œķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķƒˆķ‡“ķšŒģ› 정볓넼 ķŒŒźø°ķ•˜ģ§€ ģ•Šź³  ģ „ģžģƒź±°ėž˜ė²•ģ— ė”°ė¼ ģ¼ģ •źø°ź°„ ė³“ź“€ķ•˜ė©“ģ„œ Flagź°’ė§Œ ė³€ź²½ķ•˜ģ—¬ 다넸 ķšŒģ›ģ •ė³“ģ™€ ė™ģ¼ķ•œ ķ…Œģ“ėø”ģ— ė³“ź“€ķ•˜ź³  ģžˆėŠ” 경우","사딀 2 : ģ „ģžģƒź±°ėž˜ė²•ģ— 따넸 ģ†Œė¹„ģž 불만 ė° ė¶„ģŸģ²˜ė¦¬ģ— ź“€ķ•œ źø°ė”ģ— ėŒ€ķ•“ ꓀련 법적 ģš”ź±“ģ„ ģž˜ėŖ» ģ ģš©ķ•˜ģ—¬ 3ė…„ģ“ ģ•„ė‹Œ 5ė…„ź°„ ė³“ģ”“ķ•˜ė„ė” ģ •ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : 분리 ė°ģ“ķ„°ė² ģ“ģŠ¤ė„¼ źµ¬ģ„±ķ•˜ģ˜€ģœ¼ė‚˜ ģ ‘ź·¼ź¶Œķ•œģ„ ė³„ė„ė”œ ģ„¤ģ •ķ•˜ģ§€ ģ•Šģ•„ ģ—…ė¬“ģƒ ģ ‘ź·¼ģ“ ė¶ˆķ•„ģš”ķ•œ ģøģ›ė„ 분리 ė°ģ“ķ„°ė² ģ“ģŠ¤ģ— ģžģœ ė”­ź²Œ ģ ‘ź·¼ģ“ ź°€ėŠ„ķ•œ 경우","사딀 4 : ķƒˆķ‡“ķšŒģ› 정볓넼 ķŒŒźø°ķ•˜ģ§€ ģ•Šź³  ģ „ģžģƒź±°ėž˜ė²•ģ— ė”°ė¼ 계약 ė˜ėŠ” ģ²­ģ•½ģ² ķšŒ, ėŒ€źøˆź²°ģ œ ė° ģž¬ķ™” 공급에 ź“€ķ•œ źø°ė”ģ„ ė¶„ė¦¬ķ•˜ģ—¬ ė³“ģ”“ķ•˜ģ˜€ģœ¼ė‚˜, ģ „ģžģƒź±°ėž˜ė²•ģ— 따넸 ė³“ģ”“ģ˜ė¬“ź°€ ģ—†ėŠ” ģ„ ķƒģ •ė³“ź¹Œģ§€ ź³¼ė„ķ•˜ź²Œ ė³“ģ”“ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제21ģ”°(ź°œģøģ •ė³“ģ˜ 파기)"]}],"description": "ź°œģøģ •ė³“ģ˜ ė³“ģœ źø°ź°„ 경과 ė˜ėŠ” 처리목적 달성 ķ›„ģ—ė„ ꓀련 법령 등에 ė”°ė¼ ķŒŒźø°ķ•˜ģ§€ ģ•Šź³  ė³“ģ”“ķ•˜ėŠ” ź²½ģš°ģ—ėŠ” 핓당 목적에 ķ•„ģš”ķ•œ ģµœģ†Œķ•œģ˜ ķ•­ėŖ©ģœ¼ė”œ ģ œķ•œķ•˜ź³  다넸 ź°œģøģ •ė³“ģ™€ ė¶„ė¦¬ķ•˜ģ—¬ ģ €ģž„Ā·ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.5.1": {"name": "ź°œģøģ •ė³“ 처리방침 공개","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.5.1 ź°œģøģ •ė³“ 처리방침 공개","Subdomain": "3.5. 정볓주첓 권리볓호","AuditEvidence": ["ź°œģøģ •ė³“ 처리방침","ź°œģøģ •ė³“ 처리방침 ź°œģ • ꓀련 공지 ė‚“ģ—­(ź²Œģ‹œķŒ 등)"],"AuditChecklist": ["ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ„ ė²•ė ¹ģ—ģ„œ ģš”źµ¬ķ•˜ėŠ” ė‚“ģš©ģ„ 모두 ķ¬ķ•Øķ•˜ģ—¬ ģ•Œźø° ģ‰¬ģš“ ģš©ģ–“ė”œ źµ¬ģ²“ģ ģ“ź³  ėŖ…ķ™•ķ•˜ź²Œ ģž‘ģ„±ķ•˜ģ˜€ėŠ”ź°€?","ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ„ 정볓주첓가 ģ‰½ź²Œ ķ™•ģøķ•  수 ģžˆė„ė” ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ 등에 ģ§€ģ†ģ ģœ¼ė”œ ķ˜„ķ–‰ķ™”ķ•˜ģ—¬ ź³µź°œķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ“ ė³€ź²½ė˜ėŠ” 경우 ģ‚¬ģœ  ė° 변경 ė‚“ģš©ģ„ 지첓 ģ—†ģ“ ź³µģ§€ķ•˜ź³  정볓주첓가 ģ–øģ œė“ ģ§€ ė³€ź²½ėœ ģ‚¬ķ•­ģ„ ģ‰½ź²Œ ģ•Œģ•„ ė³¼ 수 ģžˆė„ė” ģ”°ģ¹˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź³µź°œė˜ģ–“ ģžˆėŠ” ź°œģøģ •ė³“ ģˆ˜ģ§‘, 제3ģž 제공 ė‚“ģ—­ģ“ ģ‹¤ģ œ ģˆ˜ģ§‘ ė° ģ œź³µķ•˜ėŠ” ė‚“ģ—­ź³¼ 다넸 경우","사딀 2 : ź°œģøģ •ė³“ ė³“ķ˜øģ±…ģž„ģžģ˜ 변경, ģˆ˜ķƒģž 변경 등 ź°œģøģ •ė³“ 처리방침 공개 ė‚“ģš© 중에 ė³€ź²½ģ‚¬ķ•­ģ“ ė°œģƒķ•˜ģ˜€ģŒģ—ė„ ģ“ė„¼ ė°˜ģ˜ķ•˜ģ—¬ ė³€ź²½ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ“ ź³µź°œėŠ” ė˜ģ–“ ģžˆģœ¼ė‚˜, ėŖ…ģ¹­ģ“ Ź»ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹ØŹ¼ģ“ ģ•„ė‹ˆė¼ Ź»ź°œģøģ •ė³“ ė³“ķ˜øģ •ģ±…Ź¼ģœ¼ė”œ ė˜ģ–“ ģžˆź³  źø€ģž 크기, ģƒ‰ģƒ ė“±ģ„ ķ™œģš©ķ•˜ģ—¬ 정볓주첓가 ģ‰½ź²Œ ģ°¾ģ„ 수 ģžˆė„ė” ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ“ ėŖ‡ 차딀 ź°œģ •ė˜ģ—ˆģœ¼ė‚˜, ģ˜ˆģ „ģ— ģž‘ģ„±ėœ ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ˜ ė‚“ģš©ģ„ ķ™•ģøķ•  수 ģžˆė„ė” ź³µź°œė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 5 : ģ „ģžģƒź±°ėž˜ė²•, ģƒė²• 등 다넸 법령에 ė”°ė¼ ź°œģøģ •ė³“ė„¼ ķŒŒźø°ķ•˜ģ§€ ģ•„ė‹ˆķ•˜ź³  ģ¼ģ •źø°ź°„ ė³“ź“€ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ“ģ— 따넸 볓씓근거와 ė³“ģ”“ķ•˜ėŠ” ź°œģøģ •ė³“ ķ•­ėŖ©ģ„ ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ— ź³µź°œķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제30ģ”°(ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ˜ 수립 ė° 공개), 제30ģ”°ģ˜2(ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ˜ ķ‰ź°€ ė° ź°œģ„ ź¶Œź³ )"]}],"description": "ź°œģøģ •ė³“ģ˜ 처리 목적 등 ķ•„ģš”ķ•œ ģ‚¬ķ•­ģ„ 모두 ķ¬ķ•Øķ•˜ģ—¬ 정볓주첓가 ģ•Œźø° ģ‰½ė„ė” ź°œģøģ •ė³“ ģ²˜ė¦¬ė°©ģ¹Øģ„ ģˆ˜ė¦½ķ•˜ź³ , ģ“ė„¼ 정볓주첓가 ģ–øģ œė“ ģ§€ ģ‰½ź²Œ ķ™•ģøķ•  수 ģžˆė„ė” ģ ģ ˆķ•œ 방법에 ė”°ė¼ ź³µź°œķ•˜ź³  ģ§€ģ†ģ ģœ¼ė”œ ķ˜„ķ–‰ķ™”ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.5.2": {"name": "정볓주첓 ź¶Œė¦¬ė³“ģž„","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.5.2 정볓주첓 ź¶Œė¦¬ė³“ģž„","Subdomain": "3.5. 정볓주첓 권리볓호","AuditEvidence": ["ź°œģøģ •ė³“ 처리방침","ź°œģøģ •ė³“ ģ—“ėžŒė“±ģš”źµ¬ 처리 절차, ꓀련 ģ–‘ģ‹","ź°œģøģ •ė³“ ģ—“ėžŒė“±ģš”źµ¬ ģ‹œ 씰치 ė‚“ģ—­","ķšŒģ› ķƒˆķ‡“ ė° ė™ģ˜ 철회 절차"],"AuditChecklist": ["정볓주첓 ė˜ėŠ” ź·ø ėŒ€ė¦¬ģøģ“ ź°œģøģ •ė³“ģ— ėŒ€ķ•œ ģ—“ėžŒ, ģ •ģ •Ā·ģ‚­ģ œ, ģ²˜ė¦¬ģ •ģ§€ ė° ė™ģ˜ 철회 등(ģ“ķ•˜ 'ģ—“ėžŒė“±ģš”źµ¬'ė¼ 함)ģ„ ź°œģøģ •ė³“ ģˆ˜ģ§‘ė°©ė²•Ā·ģ ˆģ°Øė³“ė‹¤ 얓렵지 ģ•„ė‹ˆķ•˜ė„ė” 권리 행사 ė°©ė²•ė° 절차넼 ė§ˆė Øķ•˜ģ—¬ ź³µź°œķ•˜ź³  ģžˆėŠ”ź°€?","정볓주첓 ė˜ėŠ” ź·ø ėŒ€ė¦¬ģøģ“ ź°œģøģ •ė³“ ģ—“ėžŒė“±ģš”źµ¬ė„¼ ķ•˜ėŠ” 경우 źø°ź°„ 낓에 ģ—“ėžŒė“±ģš”źµ¬ģ— 따넸 ķ•„ģš”ķ•œ 씰치넼 ķ•˜ź³  ģžˆėŠ”ź°€?","정볓주첓 ė˜ėŠ” ź·ø ėŒ€ė¦¬ģøģ“ ź°œģøģ •ė³“ ģˆ˜ģ§‘Ā·ģ“ģš©Ā·ģ œź³µ ė“±ģ˜ ė™ģ˜ė„¼ ģ² ķšŒķ•˜ėŠ” 경우 지첓 ģ—†ģ“ ģˆ˜ģ§‘ėœ ź°œģøģ •ė³“ė„¼ ķŒŒźø°ķ•˜ėŠ” 등 ķ•„ģš”ķ•œ 씰치넼 ģ·Øķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ˜ ģ—“ėžŒė“±ģš”źµ¬ģ— ėŒ€ķ•œ ģ”°ģ¹˜ģ— ė¶ˆė³µģ“ ģžˆėŠ” 경우 ģ“ģ˜ė„¼ ģ œźø°ķ•  수 ģžˆė„ė” ķ•„ģš”ķ•œ 절차넼 ė§ˆė Øķ•˜ģ—¬ ģ•ˆė‚“ķ•˜ź³  ģžˆėŠ”ź°€?","ģ •ė³“ģ£¼ģ²“ģ˜ ģ—“ėžŒė“±ģš”źµ¬ ė° 처리 결과에 ėŒ€ķ•˜ģ—¬ źø°ė”ģ„ 남기고 ģžˆėŠ”ź°€?","ģ •ė³“ķ†µģ‹ ė§ģ—ģ„œ ģ‚¬ģƒķ™œ 침핓 ė˜ėŠ” ėŖ…ģ˜ˆķ›¼ģ† 등 ķƒ€ģøģ˜ 권리넼 ģ¹Øķ•“ķ•œ 경우 침핓넼 ė°›ģ€ ģžź°€ ģ •ė³“ķ†µģ‹ ģ„œė¹„ģŠ¤ ģ œź³µģžģ—ź²Œ ģ •ė³“ģ˜ ģ‚­ģ œ ģš”ģ²­ ė“±ģ„ ķ•  수 ģžˆėŠ” 절차넼 ė§ˆė Øķ•˜ģ—¬ ģ‹œķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ź°œģøģ •ė³“ģ˜ ģ—“ėžŒ, ģ •ģ •Ā·ģ‚­ģ œ, ģ²˜ė¦¬ģ •ģ§€ ģš”źµ¬ ė°©ė²•ģ„ 정볓주첓가 ģ•Œ 수 ģžˆė„ė” ź³µź°œķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ź°œģøģ •ė³“ģ˜ ģ—“ėžŒ ģš”źµ¬ģ— ėŒ€ķ•˜ģ—¬ ģ •ė‹¹ķ•œ ģ‚¬ģœ ģ˜ 통지 ģ—†ģ“ ģ—“ėžŒ ģš”źµ¬ė„¼ ģ ‘ģˆ˜ė°›ģ€ ė‚ ė”œė¶€ķ„° 10ģ¼ģ„ ģ“ˆź³¼ķ•˜ģ—¬ ķšŒģ‹ ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : ź°œģøģ •ė³“ģ˜ ģ—“ėžŒ 민원에 ėŒ€ķ•œ 처리 ė‚“ģ—­ źø°ė” ė° ė³“ź“€ģ“ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우","사딀 4 : 정볓주첓 ė‹¹ģ‚¬ģž ė˜ėŠ” ģ •ė‹¹ķ•œ ėŒ€ė¦¬ģøģ“ ė§žėŠ”ģ§€ģ— ėŒ€ķ•œ ķ™•ģø 절차 ģ—†ģ“ ģ—“ėžŒ 통지가 ģ“ė£Øģ–“ģ§€ėŠ” 경우","사딀 5 : ź°œģøģ •ė³“ģ˜ ģ •ģ •Ā·ģ‚­ģ œ ģš”źµ¬ģ— ėŒ€ķ•˜ģ—¬ ģ •ģ •Ā·ģ‚­ģ œ ģš”źµ¬ė„¼ ģ ‘ģˆ˜ė°›ģ€ ė‚ ė”œė¶€ķ„° 10ģ¼ģ„ ģ“ˆź³¼ķ•˜ģ—¬ ķšŒģ‹ ķ•˜ėŠ” 경우","사딀 6 : ķšŒģ› ź°€ģž… ģ‹œģ—ėŠ” ģ˜Øė¼ģøģ„ ķ†µķ•˜ģ—¬ ģ‰½ź²Œ ķšŒģ› ź°€ģž…ģ“ ź°€ėŠ„ķ•˜ģ˜€ģœ¼ė‚˜, ķšŒģ› ķƒˆķ‡“ ģ‹œģ—ėŠ” ģ‹ ė¶„ģ¦ 등 추가 ģ„œė„˜ė„¼ ģ œģ¶œķ•˜ź²Œ ķ•˜ź±°ė‚˜ ģ˜¤ķ”„ė¼ģø ė°©ė¬øģ„ ķ†µķ•“ģ„œė§Œ ź°€ėŠ„ķ•˜ė„ė” ķ•˜ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제34ģ”°ģ˜2(ė…øģ¶œėœ ź°œģøģ •ė³“ģ˜ ģ‚­ģ œĀ·ģ°Øė‹Ø), 제35ģ”°(ź°œģøģ •ė³“ģ˜ ģ—“ėžŒ), 제35ģ”°ģ˜2(ź°œģøģ •ė³“ģ˜ 전솔 ģš”źµ¬), 제36ģ”°(ź°œģøģ •ė³“ģ˜ ģ •ģ •Ā·ģ‚­ģ œ), 제37ģ”°(ź°œģøģ •ė³“ģ˜ ģ²˜ė¦¬ģ •ģ§€ 등), 제37ģ”°ģ˜2(ģžė™ķ™”ėœ 결정에 ėŒ€ķ•œ ģ •ė³“ģ£¼ģ²“ģ˜ 권리 등), 제38ģ”°(ź¶Œė¦¬ķ–‰ģ‚¬ģ˜ 방법 ė° 절차)","ģ •ė³“ķ†µģ‹ ė§ė²• 제44ģ”°(ģ •ė³“ķ†µģ‹ ė§ģ—ģ„œģ˜ 권리볓호), 제44ģ”°ģ˜2(ģ •ė³“ģ˜ ģ‚­ģ œģš”ģ²­ 등), 제44ģ”°ģ˜3(ģž„ģ˜ģ˜ ģž„ģ‹œģ”°ģ¹˜)"]}],"description": "정볓주첓가 ź°œģøģ •ė³“ģ˜ ģ—“ėžŒ, ģ •ģ •Ā·ģ‚­ģ œ, ģ²˜ė¦¬ģ •ģ§€, ģ“ģ˜ģ œźø°, ė™ģ˜ģ² ķšŒ 등 ģš”źµ¬ė„¼ ģˆ˜ģ§‘ ė°©ė²•Ā·ģ ˆģ°Øė³“ė‹¤ ģ‰½ź²Œ ķ•  수 ģžˆė„ė” ź¶Œė¦¬ķ–‰ģ‚¬ 방법 ė° 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ , ģ •ė³“ģ£¼ģ²“ģ˜ ģš”źµ¬ė„¼ ė°›ģ€ 경우 지첓 ģ—†ģ“ ģ²˜ė¦¬ķ•˜ź³  ꓀련 źø°ė”ģ„ 남겨야 ķ•œė‹¤. ė˜ķ•œ ģ •ė³“ģ£¼ģ²“ģ˜ ģ‚¬ģƒķ™œ 침핓, ėŖ…ģ˜ˆķ›¼ģ† 등 ķƒ€ģøģ˜ 권리넼 ģ¹Øķ•“ķ•˜ėŠ” 정볓가 ģœ ķ†µė˜ģ§€ ģ•Šė„ė” ģ‚­ģ œģš”ģ²­, ģž„ģ‹œģ”°ģ¹˜ ė“±ģ˜ źø°ģ¤€ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"3.5.3": {"name": "정볓주첓에 ėŒ€ķ•œ 통지","checks": {},"status": "PASS","attributes": [{"Domain": "3. ź°œģøģ •ė³“ 처리 단계별 ģš”źµ¬ģ‚¬ķ•­","Section": "3.5.3 정볓주첓에 ėŒ€ķ•œ 통지","Subdomain": "3.5. 정볓주첓 권리볓호","AuditEvidence": ["ź°œģøģ •ė³“ ģ“ģš©Ā·ģ œź³µ ė‚“ģ—­ 통지 źø°ė”","ź°œģøģ •ė³“ ģ“ģš©Ā·ģ œź³µ ė‚“ģ—­ 통지 ģ–‘ģ‹ ė° 문구"],"AuditChecklist": ["법적 ģ˜ė¬“ ėŒ€ģƒģžģ— ķ•“ė‹¹ķ•˜ėŠ” 경우 ź°œģøģ •ė³“ ģ“ģš©Ā·ģ œź³µ ė‚“ģ—­ ė˜ėŠ” ź·ø ė‚“ģ—­ģ„ ķ™•ģøķ•  수 ģžˆėŠ” ģ •ė³“ģ‹œģŠ¤ķ…œģ— ģ ‘ģ†ķ•˜ėŠ” ė°©ė²•ģ„ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ 주기적으딜 ķ†µģ§€ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ ģ“ģš©Ā·ģ œź³µ ė‚“ģ—­ 통지 ķ•­ėŖ©ģ€ 법적 ģš”źµ¬ķ•­ėŖ©ģ„ 모두 ķ¬ķ•Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ „ė…„ė„ 말 기준 직전 3ź°œģ›” ź°„ ģ¼ģ¼ ķ‰ź·  ģ €ģž„Ā·ź“€ė¦¬ķ•˜ź³  ģžˆėŠ” ź°œģøģ •ė³“ź°€ 100ė§ŒėŖ… ģ“ģƒģœ¼ė”œģ„œ ź°œģøģ •ė³“ ģ“ģš©ģ œź³µ ė‚“ģ—­ 통지 ģ˜ė¬“ ėŒ€ģƒģžģ— 핓당 ėØģ—ė„ ė¶ˆźµ¬ķ•˜ź³  źøˆė…„ė„ģ— ź°œģøģ •ė³“ ģ“ģš© ė°ė‚“ģ—­ģ„ ķ†µģ§€ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ź°œģøģ •ė³“ ģ“ģš©Ā·ģ œź³µ ė‚“ģ—­ģ„ ź°œė³„ ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ģ§ģ ‘ģ ģœ¼ė”œ ķ†µģ§€ķ•˜ėŠ” ėŒ€ģ‹  ķ™ˆķŽ˜ģ“ģ§€ģ—ģ„œ ė‹Øģˆœ ķŒģ—…ģ°½ģ“ė‚˜ ė³„ė„ ź³µģ§€ģ‚¬ķ•­ģœ¼ė”œ ģ•ˆė‚“ė§Œ ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제20ģ”°ģ˜2(ź°œģøģ •ė³“ ģ“ģš©Ā·ģ œź³µ ė‚“ģ—­ģ˜ 통지)"]}],"description": "ź°œģøģ •ė³“ģ˜ ģ“ģš©Ā·ģ œź³µ ė‚“ģ—­ 등 ģ •ė³“ģ£¼ģ²“ģ—ź²Œ ķ†µģ§€ķ•˜ģ—¬ģ•¼ ķ•  ģ‚¬ķ•­ģ„ ķŒŒģ•…ķ•˜ģ—¬ ź·ø ė‚“ģš©ģ„ 주기적으딜 ķ†µģ§€ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.10.1": {"name": "ė³“ģ•ˆģ‹œģŠ¤ķ…œ 욓영","checks": {"kms_cmk_are_used": null,"macie_is_enabled": "PASS","securityhub_enabled": "PASS","fms_policy_compliant": null,"guardduty_is_enabled": "PASS","inspector2_is_enabled": "FAIL","elbv2_waf_acl_attached": "FAIL","kms_cmk_rotation_enabled": null,"ec2_securitygroup_not_used": "FAIL","guardduty_centrally_managed": "FAIL","wafv2_webacl_logging_enabled": "FAIL","ssm_managed_compliant_patching": "FAIL","kms_key_not_publicly_accessible": null,"ssmincidents_enabled_with_plans": null,"inspector2_active_findings_exist": "FAIL","cloudfront_distributions_using_waf": null,"cognito_user_pool_waf_acl_attached": null,"trustedadvisor_errors_and_warnings": null,"apigateway_restapi_waf_acl_attached": "FAIL","config_recorder_all_regions_enabled": null,"guardduty_no_high_severity_findings": "FAIL","ec2_securitygroup_from_launch_wizard": "FAIL","ec2_networkacl_allow_ingress_any_port": "FAIL","organizations_delegated_administrators": null,"ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_instance_port_ftp_exposed_to_internet": "PASS","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","secretsmanager_automatic_rotation_enabled": "FAIL","ec2_instance_port_cifs_exposed_to_internet": "PASS","ec2_instance_port_ldap_exposed_to_internet": "PASS","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","ec2_instance_port_kafka_exposed_to_internet": "PASS","ec2_instance_port_mysql_exposed_to_internet": "PASS","ec2_instance_port_redis_exposed_to_internet": "PASS","ec2_instance_port_oracle_exposed_to_internet": "PASS","ec2_instance_port_telnet_exposed_to_internet": "PASS","ec2_instance_port_mongodb_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_instance_port_kerberos_exposed_to_internet": "PASS","ec2_instance_port_cassandra_exposed_to_internet": "PASS","ec2_instance_port_memcached_exposed_to_internet": "PASS","ec2_instance_port_sqlserver_exposed_to_internet": "PASS","cloudwatch_log_metric_filter_sign_in_without_mfa": null,"ec2_instance_port_postgresql_exposed_to_internet": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","shield_advanced_protection_in_global_accelerators": null,"ec2_instance_internet_facing_with_instance_profile": "FAIL","shield_advanced_protection_in_route53_hosted_zones": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_authentication_failures": null,"shield_advanced_protection_in_associated_elastic_ips": null,"shield_advanced_protection_in_classic_load_balancers": null,"shield_advanced_protection_in_cloudfront_distributions": null,"ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","ec2_instance_port_elasticsearch_kibana_exposed_to_internet": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","shield_advanced_protection_in_internet_facing_load_balancers": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.1 ė³“ģ•ˆģ‹œģŠ¤ķ…œ 욓영","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["ė³“ģ•ˆģ‹œģŠ¤ķ…œ 구성","ė„¤ķŠøģ›Œķ¬ 구성","ė³“ģ•ˆģ‹œģŠ¤ķ…œ 욓영절차","방화벽 ģ •ģ±…","방화벽 ģ •ģ±… 설정·변경 ģš”ģ²­ģ„œ","ė³“ģ•ˆģ‹œģŠ¤ķ…œ ģ˜ˆģ™øģž ėŖ©ė”","ė³“ģ•ˆģ‹œģŠ¤ķ…œė³„ ꓀리 화멓(방화벽, IPS, ģ„œė²„ģ ‘ź·¼ģ œģ–“, DLP, DRM 등)","ė³“ģ•ˆģ‹œģŠ¤ķ…œ ģ •ģ±… 검토 ģ“ė „"],"AuditChecklist": ["ģ”°ģ§ģ—ģ„œ ģš“ģ˜ķ•˜ź³  ģžˆėŠ” ė³“ģ•ˆģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ 욓영절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ģ•ˆģ‹œģŠ¤ķ…œ ź“€ė¦¬ģž 등 ģ ‘ź·¼ģ“ ķ—ˆģš©ėœ ģøģ›ģ„ ģµœģ†Œķ™”ķ•˜ź³  ė¹„ģøź°€ģžģ˜ ģ ‘ź·¼ģ„ ģ—„ź²©ķ•˜ź²Œ ķ†µģ œķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ģ•ˆģ‹œģŠ¤ķ…œė³„ė”œ ģ •ģ±…ģ˜ ģ‹ ź·œ ė“±ė”, 변경, ģ‚­ģ œ ė“±ģ„ ģœ„ķ•œ ź³µģ‹ģ ģø 절차넼 수립 ė° ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ģ•ˆģ‹œģŠ¤ķ…œģ˜ ģ˜ˆģ™ø ģ •ģ±… ė“±ė”ģ— ėŒ€ķ•˜ģ—¬ ģ ˆģ°Øģ— ė”°ė¼ ź“€ė¦¬ķ•˜ź³  ģžˆģœ¼ė©°, ģ˜ˆģ™ø ģ •ģ±… ģ‚¬ģš©ģžģ— ėŒ€ķ•˜ģ—¬ ģµœģ†Œķ•œģ˜ ź¶Œķ•œģœ¼ė”œ ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ģ•ˆģ‹œģŠ¤ķ…œģ— ģ„¤ģ •ėœ ģ •ģ±…ģ˜ ķƒ€ė‹¹ģ„± 여부넼 주기적으딜 ź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ė¶ˆė²•ģ ģø ģ ‘ź·¼ ė° ź°œģøģ •ė³“ 유출 방지넼 ģœ„ķ•˜ģ—¬ ꓀련 ė²•ė ¹ģ—ģ„œ ģ •ķ•œ źø°ėŠ„ģ„ ģˆ˜ķ–‰ķ•˜ėŠ” ė³“ģ•ˆģ‹œģŠ¤ķ…œģ„ ģ„¤ģ¹˜ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ¹Øģž…ģ°Øė‹Øģ‹œģŠ¤ķ…œ ė³“ģ•ˆģ •ģ±…ģ— ėŒ€ķ•œ ģ •źø° 검토가 ģˆ˜ķ–‰ė˜ģ§€ ģ•Šģ•„ ė¶ˆķ•„ģš”ķ•˜ź±°ė‚˜ ź³¼ė„ķ•˜ź²Œ ķ—ˆģš©ėœ ģ •ģ±…ģ“ ė‹¤ģˆ˜ ģ”“ģž¬ķ•˜ėŠ” 경우","사딀 2 : ė³“ģ•ˆģ‹œģŠ¤ķ…œ ė³“ģ•ˆģ •ģ±…ģ˜ ģ‹ ģ²­, 변경, ģ‚­ģ œ, 주기적 검토에 ėŒ€ķ•œ 절차 ė° źø°ģ¤€ģ“ ģ—†ź±°ė‚˜, ģ ˆģ°ØėŠ” ģžˆģœ¼ė‚˜ ģ“ė„¼ ģ¤€ģˆ˜ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ė³“ģ•ˆģ‹œģŠ¤ķ…œģ˜ ź“€ė¦¬ģž 지정 ė° ź¶Œķ•œ 부여 ķ˜„ķ™©ģ— ėŒ€ķ•œ ź“€ė¦¬ź°ė…ģ“ ģ ģ ˆķžˆ ģ“ķ–‰ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ė‚“ė¶€ ģ§€ģ¹Øģ—ėŠ” ģ •ė³“ė³“ķ˜øė‹“ė‹¹ģžź°€ ė³“ģ•ˆģ‹œģŠ¤ķ…œģ˜ ė³“ģ•ˆģ •ģ±… 변경 ģ“ė „ģ„ źø°ė”Ā·ė³“ź“€ķ•˜ė„ė” ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ •ģ±…ź“€ė¦¬ėŒ€ģž„ģ„ 주기적으딜 ģž‘ģ„±ķ•˜ģ§€ ģ•Šź³  ģžˆź±°ė‚˜ ģ •ģ±…ź“€ė¦¬ėŒ€ģž„ģ— źø°ė”ėœ ė³“ģ•ˆģ •ģ±…ź³¼ ģ‹¤ģ œ 욓영 ģ¤‘ģø ģ‹œģŠ¤ķ…œģ˜ ė³“ģ•ˆģ •ģ±…ģ“ ģƒģ“ķ•œ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "ė³“ģ•ˆģ‹œģŠ¤ķ…œ ģœ ķ˜•ė³„ė”œ ź“€ė¦¬ģž 지정, ģµœģ‹  ģ •ģ±… ģ—…ė°ģ“ķŠø, 룰셋 변경, ģ“ė²¤ķŠø ėŖØė‹ˆķ„°ė§ ė“±ģ˜ 욓영절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ė³“ģ•ˆģ‹œģŠ¤ķ…œė³„ ģ •ģ±…ģ ģš© ķ˜„ķ™©ģ„ ź“€ė¦¬ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 16,"pass": 39,"total": 75,"manual": 0}},"2.10.2": {"name": "ķ“ė¼ģš°ė“œ ė³“ģ•ˆ","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.2 ķ“ė¼ģš°ė“œ ė³“ģ•ˆ","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ꓀련 ź³„ģ•½ģ„œ ė° SLA","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ģœ„ķ—˜ė¶„ģ„ ź²°ź³¼","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ė³“ģ•ˆķ†µģ œ ģ •ģ±…","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ź“€ė¦¬ģž ź¶Œķ•œ 부여 ķ˜„ķ™©","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ źµ¬ģ„±ė„","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ė³“ģ•ˆģ„¤ģ • ķ˜„ķ™©","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ė³“ģ•ˆģ„¤ģ • 적정성 검토 ģ“ė „"],"AuditChecklist": ["ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ģ œź³µģžģ™€ ģ •ė³“ė³“ķ˜ø ė° ź°œģøģ •ė³“ė³“ķ˜øģ— ėŒ€ķ•œ ģ±…ģž„ź³¼ ģ—­ķ• ģ„ ėŖ…ķ™•ķžˆģ •ģ˜ķ•˜ź³  ģ“ė„¼ ź³„ģ•½ģ„œ(SLA 등)에 ė°˜ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ģ“ģš© ģ‹œ ģ„œė¹„ģŠ¤ ģœ ķ˜•ģ— 따넸 ė³“ģ•ˆģœ„ķ—˜ģ„ ķ‰ź°€ķ•˜ģ—¬ ė¹„ģøź°€ ģ ‘ź·¼,ģ„¤ģ •ģ˜¤ė„˜ ė“±ģ„ 방지할 수 ģžˆė„ė” ė³“ģ•ˆ 구성 ė° 설정 기준, ė³“ģ•ˆģ„¤ģ • 변경 ė° ģŠ¹ģø 절차, ģ•ˆģ „ķ•œ ģ ‘ģ†ė°©ė²•, ź¶Œķ•œ 첓계 등 ė³“ģ•ˆ ķ†µģ œ ģ •ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ź“€ė¦¬ģž ź¶Œķ•œģ€ 역할에 ė”°ė¼ ģµœģ†Œķ™”ķ•˜ģ—¬ ė¶€ģ—¬ķ•˜ź³  ź“€ė¦¬ģž ź¶Œķ•œģ— ėŒ€ķ•œė¹„ģøź°€ ģ ‘ź·¼, ź¶Œķ•œ ģ˜¤Ā·ė‚Øģš© ė“±ģ„ 방지할 수 ģžˆė„ė” ź°•ķ™”ėœ ģøģ¦, ģ•”ķ˜øķ™”, ģ ‘ź·¼ķ†µģ œ, ź°ģ‚¬źø°ė” 등 ė³“ķ˜øėŒ€ģ±…ģ„ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?","ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ģ˜ ė³“ģ•ˆ 설정 변경, 욓영 ķ˜„ķ™© ė“±ģ„ ėŖØė‹ˆķ„°ė§ķ•˜ź³  ź·ø ģ ģ ˆģ„±ģ„ ģ •źø°ģ ģœ¼ė”œź²€ķ† ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ź³„ģ•½ģ„œ 낓에 ė³“ģ•ˆģ— ėŒ€ķ•œ ģ±…ģž„ ė° ģ—­ķ•  등에 ėŒ€ķ•œ ģ‚¬ķ•­ģ“ ķ¬ķ•Øė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ģ˜ ė³“ģ•ˆģ„¤ģ •ģ„ 변경할 수 ģžˆėŠ” ź¶Œķ•œģ“ ģ—…ė¬“ģƒ ė°˜ė“œģ‹œ ķ•„ģš”ķ•˜ģ§€ ģ•Šģ€ ģ§ģ›ė“¤ģ—ź²Œ ź³¼ė„ķ•˜ź²Œ ė¶€ģ—¬ė˜ģ–“ ģžˆėŠ” 경우","사딀 3 : ė‚“ė¶€ ģ§€ģ¹Øģ—ėŠ” ķ“ė¼ģš°ė“œ ė‚“ 사설 ė„¤ķŠøģ›Œķ¬ģ˜ ģ ‘ź·¼ķ†µģ œ 룰(Rule) 변경 ģ‹œ ė³“ģ•ˆģ±…ģž„ģž ģŠ¹ģøģ„ ė°›ė„ė” ķ•˜ź³  ģžˆģœ¼ė‚˜, ģŠ¹ģøģ ˆģ°Øė„¼ ź±°ģ¹˜ģ§€ ģ•Šź³  ė“±ė”Ā·ė³€ź²½ėœ ģ ‘ź·¼ģ œģ–“ ė£°ģ“ ė‹¤ģˆ˜ 발견된 경우","사딀 4 : ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ģ˜ ė³“ģ•ˆģ„¤ģ • 오넘딜 ė‚“ė¶€ 딜그 ķŒŒģ¼ģ“ ģøķ„°ė„·ģ„ ķ†µķ•˜ģ—¬ ź³µź°œė˜ģ–“ ģžˆėŠ” 경우"],"RelatedRegulations": []}],"description": "ķ“ė¼ģš°ė“œ ģ„œė¹„ģŠ¤ ģ“ģš© ģ‹œ ģ„œė¹„ģŠ¤ ģœ ķ˜•(SaaS, PaaS, IaaS 등)에 따넸 ė¹„ģøź°€ ģ ‘ź·¼, 설정 오넘 등에 ė”°ė¼ ģ¤‘ģš”ģ •ė³“ģ™€ ź°œģøģ •ė³“ź°€ ģœ Ā·ė…øģ¶œė˜ģ§€ ģ•Šė„ė” ź“€ė¦¬ģž ģ ‘ź·¼ ė° ė³“ģ•ˆ 설정 등에 ėŒ€ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.10.3": {"name": "ź³µź°œģ„œė²„ ė³“ģ•ˆ","checks": {"elb_ssl_listeners": "FAIL","elbv2_ssl_listeners": "FAIL","ssm_document_secrets": "PASS","elbv2_waf_acl_attached": "FAIL","elb_insecure_ssl_ciphers": "PASS","apigateway_restapi_public": "FAIL","lightsail_database_public": null,"lightsail_instance_public": null,"elbv2_insecure_ssl_ciphers": "PASS","lightsail_static_ip_unused": null,"networkfirewall_in_all_vpc": "FAIL","ec2_instance_imdsv2_enabled": "PASS","elbv2_desync_mitigation_mode": "FAIL","awslambda_function_inside_vpc": "FAIL","awslambda_function_url_public": null,"ec2_instance_secrets_user_data": "PASS","ec2_launch_template_no_secrets": "PASS","ssm_managed_compliant_patching": "FAIL","inspector2_active_findings_exist": "FAIL","acm_certificates_expiration_check": "PASS","awslambda_function_url_cors_policy": null,"cloudfront_distributions_using_waf": null,"vpc_subnet_separate_private_public": "FAIL","apigateway_restapi_waf_acl_attached": "FAIL","apigatewayv2_api_authorizers_enabled": "FAIL","awslambda_function_no_secrets_in_code": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","apigateway_restapi_authorizers_enabled": "PASS","cloudfront_distributions_https_enabled": null,"ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","apigateway_restapi_public_with_authorizer": "FAIL","ec2_instance_port_ftp_exposed_to_internet": "PASS","ec2_instance_port_rdp_exposed_to_internet": "PASS","ec2_instance_port_ssh_exposed_to_internet": "PASS","awslambda_function_no_secrets_in_variables": "PASS","awslambda_function_not_publicly_accessible": "PASS","ec2_instance_port_cifs_exposed_to_internet": "PASS","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","route53_domains_privacy_protection_enabled": null,"ec2_instance_port_kafka_exposed_to_internet": "PASS","ec2_instance_port_mysql_exposed_to_internet": "PASS","ec2_instance_port_redis_exposed_to_internet": "PASS","ec2_instance_port_oracle_exposed_to_internet": "PASS","ec2_instance_port_telnet_exposed_to_internet": "PASS","apigateway_restapi_client_certificate_enabled": "FAIL","ec2_instance_port_mongodb_exposed_to_internet": "PASS","ec2_securitygroup_allow_wide_open_public_ipv4": "PASS","ec2_instance_port_kerberos_exposed_to_internet": "PASS","ec2_instance_port_cassandra_exposed_to_internet": "PASS","ec2_instance_port_memcached_exposed_to_internet": "PASS","ec2_instance_port_sqlserver_exposed_to_internet": "PASS","kafka_cluster_mutual_tls_authentication_enabled": null,"ec2_instance_port_postgresql_exposed_to_internet": "PASS","ec2_securitygroup_with_many_ingress_egress_rules": "PASS","autoscaling_find_secrets_ec2_launch_configuration": "PASS","ec2_instance_internet_facing_with_instance_profile": "FAIL","cloudfront_distributions_using_deprecated_ssl_protocols": null,"ec2_securitygroup_allow_ingress_from_internet_to_any_port": "PASS","ec2_instance_port_elasticsearch_kibana_exposed_to_internet": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mongodb_27017_27018": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.3 ź³µź°œģ„œė²„ ė³“ģ•ˆ","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["ė„¤ķŠøģ›Œķ¬ źµ¬ģ„±ė„","ģ›¹ģ‚¬ģ“ķŠø ģ •ė³“ź³µź°œ 절차 ė° ė‚“ģ—­(ģ‹ ģ²­Ā·ģŠ¹ģøĀ·ź²Œģ‹œ ģ“ė „ 등)","ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ ė…øģ¶œ 여부 점검 ģ“ė „"],"AuditChecklist": ["ź³µź°œģ„œė²„ė„¼ ģš“ģ˜ķ•˜ėŠ” 경우 ģ“ģ— ėŒ€ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ź³µź°œģ„œė²„ėŠ” ė‚“ė¶€ ė„¤ķŠøģ›Œķ¬ģ™€ ė¶„ė¦¬ėœ DMZ ģ˜ģ—­ģ— ģ„¤ģ¹˜ķ•˜ź³  ģ¹Øģž…ģ°Øė‹Øģ‹œģŠ¤ķ…œ 등 ė³“ģ•ˆģ‹œģŠ¤ķ…œģ„ ķ†µķ•˜ģ—¬ ė³“ķ˜øķ•˜ź³  ģžˆėŠ”ź°€?","ź³µź°œģ„œė²„ģ— ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ė„¼ ź²Œģ‹œķ•˜ź±°ė‚˜ ģ €ģž„ķ•˜ģ—¬ģ•¼ ķ•  경우 ģ±…ģž„ģž ģŠ¹ģø 등 ķ—ˆź°€ ė° ź²Œģ‹œģ ˆģ°Øė„¼ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ”°ģ§ģ˜ ģ¤‘ģš”ģ •ė³“ź°€ ģ›¹ģ‚¬ģ“ķŠø ė° ģ›¹ģ„œė²„ė„¼ ķ†µķ•˜ģ—¬ ė…øģ¶œė˜ź³  ģžˆėŠ”ģ§€ 여부넼 주기적으딜 ķ™•ģøķ•˜ģ—¬ ģ¤‘ģš”ģ •ė³“ ė…øģ¶œģ„ ģøģ§€ķ•œ 경우 ģ“ė„¼ ģ¦‰ģ‹œ ģ°Øė‹Øķ•˜ėŠ” ė“±ģ˜ 씰치넼 ģ·Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģøķ„°ė„·ģ— 공개된 ģ›¹ģ‚¬ģ“ķŠøģ˜ ģ·Øģ•½ģ ģœ¼ė”œ ģøķ•˜ģ—¬ 구글 ź²€ģƒ‰ģ„ ķ†µķ•˜ģ—¬ ģ—“ėžŒ ź¶Œķ•œģ“ ģ—†ėŠ” ķƒ€ģøģ˜ ź°œģøģ •ė³“ģ— 접근할 수 ģžˆėŠ” 경우","사딀 2 : ģ›¹ģ‚¬ģ“ķŠøģ— ź°œģøģ •ė³“ė„¼ ź²Œģ‹œķ•˜ėŠ” 경우 ģŠ¹ģø 절차넼 ź±°ģ¹˜ė„ė” ė‚“ė¶€ ź·œģ •ģ“ ė§ˆė Øė˜ģ–“ ģžˆģœ¼ė‚˜, ģ“ė„¼ ģ¤€ģˆ˜ķ•˜ģ§€ ģ•Šź³  ź°œģøģ •ė³“ź°€ ź²Œģ‹œėœ 사딀가 ė‹¤ģˆ˜ ģ”“ģž¬ķ•œ 경우","사딀 3 : ź²Œģ‹œķŒ ė“±ģ˜ 웹 ģ‘ģš©ķ”„ė”œź·øėžØģ—ģ„œ ķƒ€ģøģ“ ģž‘ģ„±ķ•œ źø€ģ„ ģž„ģ˜ė”œ ģˆ˜ģ •Ā·ģ‚­ģ œķ•˜ź±°ė‚˜ ė¹„ė°€ė²ˆķ˜øė”œ 볓호된 źø€ģ„ ģ—“ėžŒķ•  수 ģžˆėŠ” 경우"],"RelatedRegulations": []}],"description": "외부 ė„¤ķŠøģ›Œķ¬ģ— ź³µź°œė˜ėŠ” ģ„œė²„ģ˜ 경우 ė‚“ė¶€ ė„¤ķŠøģ›Œķ¬ģ™€ ė¶„ė¦¬ķ•˜ź³  취약점 점검, ģ ‘ź·¼ķ†µģ œ, ģøģ¦, 정볓 ģˆ˜ģ§‘Ā·ģ €ģž„Ā·ź³µź°œ 절차 등 ź°•ķ™”ėœ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 19,"pass": 47,"total": 76,"manual": 0}},"2.10.4": {"name": "ģ „ģžź±°ėž˜ ė° ķ•€ķ…Œķ¬ ė³“ģ•ˆ","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.4 ģ „ģžź±°ėž˜ ė° ķ•€ķ…Œķ¬ ė³“ģ•ˆ","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["ģ „ģžź±°ėž˜ ė° ķ•€ķ…Œķ¬ ģ„œė¹„ģŠ¤ ė³“ķ˜øėŒ€ģ±…","ź²°ģ œģ‹œģŠ¤ķ…œ 연계 ģ‹œ ė³“ģ•ˆģ„± 검토 ź²°ź³¼"],"AuditChecklist": ["ģ „ģžź±°ėž˜ ė° ķ•€ķ…Œķ¬ ģ„œė¹„ģŠ¤ė„¼ ģ œź³µķ•˜ėŠ” 경우 ź±°ėž˜ģ˜ ģ•ˆģ „ģ„±ź³¼ 신뢰성 확볓넼 ģœ„ķ•œė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ „ģžź±°ėž˜ ė° ķ•€ķ…Œķ¬ ģ„œė¹„ģŠ¤ ģ œź³µģ„ ģœ„ķ•˜ģ—¬ ź²°ģ œģ‹œģŠ¤ķ…œ 등 외부 ģ‹œģŠ¤ķ…œź³¼ ģ—°ź³„ķ•˜ėŠ” 경우 ģ†”ģˆ˜ģ‹ ė˜ėŠ” ꓀련 ģ •ė³“ģ˜ 볓호넼 ģœ„ķ•œ ėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģ•ˆģ „ģ„±ģ„ ģ ź²€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ „ģžź²°ģ œėŒ€ķ–‰ģ—…ģ²“ģ™€ ģœ„ķƒ ź³„ģ•½ģ„ ė§ŗź³  연계넼 ķ•˜ģ˜€ģœ¼ė‚˜, ģ ģ ˆķ•œ ģøģ¦ ė° ģ ‘ź·¼ģ œķ•œ ģ—†ģ“ ķŠ¹ģ • URLģ„ ķ†µķ•˜ģ—¬ 결제 ꓀련 정볓가 모두 ķ‰ė¬øģœ¼ė”œ ģ „ģ†”ė˜ėŠ” 경우","사딀 2 : ģ „ģžź²°ģ œėŒ€ķ–‰ģ—…ģ²“ģ™€ 외부 연계 ģ‹œģŠ¤ķ…œģ“ ģ „ģš©ė§ģœ¼ė”œ ģ—°ź²°ė˜ģ–“ ģžˆģœ¼ė‚˜, 핓당 연계 ģ‹œģŠ¤ķ…œģ—ģ„œ ė‚“ė¶€ 업묓 ģ‹œģŠ¤ķ…œģœ¼ė”œģ˜ ģ ‘ź·¼ģ“ ģ¹Øģž…ģ°Øė‹Øģ‹œģŠ¤ķ…œ ė“±ģœ¼ė”œ ģ ģ ˆķžˆ ķ†µģ œė˜ģ§€ ģ•Šź³  ģžˆėŠ” 경우","사딀 3 : ė‚“ė¶€ ģ§€ģ¹Øģ—ėŠ” 외부 ķ•€ķ…Œķ¬ ģ„œė¹„ģŠ¤ 연계 ģ‹œ ģ •ė³“ė³“ķ˜øķŒ€ģ˜ ė³“ģ•ˆģ„± 검토넼 ė°›ė„ė” ė˜ģ–“ ģžˆģœ¼ė‚˜, ģµœź·¼ģ— ģ‹ ź·œ ķ•€ķ…Œķ¬ ģ„œė¹„ģŠ¤ė„¼ ģ—°ź³„ķ•˜ė©“ģ„œ ģ¼ģ •ģƒ ģ“ģœ ė”œ ė³“ģ•ˆģ„± 검토넼 ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "ģ „ģžź±°ėž˜ ė° ķ•€ķ…Œķ¬ ģ„œė¹„ģŠ¤ 제공 ģ‹œ ģ •ė³“ģœ ģ¶œģ“ė‚˜ ė°ģ“ķ„° ģ”°ģž‘Ā·ģ‚¬źø° ė“±ģ˜ 침핓사고 ģ˜ˆė°©ģ„ ģœ„ķ•˜ģ—¬ ģøģ¦Ā·ģ•”ķ˜øķ™” ė“±ģ˜ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³ , ź²°ģ œģ‹œģŠ¤ķ…œ 등 외부 ģ‹œģŠ¤ķ…œź³¼ 연계할 경우 ģ•ˆģ „ģ„±ģ„ ģ ź²€ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.10.5": {"name": "정볓전솔 ė³“ģ•ˆ","checks": {"elb_ssl_listeners": "FAIL","elbv2_ssl_listeners": "FAIL","elb_insecure_ssl_ciphers": "PASS","elbv2_insecure_ssl_ciphers": "PASS","rds_instance_transport_encrypted": "FAIL","s3_bucket_secure_transport_policy": "FAIL","glue_database_connections_ssl_enabled": null,"cloudfront_distributions_https_enabled": null,"sns_subscription_not_using_http_endpoints": "PASS","kafka_cluster_in_transit_encryption_enabled": null,"apigateway_restapi_client_certificate_enabled": "FAIL","kafka_cluster_mutual_tls_authentication_enabled": null,"directoryservice_radius_server_security_protocol": null,"cloudfront_distributions_using_deprecated_ssl_protocols": null,"elasticache_redis_cluster_in_transit_encryption_enabled": null,"opensearch_service_domains_https_communications_enforced": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.5 정볓전솔 ė³“ģ•ˆ","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["정볓전솔 ķ˜‘ģ•½ģ„œ ė˜ėŠ” ź³„ģ•½ģ„œ","정볓전솔 źø°ģˆ ķ‘œģ¤€","정볓전솔 ꓀련 źµ¬ģ„±ė„, ģøķ„°ķŽ˜ģ“ģŠ¤ ģ •ģ˜ģ„œ"],"AuditChecklist": ["외부 씰직에 ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ė„¼ 전솔할 경우 ģ•ˆģ „ķ•œ 전솔 ģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?","ģ—…ė¬“ģƒ 씰직 ź°„ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ė„¼ ģƒķ˜øźµķ™˜ķ•˜ėŠ” 경우 ģ•ˆģ „ķ•œ ģ „ģ†”ģ„ ģœ„ķ•œ ķ˜‘ģ•½ģ²“ź²° 등 ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ėŒ€ģ™ø 기꓀과 연계 ģ‹œ ģ „ģš©ė§ ė˜ėŠ” VPNģ„ ģ ģš©ķ•˜ź³  ģ¤‘ź³„ģ„œė²„ģ™€ ģøģ¦ģ„œ 적용 ė“±ģ„ ķ†µķ•˜ģ—¬ ģ•ˆģ „ķ•˜ź²Œ 정볓넼 ģ „ģ†”ķ•˜ź³  ģžˆģœ¼ė‚˜, 외부 기꓀별 연계 ģ‹œźø°, ė°©ģ‹, ė‹“ė‹¹ģž ė° ģ±…ģž„ģž, 연계 정볓, 법적 근거 등에 ėŒ€ķ•œ ķ˜„ķ™©ź“€ė¦¬ź°€ ģ ģ ˆķžˆ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šź³  ģžˆėŠ” 경우","사딀 2 : ģ¤‘ź³„ź³¼ģ •ģ—ģ„œģ˜ ģ•”ķ˜ø ķ•“ģ œ 구간 ė˜ėŠ” ģ·Øģ•½ķ•œ ģ•”ķ˜øķ™” ģ•Œź³ ė¦¬ģ¦˜(DES, 3DES) ģ‚¬ģš© 등에 ėŒ€ķ•œ ė³“ģ•ˆģ„± 검토, ė³“ģ•ˆķ‘œģ¤€ ė° ģ”°ģ¹˜ė°©ģ•ˆ 수립 등에 ėŒ€ķ•œ ķ˜‘ģ˜ź°€ ģ“ķ–‰ė˜ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "다넸 씰직에 ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ė„¼ 전솔할 경우 ģ•ˆģ „ķ•œ 전솔 ģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  씰직 ź°„ ķ•©ģ˜ė„¼ ķ†µķ•˜ģ—¬ ꓀리 ģ±…ģž„, 전솔방법, ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ 볓호넼 ģœ„ķ•œ 기술적 볓호씰치 ė“±ģ„ ķ˜‘ģ•½ķ•˜ź³  ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 5,"pass": 3,"total": 17,"manual": 0}},"2.10.6": {"name": "ģ—…ė¬“ģš© 단말기기 ė³“ģ•ˆ","checks": {"workspaces_volume_encryption_enabled": null,"appstream_fleet_maximum_session_duration": null,"appstream_fleet_session_disconnect_timeout": null,"workspaces_vpc_2private_1public_subnets_nat": null,"appstream_fleet_session_idle_disconnect_timeout": null,"appstream_fleet_default_internet_access_disabled": null},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.6 ģ—…ė¬“ģš© 단말기기 ė³“ģ•ˆ","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["ģ—…ė¬“ģš© 단말기 ė³“ģ•ˆķ†µģ œ 지침 ė° 절차","ģ—…ė¬“ģš© 단말기 ė“±ė”ķ˜„ķ™©","ģ—…ė¬“ģš© 단말기 ė³“ģ•ˆģ„¤ģ •","ģ—…ė¬“ģš© 단말기 źø°źø°ģøģ¦ ė° ģŠ¹ģø ģ“ė „","ģ—…ė¬“ģš© 단말기 ė³“ģ•ˆģ ź²€ ķ˜„ķ™©"],"AuditChecklist": ["PC, ė…øķŠøė¶, ź°€ģƒPC, ķƒœėø”ė¦æ 등 업묓에 ģ‚¬ģš©ė˜ėŠ” 단말기에 ėŒ€ķ•˜ģ—¬ źø°źø°ģøģ¦, ģŠ¹ģø, ģ ‘ź·¼ė²”ģœ„ 설정, źø°źø° ė³“ģ•ˆģ„¤ģ • ė“±ģ˜ ė³“ģ•ˆ ķ†µģ œ ģ •ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ—…ė¬“ģš© 단말기넼 ķ†µķ•˜ģ—¬ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ź°€ ģœ ģ¶œė˜ėŠ” ź²ƒģ„ ė°©ģ§€ķ•˜źø° ģœ„ķ•˜ģ—¬ ģžė£Œź³µģœ ķ”„ė”œź·øėžØ ģ‚¬ģš© źøˆģ§€, ź³µģœ ģ„¤ģ • ģ œķ•œ, ė¬“ģ„ ė§ ģ“ģš© ķ†µģ œ ė“±ģ˜ ģ •ģ±…ģ„ 수립 ė° ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ—…ė¬“ģš© ėŖØė°”ģ¼ źø°źø°ģ˜ 분실, ė„ė‚œ ė“±ģœ¼ė”œ ģøķ•œ ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“ģ˜ ģœ Ā·ė…øģ¶œģ„ ė°©ģ§€ķ•˜źø° ģœ„ķ•˜ģ—¬ ė³“ģ•ˆėŒ€ģ±…ģ„ ģ ģš©ķ•˜ź³  ģžˆėŠ”ź°€?","ģ—…ė¬“ģš© 단말기기에 ėŒ€ķ•œ ģ ‘ź·¼ķ†µģ œ ėŒ€ģ±…ģ˜ ģ ģ ˆģ„±ģ— ėŒ€ķ•˜ģ—¬ 주기적으딜 ģ ź²€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ—…ė¬“ģ ģø 목적으딜 ė…øķŠøė¶, ķƒœėø”ė¦æPC 등 ėŖØė°”ģ¼ 기기넼 ģ‚¬ģš©ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ—…ė¬“ģš© ėŖØė°”ģ¼ 기기에 ėŒ€ķ•œ ķ—ˆģš© 기준, ģ‚¬ģš© ė²”ģœ„, ģŠ¹ģø 절차, ģøģ¦ 방법 등에 ėŒ€ķ•œ ģ •ģ±…ģ“ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ėŖØė°”ģ¼ źø°źø° ė³“ģ•ˆź“€ė¦¬ ģ§€ģ¹Øģ—ģ„œėŠ” ėŖØė°”ģ¼ źø°źø°ģ˜ ģ—…ė¬“ģš© ģ‚¬ģš©ģ„ ģ›ģ¹™ģ ģœ¼ė”œ źøˆģ§€ķ•˜ź³  ķ•„ģš”ģ‹œ ģŠ¹ģø 절차넼 ķ†µķ•˜ģ—¬ ģ œķ•œėœ źø°ź°„ ė™ģ•ˆ ķ—ˆź°€ėœ ėŖØė°”ģ¼ 기기만 ģ‚¬ģš©ķ•˜ė„ė” ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, ķ—ˆź°€ėœ ėŖØė°”ģ¼ źø°źø°ź°€ ģ‹ė³„Ā·ź“€ė¦¬ė˜ģ§€ ģ•Šź³  ģŠ¹ģøė˜ģ§€ ģ•Šģ€ ėŖØė°”ģ¼ źø°źø°ģ—ģ„œė„ ė‚“ė¶€ ģ •ė³“ģ‹œģŠ¤ķ…œ ģ ‘ģ†ģ“ ź°€ėŠ„ķ•œ 경우","사딀 3 : ź°œģøģ •ė³“ ģ²˜ė¦¬ģ—…ė¬“ģ— ģ“ģš©ė˜ėŠ” ėŖØė°”ģ¼ 기기에 ėŒ€ķ•˜ģ—¬ ė¹„ė°€ė²ˆķ˜ø 설정 등 ė„ė‚œĀ·ė¶„ģ‹¤ģ— ėŒ€ķ•œ ė³“ķ˜øėŒ€ģ±…ģ“ ģ ģš©ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ė‚“ė¶€ ź·œģ •ģ—ģ„œėŠ” ģ—…ė¬“ģš© ė‹Øė§źø°ģ˜ ź³µģœ ķ“ė” ģ‚¬ģš©ģ„ źøˆģ§€ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•œ ģ£¼źø°ģ ģø ģ ź²€ģ“ ģ“ė£Øģ–“ģ§€ź³  ģžˆģ§€ ģ•Šģ•„ ė‹¤ģˆ˜ģ˜ ģ—…ė¬“ģš© ė‹Øė§źø°ģ—ģ„œ ź³¼ė„ķ•˜ź²Œ ź³µģœ ķ“ė”ė„¼ ģ„¤ģ •ķ•˜ģ—¬ ģ‚¬ģš©ķ•˜ź³  ģžˆėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "PC, ėŖØė°”ģ¼ źø°źø° 등 단말기기넼 업묓 목적으딜 ė„¤ķŠøģ›Œķ¬ģ— ģ—°ź²°ķ•  경우 źø°źø° ģøģ¦ ė° ģŠ¹ģø, ģ ‘ź·¼ ė²”ģœ„, źø°źø° ė³“ģ•ˆģ„¤ģ • ė“±ģ˜ ģ ‘ź·¼ķ†µģ œ ėŒ€ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  주기적으딜 ģ ź²€ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 6,"manual": 0}},"2.10.7": {"name": "ė³“ģ”°ģ €ģž„ė§¤ģ²“ ꓀리","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.7 ė³“ģ”°ģ €ģž„ė§¤ģ²“ ꓀리","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["ė³“ģ”°ģ €ģž„ė§¤ģ²“(USB, CD 등) 차단 ģ •ģ±…","ė³“ģ”°ģ €ģž„ė§¤ģ²“ ź“€ė¦¬ėŒ€ģž„","ė³“ģ”°ģ €ģž„ė§¤ģ²“ ģ‹¤ķƒœģ ź²€ ģ“ė „"],"AuditChecklist": ["ģ™øģž„ķ•˜ė“œ, USB메모리, CD 등 ė³“ģ”°ģ €ģž„ė§¤ģ²“ ģ·Øźø‰(ģ‚¬ģš©), 볓꓀, ķźø°, ģž¬ģ‚¬ģš©ģ— ėŒ€ķ•œ ģ •ģ±… ė° 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ģ”°ģ €ģž„ė§¤ģ²“ ė³“ģœ ķ˜„ķ™©, ģ‚¬ģš© ė° ź“€ė¦¬ģ‹¤ķƒœė„¼ 주기적으딜 ģ ź²€ķ•˜ź³  ģžˆėŠ”ź°€?","ģ£¼ģš” ģ •ė³“ģ‹œģŠ¤ķ…œģ“ ģœ„ģ¹˜ķ•œ ķ†µģ œźµ¬ģ—­, ģ¤‘ģš” ģ œķ•œźµ¬ģ—­ ė“±ģ—ģ„œ ė³“ģ”°ģ €ģž„ė§¤ģ²“ ģ‚¬ģš©ģ„ ģ œķ•œķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ģ”°ģ €ģž„ė§¤ģ²“ė„¼ ķ†µķ•œ ģ•…ģ„±ģ½”ė“œ 감염 ė° ģ¤‘ģš”ģ •ė³“ 유출 방지넼 ģœ„ķ•œ ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ ė˜ėŠ” ģ¤‘ģš”ģ •ė³“ź°€ ķ¬ķ•Øėœ ė³“ģ”°ģ €ģž„ė§¤ģ²“ė„¼ ģž źøˆģž„ģ¹˜ź°€ ģžˆėŠ” ģ•ˆģ „ķ•œ ģž„ģ†Œģ— ė³“ź“€ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ķ†µģ œźµ¬ģ—­ģø ģ„œė²„ģ‹¤ģ—ģ„œģ˜ ė³“ģ”°ģ €ģž„ė§¤ģ²“ ģ‚¬ģš©ģ„ ģ œķ•œķ•˜ėŠ” ģ •ģ±…ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ˜ˆģ™ø ģŠ¹ģø 절차넼 ģ¤€ģˆ˜ķ•˜ģ§€ ģ•Šź³  ė³“ģ”°ģ €ģž„ė§¤ģ²“ė„¼ ģ‚¬ģš©ķ•œ ģ“ė „ģ“ ė‹¤ģˆ˜ ķ™•ģøė˜ģ—ˆģœ¼ė©°, ė³“ģ”°ģ €ģž„ė§¤ģ²“ ź“€ė¦¬ģ‹¤ķƒœģ— ėŒ€ķ•œ 주기적 ģ ź²€ģ“ ģ‹¤ģ‹œė˜ģ§€ ģ•Šģ•„ ė³“ģ”°ģ €ģž„ė§¤ģ²“ ź“€ė¦¬ėŒ€ģž„ģ˜ ķ˜„ķ–‰ķ™”ź°€ ėÆøķ”ķ•œ 경우","사딀 2 : ź°œģøģ •ė³“ź°€ ķ¬ķ•Øėœ ė³“ģ”°ģ €ģž„ė§¤ģ²“ė„¼ ģž źøˆģž„ģ¹˜ź°€ ģžˆėŠ” ģ•ˆģ „ķ•œ ģž„ģ†Œģ— ė³“ź“€ķ•˜ģ§€ ģ•Šź³  사묓실 ģ„œėž 등에 ė°©ģ¹˜ķ•˜ź³  ģžˆėŠ” 경우","사딀 3 : ė³“ģ”°ģ €ģž„ė§¤ģ²“ ķ†µģ œ ģ†”ė£Øģ…˜ģ„ ė„ģž…Ā·ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ¼ė¶€ ģ‚¬ģš©ģžģ— ėŒ€ķ•˜ģ—¬ ģ ģ ˆķ•œ ģŠ¹ģø 절차 ģ—†ģ“ ģ˜ˆģ™øģ²˜ė¦¬ė˜ģ–“ ģ“°źø° ė“±ģ“ ķ—ˆģš©ėœ 경우","사딀 4 : 전산실에 ģœ„ģ¹˜ķ•œ ģ¼ė¶€ 공용 PC ė° ģ „ģ‚°ģž„ė¹„ģ—ģ„œ ģ¼ė°˜ USB메모리에 ėŒ€ķ•œ ģ“°źø°ź°€ ź°€ėŠ„ķ•œ ģƒķ™©ģ“ė‚˜ 매첓 ė°˜ģž… ė° ģ‚¬ģš© ģ œķ•œ, ģ‚¬ģš©ģ“ė „ źø°ė” ė° 검토 등 ķ†µģ œź°€ 적용되고 ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제10ģ”°(물리적 ģ•ˆģ „ģ”°ģ¹˜)"]}],"description": "ė³“ģ”°ģ €ģž„ė§¤ģ²“ė„¼ ķ†µķ•˜ģ—¬ ź°œģøģ •ė³“ ė˜ėŠ” ģ¤‘ģš”ģ •ė³“ģ˜ ģœ ģ¶œģ“ ė°œģƒķ•˜ź±°ė‚˜ ģ•…ģ„±ģ½”ė“œź°€ ź°ģ—¼ė˜ģ§€ ģ•Šė„ė” ꓀리 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ , ź°œģøģ •ė³“ ė˜ėŠ” ģ¤‘ģš”ģ •ė³“ź°€ ķ¬ķ•Øėœ ė³“ģ”°ģ €ģž„ ė§¤ģ²“ėŠ” ģ•ˆģ „ķ•œ ģž„ģ†Œģ— ė³“ź“€ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.10.8": {"name": "ķŒØģ¹˜ź“€ė¦¬","checks": {"ssm_managed_compliant_patching": "FAIL","kafka_cluster_uses_latest_version": null,"ec2_instance_account_imdsv2_enabled": null,"redshift_cluster_automatic_upgrades": null,"eks_cluster_uses_a_supported_version": null,"ec2_instance_older_than_specific_days": "FAIL","rds_instance_deprecated_engine_version": "PASS","rds_cluster_minor_version_upgrade_enabled": "PASS","dms_instance_minor_version_upgrade_enabled": null,"rds_instance_minor_version_upgrade_enabled": "PASS","awslambda_function_using_supported_runtimes": "FAIL","elasticache_redis_cluster_auto_minor_version_upgrades": null,"cloudfront_distributions_using_deprecated_ssl_protocols": null,"opensearch_service_domains_updated_to_the_latest_service_software_version": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.8 ķŒØģ¹˜ź“€ė¦¬","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["패치 적용 ꓀리 ģ •ģ±…Ā·ģ ˆģ°Ø","ģ‹œģŠ¤ķ…œė³„ 패치 적용 ķ˜„ķ™©","패치 적용 ꓀련 ģ˜ķ–„ė„ ė¶„ģ„ ź²°ź³¼"],"AuditChecklist": ["ģ„œė²„, ė„¤ķŠøģ›Œķ¬ģ‹œģŠ¤ķ…œ, ė³“ģ•ˆģ‹œģŠ¤ķ…œ, PC 등 ģžģ‚°ė³„ ķŠ¹ģ„± ė° ģ¤‘ģš”ė„ģ— ė”°ė¼ 욓영첓제(OS)와 ģ†Œķ”„ķŠøģ›Øģ–“ģ˜ ķŒØģ¹˜ź“€ė¦¬ ģ •ģ±… ė° 절차넼 ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ£¼ģš” ģ„œė²„, ė„¤ķŠøģ›Œķ¬ģ‹œģŠ¤ķ…œ, ė³“ģ•ˆģ‹œģŠ¤ķ…œ ė“±ģ˜ 경우 ģ„¤ģ¹˜ėœ OS, ģ†Œķ”„ķŠøģ›Øģ–“ 패치 적용 ķ˜„ķ™©ģ„ 주기적으딜 ź“€ė¦¬ķ•˜ź³  ģžˆėŠ”ź°€?","ģ„œė¹„ģŠ¤ ģ˜ķ–„ė„ 등에 ė”°ė¼ ģ·Øģ•½ģ ģ„ ģ”°ģ¹˜ķ•˜źø° ģœ„ķ•œ ģµœģ‹ ģ˜ 패치 ģ ģš©ģ“ ģ–“ė ¤ģš“ 경우 ė³“ģ™„ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","ģ£¼ģš” ģ„œė²„, ė„¤ķŠøģ›Œķ¬ģ‹œģŠ¤ķ…œ, ė³“ģ•ˆģ‹œģŠ¤ķ…œ ė“±ģ˜ 경우 공개 ģøķ„°ė„· ģ ‘ģ†ģ„ ķ†µķ•œ 패치넼 ģ œķ•œķ•˜ź³  ģžˆėŠ”ź°€?","ķŒØģ¹˜ź“€ė¦¬ģ‹œģŠ¤ķ…œģ„ ķ™œģš©ķ•˜ėŠ” 경우 ģ ‘ź·¼ķ†µģ œ 등 ģ¶©ė¶„ķ•œ ė³“ķ˜øėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ¼ė¶€ ģ‹œģŠ¤ķ…œģ—ģ„œ ķƒ€ė‹¹ķ•œ ģ‚¬ģœ ė‚˜ ģ±…ģž„ģž ģŠ¹ģø ģ—†ģ“ OSķŒØģ¹˜ź°€ ģž„źø°ź°„ 적용되고 ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ģ¼ė¶€ ģ‹œģŠ¤ķ…œģ— ģ„œė¹„ģŠ¤ ģ§€ģ›ģ“ ģ¢…ė£Œ(EOS)된 OSė²„ģ „ģ„ ģ‚¬ģš© ģ¤‘ģ“ė‚˜, ģ“ģ— 따넸 ėŒ€ģ‘ź³„ķšģ“ė‚˜ ė³“ģ™„ėŒ€ģ±…ģ“ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : 상용 ģ†Œķ”„ķŠøģ›Øģ–“ ė° OS에 ėŒ€ķ•“ģ„œėŠ” ģµœģ‹  ķŒØģ¹˜ź°€ 적용되고 ģžˆģœ¼ė‚˜, ģ˜¤ķ”ˆģ†ŒģŠ¤ ķ”„ė”œź·øėžØ(openssl, openssh, Apache 등)에 ėŒ€ķ•“ģ„œėŠ” ģµœģ‹  패치넼 ķ™•ģøķ•˜ź³  ģ ģš©ķ•˜ėŠ” 절차 ė° ė‹“ė‹¹ģžź°€ ģ§€ģ •ė˜ģ–“ ģžˆģ§€ ģ•Šģ•„ ģµœģ‹  ė³“ģ•ˆķŒØģ¹˜ź°€ 적용되고 ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제9ģ”°(ģ•…ģ„±ķ”„ė”œź·øėžØ 등 ė°©ģ§€)"]}],"description": "ģ†Œķ”„ķŠøģ›Øģ–“, 욓영첓제, ė³“ģ•ˆģ‹œģŠ¤ķ…œ ė“±ģ˜ ģ·Øģ•½ģ ģœ¼ė”œ ģøķ•œ 침핓사고넼 ģ˜ˆė°©ķ•˜źø° ģœ„ķ•˜ģ—¬ ģµœģ‹  패치넼 ģ ģš©ķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ė‹¤ė§Œ ģ„œė¹„ģŠ¤ ģ˜ķ–„ģ„ ź²€ķ† ķ•˜ģ—¬ ģµœģ‹  패치 ģ ģš©ģ“ ģ–“ė ¤ģšø 경우 ė³„ė„ģ˜ ė³“ģ™„ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ģ—¬ ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 3,"pass": 3,"total": 14,"manual": 0}},"2.10.9": {"name": "ģ•…ģ„±ģ½”ė“œ ķ†µģ œ","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.10.9 ģ•…ģ„±ģ½”ė“œ ķ†µģ œ","Subdomain": "2.10. ģ‹œģŠ¤ķ…œ ė° ģ„œė¹„ģŠ¤ ė³“ģ•ˆź“€ė¦¬","AuditEvidence": ["ģ•…ģ„±ķ”„ė”œź·øėžØ ėŒ€ģ‘ ģ§€ģ¹ØĀ·ģ ˆģ°ØĀ·ė§¤ė‰“ģ–¼","ė°±ģ‹ ķ”„ė”œź·øėžØ ģ„¤ģ¹˜ ķ˜„ķ™©","ė°±ģ‹ ķ”„ė”œź·øėžØ 설정 화멓","ģ•…ģ„±ķ”„ė”œź·øėžØ ėŒ€ģ‘ ģ“ė „(ėŒ€ģ‘ ė³“ź³ ģ„œ 등)"],"AuditChecklist": ["ė°”ģ“ėŸ¬ģŠ¤, ģ›œ, ķŠøė”œģ“ėŖ©ė§ˆ, ėžœģ„¬ģ›Øģ–“ ė“±ģ˜ ģ•…ģ„±ģ½”ė“œė”œė¶€ķ„° ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ģ—…ė¬“ģš©ė‹Øė§źø° ė“±ģ„ ė³“ķ˜øķ•˜źø° ģœ„ķ•˜ģ—¬ ė³“ķ˜øėŒ€ģ±…ģ„ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","백신 ģ†Œķ”„ķŠøģ›Øģ–“ 등 ė³“ģ•ˆķ”„ė”œź·øėžØģ„ ķ†µķ•˜ģ—¬ ģµœģ‹  ģ•…ģ„±ģ½”ė“œ ģ˜ˆė°©Ā·ķƒģ§€ ķ™œė™ģ„ ģ§€ģ†ģ ģœ¼ė”œ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","백신 ģ†Œķ”„ķŠøģ›Øģ–“ 등 ė³“ģ•ˆķ”„ė”œź·øėžØģ€ ģµœģ‹ ģ˜ 상태딜 ģœ ģ§€ķ•˜ź³  ķ•„ģš”ģ‹œ źø“źø‰ ė³“ģ•ˆ ģ—…ė°ģ“ķŠøė„¼ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ•…ģ„±ģ½”ė“œ 감염 발견 ģ‹œ ģ•…ģ„±ģ½”ė“œ 확산 ė° 피핓 ģµœģ†Œķ™” ė“±ģ˜ ėŒ€ģ‘ģ ˆģ°Øė„¼ ģˆ˜ė¦½Ā·ģ“ķ–‰ķ•˜ź³ ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ¼ė¶€ PC ė° ģ„œė²„ģ— ė°±ģ‹ ģ“ ģ„¤ģ¹˜ė˜ģ–“ ģžˆģ§€ ģ•Šź±°ė‚˜, 백신 ģ—”ģ§„ģ“ ģž„źø°ź°„ ģµœģ‹  ė²„ģ „ģœ¼ė”œ ģ—…ė°ģ“ķŠøė˜ģ§€ ģ•Šģ€ 경우","사딀 2 : 백신 ķ”„ė”œź·øėžØģ˜ ķ™˜ź²½ģ„¤ģ •(ģ‹¤ģ‹œź°„ 검사, ģ˜ˆģ•½ź²€ģ‚¬, ģ—…ė°ģ“ķŠø 설정 등)ģ„ ģ“ģš©ģžź°€ ģž„ģ˜ė”œ 변경할 수 ģžˆģŒģ—ė„ 그에 따넸 추가 ė³“ķ˜øėŒ€ģ±…ģ“ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : 백신 ģ¤‘ģ•™ź“€ė¦¬ģ‹œģŠ¤ķ…œģ— ģ ‘ź·¼ķ†µģ œ 등 ė³“ķ˜øėŒ€ģ±…ģ“ ėÆøė¹„ķ•˜ģ—¬ ģ¤‘ģ•™ź“€ė¦¬ģ‹œģŠ¤ķ…œģ„ ķ†µķ•œ ģ¹Øķ•“ģ‚¬ź³ ė°œģƒ ź°€ėŠ„ģ„±ģ“ ģžˆėŠ” 경우 ė˜ėŠ” 백신 ķŒØķ„“ģ— ėŒ€ķ•œ 묓결성 ź²€ģ¦ģ„ ķ•˜ģ§€ ģ•Šģ•„ ģ•…ģ˜ģ ģø ģ‚¬ģš©ģžģ— ģ˜ķ•œ ģ•…ģ„±ģ½”ė“œ ģ „ķŒŒ ź°€ėŠ„ģ„±ģ“ ģžˆėŠ” 경우","사딀 4 : ģ¼ė¶€ ė‚“ė¶€ė§ PC ė° ģ„œė²„ģ—ģ„œ ė‹¤ģˆ˜ģ˜ ģ•…ģ„±ģ½”ė“œ ź°ģ—¼ģ“ė „ģ“ ķ™•ģøė˜ģ—ˆģœ¼ė‚˜, 감염 ķ˜„ķ™©, 감염 경딜 ė° ģ›ģø ė¶„ģ„, 그에 따넸 ģ”°ģ¹˜ė‚“ģ—­ ė“±ģ“ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제9ģ”°(ģ•…ģ„±ķ”„ė”œź·øėžØ 등 ė°©ģ§€)"]}],"description": "ė°”ģ“ėŸ¬ģŠ¤Ā·ģ›œĀ·ķŠøė”œģ“ėŖ©ė§ˆĀ·ėžœģ„¬ģ›Øģ–“ ė“±ģ˜ ģ•…ģ„±ģ½”ė“œė”œė¶€ķ„° ź°œģøģ •ė³“ ė° ģ¤‘ģš”ģ •ė³“, ģ •ė³“ģ‹œģŠ¤ķ…œ ė° ģ—…ė¬“ģš© 단말기 ė“±ģ„ ė³“ķ˜øķ•˜źø° ģœ„ķ•˜ģ—¬ ģ•…ģ„±ģ½”ė“œ ģ˜ˆė°©Ā·ķƒģ§€Ā·ėŒ€ģ‘ ė“±ģ˜ ė³“ķ˜øėŒ€ģ±…ģ„ 수립 ė° ģ“ķ–‰ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.11.1": {"name": "사고 예방 ė° ėŒ€ģ‘ģ²“ź³„ 구축","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.11.1 사고 예방 ė° ėŒ€ģ‘ģ²“ź³„ 구축","Subdomain": "2.11. 사고 예방 ė° ėŒ€ģ‘","AuditEvidence": ["침핓사고 ėŒ€ģ‘ ģ§€ģ¹ØĀ·ģ ˆģ°ØĀ·ė§¤ė‰“ģ–¼","침핓사고 ėŒ€ģ‘ ģ”°ģ§ė„ ė° ė¹„ģƒģ—°ė½ė§","ė³“ģ•ˆź“€ģ œģ„œė¹„ģŠ¤ ź³„ģ•½ģ„œ(SLA 등)"],"AuditChecklist": ["침핓사고 ė° ź°œģøģ •ė³“ ģœ ģ¶œģ‚¬ź³ ė„¼ ģ˜ˆė°©ķ•˜ź³  사고 ė°œģƒ ģ‹œ ģ‹ ģ†ķ•˜ź³  효과적으딜 ėŒ€ģ‘ķ•˜źø° ģœ„ķ•œ 첓계와 절차넼 ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?","ė³“ģ•ˆź“€ģ œģ„œė¹„ģŠ¤ 등 외부 źø°ź“€ģ„ ķ†µķ•˜ģ—¬ 침핓사고 ėŒ€ģ‘ģ²“ź³„ė„¼ źµ¬ģ¶•Ā·ģš“ģ˜ķ•˜ėŠ” 경우 침핓사고 ėŒ€ģ‘ģ ˆģ°Øģ˜ ģ„øė¶€ģ‚¬ķ•­ģ„ ź³„ģ•½ģ„œģ— ė°˜ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ģ¹Øķ•“ģ‚¬ź³ ģ˜ ėŖØė‹ˆķ„°ė§, ėŒ€ģ‘ ė° 처리넼 ģœ„ķ•˜ģ—¬ 외부전문가, 전문업첓, 전문기꓀ ė“±ź³¼ģ˜ ķ˜‘ģ”°ģ²“ź³„ė„¼ ģˆ˜ė¦½ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 침핓사고에 ėŒ€ė¹„ķ•œ 침핓사고 ėŒ€ģ‘ 씰직 ė° ėŒ€ģ‘ 절차넼 ėŖ…ķ™•ķžˆ ģ •ģ˜ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : ė‚“ė¶€ 지침 ė° ģ ˆģ°Øģ— 침핓사고 단계별(사고 ģ „, ģøģ§€, 처리, 복구, 볓고 등) ėŒ€ģ‘ 절차넼 ģˆ˜ė¦½ķ•˜ģ—¬ ėŖ…ģ‹œķ•˜ź³  ģžˆģœ¼ė‚˜, 침핓사고 ė°œģƒ ģ‹œ 사고 ģœ ķ˜• ė° ģ‹¬ź°ė„ģ— 따넸 신고·통지 절차, ėŒ€ģ‘ ė° 복구 ģ ˆģ°Øģ˜ ģ¼ė¶€ ė˜ėŠ” 전부넼 ģˆ˜ė¦½ķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : 침핓사고 ėŒ€ģ‘ ģ”°ģ§ė„ ė° ė¹„ģƒģ—°ė½ė§ ė“±ģ„ ķ˜„ķ–‰ķ™”ķ•˜ģ§€ ģ•Šź³  ģžˆź±°ė‚˜, ė‹“ė‹¹ģžė³„ ģ—­ķ• ź³¼ ģ±…ģž„ģ“ ėŖ…ķ™•ķžˆ ģ •ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : 침핓사고 신고·통지 ė° ėŒ€ģ‘ ķ˜‘ģ”°ė„¼ ģœ„ķ•œ ėŒ€ģ™øźø°ź“€ ģ—°ė½ģ²˜ģ— 기꓀명, ķ™ˆķŽ˜ģ“ģ§€, ģ—°ė½ģ²˜ ė“±ģ“ ģž˜ėŖ» ėŖ…ģ‹œė˜ģ–“ ģžˆź±°ė‚˜, ģ¼ė¶€ źø°ź“€ ꓀련 정볓가 ėˆ„ė½ ė˜ėŠ” ķ˜„ķ–‰ķ™”ė˜ģ§€ ģ•Šģ€ 경우","사딀 5 : 외부 ė³“ģ•ˆź“€ģ œ 전문업첓 등 ģœ ź“€źø°ź“€ģ— 침핓사고 ķƒģ§€ ė° ėŒ€ģ‘ģ„ ģœ„ķƒķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, 침핓사고 ėŒ€ģ‘ģ— ėŒ€ķ•œ 상호 ź°„ ꓀련 ģ—­ķ•  ė° ģ±…ģž„ ė²”ģœ„ź°€ ź³„ģ•½ģ„œė‚˜ SLA에 ėŖ…ķ™•ķ•˜ź²Œ ģ •ģ˜ė˜ģ§€ ģ•Šģ€ 경우","사딀 6 : 침핓사고 ėŒ€ģ‘ģ ˆģ°Øė„¼ ģˆ˜ė¦½ķ•˜ģ˜€ģœ¼ė‚˜, ź°œģøģ •ė³“ 침핓 ģ‹ ź³  기준, ģ‹œģ  ė“±ģ“ 법적 ģš”źµ¬ģ‚¬ķ•­ģ„ ģ¤€ģˆ˜ķ•˜ģ§€ ėŖ»ķ•˜ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제34ģ”°(ź°œģøģ •ė³“ģ˜ 유출 ė“±ģ˜ 통지·신고)","ģ •ė³“ķ†µģ‹ ė§ė²• 제48ģ”°ģ˜3(ģ¹Øķ•“ģ‚¬ź³ ģ˜ ģ‹ ź³  등), 제48ģ”°ģ˜4(ģ¹Øķ•“ģ‚¬ź³ ģ˜ ģ›ģøė¶„ģ„ 등)"]}],"description": "침핓사고 ė° ź°œģøģ •ė³“ 유출 ė“±ģ„ ģ˜ˆė°©ķ•˜ź³  사고 ė°œģƒ ģ‹œ ģ‹ ģ†ķ•˜ź³  효과적으딜 ėŒ€ģ‘ķ•  수 ģžˆė„ė” 낓·외부 ģ¹Øķ•“ģ‹œė„ģ˜ ķƒģ§€Ā·ėŒ€ģ‘Ā·ė¶„ģ„ ė° 공유넼 ģœ„ķ•œ 첓계와 절차넼 ģˆ˜ė¦½ķ•˜ź³ , ꓀련 외부기꓀ ė° 전문가들과 ķ˜‘ģ”°ģ²“ź³„ė„¼ źµ¬ģ¶•ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.11.2": {"name": "취약점 점검 ė° 씰치","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","ssm_document_secrets": "PASS","inspector2_is_enabled": "FAIL","ec2_instance_imdsv2_enabled": "PASS","guardduty_centrally_managed": "FAIL","ec2_instance_secrets_user_data": "PASS","ec2_launch_template_no_secrets": "PASS","inspector2_active_findings_exist": "FAIL","trustedadvisor_errors_and_warnings": null,"guardduty_no_high_severity_findings": "FAIL","awslambda_function_no_secrets_in_code": "PASS","cloudwatch_log_group_no_secrets_in_logs": "FAIL","ecr_registry_scan_images_on_push_enabled": "PASS","cloudformation_stack_outputs_find_secrets": "PASS","codebuild_project_no_secrets_in_variables": "PASS","awslambda_function_no_secrets_in_variables": "PASS","ecs_task_definitions_no_environment_secrets": "PASS","ecr_repositories_scan_images_on_push_enabled": "FAIL","trustedadvisor_premium_support_plan_subscribed": null,"autoscaling_find_secrets_ec2_launch_configuration": "PASS","ecr_repositories_scan_vulnerabilities_in_latest_image": null,"codebuild_project_source_repo_url_no_sensitive_credentials": "PASS"},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.11.2 취약점 점검 ė° 씰치","Subdomain": "2.11. 사고 예방 ė° ėŒ€ģ‘","AuditEvidence": ["취약점 점검 ź³„ķšģ„œ","취약점 점검 ź²°ź³¼ė³“ź³ ģ„œ(웹, ėŖØė°”ģ¼ 앱, ģ„œė²„, ė„¤ķŠøģ›Œķ¬ģ‹œģŠ¤ķ…œ, ė³“ģ•ˆģ‹œģŠ¤ķ…œ, DBMS 등)","취약점 점검 ģ“ė „","취약점 ģ”°ģ¹˜ź³„ķšģ„œ","취약점 ģ”°ģ¹˜ģ™„ė£Œė³“ź³ ģ„œ","ėŖØģ˜ķ•“ķ‚¹ ź³„ķšģ„œĀ·ź²°ź³¼ė³“ź³ ģ„œ"],"AuditChecklist": ["ģ •ė³“ģ‹œģŠ¤ķ…œ 취약점 점검 절차넼 ģˆ˜ė¦½ķ•˜ź³ , ģ •źø°ģ ģœ¼ė”œ ģ ź²€ģ„ ģˆ˜ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","발견된 취약점에 ėŒ€ķ•œ 씰치넼 ģˆ˜ķ–‰ķ•˜ź³ , ź·ø 결과넼 ģ±…ģž„ģžģ—ź²Œ ė³“ź³ ķ•˜ź³  ģžˆėŠ”ź°€?","ģµœģ‹  ė³“ģ•ˆģ·Øģ•½ģ  ė°œģƒ 여부넼 ģ§€ģ†ģ ģœ¼ė”œ ķŒŒģ•…ķ•˜ź³ , ģ •ė³“ģ‹œģŠ¤ķ…œģ— ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ė¶„ģ„ķ•˜ģ—¬ ģ”°ģ¹˜ķ•˜ź³  ģžˆėŠ”ź°€?","취약점 점검 ģ“ė „ģ„ źø°ė”ź“€ė¦¬ķ•˜ģ—¬ ģ „ė…„ė„ģ— ė„ģ¶œėœ ģ·Øģ•½ģ ģ“ ģž¬ė°œģƒķ•˜ėŠ” ė“±ģ˜ ė¬øģ œģ ģ— ėŒ€ķ•˜ģ—¬ ė³“ķ˜øėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ ź·œģ •ģ— ģ—° 1회 ģ“ģƒ ģ£¼ģš” ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ 기술적 취약점 ģ ź²€ģ„ ķ•˜ė„ė” ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, ģ£¼ģš” ģ‹œģŠ¤ķ…œ 중 ģ¼ė¶€ź°€ 취약점 점검 ėŒ€ģƒģ—ģ„œ ėˆ„ė½ėœ 경우","사딀 2 : 취약점 ģ ź²€ģ—ģ„œ 발견된 취약점에 ėŒ€ķ•œ ė³“ģ™„ģ”°ģ¹˜ė„¼ ģ“ķ–‰ķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜, 단기간 낓에 ģ”°ģ¹˜ķ•  수 ģ—†ėŠ” 취약점에 ėŒ€ķ•œ ķƒ€ė‹¹ģ„± 검토 ė° ģŠ¹ģø ģ“ė „ģ“ ģ—†ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제4ģ”°(ė‚“ė¶€ ź“€ė¦¬ź³„ķšģ˜ ģˆ˜ė¦½Ā·ģ‹œķ–‰ ė° 점검), 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ·Øģ•½ģ ģ“ ė…øģ¶œė˜ģ–“ ģžˆėŠ”ģ§€ė„¼ ķ™•ģøķ•˜źø° ģœ„ķ•˜ģ—¬ ģ •źø°ģ ģœ¼ė”œ 취약점 ģ ź²€ģ„ ģˆ˜ķ–‰ķ•˜ź³ , 발견된 취약점에 ėŒ€ķ•“ģ„œėŠ” ģ‹ ģ†ķ•˜ź²Œ ģ”°ģ¹˜ķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ė˜ķ•œ ģµœģ‹  ė³“ģ•ˆģ·Øģ•½ģ ģ˜ ė°œģƒ 여부넼 ģ§€ģ†ģ ģœ¼ė”œ ķŒŒģ•…ķ•˜ź³ , ģ •ė³“ģ‹œģŠ¤ķ…œģ— ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ė¶„ģ„ķ•˜ģ—¬ ģ”°ģ¹˜ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 6,"pass": 14,"total": 23,"manual": 0}},"2.11.3": {"name": "ģ“ģƒķ–‰ģœ„ ė¶„ģ„ ė° ėŖØė‹ˆķ„°ė§","checks": {"securityhub_enabled": "PASS","fms_policy_compliant": null,"vpc_flow_logs_enabled": "FAIL","cloudtrail_insights_exist": null,"networkfirewall_in_all_vpc": "FAIL","trustedadvisor_errors_and_warnings": null,"guardduty_no_high_severity_findings": "FAIL","cloudtrail_threat_detection_enumeration": null,"cloudwatch_log_group_no_secrets_in_logs": "FAIL","cloudwatch_log_metric_filter_root_usage": null,"cloudwatch_cross_account_sharing_disabled": null,"cloudwatch_changes_to_vpcs_alarm_configured": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","cloudwatch_log_metric_filter_policy_changes": null,"cloudwatch_log_metric_filter_sign_in_without_mfa": null,"cloudwatch_changes_to_network_acls_alarm_configured": null,"cloudwatch_log_metric_filter_security_group_changes": null,"cloudwatch_log_metric_filter_unauthorized_api_calls": null,"cloudwatch_log_metric_filter_authentication_failures": null,"cloudwatch_log_metric_filter_aws_organizations_changes": null,"cognito_user_pool_client_prevent_user_existence_errors": null,"cloudwatch_changes_to_network_gateways_alarm_configured": null,"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null,"cloudwatch_changes_to_network_route_tables_alarm_configured": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null,"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null,"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.11.3 ģ“ģƒķ–‰ģœ„ ė¶„ģ„ ė° ėŖØė‹ˆķ„°ė§","Subdomain": "2.11. 사고 예방 ė° ėŒ€ģ‘","AuditEvidence": ["ģ“ģƒķ–‰ģœ„ ė¶„ģ„ ė° ėŖØė‹ˆķ„°ė§ ķ˜„ķ™©","ģ“ģƒķ–‰ģœ„ 발견 ģ‹œ ėŒ€ģ‘ ģ¦ź±°ģžė£Œ"],"AuditChecklist": ["낓·외부에 ģ˜ķ•œ ģ¹Øķ•“ģ‹œė„, ź°œģøģ •ė³“ģœ ģ¶œ ģ‹œė„, ė¶€ģ •ķ–‰ģœ„ 등 ģ“ģƒķ–‰ģœ„ė„¼ ķƒģ§€ķ•  수 ģžˆė„ė” ģ£¼ģš” ģ •ė³“ģ‹œģŠ¤ķ…œ, ģ‘ģš©ķ”„ė”œź·øėžØ, ė„¤ķŠøģ›Œķ¬, ė³“ģ•ˆģ‹œģŠ¤ķ…œ ė“±ģ—ģ„œ ė°œģƒķ•œ ė„¤ķŠøģ›Œķ¬ ķŠøėž˜ķ”½,ė°ģ“ķ„° ķė¦„, ģ“ė²¤ķŠø 딜그 ė“±ģ„ ģˆ˜ģ§‘ķ•˜ģ—¬ ė¶„ģ„ ė° ėŖØė‹ˆķ„°ė§ķ•˜ź³  ģžˆėŠ”ź°€?","ģ¹Øķ•“ģ‹œė„, ź°œģøģ •ė³“ģœ ģ¶œģ‹œė„, ė¶€ģ •ķ–‰ģœ„ ė“±ģ˜ 여부넼 ķŒė‹Øķ•˜źø° ģœ„ķ•œ 기준 ė° ģž„ź³„ģ¹˜ė„¼ ģ •ģ˜ķ•˜ź³  ģ“ģ— ė”°ė¼ ģ“ģƒķ–‰ģœ„ģ˜ ķŒė‹Ø ė° 씰사 등 ķ›„ģ† ģ”°ģ¹˜ź°€ ģ ģ‹œģ— ģ“ė£Øģ–“ģ§€ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģ™øė¶€ė”œė¶€ķ„°ģ˜ ģ„œė²„, ė„¤ķŠøģ›Œķ¬, ė°ģ“ķ„°ė² ģ“ģŠ¤, ė³“ģ•ˆģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ 침핓 ģ‹œė„ė„¼ ģøģ§€ķ•  수 ģžˆė„ė” ķ•˜ėŠ” ģƒģ‹œ ė˜ėŠ” 정기적 ėŖØė‹ˆķ„°ė§ 첓계 ė° 절차넼 ė§ˆė Øķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 2 : 외부 ė³“ģ•ˆź“€ģ œ 전문업첓 등 외부 기꓀에 ģ¹Øķ•“ģ‹œė„ ėŖØė‹ˆķ„°ė§ 업묓넼 ģœ„ķƒķ•˜ź³  ģžˆģœ¼ė‚˜, ģœ„ķƒģ—…ģ²“ź°€ ģ œź³µķ•œ ꓀련 ė³“ź³ ģ„œė„¼ ź²€ķ† ķ•œ ģ“ė „ģ“ ķ™•ģøė˜ģ§€ ģ•Šź±°ė‚˜, ģœ„ķƒ ėŒ€ģƒģ—ģ„œ ģ œģ™øėœ ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ ģžģ²“ ėŖØė‹ˆķ„°ė§ 첓계넼 갖추고 ģžˆģ§€ ģ•Šģ€ 경우","사딀 3 : ė‚“ė¶€ģ ģœ¼ė”œ ģ •ģ˜ķ•œ ģž„ź³„ģ¹˜ė„¼ ģ“ˆź³¼ķ•˜ėŠ” ģ“ģƒ ķŠøėž˜ķ”½ģ“ ģ§€ģ†ģ ģœ¼ė”œ 발견되고 ģžˆģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•œ ėŒ€ģ‘ģ”°ģ¹˜ź°€ ģ“ė£Øģ–“ģ§€ź³  ģžˆģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제6ģ”°(ģ ‘ź·¼ķ†µģ œ)"]}],"description": "낓·외부에 ģ˜ķ•œ ģ¹Øķ•“ģ‹œė„, ź°œģøģ •ė³“ģœ ģ¶œ ģ‹œė„, ė¶€ģ •ķ–‰ģœ„ ė“±ģ„ ģ‹ ģ†ķ•˜ź²Œ ķƒģ§€Ā·ėŒ€ģ‘ķ•  수 ģžˆė„ė” ė„¤ķŠøģ›Œķ¬ ė° ė°ģ“ķ„° ķė¦„ ė“±ģ„ ģˆ˜ģ§‘ķ•˜ģ—¬ ė¶„ģ„ķ•˜ė©°, ėŖØė‹ˆķ„°ė§ ė° 점검 결과에 따넸 ģ‚¬ķ›„ģ”°ģ¹˜ėŠ” ģ ģ‹œģ— ģ“ė£Øģ–“ģ øģ•¼ ķ•œė‹¤.","checks_status": {"fail": 6,"pass": 1,"total": 28,"manual": 0}},"2.11.4": {"name": "사고 ėŒ€ģ‘ ķ›ˆė Ø ė° ź°œģ„ ","checks": {"ssmincidents_enabled_with_plans": null},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.11.4 사고 ėŒ€ģ‘ ķ›ˆė Ø ė° ź°œģ„ ","Subdomain": "2.11. 사고 예방 ė° ėŒ€ģ‘","AuditEvidence": ["침핓사고 ė° ź°œģøģ •ė³“ ģœ ģ¶œģ‚¬ź³  ėŒ€ģ‘ ėŖØģ˜ķ›ˆė Ø ź³„ķšģ„œ","침핓사고 ė° ź°œģøģ •ė³“ ģœ ģ¶œģ‚¬ź³  ėŒ€ģ‘ ėŖØģ˜ķ›ˆė Ø ź²°ź³¼ģ„œ","침핓사고 ėŒ€ģ‘ 절차"],"AuditChecklist": ["침핓사고 ė° ź°œģøģ •ė³“ ģœ ģ¶œģ‚¬ź³  ėŒ€ģ‘ ģ ˆģ°Øģ— ź“€ķ•œ ėŖØģ˜ķ›ˆė Øź³„ķšģ„ ģˆ˜ė¦½ķ•˜ź³  ģ“ģ— ė”°ė¼ ģ—° 1회 ģ“ģƒ 주기적으딜 ķ›ˆė Øģ„ ģ‹¤ģ‹œķ•˜ź³  ģžˆėŠ”ź°€?","침핓사고 ė° ź°œģøģ •ė³“ ģœ ģ¶œģ‚¬ź³  ķ›ˆė Ø 결과넼 ė°˜ģ˜ķ•˜ģ—¬ 침핓사고 ė° ź°œģøģ •ė³“ ģœ ģ¶œģ‚¬ź³  ėŒ€ģ‘ģ²“ź³„ė„¼ ź°œģ„ ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : 침핓사고 ėŖØģ˜ķ›ˆė Øģ„ ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜ ꓀련 ź³„ķšģ„œ ė° ź²°ź³¼ė³“ź³ ģ„œź°€ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģ—°ź°„ 침핓사고 ėŖØģ˜ķ›ˆė Ø ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ģ˜€ģœ¼ė‚˜ ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ė˜ėŠ” ģŠ¹ģø ģ—†ģ“ 핓당 źø°ź°„ 낓에 ģ‹¤ģ‹œķ•˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ėŖØģ˜ķ›ˆė Øģ„ ź³„ķšķ•˜ģ—¬ ģ‹¤ģ‹œķ•˜ģ˜€ģœ¼ė‚˜, ꓀련 ė‚“ė¶€ 지침에 ģ •ķ•œ 절차 ė° ģ„œģ‹ģ— ė”°ė¼ ģˆ˜ķ–‰ķ•˜ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": []}],"description": "침핓사고 ė° ź°œģøģ •ė³“ ģœ ģ¶œģ‚¬ź³  ėŒ€ģ‘ 절차넼 ģž„ģ§ģ›ź³¼ ģ“ķ•“ź“€ź³„ģžź°€ ģˆ™ģ§€ķ•˜ė„ė” ģ‹œė‚˜ė¦¬ģ˜¤ģ— 따넸 ėŖØģ˜ķ›ˆė Øģ„ ģ—° 1회 ģ“ģƒ ģ‹¤ģ‹œķ•˜ź³  ķ›ˆė Øź²°ź³¼ė„¼ ė°˜ģ˜ķ•˜ģ—¬ ėŒ€ģ‘ģ²“ź³„ė„¼ ź°œģ„ ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"2.11.5": {"name": "사고 ėŒ€ģ‘ ė° 복구","checks": {},"status": "PASS","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.11.5 사고 ėŒ€ģ‘ ė° 복구","Subdomain": "2.11. 사고 예방 ė° ėŒ€ģ‘","AuditEvidence": ["침핓사고 ėŒ€ģ‘ 절차","침핓사고 ėŒ€ģ‘ė³“ź³ ģ„œ","침핓사고 ź“€ė¦¬ėŒ€ģž„","ź°œģøģ •ė³“ ģœ ģ¶œģ‹ ź³ ģ„œ","ė¹„ģƒģ—°ė½ė§"],"AuditChecklist": ["침핓사고 ė° ź°œģøģ •ė³“ ģœ ģ¶œģ˜ 징후 ė˜ėŠ” ė°œģƒģ„ ģøģ§€ķ•œ 경우 ģ •ģ˜ėœ 침핓사고 ėŒ€ģ‘ģ ˆģ°Øģ— ė”°ė¼ ģ‹ ģ†ķ•˜ź²Œ ėŒ€ģ‘ ė° 볓고가 ģ“ė£Øģ–“ģ§€ź³  ģžˆėŠ”ź°€?","ź°œģøģ •ė³“ 침핓사고 ė°œģƒ ģ‹œ ꓀련 법령에 ė”°ė¼ 정볓주첓 통지 ė° ꓀계기꓀ ģ‹ ź³  절차넼 ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","침핓사고가 ģ¢…ź²°ėœ 후 ģ‚¬ź³ ģ˜ ģ›ģøģ„ ė¶„ģ„ķ•˜ģ—¬ ź·ø 결과넼 ė³“ź³ ķ•˜ź³  ꓀련 씰직 ė°ģøė „ź³¼ ź³µģœ ķ•˜ź³  ģžˆėŠ”ź°€?","침핓사고 ė¶„ģ„ģ„ ķ†µķ•˜ģ—¬ ģ–»ģ€ 정볓넼 ķ™œģš©ķ•˜ģ—¬ ģœ ģ‚¬ 사고가 ģž¬ė°œķ•˜ģ§€ ģ•Šė„ė” ėŒ€ģ±…ģ„ ģˆ˜ė¦½ķ•˜ź³  ķ•„ģš”ķ•œ 경우 침핓사고 ėŒ€ģ‘ģ ˆģ°Ø ė“±ģ„ ė³€ź²½ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ė‚“ė¶€ 침핓사고 ėŒ€ģ‘ģ§€ģ¹Øģ—ėŠ” 침핓사고 ė°œģƒ ģ‹œ ė‚“ė¶€ ģ •ė³“ė³“ķ˜øģœ„ģ›ķšŒ ė° ģ“ķ•“ź“€ź³„ ė¶€ģ„œģ—ź²Œ ė³“ź³ ķ•˜ė„ė” ģ •ķ•˜ź³  ģžˆģœ¼ė‚˜, 침핓사고 ė°œģƒ ģ‹œ 닓당 ė¶€ģ„œģ—ģ„œ ģžģ²“ģ ģœ¼ė”œ ėŒ€ģ‘ 씰치 후 ģ •ė³“ė³“ķ˜øģœ„ģ›ķšŒ ė° ģ“ķ•“ź“€ź³„ ė¶€ģ„œģ— ė³“ź³ ķ•˜ģ§€ ģ•Šģ€ 경우","사딀 2 : 최근 DDoS 공격으딜 ģ˜ģ‹¬ė˜ėŠ” ģ¹Øķ•“ģ‚¬ź³ ė”œ ģøķ•˜ģ—¬ ģ„œė¹„ģŠ¤ ģ¼ė¶€ź°€ ģ¤‘ė‹Øėœ 사딀가 ģžˆģœ¼ė‚˜, ģ“ģ— ėŒ€ķ•œ ģ›ģøė¶„ģ„ ė° ģž¬ė°œė°©ģ§€ ėŒ€ģ±…ģ“ ģˆ˜ė¦½ė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : 외부 핓킹에 ģ˜ķ•“ ź°œģøģ •ė³“ ģœ ģ¶œģ‚¬ź³ ź°€ ė°œģƒķ•˜ģ˜€ģœ¼ė‚˜, 유출된 ź°œģøģ •ė³“ ź±“ģˆ˜ź°€ ģ†ŒėŸ‰ģ“ė¼ėŠ” ģ“ģœ ė”œ 72ģ‹œź°„ ģ“ė‚“ģ— 통지 ė° ģ‹ ź³ ź°€ ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우","사딀 4 : ė‹“ė‹¹ģžģ˜ ģ‹¤ģˆ˜ģ— ģ˜ķ•“ ģøķ„°ė„· ķ™ˆķŽ˜ģ“ģ§€ ź²Œģ‹œķŒģ„ 통핓 1ģ²œėŖ… ģ“ģƒ 정볓주첓에 ėŒ€ķ•œ ź°œģøģ •ė³“ ģœ ģ¶œģ“ ė°œģƒķ•˜ģ˜€ģœ¼ė‚˜, 핓당 정볓주첓에 ėŒ€ķ•œ 유출 통지가 ģ“ė£Øģ–“ģ§€ģ§€ ģ•Šģ€ 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제34ģ”°(ź°œģøģ •ė³“ģ˜ 유출 ė“±ģ˜ 통지·신고)","ģ •ė³“ķ†µģ‹ ė§ė²• 제48ģ”°ģ˜3(ģ¹Øķ•“ģ‚¬ź³ ģ˜ ģ‹ ź³  등), 제48ģ”°ģ˜4(ģ¹Øķ•“ģ‚¬ź³ ģ˜ ģ›ģøė¶„ģ„ 등)"]}],"description": "침핓사고 ė° ź°œģøģ •ė³“ 유출 ģ§•ķ›„ė‚˜ ė°œģƒģ„ ģøģ§€ķ•œ ė•Œģ—ėŠ” 법적 통지 ė° ģ‹ ź³  ģ˜ė¬“ė„¼ ģ¤€ģˆ˜ķ•˜ģ—¬ģ•¼ ķ•˜ė©°, ģ ˆģ°Øģ— ė”°ė¼ ģ‹ ģ†ķ•˜ź²Œ ėŒ€ģ‘ ė° ė³µźµ¬ķ•˜ź³  ģ‚¬ź³ ė¶„ģ„ 후 ģž¬ė°œė°©ģ§€ ėŒ€ģ±…ģ„ ģˆ˜ė¦½ķ•˜ģ—¬ ėŒ€ģ‘ģ²“ź³„ģ— ė°˜ģ˜ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 0,"pass": 0,"total": 0,"manual": 0}},"2.12.1": {"name": "ģž¬ķ•“Ā·ģž¬ė‚œ ėŒ€ė¹„ ģ•ˆģ „ģ”°ģ¹˜","checks": {"drs_job_exist": "FAIL","backup_plans_exist": "PASS","rds_cluster_multi_az": "FAIL","elb_is_in_multiple_az": "FAIL","rds_instance_multi_az": "FAIL","s3_bucket_object_lock": "FAIL","vpc_different_regions": null,"efs_have_backup_enabled": "FAIL","elbv2_is_in_multiple_az": "PASS","vpc_subnet_different_az": "PASS","backup_reportplans_exist": null,"neptune_cluster_multi_az": null,"elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_lifecycle_enabled": "FAIL","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"autoscaling_group_multiple_az": null,"dms_instance_multi_az_enabled": null,"ec2_ebs_volume_snapshots_exists": "FAIL","rds_cluster_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL","documentdb_cluster_backup_enabled": null,"s3_bucket_cross_region_replication": "FAIL","kms_cmk_not_deleted_unintentionally": null,"neptune_cluster_deletion_protection": null,"redshift_cluster_automated_snapshot": null,"elb_cross_zone_load_balancing_enabled": "PASS","lightsail_instance_automated_snapshots": null,"dlm_ebs_snapshot_lifecycle_policy_exists": "FAIL","documentdb_cluster_cloudwatch_log_export": null,"elasticache_redis_cluster_backup_enabled": null,"elasticache_redis_cluster_multi_az_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.12.1 ģž¬ķ•“Ā·ģž¬ė‚œ ėŒ€ė¹„ ģ•ˆģ „ģ”°ģ¹˜","Subdomain": "2.12. ģž¬ķ•“ 복구","AuditEvidence": ["IT ģž¬ķ•“ 복구 ģ§€ģ¹ØĀ·ģ ˆģ°Ø","IT ģž¬ķ•“ 복구 ź³„ķš(RTO, RPO ģ •ģ˜ ķ¬ķ•Ø)","ė¹„ģƒģ—°ė½ė§","ź°œģøģ •ė³“ģ²˜ė¦¬ģ‹œģŠ¤ķ…œ ģœ„źø°ėŒ€ģ‘ 매뉓얼"],"AuditChecklist": ["ģ”°ģ§ģ˜ 핵심 ģ„œė¹„ģŠ¤(업묓) ģ—°ģ†ģ„±ģ„ ģœ„ķ˜‘ķ•  수 ģžˆėŠ” IT ģž¬ķ•“ ģœ ķ˜•ģ„ ģ‹ė³„ķ•˜ź³ , ģœ ķ˜•ė³„ ķ”¼ķ•“ź·œėŖØ ė° 업묓에 ėÆøģ¹˜ėŠ” ģ˜ķ–„ģ„ ė¶„ģ„ķ•˜ģ—¬ 핵심 IT ģ„œė¹„ģŠ¤(업묓) ė° ģ‹œģŠ¤ķ…œģ„ģ‹ė³„ķ•˜ź³  ģžˆėŠ”ź°€?","핵심 IT ģ„œė¹„ģŠ¤ ė° ģ‹œģŠ¤ķ…œģ˜ ģ¤‘ģš”ė„ ė° ķŠ¹ģ„±ģ— 따넸 복구 ėŖ©ķ‘œģ‹œź°„, 복구 ėŖ©ķ‘œģ‹œģ ģ„ ģ •ģ˜ķ•˜ź³  ģžˆėŠ”ź°€?","ģž¬ķ•“Ā·ģž¬ė‚œ ė°œģƒ ģ‹œģ—ė„ 핵심 ģ„œė¹„ģŠ¤ ė° ģ‹œģŠ¤ķ…œģ˜ ģ—°ģ†ģ„±ģ„ ė³“ģž„ķ•  수 ģžˆė„ė” 복구 ģ „ėžµ ė° ėŒ€ģ±…, ė¹„ģƒģ‹œ 복구 씰직, ė¹„ģƒģ—°ė½ģ²“ź³„, 복구 절차 등 ģž¬ķ•“ 복구 ź³„ķšģ„ 수립 ė° ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : IT ģž¬ķ•“ 복구 ģ ˆģ°Øģ„œ 낓에 IT ģž¬ķ•“ 복구 씰직 ė° ģ—­ķ•  ģ •ģ˜, ė¹„ģƒģ—°ė½ģ²“ź³„, 복구 절차 ė° 방법 등 ģ¤‘ģš”ķ•œ ė‚“ģš©ģ“ ėˆ„ė½ė˜ģ–“ ģžˆėŠ” 경우","사딀 2 : ė¹„ģƒģ‚¬ķƒœ ė°œģƒ ģ‹œ ģ •ė³“ģ‹œģŠ¤ķ…œģ˜ ģ—°ģ†ģ„± 확볓 ė° 피핓 ģµœģ†Œķ™”ė„¼ ģœ„ķ•˜ģ—¬ 백업센터넼 źµ¬ģ¶•ķ•˜ģ—¬ ģš“ģ˜ķ•˜ź³  ģžˆģœ¼ė‚˜, ꓀련 정책에 백업센터넼 ķ™œģš©ķ•œ ģž¬ķ•“ 복구 절차 ė“±ģ“ ģˆ˜ė¦½ė˜ģ–“ ģžˆģ§€ ģ•Šģ•„ ģž¬ķ•“ 복구 ģ‹œķ—˜ ė° 복구가 효과적으딜 ģ§„ķ–‰ė˜źø° ģ–“ė ¤ģš“ 경우","사딀 3 : ģ„œė¹„ģŠ¤ 욓영과 ź“€ė Øėœ ģ¼ė¶€ ģ¤‘ģš” ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ 복구 ėŖ©ķ‘œģ‹œź°„ģ“ ģ •ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģœ¼ė©°, ģ“ģ— ėŒ€ķ•œ ģ ģ ˆķ•œ 복구 ėŒ€ģ±…ģ„ ė§ˆė Øķ•˜ź³  ģžˆģ§€ ģ•Šģ€ 경우","사딀 4 : ģž¬ķ•“ 복구 ꓀련 ģ§€ģ¹Øģ„œ 등에 IT ģ„œė¹„ģŠ¤ ė˜ėŠ” ģ‹œģŠ¤ķ…œģ— ėŒ€ķ•œ 복구 ģš°ģ„ ģˆœģœ„, 복구 ėŖ©ķ‘œģ‹œź°„, 복구 ėŖ©ķ‘œģ‹œģ  ė“±ģ“ ģ •ģ˜ė˜ģ–“ ģžˆģ§€ ģ•Šģ€ 경우","사딀 5 : ķ˜„ģ‹¤ģ  ėŒ€ģ±… ģ—†ģ“ 복구 ėŖ©ķ‘œģ‹œź°„ģ„ ź³¼ė„ ė˜ėŠ” ź³¼ģ†Œķ•˜ź²Œ ģ„¤ģ •ķ•˜ź³  ģžˆź±°ė‚˜, 복구 ėŖ©ķ‘œģ‹œģ ź³¼ 백업정책(ėŒ€ģƒ, 주기 등)ģ“ ģ ģ ˆķžˆ ģ—°ź³„ė˜ģ§€ ģ•Šģ•„ 복구 ķšØź³¼ģ„±ģ„ ė³“ģž„ķ•  수 ģ—†ėŠ” 경우"],"RelatedRegulations": ["ź°œģøģ •ė³“ ė³“ķ˜øė²• 제29ģ”°(ģ•ˆģ „ģ”°ģ¹˜ģ˜ė¬“)","ź°œģøģ •ė³“ģ˜ ģ•ˆģ „ģ„± ķ™•ė³“ģ”°ģ¹˜ 기준 제11ģ”°(ģž¬ķ•“Ā·ģž¬ė‚œ ėŒ€ė¹„ ģ•ˆģ „ģ”°ģ¹˜)"]}],"description": "ģžģ—°ģž¬ķ•“, 통신·전렄 ģž„ģ• , 핓킹 등 ģ”°ģ§ģ˜ 핵심 ģ„œė¹„ģŠ¤ ė° ģ‹œģŠ¤ķ…œģ˜ 욓영 ģ—°ģ†ģ„±ģ„ ģœ„ķ˜‘ķ•  수 ģžˆėŠ” ģž¬ķ•“ ģœ ķ˜•ģ„ ģ‹ė³„ķ•˜ź³ , ģœ ķ˜•ė³„ 예상 ķ”¼ķ•“ź·œėŖØ ė° ģ˜ķ–„ģ„ ė¶„ģ„ķ•˜ģ—¬ģ•¼ ķ•œė‹¤. ė˜ķ•œ 복구 ėŖ©ķ‘œģ‹œź°„, 복구 ėŖ©ķ‘œģ‹œģ ģ„ ģ •ģ˜ķ•˜ź³  복구 ģ „ėžµ ė° ėŒ€ģ±…, ė¹„ģƒģ‹œ 복구 씰직, ė¹„ģƒģ—°ė½ģ²“ź³„, 복구 절차 등 ģž¬ķ•“ 복구첓계넼 źµ¬ģ¶•ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 14,"pass": 5,"total": 33,"manual": 0}},"2.12.2": {"name": "ģž¬ķ•“ 복구 ģ‹œķ—˜ ė° ź°œģ„ ","checks": {"drs_job_exist": "FAIL","backup_plans_exist": "PASS","rds_cluster_multi_az": "FAIL","elb_is_in_multiple_az": "FAIL","rds_instance_multi_az": "FAIL","s3_bucket_object_lock": "FAIL","vpc_different_regions": null,"efs_have_backup_enabled": "FAIL","elbv2_is_in_multiple_az": "PASS","vpc_subnet_different_az": "PASS","backup_reportplans_exist": null,"neptune_cluster_multi_az": null,"elbv2_deletion_protection": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_lifecycle_enabled": "FAIL","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"autoscaling_group_multiple_az": null,"dms_instance_multi_az_enabled": null,"ec2_ebs_volume_snapshots_exists": "FAIL","rds_cluster_deletion_protection": "FAIL","rds_instance_deletion_protection": "FAIL","documentdb_cluster_backup_enabled": null,"s3_bucket_cross_region_replication": "FAIL","kms_cmk_not_deleted_unintentionally": null,"neptune_cluster_deletion_protection": null,"redshift_cluster_automated_snapshot": null,"elb_cross_zone_load_balancing_enabled": "PASS","lightsail_instance_automated_snapshots": null,"dlm_ebs_snapshot_lifecycle_policy_exists": "FAIL","documentdb_cluster_cloudwatch_log_export": null,"elasticache_redis_cluster_backup_enabled": null,"elasticache_redis_cluster_multi_az_enabled": null},"status": "FAIL","attributes": [{"Domain": "2. ė³“ķ˜øėŒ€ģ±… ģš”źµ¬ģ‚¬ķ•­","Section": "2.12.2 ģž¬ķ•“ 복구 ģ‹œķ—˜ ė° ź°œģ„ ","Subdomain": "2.12. ģž¬ķ•“ 복구","AuditEvidence": ["IT ģž¬ķ•“ 복구 ģ ˆģ°Øģ„œ","IT ģž¬ķ•“ 복구 ģ‹œķ—˜ ź³„ķšģ„œ","IT ģž¬ķ•“ 복구 ģ‹œķ—˜ ź²°ź³¼ģ„œ"],"AuditChecklist": ["수립된 IT ģž¬ķ•“ ė³µźµ¬ģ²“ź³„ģ˜ ģ‹¤ķšØģ„±ģ„ ķŒė‹Øķ•˜źø° ģœ„ķ•˜ģ—¬ ģž¬ķ•“ 복구 ģ‹œķ—˜ź³„ķšģ„ 수립 ė° ģ“ķ–‰ķ•˜ź³  ģžˆėŠ”ź°€?","ģ‹œķ—˜ź²°ź³¼, ģ •ė³“ģ‹œģŠ¤ķ…œ ķ™˜ź²½ė³€ķ™”, 법넠 등에 따넸 변화넼 ė°˜ģ˜ķ•  수 ģžˆė„ė” ė³µźµ¬ģ „ėžµ ė° ėŒ€ģ±…ģ„ ģ •źø°ģ ģœ¼ė”œ ź²€ķ† Ā·ė³“ģ™„ķ•˜ź³  ģžˆėŠ”ź°€?"],"NonComplianceCases": ["사딀 1 : ģž¬ķ•“ 복구 ķ›ˆė Øģ„ ź³„ķšĀ·ģ‹œķ–‰ķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜ ꓀련 ź³„ķšģ„œ ė° ź²°ź³¼ė³“ź³ ģ„œź°€ ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우","사딀 2 : ģž¬ķ•“ 복구 ķ›ˆė Ø ź³„ķšģ„ ģˆ˜ė¦½ķ•˜ģ˜€ģœ¼ė‚˜, ķƒ€ė‹¹ķ•œ ģ‚¬ģœ  ė˜ėŠ” ģŠ¹ģø ģ—†ģ“ ź³„ķšėŒ€ė”œ ģ‹¤ģ‹œķ•˜ģ§€ ģ•Šģ•˜ź±°ė‚˜ ꓀련 결과볓고가 ķ™•ģøė˜ģ§€ ģ•Šģ€ 경우","사딀 3 : ģž¬ķ•“ 복구 ķ›ˆė Øģ„ ź³„ķšķ•˜ģ—¬ ģ‹¤ģ‹œķ•˜ģ˜€ģœ¼ė‚˜, ė‚“ė¶€ ꓀련 지침에 ģ •ķ•œ 절차 ė° ģ„œģ‹ģ— ė”°ė¼ ģ“ķ–‰ė˜ģ§€ ģ•Šģ•„ ģˆ˜ė¦½ķ•œ ģž¬ķ•“ 복구 ģ ˆģ°Øģ˜ 적정성 ė° ķšØź³¼ģ„±ģ„ ķ‰ź°€ķ•˜źø° ģœ„ķ•œ ķ›ˆė Øģœ¼ė”œ 볓기 ģ–“ė ¤ģš“ 경우"],"RelatedRegulations": []}],"description": "ģž¬ķ•“ 복구 ģ „ėžµ ė° ėŒ€ģ±…ģ˜ ģ ģ •ģ„±ģ„ ģ •źø°ģ ģœ¼ė”œ ģ‹œķ—˜ķ•˜ģ—¬ ģ‹œķ—˜ź²°ź³¼, ģ •ė³“ģ‹œģŠ¤ķ…œ ķ™˜ź²½ė³€ķ™”, ė²•ź·œ 등에 따넸 변화넼 ė°˜ģ˜ķ•˜ģ—¬ ė³µźµ¬ģ „ėžµ ė° ėŒ€ģ±…ģ„ ė³“ģ™„ķ•˜ģ—¬ģ•¼ ķ•œė‹¤.","checks_status": {"fail": 14,"pass": 5,"total": 33,"manual": 0}}},"requirements_passed": 10,"requirements_failed": 27,"requirements_manual": 64,"total_requirements": 101,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "f9e5248f-1b1d-4256-b2a1-3b571315c190","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "cis_1.4_aws","framework": "CIS","version": "1.4","description": "The CIS Benchmark for CIS Amazon Web Services Foundations Benchmark, v1.4.0, Level 1 and 2 provides prescriptive guidance for configuring security options for a subset of Amazon Web Services. It has an emphasis on foundational, testable, and architecture agnostic settings","region": "eu-west-1","requirements": {"1.1": {"name": "1.1","checks": {"account_maintain_current_contact_details": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/manage-account-payment.html#contact-info","Description": "Ensure contact email and telephone details for AWS accounts are current and map to more than one individual in your organization.An AWS account supports a number of contact details, and AWS will use these to contact the account owner if activity judged to be in breach of Acceptable Use Policy or indicative of likely security compromise is observed by the AWS Abuse team. Contact details should not be for a single individual, as circumstances may arise where that individual is unavailable. Email contact details should point to a mail alias which forwards email to multiple individuals within the organization; where feasible, phone contact details should point to a PABX hunt group or other call-forwarding system.","DefaultValue": null,"AuditProcedure": "This activity can only be performed via the AWS Console, with a user who has permission to read and write Billing information (aws-portal:\\*Billing )1. Sign in to the AWS Management Console and open the `Billing and Cost Management` console at https://console.aws.amazon.com/billing/home#/. 2. On the navigation bar, choose your account name, and then choose `My Account`. 3. On the `Account Settings` page, review and verify the current details. 4. Under `Contact Information`, review and verify the current details.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "If an AWS account is observed to be behaving in a prohibited or suspicious manner, AWS will attempt to contact the account owner by email and phone using the contact details listed. If this is unsuccessful and the account behavior needs urgent mitigation, proactive measures may be taken, including throttling of traffic between the account exhibiting suspicious behavior and the AWS API endpoints and the Internet. This will result in impaired service to and from the account in question, so it is in both the customers' and AWS' best interests that prompt contact can be established. This is best achieved by setting AWS account contact details to point to resources which have multiple individuals as recipients, such as email aliases and PABX hunt groups.","RemediationProcedure": "This activity can only be performed via the AWS Console, with a user who has permission to read and write Billing information (aws-portal:\\*Billing ).1. Sign in to the AWS Management Console and open the `Billing and Cost Management` console at https://console.aws.amazon.com/billing/home#/. 2. On the navigation bar, choose your account name, and then choose `My Account`. 3. On the `Account Settings` page, next to `Account Settings`, choose `Edit`. 4. Next to the field that you need to update, choose `Edit`. 5. After you have entered your changes, choose `Save changes`. 6. After you have made your changes, choose `Done`. 7. To edit your contact information, under `Contact Information`, choose `Edit`. 8. For the fields that you want to change, type your updated information, and then choose `Update`.","AdditionalInformation": ""}],"description": "Maintain current contact details","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.2": {"name": "1.2","checks": {"account_security_contact_information_is_registered": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "","Description": "AWS provides customers with the option of specifying the contact information for account's security team. It is recommended that this information be provided.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if security contact information is present:**From Console:**1. Click on your account name at the top right corner of the console 2. From the drop-down menu Click `My Account`3. Scroll down to the `Alternate Contacts` section 4. Ensure contact information is specified in the `Security` section","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Specifying security-specific contact information will help ensure that security advisories sent by AWS reach the team in your organization that is best equipped to respond to them.","RemediationProcedure": "Perform the following to establish security contact information:**From Console:**1. Click on your account name at the top right corner of the console. 2. From the drop-down menu Click `My Account`3. Scroll down to the `Alternate Contacts` section 4. Enter contact information in the `Security` section**Note:** Consider specifying an internal email distribution list to ensure emails are regularly monitored by more than one individual.","AdditionalInformation": ""}],"description": "Ensure security contact information is registered","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.3": {"name": "1.3","checks": {"account_security_questions_are_registered_in_the_aws_account": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "","Description": "The AWS support portal allows account owners to establish security questions that can be used to authenticate individuals calling AWS customer service for support. It is recommended that security questions be established.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS account as the 'root' user 2. On the top right you will see the __ 3. Click on the __ 4. From the drop-down menu Click `My Account`5. In the `Configure Security Challenge Questions` section on the `Personal Information` page, configure three security challenge questions. 6. Click `Save questions` .","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "When creating a new AWS account, a default super user is automatically created. This account is referred to as the 'root user' or 'root' account. It is recommended that the use of this account be limited and highly controlled. During events in which the 'root' password is no longer accessible or the MFA token associated with 'root' is lost/destroyed it is possible, through authentication using secret questions and associated answers, to recover 'root' user login access.","RemediationProcedure": "**From Console:**1. Login to the AWS Account as the 'root' user 2. Click on the __ from the top right of the console 3. From the drop-down menu Click _My Account_ 4. Scroll down to the `Configure Security Questions` section 5. Click on `Edit`6. Click on each `Question` - From the drop-down select an appropriate question- Click on the `Answer` section- Enter an appropriate answer - Follow process for all 3 questions 7. Click `Update` when complete 8. Save Questions and Answers and place in a secure physical location","AdditionalInformation": ""}],"description": "Ensure security questions are registered in the AWS account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.4": {"name": "1.4","checks": {"iam_no_root_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "http://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html:http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html:http://docs.aws.amazon.com/IAM/latest/APIReference/API_GetAccountSummary.html:https://aws.amazon.com/blogs/security/an-easier-way-to-determine-the-presence-of-aws-account-access-keys/","Description": "The 'root' user account is the most privileged user in an AWS account. AWS Access Keys provide programmatic access to a given AWS account. It is recommended that all access keys associated with the 'root' user account be removed.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has access keys:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on `Credential Report`5. This will download a `.csv` file which contains credential usage for all IAM users within an AWS Account - open this file 6. For the `` user, ensure the `access_key_1_active` and `access_key_2_active` fields are set to `FALSE` .**From Command Line:**Run the following command: ```aws iam get-account-summary | grep \"AccountAccessKeysPresent\"``` If no 'root' access keys exist the output will show \"AccountAccessKeysPresent\": 0,. If the output shows a \"1\" than 'root' keys exist, refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Removing access keys associated with the 'root' user account limits vectors by which the account can be compromised. Additionally, removing the 'root' access keys encourages the creation and use of role based accounts that are least privileged.","RemediationProcedure": "Perform the following to delete or disable active 'root' user access keys**From Console:**1. Sign in to the AWS Management Console as 'root' and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. Click on __ at the top right and select `My Security Credentials` from the drop down list 3. On the pop out screen Click on `Continue to Security Credentials`4. Click on `Access Keys` _(Access Key ID and Secret Access Key)_ 5. Under the `Status` column if there are any Keys which are Active- Click on `Make Inactive` - (Temporarily disable Key - may be needed again)- Click `Delete` - (Deleted keys cannot be recovered)","AdditionalInformation": "IAM User account \"root\" for us-gov cloud regions is not enabled by default. However, on request to AWS support enables 'root' access only through access-keys (CLI, API methods) for us-gov cloud region."}],"description": "Ensure no 'root' user account access key exists","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.5": {"name": "1.5","checks": {"iam_root_mfa_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#id_root-user_manage_mfa:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html#enable-virt-mfa-for-root","Description": "The 'root' user account is the most privileged user in an AWS account. Multi-factor Authentication (MFA) adds an extra layer of protection on top of a username and password. With MFA enabled, when a user signs in to an AWS website, they will be prompted for their username and password as well as for an authentication code from their AWS MFA device.**Note:** When virtual MFA is used for 'root' accounts, it is recommended that the device used is NOT a personal device, but rather a dedicated mobile device (tablet or phone) that is managed to be kept charged and secured independent of any individual personal devices. (\"non-personal virtual MFA\") This lessens the risks of losing access to the MFA due to device loss, device trade-in or if the individual owning the device is no longer employed at the company.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has MFA setup:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on `Credential Report`5. This will download a `.csv` file which contains credential usage for all IAM users within an AWS Account - open this file 6. For the `` user, ensure the `mfa_active` field is set to `TRUE` .**From Command Line:**1. Run the following command: ```aws iam get-account-summary | grep \"AccountMFAEnabled\" ``` 2. Ensure the AccountMFAEnabled property is set to 1","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling MFA provides increased security for console access as it requires the authenticating principal to possess a device that emits a time-sensitive key and have knowledge of a credential.","RemediationProcedure": "Perform the following to establish MFA for the 'root' user account:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). Note: to manage MFA devices for the 'root' AWS account, you must use your 'root' account credentials to sign in to AWS. You cannot manage MFA devices for the 'root' account using other credentials.2. Choose `Dashboard` , and under `Security Status` , expand `Activate MFA` on your root account. 3. Choose `Activate MFA`4. In the wizard, choose `A virtual MFA` device and then choose `Next Step` . 5. IAM generates and displays configuration information for the virtual MFA device, including a QR code graphic. The graphic is a representation of the 'secret configuration key' that is available for manual entry on devices that do not support QR codes. 6. Open your virtual MFA application. (For a list of apps that you can use for hosting virtual MFA devices, see [Virtual MFA Applications](http://aws.amazon.com/iam/details/mfa/#Virtual_MFA_Applications).) If the virtual MFA application supports multiple accounts (multiple virtual MFA devices), choose the option to create a new account (a new virtual MFA device). 7. Determine whether the MFA app supports QR codes, and then do one of the following: - Use the app to scan the QR code. For example, you might choose the camera icon or choose an option similar to Scan code, and then use the device's camera to scan the code.- In the Manage MFA Device wizard, choose Show secret key for manual configuration, and then type the secret configuration key into your MFA application.When you are finished, the virtual MFA device starts generating one-time passwords.In the Manage MFA Device wizard, in the Authentication Code 1 box, type the one-time password that currently appears in the virtual MFA device. Wait up to 30 seconds for the device to generate a new one-time password. Then type the second one-time password into the Authentication Code 2 box. Choose Assign Virtual MFA.","AdditionalInformation": "IAM User account \"root\" for us-gov cloud regions does not have console access. This recommendation is not applicable for us-gov cloud regions."}],"description": "Ensure MFA is enabled for the 'root' user account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.6": {"name": "1.6","checks": {"iam_root_hardware_mfa_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_physical.html#enable-hw-mfa-for-root","Description": "The 'root' user account is the most privileged user in an AWS account. MFA adds an extra layer of protection on top of a user name and password. With MFA enabled, when a user signs in to an AWS website, they will be prompted for their user name and password as well as for an authentication code from their AWS MFA device. For Level 2, it is recommended that the 'root' user account be protected with a hardware MFA.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the 'root' user account has a hardware MFA setup:1. Run the following command to determine if the 'root' account has MFA setup: ```aws iam get-account-summary | grep \"AccountMFAEnabled\" ```The `AccountMFAEnabled` property is set to `1` will ensure that the 'root' user account has MFA (Virtual or Hardware) Enabled. If `AccountMFAEnabled` property is set to `0` the account is not compliant with this recommendation.2. If `AccountMFAEnabled` property is set to `1`, determine 'root' account has Hardware MFA enabled. Run the following command to list all virtual MFA devices: ```aws iam list-virtual-mfa-devices``` If the output contains one MFA with the following Serial Number, it means the MFA is virtual, not hardware and the account is not compliant with this recommendation: `\"SerialNumber\": \"arn:aws:iam::__:mfa/root-account-mfa-device\"`","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "A hardware MFA has a smaller attack surface than a virtual MFA. For example, a hardware MFA does not suffer the attack surface introduced by the mobile smartphone on which a virtual MFA resides.**Note**: Using hardware MFA for many, many AWS accounts may create a logistical device management issue. If this is the case, consider implementing this Level 2 recommendation selectively to the highest security AWS accounts and the Level 1 recommendation applied to the remaining accounts.","RemediationProcedure": "Perform the following to establish a hardware MFA for the 'root' user account:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). Note: to manage MFA devices for the AWS 'root' user account, you must use your 'root' account credentials to sign in to AWS. You cannot manage MFA devices for the 'root' account using other credentials. 2. Choose `Dashboard` , and under `Security Status` , expand `Activate MFA` on your root account. 3. Choose `Activate MFA`4. In the wizard, choose `A hardware MFA` device and then choose `Next Step` . 5. In the `Serial Number` box, enter the serial number that is found on the back of the MFA device. 6. In the `Authentication Code 1` box, enter the six-digit number displayed by the MFA device. You might need to press the button on the front of the device to display the number. 7. Wait 30 seconds while the device refreshes the code, and then enter the next six-digit number into the `Authentication Code 2` box. You might need to press the button on the front of the device again to display the second number. 8. Choose `Next Step` . The MFA device is now associated with the AWS account. The next time you use your AWS account credentials to sign in, you must type a code from the hardware MFA device.Remediation for this recommendation is not available through AWS CLI.","AdditionalInformation": "IAM User account 'root' for us-gov cloud regions does not have console access. This control is not applicable for us-gov cloud regions."}],"description": "Ensure hardware MFA is enabled for the 'root' user account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.7": {"name": "1.7","checks": {"iam_avoid_root_usage": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html:https://docs.aws.amazon.com/general/latest/gr/aws_tasks-that-require-root.html","Description": "With the creation of an AWS account, a 'root user' is created that cannot be disabled or deleted. That user has unrestricted access to and control over all resources in the AWS account. It is highly recommended that the use of this account be avoided for everyday tasks.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console at `https://console.aws.amazon.com/iam/` 2. In the left pane, click `Credential Report` 3. Click on `Download Report` 4. Open of Save the file locally 5. Locate the `` under the user column 6. Review `password_last_used, access_key_1_last_used_date, access_key_2_last_used_date` to determine when the 'root user' was last used.**From Command Line:**Run the following CLI commands to provide a credential report for determining the last time the 'root user' was used: ``` aws iam generate-credential-report ``` ``` aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,5,11,16 | grep -B1 '' ```Review `password_last_used`, `access_key_1_last_used_date`, `access_key_2_last_used_date` to determine when the _root user_ was last used.**Note:** There are a few conditions under which the use of the 'root' user account is required. Please see the reference links for all of the tasks that require use of the 'root' user.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "The 'root user' has unrestricted access to and control over all account resources. Use of it is inconsistent with the principles of least privilege and separation of duties, and can lead to unnecessary harm due to error or account compromise.","RemediationProcedure": "If you find that the 'root' user account is being used for daily activity to include administrative tasks that do not require the 'root' user:1. Change the 'root' user password. 2. Deactivate or delete any access keys associate with the 'root' user.**Remember, anyone who has 'root' user credentials for your AWS account has unrestricted access to and control of all the resources in your account, including billing information.","AdditionalInformation": "The 'root' user for us-gov cloud regions is not enabled by default. However, on request to AWS support, they can enable the 'root' user and grant access only through access-keys (CLI, API methods) for us-gov cloud region. If the 'root' user for us-gov cloud regions is enabled, this recommendation is applicable.Monitoring usage of the 'root' user can be accomplished by implementing recommendation 3.3 Ensure a log metric filter and alarm exist for usage of the 'root' user."}],"description": "Eliminate use of the 'root' user for administrative and daily tasks","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.8": {"name": "1.8","checks": {"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy","Description": "Password policies are, in part, used to enforce password complexity requirements. IAM password policies can be used to ensure password are at least a given length. It is recommended that the password policy require a minimum password length 14.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure the password policy is configured as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Ensure \"Minimum password length\" is set to 14 or greater.**From Command Line:** ``` aws iam get-account-password-policy ``` Ensure the output of the above command includes \"MinimumPasswordLength\": 14 (or higher)","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Setting a password complexity policy increases account resiliency against brute force login attempts.","RemediationProcedure": "Perform the following to set the password policy as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Set \"Minimum password length\" to `14` or greater. 5. Click \"Apply password policy\"**From Command Line:** ```aws iam update-account-password-policy --minimum-password-length 14 ``` Note: All commands starting with \"aws iam update-account-password-policy\" can be combined into a single command.","AdditionalInformation": ""}],"description": "Ensure IAM password policy requires minimum length of 14 or greater","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.9": {"name": "1.9","checks": {"iam_password_policy_reuse_24": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#configure-strong-password-policy","Description": "IAM password policies can prevent the reuse of a given password by the same user. It is recommended that the password policy prevent the reuse of passwords.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure the password policy is configured as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Ensure \"Prevent password reuse\" is checked 5. Ensure \"Number of passwords to remember\" is set to 24**From Command Line:** ``` aws iam get-account-password-policy``` Ensure the output of the above command includes \"PasswordReusePrevention\": 24","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Preventing password reuse increases account resiliency against brute force login attempts.","RemediationProcedure": "Perform the following to set the password policy as prescribed:**From Console:**1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Go to IAM Service on the AWS Console 3. Click on Account Settings on the Left Pane 4. Check \"Prevent password reuse\" 5. Set \"Number of passwords to remember\" is set to `24` **From Command Line:** ```aws iam update-account-password-policy --password-reuse-prevention 24 ``` Note: All commands starting with \"aws iam update-account-password-policy\" can be combined into a single command.","AdditionalInformation": ""}],"description": "Ensure IAM password policy prevents password reuse","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.1": {"name": "3.1","checks": {"cloudtrail_multi_region_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-management-events:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-management-and-data-events-with-cloudtrail.html?icmpid=docs_cloudtrail_console#logging-management-events:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-supported-services.html#cloud-trail-supported-services-data-events","Description": "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. CloudTrail provides a history of AWS API calls for an account, including API calls made via the Management Console, SDKs, command line tools, and higher-level AWS services (such as CloudFormation).","DefaultValue": null,"AuditProcedure": "Perform the following to determine if CloudTrail is enabled for all regions:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane- You will be presented with a list of trails across all regions 3. Ensure at least one Trail has `All` specified in the `Region` column 4. Click on a trail via the link in the _Name_ column 5. Ensure `Logging` is set to `ON`6. Ensure `Apply trail to all regions` is set to `Yes` 7. In section `Management Events` ensure `Read/Write Events` set to `ALL`**From Command Line:** ```aws cloudtrail describe-trails ``` Ensure `IsMultiRegionTrail` is set to `true```` aws cloudtrail get-trail-status --name  ``` Ensure `IsLogging` is set to `true` ``` aws cloudtrail get-event-selectors --trail-name  ``` Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`","ImpactStatement": "S3 lifecycle features can be used to manage the accumulation and management of logs over time. See the following AWS resource for more information on these features:1. https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html","AssessmentStatus": "Automated","RationaleStatement": "The AWS API call history produced by CloudTrail enables security analysis, resource change tracking, and compliance auditing. Additionally, - ensuring that a multi-regions trail exists will ensure that unexpected activity occurring in otherwise unused regions is detected- ensuring that a multi-regions trail exists will ensure that `Global Service Logging` is enabled for a trail by default to capture recording of events generated onAWS global services- for a multi-regions trail, ensuring that management events configured for all type of Read/Writes ensures recording of management operations that are performed on all resources in an AWS account","RemediationProcedure": "Perform the following to enable global (Multi-region) CloudTrail logging:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on _Trails_ on the left navigation pane 3. Click `Get Started Now` , if presented- Click `Add new trail` - Enter a trail name in the `Trail name` box- Set the `Apply trail to all regions` option to `Yes` - Specify an S3 bucket name in the `S3 bucket` box- Click `Create`4. If 1 or more trails already exist, select the target trail to enable for global logging 5. Click the edit icon (pencil) next to `Apply trail to all regions` , Click `Yes` and Click `Save`. 6. Click the edit icon (pencil) next to `Management Events` click `All` for setting `Read/Write Events` and Click `Save`.**From Command Line:** ``` aws cloudtrail create-trail --name  --bucket-name  --is-multi-region-trailaws cloudtrail update-trail --name  --is-multi-region-trail ```Note: Creating CloudTrail via CLI without providing any overriding options configures `Management Events` to set `All` type of `Read/Writes` by default.","AdditionalInformation": ""}],"description": "Ensure CloudTrail is enabled in all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3.2": {"name": "3.2","checks": {"cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-file-validation-enabling.html","Description": "CloudTrail log file validation creates a digitally signed digest file containing a hash of each log that CloudTrail writes to S3. These digest files can be used to determine whether a log file was changed, deleted, or unchanged after CloudTrail delivered the log. It is recommended that file validation be enabled on all CloudTrails.","DefaultValue": null,"AuditProcedure": "Perform the following on each trail to determine if log file validation is enabled:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane 3. For Every Trail: - Click on a trail via the link in the _Name_ column - Under the `General details` section, ensure `Log file validation` is set to `Enabled` **From Command Line:** ``` aws cloudtrail describe-trails ``` Ensure `LogFileValidationEnabled` is set to `true` for each trail","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling log file validation will provide additional integrity checking of CloudTrail logs.","RemediationProcedure": "Perform the following to enable log file validation on a given trail:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. Click on `Trails` on the left navigation pane 3. Click on target trail 4. Within the `General details` section click `edit` 5. Under the `Advanced settings` section 6. Check the enable box under `Log file validation`7. Click `Save changes` **From Command Line:** ``` aws cloudtrail update-trail --name  --enable-log-file-validation ``` Note that periodic validation of logs using these digests can be performed by running the following command: ``` aws cloudtrail validate-logs --trail-arn  --start-time  --end-time  ```","AdditionalInformation": ""}],"description": "Ensure CloudTrail log file validation is enabled","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.3": {"name": "3.3","checks": {"cloudtrail_logs_s3_bucket_is_not_publicly_accessible": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html","Description": "CloudTrail logs a record of every API call made in your AWS account. These logs file are stored in an S3 bucket. It is recommended that the bucket policy or access control list (ACL) applied to the S3 bucket that CloudTrail logs to prevent public access to the CloudTrail logs.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if any public access is granted to an S3 bucket via an ACL or S3 bucket policy:**From Console:**1. Go to the Amazon CloudTrail console at [https://console.aws.amazon.com/cloudtrail/home](https://console.aws.amazon.com/cloudtrail/home) 2. In the `API activity history` pane on the left, click `Trails`3. In the `Trails` pane, note the bucket names in the `S3 bucket` column 4. Go to Amazon S3 console at [https://console.aws.amazon.com/s3/home](https://console.aws.amazon.com/s3/home) 5. For each bucket noted in step 3, right-click on the bucket and click `Properties`6. In the `Properties` pane, click the `Permissions` tab. 7. The tab shows a list of grants, one row per grant, in the bucket ACL. Each row identifies the grantee and the permissions granted. 8. Ensure no rows exists that have the `Grantee` set to `Everyone` or the `Grantee` set to `Any Authenticated User.`9. If the `Edit bucket policy` button is present, click it to review the bucket policy. 10. Ensure the policy does not contain a `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ```aws cloudtrail describe-trails --query 'trailList[*].S3BucketName' ``` 2. Ensure the `AllUsers` principal is not granted privileges to that `` : ```aws s3api get-bucket-acl --bucket  --query 'Grants[?Grantee.URI== `https://acs.amazonaws.com/groups/global/AllUsers` ]' ``` 3. Ensure the `AuthenticatedUsers` principal is not granted privileges to that ``: ```aws s3api get-bucket-acl --bucket  --query 'Grants[?Grantee.URI== `https://acs.amazonaws.com/groups/global/Authenticated Users` ]' ``` 4. Get the S3 Bucket Policy ```aws s3api get-bucket-policy --bucket ``` 5. Ensure the policy does not contain a `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}**Note:** Principal set to \"\\*\" or {\"AWS\" : \"\\*\"} allows anonymous access.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Allowing public access to CloudTrail log content may aid an adversary in identifying weaknesses in the affected account's use or configuration.","RemediationProcedure": "Perform the following to remove any public access that has been granted to the bucket via an ACL or S3 bucket policy:1. Go to Amazon S3 console at [https://console.aws.amazon.com/s3/home](https://console.aws.amazon.com/s3/home) 2. Right-click on the bucket and click Properties 3. In the `Properties` pane, click the `Permissions` tab. 4. The tab shows a list of grants, one row per grant, in the bucket ACL. Each row identifies the grantee and the permissions granted. 5. Select the row that grants permission to `Everyone` or `Any Authenticated User`6. Uncheck all the permissions granted to `Everyone` or `Any Authenticated User` (click `x` to delete the row). 7. Click `Save` to save the ACL. 8. If the `Edit bucket policy` button is present, click it. 9. Remove any `Statement` having an `Effect` set to `Allow` and a `Principal` set to \"\\*\" or {\"AWS\" : \"\\*\"}.","AdditionalInformation": ""}],"description": "Ensure the S3 bucket used to store CloudTrail logs is not publicly accessible","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"3.4": {"name": "3.4","checks": {"cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-user-guide.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/how-cloudtrail-works.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-aws-service-specific-topics.html","Description": "AWS CloudTrail is a web service that records AWS API calls made in a given AWS account. 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. CloudTrail uses Amazon S3 for log file storage and delivery, so log files are stored durably. In addition to capturing CloudTrail logs within a specified S3 bucket for long term analysis, realtime analysis can be performed by configuring CloudTrail to send logs to CloudWatch Logs. For a trail that is enabled in all regions in an account, CloudTrail sends log files from all those regions to a CloudWatch Logs log group. It is recommended that CloudTrail logs be sent to CloudWatch Logs.Note: The intent of this recommendation is to ensure AWS account activity is being captured, monitored, and appropriately alarmed on. CloudWatch Logs is a native way to accomplish this using AWS services but does not preclude the use of an alternate solution.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure CloudTrail is configured as prescribed:**From Console:**1. Login to the CloudTrail console at `https://console.aws.amazon.com/cloudtrail/` 2. Under `Trails` , click on the CloudTrail you wish to evaluate 3. Under the `CloudWatch Logs` section. 4. Ensure a `CloudWatch Logs` log group is configured and listed. 5. Under `General details` confirm `Last log file delivered` has a recent (~one day old) timestamp.**From Command Line:**1. Run the following command to get a listing of existing trails: ```aws cloudtrail describe-trails ``` 2. Ensure `CloudWatchLogsLogGroupArn` is not empty and note the value of the `Name` property. 3. Using the noted value of the `Name` property, run the following command: ```aws cloudtrail get-trail-status --name  ``` 4. Ensure the `LatestcloudwatchLogdDeliveryTime` property is set to a recent (~one day old) timestamp.If the `CloudWatch Logs` log group is not setup and the delivery time is not recent refer to the remediation below.","ImpactStatement": "Note: By default, CloudWatch Logs will store Logs indefinitely unless a specific retention period is defined for the log group. When choosing the number of days to retain, keep in mind the average days it takes an organization to realize they have been breached is 210 days (at the time of this writing). Since additional time is required to research a breach, a minimum 365 day retention policy allows time for detection and research. You may also wish to archive the logs to a cheaper storage service rather than simply deleting them. See the following AWS resource to manage CloudWatch Logs retention periods:1. https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/SettingLogRetention.html","AssessmentStatus": "Automated","RationaleStatement": "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.","RemediationProcedure": "Perform the following to establish the prescribed state:**From Console:**1. Login to the CloudTrail console at `https://console.aws.amazon.com/cloudtrail/` 2. Select the `Trail` the needs to be updated. 3. Scroll down to `CloudWatch Logs` 4. Click `Edit` 5. Under `CloudWatch Logs` click the box `Enabled` 6. Under `Log Group` pick new or select an existing log group 7. Edit the `Log group name` to match the CloudTrail or pick the existing CloudWatch Group. 8. Under `IAM Role` pick new or select an existing. 9. Edit the `Role name` to match the CloudTrail or pick the existing IAM Role. 10. Click `Save changes.**From Command Line:** ``` aws cloudtrail update-trail --name  --cloudwatch-logs-log-group-arn  --cloudwatch-logs-role-arn  ```","AdditionalInformation": ""}],"description": "Ensure CloudTrail trails are integrated with CloudWatch Logs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.5": {"name": "3.5","checks": {"config_recorder_all_regions_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/cli/latest/reference/configservice/describe-configuration-recorder-status.html","Description": "AWS Config is a web service that performs configuration management of supported AWS resources within your account and delivers log files to you. The recorded information includes the configuration item (AWS resource), relationships between configuration items (AWS resources), any configuration changes between resources. It is recommended AWS Config be enabled in all regions.","DefaultValue": null,"AuditProcedure": "Process to evaluate AWS Config configuration per region**From Console:**1. Sign in to the AWS Management Console and open the AWS Config console at [https://console.aws.amazon.com/config/](https://console.aws.amazon.com/config/). 2. On the top right of the console select target Region. 3. If presented with Setup AWS Config - follow remediation procedure: 4. On the Resource inventory page, Click on edit (the gear icon). The Set Up AWS Config page appears. 5. Ensure 1 or both check-boxes under \"All Resources\" is checked.- Include global resources related to IAM resources - which needs to be enabled in 1 region only 6. Ensure the correct S3 bucket has been defined. 7. Ensure the correct SNS topic has been defined. 8. Repeat steps 2 to 7 for each region.**From Command Line:**1. Run this command to show all AWS Config recorders and their properties: ``` aws configservice describe-configuration-recorders ``` 2. Evaluate the output to ensure that there's at least one recorder for which `recordingGroup` object includes `\"allSupported\": true` AND `\"includeGlobalResourceTypes\": true`Note: There is one more parameter \"ResourceTypes\" in recordingGroup object. We don't need to check the same as whenever we set \"allSupported\": true, AWS enforces resource types to be empty (\"ResourceTypes\":[])Sample Output:``` {\"ConfigurationRecorders\": [{\"recordingGroup\": {\"allSupported\": true,\"resourceTypes\": [],\"includeGlobalResourceTypes\": true},\"roleARN\": \"arn:aws:iam:::role/service-role/\",\"name\": \"default\"}] } ```3. Run this command to show the status for all AWS Config recorders: ``` aws configservice describe-configuration-recorder-status ``` 4. In the output, find recorders with `name` key matching the recorders that met criteria in step 2. Ensure that at least one of them includes `\"recording\": true` and `\"lastStatus\": \"SUCCESS\"`","ImpactStatement": "It is recommended AWS Config be enabled in all regions.","AssessmentStatus": "Automated","RationaleStatement": "The AWS configuration item history captured by AWS Config enables security analysis, resource change tracking, and compliance auditing.","RemediationProcedure": "To implement AWS Config configuration:**From Console:**1. Select the region you want to focus on in the top right of the console 2. Click `Services`3. Click `Config`4. Define which resources you want to record in the selected region 5. Choose to include global resources (IAM resources) 6. Specify an S3 bucket in the same account or in another managed AWS account 7. Create an SNS Topic from the same AWS account or another managed AWS account**From Command Line:**1. Ensure there is an appropriate S3 bucket, SNS topic, and IAM role per the [AWS Config Service prerequisites](http://docs.aws.amazon.com/config/latest/developerguide/gs-cli-prereq.html). 2. Run this command to set up the configuration recorder ``` aws configservice subscribe --s3-bucket my-config-bucket --sns-topic arn:aws:sns:us-east-1:012345678912:my-config-notice --iam-role arn:aws:iam::012345678912:role/myConfigRole ``` 3. Run this command to start the configuration recorder: ``` start-configuration-recorder --configuration-recorder-name  ```","AdditionalInformation": ""}],"description": "Ensure AWS Config is enabled in all regions","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.6": {"name": "3.6","checks": {"cloudtrail_logs_s3_bucket_access_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerLogs.html","Description": "S3 Bucket Access Logging generates a log that contains access records for each request made to your S3 bucket. An access log record contains details about the request, such as the request type, the resources specified in the request worked, and the time and date the request was processed. It is recommended that bucket access logging be enabled on the CloudTrail S3 bucket.","DefaultValue": null,"AuditProcedure": "Perform the following ensure the CloudTrail S3 bucket has access logging is enabled:**From Console:**1. Go to the Amazon CloudTrail console at [https://console.aws.amazon.com/cloudtrail/home](https://console.aws.amazon.com/cloudtrail/home) 2. In the API activity history pane on the left, click Trails 3. In the Trails pane, note the bucket names in the S3 bucket column 4. Sign in to the AWS Management Console and open the S3 console at [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3). 5. Under `All Buckets` click on a target S3 bucket 6. Click on `Properties` in the top right of the console 7. Under `Bucket:` _ `` _ click on `Logging`8. Ensure `Enabled` is checked.**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ```aws cloudtrail describe-trails --query 'trailList[*].S3BucketName'``` 2. Ensure Bucket Logging is enabled: ``` aws s3api get-bucket-logging --bucket  ``` Ensure command does not returns empty output.Sample Output for a bucket with logging enabled:``` {\"LoggingEnabled\": {\"TargetPrefix\": \"\",\"TargetBucket\": \"\"} } ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "By enabling S3 bucket logging on target S3 buckets, it is possible to capture all events which may affect objects within any target buckets. Configuring logs to be placed in a separate bucket allows access to log information which can be useful in security and incident response workflows.","RemediationProcedure": "Perform the following to enable S3 bucket logging:**From Console:**1. Sign in to the AWS Management Console and open the S3 console at [https://console.aws.amazon.com/s3](https://console.aws.amazon.com/s3). 2. Under `All Buckets` click on the target S3 bucket 3. Click on `Properties` in the top right of the console 4. Under `Bucket:`  click on `Logging`5. Configure bucket logging- Click on the `Enabled` checkbox- Select Target Bucket from list- Enter a Target Prefix 6. Click `Save`.**From Command Line:**1. Get the name of the S3 bucket that CloudTrail is logging to: ``` aws cloudtrail describe-trails --region  --query trailList[*].S3BucketName ``` 2. Copy and add target bucket name at ``, Prefix for logfile at `` and optionally add an email address in the following template and save it as ``: ``` {\"LoggingEnabled\": {\"TargetBucket\": \"\",\"TargetPrefix\": \"\",\"TargetGrants\": [{\"Grantee\": {\"Type\": \"AmazonCustomerByEmail\",\"EmailAddress\": \"\"},\"Permission\": \"FULL_CONTROL\"}]}} ``` 3. Run the `put-bucket-logging` command with bucket name and `` as input, for more information refer at [put-bucket-logging](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-logging.html): ``` aws s3api put-bucket-logging --bucket  --bucket-logging-status file:// ```","AdditionalInformation": ""}],"description": "Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.7": {"name": "3.7","checks": {"cloudtrail_kms_encryption_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/encrypting-cloudtrail-log-files-with-aws-kms.html:https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html","Description": "AWS CloudTrail is a web service that records AWS API calls for an account and makes those logs available to users and resources in accordance with IAM policies. AWS Key Management Service (KMS) is a managed service that helps create and control the encryption keys used to encrypt account data, and uses Hardware Security Modules (HSMs) to protect the security of encryption keys. CloudTrail logs can be configured to leverage server side encryption (SSE) and KMS customer created master keys (CMK) to further protect CloudTrail logs. It is recommended that CloudTrail be configured to use SSE-KMS.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if CloudTrail is configured to use SSE-KMS:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. In the left navigation pane, choose `Trails` . 3. Select a Trail 4. Under the `S3` section, ensure `Encrypt log files` is set to `Yes` and a KMS key ID is specified in the `KSM Key Id` field.**From Command Line:**1. Run the following command: ```aws cloudtrail describe-trails``` 2. For each trail listed, SSE-KMS is enabled if the trail has a `KmsKeyId` property defined.","ImpactStatement": "Customer created keys incur an additional cost. See https://aws.amazon.com/kms/pricing/ for more information.","AssessmentStatus": "Automated","RationaleStatement": "Configuring CloudTrail to use SSE-KMS provides additional confidentiality controls on log data as a given user must have S3 read permission on the corresponding log bucket and must be granted decrypt permission by the CMK policy.","RemediationProcedure": "Perform the following to configure CloudTrail to use SSE-KMS:**From Console:**1. Sign in to the AWS Management Console and open the CloudTrail console at [https://console.aws.amazon.com/cloudtrail](https://console.aws.amazon.com/cloudtrail) 2. In the left navigation pane, choose `Trails` . 3. Click on a Trail 4. Under the `S3` section click on the edit button (pencil icon) 5. Click `Advanced`6. Select an existing CMK from the `KMS key Id` drop-down menu- Note: Ensure the CMK is located in the same region as the S3 bucket- Note: You will need to apply a KMS Key policy on the selected CMK in order for CloudTrail as a service to encrypt and decrypt log files using the CMK provided. Steps are provided [here](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/create-kms-key-policy-for-cloudtrail.html) for editing the selected CMK Key policy 7. Click `Save`8. You will see a notification message stating that you need to have decrypt permissions on the specified KMS key to decrypt log files. 9. Click `Yes` **From Command Line:** ``` aws cloudtrail update-trail --name  --kms-id  aws kms put-key-policy --key-id  --policy  ```","AdditionalInformation": "3 statements which need to be added to the CMK policy:1\\. Enable Cloudtrail to describe CMK properties ``` 
{\"Sid\": \"Allow CloudTrail access\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\"Action\": \"kms:DescribeKey\",\"Resource\": \"*\" } ``` 2\\. Granting encrypt permissions ``` 
{\"Sid\": \"Allow CloudTrail to encrypt logs\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"cloudtrail.amazonaws.com\"},\"Action\": \"kms:GenerateDataKey*\",\"Resource\": \"*\",\"Condition\": {\"StringLike\": {\"kms:EncryptionContext:aws:cloudtrail:arn\": [\"arn:aws:cloudtrail:*:aws-account-id:trail/*\"]}} } ``` 3\\. Granting decrypt permissions ``` 
{\"Sid\": \"Enable CloudTrail log decrypt permissions\",\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"arn:aws:iam::aws-account-id:user/username\"},\"Action\": \"kms:Decrypt\",\"Resource\": \"*\",\"Condition\": {\"Null\": {\"kms:EncryptionContext:aws:cloudtrail:arn\": \"false\"}} } ```"}],"description": "Ensure CloudTrail logs are encrypted at rest using KMS CMKs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"3.8": {"name": "3.8","checks": {"kms_cmk_rotation_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://aws.amazon.com/kms/pricing/:https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final","Description": "AWS Key Management Service (KMS) allows customers to rotate the backing key which is key material stored within the KMS which is tied to the key ID of the Customer Created customer master key (CMK). It is the backing key that is used to perform cryptographic operations such as encryption and decryption. Automated key rotation currently retains all prior backing keys so that decryption of encrypted data can take place transparently. It is recommended that CMK key rotation be enabled for symmetric keys. Key rotation can not be enabled for any asymmetric CMK.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam](https://console.aws.amazon.com/iam). 2. In the left navigation pane, choose `Customer managed keys` 3. Select a customer managed CMK where `Key spec = SYMMETRIC_DEFAULT` 4. Underneath the `General configuration` panel open the tab `Key rotation` 5. Ensure that the checkbox `Automatically rotate this KMS key every year.` is activated 6. Repeat steps 3 - 5 for all customer managed CMKs where \"Key spec = SYMMETRIC_DEFAULT\"**From Command Line:**1. Run the following command to get a list of all keys and their associated `KeyIds````aws kms list-keys ``` 2. For each key, note the KeyId and run the following command ``` describe-key --key-id  ``` 3. If the response contains \"KeySpec = SYMMETRIC_DEFAULT\" run the following command ```aws kms get-key-rotation-status --key-id  ``` 4. Ensure `KeyRotationEnabled` is set to `true` 5. Repeat steps 2 - 4 for all remaining CMKs","ImpactStatement": "Creation, management, and storage of CMKs may require additional time from and administrator.","AssessmentStatus": "Automated","RationaleStatement": "Rotating encryption keys helps reduce the potential impact of a compromised key as data encrypted with a new key cannot be accessed with a previous key that may have been exposed. Keys should be rotated every year, or upon event that would result in the compromise of that key.","RemediationProcedure": "**From Console:**1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam](https://console.aws.amazon.com/iam). 2. In the left navigation pane, choose `Customer managed keys` . 3. Select a customer managed CMK where `Key spec = SYMMETRIC_DEFAULT` 4. Underneath the \"General configuration\" panel open the tab \"Key rotation\" 5. Check the \"Automatically rotate this KMS key every year.\" checkbox**From Command Line:**1. Run the following command to enable key rotation: ```aws kms enable-key-rotation --key-id  ```","AdditionalInformation": ""}],"description": "Ensure rotation for customer created symmetric CMKs is enabled","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.9": {"name": "3.9","checks": {"vpc_flow_logs_enabled": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/flow-logs.html","Description": "VPC Flow Logs is a feature that enables you to capture information about the IP traffic going to and from network interfaces in your VPC. After you've created a flow log, you can view and retrieve its data in Amazon CloudWatch Logs. It is recommended that VPC Flow Logs be enabled for packet \"Rejects\" for VPCs.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if VPC Flow logs are enabled:**From Console:**1. Sign into the management console 2. Select `Services` then `VPC`3. In the left navigation pane, select `Your VPCs`4. Select a VPC 5. In the right pane, select the `Flow Logs` tab. 6. Ensure a Log Flow exists that has `Active` in the `Status` column.**From Command Line:**1. Run `describe-vpcs` command (OSX/Linux/UNIX) to list the VPC networks available in the current AWS region: ``` aws ec2 describe-vpcs --region  --query Vpcs[].VpcId ``` 2. The command output returns the `VpcId` available in the selected region. 3. Run `describe-flow-logs` command (OSX/Linux/UNIX) using the VPC ID to determine if the selected virtual network has the Flow Logs feature enabled: ``` aws ec2 describe-flow-logs --filter \"Name=resource-id,Values=\" ``` 4. If there are no Flow Logs created for the selected VPC, the command output will return an `empty list []`. 5. Repeat step 3 for other VPCs available in the same region. 6. Change the region by updating `--region` and repeat steps 1 - 5 for all the VPCs.","ImpactStatement": "By default, CloudWatch Logs will store Logs indefinitely unless a specific retention period is defined for the log group. When choosing the number of days to retain, keep in mind the average days it takes an organization to realize they have been breached is 210 days (at the time of this writing). Since additional time is required to research a breach, a minimum 365 day retention policy allows time for detection and research. You may also wish to archive the logs to a cheaper storage service rather than simply deleting them. See the following AWS resource to manage CloudWatch Logs retention periods:1. https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/SettingLogRetention.html","AssessmentStatus": "Automated","RationaleStatement": "VPC Flow Logs provide visibility into network traffic that traverses the VPC and can be used to detect anomalous traffic or insight during security workflows.","RemediationProcedure": "Perform the following to determine if VPC Flow logs is enabled:**From Console:**1. Sign into the management console 2. Select `Services` then `VPC`3. In the left navigation pane, select `Your VPCs`4. Select a VPC 5. In the right pane, select the `Flow Logs` tab. 6. If no Flow Log exists, click `Create Flow Log`7. For Filter, select `Reject` 8. Enter in a `Role` and `Destination Log Group`9. Click `Create Log Flow`10. Click on `CloudWatch Logs Group` **Note:** Setting the filter to \"Reject\" will dramatically reduce the logging data accumulation for this recommendation and provide sufficient information for the purposes of breach detection, research and remediation. However, during periods of least privilege security group engineering, setting this the filter to \"All\" can be very helpful in discovering existing traffic flows required for proper operation of an already running environment.**From Command Line:**1. Create a policy document and name it as `role_policy_document.json` and paste the following content: ``` {\"Version\": \"2012-10-17\",\"Statement\": [{\"Sid\": \"test\",\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"ec2.amazonaws.com\"},\"Action\": \"sts:AssumeRole\"}] } ``` 2. Create another policy document and name it as `iam_policy.json` and paste the following content: ``` {\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Action\":[\"logs:CreateLogGroup\",\"logs:CreateLogStream\",\"logs:DescribeLogGroups\",\"logs:DescribeLogStreams\",\"logs:PutLogEvents\",\"logs:GetLogEvents\",\"logs:FilterLogEvents\"],\"Resource\": \"*\"}] } ``` 3. Run the below command to create an IAM role: ``` aws iam create-role --role-name  --assume-role-policy-document file://role_policy_document.json``` 4. Run the below command to create an IAM policy: ``` aws iam create-policy --policy-name  --policy-document file://iam-policy.json ``` 5. Run `attach-group-policy` command using the IAM policy ARN returned at the previous step to attach the policy to the IAM role (if the command succeeds, no output is returned): ``` aws iam attach-group-policy --policy-arn arn:aws:iam:::policy/ --group-name  ``` 6. Run `describe-vpcs` to get the VpcId available in the selected region: ``` aws ec2 describe-vpcs --region  ``` 7. The command output should return the VPC Id available in the selected region. 8. Run `create-flow-logs` to create a flow log for the vpc: ``` aws ec2 create-flow-logs --resource-type VPC --resource-ids  --traffic-type REJECT --log-group-name  --deliver-logs-permission-arn  ``` 9. Repeat step 8 for other vpcs available in the selected region. 10. Change the region by updating --region and repeat remediation procedure for other vpcs.","AdditionalInformation": ""}],"description": "Ensure VPC flow logging is enabled in all VPCs","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"4.1": {"name": "4.1","checks": {"cloudwatch_log_metric_filter_unauthorized_api_calls": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://aws.amazon.com/sns/:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for unauthorized API calls.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with \"Name\":` note ``- From value associated with \"CloudWatchLogsLogGroupArn\" note Example: for CloudWatchLogsLogGroupArn that looks like arn:aws:logs:::log-group:NewGroup:*,  would be NewGroup- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name <\"Name\" as shown in describe-trails>`Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this `` that you captured in step 1:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.errorCode = *UnauthorizedOperation) || ($.errorCode = AccessDenied*) || ($.sourceIPAddress!=delivery.logs.amazonaws.com) || ($.eventName!=HeadBucket) }\", ```4. Note the \"filterName\" `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query \"MetricAlarms[?MetricName == `unauthorized_api_calls_metric`]\" ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "This alert may be triggered by normal read-only console activities that attempt to opportunistically gather optional information, but gracefully fail if they don't have permissions.If an excessive number of alerts are being generated then an organization may wish to consider adding read access to the limited IAM user permissions simply to quiet the alerts.In some cases doing this may allow the users to actually view some areas of the system - any additional access given should be reviewed for alignment with the original limited IAM user intent.","AssessmentStatus": "Automated","RationaleStatement": "Monitoring unauthorized API calls will help reveal application errors and may reduce time to detect malicious activity.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for unauthorized API calls and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name \"cloudtrail_log_group_name\" --filter-name \"\" --metric-transformations metricName=unauthorized_api_calls_metric,metricNamespace=CISBenchmark,metricValue=1 --filter-pattern \"{ ($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\") || ($.sourceIPAddress!=\"delivery.logs.amazonaws.com\") || ($.eventName!=\"HeadBucket\") }\" ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms. **Note**: Capture the TopicArn displayed when creating the SNS Topic in Step 2.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name \"unauthorized_api_calls_alarm\" --metric-name \"unauthorized_api_calls_metric\" --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace \"CISBenchmark\" --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for unauthorized API calls","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.2": {"name": "4.2","checks": {"cloudwatch_log_metric_filter_sign_in_without_mfa": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/viewing_metrics_with_cloudwatch.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for console logins that are not protected by multi-factor authentication (MFA).","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all `CloudTrails`:``` aws cloudtrail describe-trails ```- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region `CloudTrail` is active``` aws cloudtrail get-trail-status --name  ```Ensure in the output that `IsLogging` is set to `TRUE`- Ensure identified Multi-region 'Cloudtrail' captures all Management Events``` aws cloudtrail get-event-selectors --trail-name  ```Ensure in the output there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }\" ```Or (To reduce false positives incase Single Sign-On (SSO) is used in organization):``` \"filterPattern\": \"{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\") }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring for single-factor console logins will increase visibility into accounts that are not protected by MFA.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Management Console sign-in without MFA and the `` taken from audit step 1.Use Command: ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }' ```Or (To reduce false positives incase Single Sign-On (SSO) is used in organization):``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\") }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored -Filter pattern set to `{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.type = \"IAMUser\") && ($.responseElements.ConsoleLogin = \"Success\"}` reduces false alarms raised when user logs in via SSO account."}],"description": "Ensure a log metric filter and alarm exist for Management Console sign-in without MFA","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.3": {"name": "4.3","checks": {"cloudwatch_log_metric_filter_root_usage": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for 'root' login attempts.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails:`aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring for 'root' account logins will provide visibility into the use of a fully privileged account and an opportunity to reduce the use of it.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for 'Root' account usage and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name `` --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "**Configuring log metric filter and alarm on Multi-region (global) CloudTrail**- ensures that activities from all regions (used as well as unused) are monitored- ensures that activities on all supported global services are monitored- ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for usage of 'root' account","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.4": {"name": "4.4","checks": {"cloudwatch_log_metric_filter_policy_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established changes made to Identity and Access Management (IAM) policies.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails:`aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to IAM policies will help ensure authentication and authorization controls remain intact.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for IAM policy changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name `` --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for IAM policy changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.5": {"name": "4.5","checks": {"cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for detecting changes to CloudTrail's configurations.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to CloudTrail's configuration will help ensure sustained visibility to activities performed in the AWS account.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for cloudtrail configuration changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for CloudTrail configuration changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.6": {"name": "4.6","checks": {"cloudwatch_log_metric_filter_authentication_failures": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for failed console authentication attempts.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring failed console logins may decrease lead time to detect an attempt to brute force a credential, which may provide an indicator, such as source IP, that can be used in other event correlation.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS management Console Login Failures and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }' ``` **Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for AWS Management Console authentication failures","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.7": {"name": "4.7","checks": {"cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for customer created CMKs which have changed state to disabled or scheduled deletion.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Data encrypted with disabled or deleted keys will no longer be accessible.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for disabled or scheduled for deletion CMK's and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }' ``` **Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ``` **Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.8": {"name": "4.8","checks": {"cloudwatch_log_metric_filter_for_s3_bucket_policy_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for changes to S3 bucket policies.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to S3 bucket policies may reduce time to detect and correct permissive policies on sensitive S3 buckets.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for S3 bucket policy changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for S3 bucket policy changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.9": {"name": "4.9","checks": {"cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for detecting changes to CloudTrail's configurations.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to AWS Config configuration will help ensure sustained visibility of configuration items within the AWS account.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Configuration changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for AWS Config configuration changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"5.1": {"name": "5.1","checks": {"ec2_networkacl_allow_ingress_any_port": "FAIL","ec2_networkacl_allow_ingress_tcp_port_22": "FAIL","ec2_networkacl_allow_ingress_tcp_port_3389": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html:https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Security.html#VPC_Security_Comparison","Description": "The Network Access Control List (NACL) function provide stateless filtering of ingress and egress network traffic to AWS resources. It is recommended that no NACL allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "**From Console:**Perform the following to determine if the account is configured as prescribed: 1. Login to the AWS Management Console at https://console.aws.amazon.com/vpc/home 2. In the left pane, click `Network ACLs` 3. For each network ACL, perform the following:- Select the network ACL- Click the `Inbound Rules` tab- Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `0.0.0.0/0` and shows `ALLOW`**Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "**From Console:**Perform the following: 1. Login to the AWS Management Console at https://console.aws.amazon.com/vpc/home 2. In the left pane, click `Network ACLs` 3. For each network ACL to remediate, perform the following:- Select the network ACL- Click the `Inbound Rules` tab- Click `Edit inbound rules`- Either A) update the Source field to a range other than 0.0.0.0/0, or, B) Click `Delete` to remove the offending inbound rule- Click `Save`","AdditionalInformation": ""}],"description": "Ensure no Network ACLs allow ingress from 0.0.0.0/0 to remote server administration ports","checks_status": {"fail": 3,"pass": 0,"total": 3,"manual": 0}},"5.2": {"name": "5.2","checks": {"ec2_securitygroup_allow_ingress_from_internet_to_all_ports": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#deleting-security-group-rule","Description": "Security groups provide stateful filtering of ingress and egress network traffic to AWS resources. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port `22` and RDP to port `3389`.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exists that has a port range that includes port `22`, `3389`, or other remote server administration ports for your environment and has a `Source` of `0.0.0.0/0` **Note:** A Port value of `ALL` or a port range such as `0-1024` are inclusive of port `22`, `3389`, and other remote server administration ports.","ImpactStatement": "When updating an existing environment, ensure that administrators have access to remote server administration ports through another mechanism before removing access by deleting the 0.0.0.0/0 inbound rule.","AssessmentStatus": "Automated","RationaleStatement": "Public access to remote server administration ports, such as 22 and 3389, increases resource attack surface and unnecessarily raises the risk of resource compromise.","RemediationProcedure": "Perform the following to implement the prescribed state:1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. In the left pane, click `Security Groups`3. For each security group, perform the following: 1. Select the security group 2. Click the `Inbound Rules` tab 3. Click the `Edit inbound rules` button 4. Identify the rules to be edited or removed 5. Either A) update the Source field to a range other than 0.0.0.0/0, or, B) Click `Delete` to remove the offending inbound rule 6. Click `Save rules`","AdditionalInformation": ""}],"description": "Ensure no security groups allow ingress from 0.0.0.0/0 to remote server administration ports","checks_status": {"fail": 0,"pass": 3,"total": 3,"manual": 0}},"5.3": {"name": "5.3","checks": {"ec2_securitygroup_default_restrict_traffic": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "5. Networking","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#default-security-group","Description": "A VPC comes with a default security group whose initial settings deny all inbound traffic, allow all outbound traffic, and allow all traffic between instances assigned to the security group. If you don't specify a security group when you launch an instance, the instance is automatically assigned to this default security group. Security groups provide stateful filtering of ingress/egress network traffic to AWS resources. It is recommended that the default security group restrict all traffic.The default VPC in every region should have its default security group updated to comply. Any newly created VPCs will automatically contain a default security group that will need remediation to comply with this recommendation.**NOTE:** When implementing this recommendation, VPC flow logging is invaluable in determining the least privilege port access required by systems to work properly because it can log all packet acceptances and rejections occurring under the current security groups. This dramatically reduces the primary barrier to least privilege engineering - discovering the minimum ports required by systems in the environment. Even if the VPC flow logging recommendation in this benchmark is not adopted as a permanent security measure, it should be used during any period of discovery and engineering for least privileged security groups.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if the account is configured as prescribed:Security Group State1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. For each default security group, perform the following: 1. Select the `default` security group 2. Click the `Inbound Rules` tab 3. Ensure no rule exist 4. Click the `Outbound Rules` tab 5. Ensure no rules existSecurity Group Members1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all default groups in all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. Copy the id of the default security group. 5. Change to the EC2 Management Console at https://console.aws.amazon.com/ec2/v2/home 6. In the filter column type 'Security Group ID : < security group id from #4 >'","ImpactStatement": "Implementing this recommendation in an existing VPC containing operating resources requires extremely careful migration planning as the default security groups are likely to be enabling many ports that are unknown. Enabling VPC flow logging (of accepts) in an existing environment that is known to be breach free will reveal the current pattern of ports being used for each instance to communicate successfully.","AssessmentStatus": "Automated","RationaleStatement": "Configuring all VPC default security groups to restrict all traffic will encourage least privilege security group development and mindful placement of AWS resources into security groups which will in-turn reduce the exposure of those resources.","RemediationProcedure": "Security Group MembersPerform the following to implement the prescribed state:1. Identify AWS resources that exist within the default security group 2. Create a set of least privilege security groups for those resources 3. Place the resources in those security groups 4. Remove the resources noted in #1 from the default security groupSecurity Group State1. Login to the AWS Management Console at [https://console.aws.amazon.com/vpc/home](https://console.aws.amazon.com/vpc/home) 2. Repeat the next steps for all VPCs - including the default VPC in each AWS region: 3. In the left pane, click `Security Groups`4. For each default security group, perform the following: 1. Select the `default` security group 2. Click the `Inbound Rules` tab 3. Remove any inbound rules 4. Click the `Outbound Rules` tab 5. Remove any Outbound rulesRecommended:IAM groups allow you to edit the \"name\" field. After remediating default groups rules for all VPCs in all regions, edit this field to add text similar to \"DO NOT USE. DO NOT ADD RULES\"","AdditionalInformation": ""}],"description": "Ensure the default security group of every VPC restricts all traffic","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"5.4": {"name": "5.4","checks": {"vpc_peering_routing_tables_with_least_privilege": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "5. Networking","References": "https://docs.aws.amazon.com/AmazonVPC/latest/PeeringGuide/peering-configurations-partial-access.html:https://docs.aws.amazon.com/cli/latest/reference/ec2/create-vpc-peering-connection.html","Description": "Once a VPC peering connection is established, routing tables must be updated to establish any connections between the peered VPCs. These routes can be as specific as desired - even peering a VPC to only a single host on the other side of the connection.","DefaultValue": null,"AuditProcedure": "Review routing tables of peered VPCs for whether they route all subnets of each VPC and whether that is necessary to accomplish the intended purposes for peering the VPCs.**From Command Line:**1. List all the route tables from a VPC and check if \"GatewayId\" is pointing to a __ (e.g. pcx-1a2b3c4d) and if \"DestinationCidrBlock\" is as specific as desired. ``` aws ec2 describe-route-tables --filter \"Name=vpc-id,Values=\" --query \"RouteTables[*].{RouteTableId:RouteTableId, VpcId:VpcId, Routes:Routes, AssociatedSubnets:Associations[*].SubnetId}\" ```","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Being highly selective in peering routing tables is a very effective way of minimizing the impact of breach as resources outside of these routes are inaccessible to the peered VPC.","RemediationProcedure": "Remove and add route table entries to ensure that the least number of subnets or hosts as is required to accomplish the purpose for peering are routable.**From Command Line:**1. For each __ containing routes non compliant with your routing policy (which grants more than desired \"least access\"), delete the non compliant route: ``` aws ec2 delete-route --route-table-id  --destination-cidr-block  ```2. Create a new compliant route: ``` aws ec2 create-route --route-table-id  --destination-cidr-block  --vpc-peering-connection-id  ```","AdditionalInformation": "If an organization has AWS transit gateway implemented in their VPC architecture they should look to apply the recommendation above for \"least access\" routing architecture at the AWS transit gateway level in combination with what must be implemented at the standard VPC route table. More specifically, to route traffic between two or more VPCs via a transit gateway VPCs must have an attachment to a transit gateway route table as well as a route, therefore to avoid routing traffic between VPCs an attachment to the transit gateway route table should only be added where there is an intention to route traffic between the VPCs. As transit gateways are able to host multiple route tables it is possible to group VPCs by attaching them to a common route table."}],"description": "Ensure routing tables for VPC peering are \"least access\"","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.10": {"name": "1.10","checks": {"iam_user_mfa_enabled_console_access": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://tools.ietf.org/html/rfc6238:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#enable-mfa-for-privileged-users:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html:https://blogs.aws.amazon.com/security/post/Tx2SJJYE082KBUK/How-to-Delegate-Management-of-Multi-Factor-Authentication-to-AWS-IAM-Users","Description": "Multi-Factor Authentication (MFA) adds an extra layer of authentication assurance beyond traditional credentials. With MFA enabled, when a user signs in to the AWS Console, they will be prompted for their user name and password as well as for an authentication code from their physical or virtual MFA token. It is recommended that MFA be enabled for all accounts that have a console password.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if a MFA device is enabled for all IAM users having a console password:**From Console:**1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the left pane, select `Users`3. If the `MFA` or `Password age` columns are not visible in the table, click the gear icon at the upper right corner of the table and ensure a checkmark is next to both, then click `Close`. 4. Ensure that for each user where the `Password age` column shows a password age, the `MFA` column shows `Virtual`, `U2F Security Key`, or `Hardware`.**From Command Line:**1. Run the following command (OSX/Linux/UNIX) to generate a list of all IAM users along with their password and MFA status: ```aws iam generate-credential-report ``` ```aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,8``` 2. The output of this command will produce a table similar to the following: ```user,password_enabled,mfa_activeelise,false,falsebrandon,true,truerakesh,false,falsehelene,false,falseparas,true,trueanitha,false,false``` 3. For any column having `password_enabled` set to `true` , ensure `mfa_active` is also set to `true.`","ImpactStatement": "AWS will soon end support for SMS multi-factor authentication (MFA). New customers are not allowed to use this feature. We recommend that existing customers switch to one of the following alternative methods of MFA.","AssessmentStatus": "Automated","RationaleStatement": "Enabling MFA provides increased security for console access as it requires the authenticating principal to possess a device that displays a time-sensitive key and have knowledge of a credential.","RemediationProcedure": "Perform the following to enable MFA:**From Console:**1. Sign in to the AWS Management Console and open the IAM console at 'https://console.aws.amazon.com/iam/' 2. In the left pane, select `Users`. 3. In the `User Name` list, choose the name of the intended MFA user. 4. Choose the `Security Credentials` tab, and then choose `Manage MFA Device`. 5. In the `Manage MFA Device wizard`, choose `Virtual MFA` device, and then choose `Continue`. IAM generates and displays configuration information for the virtual MFA device, including a QR code graphic. The graphic is a representation of the 'secret configuration key' that is available for manual entry on devices that do not support QR codes.6. Open your virtual MFA application. (For a list of apps that you can use for hosting virtual MFA devices, see Virtual MFA Applications at https://aws.amazon.com/iam/details/mfa/#Virtual_MFA_Applications). If the virtual MFA application supports multiple accounts (multiple virtual MFA devices), choose the option to create a new account (a new virtual MFA device). 7. Determine whether the MFA app supports QR codes, and then do one of the following: - Use the app to scan the QR code. For example, you might choose the camera icon or choose an option similar to Scan code, and then use the device's camera to scan the code.- In the Manage MFA Device wizard, choose Show secret key for manual configuration, and then type the secret configuration key into your MFA application. When you are finished, the virtual MFA device starts generating one-time passwords.8. In the `Manage MFA Device wizard`, in the `MFA Code 1 box`, type the `one-time password` that currently appears in the virtual MFA device. Wait up to 30 seconds for the device to generate a new one-time password. Then type the second `one-time password` into the `MFA Code 2 box`.9. Click `Assign MFA`.","AdditionalInformation": "**Forced IAM User Self-Service Remediation**Amazon has published a pattern that forces users to self-service setup MFA before they have access to their complete permissions set. Until they complete this step, they cannot access their full permissions. This pattern can be used on new AWS accounts. It can also be used on existing accounts - it is recommended users are given instructions and a grace period to accomplish MFA enrollment before active enforcement on existing AWS accounts."}],"description": "Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.11": {"name": "1.11","checks": {"iam_user_no_setup_initial_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/cli/latest/reference/iam/delete-access-key.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html","Description": "AWS console defaults to no check boxes selected when creating a new IAM user. When cerating the IAM User credentials you have to determine what type of access they require. Programmatic access: The IAM user might need to make API calls, use the AWS CLI, or use the Tools for Windows PowerShell. In that case, create an access key (access key ID and a secret access key) for that user. AWS Management Console access: If the user needs to access the AWS Management Console, create a password for the user.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if access keys were created upon user creation and are being used and rotated as prescribed:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM`4. Click on a User where column `Password age` and `Access key age` is not set to `None` 5. Click on `Security credentials` Tab 6. Compare the user 'Creation time` to the Access Key `Created` date. 6. For any that match, the key was created during initial user setup.- Keys that were created at the same time as the user profile and do not have a last used date should be deleted. Refer to the remediation below.**From Command Line:**1. Run the following command (OSX/Linux/UNIX) to generate a list of all IAM users along with their access keys utilization: ```aws iam generate-credential-report ``` ```aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,9,11,14,16 ``` 2. The output of this command will produce a table similar to the following: ``` user,password_enabled,access_key_1_active,access_key_1_last_used_date,access_key_2_active,access_key_2_last_used_dateelise,false,true,2015-04-16T15:14:00+00:00,false,N/Abrandon,true,true,N/A,false,N/Arakesh,false,false,N/A,false,N/Ahelene,false,true,2015-11-18T17:47:00+00:00,false,N/Aparas,true,true,2016-08-28T12:04:00+00:00,true,2016-03-04T10:11:00+00:00anitha,true,true,2016-06-08T11:43:00+00:00,true,N/A``` 3. For any user having `password_enabled` set to `true` AND `access_key_last_used_date` set to `N/A` refer to the remediation below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Requiring the additional steps be taken by the user for programmatic access after their profile has been created will give a stronger indication of intent that access keys are [a] necessary for their work and [b] once the access key is established on an account that the keys may be in use somewhere in the organization.**Note**: Even if it is known the user will need access keys, require them to create the keys themselves or put in a support ticket to have them created as a separate step from user creation.","RemediationProcedure": "Perform the following to delete access keys that do not pass the audit:**From Console:**1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. As an Administrator - Click on the X `(Delete)` for keys that were created at the same time as the user profile but have not been used. 7. As an IAM User- Click on the X `(Delete)` for keys that were created at the same time as the user profile but have not been used.**From Command Line:** ``` aws iam delete-access-key --access-key-id  --user-name  ```","AdditionalInformation": "Credential report does not appear to contain \"Key Creation Date\""}],"description": "Do not setup access keys during initial user setup for all IAM users that have a console password","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.12": {"name": "1.12","checks": {"iam_user_accesskey_unused": null,"iam_user_console_access_unused": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#remove-credentials:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_admin-change-user.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "AWS IAM users can access AWS resources using different types of credentials, such as passwords or access keys. It is recommended that all credentials that have been unused in 45 or greater days be deactivated or removed.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if unused credentials exist:**From Console:**1. Login to the AWS Management Console 2. Click `Services`3. Click `IAM` 4. Click on `Users` 5. Click the `Settings` (gear) icon. 6. Select `Console last sign-in`, `Access key last used`, and `Access Key Id` 7. Click on `Close`8. Check and ensure that `Console last sign-in` is less than 45 days ago.**Note** - `Never` means the user has never logged in.9. Check and ensure that `Access key age` is less than 45 days and that `Access key last used` does not say `None`If the user hasn't signed into the Console in the last 45 days or Access keys are over 45 days old refer to the remediation.**From Command Line:****Download Credential Report:**1. Run the following commands: ```aws iam generate-credential-report aws iam get-credential-report --query 'Content' --output text | base64 -d | cut -d, -f1,4,5,6,9,10,11,14,15,16 | grep -v '^' ```**Ensure unused credentials do not exist:**2. For each user having `password_enabled` set to `TRUE` , ensure `password_last_used_date` is less than `45` days ago.- When `password_enabled` is set to `TRUE` and `password_last_used` is set to `No_Information` , ensure `password_last_changed` is less than 45 days ago.3. For each user having an `access_key_1_active` or `access_key_2_active` to `TRUE` , ensure the corresponding `access_key_n_last_used_date` is less than `45` days ago.- When a user having an `access_key_x_active` (where x is 1 or 2) to `TRUE` and corresponding access_key_x_last_used_date is set to `N/A', ensure `access_key_x_last_rotated` is less than 45 days ago.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Disabling or removing unnecessary credentials will reduce the window of opportunity for credentials associated with a compromised or abandoned account to be used.","RemediationProcedure": "**From Console:**Perform the following to manage Unused Password (IAM user console access)1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. Select user whose `Console last sign-in` is greater than 45 days 7. Click `Security credentials` 8. In section `Sign-in credentials`, `Console password` click `Manage`9. Under Console Access select `Disable` 10.Click `Apply`Perform the following to deactivate Access Keys:1. Login to the AWS Management Console: 2. Click `Services`3. Click `IAM`4. Click on `Users`5. Click on `Security Credentials`6. Select any access keys that are over 45 days old and that have been used and - Click on `Make Inactive` 7. Select any access keys that are over 45 days old and that have not been used and - Click the X to `Delete`","AdditionalInformation": " is excluded in the audit since the root account should not be used for day to day business and would likely be unused for more than 45 days."}],"description": "Ensure credentials unused for 45 days or greater are disabled","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1.13": {"name": "1.13","checks": {"iam_user_two_active_access_key": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "Access keys are long-term credentials for an IAM user or the AWS account 'root' user. You can use access keys to sign programmatic requests to the AWS CLI or AWS API (directly or using the AWS SDK)","DefaultValue": null,"AuditProcedure": "**From Console:**1. Sign in to the AWS Management Console and navigate to IAM dashboard at `https://console.aws.amazon.com/iam/`. 2. In the left navigation panel, choose `Users`. 3. Click on the IAM user name that you want to examine. 4. On the IAM user configuration page, select `Security Credentials` tab. 5. Under `Access Keys` section, in the Status column, check the current status for each access key associated with the IAM user. If the selected IAM user has more than one access key activated then the users access configuration does not adhere to security best practices and the risk of accidental exposures increases. - Repeat steps no. 3 – 5 for each IAM user in your AWS account.**From Command Line:**1. Run `list-users` command to list all IAM users within your account: ``` aws iam list-users --query \"Users[*].UserName\" ``` The command output should return an array that contains all your IAM user names.2. Run `list-access-keys` command using the IAM user name list to return the current status of each access key associated with the selected IAM user: ``` aws iam list-access-keys --user-name  ``` The command output should expose the metadata `(\"Username\", \"AccessKeyId\", \"Status\", \"CreateDate\")` for each access key on that user account.3. Check the `Status` property value for each key returned to determine each keys current state. If the `Status` property value for more than one IAM access key is set to `Active`, the user access configuration does not adhere to this recommendation, refer to the remediation below.- Repeat steps no. 2 and 3 for each IAM user in your AWS account.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Access keys are long-term credentials for an IAM user or the AWS account 'root' user. You can use access keys to sign programmatic requests to the AWS CLI or AWS API. One of the best ways to protect your account is to not allow users to have multiple access keys.","RemediationProcedure": "**From Console:**1. Sign in to the AWS Management Console and navigate to IAM dashboard at `https://console.aws.amazon.com/iam/`. 2. In the left navigation panel, choose `Users`. 3. Click on the IAM user name that you want to examine. 4. On the IAM user configuration page, select `Security Credentials` tab. 5. In `Access Keys` section, choose one access key that is less than 90 days old. This should be the only active key used by this IAM user to access AWS resources programmatically. Test your application(s) to make sure that the chosen access key is working. 6. In the same `Access Keys` section, identify your non-operational access keys (other than the chosen one) and deactivate it by clicking the `Make Inactive` link. 7. If you receive the `Change Key Status` confirmation box, click `Deactivate` to switch off the selected key. 8. Repeat steps no. 3 – 7 for each IAM user in your AWS account.**From Command Line:**1. Using the IAM user and access key information provided in the `Audit CLI`, choose one access key that is less than 90 days old. This should be the only active key used by this IAM user to access AWS resources programmatically. Test your application(s) to make sure that the chosen access key is working.2. Run the `update-access-key` command below using the IAM user name and the non-operational access key IDs to deactivate the unnecessary key(s). Refer to the Audit section to identify the unnecessary access key ID for the selected IAM user**Note** - the command does not return any output: ``` aws iam update-access-key --access-key-id  --status Inactive --user-name  ``` 3. To confirm that the selected access key pair has been successfully `deactivated` run the `list-access-keys` audit command again for that IAM User: ``` aws iam list-access-keys --user-name  ``` - The command output should expose the metadata for each access key associated with the IAM user. If the non-operational key pair(s) `Status` is set to `Inactive`, the key has been successfully deactivated and the IAM user access configuration adheres now to this recommendation.4. Repeat steps no. 1 – 3 for each IAM user in your AWS account.","AdditionalInformation": ""}],"description": "Ensure there is only one active access key available for any single IAM user","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.14": {"name": "1.14","checks": {"iam_rotate_access_key_90_days": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#rotate-credentials:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_finding-unused.html:https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html","Description": "Access keys consist of an access key ID and secret access key, which are used to sign programmatic requests that you make to AWS. AWS users need their own access keys to make programmatic calls to AWS from the AWS Command Line Interface (AWS CLI), Tools for Windows PowerShell, the AWS SDKs, or direct HTTP calls using the APIs for individual AWS services. It is recommended that all access keys be regularly rotated.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if access keys are rotated as prescribed:**From Console:**1. Go to Management Console (https://console.aws.amazon.com/iam) 2. Click on `Users` 3. Click `setting` icon 4. Select `Console last sign-in` 5. Click `Close` 6. Ensure that `Access key age` is less than 90 days ago. note) `None` in the `Access key age` means the user has not used the access key.**From Command Line:**``` aws iam generate-credential-report aws iam get-credential-report --query 'Content' --output text | base64 -d ``` The `access_key_1_last_rotated` field in this file notes The date and time, in ISO 8601 date-time format, when the user's access key was created or last changed. If the user does not have an active access key, the value in this field is N/A (not applicable).","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Rotating access keys will reduce the window of opportunity for an access key that is associated with a compromised or terminated account to be used.Access keys should be rotated to ensure that data cannot be accessed with an old key which might have been lost, cracked, or stolen.","RemediationProcedure": "Perform the following to rotate access keys:**From Console:**1. Go to Management Console (https://console.aws.amazon.com/iam) 2. Click on `Users` 3. Click on `Security Credentials`4. As an Administrator - Click on `Make Inactive` for keys that have not been rotated in `90` Days 5. As an IAM User- Click on `Make Inactive` or `Delete` for keys which have not been rotated or used in `90` Days 6. Click on `Create Access Key`7. Update programmatic call with new Access Key credentials**From Command Line:**1. While the first access key is still active, create a second access key, which is active by default. Run the following command: ``` aws iam create-access-key ```At this point, the user has two active access keys.2. Update all applications and tools to use the new access key. 3. Determine whether the first access key is still in use by using this command: ``` aws iam get-access-key-last-used ``` 4. One approach is to wait several days and then check the old access key for any use before proceeding.Even if step Step 3 indicates no use of the old key, it is recommended that you do not immediately delete the first access key. Instead, change the state of the first access key to Inactive using this command: ``` aws iam update-access-key ``` 5. Use only the new access key to confirm that your applications are working. Any applications and tools that still use the original access key will stop working at this point because they no longer have access to AWS resources. If you find such an application or tool, you can switch its state back to Active to reenable the first access key. Then return to step Step 2 and update this application to use the new key.6. After you wait some period of time to ensure that all applications and tools have been updated, you can delete the first access key with this command: ``` aws iam delete-access-key ```","AdditionalInformation": ""}],"description": "Ensure access keys are rotated every 90 days or less","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.15": {"name": "1.15","checks": {"iam_policy_attached_only_to_group_or_roles": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html","Description": "IAM users are granted access to services, functions, and data through IAM policies. There are three ways to define policies for a user: 1) Edit the user policy directly, aka an inline, or user, policy; 2) attach a policy directly to a user; 3) add the user to an IAM group that has an attached policy. Only the third implementation is recommended.","DefaultValue": null,"AuditProcedure": "Perform the following to determine if an inline policy is set or a policy is directly attached to users:1. Run the following to get a list of IAM users: ```aws iam list-users --query 'Users[*].UserName' --output text``` 2. For each user returned, run the following command to determine if any policies are attached to them: ```aws iam list-attached-user-policies --user-name aws iam list-user-policies --user-name ``` 3. If any policies are returned, the user has an inline policy or direct policy attachment.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Assigning IAM policy only through groups unifies permissions management to a single, flexible layer consistent with organizational functional roles. By unifying permissions management, the likelihood of excessive permissions is reduced.","RemediationProcedure": "Perform the following to create an IAM group and assign a policy to it:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click `Groups` and then click `Create New Group` . 3. In the `Group Name` box, type the name of the group and then click `Next Step` . 4. In the list of policies, select the check box for each policy that you want to apply to all members of the group. Then click `Next Step` . 5. Click `Create Group` Perform the following to add a user to a given group:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click `Groups`3. Select the group to add a user to 4. Click `Add Users To Group`5. Select the users to be added to the group 6. Click `Add Users` Perform the following to remove a direct association between a user and policy:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the left navigation pane, click on Users 3. For each user:- Select the user- Click on the `Permissions` tab- Expand `Permissions policies` - Click `X` for each policy; then click Detach or Remove (depending on policy type)","AdditionalInformation": ""}],"description": "Ensure IAM Users Receive Permissions Only Through Groups","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.16": {"name": "1.16","checks": {"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html:https://docs.aws.amazon.com/cli/latest/reference/iam/index.html#cli-aws-iam","Description": "IAM policies are the means by which privileges are granted to users, groups, or roles. It is recommended and considered a standard security advice to grant _least privilege_ -that is, granting only the permissions required to perform a task. Determine what users need to do and then craft policies for them that let the users perform _only_ those tasks, instead of allowing full administrative privileges.","DefaultValue": null,"AuditProcedure": "Perform the following to determine what policies are created:**From Command Line:**1. Run the following to get a list of IAM policies: ```aws iam list-policies --only-attached --output text ``` 2. For each policy returned, run the following command to determine if any policies is allowing full administrative privileges on the account: ```aws iam get-policy-version --policy-arn  --version-id  ``` 3. In output ensure policy should not have any Statement block with `\"Effect\": \"Allow\"` and `Action` set to `\"*\"` and `Resource` set to `\"*\"`","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "It's more secure to start with a minimum set of permissions and grant additional permissions as necessary, rather than starting with permissions that are too lenient and then trying to tighten them later.Providing full administrative privileges instead of restricting to the minimum set of permissions that the user is required to do exposes the resources to potentially unwanted actions.IAM policies that have a statement with \"Effect\": \"Allow\" with \"Action\": \"\\*\" over \"Resource\": \"\\*\" should be removed.","RemediationProcedure": "**From Console:**Perform the following to detach the policy that has full administrative privileges:1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/). 2. In the navigation pane, click Policies and then search for the policy name found in the audit step. 3. Select the policy that needs to be deleted. 4. In the policy action menu, select first `Detach`5. Select all Users, Groups, Roles that have this policy attached 6. Click `Detach Policy`7. In the policy action menu, select `Detach` **From Command Line:**Perform the following to detach the policy that has full administrative privileges as found in the audit step:1. Lists all IAM users, groups, and roles that the specified managed policy is attached to.```aws iam list-entities-for-policy --policy-arn  ``` 2. Detach the policy from all IAM Users: ```aws iam detach-user-policy --user-name  --policy-arn  ``` 3. Detach the policy from all IAM Groups: ```aws iam detach-group-policy --group-name  --policy-arn  ``` 4. Detach the policy from all IAM Roles: ```aws iam detach-role-policy --role-name  --policy-arn  ```","AdditionalInformation": ""}],"description": "Ensure IAM policies that allow full \"*:*\" administrative privileges are not attached","checks_status": {"fail": 0,"pass": 0,"total": 2,"manual": 0}},"1.17": {"name": "1.17","checks": {"iam_support_role_created": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html:https://aws.amazon.com/premiumsupport/pricing/:https://docs.aws.amazon.com/cli/latest/reference/iam/list-policies.html:https://docs.aws.amazon.com/cli/latest/reference/iam/attach-role-policy.html:https://docs.aws.amazon.com/cli/latest/reference/iam/list-entities-for-policy.html","Description": "AWS provides a support center that can be used for incident notification and response, as well as technical support and customer services. Create an IAM Role to allow authorized users to manage incidents with AWS Support.","DefaultValue": null,"AuditProcedure": "**From Command Line:**1. List IAM policies, filter for the 'AWSSupportAccess' managed policy, and note the \"Arn\" element value: ``` aws iam list-policies --query \"Policies[?PolicyName == 'AWSSupportAccess']\" ``` 2. Check if the 'AWSSupportAccess' policy is attached to any role:``` aws iam list-entities-for-policy --policy-arn arn:aws:iam::aws:policy/AWSSupportAccess ```3. In Output, Ensure `PolicyRoles` does not return empty. 'Example: Example: PolicyRoles: [ ]'If it returns empty refer to the remediation below.","ImpactStatement": "All AWS Support plans include an unlimited number of account and billing support cases, with no long-term contracts. Support billing calculations are performed on a per-account basis for all plans. Enterprise Support plan customers have the option to include multiple enabled accounts in an aggregated monthly billing calculation. Monthly charges for the Business and Enterprise support plans are based on each month's AWS usage charges, subject to a monthly minimum, billed in advance.","AssessmentStatus": "Automated","RationaleStatement": "By implementing least privilege for access control, an IAM Role will require an appropriate IAM Policy to allow Support Center Access in order to manage Incidents with AWS Support.","RemediationProcedure": "**From Command Line:**1. Create an IAM role for managing incidents with AWS:- Create a trust relationship policy document that allows  to manage AWS incidents, and save it locally as /tmp/TrustPolicy.json: ```{\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"\"},\"Action\": \"sts:AssumeRole\"}]} ``` 2. Create the IAM role using the above trust policy: ``` aws iam create-role --role-name  --assume-role-policy-document file:///tmp/TrustPolicy.json ``` 3. Attach 'AWSSupportAccess' managed policy to the created IAM role: ``` aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AWSSupportAccess --role-name  ```","AdditionalInformation": "AWSSupportAccess policy is a global AWS resource. It has same ARN as `arn:aws:iam::aws:policy/AWSSupportAccess` for every account."}],"description": "Ensure a support role has been created to manage incidents with AWS Support","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.18": {"name": "1.18","checks": {"ec2_instance_profile_attached": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html","Description": "AWS access from within AWS instances can be done by either encoding AWS keys into AWS API calls or by assigning the instance to a role which has an appropriate permissions policy for the required access. \"AWS Access\" means accessing the APIs of AWS in order to access AWS resources or manage AWS account resources.","DefaultValue": null,"AuditProcedure": "Where an instance is associated with a Role:For instances that are known to perform AWS actions, ensure that they belong to an instance role that has the necessary permissions:1. Login to AWS Console (with appropriate permissions to View Identity Access Management Account Settings) 2. Open the EC2 Dashboard and choose \"Instances\" 3. Click the EC2 instance that performs AWS actions, in the lower pane details find \"IAM Role\" 4. If the Role is blank, the instance is not assigned to one. 5. If the Role is filled in, it does not mean the instance might not \\*also\\* have credentials encoded on it for some activities.Where an Instance Contains Embedded Credentials:- On the instance that is known to perform AWS actions, audit all scripts and environment variables to ensure that none of them contain AWS credentials.Where an Instance Application Contains Embedded Credentials:- Applications that run on an instance may also have credentials embedded. This is a bad practice, but even worse if the source code is stored in a public code repository such as github. When an application contains credentials can be determined by eliminating all other sources of credentials and if the application can still access AWS resources - it likely contains embedded credentials. Another method is to examine all source code and configuration files of the application.","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "AWS IAM roles reduce the risks associated with sharing and rotating credentials that can be used outside of AWS itself. If credentials are compromised, they can be used from outside of the AWS account they give access to. In contrast, in order to leverage role permissions an attacker would need to gain and maintain access to a specific instance to use the privileges associated with it.Additionally, if credentials are encoded into compiled applications or other hard to change mechanisms, then they are even more unlikely to be properly rotated due to service disruption risks. As time goes on, credentials that cannot be rotated are more likely to be known by an increasing number of individuals who no longer work for the organization owning the credentials.","RemediationProcedure": "IAM roles can only be associated at the launch of an instance. To remediate an instance to add it to a role you must create a new instance.If the instance has no external dependencies on its current private ip or public addresses are elastic IPs:1. In AWS IAM create a new role. Assign a permissions policy if needed permissions are already known. 2. In the AWS console launch a new instance with identical settings to the existing instance, and ensure that the newly created role is selected. 3. Shutdown both the existing instance and the new instance. 4. Detach disks from both instances. 5. Attach the existing instance disks to the new instance. 6. Boot the new instance and you should have the same machine, but with the associated role.**Note:** if your environment has dependencies on a dynamically assigned PRIVATE IP address you can create an AMI from the existing instance, destroy the old one and then when launching from the AMI, manually assign the previous private IP address.**Note: **if your environment has dependencies on a dynamically assigned PUBLIC IP address there is not a way ensure the address is retained and assign an instance role. Dependencies on dynamically assigned public IP addresses are a bad practice and, if possible, you may wish to rebuild the instance with a new elastic IP address and make the investment to remediate affected systems while assigning the system to a role.","AdditionalInformation": ""}],"description": "Ensure IAM instance roles are used for AWS resource access from instances","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.19": {"name": "1.19","checks": {"iam_no_expired_server_certificates_stored": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_server-certs.html:https://docs.aws.amazon.com/cli/latest/reference/iam/delete-server-certificate.html","Description": "To enable HTTPS connections to your website or application in AWS, you need an SSL/TLS server certificate. You can use ACM or IAM to store and deploy server certificates.Use IAM as a certificate manager only when you must support HTTPS connections in a region that is not supported by ACM. IAM securely encrypts your private keys and stores the encrypted version in IAM SSL certificate storage. IAM supports deploying server certificates in all regions, but you must obtain your certificate from an external provider for use with AWS. You cannot upload an ACM certificate to IAM. Additionally, you cannot manage your certificates from the IAM Console.","DefaultValue": null,"AuditProcedure": "**From Console:**Getting the certificates expiration information via AWS Management Console is not currently supported.To request information about the SSL/TLS certificates stored in IAM via the AWS API use the Command Line Interface (CLI).**From Command Line:**Run list-server-certificates command to list all the IAM-stored server certificates:``` aws iam list-server-certificates ```The command output should return an array that contains all the SSL/TLS certificates currently stored in IAM and their metadata (name, ID, expiration date, etc):``` {\"ServerCertificateMetadataList\": [{\"ServerCertificateId\": \"EHDGFRW7EJFYTE88D\",\"ServerCertificateName\": \"MyServerCertificate\",\"Expiration\": \"2018-07-10T23:59:59Z\",\"Path\": \"/\",\"Arn\": \"arn:aws:iam::012345678910:server-certificate/MySSLCertificate\",\"UploadDate\": \"2018-06-10T11:56:08Z\"}] } ```Verify the `ServerCertificateName` and `Expiration` parameter value (expiration date) for each SSL/TLS certificate returned by the list-server-certificates command and determine if there are any expired server certificates currently stored in AWS IAM. If so, use the AWS API to remove them.If this command returns: ``` { { \"ServerCertificateMetadataList\": [] } ``` This means that there are no expired certificates, It DOES NOT mean that no certificates exist.","ImpactStatement": "Deleting the certificate could have implications for your application if you are using an expired server certificate with Elastic Load Balancing, CloudFront, etc. One has to make configurations at respective services to ensure there is no interruption in application functionality.","AssessmentStatus": "Automated","RationaleStatement": "Removing expired SSL/TLS certificates eliminates the risk that an invalid certificate will be deployed accidentally to a resource such as AWS Elastic Load Balancer (ELB), which can damage the credibility of the application/website behind the ELB. As a best practice, it is recommended to delete expired certificates.","RemediationProcedure": "**From Console:**Removing expired certificates via AWS Management Console is not currently supported. To delete SSL/TLS certificates stored in IAM via the AWS API use the Command Line Interface (CLI).**From Command Line:**To delete Expired Certificate run following command by replacing  with the name of the certificate to delete:``` aws iam delete-server-certificate --server-certificate-name  ```When the preceding command is successful, it does not return any output.","AdditionalInformation": ""}],"description": "Ensure that all the expired SSL/TLS certificates stored in AWS IAM are removed","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"1.20": {"name": "1.20","checks": {"accessanalyzer_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "1. Identity and Access Management","References": "https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html:https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-getting-started.html:https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/get-analyzer.html:https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/create-analyzer.html","Description": "Enable IAM Access analyzer for IAM policies about all resources in each region.IAM Access Analyzer is a technology introduced at AWS reinvent 2019. After the Analyzer is enabled in IAM, scan results are displayed on the console showing the accessible resources. Scans show resources that other accounts and federated users can access, such as KMS keys and IAM roles. So the results allow you to determine if an unintended user is allowed, making it easier for administrators to monitor least privileges access. Access Analyzer analyzes only policies that are applied to resources in the same AWS Region.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Open the IAM console at `https://console.aws.amazon.com/iam/` 2. Choose `Access analyzer` 3. Click 'Analyzers' 4. Ensure that at least one analyzer is present 5. Ensure that the `STATUS` is set to `Active` 6. Repeat these step for each active region**From Command Line:**1. Run the following command: ``` aws accessanalyzer list-analyzers | grep status ``` 2. Ensure that at least one Analyzer the `status` is set to `ACTIVE`3. Repeat the steps above for each active region.If an Access analyzer is not listed for each region or the status is not set to active refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "AWS IAM Access Analyzer helps you identify the resources in your organization and accounts, such as Amazon S3 buckets or IAM roles, that are shared with an external entity. This lets you identify unintended access to your resources and data. Access Analyzer identifies resources that are shared with external principals by using logic-based reasoning to analyze the resource-based policies in your AWS environment. IAM Access Analyzer continuously monitors all policies for S3 bucket, IAM roles, KMS(Key Management Service) keys, AWS Lambda functions, and Amazon SQS(Simple Queue Service) queues.","RemediationProcedure": "**From Console:**Perform the following to enable IAM Access analyzer for IAM policies:1. Open the IAM console at `https://console.aws.amazon.com/iam/.` 2. Choose `Access analyzer`. 3. Choose `Create analyzer`. 4. On the `Create analyzer` page, confirm that the `Region` displayed is the Region where you want to enable Access Analyzer. 5. Enter a name for the analyzer. `Optional as it will generate a name for you automatically`. 6. Add any tags that you want to apply to the analyzer. `Optional`.7. Choose `Create Analyzer`. 8. Repeat these step for each active region**From Command Line:**Run the following command: ``` aws accessanalyzer create-analyzer --analyzer-name  --type  ``` Repeat this command above for each active region.**Note:** The IAM Access Analyzer is successfully configured only when the account you use has the necessary permissions.","AdditionalInformation": ""}],"description": "Ensure that IAM Access analyzer is enabled for all regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"1.21": {"name": "1.21","checks": {"iam_check_saml_providers_sts": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "1. Identity and Access Management","References": "","Description": "In multi-account environments, IAM user centralization facilitates greater user control. User access beyond the initial account is then provided via role assumption. Centralization of users can be accomplished through federation with an external identity provider or through the use of AWS Organizations.","DefaultValue": null,"AuditProcedure": "For multi-account AWS environments with an external identity provider... 1. Determine the master account for identity federation or IAM user management 2. Login to that account through the AWS Management Console 3. Click `Services`4. Click `IAM`5. Click `Identity providers` 6. Verify the configurationThen..., determine all accounts that should not have local users present. For each account...1. Determine all accounts that should not have local users present 2. Log into the AWS Management Console 3. Switch role into each identified account 4. Click `Services`5. Click `IAM`6. Click `Users` 7. Confirm that no IAM users representing individuals are presentFor multi-account AWS environments implementing AWS Organizations without an external identity provider... 1. Determine all accounts that should not have local users present 2. Log into the AWS Management Console 3. Switch role into each identified account 4. Click `Services`5. Click `IAM`6. Click `Users` 7. Confirm that no IAM users representing individuals are present","ImpactStatement": "","AssessmentStatus": "Manual","RationaleStatement": "Centralizing IAM user management to a single identity store reduces complexity and thus the likelihood of access management errors.","RemediationProcedure": "The remediation procedure will vary based on the individual organization's implementation of identity federation and/or AWS Organizations with the acceptance criteria that no non-service IAM users, and non-root accounts, are present outside the account providing centralized IAM user management.","AdditionalInformation": ""}],"description": "Ensure IAM users are managed centrally via identity federation or AWS Organizations for multi-account environments","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.10": {"name": "3.10","checks": {"cloudtrail_s3_dataevents_write_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-cloudtrail-events.html","Description": "S3 object-level API operations such as GetObject, DeleteObject, and PutObject are called data events. By default, CloudTrail trails don't log data events and so it is recommended to enable Object-level logging for S3 buckets.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to CloudTrail dashboard at `https://console.aws.amazon.com/cloudtrail/` 2. In the left panel, click `Trails` and then click on the CloudTrail Name that you want to examine. 3. Review `General details` 4. Confirm that `Multi-region trail` is set to `Yes` 5. Scroll down to `Data events` 6. Confirm that it reads: Data events: S3 Bucket Name: All current and future S3 buckets Read: Enabled Write: Enabled 7. Repeat steps 2 to 6 to verify that Multi-region trail and Data events logging of S3 buckets in CloudTrail. If the CloudTrails do not have multi-region and data events configured for S3 refer to the remediation below.**From Command Line:**1. Run `list-trails` command to list the names of all Amazon CloudTrail trails currently available in all AWS regions: ``` aws cloudtrail list-trails ``` 2. The command output will be a list of all the trail names to include. \"TrailARN\": \"arn:aws:cloudtrail:::trail/\", \"Name\": \"\", \"HomeRegion\": \"\" 3. Next run 'get-trail- command to determine Multi-region. ``` aws cloudtrail get-trail --name  --region  ``` 4. The command output should include: \"IsMultiRegionTrail\": true, 5. Next run `get-event-selectors` command using the `Name` of the trail and the `region` returned in step 2 to determine if Data events logging feature is enabled within the selected CloudTrail trail for all S3 buckets: ``` aws cloudtrail get-event-selectors --region  --trail-name  --query EventSelectors[*].DataResources[] ``` 6. The command output should be an array that contains the configuration of the AWS resource(S3 bucket) defined for the Data events selector. \"Type\": \"AWS::S3::Object\",\"Values\": [\"arn:aws:s3\" 7. If the `get-event-selectors` command returns an empty array '[]', the Data events are not included in the selected AWS Cloudtrail trail logging configuration, therefore the S3 object-level API operations performed within your AWS account are not recorded. 8. Repeat steps 1 to 5 for auditing each CloudTrail to determine if Data events for S3 are covered. If Multi-region is not set to true and the Data events does not show S3 defined as shown refer to the remediation procedure below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling object-level logging will help you meet data compliance requirements within your organization, perform comprehensive security analysis, monitor specific patterns of user behavior in your AWS account or take immediate actions on any object-level API activity within your S3 Buckets using Amazon CloudWatch Events.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. Click on the `Object-level` logging setting, enter the CloudTrail name for the recording activity. You can choose an existing Cloudtrail or create a new one by navigating to the Cloudtrail console link `https://console.aws.amazon.com/cloudtrail/` 5. Once the Cloudtrail is selected, check the `Write` event checkbox, so that `object-level` logging for Write events is enabled. 6. Repeat steps 2 to 5 to enable object-level logging of write events for other S3 buckets.**From Command Line:**1. To enable `object-level` data events logging for S3 buckets within your AWS account, run `put-event-selectors` command using the name of the trail that you want to reconfigure as identifier: ``` aws cloudtrail put-event-selectors --region  --trail-name  --event-selectors '[{ \"ReadWriteType\": \"WriteOnly\", \"IncludeManagementEvents\":true, \"DataResources\": [{ \"Type\": \"AWS::S3::Object\", \"Values\": [\"arn:aws:s3:::/\"] }] }]' ``` 2. The command output will be `object-level` event trail configuration. 3. If you want to enable it for all buckets at once then change Values parameter to `[\"arn:aws:s3\"]` in command given above. 4. Repeat step 1 for each s3 bucket to update `object-level` logging of write events. 5. Change the AWS region by updating the `--region` command parameter and perform the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that Object-level logging for write events is enabled for S3 bucket","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"3.11": {"name": "3.11","checks": {"cloudtrail_s3_dataevents_read_enabled": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "3. Logging","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-cloudtrail-events.html","Description": "S3 object-level API operations such as GetObject, DeleteObject, and PutObject are called data events. By default, CloudTrail trails don't log data events and so it is recommended to enable Object-level logging for S3 buckets.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. If the current status for `Object-level` logging is set to `Disabled`, then object-level logging of read events for the selected s3 bucket is not set. 5. If the current status for `Object-level` logging is set to `Enabled`, but the Read event check-box is unchecked, then object-level logging of read events for the selected s3 bucket is not set. 6. Repeat steps 2 to 5 to verify `object-level` logging for `read` events of your other S3 buckets.**From Command Line:** 1. Run `describe-trails` command to list the names of all Amazon CloudTrail trails currently available in the selected AWS region: ``` aws cloudtrail describe-trails --region  --output table --query trailList[*].Name ``` 2. The command output will be table of the requested trail names. 3. Run `get-event-selectors` command using the name of the trail returned at the previous step and custom query filters to determine if Data events logging feature is enabled within the selected CloudTrail trail configuration for s3 bucket resources: ``` aws cloudtrail get-event-selectors --region  --trail-name  --query EventSelectors[*].DataResources[] ``` 4. The command output should be an array that contains the configuration of the AWS resource(S3 bucket) defined for the Data events selector. 5. If the `get-event-selectors` command returns an empty array, the Data events are not included into the selected AWS Cloudtrail trail logging configuration, therefore the S3 object-level API operations performed within your AWS account are not recorded. 6. Repeat steps 1 to 5 for auditing each s3 bucket to identify other trails that are missing the capability to log Data events. 7. Change the AWS region by updating the `--region` command parameter and perform the audit process for other regions.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Enabling object-level logging will help you meet data compliance requirements within your organization, perform comprehensive security analysis, monitor specific patterns of user behavior in your AWS account or take immediate actions on any object-level API activity using Amazon CloudWatch Events.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and navigate to S3 dashboard at `https://console.aws.amazon.com/s3/` 2. In the left navigation panel, click `buckets` and then click on the S3 Bucket Name that you want to examine. 3. Click `Properties` tab to see in detail bucket configuration. 4. Click on the `Object-level` logging setting, enter the CloudTrail name for the recording activity. You can choose an existing Cloudtrail or create a new one by navigating to the Cloudtrail console link `https://console.aws.amazon.com/cloudtrail/` 5. Once the Cloudtrail is selected, check the Read event checkbox, so that `object-level` logging for `Read` events is enabled. 6. Repeat steps 2 to 5 to enable `object-level` logging of read events for other S3 buckets.**From Command Line:** 1. To enable `object-level` data events logging for S3 buckets within your AWS account, run `put-event-selectors` command using the name of the trail that you want to reconfigure as identifier: ``` aws cloudtrail put-event-selectors --region  --trail-name  --event-selectors '[{ \"ReadWriteType\": \"ReadOnly\", \"IncludeManagementEvents\":true, \"DataResources\": [{ \"Type\": \"AWS::S3::Object\", \"Values\": [\"arn:aws:s3:::/\"] }] }]' ``` 2. The command output will be `object-level` event trail configuration. 3. If you want to enable it for all buckets at ones then change Values parameter to `[\"arn:aws:s3\"]` in command given above. 4. Repeat step 1 for each s3 bucket to update `object-level` logging of read events. 5. Change the AWS region by updating the `--region` command parameter and perform the process for other regions.","AdditionalInformation": ""}],"description": "Ensure that Object-level logging for read events is enabled for S3 bucket","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.10": {"name": "4.10","checks": {"cloudwatch_log_metric_filter_security_group_changes": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Security Groups are a stateful packet filter that controls ingress and egress traffic within a VPC. It is recommended that a metric filter and alarm be established for detecting changes to Security Groups.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query \"MetricAlarms[?MetricName== '']\" ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to security group will help ensure that resources and services are not unintentionally exposed.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for security groups changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name \"\" --filter-name \"\" --metric-transformations metricName= \"\" ,metricNamespace=\"CISBenchmark\",metricValue=1 --filter-pattern \"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }\" ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name \"\" ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn \"\" --protocol  --notification-endpoint \"\" ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name \"\" --metric-name \"\" --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace \"CISBenchmark\" --alarm-actions \"\" ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for security group changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.11": {"name": "4.11","checks": {"cloudwatch_changes_to_network_acls_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. NACLs are used as a stateless packet filter to control ingress and egress traffic for subnets within a VPC. It is recommended that a metric filter and alarm be established for changes made to NACLs.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to NACLs will help ensure that AWS resources and services are not unintentionally exposed.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for NACL changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL)","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.12": {"name": "4.12","checks": {"cloudwatch_changes_to_network_gateways_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Network gateways are required to send/receive traffic to a destination outside of a VPC. It is recommended that a metric filter and alarm be established for changes to network gateways.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``: ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }\" ``` 4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4. ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. ``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to network gateways will help ensure that all ingress/egress traffic traverses the VPC border via a controlled path.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for network gateways changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for changes to network gateways","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.13": {"name": "4.13","checks": {"cloudwatch_changes_to_network_route_tables_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Routing tables are used to route network traffic between subnets and to network gateways. It is recommended that a metric filter and alarm be established for changes to route tables.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to route tables will help ensure that all VPC traffic flows through an expected path.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for route table changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for route table changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.14": {"name": "4.14","checks": {"cloudwatch_changes_to_vpcs_alarm_configured": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html:https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is possible to have more than 1 VPC within an account, in addition it is also possible to create a peer connection between 2 VPCs enabling network traffic to route between VPCs. It is recommended that a metric filter and alarm be established for changes made to VPCs.","DefaultValue": null,"AuditProcedure": "Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured:1. Identify the log group name configured for use with active multi-region CloudTrail:- List all CloudTrails: `aws cloudtrail describe-trails`- Identify Multi region Cloudtrails: `Trails with \"IsMultiRegionTrail\" set to true`- From value associated with CloudWatchLogsLogGroupArn note ``Example: for CloudWatchLogsLogGroupArn that looks like `arn:aws:logs:::log-group:NewGroup:*`, `` would be `NewGroup`- Ensure Identified Multi region CloudTrail is active`aws cloudtrail get-trail-status --name `ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events`aws cloudtrail get-event-selectors --trail-name `Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to `true` and `ReadWriteType` set to `All`2. Get a list of all associated metric filters for this ``:``` aws logs describe-metric-filters --log-group-name \"\" ```3. Ensure the output from the above command contains the following:``` \"filterPattern\": \"{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }\" ```4. Note the `` value associated with the `filterPattern` found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4.``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ```6. Note the `AlarmActions` value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN.``` Example of valid \"SubscriptionArn\": \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring changes to VPC will help ensure VPC traffic flow is not getting impacted.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for VPC changes and the `` taken from audit step 1. ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }' ```**Note**: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify ``` aws sns create-topic --name  ```**Note**: you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2 ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ```**Note**: you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": "Configuring log metric filter and alarm on Multi-region (global) CloudTrail - ensures that activities from all regions (used as well as unused) are monitored - ensures that activities on all supported global services are monitored - ensures that all management events across all regions are monitored"}],"description": "Ensure a log metric filter and alarm exist for VPC changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"4.15": {"name": "4.15","checks": {"cloudwatch_log_metric_filter_aws_organizations_changes": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "4. Monitoring","References": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html:https://docs.aws.amazon.com/organizations/latest/userguide/orgs_security_incident-response.html","Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. It is recommended that a metric filter and alarm be established for AWS Organizations changes made in the master AWS Account.","DefaultValue": null,"AuditProcedure": "1. Perform the following to ensure that there is at least one active multi-region CloudTrail with prescribed metric filters and alarms configured: - Identify the log group name configured for use with active multi-region CloudTrail: - List all CloudTrails:``` aws cloudtrail describe-trails ``` - Identify Multi region Cloudtrails, Trails with `\"IsMultiRegionTrail\"` set to true - From value associated with CloudWatchLogsLogGroupArn note **Example:** for CloudWatchLogsLogGroupArn that looks like arn:aws:logs:::log-group:NewGroup:*,  would be NewGroup- Ensure Identified Multi region CloudTrail is active: ``` aws cloudtrail get-trail-status --name  ``` Ensure `IsLogging` is set to `TRUE`- Ensure identified Multi-region Cloudtrail captures all Management Events: ``` aws cloudtrail get-event-selectors --trail-name  ``` - Ensure there is at least one Event Selector for a Trail with `IncludeManagementEvents` set to true and `ReadWriteType` set to `All`.2. Get a list of all associated metric filters for this : ``` aws logs describe-metric-filters --log-group-name \"\" ``` 3. Ensure the output from the above command contains the following: ``` \"filterPattern\": \"{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdatePolicy\") || ($.eventName = \"UpdateOrganizationalUnit\")) }\" ``` 4. Note the `` value associated with the filterPattern found in step 3.5. Get a list of CloudWatch alarms and filter on the `` captured in step 4: ``` aws cloudwatch describe-alarms --query 'MetricAlarms[?MetricName== ``]' ``` 6. Note the AlarmActions value - this will provide the SNS topic ARN value.7. Ensure there is at least one active subscriber to the SNS topic: ``` aws sns list-subscriptions-by-topic --topic-arn ``` at least one subscription should have \"SubscriptionArn\" with valid aws ARN. Example of valid \"SubscriptionArn\":``` \"arn:aws:sns::::\" ```","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Monitoring AWS Organizations changes can help you prevent any unwanted, accidental or intentional modifications that may lead to unauthorized access or other security breaches. This monitoring technique helps you to ensure that any unexpected changes performed within your AWS Organizations can be investigated and any unwanted changes can be rolled back.","RemediationProcedure": "Perform the following to setup the metric filter, alarm, SNS topic, and subscription:1. Create a metric filter based on filter pattern provided which checks for AWS Organizations changes and the `` taken from audit step 1: ``` aws logs put-metric-filter --log-group-name  --filter-name `` --metric-transformations metricName= `` ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = organizations.amazonaws.com) && (($.eventName = \"AcceptHandshake\") || ($.eventName = \"AttachPolicy\") || ($.eventName = \"CreateAccount\") || ($.eventName = \"CreateOrganizationalUnit\") || ($.eventName = \"CreatePolicy\") || ($.eventName = \"DeclineHandshake\") || ($.eventName = \"DeleteOrganization\") || ($.eventName = \"DeleteOrganizationalUnit\") || ($.eventName = \"DeletePolicy\") || ($.eventName = \"DetachPolicy\") || ($.eventName = \"DisablePolicyType\") || ($.eventName = \"EnablePolicyType\") || ($.eventName = \"InviteAccountToOrganization\") || ($.eventName = \"LeaveOrganization\") || ($.eventName = \"MoveAccount\") || ($.eventName = \"RemoveAccountFromOrganization\") || ($.eventName = \"UpdatePolicy\") || ($.eventName = \"UpdateOrganizationalUnit\")) }' ``` **Note:** You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.2. Create an SNS topic that the alarm will notify: ``` aws sns create-topic --name  ``` **Note:** you can execute this command once and then re-use the same topic for all monitoring alarms.3. Create an SNS subscription to the topic created in step 2: ``` aws sns subscribe --topic-arn  --protocol  --notification-endpoint  ``` **Note:** you can execute this command once and then re-use the SNS subscription for all monitoring alarms.4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2: ``` aws cloudwatch put-metric-alarm --alarm-name `` --metric-name `` --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions  ```","AdditionalInformation": ""}],"description": "Ensure a log metric filter and alarm exists for AWS Organizations changes","checks_status": {"fail": 0,"pass": 0,"total": 1,"manual": 0}},"2.1.1": {"name": "2.1.1","checks": {"s3_bucket_default_encryption": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/default-bucket-encryption.html:https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html#bucket-encryption-related-resources","Description": "Amazon S3 provides a variety of no, or low, cost encryption options to protect data at rest.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select a Bucket. 3. Click on 'Properties'. 4. Verify that `Default Encryption` is enabled, and displays either `AES-256`, `AWS-KMS`, `SSE-KMS` or `SSE-S3`. 5. Repeat for all the buckets in your AWS account.**From Command Line:**1. Run command to list buckets ``` aws s3 ls ``` 2. For each bucket, run``` aws s3api get-bucket-encryption --bucket  ``` 3. Verify that either``` \"SSEAlgorithm\": \"AES256\" ```or``` \"SSEAlgorithm\": \"aws:kms\"```is displayed.","ImpactStatement": "Amazon S3 buckets with default bucket encryption using SSE-KMS cannot be used as destination buckets for Amazon S3 server access logging. Only SSE-S3 default encryption is supported for server access log destination buckets.","AssessmentStatus": "Automated","RationaleStatement": "Encrypting data at rest reduces the likelihood that it is unintentionally exposed and can nullify the impact of disclosure if the encryption remains unbroken.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select a Bucket. 3. Click on 'Properties'. 4. Click edit on `Default Encryption`. 5. Select either `AES-256`, `AWS-KMS`, `SSE-KMS` or `SSE-S3`. 6. Click `Save` 7. Repeat for all the buckets in your AWS account lacking encryption.**From Command Line:**Run either``` aws s3api put-bucket-encryption --bucket  --server-side-encryption-configuration '{\"Rules\": [{\"ApplyServerSideEncryptionByDefault\": {\"SSEAlgorithm\": \"AES256\"}}]}' ```or``` aws s3api put-bucket-encryption --bucket  --server-side-encryption-configuration '{\"Rules\": [{\"ApplyServerSideEncryptionByDefault\": {\"SSEAlgorithm\": \"aws:kms\",\"KMSMasterKeyID\": \"aws/s3\"}}]}' ```**Note:** the KMSMasterKeyID can be set to the master key of your choosing; aws/s3 is an AWS preconfigured default.","AdditionalInformation": "S3 bucket encryption only applies to objects as they are placed in the bucket. Enabling S3 bucket encryption does **not** encrypt objects previously stored within the bucket."}],"description": "Ensure all S3 buckets employ encryption-at-rest","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.2": {"name": "2.1.2","checks": {"s3_bucket_secure_transport_policy": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-policy-for-config-rule/:https://aws.amazon.com/blogs/security/how-to-use-bucket-policies-and-apply-defense-in-depth-to-help-secure-your-amazon-s3-data/:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-bucket-policy.html","Description": "At the Amazon S3 bucket level, you can configure permissions through a bucket policy making the objects accessible only through HTTPS.","DefaultValue": null,"AuditProcedure": "To allow access to HTTPS you can use a condition that checks for the key `\"aws:SecureTransport: true\"`. This means that the request is sent through HTTPS but that HTTP can still be used. So to make sure you do not allow HTTP access confirm that there is a bucket policy that explicitly denies access for HTTP requests and that it contains the key \"aws:SecureTransport\": \"false\".**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/ 2. Select the Check box next to the Bucket. 3. Click on 'Permissions', then Click on `Bucket Policy`. 4. Ensure that a policy is listed that matches: ``` '{\"Sid\": ,\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}' ``` `` and `` will be specific to your account5. Repeat for all the buckets in your AWS account.**From Command Line:**1. List all of the S3 Buckets``` aws s3 ls ``` 2. Using the list of buckets run this command on each of them: ``` aws s3api get-bucket-policy --bucket  | grep aws:SecureTransport ``` 3. Confirm that `aws:SecureTransport` is set to false `aws:SecureTransport:false` 4. Confirm that the policy line has Effect set to Deny 'Effect:Deny'","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "By default, Amazon S3 allows both HTTP and HTTPS requests. To achieve only allowing access to Amazon S3 objects through HTTPS you also have to explicitly deny access to HTTP requests. Bucket policies that allow HTTPS requests without explicitly denying HTTP requests will not comply with this recommendation.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/ 2. Select the Check box next to the Bucket. 3. Click on 'Permissions'. 4. Click 'Bucket Policy' 5. Add this to the existing policy filling in the required information ``` {\"Sid\": \",\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}}} ``` 6. Save 7. Repeat for all the buckets in your AWS account that contain sensitive data.**From Console** using AWS Policy Generator:1. Repeat steps 1-4 above. 2. Click on `Policy Generator` at the bottom of the Bucket Policy Editor 3. Select Policy Type `S3 Bucket Policy` 4. Add Statements - `Effect` = Deny - `Principal` = * - `AWS Service` = Amazon S3 - `Actions` = * - `Amazon Resource Name` =  5. Generate Policy 6. Copy the text and add it to the Bucket Policy.**From Command Line:**1. Export the bucket policy to a json file. ``` aws s3api get-bucket-policy --bucket  --query Policy --output text > policy.json ```2. Modify the policy.json file by adding in this statement: ``` {\"Sid\": \",\"Effect\": \"Deny\",\"Principal\": \"*\",\"Action\": \"s3:*\",\"Resource\": \"arn:aws:s3:::/*\",\"Condition\": {\"Bool\": {\"aws:SecureTransport\": \"false\"}}} ``` 3. Apply this modified policy back to the S3 bucket: ``` aws s3api put-bucket-policy --bucket  --policy file://policy.json ```","AdditionalInformation": ""}],"description": "Ensure S3 Bucket Policy is set to deny HTTP requests","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.1.3": {"name": "2.1.3","checks": {"s3_bucket_no_mfa_delete": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html#MultiFactorAuthenticationDelete:https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMFADelete.html:https://aws.amazon.com/blogs/security/securing-access-to-aws-using-mfa-part-3/:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_lost-or-broken.html","Description": "Once MFA Delete is enabled on your sensitive and classified S3 bucket it requires the user to have two forms of authentication.","DefaultValue": null,"AuditProcedure": "Perform the steps below to confirm MFA delete is configured on an S3 Bucket**From Console:**1. Login to the S3 console at `https://console.aws.amazon.com/s3/`2. Click the `Check` box next to the Bucket name you want to confirm3. In the window under `Properties`4. Confirm that Versioning is `Enabled`5. Confirm that MFA Delete is `Enabled`**From Command Line:**1. Run the `get-bucket-versioning` ``` aws s3api get-bucket-versioning --bucket my-bucket ```Output example: ```  EnabledEnabled ```If the Console or the CLI output does not show Versioning and MFA Delete `enabled` refer to the remediation below.","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Adding MFA delete to an S3 bucket, requires additional authentication when you change the version state of your bucket or you delete and object version adding another layer of security in the event your security credentials are compromised or unauthorized access is granted.","RemediationProcedure": "Perform the steps below to enable MFA delete on an S3 bucket.Note: -You cannot enable MFA Delete using the AWS Management Console. You must use the AWS CLI or API. -You must use your 'root' account to enable MFA Delete on S3 buckets.**From Command line:**1. Run the s3api put-bucket-versioning command``` aws s3api put-bucket-versioning --profile my-root-profile --bucket Bucket_Name --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa ā€œarn:aws:iam::aws_account_id:mfa/root-account-mfa-device passcodeā€ ```","AdditionalInformation": ""}],"description": "Ensure MFA Delete is enabled on S3 buckets","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}},"2.1.4": {"name": "2.1.4","checks": {"macie_is_enabled": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 2","Section": "2.1. Simple Storage Service (S3)","References": "https://aws.amazon.com/macie/getting-started/:https://docs.aws.amazon.com/workspaces/latest/adminguide/data-protection.html:https://docs.aws.amazon.com/macie/latest/user/data-classification.html","Description": "Amazon S3 buckets can contain sensitive data, that for security purposes should be discovered, monitored, classified and protected. Macie along with other 3rd party tools can automatically provide an inventory of Amazon S3 buckets.","DefaultValue": null,"AuditProcedure": "Perform the following steps to determine if Macie is running:**From Console:** 1. Login to the Macie console at https://console.aws.amazon.com/macie/ 2. In the left hand pane click on By job under findings. 3. Confirm that you have a Job setup for your S3 BucketsWhen you log into the Macie console if you aren't taken to the summary page and you don't have a job setup and running then refer to the remediation procedure below.If you are using a 3rd Party tool to manage and protect your s3 data you meet this recommendation.","ImpactStatement": "There is a cost associated with using Amazon Macie. There is also typically a cost associated with 3rd Party tools that perform similar processes and protection.","AssessmentStatus": "Manual","RationaleStatement": "Using a Cloud service or 3rd Party software to continuously monitor and automate the process of data discovery and classification for S3 buckets using machine learning and pattern matching is a strong defense in protecting that information.Amazon Macie is a fully managed data security and data privacy service that uses machine learning and pattern matching to discover and protect your sensitive data in AWS.","RemediationProcedure": "Perform the steps below to enable and configure Amazon Macie**From Console:**1. Log on to the Macie console at `https://console.aws.amazon.com/macie/`2. Click `Get started`.3. Click `Enable Macie`.Setup a repository for sensitive data discovery results1. In the Left pane, under Settings, click `Discovery results`.2. Make sure `Create bucket` is selected.3. Create a bucket, enter a name for the bucket. The name must be unique across all S3 buckets. In addition, the name must start with a lowercase letter or a number.4. Click on `Advanced`.5. Block all public access, make sure `Yes` is selected.6. KMS encryption, specify the AWS KMS key that you want to use to encrypt the results. The key must be a symmetric, customer master key (CMK) that's in the same Region as the S3 bucket.7. Click on `Save`Create a job to discover sensitive data1. In the left pane, click `S3 buckets`. Macie displays a list of all the S3 buckets for your account.2. Select the `check box` for each bucket that you want Macie to analyze as part of the job3. Click `Create job`.3. Click `Quick create`.4. For the Name and description step, enter a name and, optionally, a description of the job.5. Then click `Next`.6. For the Review and create step, click `Submit`.Review your findings1. In the left pane, click `Findings`.2. To view the details of a specific finding, choose any field other than the check box for the finding.If you are using a 3rd Party tool to manage and protect your s3 data, follow the Vendor documentation for implementing and configuring that tool.","AdditionalInformation": ""}],"description": "Ensure all data in Amazon S3 has been discovered, classified and secured when required.","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.1.5": {"name": "2.1.5","checks": {"s3_bucket_level_public_access_block": "PASS","s3_account_level_public_access_blocks": null},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.1. Simple Storage Service (S3)","References": "https://docs.aws.amazon.com/AmazonS3/latest/user-guide/block-public-access-account.html","Description": "Amazon S3 provides `Block public access (bucket settings)` and `Block public access (account settings)` to help you manage public access to Amazon S3 resources. By default, S3 buckets and objects are created with public access disabled. However, an IAM principal with sufficient S3 permissions can enable public access at the bucket and/or object level. While enabled, `Block public access (bucket settings)` prevents an individual bucket, and its contained objects, from becoming publicly accessible. Similarly, `Block public access (account settings)` prevents all buckets, and contained objects, from becoming publicly accessible across the entire account.","DefaultValue": null,"AuditProcedure": "**If utilizing Block Public Access (bucket settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select the Check box next to the Bucket. 3. Click on 'Edit public access settings'. 4. Ensure that block public access settings are set appropriately for this bucket 5. Repeat for all the buckets in your AWS account.**From Command Line:**1. List all of the S3 Buckets ``` aws s3 ls ``` 2. Find the public access setting on that bucket ``` aws s3api get-public-access-block --bucket  ``` Output if Block Public access is enabled:``` {\"PublicAccessBlockConfiguration\": {\"BlockPublicAcls\": true,\"IgnorePublicAcls\": true,\"BlockPublicPolicy\": true,\"RestrictPublicBuckets\": true} } ```If the output reads `false` for the separate configuration settings then proceed to the remediation.**If utilizing Block Public Access (account settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Choose `Block public access (account settings)` 3. Ensure that block public access settings are set appropriately for your AWS account.**From Command Line:**To check Public access settings for this account status, run the following command, `aws s3control get-public-access-block --account-id  --region `Output if Block Public access is enabled:``` {\"PublicAccessBlockConfiguration\": {\"IgnorePublicAcls\": true, \"BlockPublicPolicy\": true, \"BlockPublicAcls\": true, \"RestrictPublicBuckets\": true} } ```If the output reads `false` for the separate configuration settings then proceed to the remediation.","ImpactStatement": "When you apply Block Public Access settings to an account, the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously, but they eventually propagate to all Regions.","AssessmentStatus": "Automated","RationaleStatement": "Amazon S3 `Block public access (bucket settings)` prevents the accidental or malicious public exposure of data contained within the respective bucket(s). Amazon S3 `Block public access (account settings)` prevents the accidental or malicious public exposure of data contained within all buckets of the respective AWS account.Whether blocking public access to all or some buckets is an organizational decision that should be based on data sensitivity, least privilege, and use case.","RemediationProcedure": "**If utilizing Block Public Access (bucket settings)****From Console:**1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Select the Check box next to the Bucket. 3. Click on 'Edit public access settings'. 4. Click 'Block all public access' 5. Repeat for all the buckets in your AWS account that contain sensitive data.**From Command Line:**1. List all of the S3 Buckets ``` aws s3 ls ``` 2. Set the Block Public Access to true on that bucket ``` aws s3api put-public-access-block --bucket  --public-access-block-configuration \"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true\" ```**If utilizing Block Public Access (account settings)****From Console:**If the output reads `true` for the separate configuration settings then it is set on the account.1. Login to AWS Management Console and open the Amazon S3 console using https://console.aws.amazon.com/s3/2. Choose `Block Public Access (account settings)` 3. Choose `Edit` to change the block public access settings for all the buckets in your AWS account 4. Choose the settings you want to change, and then choose `Save`. For details about each setting, pause on the `i` icons. 5. When you're asked for confirmation, enter `confirm`. Then Click `Confirm` to save your changes.**From Command Line:**To set Block Public access settings for this account, run the following command: ``` aws s3control put-public-access-block --public-access-block-configuration BlockPublicAcls=true, IgnorePublicAcls=true, BlockPublicPolicy=true, RestrictPublicBuckets=true --account-id  ```","AdditionalInformation": ""}],"description": "Ensure that S3 Buckets are configured with 'Block public access (bucket settings)'","checks_status": {"fail": 0,"pass": 1,"total": 2,"manual": 0}},"2.2.1": {"name": "2.2.1","checks": {"ec2_ebs_volume_encryption": "PASS"},"status": "PASS","attributes": [{"Profile": "Level 1","Section": "2.2. Elastic Compute Cloud (EC2)","References": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html:https://aws.amazon.com/blogs/aws/new-opt-in-to-default-encryption-for-new-ebs-volumes/","Description": "Elastic Compute Cloud (EC2) supports encryption at rest when using the Elastic Block Store (EBS) service. While disabled by default, forcing encryption at EBS volume creation is supported.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under `Account attributes`, click `EBS encryption`. 3. Verify `Always encrypt new EBS volumes` displays `Enabled`. 4. Review every region in-use.**Note:** EBS volume encryption is configured per region.**From Command Line:**1. Run``` aws --region  ec2 get-ebs-encryption-by-default ``` 2. Verify that `\"EbsEncryptionByDefault\": true` is displayed. 3. Review every region in-use.**Note:** EBS volume encryption is configured per region.","ImpactStatement": "Losing access or removing the KMS key in use by the EBS volumes will result in no longer being able to access the volumes.","AssessmentStatus": "Automated","RationaleStatement": "Encrypting data at rest reduces the likelihood that it is unintentionally exposed and can nullify the impact of disclosure if the encryption remains unbroken.","RemediationProcedure": "**From Console:**1. Login to AWS Management Console and open the Amazon EC2 console using https://console.aws.amazon.com/ec2/2. Under `Account attributes`, click `EBS encryption`. 3. Click `Manage`. 4. Click the `Enable` checkbox. 5. Click `Update EBS encryption` 6. Repeat for every region requiring the change.**Note:** EBS volume encryption is configured per region.**From Command Line:**1. Run``` aws --region  ec2 enable-ebs-encryption-by-default ``` 2. Verify that `\"EbsEncryptionByDefault\": true` is displayed. 3. Repeat every region requiring the change.**Note:** EBS volume encryption is configured per region.","AdditionalInformation": "Default EBS volume encryption only applies to newly created EBS volumes. Existing EBS volumes are **not** converted automatically."}],"description": "Ensure EBS Volume Encryption is Enabled in all Regions","checks_status": {"fail": 0,"pass": 1,"total": 1,"manual": 0}},"2.3.1": {"name": "2.3.1","checks": {"rds_instance_storage_encrypted": "FAIL"},"status": "FAIL","attributes": [{"Profile": "Level 1","Section": "2.3. Relational Database Service (RDS)","References": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Encryption.html:https://aws.amazon.com/blogs/database/selecting-the-right-encryption-options-for-amazon-rds-and-amazon-aurora-database-engines/#:~:text=With%20RDS%2Dencrypted%20resources%2C%20data,transparent%20to%20your%20database%20engine.:https://aws.amazon.com/rds/features/security/","Description": "Amazon RDS encrypted DB instances use the industry standard AES-256 encryption algorithm to encrypt your data on the server that hosts your Amazon RDS DB instances. After your data is encrypted, Amazon RDS handles authentication of access and decryption of your data transparently with a minimal impact on performance.","DefaultValue": null,"AuditProcedure": "**From Console:**1. Login to the AWS Management Console and open the RDS dashboard at https://console.aws.amazon.com/rds/ 2. In the navigation pane, under RDS dashboard, click `Databases`. 3. Select the RDS Instance that you want to examine 4. Click `Instance Name` to see details, then click on `Configuration` tab. 5. Under Configuration Details section, In Storage pane search for the `Encryption Enabled` Status. 6. If the current status is set to `Disabled`, Encryption is not enabled for the selected RDS Instance database instance. 7. Repeat steps 3 to 7 to verify encryption status of other RDS Instance in same region. 8. Change region from the top of the navigation bar and repeat audit for other regions.**From Command Line:**1. Run `describe-db-instances` command to list all RDS Instance database names, available in the selected AWS region, Output will return each Instance database identifier-name.``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. Run again `describe-db-instances` command using the RDS Instance identifier returned earlier, to determine if the selected database instance is encrypted, The command output should return the encryption status `True` Or `False`. ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].StorageEncrypted' ``` 3. If the StorageEncrypted parameter value is `False`, Encryption is not enabled for the selected RDS database instance. 4. Repeat steps 1 to 3 for auditing each RDS Instance and change Region to verify for other regions","ImpactStatement": "","AssessmentStatus": "Automated","RationaleStatement": "Databases are likely to hold sensitive and critical data, it is highly recommended to implement encryption in order to protect your data from unauthorized access or disclosure. With RDS encryption enabled, the data stored on the instance's underlying storage, the automated backups, read replicas, and snapshots, are all encrypted.","RemediationProcedure": "**From Console:**1. Login to the AWS Management Console and open the RDS dashboard at https://console.aws.amazon.com/rds/. 2. In the left navigation panel, click on `Databases` 3. Select the Database instance that needs to be encrypted. 4. Click on `Actions` button placed at the top right and select `Take Snapshot`. 5. On the Take Snapshot page, enter a database name of which you want to take a snapshot in the `Snapshot Name` field and click on `Take Snapshot`. 6. Select the newly created snapshot and click on the `Action` button placed at the top right and select `Copy snapshot` from the Action menu. 7. On the Make Copy of DB Snapshot page, perform the following:- In the New DB Snapshot Identifier field, Enter a name for the `new snapshot`. - Check `Copy Tags`, New snapshot must have the same tags as the source snapshot. - Select `Yes` from the `Enable Encryption` dropdown list to enable encryption, You can choose to use the AWS default encryption key or custom key from Master Key dropdown list.8. Click `Copy Snapshot` to create an encrypted copy of the selected instance snapshot. 9. Select the new Snapshot Encrypted Copy and click on the `Action` button placed at the top right and select `Restore Snapshot` button from the Action menu, This will restore the encrypted snapshot to a new database instance. 10. On the Restore DB Instance page, enter a unique name for the new database instance in the DB Instance Identifier field. 11. Review the instance configuration details and click `Restore DB Instance`. 12. As the new instance provisioning process is completed can update application configuration to refer to the endpoint of the new Encrypted database instance Once the database endpoint is changed at the application level, can remove the unencrypted instance.**From Command Line:**1. Run `describe-db-instances` command to list all RDS database names available in the selected AWS region, The command output should return the database instance identifier. ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 2. Run `create-db-snapshot` command to create a snapshot for the selected database instance, The command output will return the `new snapshot` with name DB Snapshot Name. ``` aws rds create-db-snapshot --region  --db-snapshot-identifier  --db-instance-identifier  ``` 3. Now run `list-aliases` command to list the KMS keys aliases available in a specified region, The command output should return each `key alias currently available`. For our RDS encryption activation process, locate the ID of the AWS default KMS key. ``` aws kms list-aliases --region  ``` 4. Run `copy-db-snapshot` command using the default KMS key ID for RDS instances returned earlier to create an encrypted copy of the database instance snapshot, The command output will return the `encrypted instance snapshot configuration`. ``` aws rds copy-db-snapshot --region  --source-db-snapshot-identifier  --target-db-snapshot-identifier  --copy-tags --kms-key-id  ``` 5. Run `restore-db-instance-from-db-snapshot` command to restore the encrypted snapshot created at the previous step to a new database instance, If successful, the command output should return the new encrypted database instance configuration. ``` aws rds restore-db-instance-from-db-snapshot --region  --db-instance-identifier  --db-snapshot-identifier  ``` 6. Run `describe-db-instances` command to list all RDS database names, available in the selected AWS region, Output will return database instance identifier name Select encrypted database name that we just created DB-Name-Encrypted. ``` aws rds describe-db-instances --region  --query 'DBInstances[*].DBInstanceIdentifier' ``` 7. Run again `describe-db-instances` command using the RDS instance identifier returned earlier, to determine if the selected database instance is encrypted, The command output should return the encryption status `True`. ``` aws rds describe-db-instances --region  --db-instance-identifier  --query 'DBInstances[*].StorageEncrypted' ```","AdditionalInformation": ""}],"description": "Ensure that encryption is enabled for RDS Instances","checks_status": {"fail": 1,"pass": 0,"total": 1,"manual": 0}}},"requirements_passed": 48,"requirements_failed": 10,"requirements_manual": 0,"total_requirements": 58,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}},{"model": "api.complianceoverview","pk": "fb07e872-c61f-4749-96d2-da2b68993ae5","fields": {"tenant": "12646005-9067-4d2a-a098-8bb378604362","inserted_at": "2024-11-15T13:14:10.043Z","compliance_id": "gxp_21_cfr_part_11_aws","framework": "GxP-21-CFR-Part-11","version": "","description": "GxP refers to the regulations and guidelines that are applicable to life sciences organizations that make food and medical products. Medical products that fall under this include medicines, medical devices, and medical software applications. The overall intent of GxP requirements is to ensure that food and medical products are safe for consumers. It's also to ensure the integrity of data that's used to make product-related safety decisions.","region": "eu-west-1","requirements": {"11.30": {"name": "11.30 Controls for open systems","checks": {"elb_ssl_listeners": "FAIL","kms_cmk_rotation_enabled": null,"ec2_ebs_volume_encryption": "PASS","ec2_ebs_default_encryption": "PASS","elbv2_insecure_ssl_ciphers": "PASS","s3_bucket_default_encryption": "PASS","efs_encryption_at_rest_enabled": "FAIL","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL","sns_topics_kms_encryption_at_rest_enabled": "FAIL","dynamodb_tables_kms_cmk_encryption_enabled": null,"cloudwatch_log_group_kms_encryption_enabled": "FAIL","apigateway_restapi_client_certificate_enabled": "FAIL","sagemaker_notebook_instance_encryption_enabled": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"opensearch_service_domains_node_to_node_encryption_enabled": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.30","Section": "11.30 Controls for open systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use open systems to create, modify, maintain, or transmit electronic records shall employ procedures and controls designed to ensure the authenticity, integrity, and, as appropriate, the confidentiality of electronic records from the point of their creation to the point of their receipt. Such procedures and controls shall include those identified in 11.10, as appropriate, and additional measures such as document encryption and use of appropriate digital signature standards to ensure, as necessary under the circumstances, record authenticity, integrity, and confidentiality.","checks_status": {"fail": 9,"pass": 4,"total": 21,"manual": 0}},"11.200": {"name": "11.200 Electronic signature components and controls","checks": {"iam_root_mfa_enabled": null,"iam_no_root_access_key": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"iam_user_mfa_enabled_console_access": null,"iam_password_policy_minimum_length_14": null},"status": "PASS","attributes": [{"Type": null,"ItemId": "11.200","Section": "11.200 Electronic signature components and controls","Service": "aws","SubGroup": null,"SubSection": null}],"description": "(a) Electronic signatures that are not based upon biometrics shall: (1) Employ at least two distinct identification components such as an identification code and password. (i) When an individual executes a series of signings during a single, continuous period of controlled system access, the first signing shall be executed using all electronic signature components; subsequent signings shall be executed using at least one electronic signature component that is only executable by, and designed to be used only by, the individual. (ii) When an individual executes one or more signings not performed during a single, continuous period of controlled system access, each signing shall be executed using all of the electronic signature components. (2) Be used only by their genuine owners; and (3) Be administered and executed to ensure that attempted use of an individual's electronic signature by anyone other than its genuine owner requires collaboration of two or more individuals.","checks_status": {"fail": 0,"pass": 0,"total": 12,"manual": 0}},"11.10-a": {"name": "11.10(a)","checks": {"rds_instance_multi_az": "FAIL","elbv2_deletion_protection": "FAIL","ec2_instance_managed_by_ssm": "FAIL","rds_instance_backup_enabled": "PASS","s3_bucket_object_versioning": "FAIL","dynamodb_tables_pitr_enabled": null,"ssm_managed_compliant_patching": "FAIL","rds_instance_deletion_protection": "FAIL","redshift_cluster_automated_snapshot": null,"ec2_instance_older_than_specific_days": "FAIL","cloudtrail_log_file_validation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.10-a","Section": "11.10 Controls for closed systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use closed systems to create, modify, maintain, or transmit electronic records shall employ procedures and controls designed to ensure the authenticity, integrity, and, when appropriate, the confidentiality of electronic records, and to ensure that the signer cannot readily repudiate the signed record as not genuine. Such procedures and controls shall include the following: (a) Validation of systems to ensure accuracy, reliability, consistent intended performance, and the ability to discern invalid or altered records.","checks_status": {"fail": 8,"pass": 1,"total": 13,"manual": 0}},"11.10-c": {"name": "11.10(c)","checks": {"s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","s3_bucket_object_versioning": "FAIL","s3_bucket_default_encryption": "PASS","rds_instance_storage_encrypted": "FAIL","redshift_cluster_audit_logging": null,"redshift_cluster_public_access": null,"cloudtrail_kms_encryption_enabled": "FAIL","s3_bucket_secure_transport_policy": "FAIL","s3_bucket_policy_public_write_access": "PASS","sagemaker_notebook_instance_encryption_enabled": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.10-c","Section": "11.10 Controls for closed systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use closed systems to create, modify, maintain, or transmit electronic records shall employ procedures and controls designed to ensure the authenticity, integrity, and, when appropriate, the confidentiality of electronic records, and to ensure that the signer cannot readily repudiate the signed record as not genuine. Such procedures and controls shall include the following: (c) Protection of records to enable their accurate and ready retrieval throughout the records retention period.","checks_status": {"fail": 5,"pass": 3,"total": 14,"manual": 0}},"11.10-d": {"name": "11.10(d)","checks": {"iam_root_mfa_enabled": null,"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"ec2_instance_profile_attached": "PASS","iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"rds_instance_no_public_access": "PASS","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"iam_user_mfa_enabled_console_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"iam_password_policy_minimum_length_14": null,"s3_account_level_public_access_blocks": null,"secretsmanager_automatic_rotation_enabled": "FAIL","awslambda_function_not_publicly_accessible": "PASS","ec2_securitygroup_default_restrict_traffic": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"iam_customer_attached_policy_no_administrative_privileges": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.10-d","Section": "11.10 Controls for closed systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use closed systems to create, modify, maintain, or transmit electronic records shall employ procedures and controls designed to ensure the authenticity, integrity, and, when appropriate, the confidentiality of electronic records, and to ensure that the signer cannot readily repudiate the signed record as not genuine. Such procedures and controls shall include the following: (d) Limiting system access to authorized individuals.","checks_status": {"fail": 4,"pass": 8,"total": 38,"manual": 0}},"11.10-e": {"name": "11.10(e)","checks": {"elb_logging_enabled": "FAIL","elbv2_logging_enabled": "FAIL","vpc_flow_logs_enabled": "FAIL","redshift_cluster_audit_logging": null,"cloudtrail_multi_region_enabled": "PASS","apigateway_restapi_logging_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","opensearch_service_domains_cloudwatch_logging_enabled": null,"cloudwatch_log_group_retention_policy_specific_days_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.10-d","Section": "11.10 Controls for closed systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use closed systems to create, modify, maintain, or transmit electronic records shall employ procedures and controls designed to ensure the authenticity, integrity, and, when appropriate, the confidentiality of electronic records, and to ensure that the signer cannot readily repudiate the signed record as not genuine. Such procedures and controls shall include the following: (e) Use of secure, computer-generated, time-stamped audit trails to independently record the date and time of operator entries and actions that create, modify, or delete electronic records. Record changes shall not obscure previously recorded information. Such audit trail documentation shall be retained for a period at least as long as that required for the subject electronic records and shall be available for agency review and copying.","checks_status": {"fail": 7,"pass": 2,"total": 14,"manual": 0}},"11.10-g": {"name": "11.10(g)","checks": {"iam_root_mfa_enabled": null,"ec2_instance_public_ip": "FAIL","iam_no_root_access_key": null,"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"ec2_ebs_volume_encryption": "PASS","iam_user_accesskey_unused": null,"ec2_ebs_default_encryption": "PASS","iam_password_policy_number": null,"iam_password_policy_symbol": null,"ec2_instance_imdsv2_enabled": "PASS","rds_snapshots_public_access": "PASS","awslambda_function_url_public": null,"ec2_instance_profile_attached": "PASS","iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_root_hardware_mfa_enabled": null,"iam_rotate_access_key_90_days": null,"rds_instance_no_public_access": "PASS","efs_encryption_at_rest_enabled": "FAIL","iam_user_console_access_unused": null,"redshift_cluster_public_access": null,"iam_user_mfa_enabled_console_access": null,"s3_bucket_policy_public_write_access": "PASS","ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"iam_password_policy_minimum_length_14": null,"s3_account_level_public_access_blocks": null,"secretsmanager_automatic_rotation_enabled": "FAIL","awslambda_function_not_publicly_accessible": "PASS","dynamodb_tables_kms_cmk_encryption_enabled": null,"ec2_securitygroup_default_restrict_traffic": "FAIL","iam_policy_attached_only_to_group_or_roles": null,"iam_inline_policy_no_administrative_privileges": null,"iam_aws_attached_policy_no_administrative_privileges": null,"opensearch_service_domains_encryption_at_rest_enabled": null,"iam_customer_attached_policy_no_administrative_privileges": null,"opensearch_service_domains_node_to_node_encryption_enabled": null,"ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22": "PASS","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.10-g","Section": "11.10 Controls for closed systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use closed systems to create, modify, maintain, or transmit electronic records shall employ procedures and controls designed to ensure the authenticity, integrity, and, when appropriate, the confidentiality of electronic records, and to ensure that the signer cannot readily repudiate the signed record as not genuine. Such procedures and controls shall include the following: (g) Use of authority checks to ensure that only authorized individuals can use the system, electronically sign a record, access the operation or computer system input or output device, alter a record, or perform the operation at hand.","checks_status": {"fail": 5,"pass": 10,"total": 44,"manual": 0}},"11.10-h": {"name": "11.10(h)","checks": {"ec2_instance_managed_by_ssm": "FAIL","ssm_managed_compliant_patching": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.10-h","Section": "11.10 Controls for closed systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use closed systems to create, modify, maintain, or transmit electronic records shall employ procedures and controls designed to ensure the authenticity, integrity, and, when appropriate, the confidentiality of electronic records, and to ensure that the signer cannot readily repudiate the signed record as not genuine. Such procedures and controls shall include the following: (h) Use of device (e.g., terminal) checks to determine, as appropriate, the validity of the source of data input or operational instruction.","checks_status": {"fail": 2,"pass": 0,"total": 3,"manual": 0}},"11.10-k": {"name": "11.10(k)","checks": {"ec2_ebs_public_snapshot": "PASS","s3_bucket_public_access": null,"rds_snapshots_public_access": "PASS","rds_instance_no_public_access": "PASS","redshift_cluster_public_access": null,"cloudtrail_multi_region_enabled": "PASS","s3_bucket_policy_public_write_access": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL","cloudtrail_s3_dataevents_read_enabled": null,"ec2_networkacl_allow_ingress_any_port": "FAIL","emr_cluster_master_nodes_no_public_ip": null,"cloudtrail_s3_dataevents_write_enabled": null,"s3_bucket_server_access_logging_enabled": "FAIL","rds_instance_integration_cloudwatch_logs": "FAIL","ec2_securitygroup_default_restrict_traffic": "FAIL","sagemaker_notebook_instance_without_direct_internet_access_configured": null},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.10-k","Section": "11.10 Controls for closed systems","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use closed systems to create, modify, maintain, or transmit electronic records shall employ procedures and controls designed to ensure the authenticity, integrity, and, when appropriate, the confidentiality of electronic records, and to ensure that the signer cannot readily repudiate the signed record as not genuine. Such procedures and controls shall include the following: (k) Use of appropriate controls over systems documentation including: (1) Adequate controls over the distribution of, access to, and use of documentation for system operation and maintenance. (2) Revision and change control procedures to maintain an audit trail that documents time-sequenced development and modification of systems documentation.","checks_status": {"fail": 5,"pass": 5,"total": 17,"manual": 0}},"11.300-b": {"name": "11.300(b)","checks": {"iam_user_accesskey_unused": null,"iam_password_policy_number": null,"iam_password_policy_symbol": null,"iam_password_policy_lowercase": null,"iam_password_policy_uppercase": null,"iam_rotate_access_key_90_days": null,"iam_user_console_access_unused": null,"iam_password_policy_minimum_length_14": null,"secretsmanager_automatic_rotation_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.300-b","Section": "11.300 Controls for identification codes/passwords","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use electronic signatures based upon use of identification codes in combination with passwords shall employ controls to ensure their security and integrity. Such controls shall include: (b) Ensuring that identification code and password issuances are periodically checked, recalled, or revised (e.g., to cover such events as password aging).","checks_status": {"fail": 1,"pass": 0,"total": 10,"manual": 0}},"11.300-d": {"name": "11.300(d)","checks": {"securityhub_enabled": "PASS","guardduty_is_enabled": "PASS","cloudtrail_multi_region_enabled": "PASS","cloudtrail_cloudwatch_logging_enabled": "FAIL"},"status": "FAIL","attributes": [{"Type": null,"ItemId": "11.300-d","Section": "11.300 Controls for identification codes/passwords","Service": "aws","SubGroup": null,"SubSection": null}],"description": "Persons who use electronic signatures based upon use of identification codes in combination with passwords shall employ controls to ensure their security and integrity. Such controls shall include: (d) Use of transaction safeguards to prevent unauthorized use of passwords and/or identification codes, and to detect and report in an immediate and urgent manner any attempts at their unauthorized use to the system security unit, and, as appropriate, to organizational management.","checks_status": {"fail": 1,"pass": 3,"total": 4,"manual": 0}}},"requirements_passed": 1,"requirements_failed": 10,"requirements_manual": 0,"total_requirements": 11,"scan": "0191e280-9d2f-71c8-9b18-487a23ba185e"}}]
diff --git a/api/src/backend/api/middleware.py b/api/src/backend/api/middleware.py
index 743eff5eb7..63f2fc630b 100644
--- a/api/src/backend/api/middleware.py
+++ b/api/src/backend/api/middleware.py
@@ -8,9 +8,14 @@ def extract_auth_info(request) -> dict:
     if getattr(request, "auth", None) is not None:
         tenant_id = request.auth.get("tenant_id", "N/A")
         user_id = request.auth.get("sub", "N/A")
+        api_key_prefix = request.auth.get("api_key_prefix", "N/A")
     else:
-        tenant_id, user_id = "N/A", "N/A"
-    return {"tenant_id": tenant_id, "user_id": user_id}
+        tenant_id, user_id, api_key_prefix = "N/A", "N/A", "N/A"
+    return {
+        "tenant_id": tenant_id,
+        "user_id": user_id,
+        "api_key_prefix": api_key_prefix,
+    }
 
 
 class APILoggingMiddleware:
@@ -38,6 +43,7 @@ class APILoggingMiddleware:
             extra={
                 "user_id": auth_info["user_id"],
                 "tenant_id": auth_info["tenant_id"],
+                "api_key_prefix": auth_info["api_key_prefix"],
                 "method": request.method,
                 "path": request.path,
                 "query_params": request.GET.dict(),
diff --git a/api/src/backend/api/migrations/0048_api_key.py b/api/src/backend/api/migrations/0048_api_key.py
new file mode 100644
index 0000000000..c3142ecda1
--- /dev/null
+++ b/api/src/backend/api/migrations/0048_api_key.py
@@ -0,0 +1,136 @@
+# Generated by Django 5.1.12 on 2025-09-30 13:10
+
+import uuid
+
+import django.core.validators
+import django.db.models.deletion
+import drf_simple_apikey.models
+from django.conf import settings
+from django.db import migrations, models
+
+import api.db_utils
+import api.rls
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("api", "0047_remove_integration_unique_configuration_per_tenant"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="TenantAPIKey",
+            fields=[
+                (
+                    "name",
+                    models.CharField(
+                        max_length=100,
+                        validators=[django.core.validators.MinLengthValidator(3)],
+                    ),
+                ),
+                (
+                    "expiry_date",
+                    models.DateTimeField(
+                        default=drf_simple_apikey.models._expiry_date,
+                        help_text="Once API key expires, entities cannot use it anymore.",
+                        verbose_name="Expires",
+                    ),
+                ),
+                (
+                    "revoked",
+                    models.BooleanField(
+                        blank=True,
+                        default=False,
+                        help_text="If the API key is revoked, entities cannot use it anymore. (This cannot be undone.)",
+                    ),
+                ),
+                ("created", models.DateTimeField(auto_now_add=True, editable=False)),
+                (
+                    "whitelisted_ips",
+                    models.JSONField(
+                        blank=True,
+                        help_text="List of allowed IP addresses for this API key.",
+                        null=True,
+                    ),
+                ),
+                (
+                    "blacklisted_ips",
+                    models.JSONField(
+                        blank=True,
+                        help_text="List of denied IP addresses for this API key.",
+                        null=True,
+                    ),
+                ),
+                (
+                    "id",
+                    models.UUIDField(
+                        default=uuid.uuid4,
+                        editable=False,
+                        primary_key=True,
+                        serialize=False,
+                    ),
+                ),
+                (
+                    "prefix",
+                    models.CharField(
+                        default=api.db_utils.generate_api_key_prefix,
+                        editable=False,
+                        help_text="Unique prefix to identify the API key",
+                        max_length=11,
+                        unique=True,
+                    ),
+                ),
+                (
+                    "last_used_at",
+                    models.DateTimeField(
+                        blank=True,
+                        help_text="Last time this API key was used for authentication",
+                        null=True,
+                    ),
+                ),
+                (
+                    "entity",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="user_api_keys",
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
+                (
+                    "tenant",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
+                    ),
+                ),
+            ],
+            options={
+                "db_table": "api_keys",
+                "abstract": False,
+                "indexes": [
+                    models.Index(
+                        fields=["tenant_id", "prefix"],
+                        name="api_keys_tenant_prefix_idx",
+                    )
+                ],
+                "constraints": [
+                    models.UniqueConstraint(
+                        fields=("tenant_id", "prefix"), name="unique_api_key_prefixes"
+                    ),
+                    models.UniqueConstraint(
+                        fields=("tenant_id", "name"),
+                        name="unique_api_key_name_per_tenant",
+                    ),
+                ],
+            },
+        ),
+        migrations.AddConstraint(
+            model_name="tenantapikey",
+            constraint=api.rls.RowLevelSecurityConstraint(
+                "tenant_id",
+                name="rls_on_tenantapikey",
+                statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
+            ),
+        ),
+    ]
diff --git a/api/src/backend/api/migrations/0049_compliancerequirementoverview_passed_failed_findings.py b/api/src/backend/api/migrations/0049_compliancerequirementoverview_passed_failed_findings.py
new file mode 100644
index 0000000000..db4f340a53
--- /dev/null
+++ b/api/src/backend/api/migrations/0049_compliancerequirementoverview_passed_failed_findings.py
@@ -0,0 +1,21 @@
+# Generated by Django 5.1.12 on 2025-10-07 10:41
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("api", "0048_api_key"),
+    ]
+    operations = [
+        migrations.AddField(
+            model_name="compliancerequirementoverview",
+            name="passed_findings",
+            field=models.IntegerField(default=0),
+        ),
+        migrations.AddField(
+            model_name="compliancerequirementoverview",
+            name="total_findings",
+            field=models.IntegerField(default=0),
+        ),
+    ]
diff --git a/api/src/backend/api/migrations/0050_lighthouse_multi_llm.py b/api/src/backend/api/migrations/0050_lighthouse_multi_llm.py
new file mode 100644
index 0000000000..99a9353327
--- /dev/null
+++ b/api/src/backend/api/migrations/0050_lighthouse_multi_llm.py
@@ -0,0 +1,266 @@
+# Generated by Django 5.1.12 on 2025-10-09 07:50
+
+import json
+import logging
+import uuid
+
+import django.db.models.deletion
+from config.custom_logging import BackendLogger
+from cryptography.fernet import Fernet
+from django.conf import settings
+from django.db import migrations, models
+
+import api.rls
+from api.db_router import MainRouter
+
+logger = logging.getLogger(BackendLogger.API)
+
+
+def migrate_lighthouse_configs_forward(apps, schema_editor):
+    """
+    Migrate data from old LighthouseConfiguration to new multi-provider models.
+    Old system: one LighthouseConfiguration per tenant (always OpenAI).
+    """
+    LighthouseConfiguration = apps.get_model("api", "LighthouseConfiguration")
+    LighthouseProviderConfiguration = apps.get_model(
+        "api", "LighthouseProviderConfiguration"
+    )
+    LighthouseTenantConfiguration = apps.get_model(
+        "api", "LighthouseTenantConfiguration"
+    )
+    LighthouseProviderModels = apps.get_model("api", "LighthouseProviderModels")
+
+    fernet = Fernet(settings.SECRETS_ENCRYPTION_KEY.encode())
+
+    # Migrate only tenants that actually have a LighthouseConfiguration
+    for old_config in (
+        LighthouseConfiguration.objects.using(MainRouter.admin_db)
+        .select_related("tenant")
+        .all()
+    ):
+        tenant = old_config.tenant
+        tenant_id = str(tenant.id)
+
+        try:
+            # Create OpenAI provider configuration for this tenant
+            api_key_decrypted = fernet.decrypt(bytes(old_config.api_key)).decode()
+            credentials_encrypted = fernet.encrypt(
+                json.dumps({"api_key": api_key_decrypted}).encode()
+            )
+            provider_config = LighthouseProviderConfiguration.objects.using(
+                MainRouter.admin_db
+            ).create(
+                tenant=tenant,
+                provider_type="openai",
+                credentials=credentials_encrypted,
+                is_active=old_config.is_active,
+            )
+
+            # Create tenant configuration from old values
+            LighthouseTenantConfiguration.objects.using(MainRouter.admin_db).create(
+                tenant=tenant,
+                business_context=old_config.business_context or "",
+                default_provider="openai",
+                default_models={"openai": old_config.model},
+            )
+
+            # Create initial provider model record
+            LighthouseProviderModels.objects.using(MainRouter.admin_db).create(
+                tenant=tenant,
+                provider_configuration=provider_config,
+                model_id=old_config.model,
+                model_name=old_config.model,
+                default_parameters={},
+            )
+
+        except Exception:
+            logger.exception(
+                "Failed to migrate lighthouse config for tenant %s", tenant_id
+            )
+            continue
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("api", "0049_compliancerequirementoverview_passed_failed_findings"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="LighthouseProviderConfiguration",
+            fields=[
+                (
+                    "id",
+                    models.UUIDField(
+                        default=uuid.uuid4,
+                        editable=False,
+                        primary_key=True,
+                        serialize=False,
+                    ),
+                ),
+                ("inserted_at", models.DateTimeField(auto_now_add=True)),
+                ("updated_at", models.DateTimeField(auto_now=True)),
+                (
+                    "provider_type",
+                    models.CharField(
+                        choices=[("openai", "OpenAI")],
+                        help_text="LLM provider name",
+                        max_length=50,
+                    ),
+                ),
+                ("base_url", models.URLField(blank=True, null=True)),
+                (
+                    "credentials",
+                    models.BinaryField(
+                        help_text="Encrypted JSON credentials for the provider"
+                    ),
+                ),
+                ("is_active", models.BooleanField(default=True)),
+            ],
+            options={
+                "db_table": "lighthouse_provider_configurations",
+                "abstract": False,
+            },
+        ),
+        migrations.CreateModel(
+            name="LighthouseProviderModels",
+            fields=[
+                (
+                    "id",
+                    models.UUIDField(
+                        default=uuid.uuid4,
+                        editable=False,
+                        primary_key=True,
+                        serialize=False,
+                    ),
+                ),
+                ("inserted_at", models.DateTimeField(auto_now_add=True)),
+                ("updated_at", models.DateTimeField(auto_now=True)),
+                ("model_id", models.CharField(max_length=100)),
+                ("model_name", models.CharField(max_length=100)),
+                ("default_parameters", models.JSONField(blank=True, default=dict)),
+            ],
+            options={
+                "db_table": "lighthouse_provider_models",
+                "abstract": False,
+            },
+        ),
+        migrations.CreateModel(
+            name="LighthouseTenantConfiguration",
+            fields=[
+                (
+                    "id",
+                    models.UUIDField(
+                        default=uuid.uuid4,
+                        editable=False,
+                        primary_key=True,
+                        serialize=False,
+                    ),
+                ),
+                ("inserted_at", models.DateTimeField(auto_now_add=True)),
+                ("updated_at", models.DateTimeField(auto_now=True)),
+                ("business_context", models.TextField(blank=True, default="")),
+                ("default_provider", models.CharField(blank=True, max_length=50)),
+                ("default_models", models.JSONField(blank=True, default=dict)),
+            ],
+            options={
+                "db_table": "lighthouse_tenant_config",
+                "abstract": False,
+            },
+        ),
+        migrations.AddField(
+            model_name="lighthouseproviderconfiguration",
+            name="tenant",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
+            ),
+        ),
+        migrations.AddField(
+            model_name="lighthouseprovidermodels",
+            name="provider_configuration",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name="available_models",
+                to="api.lighthouseproviderconfiguration",
+            ),
+        ),
+        migrations.AddField(
+            model_name="lighthouseprovidermodels",
+            name="tenant",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
+            ),
+        ),
+        migrations.AddField(
+            model_name="lighthousetenantconfiguration",
+            name="tenant",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
+            ),
+        ),
+        migrations.AddIndex(
+            model_name="lighthouseproviderconfiguration",
+            index=models.Index(
+                fields=["tenant_id", "provider_type"], name="lh_pc_tenant_type_idx"
+            ),
+        ),
+        migrations.AddConstraint(
+            model_name="lighthouseproviderconfiguration",
+            constraint=api.rls.RowLevelSecurityConstraint(
+                "tenant_id",
+                name="rls_on_lighthouseproviderconfiguration",
+                statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
+            ),
+        ),
+        migrations.AddConstraint(
+            model_name="lighthouseproviderconfiguration",
+            constraint=models.UniqueConstraint(
+                fields=("tenant_id", "provider_type"),
+                name="unique_provider_config_per_tenant",
+            ),
+        ),
+        migrations.AddIndex(
+            model_name="lighthouseprovidermodels",
+            index=models.Index(
+                fields=["tenant_id", "provider_configuration"],
+                name="lh_prov_models_cfg_idx",
+            ),
+        ),
+        migrations.AddConstraint(
+            model_name="lighthouseprovidermodels",
+            constraint=api.rls.RowLevelSecurityConstraint(
+                "tenant_id",
+                name="rls_on_lighthouseprovidermodels",
+                statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
+            ),
+        ),
+        migrations.AddConstraint(
+            model_name="lighthouseprovidermodels",
+            constraint=models.UniqueConstraint(
+                fields=("tenant_id", "provider_configuration", "model_id"),
+                name="unique_provider_model_per_configuration",
+            ),
+        ),
+        migrations.AddConstraint(
+            model_name="lighthousetenantconfiguration",
+            constraint=api.rls.RowLevelSecurityConstraint(
+                "tenant_id",
+                name="rls_on_lighthousetenantconfiguration",
+                statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
+            ),
+        ),
+        migrations.AddConstraint(
+            model_name="lighthousetenantconfiguration",
+            constraint=models.UniqueConstraint(
+                fields=("tenant_id",), name="unique_tenant_lighthouse_config"
+            ),
+        ),
+        # Migrate data from old LighthouseConfiguration to new tables
+        # This runs after all tables, indexes, and constraints are created
+        # The old Lighthouse configuration table is not removed, so reverse_code is noop
+        # During rollbacks, the old Lighthouse configuration remains intact while the new tables are removed
+        migrations.RunPython(
+            migrate_lighthouse_configs_forward,
+            reverse_code=migrations.RunPython.noop,
+        ),
+    ]
diff --git a/api/src/backend/api/migrations/0051_oraclecloud_provider.py b/api/src/backend/api/migrations/0051_oraclecloud_provider.py
new file mode 100644
index 0000000000..022c022ea6
--- /dev/null
+++ b/api/src/backend/api/migrations/0051_oraclecloud_provider.py
@@ -0,0 +1,34 @@
+# Generated by Django 5.1.7 on 2025-10-14 00:00
+
+from django.db import migrations
+
+import api.db_utils
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("api", "0050_lighthouse_multi_llm"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="provider",
+            name="provider",
+            field=api.db_utils.ProviderEnumField(
+                choices=[
+                    ("aws", "AWS"),
+                    ("azure", "Azure"),
+                    ("gcp", "GCP"),
+                    ("kubernetes", "Kubernetes"),
+                    ("m365", "M365"),
+                    ("github", "GitHub"),
+                    ("oraclecloud", "Oracle Cloud Infrastructure"),
+                ],
+                default="aws",
+            ),
+        ),
+        migrations.RunSQL(
+            "ALTER TYPE provider ADD VALUE IF NOT EXISTS 'oraclecloud';",
+            reverse_sql=migrations.RunSQL.noop,
+        ),
+    ]
diff --git a/api/src/backend/api/migrations/0052_mute_rules.py b/api/src/backend/api/migrations/0052_mute_rules.py
new file mode 100644
index 0000000000..56a3ff516f
--- /dev/null
+++ b/api/src/backend/api/migrations/0052_mute_rules.py
@@ -0,0 +1,117 @@
+# Generated by Django 5.1.13 on 2025-10-22 11:56
+
+import uuid
+
+import django.contrib.postgres.fields
+import django.core.validators
+import django.db.models.deletion
+from django.conf import settings
+from django.db import migrations, models
+
+import api.rls
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("api", "0051_oraclecloud_provider"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="MuteRule",
+            fields=[
+                (
+                    "id",
+                    models.UUIDField(
+                        default=uuid.uuid4,
+                        editable=False,
+                        primary_key=True,
+                        serialize=False,
+                    ),
+                ),
+                ("inserted_at", models.DateTimeField(auto_now_add=True)),
+                ("updated_at", models.DateTimeField(auto_now=True)),
+                (
+                    "name",
+                    models.CharField(
+                        help_text="Human-readable name for this rule",
+                        max_length=100,
+                        validators=[django.core.validators.MinLengthValidator(3)],
+                    ),
+                ),
+                (
+                    "reason",
+                    models.TextField(
+                        help_text="Reason for muting",
+                        max_length=500,
+                        validators=[django.core.validators.MinLengthValidator(3)],
+                    ),
+                ),
+                (
+                    "enabled",
+                    models.BooleanField(
+                        default=True, help_text="Whether this rule is currently enabled"
+                    ),
+                ),
+                (
+                    "finding_uids",
+                    django.contrib.postgres.fields.ArrayField(
+                        base_field=models.CharField(max_length=255),
+                        help_text="List of finding UIDs to mute",
+                        size=None,
+                    ),
+                ),
+            ],
+            options={
+                "db_table": "mute_rules",
+                "abstract": False,
+            },
+        ),
+        migrations.AddField(
+            model_name="finding",
+            name="muted_at",
+            field=models.DateTimeField(
+                blank=True, help_text="Timestamp when this finding was muted", null=True
+            ),
+        ),
+        migrations.AlterField(
+            model_name="tenantapikey",
+            name="name",
+            field=models.CharField(
+                max_length=100,
+                validators=[django.core.validators.MinLengthValidator(3)],
+            ),
+        ),
+        migrations.AddField(
+            model_name="muterule",
+            name="created_by",
+            field=models.ForeignKey(
+                help_text="User who created this rule",
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name="created_mute_rules",
+                to=settings.AUTH_USER_MODEL,
+            ),
+        ),
+        migrations.AddField(
+            model_name="muterule",
+            name="tenant",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
+            ),
+        ),
+        migrations.AddConstraint(
+            model_name="muterule",
+            constraint=api.rls.RowLevelSecurityConstraint(
+                "tenant_id",
+                name="rls_on_muterule",
+                statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
+            ),
+        ),
+        migrations.AddConstraint(
+            model_name="muterule",
+            constraint=models.UniqueConstraint(
+                fields=("tenant_id", "name"), name="unique_mute_rule_name_per_tenant"
+            ),
+        ),
+    ]
diff --git a/api/src/backend/api/migrations/0053_lighthouse_bedrock_openai_compatible.py b/api/src/backend/api/migrations/0053_lighthouse_bedrock_openai_compatible.py
new file mode 100644
index 0000000000..d7054d6443
--- /dev/null
+++ b/api/src/backend/api/migrations/0053_lighthouse_bedrock_openai_compatible.py
@@ -0,0 +1,25 @@
+# Generated by Django 5.1.12 on 2025-10-14 11:46
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("api", "0052_mute_rules"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="lighthouseproviderconfiguration",
+            name="provider_type",
+            field=models.CharField(
+                choices=[
+                    ("openai", "OpenAI"),
+                    ("bedrock", "AWS Bedrock"),
+                    ("openai_compatible", "OpenAI Compatible"),
+                ],
+                help_text="LLM provider name",
+                max_length=50,
+            ),
+        )
+    ]
diff --git a/api/src/backend/api/migrations/0054_iac_provider.py b/api/src/backend/api/migrations/0054_iac_provider.py
new file mode 100644
index 0000000000..3ba456b0cf
--- /dev/null
+++ b/api/src/backend/api/migrations/0054_iac_provider.py
@@ -0,0 +1,35 @@
+# Generated by Django 5.1.10 on 2025-09-09 09:25
+
+from django.db import migrations
+
+import api.db_utils
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("api", "0053_lighthouse_bedrock_openai_compatible"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="provider",
+            name="provider",
+            field=api.db_utils.ProviderEnumField(
+                choices=[
+                    ("aws", "AWS"),
+                    ("azure", "Azure"),
+                    ("gcp", "GCP"),
+                    ("kubernetes", "Kubernetes"),
+                    ("m365", "M365"),
+                    ("github", "GitHub"),
+                    ("oci", "Oracle Cloud Infrastructure"),
+                    ("iac", "IaC"),
+                ],
+                default="aws",
+            ),
+        ),
+        migrations.RunSQL(
+            "ALTER TYPE provider ADD VALUE IF NOT EXISTS 'iac';",
+            reverse_sql=migrations.RunSQL.noop,
+        ),
+    ]
diff --git a/api/src/backend/api/migrations/0055_mongodbatlas_provider.py b/api/src/backend/api/migrations/0055_mongodbatlas_provider.py
new file mode 100644
index 0000000000..beb7a3946a
--- /dev/null
+++ b/api/src/backend/api/migrations/0055_mongodbatlas_provider.py
@@ -0,0 +1,32 @@
+# Generated by Django 5.1.13 on 2025-11-05 08:37
+
+from django.db import migrations
+
+import api.db_utils
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("api", "0054_iac_provider"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="provider",
+            name="provider",
+            field=api.db_utils.ProviderEnumField(
+                choices=[
+                    ("aws", "AWS"),
+                    ("azure", "Azure"),
+                    ("gcp", "GCP"),
+                    ("kubernetes", "Kubernetes"),
+                    ("m365", "M365"),
+                    ("github", "GitHub"),
+                    ("mongodbatlas", "MongoDB Atlas"),
+                    ("iac", "IaC"),
+                    ("oraclecloud", "Oracle Cloud Infrastructure"),
+                ],
+                default="aws",
+            ),
+        ),
+    ]
diff --git a/api/src/backend/api/migrations/0056_remove_provider_unique_provider_uids_and_more.py b/api/src/backend/api/migrations/0056_remove_provider_unique_provider_uids_and_more.py
new file mode 100644
index 0000000000..14cbc4fa47
--- /dev/null
+++ b/api/src/backend/api/migrations/0056_remove_provider_unique_provider_uids_and_more.py
@@ -0,0 +1,24 @@
+# Generated by Django 5.1.13 on 2025-11-06 09:20
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("api", "0055_mongodbatlas_provider"),
+    ]
+
+    operations = [
+        migrations.RemoveConstraint(
+            model_name="provider",
+            name="unique_provider_uids",
+        ),
+        migrations.AddConstraint(
+            model_name="provider",
+            constraint=models.UniqueConstraint(
+                condition=models.Q(("is_deleted", False)),
+                fields=("tenant_id", "provider", "uid"),
+                name="unique_provider_uids",
+            ),
+        ),
+    ]
diff --git a/api/src/backend/api/migrations/0057_threatscoresnapshot.py b/api/src/backend/api/migrations/0057_threatscoresnapshot.py
new file mode 100644
index 0000000000..ee3530a5b6
--- /dev/null
+++ b/api/src/backend/api/migrations/0057_threatscoresnapshot.py
@@ -0,0 +1,170 @@
+# Generated by Django 5.1.13 on 2025-10-31 09:04
+
+import uuid
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+import api.rls
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("api", "0056_remove_provider_unique_provider_uids_and_more"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="ThreatScoreSnapshot",
+            fields=[
+                (
+                    "id",
+                    models.UUIDField(
+                        default=uuid.uuid4,
+                        editable=False,
+                        primary_key=True,
+                        serialize=False,
+                    ),
+                ),
+                ("inserted_at", models.DateTimeField(auto_now_add=True)),
+                (
+                    "compliance_id",
+                    models.CharField(
+                        help_text="Compliance framework ID (e.g., 'prowler_threatscore_aws')",
+                        max_length=100,
+                    ),
+                ),
+                (
+                    "overall_score",
+                    models.DecimalField(
+                        decimal_places=2,
+                        help_text="Overall ThreatScore percentage (0-100)",
+                        max_digits=5,
+                    ),
+                ),
+                (
+                    "score_delta",
+                    models.DecimalField(
+                        blank=True,
+                        decimal_places=2,
+                        help_text="Score change compared to previous snapshot (positive = improvement)",
+                        max_digits=5,
+                        null=True,
+                    ),
+                ),
+                (
+                    "section_scores",
+                    models.JSONField(
+                        blank=True,
+                        default=dict,
+                        help_text="ThreatScore breakdown by section",
+                    ),
+                ),
+                (
+                    "critical_requirements",
+                    models.JSONField(
+                        blank=True,
+                        default=list,
+                        help_text="List of critical failed requirements (risk >= 4)",
+                    ),
+                ),
+                (
+                    "total_requirements",
+                    models.IntegerField(
+                        default=0, help_text="Total number of requirements evaluated"
+                    ),
+                ),
+                (
+                    "passed_requirements",
+                    models.IntegerField(
+                        default=0, help_text="Number of requirements with PASS status"
+                    ),
+                ),
+                (
+                    "failed_requirements",
+                    models.IntegerField(
+                        default=0, help_text="Number of requirements with FAIL status"
+                    ),
+                ),
+                (
+                    "manual_requirements",
+                    models.IntegerField(
+                        default=0, help_text="Number of requirements with MANUAL status"
+                    ),
+                ),
+                (
+                    "total_findings",
+                    models.IntegerField(
+                        default=0,
+                        help_text="Total number of findings across all requirements",
+                    ),
+                ),
+                (
+                    "passed_findings",
+                    models.IntegerField(
+                        default=0, help_text="Number of findings with PASS status"
+                    ),
+                ),
+                (
+                    "failed_findings",
+                    models.IntegerField(
+                        default=0, help_text="Number of findings with FAIL status"
+                    ),
+                ),
+                (
+                    "provider",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="threatscore_snapshots",
+                        related_query_name="threatscore_snapshot",
+                        to="api.provider",
+                    ),
+                ),
+                (
+                    "scan",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="threatscore_snapshots",
+                        related_query_name="threatscore_snapshot",
+                        to="api.scan",
+                    ),
+                ),
+                (
+                    "tenant",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
+                    ),
+                ),
+            ],
+            options={
+                "db_table": "threatscore_snapshots",
+                "abstract": False,
+            },
+        ),
+        migrations.AddIndex(
+            model_name="threatscoresnapshot",
+            index=models.Index(
+                fields=["tenant_id", "scan_id"], name="threatscore_snap_t_scan_idx"
+            ),
+        ),
+        migrations.AddIndex(
+            model_name="threatscoresnapshot",
+            index=models.Index(
+                fields=["tenant_id", "provider_id"], name="threatscore_snap_t_prov_idx"
+            ),
+        ),
+        migrations.AddIndex(
+            model_name="threatscoresnapshot",
+            index=models.Index(
+                fields=["tenant_id", "inserted_at"], name="threatscore_snap_t_time_idx"
+            ),
+        ),
+        migrations.AddConstraint(
+            model_name="threatscoresnapshot",
+            constraint=api.rls.RowLevelSecurityConstraint(
+                "tenant_id",
+                name="rls_on_threatscoresnapshot",
+                statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
+            ),
+        ),
+    ]
diff --git a/api/src/backend/api/migrations/0058_drop_redundant_compliance_requirement_indexes.py b/api/src/backend/api/migrations/0058_drop_redundant_compliance_requirement_indexes.py
new file mode 100644
index 0000000000..1d2ee35f4d
--- /dev/null
+++ b/api/src/backend/api/migrations/0058_drop_redundant_compliance_requirement_indexes.py
@@ -0,0 +1,25 @@
+from django.contrib.postgres.operations import RemoveIndexConcurrently
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+    atomic = False
+
+    dependencies = [
+        ("api", "0057_threatscoresnapshot"),
+    ]
+
+    operations = [
+        RemoveIndexConcurrently(
+            model_name="compliancerequirementoverview",
+            name="cro_tenant_scan_idx",
+        ),
+        RemoveIndexConcurrently(
+            model_name="compliancerequirementoverview",
+            name="cro_scan_comp_idx",
+        ),
+        RemoveIndexConcurrently(
+            model_name="compliancerequirementoverview",
+            name="cro_scan_comp_req_idx",
+        ),
+    ]
diff --git a/api/src/backend/api/migrations/0059_compliance_overview_summary.py b/api/src/backend/api/migrations/0059_compliance_overview_summary.py
new file mode 100644
index 0000000000..d2d57a34ae
--- /dev/null
+++ b/api/src/backend/api/migrations/0059_compliance_overview_summary.py
@@ -0,0 +1,75 @@
+# Generated by Django 5.1.13 on 2025-10-30 15:23
+
+import uuid
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+import api.rls
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("api", "0058_drop_redundant_compliance_requirement_indexes"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="ComplianceOverviewSummary",
+            fields=[
+                (
+                    "id",
+                    models.UUIDField(
+                        default=uuid.uuid4,
+                        editable=False,
+                        primary_key=True,
+                        serialize=False,
+                    ),
+                ),
+                ("inserted_at", models.DateTimeField(auto_now_add=True)),
+                ("compliance_id", models.TextField()),
+                ("requirements_passed", models.IntegerField(default=0)),
+                ("requirements_failed", models.IntegerField(default=0)),
+                ("requirements_manual", models.IntegerField(default=0)),
+                ("total_requirements", models.IntegerField(default=0)),
+                (
+                    "scan",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="compliance_summaries",
+                        related_query_name="compliance_summary",
+                        to="api.scan",
+                    ),
+                ),
+                (
+                    "tenant",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
+                    ),
+                ),
+            ],
+            options={
+                "db_table": "compliance_overview_summaries",
+                "abstract": False,
+                "indexes": [
+                    models.Index(
+                        fields=["tenant_id", "scan_id"], name="cos_tenant_scan_idx"
+                    )
+                ],
+                "constraints": [
+                    models.UniqueConstraint(
+                        fields=("tenant_id", "scan_id", "compliance_id"),
+                        name="unique_compliance_summary_per_scan",
+                    )
+                ],
+            },
+        ),
+        migrations.AddConstraint(
+            model_name="complianceoverviewsummary",
+            constraint=api.rls.RowLevelSecurityConstraint(
+                "tenant_id",
+                name="rls_on_complianceoverviewsummary",
+                statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
+            ),
+        ),
+    ]
diff --git a/api/src/backend/api/models.py b/api/src/backend/api/models.py
index 6c20032dbc..1191350ac6 100644
--- a/api/src/backend/api/models.py
+++ b/api/src/backend/api/models.py
@@ -22,6 +22,8 @@ from django.db.models import Q
 from django.utils.translation import gettext_lazy as _
 from django_celery_beat.models import PeriodicTask
 from django_celery_results.models import TaskResult
+from drf_simple_apikey.crypto import get_crypto
+from drf_simple_apikey.models import AbstractAPIKey, AbstractAPIKeyManager
 from psqlextra.manager import PostgresManager
 from psqlextra.models import PostgresPartitionedModel
 from psqlextra.types import PostgresPartitioningMethod
@@ -42,6 +44,7 @@ from api.db_utils import (
     StateEnumField,
     StatusEnumField,
     enum_to_choices,
+    generate_api_key_prefix,
     generate_random_token,
     one_week_from_now,
 )
@@ -74,6 +77,15 @@ class StatusChoices(models.TextChoices):
     MANUAL = "MANUAL", _("Manual")
 
 
+class OverviewStatusChoices(models.TextChoices):
+    """
+    Status filters allowed in overview/severity endpoints.
+    """
+
+    FAIL = "FAIL", _("Fail")
+    PASS = "PASS", _("Pass")
+
+
 class StateChoices(models.TextChoices):
     AVAILABLE = "available", _("Available")
     SCHEDULED = "scheduled", _("Scheduled")
@@ -116,6 +128,17 @@ class ActiveProviderPartitionedManager(PostgresManager, ActiveProviderManager):
         return super().get_queryset().filter(self.active_provider_filter())
 
 
+class TenantAPIKeyManager(AbstractAPIKeyManager):
+    separator = "."
+
+    def assign_api_key(self, obj) -> str:
+        payload = {"_pk": str(obj.pk), "_exp": obj.expiry_date.timestamp()}
+        key = get_crypto().generate(payload)
+
+        prefixed_key = f"{obj.prefix}{self.separator}{key}"
+        return prefixed_key
+
+
 class User(AbstractBaseUser):
     id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
     name = models.CharField(max_length=150, validators=[MinLengthValidator(3)])
@@ -195,6 +218,61 @@ class Membership(models.Model):
         resource_name = "memberships"
 
 
+class TenantAPIKey(AbstractAPIKey, RowLevelSecurityProtectedModel):
+    id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
+    name = models.CharField(max_length=100, validators=[MinLengthValidator(3)])
+    created = models.DateTimeField(auto_now_add=True, editable=False)
+    prefix = models.CharField(
+        max_length=11,
+        unique=True,
+        default=generate_api_key_prefix,
+        editable=False,
+        help_text="Unique prefix to identify the API key",
+    )
+    last_used_at = models.DateTimeField(
+        null=True,
+        blank=True,
+        help_text="Last time this API key was used for authentication",
+    )
+    entity = models.ForeignKey(
+        settings.AUTH_USER_MODEL,
+        on_delete=models.SET_NULL,
+        null=True,
+        blank=True,
+        related_name="user_api_keys",
+    )
+
+    objects = TenantAPIKeyManager()
+
+    class Meta(RowLevelSecurityProtectedModel.Meta):
+        db_table = "api_keys"
+
+        constraints = [
+            RowLevelSecurityConstraint(
+                field="tenant_id",
+                name="rls_on_%(class)s",
+                statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
+            ),
+            models.UniqueConstraint(
+                fields=("tenant_id", "prefix"),
+                name="unique_api_key_prefixes",
+            ),
+            models.UniqueConstraint(
+                fields=("tenant_id", "name"),
+                name="unique_api_key_name_per_tenant",
+            ),
+        ]
+
+        indexes = [
+            models.Index(
+                fields=["tenant_id", "prefix"], name="api_keys_tenant_prefix_idx"
+            ),
+        ]
+
+    class JSONAPIMeta:
+        resource_name = "api-keys"
+
+
 class Provider(RowLevelSecurityProtectedModel):
     objects = ActiveProviderManager()
     all_objects = models.Manager()
@@ -206,6 +284,9 @@ class Provider(RowLevelSecurityProtectedModel):
         KUBERNETES = "kubernetes", _("Kubernetes")
         M365 = "m365", _("M365")
         GITHUB = "github", _("GitHub")
+        MONGODBATLAS = "mongodbatlas", _("MongoDB Atlas")
+        IAC = "iac", _("IaC")
+        ORACLECLOUD = "oraclecloud", _("Oracle Cloud Infrastructure")
 
     @staticmethod
     def validate_aws_uid(value):
@@ -276,6 +357,40 @@ class Provider(RowLevelSecurityProtectedModel):
                 pointer="/data/attributes/uid",
             )
 
+    @staticmethod
+    def validate_iac_uid(value):
+        # Validate that it's a valid repository URL (git URL format)
+        if not re.match(
+            r"^(https?://|git@|ssh://)[^\s/]+[^\s]*\.git$|^(https?://)[^\s/]+[^\s]*$",
+            value,
+        ):
+            raise ModelValidationError(
+                detail="IaC provider ID must be a valid repository URL (e.g., https://github.com/user/repo or https://github.com/user/repo.git).",
+                code="iac-uid",
+                pointer="/data/attributes/uid",
+            )
+
+    @staticmethod
+    def validate_oraclecloud_uid(value):
+        if not re.match(
+            r"^ocid1\.([a-z0-9_-]+)\.([a-z0-9_-]+)\.([a-z0-9_-]*)\.([a-z0-9]+)$", value
+        ):
+            raise ModelValidationError(
+                detail="Oracle Cloud Infrastructure provider ID must be a valid tenancy OCID in the format: "
+                "ocid1....",
+                code="oraclecloud-uid",
+                pointer="/data/attributes/uid",
+            )
+
+    @staticmethod
+    def validate_mongodbatlas_uid(value):
+        if not re.match(r"^[0-9a-fA-F]{24}$", value):
+            raise ModelValidationError(
+                detail="MongoDB Atlas organization ID must be a 24-character hexadecimal string.",
+                code="mongodbatlas-uid",
+                pointer="/data/attributes/uid",
+            )
+
     id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
     inserted_at = models.DateTimeField(auto_now_add=True, editable=False)
     updated_at = models.DateTimeField(auto_now=True, editable=False)
@@ -310,7 +425,8 @@ class Provider(RowLevelSecurityProtectedModel):
 
         constraints = [
             models.UniqueConstraint(
-                fields=("tenant_id", "provider", "uid", "is_deleted"),
+                fields=("tenant_id", "provider", "uid"),
+                condition=Q(is_deleted=False),
                 name="unique_provider_uids",
             ),
             RowLevelSecurityConstraint(
@@ -732,6 +848,9 @@ class Finding(PostgresPartitionedModel, RowLevelSecurityProtectedModel):
     muted_reason = models.TextField(
         blank=True, null=True, validators=[MinLengthValidator(3)], max_length=500
     )
+    muted_at = models.DateTimeField(
+        null=True, blank=True, help_text="Timestamp when this finding was muted"
+    )
     compliance = models.JSONField(default=dict, null=True, blank=True)
 
     # Denormalize resource data for performance
@@ -1221,6 +1340,8 @@ class ComplianceRequirementOverview(RowLevelSecurityProtectedModel):
     passed_checks = models.IntegerField(default=0)
     failed_checks = models.IntegerField(default=0)
     total_checks = models.IntegerField(default=0)
+    passed_findings = models.IntegerField(default=0)
+    total_findings = models.IntegerField(default=0)
 
     scan = models.ForeignKey(
         Scan,
@@ -1250,35 +1371,70 @@ class ComplianceRequirementOverview(RowLevelSecurityProtectedModel):
             ),
         ]
         indexes = [
-            models.Index(fields=["tenant_id", "scan_id"], name="cro_tenant_scan_idx"),
-            models.Index(
-                fields=["tenant_id", "scan_id", "compliance_id"],
-                name="cro_scan_comp_idx",
-            ),
             models.Index(
                 fields=["tenant_id", "scan_id", "compliance_id", "region"],
                 name="cro_scan_comp_reg_idx",
             ),
-            models.Index(
-                fields=["tenant_id", "scan_id", "compliance_id", "requirement_id"],
-                name="cro_scan_comp_req_idx",
-            ),
-            models.Index(
-                fields=[
-                    "tenant_id",
-                    "scan_id",
-                    "compliance_id",
-                    "requirement_id",
-                    "region",
-                ],
-                name="cro_scan_comp_req_reg_idx",
-            ),
         ]
 
     class JSONAPIMeta:
         resource_name = "compliance-requirements-overviews"
 
 
+class ComplianceOverviewSummary(RowLevelSecurityProtectedModel):
+    """
+    Pre-aggregated compliance overview aggregated across ALL regions.
+    One row per (scan_id, compliance_id) combination.
+
+    This table optimizes the common case where users view overall compliance
+    without filtering by region. For region-specific views, the detailed
+    ComplianceRequirementOverview table is used instead.
+    """
+
+    id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
+    inserted_at = models.DateTimeField(auto_now_add=True, editable=False)
+
+    scan = models.ForeignKey(
+        Scan,
+        on_delete=models.CASCADE,
+        related_name="compliance_summaries",
+        related_query_name="compliance_summary",
+    )
+
+    compliance_id = models.TextField(blank=False)
+
+    # Pre-aggregated scores (computed across ALL regions)
+    requirements_passed = models.IntegerField(default=0)
+    requirements_failed = models.IntegerField(default=0)
+    requirements_manual = models.IntegerField(default=0)
+    total_requirements = models.IntegerField(default=0)
+
+    class Meta(RowLevelSecurityProtectedModel.Meta):
+        db_table = "compliance_overview_summaries"
+
+        constraints = [
+            models.UniqueConstraint(
+                fields=("tenant_id", "scan_id", "compliance_id"),
+                name="unique_compliance_summary_per_scan",
+            ),
+            RowLevelSecurityConstraint(
+                field="tenant_id",
+                name="rls_on_%(class)s",
+                statements=["SELECT", "INSERT", "DELETE"],
+            ),
+        ]
+
+        indexes = [
+            models.Index(
+                fields=["tenant_id", "scan_id"],
+                name="cos_tenant_scan_idx",
+            ),
+        ]
+
+    class JSONAPIMeta:
+        resource_name = "compliance-overview-summaries"
+
+
 class ScanSummary(RowLevelSecurityProtectedModel):
     objects = ActiveProviderManager()
     all_objects = models.Manager()
@@ -1793,22 +1949,6 @@ class LighthouseConfiguration(RowLevelSecurityProtectedModel):
     def clean(self):
         super().clean()
 
-        # Validate temperature
-        if not 0 <= self.temperature <= 1:
-            raise ModelValidationError(
-                detail="Temperature must be between 0 and 1",
-                code="invalid_temperature",
-                pointer="/data/attributes/temperature",
-            )
-
-        # Validate max_tokens
-        if not 500 <= self.max_tokens <= 5000:
-            raise ModelValidationError(
-                detail="Max tokens must be between 500 and 5000",
-                code="invalid_max_tokens",
-                pointer="/data/attributes/max_tokens",
-            )
-
     @property
     def api_key_decoded(self):
         """Return the decrypted API key, or None if unavailable or invalid."""
@@ -1833,15 +1973,6 @@ class LighthouseConfiguration(RowLevelSecurityProtectedModel):
                 code="invalid_api_key",
                 pointer="/data/attributes/api_key",
             )
-
-        # Validate OpenAI API key format
-        openai_key_pattern = r"^sk-[\w-]+T3BlbkFJ[\w-]+$"
-        if not re.match(openai_key_pattern, value):
-            raise ModelValidationError(
-                detail="Invalid OpenAI API key format.",
-                code="invalid_api_key",
-                pointer="/data/attributes/api_key",
-            )
         self.api_key = fernet.encrypt(value.encode())
 
     def save(self, *args, **kwargs):
@@ -1867,6 +1998,59 @@ class LighthouseConfiguration(RowLevelSecurityProtectedModel):
         resource_name = "lighthouse-configurations"
 
 
+class MuteRule(RowLevelSecurityProtectedModel):
+    id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
+    inserted_at = models.DateTimeField(auto_now_add=True, editable=False)
+    updated_at = models.DateTimeField(auto_now=True, editable=False)
+
+    # Rule metadata
+    name = models.CharField(
+        max_length=100,
+        validators=[MinLengthValidator(3)],
+        help_text="Human-readable name for this rule",
+    )
+    reason = models.TextField(
+        validators=[MinLengthValidator(3)],
+        max_length=500,
+        help_text="Reason for muting",
+    )
+    enabled = models.BooleanField(
+        default=True, help_text="Whether this rule is currently enabled"
+    )
+
+    # Audit fields
+    created_by = models.ForeignKey(
+        User,
+        on_delete=models.SET_NULL,
+        null=True,
+        related_name="created_mute_rules",
+        help_text="User who created this rule",
+    )
+
+    # Rule criteria - array of finding UIDs
+    finding_uids = ArrayField(
+        models.CharField(max_length=255), help_text="List of finding UIDs to mute"
+    )
+
+    class Meta(RowLevelSecurityProtectedModel.Meta):
+        db_table = "mute_rules"
+
+        constraints = [
+            RowLevelSecurityConstraint(
+                field="tenant_id",
+                name="rls_on_%(class)s",
+                statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
+            ),
+            models.UniqueConstraint(
+                fields=("tenant_id", "name"),
+                name="unique_mute_rule_name_per_tenant",
+            ),
+        ]
+
+    class JSONAPIMeta:
+        resource_name = "mute-rules"
+
+
 class Processor(RowLevelSecurityProtectedModel):
     class ProcessorChoices(models.TextChoices):
         MUTELIST = "mutelist", _("Mutelist")
@@ -1904,3 +2088,320 @@ class Processor(RowLevelSecurityProtectedModel):
 
     class JSONAPIMeta:
         resource_name = "processors"
+
+
+class LighthouseProviderConfiguration(RowLevelSecurityProtectedModel):
+    """
+    Per-tenant configuration for an LLM provider (credentials, base URL, activation).
+
+    One configuration per provider type per tenant.
+    """
+
+    class LLMProviderChoices(models.TextChoices):
+        OPENAI = "openai", _("OpenAI")
+        BEDROCK = "bedrock", _("AWS Bedrock")
+        OPENAI_COMPATIBLE = "openai_compatible", _("OpenAI Compatible")
+
+    id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
+    inserted_at = models.DateTimeField(auto_now_add=True, editable=False)
+    updated_at = models.DateTimeField(auto_now=True, editable=False)
+
+    provider_type = models.CharField(
+        max_length=50,
+        choices=LLMProviderChoices.choices,
+        help_text="LLM provider name",
+    )
+
+    # For OpenAI-compatible providers
+    base_url = models.URLField(blank=True, null=True)
+
+    # Encrypted JSON for provider-specific auth
+    credentials = models.BinaryField(
+        blank=False, null=False, help_text="Encrypted JSON credentials for the provider"
+    )
+
+    is_active = models.BooleanField(default=True)
+
+    def __str__(self):
+        return f"{self.get_provider_type_display()} ({self.tenant_id})"
+
+    def clean(self):
+        super().clean()
+
+    @property
+    def credentials_decoded(self):
+        if not self.credentials:
+            return None
+        try:
+            decrypted_data = fernet.decrypt(bytes(self.credentials))
+            return json.loads(decrypted_data.decode())
+        except (InvalidToken, json.JSONDecodeError) as e:
+            logger.warning("Failed to decrypt provider credentials: %s", e)
+            return None
+        except Exception as e:
+            logger.exception(
+                "Unexpected error while decrypting provider credentials: %s", e
+            )
+            return None
+
+    @credentials_decoded.setter
+    def credentials_decoded(self, value):
+        """
+        Set and encrypt credentials (assumes serializer performed validation).
+        """
+        if not value:
+            raise ModelValidationError(
+                detail="Credentials are required",
+                code="invalid_credentials",
+                pointer="/data/attributes/credentials",
+            )
+        self.credentials = fernet.encrypt(json.dumps(value).encode())
+
+    class Meta(RowLevelSecurityProtectedModel.Meta):
+        db_table = "lighthouse_provider_configurations"
+
+        constraints = [
+            RowLevelSecurityConstraint(
+                field="tenant_id",
+                name="rls_on_%(class)s",
+                statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
+            ),
+            models.UniqueConstraint(
+                fields=["tenant_id", "provider_type"],
+                name="unique_provider_config_per_tenant",
+            ),
+        ]
+
+        indexes = [
+            models.Index(
+                fields=["tenant_id", "provider_type"],
+                name="lh_pc_tenant_type_idx",
+            ),
+        ]
+
+    class JSONAPIMeta:
+        resource_name = "lighthouse-providers"
+
+
+class LighthouseTenantConfiguration(RowLevelSecurityProtectedModel):
+    """
+    Tenant-level Lighthouse settings (business context and defaults).
+    One record per tenant.
+    """
+
+    id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
+    inserted_at = models.DateTimeField(auto_now_add=True, editable=False)
+    updated_at = models.DateTimeField(auto_now=True, editable=False)
+
+    business_context = models.TextField(blank=True, default="")
+
+    # Preferred provider key (e.g., "openai", "bedrock", "openai_compatible")
+    default_provider = models.CharField(max_length=50, blank=True)
+
+    # Mapping of provider -> model id, e.g., {"openai": "gpt-4o", "bedrock": "anthropic.claude-v2"}
+    default_models = models.JSONField(default=dict, blank=True)
+
+    def __str__(self):
+        return f"Lighthouse Tenant Config for {self.tenant_id}"
+
+    def clean(self):
+        super().clean()
+
+    class Meta(RowLevelSecurityProtectedModel.Meta):
+        db_table = "lighthouse_tenant_config"
+
+        constraints = [
+            RowLevelSecurityConstraint(
+                field="tenant_id",
+                name="rls_on_%(class)s",
+                statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
+            ),
+            models.UniqueConstraint(
+                fields=["tenant_id"], name="unique_tenant_lighthouse_config"
+            ),
+        ]
+
+    class JSONAPIMeta:
+        resource_name = "lighthouse-configurations"
+
+
+class LighthouseProviderModels(RowLevelSecurityProtectedModel):
+    """
+    Per-tenant, per-provider configuration list of available LLM models.
+    RLS-protected; populated via provider API using tenant-scoped credentials.
+    """
+
+    id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
+    inserted_at = models.DateTimeField(auto_now_add=True, editable=False)
+    updated_at = models.DateTimeField(auto_now=True, editable=False)
+
+    # Scope to a specific provider configuration within a tenant
+    provider_configuration = models.ForeignKey(
+        LighthouseProviderConfiguration,
+        on_delete=models.CASCADE,
+        related_name="available_models",
+    )
+    model_id = models.CharField(max_length=100)
+
+    # Human-friendly model name
+    model_name = models.CharField(max_length=100)
+
+    # Model-specific default parameters (e.g., temperature, max_tokens)
+    default_parameters = models.JSONField(default=dict, blank=True)
+
+    def __str__(self):
+        return f"{self.provider_configuration.provider_type}:{self.model_id} ({self.tenant_id})"
+
+    class Meta(RowLevelSecurityProtectedModel.Meta):
+        db_table = "lighthouse_provider_models"
+        constraints = [
+            RowLevelSecurityConstraint(
+                field="tenant_id",
+                name="rls_on_%(class)s",
+                statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
+            ),
+            models.UniqueConstraint(
+                fields=["tenant_id", "provider_configuration", "model_id"],
+                name="unique_provider_model_per_configuration",
+            ),
+        ]
+        indexes = [
+            models.Index(
+                fields=["tenant_id", "provider_configuration"],
+                name="lh_prov_models_cfg_idx",
+            ),
+        ]
+
+    class JSONAPIMeta:
+        resource_name = "lighthouse-models"
+
+
+class ThreatScoreSnapshot(RowLevelSecurityProtectedModel):
+    """
+    Stores historical ThreatScore metrics for a given scan.
+    Snapshots are created automatically after each ThreatScore report generation.
+    """
+
+    id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
+    inserted_at = models.DateTimeField(auto_now_add=True, editable=False)
+
+    scan = models.ForeignKey(
+        Scan,
+        on_delete=models.CASCADE,
+        related_name="threatscore_snapshots",
+        related_query_name="threatscore_snapshot",
+    )
+
+    provider = models.ForeignKey(
+        Provider,
+        on_delete=models.CASCADE,
+        related_name="threatscore_snapshots",
+        related_query_name="threatscore_snapshot",
+    )
+
+    compliance_id = models.CharField(
+        max_length=100,
+        blank=False,
+        null=False,
+        help_text="Compliance framework ID (e.g., 'prowler_threatscore_aws')",
+    )
+
+    # Overall ThreatScore metrics
+    overall_score = models.DecimalField(
+        max_digits=5,
+        decimal_places=2,
+        help_text="Overall ThreatScore percentage (0-100)",
+    )
+
+    # Score improvement/degradation compared to previous snapshot
+    score_delta = models.DecimalField(
+        max_digits=5,
+        decimal_places=2,
+        null=True,
+        blank=True,
+        help_text="Score change compared to previous snapshot (positive = improvement)",
+    )
+
+    # Section breakdown stored as JSON
+    # Format: {"1. IAM": 85.5, "2. Attack Surface": 92.3, ...}
+    section_scores = models.JSONField(
+        default=dict,
+        blank=True,
+        help_text="ThreatScore breakdown by section",
+    )
+
+    # Critical requirements metadata stored as JSON
+    # Format: [{"requirement_id": "...", "risk_level": 5, "weight": 150, ...}, ...]
+    critical_requirements = models.JSONField(
+        default=list,
+        blank=True,
+        help_text="List of critical failed requirements (risk >= 4)",
+    )
+
+    # Summary statistics
+    total_requirements = models.IntegerField(
+        default=0,
+        help_text="Total number of requirements evaluated",
+    )
+
+    passed_requirements = models.IntegerField(
+        default=0,
+        help_text="Number of requirements with PASS status",
+    )
+
+    failed_requirements = models.IntegerField(
+        default=0,
+        help_text="Number of requirements with FAIL status",
+    )
+
+    manual_requirements = models.IntegerField(
+        default=0,
+        help_text="Number of requirements with MANUAL status",
+    )
+
+    total_findings = models.IntegerField(
+        default=0,
+        help_text="Total number of findings across all requirements",
+    )
+
+    passed_findings = models.IntegerField(
+        default=0,
+        help_text="Number of findings with PASS status",
+    )
+
+    failed_findings = models.IntegerField(
+        default=0,
+        help_text="Number of findings with FAIL status",
+    )
+
+    def __str__(self):
+        return f"ThreatScore {self.overall_score}% for scan {self.scan_id} ({self.inserted_at})"
+
+    class Meta(RowLevelSecurityProtectedModel.Meta):
+        db_table = "threatscore_snapshots"
+
+        constraints = [
+            RowLevelSecurityConstraint(
+                field="tenant_id",
+                name="rls_on_%(class)s",
+                statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
+            ),
+        ]
+
+        indexes = [
+            models.Index(
+                fields=["tenant_id", "scan_id"],
+                name="threatscore_snap_t_scan_idx",
+            ),
+            models.Index(
+                fields=["tenant_id", "provider_id"],
+                name="threatscore_snap_t_prov_idx",
+            ),
+            models.Index(
+                fields=["tenant_id", "inserted_at"],
+                name="threatscore_snap_t_time_idx",
+            ),
+        ]
+
+    class JSONAPIMeta:
+        resource_name = "threatscore-snapshots"
diff --git a/api/src/backend/api/renderers.py b/api/src/backend/api/renderers.py
index ee03f24758..44fd0edff1 100644
--- a/api/src/backend/api/renderers.py
+++ b/api/src/backend/api/renderers.py
@@ -11,11 +11,12 @@ class APIJSONRenderer(JSONRenderer):
     def render(self, data, accepted_media_type=None, renderer_context=None):
         request = renderer_context.get("request")
         tenant_id = getattr(request, "tenant_id", None) if request else None
+        db_alias = getattr(request, "db_alias", None) if request else None
         include_param_present = "include" in request.query_params if request else False
 
         # Use rls_transaction if needed for included resources, otherwise do nothing
         context_manager = (
-            rls_transaction(tenant_id)
+            rls_transaction(tenant_id, using=db_alias)
             if tenant_id and include_param_present
             else nullcontext()
         )
diff --git a/api/src/backend/api/schema_extensions.py b/api/src/backend/api/schema_extensions.py
new file mode 100644
index 0000000000..76346f6217
--- /dev/null
+++ b/api/src/backend/api/schema_extensions.py
@@ -0,0 +1,16 @@
+from drf_spectacular.extensions import OpenApiAuthenticationExtension
+from drf_spectacular.openapi import AutoSchema
+
+
+class CombinedJWTOrAPIKeyAuthenticationScheme(OpenApiAuthenticationExtension):
+    target_class = "api.authentication.CombinedJWTOrAPIKeyAuthentication"
+    name = "JWT or API Key"
+
+    def get_security_definition(self, auto_schema: AutoSchema):  # noqa: F841
+        return {
+            "type": "http",
+            "scheme": "bearer",
+            "bearerFormat": "JWT",
+            "description": "Supports both JWT Bearer tokens and API Key authentication. "
+            "Use `Bearer ` for JWT or `Api-Key ` for API keys.",
+        }
diff --git a/api/src/backend/api/schema_hooks.py b/api/src/backend/api/schema_hooks.py
new file mode 100644
index 0000000000..f94db59562
--- /dev/null
+++ b/api/src/backend/api/schema_hooks.py
@@ -0,0 +1,95 @@
+def _pick_task_response_component(components):
+    schemas = components.get("schemas", {}) or {}
+    for candidate in ("TaskResponse",):
+        if candidate in schemas:
+            return candidate
+    return None
+
+
+def _extract_task_example_from_components(components):
+    schemas = components.get("schemas", {}) or {}
+    candidate = "TaskResponse"
+    doc = schemas.get(candidate)
+    if isinstance(doc, dict) and "example" in doc:
+        return doc["example"]
+
+    res = schemas.get(candidate)
+    if isinstance(res, dict) and "example" in res:
+        example = res["example"]
+        return example if "data" in example else {"data": example}
+
+    # Fallback
+    return {
+        "data": {
+            "type": "tasks",
+            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
+            "attributes": {
+                "inserted_at": "2019-08-24T14:15:22Z",
+                "completed_at": "2019-08-24T14:15:22Z",
+                "name": "string",
+                "state": "available",
+                "result": None,
+                "task_args": None,
+                "metadata": None,
+            },
+        }
+    }
+
+
+def attach_task_202_examples(result, generator, request, public):  # noqa: F841
+    if not isinstance(result, dict):
+        return result
+
+    components = result.get("components", {}) or {}
+    task_resp_component = _pick_task_response_component(components)
+    task_example = _extract_task_example_from_components(components)
+
+    paths = result.get("paths", {}) or {}
+    for path_item in paths.values():
+        if not isinstance(path_item, dict):
+            continue
+
+        for method_obj in path_item.values():
+            if not isinstance(method_obj, dict):
+                continue
+
+            responses = method_obj.get("responses", {}) or {}
+            resp_202 = responses.get("202")
+            if not isinstance(resp_202, dict):
+                continue
+
+            content = resp_202.get("content", {}) or {}
+            jsonapi = content.get("application/vnd.api+json")
+            if not isinstance(jsonapi, dict):
+                continue
+
+            # Inject example if missing
+            if "examples" not in jsonapi and "example" not in jsonapi:
+                jsonapi["examples"] = {
+                    "Task queued": {
+                        "summary": "Task queued",
+                        "value": task_example,
+                    }
+                }
+
+            # Rewrite schema $ref if needed
+            if task_resp_component:
+                schema = jsonapi.get("schema")
+                must_replace = False
+                if not isinstance(schema, dict):
+                    must_replace = True
+                else:
+                    ref = schema.get("$ref")
+                    if not ref:
+                        must_replace = True
+                    else:
+                        current = ref.split("/")[-1]
+                        if current != task_resp_component:
+                            must_replace = True
+
+                if must_replace:
+                    jsonapi["schema"] = {
+                        "$ref": f"#/components/schemas/{task_resp_component}"
+                    }
+
+    return result
diff --git a/api/src/backend/api/signals.py b/api/src/backend/api/signals.py
index d9dc0a72d9..d449144bf4 100644
--- a/api/src/backend/api/signals.py
+++ b/api/src/backend/api/signals.py
@@ -1,12 +1,19 @@
 from celery import states
 from celery.signals import before_task_publish
 from config.celery import celery_app
-from django.db.models.signals import post_delete
+from django.db.models.signals import post_delete, pre_delete
 from django.dispatch import receiver
 from django_celery_results.backends.database import DatabaseBackend
 
 from api.db_utils import delete_related_daily_task
-from api.models import Provider
+from api.models import (
+    LighthouseProviderConfiguration,
+    LighthouseTenantConfiguration,
+    Membership,
+    Provider,
+    TenantAPIKey,
+    User,
+)
 
 
 def create_task_result_on_publish(sender=None, headers=None, **kwargs):  # noqa: F841
@@ -32,3 +39,57 @@ before_task_publish.connect(
 def delete_provider_scan_task(sender, instance, **kwargs):  # noqa: F841
     # Delete the associated periodic task when the provider is deleted
     delete_related_daily_task(instance.id)
+
+
+@receiver(pre_delete, sender=User)
+def revoke_user_api_keys(sender, instance, **kwargs):  # noqa: F841
+    """
+    Revoke all API keys associated with a user before deletion.
+
+    The entity field will be set to NULL by on_delete=SET_NULL,
+    but we explicitly revoke the keys to prevent further use.
+    """
+    TenantAPIKey.objects.filter(entity=instance).update(revoked=True)
+
+
+@receiver(post_delete, sender=Membership)
+def revoke_membership_api_keys(sender, instance, **kwargs):  # noqa: F841
+    """
+    Revoke all API keys when a user is removed from a tenant.
+
+    When a membership is deleted, all API keys created by that user
+    in that tenant should be revoked to prevent further access.
+    """
+    TenantAPIKey.objects.filter(
+        entity=instance.user, tenant_id=instance.tenant.id
+    ).update(revoked=True)
+
+
+@receiver(pre_delete, sender=LighthouseProviderConfiguration)
+def cleanup_lighthouse_defaults_before_delete(sender, instance, **kwargs):  # noqa: F841
+    """
+    Ensure tenant Lighthouse defaults do not reference a soon-to-be-deleted provider.
+
+    This runs for both per-instance deletes and queryset (bulk) deletes.
+    """
+    try:
+        tenant_cfg = LighthouseTenantConfiguration.objects.get(
+            tenant_id=instance.tenant_id
+        )
+    except LighthouseTenantConfiguration.DoesNotExist:
+        return
+
+    updated = False
+    defaults = tenant_cfg.default_models or {}
+
+    if instance.provider_type in defaults:
+        defaults.pop(instance.provider_type, None)
+        tenant_cfg.default_models = defaults
+        updated = True
+
+    if tenant_cfg.default_provider == instance.provider_type:
+        tenant_cfg.default_provider = ""
+        updated = True
+
+    if updated:
+        tenant_cfg.save()
diff --git a/api/src/backend/api/specs/v1.yaml b/api/src/backend/api/specs/v1.yaml
index cf64a00ffd..6227d2500e 100644
--- a/api/src/backend/api/specs/v1.yaml
+++ b/api/src/backend/api/specs/v1.yaml
@@ -1,17 +1,293 @@
 openapi: 3.0.3
 info:
   title: Prowler API
-  version: 1.12.0
+  version: 1.15.0
   description: |-
     Prowler API specification.
 
     This file is auto-generated.
 paths:
+  /api/v1/api-keys:
+    get:
+      operationId: api_keys_list
+      description: Retrieve a list of API keys for the tenant, with filtering support.
+      summary: List API keys
+      parameters:
+      - in: query
+        name: fields[api-keys]
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - name
+            - prefix
+            - expires_at
+            - revoked
+            - inserted_at
+            - last_used_at
+            - entity
+        description: endpoint return only specific fields in the response on a per-type
+          basis by including a fields[TYPE] query parameter.
+        explode: false
+      - in: query
+        name: filter[expires_at]
+        schema:
+          type: string
+          format: date
+      - in: query
+        name: filter[expires_at__gte]
+        schema:
+          type: string
+          format: date
+      - in: query
+        name: filter[expires_at__lte]
+        schema:
+          type: string
+          format: date
+      - in: query
+        name: filter[inserted_at]
+        schema:
+          type: string
+          format: date
+      - in: query
+        name: filter[inserted_at__gte]
+        schema:
+          type: string
+          format: date
+      - in: query
+        name: filter[inserted_at__lte]
+        schema:
+          type: string
+          format: date
+      - in: query
+        name: filter[name]
+        schema:
+          type: string
+      - in: query
+        name: filter[name__icontains]
+        schema:
+          type: string
+      - in: query
+        name: filter[prefix]
+        schema:
+          type: string
+      - in: query
+        name: filter[prefix__icontains]
+        schema:
+          type: string
+      - in: query
+        name: filter[revoked]
+        schema:
+          type: boolean
+      - name: filter[search]
+        required: false
+        in: query
+        description: A search term.
+        schema:
+          type: string
+      - in: query
+        name: include
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - entity
+        description: include query parameter to allow the client to customize which
+          related resources should be returned.
+        explode: false
+      - name: page[number]
+        required: false
+        in: query
+        description: A page number within the paginated result set.
+        schema:
+          type: integer
+      - name: page[size]
+        required: false
+        in: query
+        description: Number of results to return per page.
+        schema:
+          type: integer
+      - name: sort
+        required: false
+        in: query
+        description: '[list of fields to sort by](https://jsonapi.org/format/#fetching-sorting)'
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - name
+            - -name
+            - prefix
+            - -prefix
+            - revoked
+            - -revoked
+            - inserted_at
+            - -inserted_at
+            - expires_at
+            - -expires_at
+        explode: false
+      tags:
+      - API Keys
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/PaginatedTenantApiKeyList'
+          description: ''
+    post:
+      operationId: api_keys_create
+      description: Create a new API key for the tenant.
+      summary: Create a new API key
+      tags:
+      - API Keys
+      requestBody:
+        content:
+          application/vnd.api+json:
+            schema:
+              $ref: '#/components/schemas/TenantApiKeyCreateRequest'
+          application/x-www-form-urlencoded:
+            schema:
+              $ref: '#/components/schemas/TenantApiKeyCreateRequest'
+          multipart/form-data:
+            schema:
+              $ref: '#/components/schemas/TenantApiKeyCreateRequest'
+        required: true
+      security:
+      - JWT or API Key: []
+      responses:
+        '201':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/TenantApiKeyCreateResponse'
+          description: ''
+  /api/v1/api-keys/{id}:
+    get:
+      operationId: api_keys_retrieve
+      description: Fetch detailed information about a specific API key by its ID.
+      summary: Retrieve API key details
+      parameters:
+      - in: query
+        name: fields[api-keys]
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - name
+            - prefix
+            - expires_at
+            - revoked
+            - inserted_at
+            - last_used_at
+            - entity
+        description: endpoint return only specific fields in the response on a per-type
+          basis by including a fields[TYPE] query parameter.
+        explode: false
+      - in: path
+        name: id
+        schema:
+          type: string
+          format: uuid
+        description: A UUID string identifying this tenant api key.
+        required: true
+      - in: query
+        name: include
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - entity
+        description: include query parameter to allow the client to customize which
+          related resources should be returned.
+        explode: false
+      tags:
+      - API Keys
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/TenantApiKeyResponse'
+          description: ''
+    patch:
+      operationId: api_keys_partial_update
+      description: Modify certain fields of an existing API key without affecting
+        other settings.
+      summary: Partially update an API key
+      parameters:
+      - in: path
+        name: id
+        schema:
+          type: string
+          format: uuid
+        description: A UUID string identifying this tenant api key.
+        required: true
+      tags:
+      - API Keys
+      requestBody:
+        content:
+          application/vnd.api+json:
+            schema:
+              $ref: '#/components/schemas/PatchedTenantApiKeyUpdateRequest'
+          application/x-www-form-urlencoded:
+            schema:
+              $ref: '#/components/schemas/PatchedTenantApiKeyUpdateRequest'
+          multipart/form-data:
+            schema:
+              $ref: '#/components/schemas/PatchedTenantApiKeyUpdateRequest'
+        required: true
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/TenantApiKeyUpdateResponse'
+          description: ''
+  /api/v1/api-keys/{id}/revoke:
+    delete:
+      operationId: api_keys_revoke_destroy
+      description: Revoke an API key by its ID. This action is irreversible and will
+        prevent the key from being used.
+      summary: Revoke an API key
+      parameters:
+      - in: path
+        name: id
+        schema:
+          type: string
+          format: uuid
+        description: A UUID string identifying this tenant api key.
+        required: true
+      tags:
+      - API Keys
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/OpenApiResponseResponse'
+          description: API key was successfully revoked
   /api/v1/compliance-overviews:
     get:
       operationId: compliance_overviews_list
-      description: Retrieve an overview of all the compliance in a given scan.
-      summary: List compliance overviews for a scan
+      description: Retrieve an overview of all compliance frameworks. If scan_id is
+        provided, returns compliance data for that specific scan. If scan_id is omitted,
+        returns compliance data aggregated from the latest completed scan of each
+        provider.
+      summary: List compliance overviews
       parameters:
       - in: query
         name: fields[compliance-overviews]
@@ -70,6 +346,32 @@ paths:
         schema:
           type: string
           format: date-time
+      - in: query
+        name: filter[provider_id]
+        schema:
+          type: string
+          format: uuid
+        description: Filter by specific provider ID.
+      - in: query
+        name: filter[provider_id__in]
+        schema:
+          type: array
+          items:
+            type: string
+            format: uuid
+        description: Filter by multiple provider IDs (comma-separated).
+      - in: query
+        name: filter[provider_type]
+        schema:
+          type: string
+        description: Filter by provider type (e.g., aws, azure, gcp).
+      - in: query
+        name: filter[provider_type__in]
+        schema:
+          type: array
+          items:
+            type: string
+        description: Filter by multiple provider types (comma-separated).
       - in: query
         name: filter[region]
         schema:
@@ -92,8 +394,8 @@ paths:
         schema:
           type: string
           format: uuid
-        description: Related scan ID.
-        required: true
+        description: Optional scan ID. If provided, returns compliance for that scan.
+          If omitted, returns compliance for the latest completed scan per provider.
       - name: filter[search]
         required: false
         in: query
@@ -135,7 +437,7 @@ paths:
       tags:
       - Compliance Overview
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -147,7 +449,22 @@ paths:
           content:
             application/vnd.api+json:
               schema:
-                $ref: '#/components/schemas/PaginatedTaskList'
+                $ref: '#/components/schemas/TaskResponse'
+              examples:
+                Task queued:
+                  summary: Task queued
+                  value:
+                    data:
+                      type: tasks
+                      id: 497f6eca-6276-4993-bfeb-53cbbbba6f08
+                      attributes:
+                        inserted_at: '2019-08-24T14:15:22Z'
+                        completed_at: '2019-08-24T14:15:22Z'
+                        name: string
+                        state: available
+                        result: null
+                        task_args: null
+                        metadata: null
           description: The task is in progress
         '500':
           description: Compliance overviews generation task failed
@@ -167,6 +484,7 @@ paths:
             type: string
             enum:
             - id
+            - compliance_name
             - framework_description
             - name
             - framework
@@ -185,7 +503,7 @@ paths:
       tags:
       - Compliance Overview
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -221,7 +539,7 @@ paths:
       tags:
       - Compliance Overview
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -230,6 +548,25 @@ paths:
                 $ref: '#/components/schemas/OpenApiResponseResponse'
           description: Compliance overviews metadata obtained successfully
         '202':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/TaskResponse'
+              examples:
+                Task queued:
+                  summary: Task queued
+                  value:
+                    data:
+                      type: tasks
+                      id: 497f6eca-6276-4993-bfeb-53cbbbba6f08
+                      attributes:
+                        inserted_at: '2019-08-24T14:15:22Z'
+                        completed_at: '2019-08-24T14:15:22Z'
+                        name: string
+                        state: available
+                        result: null
+                        task_args: null
+                        metadata: null
           description: The task is in progress
         '500':
           description: Compliance overviews generation task failed
@@ -298,6 +635,77 @@ paths:
         schema:
           type: string
           format: date-time
+      - in: query
+        name: filter[provider_id]
+        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:
+          type: string
+          x-spec-enum-id: eca8c51e6bd28935
+          enum:
+          - aws
+          - azure
+          - gcp
+          - github
+          - iac
+          - kubernetes
+          - m365
+          - mongodbatlas
+          - oraclecloud
+        description: |-
+          * `aws` - AWS
+          * `azure` - Azure
+          * `gcp` - GCP
+          * `kubernetes` - Kubernetes
+          * `m365` - M365
+          * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
+      - in: query
+        name: filter[provider_type__in]
+        schema:
+          type: array
+          items:
+            type: string
+            x-spec-enum-id: eca8c51e6bd28935
+            enum:
+            - aws
+            - azure
+            - gcp
+            - github
+            - iac
+            - kubernetes
+            - m365
+            - mongodbatlas
+            - oraclecloud
+        description: |-
+          Multiple values may be separated by commas.
+
+          * `aws` - AWS
+          * `azure` - Azure
+          * `gcp` - GCP
+          * `kubernetes` - Kubernetes
+          * `m365` - M365
+          * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
+        explode: false
+        style: form
       - in: query
         name: filter[region]
         schema:
@@ -351,7 +759,7 @@ paths:
       tags:
       - Compliance Overview
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -360,6 +768,25 @@ paths:
                 $ref: '#/components/schemas/PaginatedComplianceOverviewDetailList'
           description: Compliance requirement details obtained successfully
         '202':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/TaskResponse'
+              examples:
+                Task queued:
+                  summary: Task queued
+                  value:
+                    data:
+                      type: tasks
+                      id: 497f6eca-6276-4993-bfeb-53cbbbba6f08
+                      attributes:
+                        inserted_at: '2019-08-24T14:15:22Z'
+                        completed_at: '2019-08-24T14:15:22Z'
+                        name: string
+                        state: available
+                        result: null
+                        task_args: null
+                        metadata: null
           description: The task is in progress
         '500':
           description: Compliance overviews generation task failed
@@ -417,6 +844,7 @@ paths:
         name: filter[delta]
         schema:
           type: string
+          x-spec-enum-id: fef6b0e2506af8bc
           nullable: true
           enum:
           - changed
@@ -452,6 +880,7 @@ paths:
         name: filter[impact]
         schema:
           type: string
+          x-spec-enum-id: c93e070ed135d9bf
           enum:
           - critical
           - high
@@ -540,13 +969,17 @@ paths:
         name: filter[provider_type]
         schema:
           type: string
+          x-spec-enum-id: eca8c51e6bd28935
           enum:
           - aws
           - azure
           - gcp
           - github
+          - iac
           - kubernetes
           - m365
+          - mongodbatlas
+          - oraclecloud
         description: |-
           * `aws` - AWS
           * `azure` - Azure
@@ -554,19 +987,26 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
       - in: query
         name: filter[provider_type__in]
         schema:
           type: array
           items:
             type: string
+            x-spec-enum-id: eca8c51e6bd28935
             enum:
             - aws
             - azure
             - gcp
             - github
+            - iac
             - kubernetes
             - m365
+            - mongodbatlas
+            - oraclecloud
         description: |-
           Multiple values may be separated by commas.
 
@@ -576,6 +1016,9 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
         explode: false
         style: form
       - in: query
@@ -715,6 +1158,7 @@ paths:
         name: filter[severity]
         schema:
           type: string
+          x-spec-enum-id: c93e070ed135d9bf
           enum:
           - critical
           - high
@@ -740,6 +1184,7 @@ paths:
         name: filter[status]
         schema:
           type: string
+          x-spec-enum-id: ce612ddbfa464789
           enum:
           - FAIL
           - MANUAL
@@ -832,7 +1277,7 @@ paths:
       tags:
       - Finding
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -894,7 +1339,7 @@ paths:
       tags:
       - Finding
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -941,6 +1386,7 @@ paths:
         name: filter[delta]
         schema:
           type: string
+          x-spec-enum-id: fef6b0e2506af8bc
           nullable: true
           enum:
           - changed
@@ -976,6 +1422,7 @@ paths:
         name: filter[impact]
         schema:
           type: string
+          x-spec-enum-id: c93e070ed135d9bf
           enum:
           - critical
           - high
@@ -1061,13 +1508,17 @@ paths:
         name: filter[provider_type]
         schema:
           type: string
+          x-spec-enum-id: eca8c51e6bd28935
           enum:
           - aws
           - azure
           - gcp
           - github
+          - iac
           - kubernetes
           - m365
+          - mongodbatlas
+          - oraclecloud
         description: |-
           * `aws` - AWS
           * `azure` - Azure
@@ -1075,19 +1526,26 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
       - in: query
         name: filter[provider_type__in]
         schema:
           type: array
           items:
             type: string
+            x-spec-enum-id: eca8c51e6bd28935
             enum:
             - aws
             - azure
             - gcp
             - github
+            - iac
             - kubernetes
             - m365
+            - mongodbatlas
+            - oraclecloud
         description: |-
           Multiple values may be separated by commas.
 
@@ -1097,6 +1555,9 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
         explode: false
         style: form
       - in: query
@@ -1236,6 +1697,7 @@ paths:
         name: filter[severity]
         schema:
           type: string
+          x-spec-enum-id: c93e070ed135d9bf
           enum:
           - critical
           - high
@@ -1261,6 +1723,7 @@ paths:
         name: filter[status]
         schema:
           type: string
+          x-spec-enum-id: ce612ddbfa464789
           enum:
           - FAIL
           - MANUAL
@@ -1329,7 +1792,7 @@ paths:
       tags:
       - Finding
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       deprecated: true
       responses:
         '200':
@@ -1392,6 +1855,7 @@ paths:
         name: filter[delta]
         schema:
           type: string
+          x-spec-enum-id: fef6b0e2506af8bc
           nullable: true
           enum:
           - changed
@@ -1427,6 +1891,7 @@ paths:
         name: filter[impact]
         schema:
           type: string
+          x-spec-enum-id: c93e070ed135d9bf
           enum:
           - critical
           - high
@@ -1490,13 +1955,17 @@ paths:
         name: filter[provider_type]
         schema:
           type: string
+          x-spec-enum-id: eca8c51e6bd28935
           enum:
           - aws
           - azure
           - gcp
           - github
+          - iac
           - kubernetes
           - m365
+          - mongodbatlas
+          - oraclecloud
         description: |-
           * `aws` - AWS
           * `azure` - Azure
@@ -1504,19 +1973,26 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
       - in: query
         name: filter[provider_type__in]
         schema:
           type: array
           items:
             type: string
+            x-spec-enum-id: eca8c51e6bd28935
             enum:
             - aws
             - azure
             - gcp
             - github
+            - iac
             - kubernetes
             - m365
+            - mongodbatlas
+            - oraclecloud
         description: |-
           Multiple values may be separated by commas.
 
@@ -1526,6 +2002,9 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
         explode: false
         style: form
       - in: query
@@ -1650,6 +2129,7 @@ paths:
         name: filter[severity]
         schema:
           type: string
+          x-spec-enum-id: c93e070ed135d9bf
           enum:
           - critical
           - high
@@ -1675,6 +2155,7 @@ paths:
         name: filter[status]
         schema:
           type: string
+          x-spec-enum-id: ce612ddbfa464789
           enum:
           - FAIL
           - MANUAL
@@ -1745,7 +2226,7 @@ paths:
       tags:
       - Finding
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -1794,6 +2275,7 @@ paths:
         name: filter[delta]
         schema:
           type: string
+          x-spec-enum-id: fef6b0e2506af8bc
           nullable: true
           enum:
           - changed
@@ -1829,6 +2311,7 @@ paths:
         name: filter[impact]
         schema:
           type: string
+          x-spec-enum-id: c93e070ed135d9bf
           enum:
           - critical
           - high
@@ -1917,13 +2400,17 @@ paths:
         name: filter[provider_type]
         schema:
           type: string
+          x-spec-enum-id: eca8c51e6bd28935
           enum:
           - aws
           - azure
           - gcp
           - github
+          - iac
           - kubernetes
           - m365
+          - mongodbatlas
+          - oraclecloud
         description: |-
           * `aws` - AWS
           * `azure` - Azure
@@ -1931,19 +2418,26 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
       - in: query
         name: filter[provider_type__in]
         schema:
           type: array
           items:
             type: string
+            x-spec-enum-id: eca8c51e6bd28935
             enum:
             - aws
             - azure
             - gcp
             - github
+            - iac
             - kubernetes
             - m365
+            - mongodbatlas
+            - oraclecloud
         description: |-
           Multiple values may be separated by commas.
 
@@ -1953,6 +2447,9 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
         explode: false
         style: form
       - in: query
@@ -2092,6 +2589,7 @@ paths:
         name: filter[severity]
         schema:
           type: string
+          x-spec-enum-id: c93e070ed135d9bf
           enum:
           - critical
           - high
@@ -2117,6 +2615,7 @@ paths:
         name: filter[status]
         schema:
           type: string
+          x-spec-enum-id: ce612ddbfa464789
           enum:
           - FAIL
           - MANUAL
@@ -2185,7 +2684,7 @@ paths:
       tags:
       - Finding
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -2234,6 +2733,7 @@ paths:
         name: filter[delta]
         schema:
           type: string
+          x-spec-enum-id: fef6b0e2506af8bc
           nullable: true
           enum:
           - changed
@@ -2269,6 +2769,7 @@ paths:
         name: filter[impact]
         schema:
           type: string
+          x-spec-enum-id: c93e070ed135d9bf
           enum:
           - critical
           - high
@@ -2332,13 +2833,17 @@ paths:
         name: filter[provider_type]
         schema:
           type: string
+          x-spec-enum-id: eca8c51e6bd28935
           enum:
           - aws
           - azure
           - gcp
           - github
+          - iac
           - kubernetes
           - m365
+          - mongodbatlas
+          - oraclecloud
         description: |-
           * `aws` - AWS
           * `azure` - Azure
@@ -2346,19 +2851,26 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
       - in: query
         name: filter[provider_type__in]
         schema:
           type: array
           items:
             type: string
+            x-spec-enum-id: eca8c51e6bd28935
             enum:
             - aws
             - azure
             - gcp
             - github
+            - iac
             - kubernetes
             - m365
+            - mongodbatlas
+            - oraclecloud
         description: |-
           Multiple values may be separated by commas.
 
@@ -2368,6 +2880,9 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
         explode: false
         style: form
       - in: query
@@ -2492,6 +3007,7 @@ paths:
         name: filter[severity]
         schema:
           type: string
+          x-spec-enum-id: c93e070ed135d9bf
           enum:
           - critical
           - high
@@ -2517,6 +3033,7 @@ paths:
         name: filter[status]
         schema:
           type: string
+          x-spec-enum-id: ce612ddbfa464789
           enum:
           - FAIL
           - MANUAL
@@ -2575,7 +3092,7 @@ paths:
       tags:
       - Finding
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -2633,6 +3150,7 @@ paths:
         name: filter[integration_type]
         schema:
           type: string
+          x-spec-enum-id: 6cfd0ff9cf4d6dcc
           enum:
           - amazon_s3
           - aws_security_hub
@@ -2649,6 +3167,7 @@ paths:
           type: array
           items:
             type: string
+            x-spec-enum-id: 6cfd0ff9cf4d6dcc
             enum:
             - amazon_s3
             - aws_security_hub
@@ -2725,7 +3244,7 @@ paths:
       tags:
       - Integration
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -2753,7 +3272,7 @@ paths:
               $ref: '#/components/schemas/IntegrationCreateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '201':
           content:
@@ -2761,6 +3280,71 @@ paths:
               schema:
                 $ref: '#/components/schemas/IntegrationCreateResponse'
           description: ''
+  /api/v1/integrations/{integration_pk}/jira/dispatches:
+    post:
+      operationId: integrations_jira_dispatches_create
+      description: Send a set of filtered findings to the given integration. At least
+        one finding filter must be provided.
+      summary: Send findings to a Jira integration
+      parameters:
+      - in: query
+        name: filter[finding_id]
+        schema:
+          type: string
+          format: uuid
+      - in: query
+        name: filter[finding_id__in]
+        schema:
+          type: array
+          items:
+            type: string
+            format: uuid
+        description: Multiple values may be separated by commas.
+        explode: false
+        style: form
+      - in: path
+        name: integration_pk
+        schema:
+          type: string
+        required: true
+      tags:
+      - Integration
+      requestBody:
+        content:
+          application/vnd.api+json:
+            schema:
+              $ref: '#/components/schemas/IntegrationJiraDispatchRequest'
+          application/x-www-form-urlencoded:
+            schema:
+              $ref: '#/components/schemas/IntegrationJiraDispatchRequest'
+          multipart/form-data:
+            schema:
+              $ref: '#/components/schemas/IntegrationJiraDispatchRequest'
+        required: true
+      security:
+      - JWT or API Key: []
+      responses:
+        '202':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/TaskResponse'
+              examples:
+                Task queued:
+                  summary: Task queued
+                  value:
+                    data:
+                      type: tasks
+                      id: 497f6eca-6276-4993-bfeb-53cbbbba6f08
+                      attributes:
+                        inserted_at: '2019-08-24T14:15:22Z'
+                        completed_at: '2019-08-24T14:15:22Z'
+                        name: string
+                        state: available
+                        result: null
+                        task_args: null
+                        metadata: null
+          description: ''
   /api/v1/integrations/{id}:
     get:
       operationId: integrations_retrieve
@@ -2808,7 +3392,7 @@ paths:
       tags:
       - Integration
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -2844,7 +3428,7 @@ paths:
               $ref: '#/components/schemas/PatchedIntegrationUpdateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -2867,7 +3451,7 @@ paths:
       tags:
       - Integration
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: No response body
@@ -2887,13 +3471,28 @@ paths:
       tags:
       - Integration
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '202':
           content:
             application/vnd.api+json:
               schema:
-                $ref: '#/components/schemas/OpenApiResponseResponse'
+                $ref: '#/components/schemas/TaskResponse'
+              examples:
+                Task queued:
+                  summary: Task queued
+                  value:
+                    data:
+                      type: tasks
+                      id: 497f6eca-6276-4993-bfeb-53cbbbba6f08
+                      attributes:
+                        inserted_at: '2019-08-24T14:15:22Z'
+                        completed_at: '2019-08-24T14:15:22Z'
+                        name: string
+                        state: available
+                        result: null
+                        task_args: null
+                        metadata: null
           description: ''
   /api/v1/invitations/accept:
     post:
@@ -2916,7 +3515,7 @@ paths:
               $ref: '#/components/schemas/InvitationAcceptRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '201':
           content:
@@ -2927,8 +3526,8 @@ paths:
   /api/v1/lighthouse-configurations:
     get:
       operationId: lighthouse_configurations_list
-      description: Retrieve a list of all Lighthouse configurations.
-      summary: List all Lighthouse configurations
+      description: Retrieve a list of all Lighthouse AI configurations.
+      summary: List all Lighthouse AI configurations
       parameters:
       - in: query
         name: fields[lighthouse-configurations]
@@ -2987,9 +3586,10 @@ paths:
             - -is_active
         explode: false
       tags:
-      - Lighthouse
+      - Lighthouse AI
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
+      deprecated: true
       responses:
         '200':
           content:
@@ -2999,10 +3599,10 @@ paths:
           description: ''
     post:
       operationId: lighthouse_configurations_create
-      description: Create a new Lighthouse configuration with the specified details.
-      summary: Create a new Lighthouse configuration
+      description: Create a new Lighthouse AI configuration with the specified details.
+      summary: Create a new Lighthouse AI configuration
       tags:
-      - Lighthouse
+      - Lighthouse AI
       requestBody:
         content:
           application/vnd.api+json:
@@ -3016,7 +3616,8 @@ paths:
               $ref: '#/components/schemas/LighthouseConfigCreateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
+      deprecated: true
       responses:
         '201':
           content:
@@ -3027,8 +3628,8 @@ paths:
   /api/v1/lighthouse-configurations/{id}:
     patch:
       operationId: lighthouse_configurations_partial_update
-      description: Update certain fields of an existing Lighthouse configuration.
-      summary: Partially update a Lighthouse configuration
+      description: Update certain fields of an existing Lighthouse AI configuration.
+      summary: Partially update a Lighthouse AI configuration
       parameters:
       - in: path
         name: id
@@ -3036,7 +3637,7 @@ paths:
           type: string
         required: true
       tags:
-      - Lighthouse
+      - Lighthouse AI
       requestBody:
         content:
           application/vnd.api+json:
@@ -3050,7 +3651,8 @@ paths:
               $ref: '#/components/schemas/PatchedLighthouseConfigUpdateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
+      deprecated: true
       responses:
         '200':
           content:
@@ -3060,8 +3662,8 @@ paths:
           description: ''
     delete:
       operationId: lighthouse_configurations_destroy
-      description: Remove a Lighthouse configuration by its ID.
-      summary: Delete a Lighthouse configuration
+      description: Remove a Lighthouse AI configuration by its ID.
+      summary: Delete a Lighthouse AI configuration
       parameters:
       - in: path
         name: id
@@ -3069,9 +3671,10 @@ paths:
           type: string
         required: true
       tags:
-      - Lighthouse
+      - Lighthouse AI
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
+      deprecated: true
       responses:
         '204':
           description: No response body
@@ -3079,7 +3682,7 @@ paths:
     post:
       operationId: lighthouse_configurations_connection_create
       description: Verify the connection to the OpenAI API for a specific Lighthouse
-        configuration.
+        AI configuration.
       summary: Check the connection to the OpenAI API
       parameters:
       - in: path
@@ -3088,16 +3691,912 @@ paths:
           type: string
         required: true
       tags:
-      - Lighthouse
+      - Lighthouse AI
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
+      deprecated: true
       responses:
         '202':
           content:
             application/vnd.api+json:
               schema:
-                $ref: '#/components/schemas/OpenApiResponseResponse'
+                $ref: '#/components/schemas/TaskResponse'
+              examples:
+                Task queued:
+                  summary: Task queued
+                  value:
+                    data:
+                      type: tasks
+                      id: 497f6eca-6276-4993-bfeb-53cbbbba6f08
+                      attributes:
+                        inserted_at: '2019-08-24T14:15:22Z'
+                        completed_at: '2019-08-24T14:15:22Z'
+                        name: string
+                        state: available
+                        result: null
+                        task_args: null
+                        metadata: null
           description: ''
+  /api/v1/lighthouse/configuration:
+    get:
+      operationId: lighthouse_configuration_list
+      description: Retrieve current tenant-level Lighthouse AI settings. Returns a
+        single configuration object.
+      summary: Get Lighthouse AI Tenant config
+      parameters:
+      - in: query
+        name: fields[lighthouse-configurations]
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - inserted_at
+            - updated_at
+            - business_context
+            - default_provider
+            - default_models
+            - url
+        description: endpoint return only specific fields in the response on a per-type
+          basis by including a fields[TYPE] query parameter.
+        explode: false
+      - name: filter[search]
+        required: false
+        in: query
+        description: A search term.
+        schema:
+          type: string
+      - name: page[number]
+        required: false
+        in: query
+        description: A page number within the paginated result set.
+        schema:
+          type: integer
+      - name: page[size]
+        required: false
+        in: query
+        description: Number of results to return per page.
+        schema:
+          type: integer
+      - name: sort
+        required: false
+        in: query
+        description: '[list of fields to sort by](https://jsonapi.org/format/#fetching-sorting)'
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - id
+            - -id
+            - inserted_at
+            - -inserted_at
+            - updated_at
+            - -updated_at
+            - business_context
+            - -business_context
+            - default_provider
+            - -default_provider
+            - default_models
+            - -default_models
+            - url
+            - -url
+        explode: false
+      tags:
+      - Lighthouse AI
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/PaginatedLighthouseTenantConfigList'
+          description: ''
+    patch:
+      operationId: lighthouse_configuration_partial_update
+      description: Update tenant-level settings. Validates that the default provider
+        is configured and active and that default model IDs exist for the chosen providers.
+        Auto-creates configuration if it doesn't exist.
+      summary: Update Lighthouse AI Tenant config
+      tags:
+      - Lighthouse AI
+      requestBody:
+        content:
+          application/vnd.api+json:
+            schema:
+              $ref: '#/components/schemas/PatchedLighthouseTenantConfigUpdateRequest'
+          application/x-www-form-urlencoded:
+            schema:
+              $ref: '#/components/schemas/PatchedLighthouseTenantConfigUpdateRequest'
+          multipart/form-data:
+            schema:
+              $ref: '#/components/schemas/PatchedLighthouseTenantConfigUpdateRequest'
+        required: true
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/LighthouseTenantConfigUpdateResponse'
+          description: ''
+  /api/v1/lighthouse/models:
+    get:
+      operationId: lighthouse_models_list
+      description: List available LLM models per configured provider for the current
+        tenant.
+      summary: List all LLM models
+      parameters:
+      - in: query
+        name: fields[lighthouse-models]
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - inserted_at
+            - updated_at
+            - provider_configuration
+            - model_id
+            - model_name
+            - default_parameters
+            - url
+        description: endpoint return only specific fields in the response on a per-type
+          basis by including a fields[TYPE] query parameter.
+        explode: false
+      - in: query
+        name: filter[model_id]
+        schema:
+          type: string
+      - in: query
+        name: filter[model_id__icontains]
+        schema:
+          type: string
+      - in: query
+        name: filter[model_id__in]
+        schema:
+          type: array
+          items:
+            type: string
+        description: Multiple values may be separated by commas.
+        explode: false
+        style: form
+      - in: query
+        name: filter[provider_type]
+        schema:
+          type: string
+          x-spec-enum-id: 30bc523cb9ec0e8b
+          enum:
+          - bedrock
+          - openai
+          - openai_compatible
+        description: |-
+          LLM provider name
+
+          * `openai` - OpenAI
+          * `bedrock` - AWS Bedrock
+          * `openai_compatible` - OpenAI Compatible
+      - in: query
+        name: filter[provider_type__in]
+        schema:
+          type: array
+          items:
+            type: string
+            x-spec-enum-id: 30bc523cb9ec0e8b
+            enum:
+            - bedrock
+            - openai
+            - openai_compatible
+        description: |-
+          Multiple values may be separated by commas.
+
+          * `openai` - OpenAI
+          * `bedrock` - AWS Bedrock
+          * `openai_compatible` - OpenAI Compatible
+        explode: false
+        style: form
+      - name: filter[search]
+        required: false
+        in: query
+        description: A search term.
+        schema:
+          type: string
+      - name: page[number]
+        required: false
+        in: query
+        description: A page number within the paginated result set.
+        schema:
+          type: integer
+      - name: page[size]
+        required: false
+        in: query
+        description: Number of results to return per page.
+        schema:
+          type: integer
+      - name: sort
+        required: false
+        in: query
+        description: '[list of fields to sort by](https://jsonapi.org/format/#fetching-sorting)'
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - id
+            - -id
+            - inserted_at
+            - -inserted_at
+            - updated_at
+            - -updated_at
+            - provider_configuration
+            - -provider_configuration
+            - model_id
+            - -model_id
+            - model_name
+            - -model_name
+            - default_parameters
+            - -default_parameters
+            - url
+            - -url
+        explode: false
+      tags:
+      - Lighthouse AI
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/PaginatedLighthouseProviderModelsList'
+          description: ''
+  /api/v1/lighthouse/models/{id}:
+    get:
+      operationId: lighthouse_models_retrieve
+      description: Get details for a specific LLM model.
+      summary: Retrieve LLM model details
+      parameters:
+      - in: query
+        name: fields[lighthouse-models]
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - inserted_at
+            - updated_at
+            - provider_configuration
+            - model_id
+            - model_name
+            - default_parameters
+            - url
+        description: endpoint return only specific fields in the response on a per-type
+          basis by including a fields[TYPE] query parameter.
+        explode: false
+      - in: path
+        name: id
+        schema:
+          type: string
+          format: uuid
+        description: A UUID string identifying this lighthouse provider models.
+        required: true
+      tags:
+      - Lighthouse AI
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/LighthouseProviderModelsResponse'
+          description: ''
+  /api/v1/lighthouse/providers:
+    get:
+      operationId: lighthouse_providers_list
+      description: Retrieve all LLM provider configurations for the current tenant
+      summary: List all LLM provider configurations
+      parameters:
+      - in: query
+        name: fields[lighthouse-providers]
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - inserted_at
+            - updated_at
+            - provider_type
+            - base_url
+            - is_active
+            - credentials
+            - url
+        description: endpoint return only specific fields in the response on a per-type
+          basis by including a fields[TYPE] query parameter.
+        explode: false
+      - in: query
+        name: filter[is_active]
+        schema:
+          type: boolean
+      - in: query
+        name: filter[provider_type]
+        schema:
+          type: string
+          x-spec-enum-id: 30bc523cb9ec0e8b
+          enum:
+          - bedrock
+          - openai
+          - openai_compatible
+        description: |-
+          LLM provider name
+
+          * `openai` - OpenAI
+          * `bedrock` - AWS Bedrock
+          * `openai_compatible` - OpenAI Compatible
+      - in: query
+        name: filter[provider_type__in]
+        schema:
+          type: array
+          items:
+            type: string
+            x-spec-enum-id: 30bc523cb9ec0e8b
+            enum:
+            - bedrock
+            - openai
+            - openai_compatible
+        description: |-
+          Multiple values may be separated by commas.
+
+          * `openai` - OpenAI
+          * `bedrock` - AWS Bedrock
+          * `openai_compatible` - OpenAI Compatible
+        explode: false
+        style: form
+      - name: filter[search]
+        required: false
+        in: query
+        description: A search term.
+        schema:
+          type: string
+      - name: page[number]
+        required: false
+        in: query
+        description: A page number within the paginated result set.
+        schema:
+          type: integer
+      - name: page[size]
+        required: false
+        in: query
+        description: Number of results to return per page.
+        schema:
+          type: integer
+      - name: sort
+        required: false
+        in: query
+        description: '[list of fields to sort by](https://jsonapi.org/format/#fetching-sorting)'
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - id
+            - -id
+            - inserted_at
+            - -inserted_at
+            - updated_at
+            - -updated_at
+            - provider_type
+            - -provider_type
+            - base_url
+            - -base_url
+            - is_active
+            - -is_active
+            - credentials
+            - -credentials
+            - url
+            - -url
+        explode: false
+      tags:
+      - Lighthouse AI
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/PaginatedLighthouseProviderConfigList'
+          description: ''
+    post:
+      operationId: lighthouse_providers_create
+      description: Create a per-tenant configuration for an LLM provider. Only one
+        configuration per provider type is allowed per tenant.
+      summary: Create LLM provider configuration
+      tags:
+      - Lighthouse AI
+      requestBody:
+        content:
+          application/vnd.api+json:
+            schema:
+              $ref: '#/components/schemas/LighthouseProviderConfigCreateRequest'
+          application/x-www-form-urlencoded:
+            schema:
+              $ref: '#/components/schemas/LighthouseProviderConfigCreateRequest'
+          multipart/form-data:
+            schema:
+              $ref: '#/components/schemas/LighthouseProviderConfigCreateRequest'
+        required: true
+      security:
+      - JWT or API Key: []
+      responses:
+        '201':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/LighthouseProviderConfigCreateResponse'
+          description: ''
+  /api/v1/lighthouse/providers/{id}:
+    get:
+      operationId: lighthouse_providers_retrieve
+      description: Get details for a specific provider configuration in the current
+        tenant.
+      summary: Retrieve LLM provider configuration
+      parameters:
+      - in: query
+        name: fields[lighthouse-providers]
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - inserted_at
+            - updated_at
+            - provider_type
+            - base_url
+            - is_active
+            - credentials
+            - url
+        description: endpoint return only specific fields in the response on a per-type
+          basis by including a fields[TYPE] query parameter.
+        explode: false
+      - in: path
+        name: id
+        schema:
+          type: string
+          format: uuid
+        description: A UUID string identifying this lighthouse provider configuration.
+        required: true
+      tags:
+      - Lighthouse AI
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/LighthouseProviderConfigResponse'
+          description: ''
+    patch:
+      operationId: lighthouse_providers_partial_update
+      description: Partially update a provider configuration (e.g., base_url, is_active).
+      summary: Update LLM provider configuration
+      parameters:
+      - in: path
+        name: id
+        schema:
+          type: string
+          format: uuid
+        description: A UUID string identifying this lighthouse provider configuration.
+        required: true
+      tags:
+      - Lighthouse AI
+      requestBody:
+        content:
+          application/vnd.api+json:
+            schema:
+              $ref: '#/components/schemas/PatchedLighthouseProviderConfigUpdateRequest'
+          application/x-www-form-urlencoded:
+            schema:
+              $ref: '#/components/schemas/PatchedLighthouseProviderConfigUpdateRequest'
+          multipart/form-data:
+            schema:
+              $ref: '#/components/schemas/PatchedLighthouseProviderConfigUpdateRequest'
+        required: true
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/LighthouseProviderConfigUpdateResponse'
+          description: ''
+    delete:
+      operationId: lighthouse_providers_destroy
+      description: Delete a provider configuration. Any tenant defaults that reference
+        this provider are cleared during deletion.
+      summary: Delete LLM provider configuration
+      parameters:
+      - in: path
+        name: id
+        schema:
+          type: string
+          format: uuid
+        description: A UUID string identifying this lighthouse provider configuration.
+        required: true
+      tags:
+      - Lighthouse AI
+      security:
+      - JWT or API Key: []
+      responses:
+        '204':
+          description: No response body
+  /api/v1/lighthouse/providers/{id}/connection:
+    post:
+      operationId: lighthouse_providers_connection_create
+      description: Validate provider credentials asynchronously and toggle is_active.
+      summary: Check LLM provider connection
+      parameters:
+      - in: path
+        name: id
+        schema:
+          type: string
+          format: uuid
+        description: A UUID string identifying this lighthouse provider configuration.
+        required: true
+      tags:
+      - Lighthouse AI
+      security:
+      - JWT or API Key: []
+      responses:
+        '202':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/TaskResponse'
+              examples:
+                Task queued:
+                  summary: Task queued
+                  value:
+                    data:
+                      type: tasks
+                      id: 497f6eca-6276-4993-bfeb-53cbbbba6f08
+                      attributes:
+                        inserted_at: '2019-08-24T14:15:22Z'
+                        completed_at: '2019-08-24T14:15:22Z'
+                        name: string
+                        state: available
+                        result: null
+                        task_args: null
+                        metadata: null
+          description: ''
+  /api/v1/lighthouse/providers/{id}/refresh-models:
+    post:
+      operationId: lighthouse_providers_refresh_models_create
+      description: Fetch available models for this provider configuration and upsert
+        into catalog. Supports OpenAI, OpenAI-compatible, and AWS Bedrock providers.
+      summary: Refresh LLM models catalog
+      parameters:
+      - in: path
+        name: id
+        schema:
+          type: string
+          format: uuid
+        description: A UUID string identifying this lighthouse provider configuration.
+        required: true
+      tags:
+      - Lighthouse AI
+      security:
+      - JWT or API Key: []
+      responses:
+        '202':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/TaskResponse'
+              examples:
+                Task queued:
+                  summary: Task queued
+                  value:
+                    data:
+                      type: tasks
+                      id: 497f6eca-6276-4993-bfeb-53cbbbba6f08
+                      attributes:
+                        inserted_at: '2019-08-24T14:15:22Z'
+                        completed_at: '2019-08-24T14:15:22Z'
+                        name: string
+                        state: available
+                        result: null
+                        task_args: null
+                        metadata: null
+          description: ''
+  /api/v1/mute-rules:
+    get:
+      operationId: mute_rules_list
+      description: Retrieve a list of all mute rules with filtering options.
+      summary: List all mute rules
+      parameters:
+      - in: query
+        name: fields[mute-rules]
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - inserted_at
+            - updated_at
+            - name
+            - reason
+            - enabled
+            - created_by
+            - finding_uids
+        description: endpoint return only specific fields in the response on a per-type
+          basis by including a fields[TYPE] query parameter.
+        explode: false
+      - in: query
+        name: filter[created_by]
+        schema:
+          type: string
+          format: uuid
+      - in: query
+        name: filter[enabled]
+        schema:
+          type: boolean
+      - in: query
+        name: filter[id]
+        schema:
+          type: string
+          format: uuid
+      - in: query
+        name: filter[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[inserted_at]
+        schema:
+          type: string
+          format: date
+      - in: query
+        name: filter[inserted_at__gte]
+        schema:
+          type: string
+          format: date-time
+      - in: query
+        name: filter[inserted_at__lte]
+        schema:
+          type: string
+          format: date-time
+      - in: query
+        name: filter[name]
+        schema:
+          type: string
+      - in: query
+        name: filter[name__icontains]
+        schema:
+          type: string
+      - in: query
+        name: filter[reason__icontains]
+        schema:
+          type: string
+      - name: filter[search]
+        required: false
+        in: query
+        description: A search term.
+        schema:
+          type: string
+      - in: query
+        name: filter[updated_at]
+        schema:
+          type: string
+          format: date
+      - in: query
+        name: filter[updated_at__gte]
+        schema:
+          type: string
+          format: date-time
+      - in: query
+        name: filter[updated_at__lte]
+        schema:
+          type: string
+          format: date-time
+      - in: query
+        name: include
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - created_by
+        description: include query parameter to allow the client to customize which
+          related resources should be returned.
+        explode: false
+      - name: page[number]
+        required: false
+        in: query
+        description: A page number within the paginated result set.
+        schema:
+          type: integer
+      - name: page[size]
+        required: false
+        in: query
+        description: Number of results to return per page.
+        schema:
+          type: integer
+      - name: sort
+        required: false
+        in: query
+        description: '[list of fields to sort by](https://jsonapi.org/format/#fetching-sorting)'
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - name
+            - -name
+            - enabled
+            - -enabled
+            - inserted_at
+            - -inserted_at
+            - updated_at
+            - -updated_at
+        explode: false
+      tags:
+      - Mute Rules
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/PaginatedMuteRuleList'
+          description: ''
+    post:
+      operationId: mute_rules_create
+      description: Create a new mute rule by providing finding IDs, name, and reason.
+        The rule will immediately mute the selected findings and launch a background
+        task to mute all historical findings with matching UIDs.
+      summary: Create a new mute rule
+      tags:
+      - Mute Rules
+      requestBody:
+        content:
+          application/vnd.api+json:
+            schema:
+              $ref: '#/components/schemas/MuteRuleCreateRequest'
+          application/x-www-form-urlencoded:
+            schema:
+              $ref: '#/components/schemas/MuteRuleCreateRequest'
+          multipart/form-data:
+            schema:
+              $ref: '#/components/schemas/MuteRuleCreateRequest'
+        required: true
+      security:
+      - JWT or API Key: []
+      responses:
+        '201':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/MuteRuleCreateResponse'
+          description: ''
+  /api/v1/mute-rules/{id}:
+    get:
+      operationId: mute_rules_retrieve
+      description: Fetch detailed information about a specific mute rule by ID.
+      summary: Retrieve a mute rule
+      parameters:
+      - in: query
+        name: fields[mute-rules]
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - inserted_at
+            - updated_at
+            - name
+            - reason
+            - enabled
+            - created_by
+            - finding_uids
+        description: endpoint return only specific fields in the response on a per-type
+          basis by including a fields[TYPE] query parameter.
+        explode: false
+      - in: path
+        name: id
+        schema:
+          type: string
+          format: uuid
+        description: A UUID string identifying this mute rule.
+        required: true
+      - in: query
+        name: include
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - created_by
+        description: include query parameter to allow the client to customize which
+          related resources should be returned.
+        explode: false
+      tags:
+      - Mute Rules
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/MuteRuleResponse'
+          description: ''
+    patch:
+      operationId: mute_rules_partial_update
+      description: Update certain fields of an existing mute rule (e.g., name, reason,
+        enabled).
+      summary: Partially update a mute rule
+      parameters:
+      - in: path
+        name: id
+        schema:
+          type: string
+          format: uuid
+        description: A UUID string identifying this mute rule.
+        required: true
+      tags:
+      - Mute Rules
+      requestBody:
+        content:
+          application/vnd.api+json:
+            schema:
+              $ref: '#/components/schemas/PatchedMuteRuleUpdateRequest'
+          application/x-www-form-urlencoded:
+            schema:
+              $ref: '#/components/schemas/PatchedMuteRuleUpdateRequest'
+          multipart/form-data:
+            schema:
+              $ref: '#/components/schemas/PatchedMuteRuleUpdateRequest'
+        required: true
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/SerializerMetaclassResponse'
+          description: ''
+    delete:
+      operationId: mute_rules_destroy
+      description: 'Remove a mute rule from the system. Note: Previously muted findings
+        remain muted.'
+      summary: Delete a mute rule
+      parameters:
+      - in: path
+        name: id
+        schema:
+          type: string
+          format: uuid
+        description: A UUID string identifying this mute rule.
+        required: true
+      tags:
+      - Mute Rules
+      security:
+      - JWT or API Key: []
+      responses:
+        '204':
+          description: No response body
   /api/v1/overviews/findings:
     get:
       operationId: overviews_findings_retrieve
@@ -3157,17 +4656,31 @@ 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:
           type: string
+          x-spec-enum-id: eca8c51e6bd28935
           enum:
           - aws
           - azure
           - gcp
           - github
+          - iac
           - kubernetes
           - m365
+          - mongodbatlas
+          - oraclecloud
         description: |-
           * `aws` - AWS
           * `azure` - Azure
@@ -3175,19 +4688,26 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
       - in: query
         name: filter[provider_type__in]
         schema:
           type: array
           items:
             type: string
+            x-spec-enum-id: eca8c51e6bd28935
             enum:
             - aws
             - azure
             - gcp
             - github
+            - iac
             - kubernetes
             - m365
+            - mongodbatlas
+            - oraclecloud
         description: |-
           Multiple values may be separated by commas.
 
@@ -3197,6 +4717,9 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
         explode: false
         style: form
       - in: query
@@ -3263,7 +4786,7 @@ paths:
       tags:
       - Overview
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -3322,17 +4845,31 @@ 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:
           type: string
+          x-spec-enum-id: eca8c51e6bd28935
           enum:
           - aws
           - azure
           - gcp
           - github
+          - iac
           - kubernetes
           - m365
+          - mongodbatlas
+          - oraclecloud
         description: |-
           * `aws` - AWS
           * `azure` - Azure
@@ -3340,19 +4877,26 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
       - in: query
         name: filter[provider_type__in]
         schema:
           type: array
           items:
             type: string
+            x-spec-enum-id: eca8c51e6bd28935
             enum:
             - aws
             - azure
             - gcp
             - github
+            - iac
             - kubernetes
             - m365
+            - mongodbatlas
+            - oraclecloud
         description: |-
           Multiple values may be separated by commas.
 
@@ -3362,6 +4906,9 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
         explode: false
         style: form
       - in: query
@@ -3387,6 +4934,25 @@ paths:
         description: A search term.
         schema:
           type: string
+      - in: query
+        name: filter[status]
+        schema:
+          type: string
+          enum:
+          - FAIL
+          - PASS
+        description: |-
+          * `FAIL` - Fail
+          * `PASS` - Pass
+      - in: query
+        name: filter[status__in]
+        schema:
+          type: array
+          items:
+            type: string
+        description: Multiple values may be separated by commas.
+        explode: false
+        style: form
       - name: sort
         required: false
         in: query
@@ -3412,7 +4978,7 @@ paths:
       tags:
       - Overview
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -3446,7 +5012,7 @@ paths:
       tags:
       - Overview
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -3454,13 +5020,43 @@ paths:
               schema:
                 $ref: '#/components/schemas/OverviewProviderResponse'
           description: ''
+  /api/v1/overviews/providers/count:
+    get:
+      operationId: overviews_providers_count_retrieve
+      description: Retrieve the number of providers grouped by provider type. This
+        endpoint counts every provider in the tenant, including those without completed
+        scans.
+      summary: Get provider counts grouped by type
+      parameters:
+      - in: query
+        name: fields[providers-count-overview]
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - id
+            - count
+        description: endpoint return only specific fields in the response on a per-type
+          basis by including a fields[TYPE] query parameter.
+        explode: false
+      tags:
+      - Overview
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/OverviewProviderCountResponse'
+          description: ''
   /api/v1/overviews/services:
     get:
       operationId: overviews_services_retrieve
       description: Retrieve an aggregated summary of findings grouped by service.
         The response includes the total count of findings for each service, as long
-        as there are at least one finding for that service. At least one of the `inserted_at`
-        filters must be provided.
+        as there are at least one finding for that service.
       summary: Get findings data by service
       parameters:
       - in: query
@@ -3503,17 +5099,31 @@ 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:
           type: string
+          x-spec-enum-id: eca8c51e6bd28935
           enum:
           - aws
           - azure
           - gcp
           - github
+          - iac
           - kubernetes
           - m365
+          - mongodbatlas
+          - oraclecloud
         description: |-
           * `aws` - AWS
           * `azure` - Azure
@@ -3521,19 +5131,26 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
       - in: query
         name: filter[provider_type__in]
         schema:
           type: array
           items:
             type: string
+            x-spec-enum-id: eca8c51e6bd28935
             enum:
             - aws
             - azure
             - gcp
             - github
+            - iac
             - kubernetes
             - m365
+            - mongodbatlas
+            - oraclecloud
         description: |-
           Multiple values may be separated by commas.
 
@@ -3543,6 +5160,9 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
         explode: false
         style: form
       - in: query
@@ -3591,7 +5211,7 @@ paths:
       tags:
       - Overview
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -3599,6 +5219,90 @@ paths:
               schema:
                 $ref: '#/components/schemas/OverviewServiceResponse'
           description: ''
+  /api/v1/overviews/threatscore:
+    get:
+      operationId: overviews_threatscore_retrieve
+      description: Retrieve ThreatScore metrics. By default, returns the latest snapshot
+        for each provider. Use snapshot_id to retrieve a specific historical snapshot.
+      summary: Get ThreatScore snapshots
+      parameters:
+      - in: query
+        name: fields[threatscore-snapshots]
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - id
+            - inserted_at
+            - scan
+            - provider
+            - compliance_id
+            - overall_score
+            - score_delta
+            - section_scores
+            - critical_requirements
+            - total_requirements
+            - passed_requirements
+            - failed_requirements
+            - manual_requirements
+            - total_findings
+            - passed_findings
+            - failed_findings
+        description: endpoint return only specific fields in the response on a per-type
+          basis by including a fields[TYPE] query parameter.
+        explode: false
+      - in: query
+        name: include
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - scan
+            - provider
+        description: include query parameter to allow the client to customize which
+          related resources should be returned.
+        explode: false
+      - in: query
+        name: provider_id
+        schema:
+          type: string
+          format: uuid
+        description: Filter by specific provider ID
+      - in: query
+        name: provider_id__in
+        schema:
+          type: string
+        description: Filter by multiple provider IDs (comma-separated UUIDs)
+      - in: query
+        name: provider_type
+        schema:
+          type: string
+        description: Filter by provider type (aws, azure, gcp, etc.)
+      - in: query
+        name: provider_type__in
+        schema:
+          type: string
+        description: Filter by multiple provider types (comma-separated)
+      - in: query
+        name: snapshot_id
+        schema:
+          type: string
+          format: uuid
+        description: Retrieve a specific snapshot by ID. If not provided, returns
+          latest snapshots.
+      tags:
+      - Overviews
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          content:
+            application/vnd.api+json:
+              schema:
+                $ref: '#/components/schemas/ThreatScoreSnapshotResponse'
+          description: ''
   /api/v1/processors:
     get:
       operationId: processors_list
@@ -3625,6 +5329,7 @@ paths:
         name: filter[processor_type]
         schema:
           type: string
+          x-spec-enum-id: 53cda4a99fe3d655
           enum:
           - mutelist
         description: '* `mutelist` - Mutelist'
@@ -3634,6 +5339,7 @@ paths:
           type: array
           items:
             type: string
+            x-spec-enum-id: 53cda4a99fe3d655
             enum:
             - mutelist
         description: |-
@@ -3685,7 +5391,7 @@ paths:
       tags:
       - Processor
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -3713,7 +5419,7 @@ paths:
               $ref: '#/components/schemas/ProcessorCreateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '201':
           content:
@@ -3752,7 +5458,7 @@ paths:
       tags:
       - Processor
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -3788,7 +5494,7 @@ paths:
               $ref: '#/components/schemas/PatchedProcessorUpdateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -3811,7 +5517,7 @@ paths:
       tags:
       - Processor
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: No response body
@@ -3941,7 +5647,7 @@ paths:
       tags:
       - Provider Group
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -3969,7 +5675,7 @@ paths:
               $ref: '#/components/schemas/ProviderGroupCreateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '201':
           content:
@@ -4010,7 +5716,7 @@ paths:
       tags:
       - Provider Group
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -4046,7 +5752,7 @@ paths:
               $ref: '#/components/schemas/PatchedProviderGroupUpdateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -4069,7 +5775,7 @@ paths:
       tags:
       - Provider Group
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: No response body
@@ -4094,7 +5800,7 @@ paths:
               $ref: '#/components/schemas/ProviderGroupMembershipRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: Relationship created successfully
@@ -4120,7 +5826,7 @@ paths:
               $ref: '#/components/schemas/PatchedProviderGroupMembershipRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: Relationship updated successfully
@@ -4132,7 +5838,7 @@ paths:
       tags:
       - Provider Group
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: Relationship deleted successfully
@@ -4183,6 +5889,12 @@ paths:
         name: filter[connected]
         schema:
           type: boolean
+        description: |-
+          Filter by connection status. Set to True to return only
+                  connected providers, or False to return only providers with failed
+                  connections. If not specified, both connected and failed providers are
+                  included. Providers with no connection attempt (status is null) are
+                  excluded from this filter.
       - in: query
         name: filter[id]
         schema:
@@ -4203,6 +5915,9 @@ paths:
         schema:
           type: string
           format: date
+        description: |-
+          Filter by date when the provider was added
+                  (format: YYYY-MM-DD)
       - in: query
         name: filter[inserted_at__gte]
         schema:
@@ -4217,13 +5932,17 @@ paths:
         name: filter[provider]
         schema:
           type: string
+          x-spec-enum-id: eca8c51e6bd28935
           enum:
           - aws
           - azure
           - gcp
           - github
+          - iac
           - kubernetes
           - m365
+          - mongodbatlas
+          - oraclecloud
         description: |-
           * `aws` - AWS
           * `azure` - Azure
@@ -4231,13 +5950,94 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
       - in: query
         name: filter[provider__in]
         schema:
           type: array
           items:
             type: string
-        description: Multiple values may be separated by commas.
+            x-spec-enum-id: eca8c51e6bd28935
+            enum:
+            - aws
+            - azure
+            - gcp
+            - github
+            - iac
+            - kubernetes
+            - m365
+            - mongodbatlas
+            - oraclecloud
+        description: |-
+          Multiple values may be separated by commas.
+
+          * `aws` - AWS
+          * `azure` - Azure
+          * `gcp` - GCP
+          * `kubernetes` - Kubernetes
+          * `m365` - M365
+          * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
+        explode: false
+        style: form
+      - in: query
+        name: filter[provider_type]
+        schema:
+          type: string
+          x-spec-enum-id: eca8c51e6bd28935
+          enum:
+          - aws
+          - azure
+          - gcp
+          - github
+          - iac
+          - kubernetes
+          - m365
+          - mongodbatlas
+          - oraclecloud
+        description: |-
+          * `aws` - AWS
+          * `azure` - Azure
+          * `gcp` - GCP
+          * `kubernetes` - Kubernetes
+          * `m365` - M365
+          * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
+      - in: query
+        name: filter[provider_type__in]
+        schema:
+          type: array
+          items:
+            type: string
+            x-spec-enum-id: eca8c51e6bd28935
+            enum:
+            - aws
+            - azure
+            - gcp
+            - github
+            - iac
+            - kubernetes
+            - m365
+            - mongodbatlas
+            - oraclecloud
+        description: |-
+          Multiple values may be separated by commas.
+
+          * `aws` - AWS
+          * `azure` - Azure
+          * `gcp` - GCP
+          * `kubernetes` - Kubernetes
+          * `m365` - M365
+          * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
         explode: false
         style: form
       - name: filter[search]
@@ -4268,6 +6068,9 @@ paths:
         schema:
           type: string
           format: date
+        description: |-
+          Filter by date when the provider was updated
+                  (format: YYYY-MM-DD)
       - in: query
         name: filter[updated_at__gte]
         schema:
@@ -4326,7 +6129,7 @@ paths:
       tags:
       - Provider
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -4354,7 +6157,7 @@ paths:
               $ref: '#/components/schemas/ProviderCreateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '201':
           content:
@@ -4408,7 +6211,7 @@ paths:
       tags:
       - Provider
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -4444,7 +6247,7 @@ paths:
               $ref: '#/components/schemas/PatchedProviderUpdateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -4467,13 +6270,28 @@ paths:
       tags:
       - Provider
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '202':
           content:
             application/vnd.api+json:
               schema:
-                $ref: '#/components/schemas/OpenApiResponseResponse'
+                $ref: '#/components/schemas/TaskResponse'
+              examples:
+                Task queued:
+                  summary: Task queued
+                  value:
+                    data:
+                      type: tasks
+                      id: 497f6eca-6276-4993-bfeb-53cbbbba6f08
+                      attributes:
+                        inserted_at: '2019-08-24T14:15:22Z'
+                        completed_at: '2019-08-24T14:15:22Z'
+                        name: string
+                        state: available
+                        result: null
+                        task_args: null
+                        metadata: null
           description: ''
   /api/v1/providers/{id}/connection:
     post:
@@ -4492,13 +6310,28 @@ paths:
       tags:
       - Provider
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '202':
           content:
             application/vnd.api+json:
               schema:
-                $ref: '#/components/schemas/OpenApiResponseResponse'
+                $ref: '#/components/schemas/TaskResponse'
+              examples:
+                Task queued:
+                  summary: Task queued
+                  value:
+                    data:
+                      type: tasks
+                      id: 497f6eca-6276-4993-bfeb-53cbbbba6f08
+                      attributes:
+                        inserted_at: '2019-08-24T14:15:22Z'
+                        completed_at: '2019-08-24T14:15:22Z'
+                        name: string
+                        state: available
+                        result: null
+                        task_args: null
+                        metadata: null
           description: ''
   /api/v1/providers/secrets:
     get:
@@ -4528,6 +6361,7 @@ paths:
         schema:
           type: string
           format: date
+        description: 'Filter by date when the secret was added (format: YYYY-MM-DD)'
       - in: query
         name: filter[name]
         schema:
@@ -4552,6 +6386,7 @@ paths:
         schema:
           type: string
           format: date
+        description: 'Filter by date when the secret was updated (format: YYYY-MM-DD)'
       - name: page[number]
         required: false
         in: query
@@ -4583,7 +6418,7 @@ paths:
       tags:
       - Provider
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -4611,7 +6446,7 @@ paths:
               $ref: '#/components/schemas/ProviderSecretCreateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '201':
           content:
@@ -4650,7 +6485,7 @@ paths:
       tags:
       - Provider
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -4685,7 +6520,7 @@ paths:
               $ref: '#/components/schemas/PatchedProviderSecretUpdateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -4707,7 +6542,7 @@ paths:
       tags:
       - Provider
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: No response body
@@ -4737,6 +6572,9 @@ paths:
             - findings
             - failed_findings_count
             - url
+            - metadata
+            - details
+            - partition
             - type
         description: endpoint return only specific fields in the response on a per-type
           basis by including a fields[TYPE] query parameter.
@@ -4800,13 +6638,17 @@ paths:
         name: filter[provider_type]
         schema:
           type: string
+          x-spec-enum-id: eca8c51e6bd28935
           enum:
           - aws
           - azure
           - gcp
           - github
+          - iac
           - kubernetes
           - m365
+          - mongodbatlas
+          - oraclecloud
         description: |-
           * `aws` - AWS
           * `azure` - Azure
@@ -4814,19 +6656,26 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
       - in: query
         name: filter[provider_type__in]
         schema:
           type: array
           items:
             type: string
+            x-spec-enum-id: eca8c51e6bd28935
             enum:
             - aws
             - azure
             - gcp
             - github
+            - iac
             - kubernetes
             - m365
+            - mongodbatlas
+            - oraclecloud
         description: |-
           Multiple values may be separated by commas.
 
@@ -4836,6 +6685,9 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
         explode: false
         style: form
       - in: query
@@ -5022,7 +6874,7 @@ paths:
       tags:
       - Resource
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -5056,6 +6908,9 @@ paths:
             - findings
             - failed_findings_count
             - url
+            - metadata
+            - details
+            - partition
             - type
         description: endpoint return only specific fields in the response on a per-type
           basis by including a fields[TYPE] query parameter.
@@ -5082,7 +6937,7 @@ paths:
       tags:
       - Resource
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -5115,6 +6970,9 @@ paths:
             - findings
             - failed_findings_count
             - url
+            - metadata
+            - details
+            - partition
             - type
         description: endpoint return only specific fields in the response on a per-type
           basis by including a fields[TYPE] query parameter.
@@ -5163,13 +7021,17 @@ paths:
         name: filter[provider_type]
         schema:
           type: string
+          x-spec-enum-id: eca8c51e6bd28935
           enum:
           - aws
           - azure
           - gcp
           - github
+          - iac
           - kubernetes
           - m365
+          - mongodbatlas
+          - oraclecloud
         description: |-
           * `aws` - AWS
           * `azure` - Azure
@@ -5177,19 +7039,26 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
       - in: query
         name: filter[provider_type__in]
         schema:
           type: array
           items:
             type: string
+            x-spec-enum-id: eca8c51e6bd28935
             enum:
             - aws
             - azure
             - gcp
             - github
+            - iac
             - kubernetes
             - m365
+            - mongodbatlas
+            - oraclecloud
         description: |-
           Multiple values may be separated by commas.
 
@@ -5199,6 +7068,9 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
         explode: false
         style: form
       - in: query
@@ -5340,7 +7212,7 @@ paths:
       tags:
       - Resource
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -5427,13 +7299,17 @@ paths:
         name: filter[provider_type]
         schema:
           type: string
+          x-spec-enum-id: eca8c51e6bd28935
           enum:
           - aws
           - azure
           - gcp
           - github
+          - iac
           - kubernetes
           - m365
+          - mongodbatlas
+          - oraclecloud
         description: |-
           * `aws` - AWS
           * `azure` - Azure
@@ -5441,19 +7317,26 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
       - in: query
         name: filter[provider_type__in]
         schema:
           type: array
           items:
             type: string
+            x-spec-enum-id: eca8c51e6bd28935
             enum:
             - aws
             - azure
             - gcp
             - github
+            - iac
             - kubernetes
             - m365
+            - mongodbatlas
+            - oraclecloud
         description: |-
           Multiple values may be separated by commas.
 
@@ -5463,6 +7346,9 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
         explode: false
         style: form
       - in: query
@@ -5625,7 +7511,7 @@ paths:
       tags:
       - Resource
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -5697,13 +7583,17 @@ paths:
         name: filter[provider_type]
         schema:
           type: string
+          x-spec-enum-id: eca8c51e6bd28935
           enum:
           - aws
           - azure
           - gcp
           - github
+          - iac
           - kubernetes
           - m365
+          - mongodbatlas
+          - oraclecloud
         description: |-
           * `aws` - AWS
           * `azure` - Azure
@@ -5711,19 +7601,26 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
       - in: query
         name: filter[provider_type__in]
         schema:
           type: array
           items:
             type: string
+            x-spec-enum-id: eca8c51e6bd28935
             enum:
             - aws
             - azure
             - gcp
             - github
+            - iac
             - kubernetes
             - m365
+            - mongodbatlas
+            - oraclecloud
         description: |-
           Multiple values may be separated by commas.
 
@@ -5733,6 +7630,9 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
         explode: false
         style: form
       - in: query
@@ -5862,7 +7762,7 @@ paths:
       tags:
       - Resource
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -6032,7 +7932,7 @@ paths:
       tags:
       - Role
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -6059,7 +7959,7 @@ paths:
               $ref: '#/components/schemas/RoleCreateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '201':
           content:
@@ -6107,7 +8007,7 @@ paths:
       tags:
       - Role
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -6117,8 +8017,10 @@ paths:
           description: ''
     patch:
       operationId: roles_partial_update
-      description: Update certain fields of an existing role's information without
-        affecting other fields.
+      description: Update selected fields on an existing role. When changing the `users`
+        relationship of a role that grants MANAGE_ACCOUNT, the API blocks attempts
+        that would leave the tenant without any MANAGE_ACCOUNT assignees and prevents
+        callers from removing their own assignment to that role.
       summary: Partially update a role
       parameters:
       - in: path
@@ -6143,7 +8045,7 @@ paths:
               $ref: '#/components/schemas/PatchedRoleUpdateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -6153,7 +8055,8 @@ paths:
           description: ''
     delete:
       operationId: roles_destroy
-      description: Remove a role from the system by their ID.
+      description: Delete the specified role. The API rejects deletion of the last
+        role in the tenant that grants MANAGE_ACCOUNT.
       summary: Delete a role
       parameters:
       - in: path
@@ -6166,7 +8069,7 @@ paths:
       tags:
       - Role
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: No response body
@@ -6191,7 +8094,7 @@ paths:
               $ref: '#/components/schemas/RoleProviderGroupRelationshipRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: Relationship created successfully
@@ -6217,7 +8120,7 @@ paths:
               $ref: '#/components/schemas/PatchedRoleProviderGroupRelationshipRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: Relationship updated successfully
@@ -6229,7 +8132,7 @@ paths:
       tags:
       - Role
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: Relationship deleted successfully
@@ -6295,7 +8198,7 @@ paths:
       tags:
       - SAML
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -6323,7 +8226,7 @@ paths:
               $ref: '#/components/schemas/SAMLConfigurationRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '201':
           content:
@@ -6362,7 +8265,7 @@ paths:
       tags:
       - SAML
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -6398,7 +8301,7 @@ paths:
               $ref: '#/components/schemas/PatchedSAMLConfigurationRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -6422,7 +8325,7 @@ paths:
       tags:
       - SAML
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: No response body
@@ -6527,13 +8430,17 @@ paths:
         name: filter[provider_type]
         schema:
           type: string
+          x-spec-enum-id: eca8c51e6bd28935
           enum:
           - aws
           - azure
           - gcp
           - github
+          - iac
           - kubernetes
           - m365
+          - mongodbatlas
+          - oraclecloud
         description: |-
           * `aws` - AWS
           * `azure` - Azure
@@ -6541,19 +8448,26 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
       - in: query
         name: filter[provider_type__in]
         schema:
           type: array
           items:
             type: string
+            x-spec-enum-id: eca8c51e6bd28935
             enum:
             - aws
             - azure
             - gcp
             - github
+            - iac
             - kubernetes
             - m365
+            - mongodbatlas
+            - oraclecloud
         description: |-
           Multiple values may be separated by commas.
 
@@ -6563,6 +8477,9 @@ paths:
           * `kubernetes` - Kubernetes
           * `m365` - M365
           * `github` - GitHub
+          * `mongodbatlas` - MongoDB Atlas
+          * `iac` - IaC
+          * `oraclecloud` - Oracle Cloud Infrastructure
         explode: false
         style: form
       - in: query
@@ -6607,6 +8524,7 @@ paths:
         name: filter[state]
         schema:
           type: string
+          x-spec-enum-id: d38ba07264e1ed34
           enum:
           - available
           - cancelled
@@ -6627,6 +8545,7 @@ paths:
           type: array
           items:
             type: string
+            x-spec-enum-id: d38ba07264e1ed34
             enum:
             - available
             - cancelled
@@ -6649,6 +8568,7 @@ paths:
         name: filter[trigger]
         schema:
           type: string
+          x-spec-enum-id: 2e52c981d1c89bdf
           enum:
           - manual
           - scheduled
@@ -6703,7 +8623,7 @@ paths:
       tags:
       - Scan
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -6735,13 +8655,28 @@ paths:
               $ref: '#/components/schemas/ScanCreateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '202':
           content:
             application/vnd.api+json:
               schema:
-                $ref: '#/components/schemas/OpenApiResponseResponse'
+                $ref: '#/components/schemas/TaskResponse'
+              examples:
+                Task queued:
+                  summary: Task queued
+                  value:
+                    data:
+                      type: tasks
+                      id: 497f6eca-6276-4993-bfeb-53cbbbba6f08
+                      attributes:
+                        inserted_at: '2019-08-24T14:15:22Z'
+                        completed_at: '2019-08-24T14:15:22Z'
+                        name: string
+                        state: available
+                        result: null
+                        task_args: null
+                        metadata: null
           description: ''
   /api/v1/scans/{id}:
     get:
@@ -6795,7 +8730,7 @@ paths:
       tags:
       - Scan
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -6831,7 +8766,7 @@ paths:
               $ref: '#/components/schemas/PatchedScanUpdateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -6874,7 +8809,7 @@ paths:
       tags:
       - Scan
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           description: CSV file containing the compliance report
@@ -6907,7 +8842,7 @@ paths:
       tags:
       - Scan
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           description: Report obtained successfully
@@ -6918,6 +8853,72 @@ paths:
         '404':
           description: The scan has no reports, or the report generation task has
             not started yet
+  /api/v1/scans/{id}/threatscore:
+    get:
+      operationId: scans_threatscore_retrieve
+      description: Download a specific threatscore report (e.g., 'prowler_threatscore_aws')
+        as a PDF file.
+      summary: Retrieve threatscore report
+      parameters:
+      - in: query
+        name: fields[scans]
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - name
+            - trigger
+            - state
+            - unique_resource_count
+            - progress
+            - duration
+            - provider
+            - task
+            - inserted_at
+            - started_at
+            - completed_at
+            - scheduled_at
+            - next_scan_at
+            - processor
+            - url
+        description: endpoint return only specific fields in the response on a per-type
+          basis by including a fields[TYPE] query parameter.
+        explode: false
+      - in: path
+        name: id
+        schema:
+          type: string
+          format: uuid
+        description: A UUID string identifying this scan.
+        required: true
+      - in: query
+        name: include
+        schema:
+          type: array
+          items:
+            type: string
+            enum:
+            - provider
+        description: include query parameter to allow the client to customize which
+          related resources should be returned.
+        explode: false
+      tags:
+      - Scan
+      security:
+      - JWT or API Key: []
+      responses:
+        '200':
+          description: PDF file containing the threatscore report
+        '202':
+          description: The task is in progress
+        '401':
+          description: API key missing or user not Authenticated
+        '403':
+          description: There is a problem with credentials
+        '404':
+          description: The scan has no threatscore reports, or the threatscore report
+            generation task has not started yet
   /api/v1/schedules/daily:
     post:
       operationId: schedules_daily_create
@@ -6939,13 +8940,28 @@ paths:
               $ref: '#/components/schemas/ScheduleDailyCreateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '202':
           content:
             application/vnd.api+json:
               schema:
-                $ref: '#/components/schemas/OpenApiResponseResponse'
+                $ref: '#/components/schemas/TaskResponse'
+              examples:
+                Task queued:
+                  summary: Task queued
+                  value:
+                    data:
+                      type: tasks
+                      id: 497f6eca-6276-4993-bfeb-53cbbbba6f08
+                      attributes:
+                        inserted_at: '2019-08-24T14:15:22Z'
+                        completed_at: '2019-08-24T14:15:22Z'
+                        name: string
+                        state: available
+                        result: null
+                        task_args: null
+                        metadata: null
           description: ''
   /api/v1/tasks:
     get:
@@ -7039,7 +9055,7 @@ paths:
       tags:
       - Task
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -7080,7 +9096,7 @@ paths:
       tags:
       - Task
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -7104,13 +9120,28 @@ paths:
       tags:
       - Task
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '202':
           content:
             application/vnd.api+json:
               schema:
-                $ref: '#/components/schemas/OpenApiResponseResponse'
+                $ref: '#/components/schemas/TaskResponse'
+              examples:
+                Task queued:
+                  summary: Task queued
+                  value:
+                    data:
+                      type: tasks
+                      id: 497f6eca-6276-4993-bfeb-53cbbbba6f08
+                      attributes:
+                        inserted_at: '2019-08-24T14:15:22Z'
+                        completed_at: '2019-08-24T14:15:22Z'
+                        name: string
+                        state: available
+                        result: null
+                        task_args: null
+                        metadata: null
           description: ''
   /api/v1/tenants:
     get:
@@ -7211,7 +9242,7 @@ paths:
       tags:
       - Tenant
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -7239,7 +9270,7 @@ paths:
               $ref: '#/components/schemas/TenantRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '201':
           content:
@@ -7275,7 +9306,7 @@ paths:
       tags:
       - Tenant
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -7311,7 +9342,7 @@ paths:
               $ref: '#/components/schemas/PatchedTenantRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -7334,7 +9365,7 @@ paths:
       tags:
       - Tenant
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: No response body
@@ -7407,7 +9438,7 @@ paths:
       tags:
       - Tenant
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -7439,7 +9470,7 @@ paths:
       tags:
       - Tenant
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: No response body
@@ -7532,6 +9563,7 @@ paths:
         name: filter[state]
         schema:
           type: string
+          x-spec-enum-id: 92a1c1fd12e13e25
           enum:
           - accepted
           - expired
@@ -7617,7 +9649,7 @@ paths:
       tags:
       - Invitation
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -7646,7 +9678,7 @@ paths:
               $ref: '#/components/schemas/InvitationCreateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '201':
           content:
@@ -7688,7 +9720,7 @@ paths:
       tags:
       - Invitation
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -7723,7 +9755,7 @@ paths:
               $ref: '#/components/schemas/PatchedInvitationUpdateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -7745,7 +9777,7 @@ paths:
       tags:
       - Invitation
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: No response body
@@ -7770,7 +9802,7 @@ paths:
               $ref: '#/components/schemas/TokenRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       - {}
       responses:
         '200':
@@ -7800,7 +9832,7 @@ paths:
               $ref: '#/components/schemas/TokenRefreshRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       - {}
       responses:
         '200':
@@ -7830,7 +9862,7 @@ paths:
               $ref: '#/components/schemas/TokenSwitchTenantRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -7923,6 +9955,7 @@ paths:
             type: string
             enum:
             - roles
+            - memberships
         description: include query parameter to allow the client to customize which
           related resources should be returned.
         explode: false
@@ -7961,7 +9994,7 @@ paths:
       tags:
       - User
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -7996,7 +10029,7 @@ paths:
               $ref: '#/components/schemas/UserCreateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       - {}
       responses:
         '201':
@@ -8042,13 +10075,14 @@ paths:
             type: string
             enum:
             - roles
+            - memberships
         description: include query parameter to allow the client to customize which
           related resources should be returned.
         explode: false
       tags:
       - User
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -8083,7 +10117,7 @@ paths:
               $ref: '#/components/schemas/PatchedUserUpdateRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -8106,7 +10140,7 @@ paths:
       tags:
       - User
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: No response body
@@ -8131,7 +10165,7 @@ paths:
               $ref: '#/components/schemas/UserRoleRelationshipRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: Relationship created successfully
@@ -8140,7 +10174,8 @@ paths:
     patch:
       operationId: users_relationships_roles_partial_update
       description: Update the user-roles relationship information without affecting
-        other fields.
+        other fields. If the update would remove MANAGE_ACCOUNT from the last remaining
+        user in the tenant, the API rejects the request with a 400 response.
       summary: Partially update a user-roles relationship
       tags:
       - User
@@ -8157,18 +10192,22 @@ paths:
               $ref: '#/components/schemas/PatchedUserRoleRelationshipRequest'
         required: true
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: Relationship updated successfully
     delete:
       operationId: users_relationships_roles_destroy
       description: Remove the user-roles relationship from the system by their ID.
+        If removing MANAGE_ACCOUNT would take it away from the last remaining user
+        in the tenant, the API rejects the request with a 400 response. Users also
+        cannot delete their own role assignments; attempting to do so returns a 400
+        response.
       summary: Delete a user-roles relationship
       tags:
       - User
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '204':
           description: Relationship deleted successfully
@@ -8217,6 +10256,7 @@ paths:
         name: filter[role]
         schema:
           type: string
+          x-spec-enum-id: 12c359ee5dc51001
           enum:
           - member
           - owner
@@ -8271,7 +10311,7 @@ paths:
       tags:
       - User
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -8316,7 +10356,7 @@ paths:
       tags:
       - User
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -8354,13 +10394,14 @@ paths:
             type: string
             enum:
             - roles
+            - memberships
         description: include query parameter to allow the client to customize which
           related resources should be returned.
         explode: false
       tags:
       - User
       security:
-      - jwtAuth: []
+      - JWT or API Key: []
       responses:
         '200':
           content:
@@ -8378,11 +10419,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/ComplianceOverviewTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - compliance-overviews
         id: {}
         attributes:
           type: object
@@ -8417,17 +10459,20 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/ComplianceOverviewAttributesTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - compliance-requirements-attributes
         id: {}
         attributes:
           type: object
           properties:
             id:
               type: string
+            compliance_name:
+              type: string
             framework_description:
               type: string
             name:
@@ -8441,16 +10486,13 @@ components:
             attributes: {}
           required:
           - id
+          - compliance_name
           - framework_description
           - name
           - framework
           - version
           - description
           - attributes
-    ComplianceOverviewAttributesTypeEnum:
-      type: string
-      enum:
-      - compliance-requirements-attributes
     ComplianceOverviewDetail:
       type: object
       required:
@@ -8459,11 +10501,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/ComplianceOverviewDetailTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - compliance-requirements-details
         id: {}
         attributes:
           type: object
@@ -8486,16 +10529,13 @@ components:
                 * `FAIL` - Fail
                 * `PASS` - Pass
                 * `MANUAL` - Manual
+              x-spec-enum-id: ce612ddbfa464789
           required:
           - id
           - framework
           - version
           - description
           - status
-    ComplianceOverviewDetailTypeEnum:
-      type: string
-      enum:
-      - compliance-requirements-details
     ComplianceOverviewMetadata:
       type: object
       required:
@@ -8504,11 +10544,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/ComplianceOverviewMetadataTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - compliance-overviews-metadata
         id: {}
         attributes:
           type: object
@@ -8519,14 +10560,6 @@ components:
                 type: string
           required:
           - regions
-    ComplianceOverviewMetadataTypeEnum:
-      type: string
-      enum:
-      - compliance-overviews-metadata
-    ComplianceOverviewTypeEnum:
-      type: string
-      enum:
-      - compliance-overviews
     Finding:
       type: object
       required:
@@ -8535,11 +10568,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/FindingTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - findings
         id:
           type: string
           format: uuid
@@ -8558,6 +10592,7 @@ components:
               description: |-
                 * `new` - New
                 * `changed` - Changed
+              x-spec-enum-id: fef6b0e2506af8bc
               nullable: true
             status:
               enum:
@@ -8569,6 +10604,7 @@ components:
                 * `FAIL` - Fail
                 * `PASS` - Pass
                 * `MANUAL` - Manual
+              x-spec-enum-id: ce612ddbfa464789
             status_extended:
               type: string
               nullable: true
@@ -8586,6 +10622,7 @@ components:
                 * `medium` - Medium
                 * `low` - Low
                 * `informational` - Informational
+              x-spec-enum-id: c93e070ed135d9bf
             check_id:
               type: string
               maxLength: 100
@@ -8682,11 +10719,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/FindingDynamicFilterTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - finding-dynamic-filters
         id: {}
         attributes:
           type: object
@@ -8709,10 +10747,6 @@ components:
           $ref: '#/components/schemas/FindingDynamicFilter'
       required:
       - data
-    FindingDynamicFilterTypeEnum:
-      type: string
-      enum:
-      - finding-dynamic-filters
     FindingMetadata:
       type: object
       required:
@@ -8721,11 +10755,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/FindingMetadataTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - findings-metadata
         id: {}
         attributes:
           type: object
@@ -8753,10 +10788,6 @@ components:
           $ref: '#/components/schemas/FindingMetadata'
       required:
       - data
-    FindingMetadataTypeEnum:
-      type: string
-      enum:
-      - findings-metadata
     FindingResponse:
       type: object
       properties:
@@ -8764,10 +10795,6 @@ components:
           $ref: '#/components/schemas/Finding'
       required:
       - data
-    FindingTypeEnum:
-      type: string
-      enum:
-      - findings
     Integration:
       type: object
       required:
@@ -8776,11 +10803,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/TypeC82Enum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - integrations
         id:
           type: string
           format: uuid
@@ -8816,6 +10844,7 @@ components:
                 * `aws_security_hub` - AWS Security Hub
                 * `jira` - JIRA
                 * `slack` - Slack
+              x-spec-enum-id: 6cfd0ff9cf4d6dcc
             configuration: {}
           required:
           - integration_type
@@ -8859,11 +10888,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/TypeC82Enum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - integrations
         attributes:
           type: object
           properties:
@@ -8898,6 +10928,7 @@ components:
                 * `aws_security_hub` - AWS Security Hub
                 * `jira` - JIRA
                 * `slack` - Slack
+              x-spec-enum-id: 6cfd0ff9cf4d6dcc
             configuration:
               oneOf:
               - type: object
@@ -8924,13 +10955,19 @@ components:
                   send_only_fails:
                     type: boolean
                     default: false
-                    description: If true, only findings with status 'FAIL' will
-                      be sent to Security Hub.
+                    description: If true, only findings with status 'FAIL' will be
+                      sent to Security Hub.
                   archive_previous_findings:
                     type: boolean
                     default: false
                     description: If true, archives findings that are not present in
                       the current execution.
+              - type: object
+                title: JIRA
+                description: JIRA integration does not accept any configuration in
+                  the payload. Leave it as an empty JSON object (`{}`).
+                properties: {}
+                additionalProperties: false
             credentials:
               oneOf:
               - type: object
@@ -8970,6 +11007,24 @@ components:
                       - User_Session-1
                       - Test.Session@2
                     pattern: ^[a-zA-Z0-9=,.@_-]+$
+              - type: object
+                title: JIRA Credentials
+                properties:
+                  user_mail:
+                    type: string
+                    format: email
+                    description: The email address of the JIRA user account.
+                  api_token:
+                    type: string
+                    description: The API token for authentication with JIRA. This
+                      can be generated from your Atlassian account settings.
+                  domain:
+                    type: string
+                    description: The JIRA domain/instance URL (e.g., 'your-domain.atlassian.net').
+                required:
+                - user_mail
+                - api_token
+                - domain
               writeOnly: true
           required:
           - integration_type
@@ -9056,6 +11111,7 @@ components:
                     * `aws_security_hub` - AWS Security Hub
                     * `jira` - JIRA
                     * `slack` - Slack
+                  x-spec-enum-id: 6cfd0ff9cf4d6dcc
                 configuration:
                   oneOf:
                   - type: object
@@ -9090,6 +11146,12 @@ components:
                         default: false
                         description: If true, archives findings that are not present
                           in the current execution.
+                  - type: object
+                    title: JIRA
+                    description: JIRA integration does not accept any configuration
+                      in the payload. Leave it as an empty JSON object (`{}`).
+                    properties: {}
+                    additionalProperties: false
                 credentials:
                   oneOf:
                   - type: object
@@ -9130,6 +11192,24 @@ components:
                           - User_Session-1
                           - Test.Session@2
                         pattern: ^[a-zA-Z0-9=,.@_-]+$
+                  - type: object
+                    title: JIRA Credentials
+                    properties:
+                      user_mail:
+                        type: string
+                        format: email
+                        description: The email address of the JIRA user account.
+                      api_token:
+                        type: string
+                        description: The API token for authentication with JIRA. This
+                          can be generated from your Atlassian account settings.
+                      domain:
+                        type: string
+                        description: The JIRA domain/instance URL (e.g., 'your-domain.atlassian.net').
+                    required:
+                    - user_mail
+                    - api_token
+                    - domain
                   writeOnly: true
               required:
               - integration_type
@@ -9175,6 +11255,39 @@ components:
           $ref: '#/components/schemas/IntegrationCreate'
       required:
       - data
+    IntegrationJiraDispatchRequest:
+      type: object
+      properties:
+        data:
+          type: object
+          required:
+          - type
+          additionalProperties: false
+          properties:
+            type:
+              type: string
+              description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                member is used to describe resource objects that share common attributes
+                and relationships.
+              enum:
+              - integrations-jira-dispatches
+            attributes:
+              type: object
+              properties:
+                project_key:
+                  type: string
+                  minLength: 1
+                issue_type:
+                  enum:
+                  - Task
+                  type: string
+                  description: '* `Task` - Task'
+                  x-spec-enum-id: b527b0cec62087c1
+              required:
+              - project_key
+              - issue_type
+      required:
+      - data
     IntegrationResponse:
       type: object
       properties:
@@ -9190,11 +11303,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/TypeC82Enum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - integrations
         id: {}
         attributes:
           type: object
@@ -9230,6 +11344,7 @@ components:
                 * `aws_security_hub` - AWS Security Hub
                 * `jira` - JIRA
                 * `slack` - Slack
+              x-spec-enum-id: 6cfd0ff9cf4d6dcc
               readOnly: true
             configuration:
               oneOf:
@@ -9257,13 +11372,19 @@ components:
                   send_only_fails:
                     type: boolean
                     default: false
-                    description: If true, only findings with status 'FAIL' will
-                      be sent to Security Hub.
+                    description: If true, only findings with status 'FAIL' will be
+                      sent to Security Hub.
                   archive_previous_findings:
                     type: boolean
                     default: false
                     description: If true, archives findings that are not present in
                       the current execution.
+              - type: object
+                title: JIRA
+                description: JIRA integration does not accept any configuration in
+                  the payload. Leave it as an empty JSON object (`{}`).
+                properties: {}
+                additionalProperties: false
             credentials:
               oneOf:
               - type: object
@@ -9303,6 +11424,24 @@ components:
                       - User_Session-1
                       - Test.Session@2
                     pattern: ^[a-zA-Z0-9=,.@_-]+$
+              - type: object
+                title: JIRA Credentials
+                properties:
+                  user_mail:
+                    type: string
+                    format: email
+                    description: The email address of the JIRA user account.
+                  api_token:
+                    type: string
+                    description: The API token for authentication with JIRA. This
+                      can be generated from your Atlassian account settings.
+                  domain:
+                    type: string
+                    description: The JIRA domain/instance URL (e.g., 'your-domain.atlassian.net').
+                required:
+                - user_mail
+                - api_token
+                - domain
               writeOnly: true
         relationships:
           type: object
@@ -9350,11 +11489,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/TypeD4dEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - invitations
         id:
           type: string
           format: uuid
@@ -9385,6 +11525,7 @@ components:
                 * `accepted` - Invitation was accepted by a user
                 * `expired` - Invitation expired after the configured time
                 * `revoked` - Invitation was revoked by a user
+              x-spec-enum-id: 92a1c1fd12e13e25
             token:
               type: string
               readOnly: true
@@ -9485,11 +11626,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/TypeD4dEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - invitations
         attributes:
           type: object
           properties:
@@ -9514,6 +11656,7 @@ components:
                 * `accepted` - Invitation was accepted by a user
                 * `expired` - Invitation expired after the configured time
                 * `revoked` - Invitation was revoked by a user
+              x-spec-enum-id: 92a1c1fd12e13e25
               readOnly: true
             token:
               type: string
@@ -9620,6 +11763,7 @@ components:
                     * `accepted` - Invitation was accepted by a user
                     * `expired` - Invitation expired after the configured time
                     * `revoked` - Invitation was revoked by a user
+                  x-spec-enum-id: 92a1c1fd12e13e25
                   readOnly: true
                 token:
                   type: string
@@ -9710,11 +11854,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/TypeD4dEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - invitations
         id:
           type: string
           format: uuid
@@ -9740,6 +11885,7 @@ components:
                 * `accepted` - Invitation was accepted by a user
                 * `expired` - Invitation expired after the configured time
                 * `revoked` - Invitation was revoked by a user
+              x-spec-enum-id: 92a1c1fd12e13e25
               readOnly: true
             token:
               type: string
@@ -9790,11 +11936,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type4bfEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - lighthouse-configurations
         id:
           type: string
           format: uuid
@@ -9821,6 +11968,7 @@ components:
               - gpt-5-mini-2025-08-07
               - gpt-5-mini
               type: string
+              x-spec-enum-id: bd2108eb25b2d472
               description: |-
                 Must be one of the supported model names
 
@@ -9866,11 +12014,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type4bfEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - lighthouse-configurations
         attributes:
           type: object
           properties:
@@ -9895,6 +12044,7 @@ components:
               - gpt-5-mini-2025-08-07
               - gpt-5-mini
               type: string
+              x-spec-enum-id: bd2108eb25b2d472
               description: |-
                 Must be one of the supported model names
 
@@ -9975,6 +12125,7 @@ components:
                   - gpt-5-mini-2025-08-07
                   - gpt-5-mini
                   type: string
+                  x-spec-enum-id: bd2108eb25b2d472
                   description: |-
                     Must be one of the supported model names
 
@@ -10031,11 +12182,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type4bfEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - lighthouse-configurations
         id:
           type: string
           format: uuid
@@ -10063,6 +12215,7 @@ components:
               - gpt-5-mini-2025-08-07
               - gpt-5-mini
               type: string
+              x-spec-enum-id: bd2108eb25b2d472
               description: |-
                 Must be one of the supported model names
 
@@ -10098,6 +12251,481 @@ components:
           $ref: '#/components/schemas/LighthouseConfigUpdate'
       required:
       - data
+    LighthouseProviderConfig:
+      type: object
+      required:
+      - type
+      - id
+      additionalProperties: false
+      properties:
+        type:
+          type: string
+          description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+            member is used to describe resource objects that share common attributes
+            and relationships.
+          enum:
+          - lighthouse-providers
+        id:
+          type: string
+          format: uuid
+        attributes:
+          type: object
+          properties:
+            inserted_at:
+              type: string
+              format: date-time
+              readOnly: true
+            updated_at:
+              type: string
+              format: date-time
+              readOnly: true
+            provider_type:
+              enum:
+              - openai
+              - bedrock
+              - openai_compatible
+              type: string
+              x-spec-enum-id: 30bc523cb9ec0e8b
+              description: |-
+                LLM provider name
+
+                * `openai` - OpenAI
+                * `bedrock` - AWS Bedrock
+                * `openai_compatible` - OpenAI Compatible
+            base_url:
+              type: string
+              format: uri
+              nullable: true
+              maxLength: 200
+            is_active:
+              type: boolean
+              readOnly: true
+            credentials:
+              readOnly: true
+          required:
+          - provider_type
+    LighthouseProviderConfigCreate:
+      type: object
+      required:
+      - type
+      additionalProperties: false
+      properties:
+        type:
+          type: string
+          description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+            member is used to describe resource objects that share common attributes
+            and relationships.
+          enum:
+          - lighthouse-providers
+        attributes:
+          type: object
+          properties:
+            provider_type:
+              enum:
+              - openai
+              - bedrock
+              - openai_compatible
+              type: string
+              x-spec-enum-id: 30bc523cb9ec0e8b
+              description: |-
+                LLM provider type. Determines which credential format to use. See 'credentials' field documentation for provider-specific requirements.
+
+                * `openai` - OpenAI
+                * `bedrock` - AWS Bedrock
+                * `openai_compatible` - OpenAI Compatible
+            base_url:
+              type: string
+              format: uri
+              nullable: true
+              description: Base URL for the LLM provider API. Required for 'openai_compatible'
+                provider type.
+            credentials:
+              oneOf:
+              - type: object
+                title: OpenAI Credentials
+                properties:
+                  api_key:
+                    type: string
+                    description: OpenAI API key. Must start with 'sk-' followed by
+                      alphanumeric characters, hyphens, or underscores.
+                    pattern: ^sk-[\w-]+$
+                required:
+                - api_key
+              - type: object
+                title: AWS Bedrock Credentials
+                properties:
+                  access_key_id:
+                    type: string
+                    description: AWS access key ID.
+                    pattern: ^AKIA[0-9A-Z]{16}$
+                  secret_access_key:
+                    type: string
+                    description: AWS secret access key.
+                    pattern: ^[A-Za-z0-9/+=]{40}$
+                  region:
+                    type: string
+                    description: 'AWS region identifier where Bedrock is available.
+                      Examples: us-east-1, us-west-2, eu-west-1, ap-northeast-1.'
+                    pattern: ^[a-z]{2}-[a-z]+-\d+$
+                required:
+                - access_key_id
+                - secret_access_key
+                - region
+              - type: object
+                title: OpenAI Compatible Credentials
+                properties:
+                  api_key:
+                    type: string
+                    description: 'API key for OpenAI-compatible provider. The format
+                      varies by provider. Note: The ''base_url'' field (separate from
+                      credentials) is required when using this provider type.'
+                required:
+                - api_key
+              writeOnly: true
+            is_active:
+              type: boolean
+          required:
+          - provider_type
+          - credentials
+    LighthouseProviderConfigCreateRequest:
+      type: object
+      properties:
+        data:
+          type: object
+          required:
+          - type
+          additionalProperties: false
+          properties:
+            type:
+              type: string
+              description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                member is used to describe resource objects that share common attributes
+                and relationships.
+              enum:
+              - lighthouse-providers
+            attributes:
+              type: object
+              properties:
+                provider_type:
+                  enum:
+                  - openai
+                  - bedrock
+                  - openai_compatible
+                  type: string
+                  x-spec-enum-id: 30bc523cb9ec0e8b
+                  description: |-
+                    LLM provider type. Determines which credential format to use. See 'credentials' field documentation for provider-specific requirements.
+
+                    * `openai` - OpenAI
+                    * `bedrock` - AWS Bedrock
+                    * `openai_compatible` - OpenAI Compatible
+                base_url:
+                  type: string
+                  format: uri
+                  nullable: true
+                  minLength: 1
+                  description: Base URL for the LLM provider API. Required for 'openai_compatible'
+                    provider type.
+                credentials:
+                  oneOf:
+                  - type: object
+                    title: OpenAI Credentials
+                    properties:
+                      api_key:
+                        type: string
+                        description: OpenAI API key. Must start with 'sk-' followed
+                          by alphanumeric characters, hyphens, or underscores.
+                        pattern: ^sk-[\w-]+$
+                    required:
+                    - api_key
+                  - type: object
+                    title: AWS Bedrock Credentials
+                    properties:
+                      access_key_id:
+                        type: string
+                        description: AWS access key ID.
+                        pattern: ^AKIA[0-9A-Z]{16}$
+                      secret_access_key:
+                        type: string
+                        description: AWS secret access key.
+                        pattern: ^[A-Za-z0-9/+=]{40}$
+                      region:
+                        type: string
+                        description: 'AWS region identifier where Bedrock is available.
+                          Examples: us-east-1, us-west-2, eu-west-1, ap-northeast-1.'
+                        pattern: ^[a-z]{2}-[a-z]+-\d+$
+                    required:
+                    - access_key_id
+                    - secret_access_key
+                    - region
+                  - type: object
+                    title: OpenAI Compatible Credentials
+                    properties:
+                      api_key:
+                        type: string
+                        description: 'API key for OpenAI-compatible provider. The
+                          format varies by provider. Note: The ''base_url'' field
+                          (separate from credentials) is required when using this
+                          provider type.'
+                    required:
+                    - api_key
+                  writeOnly: true
+                is_active:
+                  type: boolean
+              required:
+              - provider_type
+              - credentials
+      required:
+      - data
+    LighthouseProviderConfigCreateResponse:
+      type: object
+      properties:
+        data:
+          $ref: '#/components/schemas/LighthouseProviderConfigCreate'
+      required:
+      - data
+    LighthouseProviderConfigResponse:
+      type: object
+      properties:
+        data:
+          $ref: '#/components/schemas/LighthouseProviderConfig'
+      required:
+      - data
+    LighthouseProviderConfigUpdate:
+      type: object
+      required:
+      - type
+      - id
+      additionalProperties: false
+      properties:
+        type:
+          type: string
+          description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+            member is used to describe resource objects that share common attributes
+            and relationships.
+          enum:
+          - lighthouse-providers
+        id:
+          type: string
+          format: uuid
+        attributes:
+          type: object
+          properties:
+            provider_type:
+              enum:
+              - openai
+              - bedrock
+              - openai_compatible
+              type: string
+              x-spec-enum-id: 30bc523cb9ec0e8b
+              readOnly: true
+              description: |-
+                LLM provider name
+
+                * `openai` - OpenAI
+                * `bedrock` - AWS Bedrock
+                * `openai_compatible` - OpenAI Compatible
+            base_url:
+              type: string
+              format: uri
+              nullable: true
+              description: Base URL for the LLM provider API. Required for 'openai_compatible'
+                provider type.
+            credentials:
+              oneOf:
+              - type: object
+                title: OpenAI Credentials
+                properties:
+                  api_key:
+                    type: string
+                    description: OpenAI API key. Must start with 'sk-' followed by
+                      alphanumeric characters, hyphens, or underscores.
+                    pattern: ^sk-[\w-]+$
+                required:
+                - api_key
+              - type: object
+                title: AWS Bedrock Credentials
+                properties:
+                  access_key_id:
+                    type: string
+                    description: AWS access key ID.
+                    pattern: ^AKIA[0-9A-Z]{16}$
+                  secret_access_key:
+                    type: string
+                    description: AWS secret access key.
+                    pattern: ^[A-Za-z0-9/+=]{40}$
+                  region:
+                    type: string
+                    description: 'AWS region identifier where Bedrock is available.
+                      Examples: us-east-1, us-west-2, eu-west-1, ap-northeast-1.'
+                    pattern: ^[a-z]{2}-[a-z]+-\d+$
+                required:
+                - access_key_id
+                - secret_access_key
+                - region
+              - type: object
+                title: OpenAI Compatible Credentials
+                properties:
+                  api_key:
+                    type: string
+                    description: 'API key for OpenAI-compatible provider. The format
+                      varies by provider. Note: The ''base_url'' field (separate from
+                      credentials) is required when using this provider type.'
+                required:
+                - api_key
+              writeOnly: true
+            is_active:
+              type: boolean
+    LighthouseProviderConfigUpdateResponse:
+      type: object
+      properties:
+        data:
+          $ref: '#/components/schemas/LighthouseProviderConfigUpdate'
+      required:
+      - data
+    LighthouseProviderModels:
+      type: object
+      required:
+      - type
+      - id
+      additionalProperties: false
+      properties:
+        type:
+          type: string
+          description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+            member is used to describe resource objects that share common attributes
+            and relationships.
+          enum:
+          - lighthouse-models
+        id:
+          type: string
+          format: uuid
+        attributes:
+          type: object
+          properties:
+            inserted_at:
+              type: string
+              format: date-time
+              readOnly: true
+            updated_at:
+              type: string
+              format: date-time
+              readOnly: true
+            model_id:
+              type: string
+              maxLength: 100
+            model_name:
+              type: string
+              maxLength: 100
+            default_parameters: {}
+          required:
+          - model_id
+          - model_name
+        relationships:
+          type: object
+          properties:
+            provider_configuration:
+              type: object
+              properties:
+                data:
+                  type: object
+                  properties:
+                    id:
+                      type: string
+                      format: uuid
+                    type:
+                      type: string
+                      enum:
+                      - lighthouse-providers
+                      title: Resource Type Name
+                      description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                        member is used to describe resource objects that share common
+                        attributes and relationships.
+                  required:
+                  - id
+                  - type
+              required:
+              - data
+              description: The identifier of the related object.
+              title: Resource Identifier
+              readOnly: true
+    LighthouseProviderModelsResponse:
+      type: object
+      properties:
+        data:
+          $ref: '#/components/schemas/LighthouseProviderModels'
+      required:
+      - data
+    LighthouseTenantConfig:
+      type: object
+      required:
+      - type
+      - id
+      additionalProperties: false
+      properties:
+        type:
+          type: string
+          description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+            member is used to describe resource objects that share common attributes
+            and relationships.
+          enum:
+          - lighthouse-configurations
+        id:
+          type: string
+          format: uuid
+        attributes:
+          type: object
+          properties:
+            inserted_at:
+              type: string
+              format: date-time
+              readOnly: true
+            updated_at:
+              type: string
+              format: date-time
+              readOnly: true
+            business_context:
+              type: string
+            default_provider:
+              type: string
+              maxLength: 50
+            default_models: {}
+            url:
+              type: string
+              readOnly: true
+    LighthouseTenantConfigUpdate:
+      type: object
+      required:
+      - type
+      - id
+      additionalProperties: false
+      properties:
+        type:
+          type: string
+          description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+            member is used to describe resource objects that share common attributes
+            and relationships.
+          enum:
+          - lighthouse-configurations
+        id:
+          type: string
+          format: uuid
+        attributes:
+          type: object
+          properties:
+            business_context:
+              type: string
+            default_provider:
+              type: string
+              maxLength: 50
+            default_models: {}
+    LighthouseTenantConfigUpdateResponse:
+      type: object
+      properties:
+        data:
+          $ref: '#/components/schemas/LighthouseTenantConfigUpdate'
+      required:
+      - data
     Membership:
       type: object
       required:
@@ -10105,11 +12733,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/MembershipTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - memberships
         attributes:
           type: object
           properties:
@@ -10121,6 +12750,7 @@ components:
               description: |-
                 * `owner` - Owner
                 * `member` - Member
+              x-spec-enum-id: 12c359ee5dc51001
             date_joined:
               type: string
               format: date-time
@@ -10187,15 +12817,277 @@ components:
           $ref: '#/components/schemas/Membership'
       required:
       - data
-    MembershipTypeEnum:
-      type: string
-      enum:
-      - memberships
+    MuteRule:
+      type: object
+      required:
+      - type
+      - id
+      additionalProperties: false
+      properties:
+        type:
+          type: string
+          description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+            member is used to describe resource objects that share common attributes
+            and relationships.
+          enum:
+          - mute-rules
+        id:
+          type: string
+          format: uuid
+        attributes:
+          type: object
+          properties:
+            inserted_at:
+              type: string
+              format: date-time
+              readOnly: true
+            updated_at:
+              type: string
+              format: date-time
+              readOnly: true
+            name:
+              type: string
+              description: Human-readable name for this rule
+              maxLength: 100
+              minLength: 3
+            reason:
+              type: string
+              description: Reason for muting
+              minLength: 3
+              maxLength: 500
+            enabled:
+              type: boolean
+              description: Whether this rule is currently enabled
+            finding_uids:
+              type: array
+              items:
+                type: string
+              readOnly: true
+              description: List of finding UIDs that are muted by this rule
+          required:
+          - name
+          - reason
+        relationships:
+          type: object
+          properties:
+            created_by:
+              type: object
+              properties:
+                data:
+                  type: object
+                  properties:
+                    id:
+                      type: string
+                      format: uuid
+                    type:
+                      type: string
+                      enum:
+                      - users
+                      title: Resource Type Name
+                      description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                        member is used to describe resource objects that share common
+                        attributes and relationships.
+                  required:
+                  - id
+                  - type
+              required:
+              - data
+              description: The identifier of the related object.
+              title: Resource Identifier
+              nullable: true
+    MuteRuleCreate:
+      type: object
+      required:
+      - type
+      additionalProperties: false
+      properties:
+        type:
+          type: string
+          description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+            member is used to describe resource objects that share common attributes
+            and relationships.
+          enum:
+          - mute-rules
+        attributes:
+          type: object
+          properties:
+            inserted_at:
+              type: string
+              format: date-time
+              readOnly: true
+            updated_at:
+              type: string
+              format: date-time
+              readOnly: true
+            name:
+              type: string
+              description: Human-readable name for this rule
+              maxLength: 100
+              minLength: 3
+            reason:
+              type: string
+              description: Reason for muting
+              minLength: 3
+              maxLength: 500
+            enabled:
+              type: boolean
+              readOnly: true
+              description: Whether this rule is currently enabled
+            finding_ids:
+              type: array
+              items:
+                type: string
+                format: uuid
+              writeOnly: true
+              description: List of Finding IDs to mute (will be converted to UIDs)
+            finding_uids:
+              type: array
+              items:
+                type: string
+              readOnly: true
+              description: List of finding UIDs that are muted by this rule
+          required:
+          - name
+          - reason
+          - finding_ids
+        relationships:
+          type: object
+          properties:
+            created_by:
+              type: object
+              properties:
+                data:
+                  type: object
+                  properties:
+                    id:
+                      type: string
+                      format: uuid
+                    type:
+                      type: string
+                      enum:
+                      - users
+                      title: Resource Type Name
+                      description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                        member is used to describe resource objects that share common
+                        attributes and relationships.
+                  required:
+                  - id
+                  - type
+              required:
+              - data
+              description: The identifier of the related object.
+              title: Resource Identifier
+              readOnly: true
+              nullable: true
+    MuteRuleCreateRequest:
+      type: object
+      properties:
+        data:
+          type: object
+          required:
+          - type
+          additionalProperties: false
+          properties:
+            type:
+              type: string
+              description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                member is used to describe resource objects that share common attributes
+                and relationships.
+              enum:
+              - mute-rules
+            attributes:
+              type: object
+              properties:
+                inserted_at:
+                  type: string
+                  format: date-time
+                  readOnly: true
+                updated_at:
+                  type: string
+                  format: date-time
+                  readOnly: true
+                name:
+                  type: string
+                  minLength: 3
+                  description: Human-readable name for this rule
+                  maxLength: 100
+                reason:
+                  type: string
+                  minLength: 3
+                  description: Reason for muting
+                  maxLength: 500
+                enabled:
+                  type: boolean
+                  readOnly: true
+                  description: Whether this rule is currently enabled
+                finding_ids:
+                  type: array
+                  items:
+                    type: string
+                    format: uuid
+                  writeOnly: true
+                  description: List of Finding IDs to mute (will be converted to UIDs)
+                finding_uids:
+                  type: array
+                  items:
+                    type: string
+                    minLength: 1
+                  readOnly: true
+                  description: List of finding UIDs that are muted by this rule
+              required:
+              - name
+              - reason
+              - finding_ids
+            relationships:
+              type: object
+              properties:
+                created_by:
+                  type: object
+                  properties:
+                    data:
+                      type: object
+                      properties:
+                        id:
+                          type: string
+                          format: uuid
+                        type:
+                          type: string
+                          enum:
+                          - users
+                          title: Resource Type Name
+                          description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                            member is used to describe resource objects that share
+                            common attributes and relationships.
+                      required:
+                      - id
+                      - type
+                  required:
+                  - data
+                  description: The identifier of the related object.
+                  title: Resource Identifier
+                  readOnly: true
+                  nullable: true
+      required:
+      - data
+    MuteRuleCreateResponse:
+      type: object
+      properties:
+        data:
+          $ref: '#/components/schemas/MuteRuleCreate'
+      required:
+      - data
+    MuteRuleResponse:
+      type: object
+      properties:
+        data:
+          $ref: '#/components/schemas/MuteRule'
+      required:
+      - data
     OpenApiResponseResponse:
       type: object
       properties:
         data:
-          $ref: '#/components/schemas/ComplianceOverviewMetadata'
+          $ref: '#/components/schemas/TenantApiKey'
       required:
       - data
     OverviewFinding:
@@ -10206,11 +13098,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/OverviewFindingTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - findings-overview
         id: {}
         attributes:
           type: object
@@ -10265,10 +13158,6 @@ components:
           $ref: '#/components/schemas/OverviewFinding'
       required:
       - data
-    OverviewFindingTypeEnum:
-      type: string
-      enum:
-      - findings-overview
     OverviewProvider:
       type: object
       required:
@@ -10277,11 +13166,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/OverviewProviderTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - providers-overview
         id: {}
         attributes:
           type: object
@@ -10308,6 +13198,38 @@ components:
               readOnly: true
           required:
           - id
+    OverviewProviderCount:
+      type: object
+      required:
+      - type
+      - id
+      additionalProperties: false
+      properties:
+        type:
+          type: string
+          description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+            member is used to describe resource objects that share common attributes
+            and relationships.
+          enum:
+          - providers-count-overview
+        id: {}
+        attributes:
+          type: object
+          properties:
+            id:
+              type: string
+            count:
+              type: integer
+          required:
+          - id
+          - count
+    OverviewProviderCountResponse:
+      type: object
+      properties:
+        data:
+          $ref: '#/components/schemas/OverviewProviderCount'
+      required:
+      - data
     OverviewProviderResponse:
       type: object
       properties:
@@ -10315,10 +13237,6 @@ components:
           $ref: '#/components/schemas/OverviewProvider'
       required:
       - data
-    OverviewProviderTypeEnum:
-      type: string
-      enum:
-      - providers-overview
     OverviewService:
       type: object
       required:
@@ -10327,11 +13245,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/OverviewServiceTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - services-overview
         id: {}
         attributes:
           type: object
@@ -10359,10 +13278,6 @@ components:
           $ref: '#/components/schemas/OverviewService'
       required:
       - data
-    OverviewServiceTypeEnum:
-      type: string
-      enum:
-      - services-overview
     OverviewSeverity:
       type: object
       required:
@@ -10371,11 +13286,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/OverviewSeverityTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - findings-severity-overview
         id: {}
         attributes:
           type: object
@@ -10406,10 +13322,6 @@ components:
           $ref: '#/components/schemas/OverviewSeverity'
       required:
       - data
-    OverviewSeverityTypeEnum:
-      type: string
-      enum:
-      - findings-severity-overview
     PaginatedComplianceOverviewAttributesList:
       type: object
       properties:
@@ -10473,6 +13385,33 @@ components:
             $ref: '#/components/schemas/LighthouseConfig'
       required:
       - data
+    PaginatedLighthouseProviderConfigList:
+      type: object
+      properties:
+        data:
+          type: array
+          items:
+            $ref: '#/components/schemas/LighthouseProviderConfig'
+      required:
+      - data
+    PaginatedLighthouseProviderModelsList:
+      type: object
+      properties:
+        data:
+          type: array
+          items:
+            $ref: '#/components/schemas/LighthouseProviderModels'
+      required:
+      - data
+    PaginatedLighthouseTenantConfigList:
+      type: object
+      properties:
+        data:
+          type: array
+          items:
+            $ref: '#/components/schemas/LighthouseTenantConfig'
+      required:
+      - data
     PaginatedMembershipList:
       type: object
       properties:
@@ -10482,6 +13421,15 @@ components:
             $ref: '#/components/schemas/Membership'
       required:
       - data
+    PaginatedMuteRuleList:
+      type: object
+      properties:
+        data:
+          type: array
+          items:
+            $ref: '#/components/schemas/MuteRule'
+      required:
+      - data
     PaginatedProcessorList:
       type: object
       properties:
@@ -10563,6 +13511,15 @@ components:
             $ref: '#/components/schemas/Task'
       required:
       - data
+    PaginatedTenantApiKeyList:
+      type: object
+      properties:
+        data:
+          type: array
+          items:
+            $ref: '#/components/schemas/TenantApiKey'
+      required:
+      - data
     PaginatedTenantList:
       type: object
       properties:
@@ -10633,6 +13590,7 @@ components:
                     * `aws_security_hub` - AWS Security Hub
                     * `jira` - JIRA
                     * `slack` - Slack
+                  x-spec-enum-id: 6cfd0ff9cf4d6dcc
                   readOnly: true
                 configuration:
                   oneOf:
@@ -10668,6 +13626,12 @@ components:
                         default: false
                         description: If true, archives findings that are not present
                           in the current execution.
+                  - type: object
+                    title: JIRA
+                    description: JIRA integration does not accept any configuration
+                      in the payload. Leave it as an empty JSON object (`{}`).
+                    properties: {}
+                    additionalProperties: false
                 credentials:
                   oneOf:
                   - type: object
@@ -10708,6 +13672,24 @@ components:
                           - User_Session-1
                           - Test.Session@2
                         pattern: ^[a-zA-Z0-9=,.@_-]+$
+                  - type: object
+                    title: JIRA Credentials
+                    properties:
+                      user_mail:
+                        type: string
+                        format: email
+                        description: The email address of the JIRA user account.
+                      api_token:
+                        type: string
+                        description: The API token for authentication with JIRA. This
+                          can be generated from your Atlassian account settings.
+                      domain:
+                        type: string
+                        description: The JIRA domain/instance URL (e.g., 'your-domain.atlassian.net').
+                    required:
+                    - user_mail
+                    - api_token
+                    - domain
                   writeOnly: true
             relationships:
               type: object
@@ -10785,6 +13767,7 @@ components:
                     * `accepted` - Invitation was accepted by a user
                     * `expired` - Invitation expired after the configured time
                     * `revoked` - Invitation was revoked by a user
+                  x-spec-enum-id: 92a1c1fd12e13e25
                   readOnly: true
                 token:
                   type: string
@@ -10868,6 +13851,7 @@ components:
                   - gpt-5-mini-2025-08-07
                   - gpt-5-mini
                   type: string
+                  x-spec-enum-id: bd2108eb25b2d472
                   description: |-
                     Must be one of the supported model names
 
@@ -10898,6 +13882,167 @@ components:
                   readOnly: true
       required:
       - data
+    PatchedLighthouseProviderConfigUpdateRequest:
+      type: object
+      properties:
+        data:
+          type: object
+          required:
+          - type
+          - id
+          additionalProperties: false
+          properties:
+            type:
+              type: string
+              description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                member is used to describe resource objects that share common attributes
+                and relationships.
+              enum:
+              - lighthouse-providers
+            id:
+              type: string
+              format: uuid
+            attributes:
+              type: object
+              properties:
+                provider_type:
+                  enum:
+                  - openai
+                  - bedrock
+                  - openai_compatible
+                  type: string
+                  x-spec-enum-id: 30bc523cb9ec0e8b
+                  readOnly: true
+                  description: |-
+                    LLM provider name
+
+                    * `openai` - OpenAI
+                    * `bedrock` - AWS Bedrock
+                    * `openai_compatible` - OpenAI Compatible
+                base_url:
+                  type: string
+                  format: uri
+                  nullable: true
+                  minLength: 1
+                  description: Base URL for the LLM provider API. Required for 'openai_compatible'
+                    provider type.
+                credentials:
+                  oneOf:
+                  - type: object
+                    title: OpenAI Credentials
+                    properties:
+                      api_key:
+                        type: string
+                        description: OpenAI API key. Must start with 'sk-' followed
+                          by alphanumeric characters, hyphens, or underscores.
+                        pattern: ^sk-[\w-]+$
+                    required:
+                    - api_key
+                  - type: object
+                    title: AWS Bedrock Credentials
+                    properties:
+                      access_key_id:
+                        type: string
+                        description: AWS access key ID.
+                        pattern: ^AKIA[0-9A-Z]{16}$
+                      secret_access_key:
+                        type: string
+                        description: AWS secret access key.
+                        pattern: ^[A-Za-z0-9/+=]{40}$
+                      region:
+                        type: string
+                        description: 'AWS region identifier where Bedrock is available.
+                          Examples: us-east-1, us-west-2, eu-west-1, ap-northeast-1.'
+                        pattern: ^[a-z]{2}-[a-z]+-\d+$
+                    required:
+                    - access_key_id
+                    - secret_access_key
+                    - region
+                  - type: object
+                    title: OpenAI Compatible Credentials
+                    properties:
+                      api_key:
+                        type: string
+                        description: 'API key for OpenAI-compatible provider. The
+                          format varies by provider. Note: The ''base_url'' field
+                          (separate from credentials) is required when using this
+                          provider type.'
+                    required:
+                    - api_key
+                  writeOnly: true
+                is_active:
+                  type: boolean
+      required:
+      - data
+    PatchedLighthouseTenantConfigUpdateRequest:
+      type: object
+      properties:
+        data:
+          type: object
+          required:
+          - type
+          - id
+          additionalProperties: false
+          properties:
+            type:
+              type: string
+              description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                member is used to describe resource objects that share common attributes
+                and relationships.
+              enum:
+              - lighthouse-configurations
+            id:
+              type: string
+              format: uuid
+            attributes:
+              type: object
+              properties:
+                business_context:
+                  type: string
+                default_provider:
+                  type: string
+                  maxLength: 50
+                default_models: {}
+      required:
+      - data
+    PatchedMuteRuleUpdateRequest:
+      type: object
+      properties:
+        data:
+          type: object
+          required:
+          - type
+          - id
+          additionalProperties: false
+          properties:
+            type:
+              type: string
+              description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                member is used to describe resource objects that share common attributes
+                and relationships.
+              enum:
+              - mute-rules
+            id:
+              type: string
+              format: uuid
+            attributes:
+              type: object
+              properties:
+                name:
+                  type: string
+                  minLength: 3
+                  description: Human-readable name for this rule
+                  maxLength: 100
+                reason:
+                  type: string
+                  minLength: 3
+                  description: Reason for muting
+                  maxLength: 500
+                enabled:
+                  type: boolean
+                  description: Whether this rule is currently enabled
+      required:
+      - data
     PatchedProcessorUpdateRequest:
       type: object
       properties:
@@ -11174,6 +14319,7 @@ components:
                     * `static` - Key-value pairs
                     * `role` - Role assumption
                     * `service_account` - GCP Service Account Key
+                  x-spec-enum-id: 20c74ebcd6671497
                 secret:
                   oneOf:
                   - type: object
@@ -11262,26 +14408,47 @@ components:
                         type: string
                         description: The Azure application (client) ID for authentication
                           in Azure AD.
-                      client_secret:
-                        type: string
-                        description: The client secret associated with the application
-                          (client) ID, providing secure access.
                       tenant_id:
                         type: string
                         description: The Azure tenant ID, representing the directory
                           where the application is registered.
+                      client_secret:
+                        type: string
+                        description: The client secret associated with the application
+                          (client) ID, providing secure access.
                       user:
                         type: email
                         description: User microsoft email address.
+                        deprecated: true
                       password:
                         type: string
                         description: User password.
+                        deprecated: true
                     required:
                     - client_id
                     - client_secret
                     - tenant_id
                     - user
                     - password
+                  - type: object
+                    title: M365 Certificate Credentials
+                    properties:
+                      client_id:
+                        type: string
+                        description: The Azure application (client) ID for authentication
+                          in Azure AD.
+                      tenant_id:
+                        type: string
+                        description: The Azure tenant ID, representing the directory
+                          where the application is registered.
+                      certificate_content:
+                        type: string
+                        description: The certificate content in base64 format for
+                          certificate-based authentication.
+                    required:
+                    - client_id
+                    - tenant_id
+                    - certificate_content
                   - type: object
                     title: GCP Static Credentials
                     properties:
@@ -11346,6 +14513,62 @@ components:
                     required:
                     - github_app_id
                     - github_app_key
+                  - type: object
+                    title: IaC Repository Credentials
+                    properties:
+                      repository_url:
+                        type: string
+                        description: Repository URL to scan for IaC files.
+                      access_token:
+                        type: string
+                        description: Optional access token for private repositories.
+                    required:
+                    - repository_url
+                  - type: object
+                    title: Oracle Cloud Infrastructure (OCI) API Key Credentials
+                    properties:
+                      user:
+                        type: string
+                        description: The OCID of the user to authenticate with.
+                      fingerprint:
+                        type: string
+                        description: The fingerprint of the API signing key.
+                      key_file:
+                        type: string
+                        description: The path to the private key file for API signing.
+                          Either key_file or key_content must be provided.
+                      key_content:
+                        type: string
+                        description: The content of the private key for API signing
+                          (base64 encoded). Either key_file or key_content must be
+                          provided.
+                      tenancy:
+                        type: string
+                        description: The OCID of the tenancy.
+                      region:
+                        type: string
+                        description: The OCI region identifier (e.g., us-ashburn-1,
+                          us-phoenix-1).
+                      pass_phrase:
+                        type: string
+                        description: The passphrase for the private key, if encrypted.
+                    required:
+                    - user
+                    - fingerprint
+                    - tenancy
+                    - region
+                  - type: object
+                    title: MongoDB Atlas API Key
+                    properties:
+                      atlas_public_key:
+                        type: string
+                        description: MongoDB Atlas API public key.
+                      atlas_private_key:
+                        type: string
+                        description: MongoDB Atlas API private key.
+                    required:
+                    - atlas_public_key
+                    - atlas_private_key
                   writeOnly: true
               required:
               - secret
@@ -11403,6 +14626,8 @@ components:
                 alias:
                   type: string
                   nullable: true
+                  description: Human readable name to identify the provider, e.g.
+                    'Production AWS Account', 'Dev Environment'
                   maxLength: 100
                   minLength: 3
       required:
@@ -11658,6 +14883,85 @@ components:
                   minLength: 3
       required:
       - data
+    PatchedTenantApiKeyUpdateRequest:
+      type: object
+      properties:
+        data:
+          type: object
+          required:
+          - type
+          - id
+          additionalProperties: false
+          properties:
+            type:
+              type: string
+              description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                member is used to describe resource objects that share common attributes
+                and relationships.
+              enum:
+              - api-keys
+            id:
+              type: string
+              format: uuid
+            attributes:
+              type: object
+              properties:
+                name:
+                  type: string
+                  minLength: 3
+                  maxLength: 100
+                prefix:
+                  type: string
+                  readOnly: true
+                  minLength: 1
+                  description: Unique prefix to identify the API key
+                expires_at:
+                  type: string
+                  format: date-time
+                  readOnly: true
+                inserted_at:
+                  type: string
+                  format: date-time
+                  readOnly: true
+                last_used_at:
+                  type: string
+                  format: date-time
+                  readOnly: true
+                  nullable: true
+                  description: Last time this API key was used for authentication
+              required:
+              - name
+            relationships:
+              type: object
+              properties:
+                entity:
+                  type: object
+                  properties:
+                    data:
+                      type: object
+                      properties:
+                        id:
+                          type: string
+                          format: uuid
+                        type:
+                          type: string
+                          enum:
+                          - users
+                          title: Resource Type Name
+                          description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                            member is used to describe resource objects that share
+                            common attributes and relationships.
+                      required:
+                      - id
+                      - type
+                  required:
+                  - data
+                  description: The identifier of the related object.
+                  title: Resource Identifier
+                  readOnly: true
+                  nullable: true
+      required:
+      - data
     PatchedTenantRequest:
       type: object
       properties:
@@ -11806,11 +15110,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type552Enum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - processors
         id:
           type: string
           format: uuid
@@ -11830,6 +15135,7 @@ components:
               - mutelist
               type: string
               description: '* `mutelist` - Mutelist'
+              x-spec-enum-id: 53cda4a99fe3d655
             configuration:
               oneOf:
               - type: object
@@ -11907,11 +15213,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type552Enum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - processors
         attributes:
           type: object
           properties:
@@ -11928,6 +15235,7 @@ components:
               - mutelist
               type: string
               description: '* `mutelist` - Mutelist'
+              x-spec-enum-id: 53cda4a99fe3d655
             configuration:
               oneOf:
               - type: object
@@ -12030,6 +15338,7 @@ components:
                   - mutelist
                   type: string
                   description: '* `mutelist` - Mutelist'
+                  x-spec-enum-id: 53cda4a99fe3d655
                 configuration:
                   oneOf:
                   - type: object
@@ -12124,11 +15433,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type552Enum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - processors
         id: {}
         attributes:
           type: object
@@ -12225,11 +15535,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type227Enum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - providers
         id:
           type: string
           format: uuid
@@ -12252,6 +15563,9 @@ components:
               - kubernetes
               - m365
               - github
+              - mongodbatlas
+              - iac
+              - oraclecloud
               type: string
               description: |-
                 * `aws` - AWS
@@ -12260,6 +15574,10 @@ components:
                 * `kubernetes` - Kubernetes
                 * `m365` - M365
                 * `github` - GitHub
+                * `mongodbatlas` - MongoDB Atlas
+                * `iac` - IaC
+                * `oraclecloud` - Oracle Cloud Infrastructure
+              x-spec-enum-id: eca8c51e6bd28935
             uid:
               type: string
               title: Unique identifier for the provider, set by the provider
@@ -12347,17 +15665,20 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type227Enum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - providers
         attributes:
           type: object
           properties:
             alias:
               type: string
               nullable: true
+              description: Human readable name to identify the provider, e.g. 'Production
+                AWS Account', 'Dev Environment'
               maxLength: 100
               minLength: 3
             provider:
@@ -12368,17 +15689,28 @@ components:
               - kubernetes
               - m365
               - github
+              - mongodbatlas
+              - iac
+              - oraclecloud
               type: string
+              x-spec-enum-id: eca8c51e6bd28935
               description: |-
+                Type of provider to create.
+
                 * `aws` - AWS
                 * `azure` - Azure
                 * `gcp` - GCP
                 * `kubernetes` - Kubernetes
                 * `m365` - M365
                 * `github` - GitHub
+                * `mongodbatlas` - MongoDB Atlas
+                * `iac` - IaC
+                * `oraclecloud` - Oracle Cloud Infrastructure
             uid:
               type: string
               title: Unique identifier for the provider, set by the provider
+              description: Unique identifier for the provider, set by the provider,
+                e.g. AWS account ID, Azure subscription ID, GCP project ID, etc.
               maxLength: 250
               minLength: 3
           required:
@@ -12405,6 +15737,8 @@ components:
                 alias:
                   type: string
                   nullable: true
+                  description: Human readable name to identify the provider, e.g.
+                    'Production AWS Account', 'Dev Environment'
                   maxLength: 100
                   minLength: 3
                 provider:
@@ -12415,18 +15749,29 @@ components:
                   - kubernetes
                   - m365
                   - github
+                  - mongodbatlas
+                  - iac
+                  - oraclecloud
                   type: string
+                  x-spec-enum-id: eca8c51e6bd28935
                   description: |-
+                    Type of provider to create.
+
                     * `aws` - AWS
                     * `azure` - Azure
                     * `gcp` - GCP
                     * `kubernetes` - Kubernetes
                     * `m365` - M365
                     * `github` - GitHub
+                    * `mongodbatlas` - MongoDB Atlas
+                    * `iac` - IaC
+                    * `oraclecloud` - Oracle Cloud Infrastructure
                 uid:
                   type: string
                   minLength: 3
                   title: Unique identifier for the provider, set by the provider
+                  description: Unique identifier for the provider, set by the provider,
+                    e.g. AWS account ID, Azure subscription ID, GCP project ID, etc.
                   maxLength: 250
               required:
               - uid
@@ -12447,11 +15792,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type34dEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - provider-groups
         id:
           type: string
           format: uuid
@@ -12537,11 +15883,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type34dEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - provider-groups
         attributes:
           type: object
           properties:
@@ -12828,11 +16175,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type049Enum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - provider-secrets
         id:
           type: string
           format: uuid
@@ -12862,6 +16210,7 @@ components:
                 * `static` - Key-value pairs
                 * `role` - Role assumption
                 * `service_account` - GCP Service Account Key
+              x-spec-enum-id: 20c74ebcd6671497
           required:
           - secret_type
         relationships:
@@ -12900,11 +16249,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type049Enum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - provider-secrets
         attributes:
           type: object
           properties:
@@ -12931,6 +16281,7 @@ components:
                 * `static` - Key-value pairs
                 * `role` - Role assumption
                 * `service_account` - GCP Service Account Key
+              x-spec-enum-id: 20c74ebcd6671497
             secret:
               oneOf:
               - type: object
@@ -13018,26 +16369,47 @@ components:
                     type: string
                     description: The Azure application (client) ID for authentication
                       in Azure AD.
-                  client_secret:
-                    type: string
-                    description: The client secret associated with the application
-                      (client) ID, providing secure access.
                   tenant_id:
                     type: string
                     description: The Azure tenant ID, representing the directory where
                       the application is registered.
+                  client_secret:
+                    type: string
+                    description: The client secret associated with the application
+                      (client) ID, providing secure access.
                   user:
                     type: email
                     description: User microsoft email address.
+                    deprecated: true
                   password:
                     type: string
                     description: User password.
+                    deprecated: true
                 required:
                 - client_id
                 - client_secret
                 - tenant_id
                 - user
                 - password
+              - type: object
+                title: M365 Certificate Credentials
+                properties:
+                  client_id:
+                    type: string
+                    description: The Azure application (client) ID for authentication
+                      in Azure AD.
+                  tenant_id:
+                    type: string
+                    description: The Azure tenant ID, representing the directory where
+                      the application is registered.
+                  certificate_content:
+                    type: string
+                    description: The certificate content in base64 format for certificate-based
+                      authentication.
+                required:
+                - client_id
+                - tenant_id
+                - certificate_content
               - type: object
                 title: GCP Static Credentials
                 properties:
@@ -13102,6 +16474,60 @@ components:
                 required:
                 - github_app_id
                 - github_app_key
+              - type: object
+                title: IaC Repository Credentials
+                properties:
+                  repository_url:
+                    type: string
+                    description: Repository URL to scan for IaC files.
+                  access_token:
+                    type: string
+                    description: Optional access token for private repositories.
+                required:
+                - repository_url
+              - type: object
+                title: Oracle Cloud Infrastructure (OCI) API Key Credentials
+                properties:
+                  user:
+                    type: string
+                    description: The OCID of the user to authenticate with.
+                  fingerprint:
+                    type: string
+                    description: The fingerprint of the API signing key.
+                  key_file:
+                    type: string
+                    description: The path to the private key file for API signing.
+                      Either key_file or key_content must be provided.
+                  key_content:
+                    type: string
+                    description: The content of the private key for API signing (base64
+                      encoded). Either key_file or key_content must be provided.
+                  tenancy:
+                    type: string
+                    description: The OCID of the tenancy.
+                  region:
+                    type: string
+                    description: The OCI region identifier (e.g., us-ashburn-1, us-phoenix-1).
+                  pass_phrase:
+                    type: string
+                    description: The passphrase for the private key, if encrypted.
+                required:
+                - user
+                - fingerprint
+                - tenancy
+                - region
+              - type: object
+                title: MongoDB Atlas API Key
+                properties:
+                  atlas_public_key:
+                    type: string
+                    description: MongoDB Atlas API public key.
+                  atlas_private_key:
+                    type: string
+                    description: MongoDB Atlas API private key.
+                required:
+                - atlas_public_key
+                - atlas_private_key
               writeOnly: true
           required:
           - secret_type
@@ -13177,6 +16603,7 @@ components:
                     * `static` - Key-value pairs
                     * `role` - Role assumption
                     * `service_account` - GCP Service Account Key
+                  x-spec-enum-id: 20c74ebcd6671497
                 secret:
                   oneOf:
                   - type: object
@@ -13265,26 +16692,47 @@ components:
                         type: string
                         description: The Azure application (client) ID for authentication
                           in Azure AD.
-                      client_secret:
-                        type: string
-                        description: The client secret associated with the application
-                          (client) ID, providing secure access.
                       tenant_id:
                         type: string
                         description: The Azure tenant ID, representing the directory
                           where the application is registered.
+                      client_secret:
+                        type: string
+                        description: The client secret associated with the application
+                          (client) ID, providing secure access.
                       user:
                         type: email
                         description: User microsoft email address.
+                        deprecated: true
                       password:
                         type: string
                         description: User password.
+                        deprecated: true
                     required:
                     - client_id
                     - client_secret
                     - tenant_id
                     - user
                     - password
+                  - type: object
+                    title: M365 Certificate Credentials
+                    properties:
+                      client_id:
+                        type: string
+                        description: The Azure application (client) ID for authentication
+                          in Azure AD.
+                      tenant_id:
+                        type: string
+                        description: The Azure tenant ID, representing the directory
+                          where the application is registered.
+                      certificate_content:
+                        type: string
+                        description: The certificate content in base64 format for
+                          certificate-based authentication.
+                    required:
+                    - client_id
+                    - tenant_id
+                    - certificate_content
                   - type: object
                     title: GCP Static Credentials
                     properties:
@@ -13349,6 +16797,62 @@ components:
                     required:
                     - github_app_id
                     - github_app_key
+                  - type: object
+                    title: IaC Repository Credentials
+                    properties:
+                      repository_url:
+                        type: string
+                        description: Repository URL to scan for IaC files.
+                      access_token:
+                        type: string
+                        description: Optional access token for private repositories.
+                    required:
+                    - repository_url
+                  - type: object
+                    title: Oracle Cloud Infrastructure (OCI) API Key Credentials
+                    properties:
+                      user:
+                        type: string
+                        description: The OCID of the user to authenticate with.
+                      fingerprint:
+                        type: string
+                        description: The fingerprint of the API signing key.
+                      key_file:
+                        type: string
+                        description: The path to the private key file for API signing.
+                          Either key_file or key_content must be provided.
+                      key_content:
+                        type: string
+                        description: The content of the private key for API signing
+                          (base64 encoded). Either key_file or key_content must be
+                          provided.
+                      tenancy:
+                        type: string
+                        description: The OCID of the tenancy.
+                      region:
+                        type: string
+                        description: The OCI region identifier (e.g., us-ashburn-1,
+                          us-phoenix-1).
+                      pass_phrase:
+                        type: string
+                        description: The passphrase for the private key, if encrypted.
+                    required:
+                    - user
+                    - fingerprint
+                    - tenancy
+                    - region
+                  - type: object
+                    title: MongoDB Atlas API Key
+                    properties:
+                      atlas_public_key:
+                        type: string
+                        description: MongoDB Atlas API public key.
+                      atlas_private_key:
+                        type: string
+                        description: MongoDB Atlas API private key.
+                    required:
+                    - atlas_public_key
+                    - atlas_private_key
                   writeOnly: true
               required:
               - secret_type
@@ -13406,11 +16910,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type049Enum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - provider-secrets
         id:
           type: string
           format: uuid
@@ -13440,6 +16945,7 @@ components:
                 * `static` - Key-value pairs
                 * `role` - Role assumption
                 * `service_account` - GCP Service Account Key
+              x-spec-enum-id: 20c74ebcd6671497
             secret:
               oneOf:
               - type: object
@@ -13527,26 +17033,47 @@ components:
                     type: string
                     description: The Azure application (client) ID for authentication
                       in Azure AD.
-                  client_secret:
-                    type: string
-                    description: The client secret associated with the application
-                      (client) ID, providing secure access.
                   tenant_id:
                     type: string
                     description: The Azure tenant ID, representing the directory where
                       the application is registered.
+                  client_secret:
+                    type: string
+                    description: The client secret associated with the application
+                      (client) ID, providing secure access.
                   user:
                     type: email
                     description: User microsoft email address.
+                    deprecated: true
                   password:
                     type: string
                     description: User password.
+                    deprecated: true
                 required:
                 - client_id
                 - client_secret
                 - tenant_id
                 - user
                 - password
+              - type: object
+                title: M365 Certificate Credentials
+                properties:
+                  client_id:
+                    type: string
+                    description: The Azure application (client) ID for authentication
+                      in Azure AD.
+                  tenant_id:
+                    type: string
+                    description: The Azure tenant ID, representing the directory where
+                      the application is registered.
+                  certificate_content:
+                    type: string
+                    description: The certificate content in base64 format for certificate-based
+                      authentication.
+                required:
+                - client_id
+                - tenant_id
+                - certificate_content
               - type: object
                 title: GCP Static Credentials
                 properties:
@@ -13611,6 +17138,60 @@ components:
                 required:
                 - github_app_id
                 - github_app_key
+              - type: object
+                title: IaC Repository Credentials
+                properties:
+                  repository_url:
+                    type: string
+                    description: Repository URL to scan for IaC files.
+                  access_token:
+                    type: string
+                    description: Optional access token for private repositories.
+                required:
+                - repository_url
+              - type: object
+                title: Oracle Cloud Infrastructure (OCI) API Key Credentials
+                properties:
+                  user:
+                    type: string
+                    description: The OCID of the user to authenticate with.
+                  fingerprint:
+                    type: string
+                    description: The fingerprint of the API signing key.
+                  key_file:
+                    type: string
+                    description: The path to the private key file for API signing.
+                      Either key_file or key_content must be provided.
+                  key_content:
+                    type: string
+                    description: The content of the private key for API signing (base64
+                      encoded). Either key_file or key_content must be provided.
+                  tenancy:
+                    type: string
+                    description: The OCID of the tenancy.
+                  region:
+                    type: string
+                    description: The OCI region identifier (e.g., us-ashburn-1, us-phoenix-1).
+                  pass_phrase:
+                    type: string
+                    description: The passphrase for the private key, if encrypted.
+                required:
+                - user
+                - fingerprint
+                - tenancy
+                - region
+              - type: object
+                title: MongoDB Atlas API Key
+                properties:
+                  atlas_public_key:
+                    type: string
+                    description: MongoDB Atlas API public key.
+                  atlas_private_key:
+                    type: string
+                    description: MongoDB Atlas API private key.
+                required:
+                - atlas_public_key
+                - atlas_private_key
               writeOnly: true
           required:
           - secret
@@ -13657,11 +17238,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/ResourceTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - resources
         id:
           type: string
           format: uuid
@@ -13698,6 +17280,18 @@ components:
             failed_findings_count:
               type: integer
               readOnly: true
+            metadata:
+              type: string
+              readOnly: true
+              nullable: true
+            details:
+              type: string
+              readOnly: true
+              nullable: true
+            partition:
+              type: string
+              readOnly: true
+              nullable: true
             type:
               type: string
               readOnly: true
@@ -13767,11 +17361,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/ResourceMetadataTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - resources-metadata
         id: {}
         attributes:
           type: object
@@ -13799,10 +17394,6 @@ components:
           $ref: '#/components/schemas/ResourceMetadata'
       required:
       - data
-    ResourceMetadataTypeEnum:
-      type: string
-      enum:
-      - resources-metadata
     ResourceResponse:
       type: object
       properties:
@@ -13810,10 +17401,6 @@ components:
           $ref: '#/components/schemas/Resource'
       required:
       - data
-    ResourceTypeEnum:
-      type: string
-      enum:
-      - resources
     Role:
       type: object
       required:
@@ -13822,11 +17409,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type6bbEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - roles
         id:
           type: string
           format: uuid
@@ -13956,11 +17544,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type6bbEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - roles
         attributes:
           type: object
           properties:
@@ -14299,11 +17888,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/SAMLConfigurationTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - saml-configurations
         id:
           type: string
           format: uuid
@@ -14378,10 +17968,6 @@ components:
           $ref: '#/components/schemas/SAMLConfiguration'
       required:
       - data
-    SAMLConfigurationTypeEnum:
-      type: string
-      enum:
-      - saml-configurations
     Scan:
       type: object
       required:
@@ -14390,11 +17976,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/TypeE53Enum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - scans
         id:
           type: string
           format: uuid
@@ -14414,6 +18001,7 @@ components:
               description: |-
                 * `scheduled` - Scheduled
                 * `manual` - Manual
+              x-spec-enum-id: 2e52c981d1c89bdf
               readOnly: true
             state:
               enum:
@@ -14431,6 +18019,7 @@ components:
                 * `completed` - Completed
                 * `failed` - Failed
                 * `cancelled` - Cancelled
+              x-spec-enum-id: d38ba07264e1ed34
               readOnly: true
             unique_resource_count:
               type: integer
@@ -14614,11 +18203,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/TypeE53Enum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - scans
         id:
           type: string
           format: uuid
@@ -14667,7 +18257,7 @@ components:
       type: object
       properties:
         data:
-          $ref: '#/components/schemas/ProviderGroup'
+          $ref: '#/components/schemas/MuteRule'
       required:
       - data
     Task:
@@ -14678,11 +18268,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/TaskTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - tasks
         id:
           type: string
           format: uuid
@@ -14723,10 +18314,6 @@ components:
           $ref: '#/components/schemas/Task'
       required:
       - data
-    TaskTypeEnum:
-      type: string
-      enum:
-      - tasks
     Tenant:
       type: object
       required:
@@ -14735,11 +18322,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/TenantTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - tenants
         id:
           type: string
           format: uuid
@@ -14783,6 +18371,333 @@ components:
               description: A related resource object from type memberships
               title: memberships
               readOnly: true
+    TenantApiKey:
+      type: object
+      required:
+      - type
+      - id
+      additionalProperties: false
+      properties:
+        type:
+          type: string
+          description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+            member is used to describe resource objects that share common attributes
+            and relationships.
+          enum:
+          - api-keys
+        id:
+          type: string
+          format: uuid
+        attributes:
+          type: object
+          properties:
+            name:
+              type: string
+              maxLength: 100
+              minLength: 3
+            prefix:
+              type: string
+              readOnly: true
+              description: Unique prefix to identify the API key
+            expires_at:
+              type: string
+              format: date-time
+              readOnly: true
+            revoked:
+              type: boolean
+              description: If the API key is revoked, entities cannot use it anymore.
+                (This cannot be undone.)
+            inserted_at:
+              type: string
+              format: date-time
+              readOnly: true
+            last_used_at:
+              type: string
+              format: date-time
+              nullable: true
+              description: Last time this API key was used for authentication
+          required:
+          - name
+        relationships:
+          type: object
+          properties:
+            entity:
+              type: object
+              properties:
+                data:
+                  type: object
+                  properties:
+                    id:
+                      type: string
+                      format: uuid
+                    type:
+                      type: string
+                      enum:
+                      - users
+                      title: Resource Type Name
+                      description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                        member is used to describe resource objects that share common
+                        attributes and relationships.
+                  required:
+                  - id
+                  - type
+              required:
+              - data
+              description: The identifier of the related object.
+              title: Resource Identifier
+              nullable: true
+    TenantApiKeyCreate:
+      type: object
+      required:
+      - type
+      additionalProperties: false
+      properties:
+        type:
+          type: string
+          description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+            member is used to describe resource objects that share common attributes
+            and relationships.
+          enum:
+          - api-keys
+        attributes:
+          type: object
+          properties:
+            name:
+              type: string
+              maxLength: 100
+              minLength: 3
+            prefix:
+              type: string
+              readOnly: true
+              description: Unique prefix to identify the API key
+            expires_at:
+              type: string
+              format: date-time
+            revoked:
+              type: boolean
+              readOnly: true
+              description: If the API key is revoked, entities cannot use it anymore.
+                (This cannot be undone.)
+            inserted_at:
+              type: string
+              format: date-time
+              readOnly: true
+            last_used_at:
+              type: string
+              format: date-time
+              readOnly: true
+              nullable: true
+              description: Last time this API key was used for authentication
+            api_key:
+              type: string
+              readOnly: true
+          required:
+          - name
+        relationships:
+          type: object
+          properties:
+            entity:
+              type: object
+              properties:
+                data:
+                  type: object
+                  properties:
+                    id:
+                      type: string
+                      format: uuid
+                    type:
+                      type: string
+                      enum:
+                      - users
+                      title: Resource Type Name
+                      description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                        member is used to describe resource objects that share common
+                        attributes and relationships.
+                  required:
+                  - id
+                  - type
+              required:
+              - data
+              description: The identifier of the related object.
+              title: Resource Identifier
+              readOnly: true
+              nullable: true
+    TenantApiKeyCreateRequest:
+      type: object
+      properties:
+        data:
+          type: object
+          required:
+          - type
+          additionalProperties: false
+          properties:
+            type:
+              type: string
+              description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                member is used to describe resource objects that share common attributes
+                and relationships.
+              enum:
+              - api-keys
+            attributes:
+              type: object
+              properties:
+                name:
+                  type: string
+                  minLength: 3
+                  maxLength: 100
+                prefix:
+                  type: string
+                  readOnly: true
+                  minLength: 1
+                  description: Unique prefix to identify the API key
+                expires_at:
+                  type: string
+                  format: date-time
+                revoked:
+                  type: boolean
+                  readOnly: true
+                  description: If the API key is revoked, entities cannot use it anymore.
+                    (This cannot be undone.)
+                inserted_at:
+                  type: string
+                  format: date-time
+                  readOnly: true
+                last_used_at:
+                  type: string
+                  format: date-time
+                  readOnly: true
+                  nullable: true
+                  description: Last time this API key was used for authentication
+                api_key:
+                  type: string
+                  readOnly: true
+              required:
+              - name
+            relationships:
+              type: object
+              properties:
+                entity:
+                  type: object
+                  properties:
+                    data:
+                      type: object
+                      properties:
+                        id:
+                          type: string
+                          format: uuid
+                        type:
+                          type: string
+                          enum:
+                          - users
+                          title: Resource Type Name
+                          description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                            member is used to describe resource objects that share
+                            common attributes and relationships.
+                      required:
+                      - id
+                      - type
+                  required:
+                  - data
+                  description: The identifier of the related object.
+                  title: Resource Identifier
+                  readOnly: true
+                  nullable: true
+      required:
+      - data
+    TenantApiKeyCreateResponse:
+      type: object
+      properties:
+        data:
+          $ref: '#/components/schemas/TenantApiKeyCreate'
+      required:
+      - data
+    TenantApiKeyResponse:
+      type: object
+      properties:
+        data:
+          $ref: '#/components/schemas/TenantApiKey'
+      required:
+      - data
+    TenantApiKeyUpdate:
+      type: object
+      required:
+      - type
+      - id
+      additionalProperties: false
+      properties:
+        type:
+          type: string
+          description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+            member is used to describe resource objects that share common attributes
+            and relationships.
+          enum:
+          - api-keys
+        id:
+          type: string
+          format: uuid
+        attributes:
+          type: object
+          properties:
+            name:
+              type: string
+              maxLength: 100
+              minLength: 3
+            prefix:
+              type: string
+              readOnly: true
+              description: Unique prefix to identify the API key
+            expires_at:
+              type: string
+              format: date-time
+              readOnly: true
+            inserted_at:
+              type: string
+              format: date-time
+              readOnly: true
+            last_used_at:
+              type: string
+              format: date-time
+              readOnly: true
+              nullable: true
+              description: Last time this API key was used for authentication
+          required:
+          - name
+        relationships:
+          type: object
+          properties:
+            entity:
+              type: object
+              properties:
+                data:
+                  type: object
+                  properties:
+                    id:
+                      type: string
+                      format: uuid
+                    type:
+                      type: string
+                      enum:
+                      - users
+                      title: Resource Type Name
+                      description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                        member is used to describe resource objects that share common
+                        attributes and relationships.
+                  required:
+                  - id
+                  - type
+              required:
+              - data
+              description: The identifier of the related object.
+              title: Resource Identifier
+              readOnly: true
+              nullable: true
+    TenantApiKeyUpdateResponse:
+      type: object
+      properties:
+        data:
+          $ref: '#/components/schemas/TenantApiKeyUpdate'
+      required:
+      - data
     TenantRequest:
       type: object
       properties:
@@ -14849,10 +18764,143 @@ components:
           $ref: '#/components/schemas/Tenant'
       required:
       - data
-    TenantTypeEnum:
-      type: string
-      enum:
-      - tenants
+    ThreatScoreSnapshot:
+      type: object
+      required:
+      - type
+      - id
+      additionalProperties: false
+      properties:
+        type:
+          type: string
+          description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+            member is used to describe resource objects that share common attributes
+            and relationships.
+          enum:
+          - threatscore-snapshots
+        id: {}
+        attributes:
+          type: object
+          properties:
+            id:
+              type: string
+              readOnly: true
+            inserted_at:
+              type: string
+              format: date-time
+              readOnly: true
+            compliance_id:
+              type: string
+              readOnly: true
+              description: Compliance framework ID (e.g., 'prowler_threatscore_aws')
+            overall_score:
+              type: string
+              format: decimal
+              pattern: ^-?\d{0,3}(?:\.\d{0,2})?$
+              readOnly: true
+              description: Overall ThreatScore percentage (0-100)
+            score_delta:
+              type: string
+              format: decimal
+              pattern: ^-?\d{0,3}(?:\.\d{0,2})?$
+              readOnly: true
+              nullable: true
+              description: Score change compared to previous snapshot (positive =
+                improvement)
+            section_scores:
+              readOnly: true
+              description: ThreatScore breakdown by section
+            critical_requirements:
+              readOnly: true
+              description: List of critical failed requirements (risk >= 4)
+            total_requirements:
+              type: integer
+              readOnly: true
+              description: Total number of requirements evaluated
+            passed_requirements:
+              type: integer
+              readOnly: true
+              description: Number of requirements with PASS status
+            failed_requirements:
+              type: integer
+              readOnly: true
+              description: Number of requirements with FAIL status
+            manual_requirements:
+              type: integer
+              readOnly: true
+              description: Number of requirements with MANUAL status
+            total_findings:
+              type: integer
+              readOnly: true
+              description: Total number of findings across all requirements
+            passed_findings:
+              type: integer
+              readOnly: true
+              description: Number of findings with PASS status
+            failed_findings:
+              type: integer
+              readOnly: true
+              description: Number of findings with FAIL status
+        relationships:
+          type: object
+          properties:
+            scan:
+              type: object
+              properties:
+                data:
+                  type: object
+                  properties:
+                    id:
+                      type: string
+                      format: uuid
+                    type:
+                      type: string
+                      enum:
+                      - scans
+                      title: Resource Type Name
+                      description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                        member is used to describe resource objects that share common
+                        attributes and relationships.
+                  required:
+                  - id
+                  - type
+              required:
+              - data
+              description: The identifier of the related object.
+              title: Resource Identifier
+              readOnly: true
+            provider:
+              type: object
+              properties:
+                data:
+                  type: object
+                  properties:
+                    id:
+                      type: string
+                      format: uuid
+                    type:
+                      type: string
+                      enum:
+                      - providers
+                      title: Resource Type Name
+                      description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                        member is used to describe resource objects that share common
+                        attributes and relationships.
+                  required:
+                  - id
+                  - type
+              required:
+              - data
+              description: The identifier of the related object.
+              title: Resource Identifier
+              readOnly: true
+    ThreatScoreSnapshotResponse:
+      type: object
+      properties:
+        data:
+          $ref: '#/components/schemas/ThreatScoreSnapshot'
+      required:
+      - data
     Token:
       type: object
       required:
@@ -14860,11 +18908,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/TokenTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - tokens
         attributes:
           type: object
           properties:
@@ -14896,11 +18945,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/TokenRefreshTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - tokens-refresh
         attributes:
           type: object
           properties:
@@ -14948,10 +18998,6 @@ components:
           $ref: '#/components/schemas/TokenRefresh'
       required:
       - data
-    TokenRefreshTypeEnum:
-      type: string
-      enum:
-      - tokens-refresh
     TokenRequest:
       type: object
       properties:
@@ -15012,11 +19058,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/TokenSwitchTenantTypeEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - tokens-switch-tenant
         attributes:
           type: object
           properties:
@@ -15076,54 +19123,6 @@ components:
           $ref: '#/components/schemas/TokenSwitchTenant'
       required:
       - data
-    TokenSwitchTenantTypeEnum:
-      type: string
-      enum:
-      - tokens-switch-tenant
-    TokenTypeEnum:
-      type: string
-      enum:
-      - tokens
-    Type049Enum:
-      type: string
-      enum:
-      - provider-secrets
-    Type227Enum:
-      type: string
-      enum:
-      - providers
-    Type34dEnum:
-      type: string
-      enum:
-      - provider-groups
-    Type4bfEnum:
-      type: string
-      enum:
-      - lighthouse-configurations
-    Type552Enum:
-      type: string
-      enum:
-      - processors
-    Type6bbEnum:
-      type: string
-      enum:
-      - roles
-    Type8cdEnum:
-      type: string
-      enum:
-      - users
-    TypeC82Enum:
-      type: string
-      enum:
-      - integrations
-    TypeD4dEnum:
-      type: string
-      enum:
-      - invitations
-    TypeE53Enum:
-      type: string
-      enum:
-      - scans
     User:
       type: object
       required:
@@ -15132,11 +19131,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type8cdEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - users
         id:
           type: string
           format: uuid
@@ -15169,59 +19169,49 @@ components:
               type: object
               properties:
                 data:
-                  type: array
-                  items:
-                    type: object
-                    properties:
-                      id:
-                        type: string
-                        format: uuid
-                        title: Resource Identifier
-                        description: The identifier of the related object.
-                      type:
-                        type: string
-                        enum:
-                        - memberships
-                        title: Resource Type Name
-                        description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
-                          member is used to describe resource objects that share common
-                          attributes and relationships.
-                    required:
-                    - id
-                    - type
+                  type: object
+                  properties:
+                    id:
+                      type: string
+                    type:
+                      type: string
+                      enum:
+                      - memberships
+                      title: Resource Type Name
+                      description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                        member is used to describe resource objects that share common
+                        attributes and relationships.
+                  required:
+                  - id
+                  - type
               required:
               - data
-              description: A related resource object from type memberships
-              title: memberships
+              description: The identifier of the related object.
+              title: Resource Identifier
               readOnly: true
             roles:
               type: object
               properties:
                 data:
-                  type: array
-                  items:
-                    type: object
-                    properties:
-                      id:
-                        type: string
-                        format: uuid
-                        title: Resource Identifier
-                        description: The identifier of the related object.
-                      type:
-                        type: string
-                        enum:
-                        - roles
-                        title: Resource Type Name
-                        description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
-                          member is used to describe resource objects that share common
-                          attributes and relationships.
-                    required:
-                    - id
-                    - type
+                  type: object
+                  properties:
+                    id:
+                      type: string
+                    type:
+                      type: string
+                      enum:
+                      - roles
+                      title: Resource Type Name
+                      description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+                        member is used to describe resource objects that share common
+                        attributes and relationships.
+                  required:
+                  - id
+                  - type
               required:
               - data
-              description: A related resource object from type roles
-              title: roles
+              description: The identifier of the related object.
+              title: Resource Identifier
               readOnly: true
     UserCreate:
       type: object
@@ -15230,11 +19220,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type8cdEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - users
         attributes:
           type: object
           properties:
@@ -15348,11 +19339,12 @@ components:
       additionalProperties: false
       properties:
         type:
-          allOf:
-          - $ref: '#/components/schemas/Type8cdEnum'
+          type: string
           description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
             member is used to describe resource objects that share common attributes
             and relationships.
+          enum:
+          - users
         id:
           type: string
           format: uuid
@@ -15385,10 +19377,12 @@ components:
       required:
       - data
   securitySchemes:
-    jwtAuth:
+    JWT or API Key:
       type: http
       scheme: bearer
       bearerFormat: JWT
+      description: Supports both JWT Bearer tokens and API Key authentication. Use
+        `Bearer ` for JWT or `Api-Key ` for API keys.
 tags:
 - name: User
   description: Endpoints for managing user accounts.
@@ -15400,35 +19394,51 @@ tags:
 - name: Invitation
   description: Endpoints for tenant invitations management, allowing retrieval and
     filtering of invitations, creating new invitations, accepting and revoking them.
+- name: Role
+  description: Endpoints for managing RBAC roles within tenants, allowing creation,
+    retrieval, updating, and deletion of role configurations and permissions.
 - name: Provider
   description: Endpoints for managing providers (AWS, GCP, Azure, etc...).
 - name: Provider Group
   description: Endpoints for managing provider groups.
+- name: Task
+  description: Endpoints for task management, allowing retrieval of task status and
+    revoking tasks that have not started.
 - name: Scan
   description: Endpoints for triggering manual scans and viewing scan results.
+- name: Schedule
+  description: Endpoints for managing scan schedules, allowing configuration of automated
+    scans with different scheduling options.
 - name: Resource
   description: Endpoints for managing resources discovered by scans, allowing retrieval
     and filtering of resource information.
 - name: Finding
   description: Endpoints for managing findings, allowing retrieval and filtering of
     findings that result from scans.
-- name: Overview
-  description: Endpoints for retrieving aggregated summaries of resources from the
-    system.
+- name: Processor
+  description: Endpoints for managing post-processors used to process Prowler findings,
+    including registration, configuration, and deletion of post-processing actions.
 - name: Compliance Overview
   description: Endpoints for checking the compliance overview, allowing filtering
     by scan, provider or compliance framework ID.
-- name: Task
-  description: Endpoints for task management, allowing retrieval of task status and
-    revoking tasks that have not started.
+- name: Overview
+  description: Endpoints for retrieving aggregated summaries of resources from the
+    system.
 - name: Integration
   description: Endpoints for managing third-party integrations, including registration,
     configuration, retrieval, and deletion of integrations such as S3, JIRA, or other
     services.
-- name: Lighthouse
-  description: Endpoints for managing Lighthouse configurations, including creation,
+- name: Lighthouse AI
+  description: Endpoints for managing Lighthouse AI configurations, including creation,
     retrieval, updating, and deletion of configurations such as OpenAI keys, models,
     and business context.
-- name: Processor
-  description: Endpoints for managing post-processors used to process Prowler findings,
-    including registration, configuration, and deletion of post-processing actions.
+- name: SAML
+  description: Endpoints for Single Sign-On authentication management via SAML for
+    seamless user authentication.
+- name: API Keys
+  description: Endpoints for API keys management. These can be used as an alternative
+    to JWT authorization.
+- name: Mute Rules
+  description: Endpoints for simple mute rules management. These can be used as an
+    alternative to the Mutelist Processor if you need to mute specific findings across
+    your tenant with a specific reason.
diff --git a/api/src/backend/api/tests/integration/test_authentication.py b/api/src/backend/api/tests/integration/test_authentication.py
index 24d8e16f76..2abf725124 100644
--- a/api/src/backend/api/tests/integration/test_authentication.py
+++ b/api/src/backend/api/tests/integration/test_authentication.py
@@ -1,9 +1,14 @@
+import time
+from datetime import datetime, timedelta, timezone
+from uuid import uuid4
+
 import pytest
 from conftest import TEST_PASSWORD, get_api_tokens, get_authorization_header
 from django.urls import reverse
+from drf_simple_apikey.crypto import get_crypto
 from rest_framework.test import APIClient
 
-from api.models import Membership, User
+from api.models import Membership, Role, TenantAPIKey, User, UserRoleRelationship
 
 
 @pytest.mark.django_db
@@ -298,3 +303,1204 @@ class TestTokenSwitchTenant:
         assert invalid_tenant_response.json()["errors"][0]["detail"] == (
             "Tenant does not exist or user is not a " "member."
         )
+
+
+@pytest.mark.django_db
+class TestAPIKeyAuthentication:
+    def test_successful_authentication_with_api_key(
+        self, create_test_user, tenants_fixture, api_keys_fixture
+    ):
+        """Verify API key can authenticate and access protected endpoints."""
+        client = APIClient()
+        api_key = api_keys_fixture[0]
+
+        # Use API key to authenticate and access protected endpoint
+        api_key_headers = get_api_key_header(api_key._raw_key)
+        response = client.get(reverse("provider-list"), headers=api_key_headers)
+
+        assert response.status_code == 200
+        assert "data" in response.json()
+
+    def test_api_key_one_time_display_on_creation(
+        self, create_test_user_rbac, tenants_fixture
+    ):
+        """Verify full key only returned on creation, subsequent retrieval shows prefix only."""
+        client = APIClient()
+
+        # Authenticate with JWT to create API key
+        access_token, _ = get_api_tokens(
+            client, create_test_user_rbac.email, TEST_PASSWORD
+        )
+        jwt_headers = get_authorization_header(access_token)
+
+        # Create API key
+        api_key_name = "Test One-Time Key"
+        create_response = client.post(
+            reverse("api-key-list"),
+            data={
+                "data": {
+                    "type": "api-keys",
+                    "attributes": {
+                        "name": api_key_name,
+                    },
+                }
+            },
+            format="vnd.api+json",
+            headers=jwt_headers,
+        )
+
+        assert create_response.status_code == 201
+        created_data = create_response.json()["data"]
+        api_key_id = created_data["id"]
+
+        # Verify full key is present in creation response
+        assert "api_key" in created_data["attributes"]
+        full_key = created_data["attributes"]["api_key"]
+        assert full_key.startswith("pk_")
+        assert "." in full_key
+
+        # Retrieve the same API key
+        retrieve_response = client.get(
+            reverse("api-key-detail", kwargs={"pk": api_key_id}),
+            headers=jwt_headers,
+        )
+
+        assert retrieve_response.status_code == 200
+        retrieved_data = retrieve_response.json()["data"]
+
+        # Verify full key is NOT present in retrieval response
+        assert "api_key" not in retrieved_data["attributes"]
+        # Only prefix should be visible
+        assert "prefix" in retrieved_data["attributes"]
+        assert retrieved_data["attributes"]["prefix"].startswith("pk_")
+
+    def test_last_used_at_tracking(
+        self, create_test_user, tenants_fixture, api_keys_fixture
+    ):
+        """Verify last_used_at timestamp updates on each authentication."""
+        client = APIClient()
+        api_key = api_keys_fixture[0]
+
+        # Verify initially last_used_at is None
+        assert api_key.last_used_at is None
+
+        # Use API key to authenticate
+        api_key_headers = get_api_key_header(api_key._raw_key)
+        first_response = client.get(reverse("provider-list"), headers=api_key_headers)
+        assert first_response.status_code == 200
+
+        # Reload from database and check last_used_at is set
+        api_key.refresh_from_db()
+        first_used_at = api_key.last_used_at
+        assert first_used_at is not None
+
+        # Use the same key again after a small delay
+        time.sleep(0.1)
+
+        second_response = client.get(reverse("provider-list"), headers=api_key_headers)
+        assert second_response.status_code == 200
+
+        # Reload and verify last_used_at was updated
+        api_key.refresh_from_db()
+        second_used_at = api_key.last_used_at
+        assert second_used_at is not None
+        assert second_used_at > first_used_at
+
+
+@pytest.mark.django_db
+class TestAPIKeyErrors:
+    def test_invalid_api_key_format_missing_separator(
+        self, create_test_user, tenants_fixture
+    ):
+        """Malformed key without . separator."""
+        client = APIClient()
+
+        # Create malformed key without separator
+        malformed_key = "pk_12345678abcdefgh"
+        api_key_headers = get_api_key_header(malformed_key)
+
+        response = client.get(reverse("provider-list"), headers=api_key_headers)
+
+        assert response.status_code == 401
+        assert "Invalid API Key." in response.json()["errors"][0]["detail"]
+
+    def test_invalid_api_key_format_malformed(self, create_test_user, tenants_fixture):
+        """Completely invalid format."""
+        client = APIClient()
+
+        # Various malformed keys
+        malformed_keys = [
+            "invalid_key",
+            "Bearer some_token",
+            "",
+            "pk_.",
+            ".encrypted_part",
+        ]
+
+        for malformed_key in malformed_keys:
+            api_key_headers = get_api_key_header(malformed_key)
+            response = client.get(reverse("provider-list"), headers=api_key_headers)
+
+            assert response.status_code == 401
+            assert "Invalid API Key." in response.json()["errors"][0]["detail"]
+
+    def test_expired_api_key_rejected(self, create_test_user, tenants_fixture):
+        """Key past expiry date returns 401."""
+        client = APIClient()
+
+        # Create API key with past expiry date
+        expired_key, raw_key = TenantAPIKey.objects.create_api_key(
+            name="Expired Key",
+            tenant_id=tenants_fixture[0].id,
+            entity=create_test_user,
+            expiry_date=datetime.now(timezone.utc) - timedelta(days=1),
+        )
+
+        api_key_headers = get_api_key_header(raw_key)
+        response = client.get(reverse("provider-list"), headers=api_key_headers)
+
+        assert response.status_code == 401
+        assert "API Key has already expired." in response.json()["errors"][0]["detail"]
+
+    def test_revoked_api_key_rejected(
+        self, create_test_user, tenants_fixture, api_keys_fixture
+    ):
+        """Revoked key returns 401."""
+        client = APIClient()
+
+        # Use the revoked key from fixture
+        revoked_key = api_keys_fixture[2]
+        assert revoked_key.revoked is True
+
+        api_key_headers = get_api_key_header(revoked_key._raw_key)
+        response = client.get(reverse("provider-list"), headers=api_key_headers)
+
+        assert response.status_code == 401
+        assert "API Key has been revoked." in response.json()["errors"][0]["detail"]
+
+    def test_non_existent_api_key(self, create_test_user, tenants_fixture):
+        """Key UUID doesn't exist in database."""
+        client = APIClient()
+
+        # Create a valid-looking key with non-existent UUID
+        crypto = get_crypto()
+        fake_uuid = str(uuid4())
+        fake_expiry = (datetime.now(timezone.utc) + timedelta(days=30)).timestamp()
+        payload = {"_pk": fake_uuid, "_exp": fake_expiry}
+        encrypted_payload = crypto.generate(payload)
+
+        fake_key = f"pk_fakepfx.{encrypted_payload}"
+        api_key_headers = get_api_key_header(fake_key)
+
+        response = client.get(reverse("provider-list"), headers=api_key_headers)
+
+        assert response.status_code == 401
+        assert (
+            "No entity matching this api key." in response.json()["errors"][0]["detail"]
+        )
+
+    def test_corrupted_payload(self, create_test_user, tenants_fixture):
+        """Tampered/corrupted encrypted payload."""
+        client = APIClient()
+
+        # Create key with corrupted encrypted portion
+        corrupted_key = "pk_12345678.corrupted_encrypted_data_here"
+        api_key_headers = get_api_key_header(corrupted_key)
+
+        response = client.get(reverse("provider-list"), headers=api_key_headers)
+
+        assert response.status_code == 401
+        assert "Invalid API Key." in response.json()["errors"][0]["detail"]
+
+
+@pytest.mark.django_db
+class TestAPIKeyTenantIsolation:
+    def test_api_key_tenant_isolation(
+        self, create_test_user, tenants_fixture, api_keys_fixture
+    ):
+        """User in tenant A cannot use API key from tenant B."""
+        client = APIClient()
+
+        # Create a second user in a different tenant
+        second_user = User.objects.create_user(
+            name="second_user",
+            email="second_user@prowler.com",
+            password="Test_password@1",
+        )
+        second_tenant = tenants_fixture[1]
+        Membership.objects.create(user=second_user, tenant=second_tenant)
+
+        # Create and assign role to second_user
+        second_role = Role.objects.create(
+            tenant_id=second_tenant.id,
+            name="Second Tenant Role",
+            unlimited_visibility=True,
+            manage_account=True,
+        )
+        UserRoleRelationship.objects.create(
+            user=second_user,
+            role=second_role,
+            tenant_id=second_tenant.id,
+        )
+
+        # Create API key for second user in second tenant
+        second_key, raw_key = TenantAPIKey.objects.create_api_key(
+            name="Second Tenant Key",
+            tenant_id=second_tenant.id,
+            entity=second_user,
+        )
+
+        # First user's API key from first tenant
+        first_key = api_keys_fixture[0]
+        tenants_fixture[0]
+
+        # Verify both keys are from different tenants
+        assert first_key.tenant_id != second_key.tenant_id
+
+        # Each key should only access resources in its own tenant
+        # This is enforced by RLS at the database level
+        first_headers = get_api_key_header(first_key._raw_key)
+        second_headers = get_api_key_header(raw_key)
+
+        # Both should work for their respective tenants
+        first_response = client.get(reverse("provider-list"), headers=first_headers)
+        assert first_response.status_code == 200
+
+        second_response = client.get(reverse("provider-list"), headers=second_headers)
+        assert second_response.status_code == 200
+
+        # Verify tenant context is correct in each response
+        # The responses should contain only data for their respective tenants
+
+    def test_api_key_filters_by_tenant(
+        self, create_test_user, tenants_fixture, api_keys_fixture
+    ):
+        """List endpoint only shows keys for current tenant."""
+        client = APIClient()
+
+        # Create JWT token for first tenant
+        access_token, _ = get_api_tokens(client, create_test_user.email, TEST_PASSWORD)
+        jwt_headers = get_authorization_header(access_token)
+
+        # List API keys
+        list_response = client.get(reverse("api-key-list"), headers=jwt_headers)
+
+        assert list_response.status_code == 200
+        keys_data = list_response.json()["data"]
+
+        # Verify all returned keys belong to the current tenant
+        tenants_fixture[0].id
+        for key_data in keys_data:
+            # We can't directly see tenant_id in response, but all keys should be from fixtures
+            # which are created in first tenant
+            assert key_data["type"] == "api-keys"
+
+        # Count should match the number of non-revoked keys in api_keys_fixture for this tenant
+        # api_keys_fixture creates 3 keys (1 normal, 1 with expiry, 1 revoked)
+        assert len(keys_data) == 3
+
+    def test_api_key_revoked_when_user_removed_from_tenant(self, tenants_fixture):
+        """When user membership is deleted, all user's API keys for that tenant are revoked."""
+        client = APIClient()
+        tenant = tenants_fixture[0]
+
+        # Create a fresh user for this test
+        test_user = User.objects.create_user(
+            name="test_membership_removal",
+            email="membership_removal@prowler.com",
+            password=TEST_PASSWORD,
+        )
+
+        # Create membership between user and tenant
+        Membership.objects.create(
+            user=test_user,
+            tenant=tenant,
+            role=Membership.RoleChoices.OWNER,
+        )
+
+        # Create role with manage_account permission
+        role = Role.objects.create(
+            tenant_id=tenant.id,
+            name="Membership Removal Role",
+            unlimited_visibility=True,
+            manage_account=True,
+        )
+
+        # Assign role to user
+        UserRoleRelationship.objects.create(
+            user=test_user,
+            role=role,
+            tenant_id=tenant.id,
+        )
+
+        # Create API key for this user in this tenant
+        api_key, raw_key = TenantAPIKey.objects.create_api_key(
+            name="Test Key for Membership Removal",
+            tenant_id=tenant.id,
+            entity=test_user,
+        )
+
+        # Verify API key works initially
+        api_key_headers = get_api_key_header(raw_key)
+        initial_response = client.get(reverse("provider-list"), headers=api_key_headers)
+        assert initial_response.status_code == 200
+
+        # Store API key ID for later verification
+        api_key_id = api_key.id
+
+        # Remove user from tenant by deleting membership
+        Membership.objects.filter(user=test_user, tenant=tenant).delete()
+
+        # Reload API key from database
+        api_key.refresh_from_db()
+
+        # Verify API key still exists in database
+        assert TenantAPIKey.objects.filter(id=api_key_id).exists()
+
+        # Verify API key is now revoked
+        assert api_key.revoked is True
+
+        # Verify authentication with this API key now fails with 401
+        auth_response = client.get(reverse("provider-list"), headers=api_key_headers)
+        assert auth_response.status_code == 401
+
+        # Verify error message indicates revocation
+        response_json = auth_response.json()
+        assert "errors" in response_json
+        error_detail = response_json["errors"][0]["detail"]
+        assert "revoked" in error_detail.lower()
+
+
+@pytest.mark.django_db
+class TestAPIKeyLifecycle:
+    def test_create_api_key(self, create_test_user_rbac, tenants_fixture):
+        """Create via POST with name and optional expiry."""
+        client = APIClient()
+
+        # Authenticate with JWT
+        access_token, _ = get_api_tokens(
+            client, create_test_user_rbac.email, TEST_PASSWORD
+        )
+        jwt_headers = get_authorization_header(access_token)
+
+        # Create API key without expiry
+        key_name = "Test Lifecycle Key"
+        create_response = client.post(
+            reverse("api-key-list"),
+            data={
+                "data": {
+                    "type": "api-keys",
+                    "attributes": {
+                        "name": key_name,
+                    },
+                }
+            },
+            format="vnd.api+json",
+            headers=jwt_headers,
+        )
+
+        assert create_response.status_code == 201
+        created_data = create_response.json()["data"]
+
+        assert created_data["attributes"]["name"] == key_name
+        assert "api_key" in created_data["attributes"]
+        assert "prefix" in created_data["attributes"]
+        assert created_data["attributes"]["revoked"] is False
+
+        # Create API key with expiry
+        future_expiry = (datetime.now(timezone.utc) + timedelta(days=90)).isoformat()
+        create_with_expiry_response = client.post(
+            reverse("api-key-list"),
+            data={
+                "data": {
+                    "type": "api-keys",
+                    "attributes": {
+                        "name": "Key with Expiry",
+                        "expires_at": future_expiry,
+                    },
+                }
+            },
+            format="vnd.api+json",
+            headers=jwt_headers,
+        )
+
+        assert create_with_expiry_response.status_code == 201
+        expiry_data = create_with_expiry_response.json()["data"]
+        assert expiry_data["attributes"]["expires_at"] is not None
+
+    def test_update_api_key_name_only(
+        self, create_test_user, tenants_fixture, api_keys_fixture
+    ):
+        """PATCH only allows name changes."""
+        client = APIClient()
+
+        # Authenticate with JWT
+        access_token, _ = get_api_tokens(client, create_test_user.email, TEST_PASSWORD)
+        jwt_headers = get_authorization_header(access_token)
+
+        api_key = api_keys_fixture[0]
+        api_key.name
+        new_name = "Updated API Key Name"
+
+        # Update name
+        update_response = client.patch(
+            reverse("api-key-detail", kwargs={"pk": api_key.id}),
+            data={
+                "data": {
+                    "type": "api-keys",
+                    "id": str(api_key.id),
+                    "attributes": {
+                        "name": new_name,
+                    },
+                }
+            },
+            format="vnd.api+json",
+            headers=jwt_headers,
+        )
+
+        assert update_response.status_code == 200
+        updated_data = update_response.json()["data"]
+        assert updated_data["attributes"]["name"] == new_name
+
+        # Verify name was actually updated in database
+        api_key.refresh_from_db()
+        assert api_key.name == new_name
+
+        # Verify other fields remain unchanged
+        assert api_key.prefix == updated_data["attributes"]["prefix"]
+        assert api_key.revoked is False
+
+    def test_delete_api_key(self, create_test_user, tenants_fixture, api_keys_fixture):
+        """DELETE revokes key (sets revoked=True)."""
+        client = APIClient()
+
+        # Authenticate with JWT
+        access_token, _ = get_api_tokens(client, create_test_user.email, TEST_PASSWORD)
+        jwt_headers = get_authorization_header(access_token)
+
+        api_key = api_keys_fixture[1]
+        api_key_id = api_key.id
+
+        # Revoke API key using the revoke endpoint
+        revoke_response = client.delete(
+            reverse("api-key-revoke", kwargs={"pk": api_key_id}),
+            headers=jwt_headers,
+        )
+
+        assert revoke_response.status_code == 200
+
+        # Verify key still exists but is revoked
+        api_key.refresh_from_db()
+        assert api_key.revoked is True
+
+        # Verify revoked key can no longer authenticate
+        api_key_headers = get_api_key_header(api_key._raw_key)
+        auth_response = client.get(reverse("provider-list"), headers=api_key_headers)
+
+        assert auth_response.status_code == 401
+
+    def test_multiple_keys_per_user(self, create_test_user_rbac, tenants_fixture):
+        """User can have multiple active keys."""
+        client = APIClient()
+
+        # Authenticate with JWT
+        access_token, _ = get_api_tokens(
+            client, create_test_user_rbac.email, TEST_PASSWORD
+        )
+        jwt_headers = get_authorization_header(access_token)
+
+        # Create multiple API keys
+        key_names = ["Key One", "Key Two", "Key Three"]
+        created_keys = []
+
+        for name in key_names:
+            create_response = client.post(
+                reverse("api-key-list"),
+                data={
+                    "data": {
+                        "type": "api-keys",
+                        "attributes": {
+                            "name": name,
+                        },
+                    }
+                },
+                format="vnd.api+json",
+                headers=jwt_headers,
+            )
+
+            assert create_response.status_code == 201
+            created_keys.append(create_response.json()["data"])
+
+        # Verify all keys were created
+        assert len(created_keys) == 3
+
+        # List all keys and verify count
+        list_response = client.get(reverse("api-key-list"), headers=jwt_headers)
+        assert list_response.status_code == 200
+
+        # Should include the 3 new keys plus the ones from api_keys_fixture
+        keys_list = list_response.json()["data"]
+        assert len(keys_list) >= 3
+
+        # Verify each created key can authenticate independently
+        for key_data in created_keys:
+            full_key = key_data["attributes"]["api_key"]
+            api_key_headers = get_api_key_header(full_key)
+            auth_response = client.get(
+                reverse("provider-list"), headers=api_key_headers
+            )
+            assert auth_response.status_code == 200
+
+    def test_api_key_becomes_invalid_when_user_deleted(self, tenants_fixture):
+        """When user is deleted, API key entity is set to None and authentication fails."""
+        client = APIClient()
+        tenant = tenants_fixture[0]
+
+        # Create a fresh user for this test to avoid affecting other tests
+        test_user = User.objects.create_user(
+            name="test_deletion_user",
+            email="deletion_test@prowler.com",
+            password=TEST_PASSWORD,
+        )
+        Membership.objects.create(
+            user=test_user,
+            tenant=tenant,
+            role=Membership.RoleChoices.OWNER,
+        )
+
+        # Create role for the user
+        role = Role.objects.create(
+            tenant_id=tenant.id,
+            name="Deletion Test Role",
+            unlimited_visibility=True,
+            manage_account=True,
+        )
+        UserRoleRelationship.objects.create(
+            user=test_user,
+            role=role,
+            tenant_id=tenant.id,
+        )
+
+        # Create API key for this user
+        api_key, raw_key = TenantAPIKey.objects.create_api_key(
+            name="Test Key for Deletion",
+            tenant_id=tenant.id,
+            entity=test_user,
+        )
+
+        # Verify the API key works initially
+        api_key_headers = get_api_key_header(raw_key)
+        initial_response = client.get(reverse("provider-list"), headers=api_key_headers)
+        assert initial_response.status_code == 200
+
+        # Store the API key ID for later verification
+        api_key_id = api_key.id
+
+        # Delete the user
+        test_user.delete()
+
+        # Reload the API key from database
+        api_key.refresh_from_db()
+
+        # Verify the API key still exists in database (not cascade deleted)
+        assert TenantAPIKey.objects.filter(id=api_key_id).exists()
+
+        # Verify entity field is now None (CASCADE behavior is SET_NULL)
+        assert api_key.entity is None
+
+        # Verify authentication with this API key now fails
+        auth_response = client.get(reverse("provider-list"), headers=api_key_headers)
+
+        # Must return 401 Unauthorized, not 500 Internal Server Error
+        assert auth_response.status_code == 401, (
+            f"Expected 401 but got {auth_response.status_code}: "
+            f"{auth_response.json()}"
+        )
+
+        # Verify error message is present
+        response_json = auth_response.json()
+        assert "errors" in response_json
+        error_detail = response_json["errors"][0]["detail"]
+        # The error should indicate authentication failed due to invalid/orphaned key
+        assert (
+            "API Key" in error_detail
+            or "Invalid" in error_detail
+            or "entity" in error_detail.lower()
+        )
+
+
+@pytest.mark.django_db
+class TestCombinedAuthentication:
+    def test_jwt_takes_priority_over_api_key(
+        self, create_test_user, tenants_fixture, api_keys_fixture
+    ):
+        """When Bearer token present, JWT is used."""
+        client = APIClient()
+
+        # Get JWT token
+        access_token, _ = get_api_tokens(client, create_test_user.email, TEST_PASSWORD)
+
+        # Create headers with both Bearer (JWT) and API key would conflict
+        # But we'll test that Bearer takes priority by setting Authorization to Bearer
+        jwt_headers = {"Authorization": f"Bearer {access_token}"}
+
+        response = client.get(reverse("provider-list"), headers=jwt_headers)
+
+        assert response.status_code == 200
+
+        # The authentication should have used JWT, not API key
+        # We can verify this worked as JWT authentication
+
+    def test_api_key_header_format_validation(
+        self, create_test_user, tenants_fixture, api_keys_fixture
+    ):
+        """Verify Authorization: Api-Key  format."""
+        client = APIClient()
+
+        api_key = api_keys_fixture[0]
+
+        # Correct format
+        correct_headers = {"Authorization": f"Api-Key {api_key._raw_key}"}
+        correct_response = client.get(reverse("provider-list"), headers=correct_headers)
+        assert correct_response.status_code == 200
+
+        # Wrong format - using Bearer instead of Api-Key
+        wrong_format_headers = {"Authorization": f"Bearer {api_key._raw_key}"}
+        wrong_response = client.get(
+            reverse("provider-list"), headers=wrong_format_headers
+        )
+        # Should fail because it tries to parse as JWT
+        assert wrong_response.status_code == 401
+
+        # Wrong format - missing Api-Key prefix
+        no_prefix_headers = {"Authorization": api_key._raw_key}
+        no_prefix_response = client.get(
+            reverse("provider-list"), headers=no_prefix_headers
+        )
+        assert no_prefix_response.status_code == 401
+
+    def test_concurrent_api_key_usage(
+        self, create_test_user, tenants_fixture, api_keys_fixture
+    ):
+        """Same key can be used multiple times concurrently."""
+        client = APIClient()
+
+        api_key = api_keys_fixture[0]
+        api_key_headers = get_api_key_header(api_key._raw_key)
+
+        # Make multiple concurrent requests with the same key
+        responses = []
+        for _ in range(5):
+            response = client.get(reverse("provider-list"), headers=api_key_headers)
+            responses.append(response)
+
+        # All requests should succeed
+        for response in responses:
+            assert response.status_code == 200
+
+        # Verify last_used_at was updated
+        api_key.refresh_from_db()
+        assert api_key.last_used_at is not None
+
+
+@pytest.mark.django_db
+class TestAPIKeyRLSBypass:
+    """Test RLS bypass fix for API key authentication.
+
+    These tests verify that API key authentication works correctly even when
+    RLS context is not set, which is critical since we don't know the tenant_id
+    until we look up the API key (which itself is protected by RLS).
+
+    The fix ensures all database operations during authentication use the admin
+    database, bypassing RLS constraints.
+    """
+
+    def test_api_key_authentication_without_rls_context(
+        self, create_test_user, tenants_fixture, api_keys_fixture
+    ):
+        """Verify API key authentication works without pre-existing RLS context.
+
+        This is the core fix: authentication must succeed even when prowler.tenant_id
+        is not set, since we need to look up the API key to discover the tenant.
+        """
+        client = APIClient()
+        api_key = api_keys_fixture[0]
+
+        api_key_headers = get_api_key_header(api_key._raw_key)
+        response = client.get(reverse("provider-list"), headers=api_key_headers)
+
+        assert response.status_code == 200
+        assert "data" in response.json()
+
+    def test_api_key_lookup_uses_admin_database(
+        self, create_test_user, tenants_fixture
+    ):
+        """Verify API key lookup uses admin database during authentication.
+
+        The TenantAPIKey model is RLS-protected, so queries against it would
+        normally fail without prowler.tenant_id set. The fix routes lookups
+        to the admin database which bypasses RLS.
+        """
+        client = APIClient()
+        tenant = tenants_fixture[0]
+
+        role = Role.objects.create(
+            tenant_id=tenant.id,
+            name="Admin DB Test Role",
+            unlimited_visibility=True,
+            manage_account=True,
+        )
+        UserRoleRelationship.objects.create(
+            user=create_test_user,
+            role=role,
+            tenant_id=tenant.id,
+        )
+
+        api_key, raw_key = TenantAPIKey.objects.create_api_key(
+            name="Admin DB Test Key",
+            tenant_id=tenant.id,
+            entity=create_test_user,
+        )
+
+        api_key_headers = get_api_key_header(raw_key)
+        response = client.get(reverse("provider-list"), headers=api_key_headers)
+
+        assert response.status_code == 200
+
+        api_key.refresh_from_db()
+        assert api_key.last_used_at is not None
+
+    def test_tenant_context_established_after_authentication(
+        self, create_test_user, tenants_fixture, api_keys_fixture
+    ):
+        """Verify correct tenant context is established after API key auth.
+
+        After authentication, the tenant_id from the API key should be used
+        to set up the proper RLS context for subsequent queries.
+        """
+        client = APIClient()
+        api_key = api_keys_fixture[0]
+
+        api_key_headers = get_api_key_header(api_key._raw_key)
+
+        # Use tenant-list endpoint to get actual tenant IDs
+        tenant_response = client.get(reverse("tenant-list"), headers=api_key_headers)
+
+        assert tenant_response.status_code == 200
+        tenant_data = tenant_response.json()["data"]
+        tenant_ids = [t["id"] for t in tenant_data]
+
+        # Verify the API key's tenant is in the list of accessible tenants
+        assert str(api_key.tenant_id) in tenant_ids
+
+    def test_concurrent_authentication_different_tenants(self, tenants_fixture):
+        """Verify multiple API keys from different tenants can authenticate simultaneously.
+
+        This tests that the admin database routing works correctly in concurrent
+        scenarios and doesn't cause tenant isolation issues.
+        """
+        client = APIClient()
+
+        user1 = User.objects.create_user(
+            name="concurrent_user1",
+            email="concurrent1@test.com",
+            password=TEST_PASSWORD,
+        )
+        user2 = User.objects.create_user(
+            name="concurrent_user2",
+            email="concurrent2@test.com",
+            password=TEST_PASSWORD,
+        )
+
+        tenant1 = tenants_fixture[0]
+        tenant2 = tenants_fixture[1]
+
+        Membership.objects.create(user=user1, tenant=tenant1)
+        Membership.objects.create(user=user2, tenant=tenant2)
+
+        role1 = Role.objects.create(
+            tenant_id=tenant1.id,
+            name="Concurrent Role 1",
+            unlimited_visibility=True,
+            manage_account=True,
+        )
+        role2 = Role.objects.create(
+            tenant_id=tenant2.id,
+            name="Concurrent Role 2",
+            unlimited_visibility=True,
+            manage_account=True,
+        )
+
+        UserRoleRelationship.objects.create(
+            user=user1,
+            role=role1,
+            tenant_id=tenant1.id,
+        )
+        UserRoleRelationship.objects.create(
+            user=user2,
+            role=role2,
+            tenant_id=tenant2.id,
+        )
+
+        api_key1, raw_key1 = TenantAPIKey.objects.create_api_key(
+            name="Concurrent Key 1",
+            tenant_id=tenant1.id,
+            entity=user1,
+        )
+        api_key2, raw_key2 = TenantAPIKey.objects.create_api_key(
+            name="Concurrent Key 2",
+            tenant_id=tenant2.id,
+            entity=user2,
+        )
+
+        headers1 = get_api_key_header(raw_key1)
+        headers2 = get_api_key_header(raw_key2)
+
+        response1 = client.get(reverse("provider-list"), headers=headers1)
+        response2 = client.get(reverse("provider-list"), headers=headers2)
+
+        assert response1.status_code == 200
+        assert response2.status_code == 200
+
+        api_key1.refresh_from_db()
+        api_key2.refresh_from_db()
+
+        assert api_key1.last_used_at is not None
+        assert api_key2.last_used_at is not None
+        assert api_key1.tenant_id == tenant1.id
+        assert api_key2.tenant_id == tenant2.id
+
+    def test_api_key_update_last_used_uses_admin_db(
+        self, create_test_user, tenants_fixture, api_keys_fixture
+    ):
+        """Verify last_used_at update uses admin database.
+
+        The update to last_used_at during authentication must also use the
+        admin database since it occurs before RLS context is established.
+        """
+        client = APIClient()
+        api_key = api_keys_fixture[0]
+
+        assert api_key.last_used_at is None
+
+        api_key_headers = get_api_key_header(api_key._raw_key)
+        first_response = client.get(reverse("provider-list"), headers=api_key_headers)
+
+        assert first_response.status_code == 200
+
+        api_key.refresh_from_db()
+        first_timestamp = api_key.last_used_at
+        assert first_timestamp is not None
+
+        time.sleep(0.1)
+
+        second_response = client.get(reverse("provider-list"), headers=api_key_headers)
+        assert second_response.status_code == 200
+
+        api_key.refresh_from_db()
+        second_timestamp = api_key.last_used_at
+        assert second_timestamp > first_timestamp
+
+    def test_api_key_prefix_lookup_bypasses_rls(
+        self, create_test_user, tenants_fixture
+    ):
+        """Verify prefix-based API key lookup works without RLS context.
+
+        The authentication process splits the key into prefix and encrypted parts,
+        then looks up by prefix. This lookup must work via admin database.
+        """
+        client = APIClient()
+        tenant = tenants_fixture[0]
+
+        role = Role.objects.create(
+            tenant_id=tenant.id,
+            name="Prefix Test Role",
+            unlimited_visibility=True,
+            manage_account=True,
+        )
+        UserRoleRelationship.objects.create(
+            user=create_test_user,
+            role=role,
+            tenant_id=tenant.id,
+        )
+
+        api_key, raw_key = TenantAPIKey.objects.create_api_key(
+            name="Prefix Test Key",
+            tenant_id=tenant.id,
+            entity=create_test_user,
+        )
+
+        prefix = raw_key.split(".")[0]
+        assert prefix == api_key.prefix
+
+        api_key_headers = get_api_key_header(raw_key)
+        response = client.get(reverse("provider-list"), headers=api_key_headers)
+
+        assert response.status_code == 200
+
+    def test_expired_api_key_check_uses_admin_db(
+        self, create_test_user, tenants_fixture
+    ):
+        """Verify expired API key validation works via admin database.
+
+        Checking if a key is expired requires reading from TenantAPIKey,
+        which must use admin database during authentication.
+        """
+        client = APIClient()
+        tenant = tenants_fixture[0]
+
+        expired_key, raw_key = TenantAPIKey.objects.create_api_key(
+            name="Expired Test Key",
+            tenant_id=tenant.id,
+            entity=create_test_user,
+            expiry_date=datetime.now(timezone.utc) - timedelta(days=1),
+        )
+
+        api_key_headers = get_api_key_header(raw_key)
+        response = client.get(reverse("provider-list"), headers=api_key_headers)
+
+        assert response.status_code == 401
+        assert "expired" in response.json()["errors"][0]["detail"].lower()
+
+    def test_revoked_api_key_check_uses_admin_db(
+        self, create_test_user, tenants_fixture
+    ):
+        """Verify revoked API key validation works via admin database.
+
+        Checking if a key is revoked requires reading from TenantAPIKey,
+        which must use admin database during authentication.
+        """
+        client = APIClient()
+        tenant = tenants_fixture[0]
+
+        role = Role.objects.create(
+            tenant_id=tenant.id,
+            name="Revoked Test Role",
+            unlimited_visibility=True,
+            manage_account=True,
+        )
+        UserRoleRelationship.objects.create(
+            user=create_test_user,
+            role=role,
+            tenant_id=tenant.id,
+        )
+
+        api_key, raw_key = TenantAPIKey.objects.create_api_key(
+            name="Revoked Test Key",
+            tenant_id=tenant.id,
+            entity=create_test_user,
+        )
+
+        api_key.revoked = True
+        api_key.save()
+
+        api_key_headers = get_api_key_header(raw_key)
+        response = client.get(reverse("provider-list"), headers=api_key_headers)
+
+        assert response.status_code == 401
+        assert "revoked" in response.json()["errors"][0]["detail"].lower()
+
+
+@pytest.mark.django_db
+class TestAPIKeyMultiTenantWorkflows:
+    """Test complete multi-tenant workflows using API keys.
+
+    These integration tests verify end-to-end scenarios where API keys
+    are used across different tenants and ensure proper isolation.
+    """
+
+    def test_user_with_multiple_tenant_memberships_api_keys(self, tenants_fixture):
+        """User with memberships in multiple tenants can use different API keys.
+
+        Tests that a user can have separate API keys for different tenants
+        and each key only accesses resources in its tenant.
+        """
+        client = APIClient()
+
+        user = User.objects.create_user(
+            name="multi_tenant_user",
+            email="multitenant@test.com",
+            password=TEST_PASSWORD,
+        )
+
+        tenant1 = tenants_fixture[0]
+        tenant2 = tenants_fixture[1]
+
+        Membership.objects.create(user=user, tenant=tenant1)
+        Membership.objects.create(user=user, tenant=tenant2)
+
+        role1 = Role.objects.create(
+            tenant_id=tenant1.id,
+            name="Multi Tenant Role 1",
+            unlimited_visibility=True,
+            manage_account=True,
+        )
+        role2 = Role.objects.create(
+            tenant_id=tenant2.id,
+            name="Multi Tenant Role 2",
+            unlimited_visibility=True,
+            manage_account=True,
+        )
+
+        UserRoleRelationship.objects.create(
+            user=user,
+            role=role1,
+            tenant_id=tenant1.id,
+        )
+        UserRoleRelationship.objects.create(
+            user=user,
+            role=role2,
+            tenant_id=tenant2.id,
+        )
+
+        key1, raw_key1 = TenantAPIKey.objects.create_api_key(
+            name="Tenant 1 Key",
+            tenant_id=tenant1.id,
+            entity=user,
+        )
+        key2, raw_key2 = TenantAPIKey.objects.create_api_key(
+            name="Tenant 2 Key",
+            tenant_id=tenant2.id,
+            entity=user,
+        )
+
+        headers1 = get_api_key_header(raw_key1)
+        headers2 = get_api_key_header(raw_key2)
+
+        response1 = client.get(reverse("provider-list"), headers=headers1)
+        response2 = client.get(reverse("provider-list"), headers=headers2)
+
+        assert response1.status_code == 200
+        assert response2.status_code == 200
+
+        me_response1 = client.get(reverse("user-me"), headers=headers1)
+        me_response2 = client.get(reverse("user-me"), headers=headers2)
+
+        assert me_response1.status_code == 200
+        assert me_response2.status_code == 200
+
+        assert me_response1.json()["data"]["id"] == str(user.id)
+        assert me_response2.json()["data"]["id"] == str(user.id)
+
+    def test_api_key_cannot_access_different_tenant_resources(
+        self, tenants_fixture, providers_fixture
+    ):
+        """API key from one tenant cannot access resources from another tenant.
+
+        Verifies RLS enforcement after authentication ensures tenant isolation.
+        """
+        client = APIClient()
+
+        user1 = User.objects.create_user(
+            name="tenant1_user",
+            email="tenant1user@test.com",
+            password=TEST_PASSWORD,
+        )
+        user2 = User.objects.create_user(
+            name="tenant2_user",
+            email="tenant2user@test.com",
+            password=TEST_PASSWORD,
+        )
+
+        tenant1 = tenants_fixture[0]
+        tenant2 = tenants_fixture[1]
+
+        Membership.objects.create(user=user1, tenant=tenant1)
+        Membership.objects.create(user=user2, tenant=tenant2)
+
+        role1 = Role.objects.create(
+            tenant_id=tenant1.id,
+            name="Isolation Test Role 1",
+            unlimited_visibility=True,
+            manage_account=True,
+        )
+        role2 = Role.objects.create(
+            tenant_id=tenant2.id,
+            name="Isolation Test Role 2",
+            unlimited_visibility=True,
+            manage_account=True,
+        )
+
+        UserRoleRelationship.objects.create(
+            user=user1,
+            role=role1,
+            tenant_id=tenant1.id,
+        )
+        UserRoleRelationship.objects.create(
+            user=user2,
+            role=role2,
+            tenant_id=tenant2.id,
+        )
+
+        key1, raw_key1 = TenantAPIKey.objects.create_api_key(
+            name="Isolation Key 1",
+            tenant_id=tenant1.id,
+            entity=user1,
+        )
+
+        headers1 = get_api_key_header(raw_key1)
+
+        provider_response = client.get(reverse("provider-list"), headers=headers1)
+        assert provider_response.status_code == 200
+
+        providers_data = provider_response.json()["data"]
+
+        if providers_data:
+            for provider in providers_data:
+                provider_tenant_id = str(tenants_fixture[0].id)
+                assert str(tenant2.id) != provider_tenant_id
+
+    def test_api_key_workflow_create_authenticate_revoke(
+        self, create_test_user_rbac, tenants_fixture
+    ):
+        """Complete workflow: create API key via JWT, use it, then revoke via JWT.
+
+        Tests the full lifecycle using both JWT and API key authentication.
+        """
+        client = APIClient()
+        tenants_fixture[0]
+
+        jwt_access_token, _ = get_api_tokens(
+            client, create_test_user_rbac.email, TEST_PASSWORD
+        )
+        jwt_headers = get_authorization_header(jwt_access_token)
+
+        create_response = client.post(
+            reverse("api-key-list"),
+            data={
+                "data": {
+                    "type": "api-keys",
+                    "attributes": {
+                        "name": "Workflow Test Key",
+                    },
+                }
+            },
+            format="vnd.api+json",
+            headers=jwt_headers,
+        )
+
+        assert create_response.status_code == 201
+        api_key_data = create_response.json()["data"]
+        api_key_id = api_key_data["id"]
+        raw_api_key = api_key_data["attributes"]["api_key"]
+
+        api_key_headers = get_api_key_header(raw_api_key)
+        auth_response = client.get(reverse("provider-list"), headers=api_key_headers)
+        assert auth_response.status_code == 200
+
+        revoke_response = client.delete(
+            reverse("api-key-revoke", kwargs={"pk": api_key_id}),
+            headers=jwt_headers,
+        )
+        assert revoke_response.status_code == 200
+
+        revoked_auth_response = client.get(
+            reverse("provider-list"), headers=api_key_headers
+        )
+        assert revoked_auth_response.status_code == 401
+        assert "revoked" in revoked_auth_response.json()["errors"][0]["detail"].lower()
+
+
+def get_api_key_header(api_key: str) -> dict:
+    """Helper to create API key authorization header."""
+    return {"Authorization": f"Api-Key {api_key}"}
diff --git a/api/src/backend/api/tests/integration/test_rls_transaction.py b/api/src/backend/api/tests/integration/test_rls_transaction.py
new file mode 100644
index 0000000000..6731b39d71
--- /dev/null
+++ b/api/src/backend/api/tests/integration/test_rls_transaction.py
@@ -0,0 +1,39 @@
+"""Tests for rls_transaction retry and fallback logic."""
+
+import pytest
+from django.db import DEFAULT_DB_ALIAS
+from rest_framework_json_api.serializers import ValidationError
+
+from api.db_utils import rls_transaction
+
+
+@pytest.mark.django_db
+class TestRLSTransaction:
+    """Simple integration tests for rls_transaction using real DB."""
+
+    @pytest.fixture
+    def tenant(self, tenants_fixture):
+        return tenants_fixture[0]
+
+    def test_success_on_primary(self, tenant):
+        """Basic: transaction succeeds on primary database."""
+        with rls_transaction(str(tenant.id), using=DEFAULT_DB_ALIAS) as cursor:
+            cursor.execute("SELECT 1")
+            result = cursor.fetchone()
+            assert result == (1,)
+
+    def test_invalid_uuid_raises_validation_error(self):
+        """Invalid UUID raises ValidationError before DB operations."""
+        with pytest.raises(ValidationError, match="Must be a valid UUID"):
+            with rls_transaction("not-a-uuid", using=DEFAULT_DB_ALIAS):
+                pass
+
+    def test_custom_parameter_name(self, tenant):
+        """Test custom RLS parameter name."""
+        custom_param = "api.custom_id"
+        with rls_transaction(
+            str(tenant.id), parameter=custom_param, using=DEFAULT_DB_ALIAS
+        ) as cursor:
+            cursor.execute("SELECT current_setting(%s, true)", [custom_param])
+            result = cursor.fetchone()
+            assert result == (str(tenant.id),)
diff --git a/api/src/backend/api/tests/test_apps.py b/api/src/backend/api/tests/test_apps.py
new file mode 100644
index 0000000000..1509705894
--- /dev/null
+++ b/api/src/backend/api/tests/test_apps.py
@@ -0,0 +1,152 @@
+import os
+from pathlib import Path
+from unittest.mock import MagicMock
+
+import pytest
+from django.conf import settings
+
+import api.apps as api_apps_module
+from api.apps import (
+    ApiConfig,
+    PRIVATE_KEY_FILE,
+    PUBLIC_KEY_FILE,
+    SIGNING_KEY_ENV,
+    VERIFYING_KEY_ENV,
+)
+
+
+@pytest.fixture(autouse=True)
+def reset_keys_initialized(monkeypatch):
+    """Ensure per-test clean state for the module-level guard flag."""
+    monkeypatch.setattr(api_apps_module, "_keys_initialized", False, raising=False)
+
+
+def _stub_keys():
+    return (
+        """-----BEGIN PRIVATE KEY-----\nPRIVATE\n-----END PRIVATE KEY-----\n""",
+        """-----BEGIN PUBLIC KEY-----\nPUBLIC\n-----END PUBLIC KEY-----\n""",
+    )
+
+
+def test_generate_jwt_keys_when_missing(monkeypatch, tmp_path):
+    # Arrange: isolate FS, env, and settings; force generation path
+    monkeypatch.setattr(
+        api_apps_module, "KEYS_DIRECTORY", Path(tmp_path), raising=False
+    )
+    monkeypatch.delenv(SIGNING_KEY_ENV, raising=False)
+    monkeypatch.delenv(VERIFYING_KEY_ENV, raising=False)
+
+    # Work on a copy of SIMPLE_JWT to avoid mutating the global settings dict for other tests
+    monkeypatch.setattr(
+        settings, "SIMPLE_JWT", settings.SIMPLE_JWT.copy(), raising=False
+    )
+    monkeypatch.setattr(settings, "TESTING", False, raising=False)
+
+    # Avoid dependency on the cryptography package
+    monkeypatch.setattr(ApiConfig, "_generate_jwt_keys", staticmethod(_stub_keys))
+
+    config = ApiConfig("api", api_apps_module)
+
+    # Act
+    config._ensure_crypto_keys()
+
+    # Assert: files created with expected content
+    priv_path = Path(tmp_path) / PRIVATE_KEY_FILE
+    pub_path = Path(tmp_path) / PUBLIC_KEY_FILE
+    assert priv_path.is_file()
+    assert pub_path.is_file()
+    assert priv_path.read_text() == _stub_keys()[0]
+    assert pub_path.read_text() == _stub_keys()[1]
+
+    # Env vars and Django settings updated
+    assert os.environ[SIGNING_KEY_ENV] == _stub_keys()[0]
+    assert os.environ[VERIFYING_KEY_ENV] == _stub_keys()[1]
+    assert settings.SIMPLE_JWT["SIGNING_KEY"] == _stub_keys()[0]
+    assert settings.SIMPLE_JWT["VERIFYING_KEY"] == _stub_keys()[1]
+
+
+def test_ensure_crypto_keys_are_idempotent_within_process(monkeypatch, tmp_path):
+    # Arrange
+    monkeypatch.setattr(
+        api_apps_module, "KEYS_DIRECTORY", Path(tmp_path), raising=False
+    )
+    monkeypatch.delenv(SIGNING_KEY_ENV, raising=False)
+    monkeypatch.delenv(VERIFYING_KEY_ENV, raising=False)
+    monkeypatch.setattr(
+        settings, "SIMPLE_JWT", settings.SIMPLE_JWT.copy(), raising=False
+    )
+    monkeypatch.setattr(settings, "TESTING", False, raising=False)
+
+    mock_generate = MagicMock(side_effect=_stub_keys)
+    monkeypatch.setattr(ApiConfig, "_generate_jwt_keys", staticmethod(mock_generate))
+
+    config = ApiConfig("api", api_apps_module)
+
+    # Act: first call should generate, second should be a no-op (guard flag)
+    config._ensure_crypto_keys()
+    config._ensure_crypto_keys()
+
+    # Assert: generation occurred exactly once
+    assert mock_generate.call_count == 1
+
+
+def test_ensure_jwt_keys_uses_existing_files(monkeypatch, tmp_path):
+    # Arrange: pre-create key files
+    monkeypatch.setattr(
+        api_apps_module, "KEYS_DIRECTORY", Path(tmp_path), raising=False
+    )
+    monkeypatch.setattr(
+        settings, "SIMPLE_JWT", settings.SIMPLE_JWT.copy(), raising=False
+    )
+
+    existing_private, existing_public = _stub_keys()
+
+    (Path(tmp_path) / PRIVATE_KEY_FILE).write_text(existing_private)
+    (Path(tmp_path) / PUBLIC_KEY_FILE).write_text(existing_public)
+
+    # If generation were called, fail the test
+    def _fail_generate():
+        raise AssertionError("_generate_jwt_keys should not be called when files exist")
+
+    monkeypatch.setattr(ApiConfig, "_generate_jwt_keys", staticmethod(_fail_generate))
+
+    config = ApiConfig("api", api_apps_module)
+
+    # Act: call the lower-level method directly to set env/settings from files
+    config._ensure_jwt_keys()
+
+    # Assert
+    # _read_key_file() strips trailing newlines; environment/settings should reflect stripped content
+    assert os.environ[SIGNING_KEY_ENV] == existing_private.strip()
+    assert os.environ[VERIFYING_KEY_ENV] == existing_public.strip()
+    assert settings.SIMPLE_JWT["SIGNING_KEY"] == existing_private.strip()
+    assert settings.SIMPLE_JWT["VERIFYING_KEY"] == existing_public.strip()
+
+
+def test_ensure_crypto_keys_skips_when_env_vars(monkeypatch, tmp_path):
+    # Arrange: put values in env so the orchestrator doesn't generate
+    monkeypatch.setattr(
+        api_apps_module, "KEYS_DIRECTORY", Path(tmp_path), raising=False
+    )
+    monkeypatch.setenv(SIGNING_KEY_ENV, "ENV-PRIVATE")
+    monkeypatch.setenv(VERIFYING_KEY_ENV, "ENV-PUBLIC")
+    monkeypatch.setattr(
+        settings, "SIMPLE_JWT", settings.SIMPLE_JWT.copy(), raising=False
+    )
+    monkeypatch.setattr(settings, "TESTING", False, raising=False)
+
+    called = {"ensure": False}
+
+    def _track_call():
+        called["ensure"] = True
+        return _stub_keys()
+
+    monkeypatch.setattr(ApiConfig, "_generate_jwt_keys", staticmethod(_track_call))
+
+    config = ApiConfig("api", api_apps_module)
+
+    # Act
+    config._ensure_crypto_keys()
+
+    # Assert: orchestrator did not trigger generation when env present
+    assert called["ensure"] is False
diff --git a/api/src/backend/api/tests/test_authentication.py b/api/src/backend/api/tests/test_authentication.py
new file mode 100644
index 0000000000..6745c36e91
--- /dev/null
+++ b/api/src/backend/api/tests/test_authentication.py
@@ -0,0 +1,384 @@
+import time
+from datetime import datetime, timedelta, timezone
+from unittest.mock import patch
+from uuid import uuid4
+
+import pytest
+from django.test import RequestFactory
+from rest_framework.exceptions import AuthenticationFailed
+
+from api.authentication import TenantAPIKeyAuthentication
+from api.db_router import MainRouter
+from api.models import TenantAPIKey
+
+
+@pytest.mark.django_db
+class TestTenantAPIKeyAuthentication:
+    @pytest.fixture
+    def auth_backend(self):
+        """Create an instance of TenantAPIKeyAuthentication."""
+        return TenantAPIKeyAuthentication()
+
+    @pytest.fixture
+    def request_factory(self):
+        """Create a Django request factory."""
+        return RequestFactory()
+
+    def test_authenticate_credentials_uses_admin_database(
+        self, auth_backend, api_keys_fixture, request_factory
+    ):
+        """Test that _authenticate_credentials routes queries to admin database."""
+        api_key = api_keys_fixture[0]
+        raw_key = api_key._raw_key
+
+        # Extract the encrypted key part (after the prefix and separator)
+        _, encrypted_key = raw_key.split(TenantAPIKey.objects.separator, 1)
+
+        # Create a mock request
+        request = request_factory.get("/")
+
+        # Call the method
+        entity, auth_dict = auth_backend._authenticate_credentials(
+            request, encrypted_key
+        )
+
+        # Verify that the entity is the user associated with the API key
+        assert entity == api_key.entity
+        assert entity.id == api_key.entity.id
+
+    def test_authenticate_credentials_restores_manager_on_success(
+        self, auth_backend, api_keys_fixture, request_factory
+    ):
+        """Test that the manager is restored after successful authentication."""
+        api_key = api_keys_fixture[0]
+        raw_key = api_key._raw_key
+        _, encrypted_key = raw_key.split(TenantAPIKey.objects.separator, 1)
+
+        # Store the original manager
+        original_manager = TenantAPIKey.objects
+
+        request = request_factory.get("/")
+
+        # Call the method
+        auth_backend._authenticate_credentials(request, encrypted_key)
+
+        # Verify the manager was restored
+        assert TenantAPIKey.objects == original_manager
+
+    def test_authenticate_credentials_restores_manager_on_exception(
+        self, auth_backend, request_factory
+    ):
+        """Test that the manager is restored even when an exception occurs."""
+        # Store the original manager
+        original_manager = TenantAPIKey.objects
+
+        request = request_factory.get("/")
+
+        # Try to authenticate with an invalid key that will raise an exception
+        with pytest.raises(Exception):
+            auth_backend._authenticate_credentials(request, "invalid_encrypted_key")
+
+        # Verify the manager was restored despite the exception
+        assert TenantAPIKey.objects == original_manager
+
+    def test_authenticate_valid_api_key(
+        self, auth_backend, api_keys_fixture, request_factory
+    ):
+        """Test successful authentication with a valid API key."""
+        api_key = api_keys_fixture[0]
+        raw_key = api_key._raw_key
+
+        # Create a request with the API key in the Authorization header
+        request = request_factory.get("/")
+        request.META["HTTP_AUTHORIZATION"] = f"Api-Key {raw_key}"
+
+        # Authenticate
+        entity, auth_dict = auth_backend.authenticate(request)
+
+        # Verify the entity and auth dict
+        assert entity == api_key.entity
+        assert auth_dict["tenant_id"] == str(api_key.tenant_id)
+        assert auth_dict["sub"] == str(api_key.entity.id)
+        assert auth_dict["api_key_prefix"] == api_key.prefix
+
+        # Verify that last_used_at was updated
+        api_key.refresh_from_db()
+        assert api_key.last_used_at is not None
+        assert (datetime.now(timezone.utc) - api_key.last_used_at).seconds < 5
+
+    def test_authenticate_valid_api_key_uses_admin_database(
+        self, auth_backend, api_keys_fixture, request_factory
+    ):
+        """Test that authenticate uses admin database for API key lookup."""
+        api_key = api_keys_fixture[0]
+        raw_key = api_key._raw_key
+
+        request = request_factory.get("/")
+        request.META["HTTP_AUTHORIZATION"] = f"Api-Key {raw_key}"
+
+        # Mock the manager's using method to verify it's called with admin_db
+        with patch.object(
+            TenantAPIKey.objects, "using", wraps=TenantAPIKey.objects.using
+        ) as mock_using:
+            auth_backend.authenticate(request)
+
+            # Verify that .using('admin') was called
+            mock_using.assert_called_with(MainRouter.admin_db)
+
+    def test_authenticate_invalid_key_format_missing_separator(
+        self, auth_backend, request_factory
+    ):
+        """Test authentication fails with invalid API key format (no separator)."""
+        request = request_factory.get("/")
+        request.META["HTTP_AUTHORIZATION"] = "Api-Key invalid_key_no_separator"
+
+        with pytest.raises(AuthenticationFailed) as exc_info:
+            auth_backend.authenticate(request)
+
+        assert str(exc_info.value.detail) == "Invalid API Key."
+
+    def test_authenticate_invalid_key_format_empty_prefix(
+        self, auth_backend, request_factory
+    ):
+        """Test authentication fails with empty prefix."""
+        request = request_factory.get("/")
+        request.META["HTTP_AUTHORIZATION"] = "Api-Key .encrypted_part"
+
+        with pytest.raises(AuthenticationFailed) as exc_info:
+            auth_backend.authenticate(request)
+
+        assert str(exc_info.value.detail) == "Invalid API Key."
+
+    def test_authenticate_invalid_encrypted_key(
+        self, auth_backend, api_keys_fixture, request_factory
+    ):
+        """Test authentication fails with invalid encrypted key."""
+        api_key = api_keys_fixture[0]
+
+        # Create an invalid key with valid prefix but invalid encryption
+        invalid_key = f"{api_key.prefix}.invalid_encrypted_data"
+
+        request = request_factory.get("/")
+        request.META["HTTP_AUTHORIZATION"] = f"Api-Key {invalid_key}"
+
+        with pytest.raises(AuthenticationFailed) as exc_info:
+            auth_backend.authenticate(request)
+
+        assert str(exc_info.value.detail) == "Invalid API Key."
+
+    def test_authenticate_revoked_api_key(
+        self, auth_backend, api_keys_fixture, request_factory
+    ):
+        """Test authentication fails with a revoked API key."""
+        # Use the revoked API key (index 2 from fixture)
+        api_key = api_keys_fixture[2]
+        raw_key = api_key._raw_key
+
+        request = request_factory.get("/")
+        request.META["HTTP_AUTHORIZATION"] = f"Api-Key {raw_key}"
+
+        # The revoked key should fail during credential validation
+        with pytest.raises(AuthenticationFailed) as exc_info:
+            auth_backend.authenticate(request)
+
+        assert str(exc_info.value.detail) == "This API Key has been revoked."
+
+    def test_authenticate_expired_api_key(
+        self, auth_backend, create_test_user, tenants_fixture, request_factory
+    ):
+        """Test authentication fails with an expired API key."""
+        tenant = tenants_fixture[0]
+        user = create_test_user
+
+        # Create an expired API key
+        api_key, raw_key = TenantAPIKey.objects.create_api_key(
+            name="Expired API Key",
+            tenant_id=tenant.id,
+            entity=user,
+            expiry_date=datetime.now(timezone.utc) - timedelta(days=1),
+        )
+
+        request = request_factory.get("/")
+        request.META["HTTP_AUTHORIZATION"] = f"Api-Key {raw_key}"
+
+        with pytest.raises(AuthenticationFailed) as exc_info:
+            auth_backend.authenticate(request)
+
+        assert str(exc_info.value.detail) == "API Key has already expired."
+
+    def test_authenticate_nonexistent_api_key(
+        self, auth_backend, api_keys_fixture, request_factory
+    ):
+        """Test authentication fails when API key doesn't exist in database."""
+        # Create a valid-looking encrypted key with a non-existent UUID
+        api_key = api_keys_fixture[0]
+        non_existent_uuid = str(uuid4())
+
+        # Manually create an encrypted key with a non-existent ID
+        payload = {
+            "_pk": non_existent_uuid,
+            "_exp": (datetime.now(timezone.utc) + timedelta(days=30)).timestamp(),
+        }
+        encrypted_key = auth_backend.key_crypto.generate(payload)
+        fake_key = f"{api_key.prefix}.{encrypted_key}"
+
+        request = request_factory.get("/")
+        request.META["HTTP_AUTHORIZATION"] = f"Api-Key {fake_key}"
+
+        with pytest.raises(AuthenticationFailed) as exc_info:
+            auth_backend.authenticate(request)
+
+        assert str(exc_info.value.detail) == "No entity matching this api key."
+
+    def test_authenticate_updates_last_used_at(
+        self, auth_backend, api_keys_fixture, request_factory
+    ):
+        """Test that last_used_at is updated on successful authentication."""
+        api_key = api_keys_fixture[0]
+        raw_key = api_key._raw_key
+
+        # Store the original last_used_at
+        original_last_used = api_key.last_used_at
+
+        request = request_factory.get("/")
+        request.META["HTTP_AUTHORIZATION"] = f"Api-Key {raw_key}"
+
+        # Authenticate
+        auth_backend.authenticate(request)
+
+        # Refresh from database
+        api_key.refresh_from_db()
+
+        # Verify last_used_at was updated
+        assert api_key.last_used_at is not None
+        if original_last_used:
+            assert api_key.last_used_at > original_last_used
+
+    def test_authenticate_saves_to_admin_database(
+        self, auth_backend, api_keys_fixture, request_factory
+    ):
+        """Test that the API key save operation uses admin database."""
+        api_key = api_keys_fixture[0]
+        raw_key = api_key._raw_key
+
+        request = request_factory.get("/")
+        request.META["HTTP_AUTHORIZATION"] = f"Api-Key {raw_key}"
+
+        # Mock the save method to verify it's called with using='admin'
+        with patch.object(TenantAPIKey, "save") as mock_save:
+            auth_backend.authenticate(request)
+
+            # Verify save was called with using=admin_db
+            mock_save.assert_called_once_with(
+                update_fields=["last_used_at"], using=MainRouter.admin_db
+            )
+
+    def test_authenticate_returns_correct_auth_dict(
+        self, auth_backend, api_keys_fixture, request_factory
+    ):
+        """Test that the auth dict contains all required fields."""
+        api_key = api_keys_fixture[0]
+        raw_key = api_key._raw_key
+
+        request = request_factory.get("/")
+        request.META["HTTP_AUTHORIZATION"] = f"Api-Key {raw_key}"
+
+        entity, auth_dict = auth_backend.authenticate(request)
+
+        # Verify all required fields are present
+        assert "tenant_id" in auth_dict
+        assert "sub" in auth_dict
+        assert "api_key_prefix" in auth_dict
+
+        # Verify values are correct
+        assert auth_dict["tenant_id"] == str(api_key.tenant_id)
+        assert auth_dict["sub"] == str(api_key.entity.id)
+        assert auth_dict["api_key_prefix"] == api_key.prefix
+
+    def test_authenticate_with_multiple_api_keys_same_tenant(
+        self, auth_backend, api_keys_fixture, request_factory
+    ):
+        """Test that authentication works correctly with multiple API keys for the same tenant."""
+        # Test with first API key
+        api_key1 = api_keys_fixture[0]
+        raw_key1 = api_key1._raw_key
+
+        request1 = request_factory.get("/")
+        request1.META["HTTP_AUTHORIZATION"] = f"Api-Key {raw_key1}"
+
+        entity1, auth_dict1 = auth_backend.authenticate(request1)
+
+        assert entity1 == api_key1.entity
+        assert auth_dict1["api_key_prefix"] == api_key1.prefix
+
+        # Test with second API key
+        api_key2 = api_keys_fixture[1]
+        raw_key2 = api_key2._raw_key
+
+        request2 = request_factory.get("/")
+        request2.META["HTTP_AUTHORIZATION"] = f"Api-Key {raw_key2}"
+
+        entity2, auth_dict2 = auth_backend.authenticate(request2)
+
+        assert entity2 == api_key2.entity
+        assert auth_dict2["api_key_prefix"] == api_key2.prefix
+
+        # Verify they're different keys but same tenant
+        assert auth_dict1["api_key_prefix"] != auth_dict2["api_key_prefix"]
+        assert auth_dict1["tenant_id"] == auth_dict2["tenant_id"]
+
+    def test_authenticate_with_wrong_prefix_in_db(
+        self, auth_backend, api_keys_fixture, request_factory
+    ):
+        """Test authentication fails when prefix doesn't match database."""
+        api_key = api_keys_fixture[0]
+        raw_key = api_key._raw_key
+
+        # Extract the encrypted part and combine with wrong prefix
+        _, encrypted_part = raw_key.split(TenantAPIKey.objects.separator, 1)
+        wrong_key = f"pk_wrong123.{encrypted_part}"
+
+        request = request_factory.get("/")
+        request.META["HTTP_AUTHORIZATION"] = f"Api-Key {wrong_key}"
+
+        with pytest.raises(AuthenticationFailed) as exc_info:
+            auth_backend.authenticate(request)
+
+        assert str(exc_info.value.detail) == "Invalid API Key."
+
+    def test_authenticate_credentials_exception_handling(
+        self, auth_backend, request_factory
+    ):
+        """Test that exceptions in _authenticate_credentials are properly handled."""
+        request = request_factory.get("/")
+
+        # Test with completely invalid data that will cause InvalidToken
+        with pytest.raises(Exception):
+            auth_backend._authenticate_credentials(request, "completely_invalid")
+
+    def test_authenticate_with_expired_timestamp(
+        self, auth_backend, create_test_user, tenants_fixture, request_factory
+    ):
+        """Test that expired timestamp in encrypted key causes authentication failure."""
+        tenant = tenants_fixture[0]
+        user = create_test_user
+
+        # Create an API key with a very short expiry
+        api_key, raw_key = TenantAPIKey.objects.create_api_key(
+            name="Short-lived API Key",
+            tenant_id=tenant.id,
+            entity=user,
+            expiry_date=datetime.now(timezone.utc) + timedelta(seconds=1),
+        )
+
+        # Wait for the key to expire
+        time.sleep(2)
+
+        request = request_factory.get("/")
+        request.META["HTTP_AUTHORIZATION"] = f"Api-Key {raw_key}"
+
+        # Should fail with expired key
+        with pytest.raises(AuthenticationFailed) as exc_info:
+            auth_backend.authenticate(request)
+
+        assert str(exc_info.value.detail) == "API Key has already expired."
diff --git a/api/src/backend/api/tests/test_compliance.py b/api/src/backend/api/tests/test_compliance.py
index 619d7d2325..7312335921 100644
--- a/api/src/backend/api/tests/test_compliance.py
+++ b/api/src/backend/api/tests/test_compliance.py
@@ -239,6 +239,7 @@ class TestCompliance:
             Framework="Framework 1",
             Version="1.0",
             Description="Description of compliance1",
+            Name="Compliance 1",
         )
         prowler_compliance = {"aws": {"compliance1": compliance1}}
 
@@ -248,6 +249,7 @@ class TestCompliance:
             "aws": {
                 "compliance1": {
                     "framework": "Framework 1",
+                    "name": "Compliance 1",
                     "version": "1.0",
                     "provider": "aws",
                     "description": "Description of compliance1",
diff --git a/api/src/backend/api/tests/test_db_utils.py b/api/src/backend/api/tests/test_db_utils.py
index f4b8bb88af..f706ab8c71 100644
--- a/api/src/backend/api/tests/test_db_utils.py
+++ b/api/src/backend/api/tests/test_db_utils.py
@@ -1,23 +1,38 @@
 from datetime import datetime, timezone
 from enum import Enum
-from unittest.mock import patch
+from unittest.mock import MagicMock, patch
 
 import pytest
 from django.conf import settings
+from django.db import DEFAULT_DB_ALIAS, OperationalError
 from freezegun import freeze_time
+from rest_framework_json_api.serializers import ValidationError
 
 from api.db_utils import (
+    POSTGRES_TENANT_VAR,
     _should_create_index_on_partition,
     batch_delete,
     create_objects_in_batches,
     enum_to_choices,
+    generate_api_key_prefix,
     generate_random_token,
     one_week_from_now,
+    rls_transaction,
     update_objects_in_batches,
 )
 from api.models import Provider
 
 
+@pytest.fixture
+def enable_read_replica():
+    """
+    Fixture to enable READ_REPLICA_ALIAS for tests that need replica functionality.
+    This avoids polluting the global test configuration.
+    """
+    with patch("api.db_utils.READ_REPLICA_ALIAS", "replica"):
+        yield "replica"
+
+
 class TestEnumToChoices:
     def test_enum_to_choices_simple(self):
         class Color(Enum):
@@ -313,3 +328,523 @@ class TestUpdateObjectsInBatches:
 
         qs = Provider.objects.filter(tenant=tenant, uid__endswith="_upd")
         assert qs.count() == total
+
+
+class TestGenerateApiKeyPrefix:
+    def test_prefix_format(self):
+        """Test that generated prefix starts with 'pk_'."""
+        prefix = generate_api_key_prefix()
+        assert prefix.startswith("pk_")
+
+    def test_prefix_length(self):
+        """Test that prefix has correct length (pk_ + 8 random chars = 11)."""
+        prefix = generate_api_key_prefix()
+        assert len(prefix) == 11
+
+    def test_prefix_uniqueness(self):
+        """Test that multiple generations produce unique prefixes."""
+        prefixes = {generate_api_key_prefix() for _ in range(100)}
+        assert len(prefixes) == 100
+
+    def test_prefix_character_set(self):
+        """Test that random part uses only allowed characters."""
+        allowed_chars = "23456789ABCDEFGHJKMNPQRSTVWXYZ"
+        for _ in range(50):
+            prefix = generate_api_key_prefix()
+            random_part = prefix[3:]  # Strip 'pk_'
+            assert all(char in allowed_chars for char in random_part)
+
+
+@pytest.mark.django_db
+class TestRlsTransaction:
+    def test_rls_transaction_valid_uuid_string(self, tenants_fixture):
+        """Test rls_transaction with valid UUID string."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+
+        with rls_transaction(tenant_id) as cursor:
+            assert cursor is not None
+            cursor.execute("SELECT current_setting(%s)", [POSTGRES_TENANT_VAR])
+            result = cursor.fetchone()
+            assert result[0] == tenant_id
+
+    def test_rls_transaction_valid_uuid_object(self, tenants_fixture):
+        """Test rls_transaction with UUID object."""
+        tenant = tenants_fixture[0]
+
+        with rls_transaction(tenant.id) as cursor:
+            assert cursor is not None
+            cursor.execute("SELECT current_setting(%s)", [POSTGRES_TENANT_VAR])
+            result = cursor.fetchone()
+            assert result[0] == str(tenant.id)
+
+    def test_rls_transaction_invalid_uuid_raises_validation_error(self):
+        """Test rls_transaction raises ValidationError for invalid UUID."""
+        invalid_uuid = "not-a-valid-uuid"
+
+        with pytest.raises(ValidationError, match="Must be a valid UUID"):
+            with rls_transaction(invalid_uuid):
+                pass
+
+    def test_rls_transaction_uses_default_database_when_no_alias(self, tenants_fixture):
+        """Test rls_transaction uses DEFAULT_DB_ALIAS when no alias specified."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+
+        with patch("api.db_utils.get_read_db_alias", return_value=None):
+            with patch("api.db_utils.connections") as mock_connections:
+                mock_conn = MagicMock()
+                mock_cursor = MagicMock()
+                mock_conn.cursor.return_value.__enter__.return_value = mock_cursor
+                mock_connections.__getitem__.return_value = mock_conn
+                mock_connections.__contains__.return_value = True
+
+                with patch("api.db_utils.transaction.atomic"):
+                    with rls_transaction(tenant_id):
+                        pass
+
+                mock_connections.__getitem__.assert_called_with(DEFAULT_DB_ALIAS)
+
+    def test_rls_transaction_uses_specified_alias(self, tenants_fixture):
+        """Test rls_transaction uses specified database alias via using parameter."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+        custom_alias = "custom_db"
+
+        with patch("api.db_utils.connections") as mock_connections:
+            mock_conn = MagicMock()
+            mock_cursor = MagicMock()
+            mock_conn.cursor.return_value.__enter__.return_value = mock_cursor
+            mock_connections.__getitem__.return_value = mock_conn
+            mock_connections.__contains__.return_value = True
+
+            with patch("api.db_utils.transaction.atomic"):
+                with patch("api.db_utils.set_read_db_alias") as mock_set_alias:
+                    with patch("api.db_utils.reset_read_db_alias") as mock_reset_alias:
+                        mock_set_alias.return_value = "test_token"
+                        with rls_transaction(tenant_id, using=custom_alias):
+                            pass
+
+                        mock_connections.__getitem__.assert_called_with(custom_alias)
+                        mock_set_alias.assert_called_once_with(custom_alias)
+                        mock_reset_alias.assert_called_once_with("test_token")
+
+    def test_rls_transaction_uses_read_replica_from_router(
+        self, tenants_fixture, enable_read_replica
+    ):
+        """Test rls_transaction uses read replica alias from router."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+
+        with patch("api.db_utils.get_read_db_alias", return_value=enable_read_replica):
+            with patch("api.db_utils.connections") as mock_connections:
+                mock_conn = MagicMock()
+                mock_cursor = MagicMock()
+                mock_conn.cursor.return_value.__enter__.return_value = mock_cursor
+                mock_connections.__getitem__.return_value = mock_conn
+                mock_connections.__contains__.return_value = True
+
+                with patch("api.db_utils.transaction.atomic"):
+                    with patch("api.db_utils.set_read_db_alias") as mock_set_alias:
+                        with patch(
+                            "api.db_utils.reset_read_db_alias"
+                        ) as mock_reset_alias:
+                            mock_set_alias.return_value = "test_token"
+                            with rls_transaction(tenant_id):
+                                pass
+
+                            mock_connections.__getitem__.assert_called()
+                            mock_set_alias.assert_called_once()
+                            mock_reset_alias.assert_called_once()
+
+    def test_rls_transaction_fallback_to_default_when_alias_not_in_connections(
+        self, tenants_fixture
+    ):
+        """Test rls_transaction falls back to DEFAULT_DB_ALIAS when alias not in connections."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+        invalid_alias = "nonexistent_db"
+
+        with patch("api.db_utils.get_read_db_alias", return_value=invalid_alias):
+            with patch("api.db_utils.connections") as mock_connections:
+                mock_conn = MagicMock()
+                mock_cursor = MagicMock()
+                mock_conn.cursor.return_value.__enter__.return_value = mock_cursor
+
+                def contains_check(alias):
+                    return alias == DEFAULT_DB_ALIAS
+
+                mock_connections.__contains__.side_effect = contains_check
+                mock_connections.__getitem__.return_value = mock_conn
+
+                with patch("api.db_utils.transaction.atomic"):
+                    with rls_transaction(tenant_id):
+                        pass
+
+                    mock_connections.__getitem__.assert_called_with(DEFAULT_DB_ALIAS)
+
+    def test_rls_transaction_successful_execution_on_replica_no_retries(
+        self, tenants_fixture, enable_read_replica
+    ):
+        """Test successful execution on replica without retries."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+
+        with patch("api.db_utils.get_read_db_alias", return_value=enable_read_replica):
+            with patch("api.db_utils.connections") as mock_connections:
+                mock_conn = MagicMock()
+                mock_cursor = MagicMock()
+                mock_conn.cursor.return_value.__enter__.return_value = mock_cursor
+                mock_connections.__getitem__.return_value = mock_conn
+                mock_connections.__contains__.return_value = True
+
+                with patch("api.db_utils.transaction.atomic"):
+                    with patch("api.db_utils.set_read_db_alias", return_value="token"):
+                        with patch("api.db_utils.reset_read_db_alias"):
+                            with rls_transaction(tenant_id):
+                                pass
+
+                            assert mock_cursor.execute.call_count == 1
+
+    def test_rls_transaction_retry_with_exponential_backoff_on_operational_error(
+        self, tenants_fixture, enable_read_replica
+    ):
+        """Test retry with exponential backoff on OperationalError on replica."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+
+        with patch("api.db_utils.get_read_db_alias", return_value=enable_read_replica):
+            with patch("api.db_utils.connections") as mock_connections:
+                mock_conn = MagicMock()
+                mock_cursor = MagicMock()
+                mock_conn.cursor.return_value.__enter__.return_value = mock_cursor
+                mock_connections.__getitem__.return_value = mock_conn
+                mock_connections.__contains__.return_value = True
+
+                call_count = 0
+
+                def atomic_side_effect(*args, **kwargs):
+                    nonlocal call_count
+                    call_count += 1
+                    if call_count < 3:
+                        raise OperationalError("Connection error")
+                    return MagicMock(
+                        __enter__=MagicMock(return_value=None),
+                        __exit__=MagicMock(return_value=False),
+                    )
+
+                with patch(
+                    "api.db_utils.transaction.atomic", side_effect=atomic_side_effect
+                ):
+                    with patch("api.db_utils.time.sleep") as mock_sleep:
+                        with patch(
+                            "api.db_utils.set_read_db_alias", return_value="token"
+                        ):
+                            with patch("api.db_utils.reset_read_db_alias"):
+                                with patch("api.db_utils.logger") as mock_logger:
+                                    with rls_transaction(tenant_id):
+                                        pass
+
+                                    assert mock_sleep.call_count == 2
+                                    mock_sleep.assert_any_call(0.5)
+                                    mock_sleep.assert_any_call(1.0)
+                                    assert mock_logger.info.call_count == 2
+
+    def test_rls_transaction_max_three_attempts_for_replica(
+        self, tenants_fixture, enable_read_replica
+    ):
+        """Test maximum 3 attempts for replica database."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+
+        with patch("api.db_utils.get_read_db_alias", return_value=enable_read_replica):
+            with patch("api.db_utils.connections") as mock_connections:
+                mock_conn = MagicMock()
+                mock_cursor = MagicMock()
+                mock_conn.cursor.return_value.__enter__.return_value = mock_cursor
+                mock_connections.__getitem__.return_value = mock_conn
+                mock_connections.__contains__.return_value = True
+
+                with patch("api.db_utils.transaction.atomic") as mock_atomic:
+                    mock_atomic.side_effect = OperationalError("Persistent error")
+
+                    with patch("api.db_utils.time.sleep"):
+                        with patch(
+                            "api.db_utils.set_read_db_alias", return_value="token"
+                        ):
+                            with patch("api.db_utils.reset_read_db_alias"):
+                                with pytest.raises(OperationalError):
+                                    with rls_transaction(tenant_id):
+                                        pass
+
+                                assert mock_atomic.call_count == 3
+
+    def test_rls_transaction_only_one_attempt_for_primary(self, tenants_fixture):
+        """Test only 1 attempt for primary database."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+
+        with patch("api.db_utils.get_read_db_alias", return_value=None):
+            with patch("api.db_utils.connections") as mock_connections:
+                mock_conn = MagicMock()
+                mock_cursor = MagicMock()
+                mock_conn.cursor.return_value.__enter__.return_value = mock_cursor
+                mock_connections.__getitem__.return_value = mock_conn
+                mock_connections.__contains__.return_value = True
+
+                with patch("api.db_utils.transaction.atomic") as mock_atomic:
+                    mock_atomic.side_effect = OperationalError("Primary error")
+
+                    with pytest.raises(OperationalError):
+                        with rls_transaction(tenant_id):
+                            pass
+
+                    assert mock_atomic.call_count == 1
+
+    def test_rls_transaction_fallback_to_primary_after_max_attempts(
+        self, tenants_fixture, enable_read_replica
+    ):
+        """Test fallback to primary DB after max attempts on replica."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+
+        with patch("api.db_utils.get_read_db_alias", return_value=enable_read_replica):
+            with patch("api.db_utils.connections") as mock_connections:
+                mock_conn = MagicMock()
+                mock_cursor = MagicMock()
+                mock_conn.cursor.return_value.__enter__.return_value = mock_cursor
+                mock_connections.__getitem__.return_value = mock_conn
+                mock_connections.__contains__.return_value = True
+
+                call_count = 0
+
+                def atomic_side_effect(*args, **kwargs):
+                    nonlocal call_count
+                    call_count += 1
+                    if call_count < 3:
+                        raise OperationalError("Replica error")
+                    return MagicMock(
+                        __enter__=MagicMock(return_value=None),
+                        __exit__=MagicMock(return_value=False),
+                    )
+
+                with patch(
+                    "api.db_utils.transaction.atomic", side_effect=atomic_side_effect
+                ):
+                    with patch("api.db_utils.time.sleep"):
+                        with patch(
+                            "api.db_utils.set_read_db_alias", return_value="token"
+                        ):
+                            with patch("api.db_utils.reset_read_db_alias"):
+                                with patch("api.db_utils.logger") as mock_logger:
+                                    with rls_transaction(tenant_id):
+                                        pass
+
+                                    mock_logger.warning.assert_called_once()
+                                    warning_msg = mock_logger.warning.call_args[0][0]
+                                    assert "falling back to primary DB" in warning_msg
+
+    def test_rls_transaction_logger_warning_on_fallback(
+        self, tenants_fixture, enable_read_replica
+    ):
+        """Test logger warnings are emitted on fallback to primary."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+
+        with patch("api.db_utils.get_read_db_alias", return_value=enable_read_replica):
+            with patch("api.db_utils.connections") as mock_connections:
+                mock_conn = MagicMock()
+                mock_cursor = MagicMock()
+                mock_conn.cursor.return_value.__enter__.return_value = mock_cursor
+                mock_connections.__getitem__.return_value = mock_conn
+                mock_connections.__contains__.return_value = True
+
+                call_count = 0
+
+                def atomic_side_effect(*args, **kwargs):
+                    nonlocal call_count
+                    call_count += 1
+                    if call_count < 3:
+                        raise OperationalError("Replica error")
+                    return MagicMock(
+                        __enter__=MagicMock(return_value=None),
+                        __exit__=MagicMock(return_value=False),
+                    )
+
+                with patch(
+                    "api.db_utils.transaction.atomic", side_effect=atomic_side_effect
+                ):
+                    with patch("api.db_utils.time.sleep"):
+                        with patch(
+                            "api.db_utils.set_read_db_alias", return_value="token"
+                        ):
+                            with patch("api.db_utils.reset_read_db_alias"):
+                                with patch("api.db_utils.logger") as mock_logger:
+                                    with rls_transaction(tenant_id):
+                                        pass
+
+                                    assert mock_logger.info.call_count == 2
+                                    assert mock_logger.warning.call_count == 1
+
+    def test_rls_transaction_operational_error_raised_immediately_on_primary(
+        self, tenants_fixture
+    ):
+        """Test OperationalError raised immediately on primary without retry."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+
+        with patch("api.db_utils.get_read_db_alias", return_value=None):
+            with patch("api.db_utils.connections") as mock_connections:
+                mock_conn = MagicMock()
+                mock_cursor = MagicMock()
+                mock_conn.cursor.return_value.__enter__.return_value = mock_cursor
+                mock_connections.__getitem__.return_value = mock_conn
+                mock_connections.__contains__.return_value = True
+
+                with patch("api.db_utils.transaction.atomic") as mock_atomic:
+                    mock_atomic.side_effect = OperationalError("Primary error")
+
+                    with patch("api.db_utils.time.sleep") as mock_sleep:
+                        with pytest.raises(OperationalError):
+                            with rls_transaction(tenant_id):
+                                pass
+
+                        mock_sleep.assert_not_called()
+
+    def test_rls_transaction_operational_error_raised_after_max_attempts(
+        self, tenants_fixture, enable_read_replica
+    ):
+        """Test OperationalError raised after max attempts on replica."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+
+        with patch("api.db_utils.get_read_db_alias", return_value=enable_read_replica):
+            with patch("api.db_utils.connections") as mock_connections:
+                mock_conn = MagicMock()
+                mock_cursor = MagicMock()
+                mock_conn.cursor.return_value.__enter__.return_value = mock_cursor
+                mock_connections.__getitem__.return_value = mock_conn
+                mock_connections.__contains__.return_value = True
+
+                with patch("api.db_utils.transaction.atomic") as mock_atomic:
+                    mock_atomic.side_effect = OperationalError(
+                        "Persistent replica error"
+                    )
+
+                    with patch("api.db_utils.time.sleep"):
+                        with patch(
+                            "api.db_utils.set_read_db_alias", return_value="token"
+                        ):
+                            with patch("api.db_utils.reset_read_db_alias"):
+                                with pytest.raises(OperationalError):
+                                    with rls_transaction(tenant_id):
+                                        pass
+
+    def test_rls_transaction_router_token_set_for_non_default_alias(
+        self, tenants_fixture
+    ):
+        """Test router token is set when using non-default alias."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+        custom_alias = "custom_db"
+
+        with patch("api.db_utils.connections") as mock_connections:
+            mock_conn = MagicMock()
+            mock_cursor = MagicMock()
+            mock_conn.cursor.return_value.__enter__.return_value = mock_cursor
+            mock_connections.__getitem__.return_value = mock_conn
+            mock_connections.__contains__.return_value = True
+
+            with patch("api.db_utils.transaction.atomic"):
+                with patch("api.db_utils.set_read_db_alias") as mock_set_alias:
+                    with patch("api.db_utils.reset_read_db_alias") as mock_reset_alias:
+                        mock_set_alias.return_value = "test_token"
+                        with rls_transaction(tenant_id, using=custom_alias):
+                            pass
+
+                        mock_set_alias.assert_called_once_with(custom_alias)
+                        mock_reset_alias.assert_called_once_with("test_token")
+
+    def test_rls_transaction_router_token_reset_in_finally_block(self, tenants_fixture):
+        """Test router token is reset in finally block even on error."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+        custom_alias = "custom_db"
+
+        with patch("api.db_utils.connections") as mock_connections:
+            mock_conn = MagicMock()
+            mock_cursor = MagicMock()
+            mock_conn.cursor.return_value.__enter__.return_value = mock_cursor
+            mock_connections.__getitem__.return_value = mock_conn
+            mock_connections.__contains__.return_value = True
+
+            with patch("api.db_utils.transaction.atomic") as mock_atomic:
+                mock_atomic.side_effect = Exception("Unexpected error")
+
+                with patch("api.db_utils.set_read_db_alias", return_value="test_token"):
+                    with patch("api.db_utils.reset_read_db_alias") as mock_reset_alias:
+                        with pytest.raises(Exception):
+                            with rls_transaction(tenant_id, using=custom_alias):
+                                pass
+
+                        mock_reset_alias.assert_called_once_with("test_token")
+
+    def test_rls_transaction_router_token_not_set_for_default_alias(
+        self, tenants_fixture
+    ):
+        """Test router token is not set when using default alias."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+
+        with patch("api.db_utils.get_read_db_alias", return_value=None):
+            with patch("api.db_utils.connections") as mock_connections:
+                mock_conn = MagicMock()
+                mock_cursor = MagicMock()
+                mock_conn.cursor.return_value.__enter__.return_value = mock_cursor
+                mock_connections.__getitem__.return_value = mock_conn
+                mock_connections.__contains__.return_value = True
+
+                with patch("api.db_utils.transaction.atomic"):
+                    with patch("api.db_utils.set_read_db_alias") as mock_set_alias:
+                        with patch(
+                            "api.db_utils.reset_read_db_alias"
+                        ) as mock_reset_alias:
+                            with rls_transaction(tenant_id):
+                                pass
+
+                            mock_set_alias.assert_not_called()
+                            mock_reset_alias.assert_not_called()
+
+    def test_rls_transaction_set_config_query_executed_with_correct_params(
+        self, tenants_fixture
+    ):
+        """Test SET_CONFIG_QUERY executed with correct parameters."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+
+        with rls_transaction(tenant_id) as cursor:
+            cursor.execute("SELECT current_setting(%s)", [POSTGRES_TENANT_VAR])
+            result = cursor.fetchone()
+            assert result[0] == tenant_id
+
+    def test_rls_transaction_custom_parameter(self, tenants_fixture):
+        """Test rls_transaction with custom parameter name."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+        custom_param = "api.user_id"
+
+        with rls_transaction(tenant_id, parameter=custom_param) as cursor:
+            cursor.execute("SELECT current_setting(%s)", [custom_param])
+            result = cursor.fetchone()
+            assert result[0] == tenant_id
+
+    def test_rls_transaction_cursor_yielded_correctly(self, tenants_fixture):
+        """Test cursor is yielded correctly."""
+        tenant = tenants_fixture[0]
+        tenant_id = str(tenant.id)
+
+        with rls_transaction(tenant_id) as cursor:
+            assert cursor is not None
+            cursor.execute("SELECT 1")
+            result = cursor.fetchone()
+            assert result[0] == 1
diff --git a/api/src/backend/api/tests/test_middleware.py b/api/src/backend/api/tests/test_middleware.py
index 1bd8a07351..07165987de 100644
--- a/api/src/backend/api/tests/test_middleware.py
+++ b/api/src/backend/api/tests/test_middleware.py
@@ -24,6 +24,7 @@ def test_api_logging_middleware_logging(mock_logger):
         mock_extract_auth_info.return_value = {
             "user_id": "user123",
             "tenant_id": "tenant456",
+            "api_key_prefix": "pk_test",
         }
 
         with patch("api.middleware.logging.getLogger") as mock_get_logger:
@@ -44,6 +45,7 @@ def test_api_logging_middleware_logging(mock_logger):
                 expected_extra = {
                     "user_id": "user123",
                     "tenant_id": "tenant456",
+                    "api_key_prefix": "pk_test",
                     "method": "GET",
                     "path": "/test-path",
                     "query_params": {"param1": "value1", "param2": "value2"},
diff --git a/api/src/backend/api/tests/test_rbac.py b/api/src/backend/api/tests/test_rbac.py
index 12271d81b9..addd8b4ec6 100644
--- a/api/src/backend/api/tests/test_rbac.py
+++ b/api/src/backend/api/tests/test_rbac.py
@@ -1,3 +1,4 @@
+import json
 from unittest.mock import ANY, Mock, patch
 
 import pytest
@@ -151,6 +152,221 @@ class TestUserViewSet:
         assert response.status_code == status.HTTP_200_OK
         assert response.json()["data"]["attributes"]["email"] == "rbac_limited@rbac.com"
 
+    def test_me_shows_own_roles_and_memberships_without_manage_account(
+        self, authenticated_client_no_permissions_rbac
+    ):
+        response = authenticated_client_no_permissions_rbac.get(reverse("user-me"))
+        assert response.status_code == status.HTTP_200_OK
+
+        rels = response.json()["data"]["relationships"]
+
+        # Self should see own roles and memberships even without manage_account
+        assert isinstance(rels["roles"]["data"], list)
+        assert rels["memberships"]["meta"]["count"] == 1
+
+    def test_me_shows_roles_and_memberships_with_manage_account(
+        self, authenticated_client_rbac
+    ):
+        response = authenticated_client_rbac.get(reverse("user-me"))
+        assert response.status_code == status.HTTP_200_OK
+
+        rels = response.json()["data"]["relationships"]
+
+        # Roles should have data when manage_account is True
+        assert len(rels["roles"]["data"]) > 0
+
+        # Memberships should be present and count > 0
+        assert rels["memberships"]["meta"]["count"] > 0
+
+    def test_me_include_roles_and_memberships_included_block(
+        self, authenticated_client_rbac
+    ):
+        # Request current user info including roles and memberships
+        response = authenticated_client_rbac.get(
+            reverse("user-me"), {"include": "roles,memberships"}
+        )
+        assert response.status_code == status.HTTP_200_OK
+        payload = response.json()
+
+        # Included must contain memberships corresponding to relationships data
+        rel_memberships = payload["data"]["relationships"]["memberships"]
+        ids_in_relationship = {item["id"] for item in rel_memberships["data"]}
+
+        included = payload["included"]
+        included_membership_ids = {
+            item["id"] for item in included if item["type"] == "memberships"
+        }
+
+        # If there are memberships in relationships, they must be present in included
+        if ids_in_relationship:
+            assert ids_in_relationship.issubset(included_membership_ids)
+        else:
+            # At minimum, included should contain the user's membership when requested
+            # (count should align with meta count)
+            assert rel_memberships["meta"]["count"] == len(included_membership_ids)
+
+    def test_list_users_with_manage_account_only_forbidden(
+        self, authenticated_client_rbac_manage_account
+    ):
+        response = authenticated_client_rbac_manage_account.get(reverse("user-list"))
+        assert response.status_code == status.HTTP_403_FORBIDDEN
+
+    def test_retrieve_other_user_with_manage_account_only_forbidden(
+        self, authenticated_client_rbac_manage_account, create_test_user
+    ):
+        response = authenticated_client_rbac_manage_account.get(
+            reverse("user-detail", kwargs={"pk": create_test_user.id})
+        )
+        assert response.status_code == status.HTTP_403_FORBIDDEN
+
+    def test_list_users_with_manage_users_only_hides_relationships(
+        self, authenticated_client_rbac_manage_users_only
+    ):
+        # Ensure there is at least one other user in the same tenant
+        mu_user = authenticated_client_rbac_manage_users_only.user
+        mu_membership = Membership.objects.filter(user=mu_user).first()
+        tenant = mu_membership.tenant
+
+        other_user = User.objects.create_user(
+            name="other_in_tenant",
+            email="other_in_tenant@rbac.com",
+            password="Password123@",
+        )
+        Membership.objects.create(user=other_user, tenant=tenant)
+
+        response = authenticated_client_rbac_manage_users_only.get(reverse("user-list"))
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert isinstance(data, list)
+
+        current_user_id = str(mu_user.id)
+        assert any(item["id"] == current_user_id for item in data)
+
+        for item in data:
+            rels = item["relationships"]
+            if item["id"] == current_user_id:
+                # Self should see own relationships
+                assert isinstance(rels["roles"]["data"], list)
+                assert rels["memberships"]["meta"].get("count", 0) >= 1
+            else:
+                # Others should be hidden without manage_account
+                assert rels["roles"]["data"] == []
+                assert rels["memberships"]["data"] == []
+                assert rels["memberships"]["meta"]["count"] == 0
+
+    def test_include_roles_hidden_without_manage_account(
+        self, authenticated_client_rbac_manage_users_only
+    ):
+        # Arrange: ensure another user in the same tenant with its own role
+        mu_user = authenticated_client_rbac_manage_users_only.user
+        mu_membership = Membership.objects.filter(user=mu_user).first()
+        tenant = mu_membership.tenant
+
+        other_user = User.objects.create_user(
+            name="other_in_tenant_inc",
+            email="other_in_tenant_inc@rbac.com",
+            password="Password123@",
+        )
+        Membership.objects.create(user=other_user, tenant=tenant)
+        other_role = Role.objects.create(
+            name="other_inc_role",
+            tenant_id=tenant.id,
+            manage_users=False,
+            manage_account=False,
+        )
+        UserRoleRelationship.objects.create(
+            user=other_user, role=other_role, tenant_id=tenant.id
+        )
+
+        response = authenticated_client_rbac_manage_users_only.get(
+            reverse("user-list"), {"include": "roles"}
+        )
+        assert response.status_code == status.HTTP_200_OK
+        payload = response.json()
+
+        # Assert: included must not contain the other user's role
+        included = payload.get("included", [])
+        included_role_ids = {
+            item["id"] for item in included if item.get("type") == "roles"
+        }
+        assert str(other_role.id) not in included_role_ids
+
+        # Relationships for other user should be empty
+        for item in payload["data"]:
+            if item["id"] == str(other_user.id):
+                rels = item["relationships"]
+                assert rels["roles"]["data"] == []
+
+    def test_include_roles_visible_with_manage_account(
+        self, authenticated_client_rbac, tenants_fixture
+    ):
+        # Arrange: another user in tenant[0] with its role
+        tenant = tenants_fixture[0]
+        other_user = User.objects.create_user(
+            name="other_with_role",
+            email="other_with_role@rbac.com",
+            password="Password123@",
+        )
+        Membership.objects.create(user=other_user, tenant=tenant)
+        other_role = Role.objects.create(
+            name="other_visible_role",
+            tenant_id=tenant.id,
+            manage_users=False,
+            manage_account=False,
+        )
+        UserRoleRelationship.objects.create(
+            user=other_user, role=other_role, tenant_id=tenant.id
+        )
+
+        response = authenticated_client_rbac.get(
+            reverse("user-list"), {"include": "roles"}
+        )
+        assert response.status_code == status.HTTP_200_OK
+        payload = response.json()
+
+        # Assert: included must contain the other user's role
+        included = payload.get("included", [])
+        included_role_ids = {
+            item["id"] for item in included if item.get("type") == "roles"
+        }
+        assert str(other_role.id) in included_role_ids
+
+    def test_retrieve_user_with_manage_users_only_hides_relationships(
+        self, authenticated_client_rbac_manage_users_only
+    ):
+        # Create a target user in the same tenant to ensure visibility
+        mu_user = authenticated_client_rbac_manage_users_only.user
+        mu_membership = Membership.objects.filter(user=mu_user).first()
+        tenant = mu_membership.tenant
+
+        target_user = User.objects.create_user(
+            name="target_same_tenant",
+            email="target_same_tenant@rbac.com",
+            password="Password123@",
+        )
+        Membership.objects.create(user=target_user, tenant=tenant)
+
+        response = authenticated_client_rbac_manage_users_only.get(
+            reverse("user-detail", kwargs={"pk": target_user.id})
+        )
+        assert response.status_code == status.HTTP_200_OK
+        rels = response.json()["data"]["relationships"]
+        assert rels["roles"]["data"] == []
+        assert rels["memberships"]["data"] == []
+        assert rels["memberships"]["meta"]["count"] == 0
+
+    def test_list_users_with_all_permissions_shows_relationships(
+        self, authenticated_client_rbac
+    ):
+        response = authenticated_client_rbac.get(reverse("user-list"))
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert isinstance(data, list)
+
+        rels = data[0]["relationships"]
+        assert len(rels["roles"]["data"]) >= 0
+        assert rels["memberships"]["meta"]["count"] >= 0
+
 
 @pytest.mark.django_db
 class TestProviderViewSet:
@@ -494,3 +710,123 @@ class TestLimitedVisibility:
 
         assert response.status_code == status.HTTP_200_OK
         assert len(response.json()["data"]) == 0
+
+
+@pytest.mark.django_db
+class TestRolePermissions:
+    def test_role_create_with_manage_account_only_allowed(
+        self, authenticated_client_rbac_manage_account
+    ):
+        data = {
+            "data": {
+                "type": "roles",
+                "attributes": {
+                    "name": "Role Manage Account Only",
+                    "manage_users": "false",
+                    "manage_account": "true",
+                    "manage_providers": "false",
+                    "manage_scans": "false",
+                    "unlimited_visibility": "false",
+                },
+                "relationships": {"provider_groups": {"data": []}},
+            }
+        }
+        response = authenticated_client_rbac_manage_account.post(
+            reverse("role-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+
+    def test_role_create_with_manage_users_only_forbidden(
+        self, authenticated_client_rbac_manage_users_only
+    ):
+        data = {
+            "data": {
+                "type": "roles",
+                "attributes": {
+                    "name": "Role Manage Users Only",
+                    "manage_users": "true",
+                    "manage_account": "false",
+                    "manage_providers": "false",
+                    "manage_scans": "false",
+                    "unlimited_visibility": "false",
+                },
+                "relationships": {"provider_groups": {"data": []}},
+            }
+        }
+        response = authenticated_client_rbac_manage_users_only.post(
+            reverse("role-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_403_FORBIDDEN
+
+
+@pytest.mark.django_db
+class TestUserRoleLinkPermissions:
+    def test_link_user_roles_with_manage_account_only_allowed(
+        self, authenticated_client_rbac_manage_account
+    ):
+        # Arrange: create a second user in the same tenant as the manage_account user
+        ma_user = authenticated_client_rbac_manage_account.user
+        ma_membership = Membership.objects.filter(user=ma_user).first()
+        tenant = ma_membership.tenant
+
+        user2 = User.objects.create_user(
+            name="target_user",
+            email="target_user_ma@rbac.com",
+            password="Password123@",
+        )
+        Membership.objects.create(user=user2, tenant=tenant)
+
+        # Create a role in the same tenant
+        role = Role.objects.create(
+            name="linkable_role",
+            tenant_id=tenant.id,
+            manage_users=False,
+            manage_account=False,
+        )
+
+        data = {"data": [{"type": "roles", "id": str(role.id)}]}
+
+        # Act
+        response = authenticated_client_rbac_manage_account.post(
+            reverse("user-roles-relationship", kwargs={"pk": user2.id}),
+            data=data,
+            content_type="application/vnd.api+json",
+        )
+
+        # Assert
+        assert response.status_code == status.HTTP_204_NO_CONTENT
+
+    def test_link_user_roles_with_manage_users_only_forbidden(
+        self, authenticated_client_rbac_manage_users_only
+    ):
+        mu_user = authenticated_client_rbac_manage_users_only.user
+        mu_membership = Membership.objects.filter(user=mu_user).first()
+        tenant = mu_membership.tenant
+
+        user2 = User.objects.create_user(
+            name="target_user2",
+            email="target_user_mu@rbac.com",
+            password="Password123@",
+        )
+        Membership.objects.create(user=user2, tenant=tenant)
+
+        role = Role.objects.create(
+            name="linkable_role_mu",
+            tenant_id=tenant.id,
+            manage_users=False,
+            manage_account=False,
+        )
+
+        data = {"data": [{"type": "roles", "id": str(role.id)}]}
+
+        response = authenticated_client_rbac_manage_users_only.post(
+            reverse("user-roles-relationship", kwargs={"pk": user2.id}),
+            data=data,
+            content_type="application/vnd.api+json",
+        )
+
+        assert response.status_code == status.HTTP_403_FORBIDDEN
diff --git a/api/src/backend/api/tests/test_utils.py b/api/src/backend/api/tests/test_utils.py
index 352c8262fa..d67df93ff5 100644
--- a/api/src/backend/api/tests/test_utils.py
+++ b/api/src/backend/api/tests/test_utils.py
@@ -6,20 +6,25 @@ from rest_framework.exceptions import NotFound, ValidationError
 
 from api.db_router import MainRouter
 from api.exceptions import InvitationTokenExpiredException
-from api.models import Invitation, Provider
+from api.models import Integration, Invitation, Provider
 from api.utils import (
     get_prowler_provider_kwargs,
     initialize_prowler_provider,
     merge_dicts,
+    prowler_integration_connection_test,
     prowler_provider_connection_test,
     return_prowler_provider,
     validate_invitation,
 )
 from prowler.providers.aws.aws_provider import AwsProvider
+from prowler.providers.aws.lib.security_hub.security_hub import SecurityHubConnection
 from prowler.providers.azure.azure_provider import AzureProvider
 from prowler.providers.gcp.gcp_provider import GcpProvider
+from prowler.providers.github.github_provider import GithubProvider
 from prowler.providers.kubernetes.kubernetes_provider import KubernetesProvider
 from prowler.providers.m365.m365_provider import M365Provider
+from prowler.providers.mongodbatlas.mongodbatlas_provider import MongodbatlasProvider
+from prowler.providers.oraclecloud.oraclecloud_provider import OraclecloudProvider
 
 
 class TestMergeDicts:
@@ -106,6 +111,9 @@ class TestReturnProwlerProvider:
             (Provider.ProviderChoices.AZURE.value, AzureProvider),
             (Provider.ProviderChoices.KUBERNETES.value, KubernetesProvider),
             (Provider.ProviderChoices.M365.value, M365Provider),
+            (Provider.ProviderChoices.GITHUB.value, GithubProvider),
+            (Provider.ProviderChoices.MONGODBATLAS.value, MongodbatlasProvider),
+            (Provider.ProviderChoices.ORACLECLOUD.value, OraclecloudProvider),
         ],
     )
     def test_return_prowler_provider(self, provider_type, expected_provider):
@@ -197,6 +205,18 @@ class TestGetProwlerProviderKwargs:
                 Provider.ProviderChoices.M365.value,
                 {},
             ),
+            (
+                Provider.ProviderChoices.GITHUB.value,
+                {"organizations": ["provider_uid"]},
+            ),
+            (
+                Provider.ProviderChoices.ORACLECLOUD.value,
+                {},
+            ),
+            (
+                Provider.ProviderChoices.MONGODBATLAS.value,
+                {"atlas_organization_id": "provider_uid"},
+            ),
         ],
     )
     def test_get_prowler_provider_kwargs(self, provider_type, expected_extra_kwargs):
@@ -390,3 +410,258 @@ class TestValidateInvitation:
             mock_db.get.assert_called_once_with(
                 token="VALID_TOKEN", email__iexact="user@example.com"
             )
+
+
+class TestProwlerIntegrationConnectionTest:
+    """Test prowler_integration_connection_test function for SecurityHub regions reset."""
+
+    @patch("api.utils.SecurityHub")
+    def test_security_hub_connection_failure_resets_regions(
+        self, mock_security_hub_class
+    ):
+        """Test that SecurityHub connection failure resets regions to empty dict."""
+        # Create integration with existing regions configuration
+        integration = MagicMock()
+        integration.integration_type = Integration.IntegrationChoices.AWS_SECURITY_HUB
+        integration.credentials = {
+            "aws_access_key_id": "test_key",
+            "aws_secret_access_key": "test_secret",
+        }
+        integration.configuration = {
+            "send_only_fails": True,
+            "regions": {
+                "us-east-1": True,
+                "us-west-2": True,
+                "eu-west-1": False,
+                "ap-south-1": False,
+            },
+        }
+
+        # Mock provider relationship
+        mock_provider = MagicMock()
+        mock_provider.uid = "123456789012"
+        mock_relationship = MagicMock()
+        mock_relationship.provider = mock_provider
+        integration.integrationproviderrelationship_set.first.return_value = (
+            mock_relationship
+        )
+
+        # Mock failed SecurityHub connection
+        mock_connection = SecurityHubConnection(
+            is_connected=False,
+            error=Exception("SecurityHub testing"),
+            enabled_regions=set(),
+            disabled_regions=set(),
+        )
+        mock_security_hub_class.test_connection.return_value = mock_connection
+
+        # Call the function
+        result = prowler_integration_connection_test(integration)
+
+        # Assertions
+        assert result.is_connected is False
+        assert str(result.error) == "SecurityHub testing"
+
+        # Verify regions were completely reset to empty dict
+        assert integration.configuration["regions"] == {}
+
+        # Verify save was called to persist the change
+        integration.save.assert_called_once()
+
+        # Verify test_connection was called with correct parameters
+        mock_security_hub_class.test_connection.assert_called_once_with(
+            aws_account_id="123456789012",
+            raise_on_exception=False,
+            aws_access_key_id="test_key",
+            aws_secret_access_key="test_secret",
+        )
+
+    @patch("api.utils.SecurityHub")
+    def test_security_hub_connection_success_saves_regions(
+        self, mock_security_hub_class
+    ):
+        """Test that successful SecurityHub connection saves regions correctly."""
+        integration = MagicMock()
+        integration.integration_type = Integration.IntegrationChoices.AWS_SECURITY_HUB
+        integration.credentials = {
+            "aws_access_key_id": "valid_key",
+            "aws_secret_access_key": "valid_secret",
+        }
+        integration.configuration = {"send_only_fails": False}
+
+        # Mock provider relationship
+        mock_provider = MagicMock()
+        mock_provider.uid = "123456789012"
+        mock_relationship = MagicMock()
+        mock_relationship.provider = mock_provider
+        integration.integrationproviderrelationship_set.first.return_value = (
+            mock_relationship
+        )
+
+        # Mock successful SecurityHub connection with regions
+        mock_connection = SecurityHubConnection(
+            is_connected=True,
+            error=None,
+            enabled_regions={"us-east-1", "eu-west-1"},
+            disabled_regions={"ap-south-1"},
+        )
+        mock_security_hub_class.test_connection.return_value = mock_connection
+
+        result = prowler_integration_connection_test(integration)
+
+        assert result.is_connected is True
+
+        # Verify regions were saved correctly
+        assert integration.configuration["regions"]["us-east-1"] is True
+        assert integration.configuration["regions"]["eu-west-1"] is True
+        assert integration.configuration["regions"]["ap-south-1"] is False
+        integration.save.assert_called_once()
+
+    @patch("api.utils.rls_transaction")
+    @patch("api.utils.Jira")
+    def test_jira_connection_success_basic_auth(
+        self, mock_jira_class, mock_rls_transaction
+    ):
+        integration = MagicMock()
+        integration.integration_type = Integration.IntegrationChoices.JIRA
+        integration.tenant_id = "test-tenant-id"
+        integration.credentials = {
+            "user_mail": "test@example.com",
+            "api_token": "test_api_token",
+            "domain": "example.atlassian.net",
+        }
+        integration.configuration = {}
+
+        # Mock successful JIRA connection with projects
+        mock_connection = MagicMock()
+        mock_connection.is_connected = True
+        mock_connection.error = None
+        mock_connection.projects = {"PROJ1": "Project 1", "PROJ2": "Project 2"}
+        mock_jira_class.test_connection.return_value = mock_connection
+
+        # Mock rls_transaction context manager
+        mock_rls_transaction.return_value.__enter__ = MagicMock()
+        mock_rls_transaction.return_value.__exit__ = MagicMock()
+
+        result = prowler_integration_connection_test(integration)
+
+        assert result.is_connected is True
+        assert result.error is None
+
+        # Verify JIRA connection was called with correct parameters including domain from credentials
+        mock_jira_class.test_connection.assert_called_once_with(
+            user_mail="test@example.com",
+            api_token="test_api_token",
+            domain="example.atlassian.net",
+            raise_on_exception=False,
+        )
+
+        # Verify rls_transaction was called with correct tenant_id
+        mock_rls_transaction.assert_called_once_with("test-tenant-id")
+
+        # Verify projects were saved to integration configuration
+        assert integration.configuration["projects"] == {
+            "PROJ1": "Project 1",
+            "PROJ2": "Project 2",
+        }
+
+        # Verify integration.save() was called
+        integration.save.assert_called_once()
+
+    @patch("api.utils.rls_transaction")
+    @patch("api.utils.Jira")
+    def test_jira_connection_failure_invalid_credentials(
+        self, mock_jira_class, mock_rls_transaction
+    ):
+        integration = MagicMock()
+        integration.integration_type = Integration.IntegrationChoices.JIRA
+        integration.tenant_id = "test-tenant-id"
+        integration.credentials = {
+            "user_mail": "invalid@example.com",
+            "api_token": "invalid_token",
+            "domain": "invalid.atlassian.net",
+        }
+        integration.configuration = {}
+
+        # Mock failed JIRA connection
+        mock_connection = MagicMock()
+        mock_connection.is_connected = False
+        mock_connection.error = Exception("Authentication failed: Invalid credentials")
+        mock_connection.projects = {}  # Empty projects when connection fails
+        mock_jira_class.test_connection.return_value = mock_connection
+
+        # Mock rls_transaction context manager
+        mock_rls_transaction.return_value.__enter__ = MagicMock()
+        mock_rls_transaction.return_value.__exit__ = MagicMock()
+
+        result = prowler_integration_connection_test(integration)
+
+        assert result.is_connected is False
+        assert "Authentication failed: Invalid credentials" in str(result.error)
+
+        # Verify JIRA connection was called with correct parameters
+        mock_jira_class.test_connection.assert_called_once_with(
+            user_mail="invalid@example.com",
+            api_token="invalid_token",
+            domain="invalid.atlassian.net",
+            raise_on_exception=False,
+        )
+
+        # Verify rls_transaction was called even on failure
+        mock_rls_transaction.assert_called_once_with("test-tenant-id")
+
+        # Verify empty projects dict was saved to integration configuration
+        assert integration.configuration["projects"] == {}
+
+        # Verify integration.save() was called even on connection failure
+        integration.save.assert_called_once()
+
+    @patch("api.utils.rls_transaction")
+    @patch("api.utils.Jira")
+    def test_jira_connection_projects_update_with_existing_configuration(
+        self, mock_jira_class, mock_rls_transaction
+    ):
+        """Test that projects are properly updated when integration already has configuration data"""
+        integration = MagicMock()
+        integration.integration_type = Integration.IntegrationChoices.JIRA
+        integration.tenant_id = "test-tenant-id"
+        integration.credentials = {
+            "user_mail": "test@example.com",
+            "api_token": "test_api_token",
+            "domain": "example.atlassian.net",
+        }
+        integration.configuration = {
+            "issue_types": ["Task"],  # Existing configuration
+            "projects": {"OLD_PROJ": "Old Project"},  # Will be overwritten
+        }
+
+        # Mock successful JIRA connection with new projects
+        mock_connection = MagicMock()
+        mock_connection.is_connected = True
+        mock_connection.error = None
+        mock_connection.projects = {
+            "NEW_PROJ1": "New Project 1",
+            "NEW_PROJ2": "New Project 2",
+        }
+        mock_jira_class.test_connection.return_value = mock_connection
+
+        # Mock rls_transaction context manager
+        mock_rls_transaction.return_value.__enter__ = MagicMock()
+        mock_rls_transaction.return_value.__exit__ = MagicMock()
+
+        result = prowler_integration_connection_test(integration)
+
+        assert result.is_connected is True
+        assert result.error is None
+
+        # Verify projects were updated (old projects replaced with new ones)
+        assert integration.configuration["projects"] == {
+            "NEW_PROJ1": "New Project 1",
+            "NEW_PROJ2": "New Project 2",
+        }
+
+        # Verify other configuration fields were preserved
+        assert integration.configuration["issue_types"] == ["Task"]
+
+        # Verify integration.save() was called
+        integration.save.assert_called_once()
diff --git a/api/src/backend/api/tests/test_views.py b/api/src/backend/api/tests/test_views.py
index 0518cd446a..e5eaa2f836 100644
--- a/api/src/backend/api/tests/test_views.py
+++ b/api/src/backend/api/tests/test_views.py
@@ -4,6 +4,7 @@ import json
 import os
 import tempfile
 from datetime import datetime, timedelta, timezone
+from decimal import Decimal
 from pathlib import Path
 from types import SimpleNamespace
 from unittest.mock import ANY, MagicMock, Mock, patch
@@ -12,6 +13,7 @@ from uuid import uuid4
 
 import jwt
 import pytest
+from allauth.account.models import EmailAddress
 from allauth.socialaccount.models import SocialAccount, SocialApp
 from botocore.exceptions import ClientError, NoCredentialsError
 from conftest import (
@@ -22,6 +24,7 @@ from conftest import (
     today_after_n_days,
 )
 from django.conf import settings
+from django.db.models import Count
 from django.http import JsonResponse
 from django.test import RequestFactory
 from django.urls import reverse
@@ -32,26 +35,40 @@ from rest_framework.response import Response
 from api.compliance import get_compliance_frameworks
 from api.db_router import MainRouter
 from api.models import (
+    ComplianceOverviewSummary,
+    ComplianceRequirementOverview,
+    Finding,
     Integration,
     Invitation,
+    LighthouseProviderConfiguration,
+    LighthouseProviderModels,
+    LighthouseTenantConfiguration,
     Membership,
     Processor,
     Provider,
     ProviderGroup,
     ProviderGroupMembership,
     ProviderSecret,
+    Resource,
     Role,
     RoleProviderGroupRelationship,
     SAMLConfiguration,
     SAMLToken,
     Scan,
+    ScanSummary,
     StateChoices,
+    StatusChoices,
     Task,
+    TenantAPIKey,
+    ThreatScoreSnapshot,
     User,
     UserRoleRelationship,
 )
 from api.rls import Tenant
+from api.v1.serializers import TokenSerializer
 from api.v1.views import ComplianceOverviewViewSet, TenantFinishACSView
+from prowler.lib.check.models import Severity
+from prowler.lib.outputs.finding import Status
 
 
 class TestViewSet:
@@ -324,6 +341,78 @@ class TestUserViewSet:
         assert response.status_code == status.HTTP_400_BAD_REQUEST
         assert User.objects.filter(id=another_user.id).exists()
 
+    def test_users_destroy_cascades_allauth_and_memberships(
+        self, authenticated_client, create_test_user
+    ):
+        # Create related admin-side objects (email + SocialAccount)
+        EmailAddress.objects.create(
+            user=create_test_user,
+            email=create_test_user.email,
+            primary=True,
+            verified=True,
+        )
+        SocialAccount.objects.create(
+            user=create_test_user, provider="fake-provider", uid="uid-fake-provider"
+        )
+
+        # Sanity check pre-conditions
+        assert EmailAddress.objects.filter(user=create_test_user).exists()
+        assert SocialAccount.objects.filter(user=create_test_user).exists()
+        assert Membership.objects.filter(user=create_test_user).exists()
+        assert UserRoleRelationship.objects.filter(user=create_test_user).exists()
+
+        # Delete current user
+        response = authenticated_client.delete(
+            reverse("user-detail", kwargs={"pk": str(create_test_user.id)})
+        )
+        assert response.status_code == status.HTTP_204_NO_CONTENT
+
+        # Assert user and related objects are gone
+        assert not User.objects.filter(id=create_test_user.id).exists()
+        assert not EmailAddress.objects.filter(user_id=create_test_user.id).exists()
+        assert not SocialAccount.objects.filter(user_id=create_test_user.id).exists()
+        assert not Membership.objects.filter(user_id=create_test_user.id).exists()
+        assert not UserRoleRelationship.objects.filter(
+            user_id=create_test_user.id
+        ).exists()
+
+    def test_users_destroy_with_saml_configuration_and_memberships(
+        self, authenticated_client, create_test_user, saml_setup
+    ):
+        # Ensure SAML configuration exists for tenant (from saml_setup fixture)
+        domain = saml_setup["domain"]
+        config = SAMLConfiguration.objects.get(email_domain=domain)
+
+        # Attach a SAML SocialAccount to the user
+        SocialAccount.objects.create(
+            user=create_test_user, provider="saml", uid="uid-saml"
+        )
+
+        # Sanity check pre-conditions
+        assert SocialAccount.objects.filter(
+            user=create_test_user, provider="saml"
+        ).exists()
+        assert Membership.objects.filter(user=create_test_user).exists()
+        assert UserRoleRelationship.objects.filter(user=create_test_user).exists()
+
+        # Delete current user
+        response = authenticated_client.delete(
+            reverse("user-detail", kwargs={"pk": str(create_test_user.id)})
+        )
+        assert response.status_code == status.HTTP_204_NO_CONTENT
+
+        # Assert user-related rows are removed
+        assert not User.objects.filter(id=create_test_user.id).exists()
+        assert not SocialAccount.objects.filter(user_id=create_test_user.id).exists()
+        assert not Membership.objects.filter(user_id=create_test_user.id).exists()
+        assert not UserRoleRelationship.objects.filter(
+            user_id=create_test_user.id
+        ).exists()
+
+        # Tenant-level SAML configuration should remain intact
+        assert SAMLConfiguration.objects.filter(id=config.id).exists()
+        assert SocialApp.objects.filter(provider="saml", client_id=domain).exists()
+
     @pytest.mark.parametrize(
         "attribute_key, attribute_value, error_field",
         [
@@ -867,6 +956,74 @@ class TestProviderViewSet:
         assert response.status_code == status.HTTP_200_OK
         assert len(response.json()["data"]) == len(providers_fixture)
 
+    def test_providers_filter_provider_type(
+        self, authenticated_client, providers_fixture
+    ):
+        response = authenticated_client.get(
+            reverse("provider-list"), {"filter[provider_type]": "aws"}
+        )
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert len(data) == 2
+        assert all(item["attributes"]["provider"] == "aws" for item in data)
+
+    def test_providers_filter_provider_type_in(
+        self, authenticated_client, providers_fixture
+    ):
+        response = authenticated_client.get(
+            reverse("provider-list"), {"filter[provider_type__in]": "aws,gcp"}
+        )
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert len(data) == 3
+        assert {"aws", "gcp"} >= {item["attributes"]["provider"] for item in data}
+
+    def test_providers_filter_provider_type_invalid(
+        self, authenticated_client, providers_fixture
+    ):
+        response = authenticated_client.get(
+            reverse("provider-list"), {"filter[provider_type]": "invalid"}
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+
+    def test_providers_disable_pagination(
+        self, authenticated_client, providers_fixture, tenants_fixture
+    ):
+        tenant, *_ = tenants_fixture
+        existing_count = Provider.objects.filter(tenant_id=tenant.id).count()
+        target_total = settings.REST_FRAMEWORK["PAGE_SIZE"] + 1
+        additional_needed = max(0, target_total - existing_count)
+
+        base_uid = 200000000000
+        for index in range(additional_needed):
+            Provider.objects.create(
+                tenant_id=tenant.id,
+                provider=Provider.ProviderChoices.AWS,
+                uid=f"{base_uid + index:012d}",
+                alias=f"aws_extra_{index}",
+            )
+
+        total_providers = Provider.objects.filter(tenant_id=tenant.id).count()
+
+        paginated_response = authenticated_client.get(reverse("provider-list"))
+        assert paginated_response.status_code == status.HTTP_200_OK
+        paginated_data = paginated_response.json()["data"]
+        assert len(paginated_data) == min(
+            settings.REST_FRAMEWORK["PAGE_SIZE"], total_providers
+        )
+        paginated_meta = paginated_response.json().get("meta", {})
+        assert "pagination" in paginated_meta
+        assert paginated_meta["pagination"]["count"] == total_providers
+
+        unpaginated_response = authenticated_client.get(
+            reverse("provider-list"), {"page[disable]": "true"}
+        )
+        assert unpaginated_response.status_code == status.HTTP_200_OK
+        unpaginated_data = unpaginated_response.json()["data"]
+        assert len(unpaginated_data) == total_providers
+        unpaginated_meta = unpaginated_response.json().get("meta", {})
+        assert "pagination" not in unpaginated_meta
+
     @pytest.mark.parametrize(
         "include_values, expected_resources",
         [
@@ -991,6 +1148,21 @@ class TestProviderViewSet:
                     "uid": "a12345678901234567890123456789012345678",
                     "alias": "Long Username",
                 },
+                {
+                    "provider": "iac",
+                    "uid": "https://github.com/user/repo.git",
+                    "alias": "Git Repo",
+                },
+                {
+                    "provider": "iac",
+                    "uid": "https://gitlab.com/user/project",
+                    "alias": "GitLab Repo",
+                },
+                {
+                    "provider": "mongodbatlas",
+                    "uid": "64b1d3c0e4b03b1234567890",
+                    "alias": "Atlas Organization",
+                },
             ]
         ),
     )
@@ -1004,6 +1176,161 @@ class TestProviderViewSet:
         assert Provider.objects.get().uid == provider_json_payload["uid"]
         assert Provider.objects.get().alias == provider_json_payload["alias"]
 
+    @pytest.mark.parametrize(
+        "provider_json_payload",
+        (
+            [
+                {"provider": "aws", "uid": "111111111111", "alias": "test"},
+                {"provider": "gcp", "uid": "a12322-test54321", "alias": "test"},
+                {
+                    "provider": "kubernetes",
+                    "uid": "kubernetes-test-123456789",
+                    "alias": "test",
+                },
+                {
+                    "provider": "kubernetes",
+                    "uid": "arn:aws:eks:us-east-1:111122223333:cluster/test-cluster-long-name-123456789",
+                    "alias": "EKS",
+                },
+                {
+                    "provider": "kubernetes",
+                    "uid": "gke_aaaa-dev_europe-test1_dev-aaaa-test-cluster-long-name-123456789",
+                    "alias": "GKE",
+                },
+                {
+                    "provider": "kubernetes",
+                    "uid": "gke_project/cluster-name",
+                    "alias": "GKE",
+                },
+                {
+                    "provider": "kubernetes",
+                    "uid": "admin@k8s-demo",
+                    "alias": "test",
+                },
+                {
+                    "provider": "azure",
+                    "uid": "8851db6b-42e5-4533-aa9e-30a32d67e875",
+                    "alias": "test",
+                },
+                {
+                    "provider": "m365",
+                    "uid": "TestingPro.onmicrosoft.com",
+                    "alias": "test",
+                },
+                {
+                    "provider": "m365",
+                    "uid": "subdomain.domain.es",
+                    "alias": "test",
+                },
+                {
+                    "provider": "m365",
+                    "uid": "microsoft.net",
+                    "alias": "test",
+                },
+                {
+                    "provider": "m365",
+                    "uid": "subdomain1.subdomain2.subdomain3.subdomain4.domain.net",
+                    "alias": "test",
+                },
+                {
+                    "provider": "github",
+                    "uid": "test-user",
+                    "alias": "test",
+                },
+                {
+                    "provider": "github",
+                    "uid": "test-organization",
+                    "alias": "GitHub Org",
+                },
+                {
+                    "provider": "github",
+                    "uid": "prowler-cloud",
+                    "alias": "Prowler",
+                },
+                {
+                    "provider": "github",
+                    "uid": "microsoft",
+                    "alias": "Microsoft",
+                },
+                {
+                    "provider": "github",
+                    "uid": "a12345678901234567890123456789012345678",
+                    "alias": "Long Username",
+                },
+            ]
+        ),
+    )
+    @patch("api.v1.views.Task.objects.get")
+    @patch("api.v1.views.delete_provider_task.delay")
+    def test_providers_soft_delete(
+        self,
+        mock_delete_task,
+        mock_task_get,
+        authenticated_client,
+        provider_json_payload,
+        tasks_fixture,
+    ):
+        # Mock the Celery task response
+        prowler_task = tasks_fixture[0]
+        task_mock = Mock()
+        task_mock.id = prowler_task.id
+        mock_delete_task.return_value = task_mock
+        mock_task_get.return_value = prowler_task
+
+        # 1.Create a provider
+        response = authenticated_client.post(
+            reverse("provider-list"), data=provider_json_payload, format="json"
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+        assert Provider.objects.count() == 1
+        provider_id = response.json()["data"]["id"]
+
+        # 2. Soft delete the provider using the actual API endpoint
+        response = authenticated_client.delete(
+            reverse("provider-detail", kwargs={"pk": provider_id})
+        )
+        assert response.status_code == status.HTTP_202_ACCEPTED
+        assert Provider.objects.count() == 0
+        assert Provider.all_objects.count() == 1
+
+        mock_delete_task.assert_called_once_with(
+            provider_id=str(provider_id), tenant_id=ANY
+        )
+
+        # 3. Create a provider with the same UID should succeed (since the old one is soft deleted)
+        response = authenticated_client.post(
+            reverse("provider-list"), data=provider_json_payload, format="json"
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+        assert Provider.objects.count() == 1
+        assert Provider.all_objects.count() == 2
+        provider_id = response.json()["data"]["id"]
+
+        # 4. Creating another provider with the same UID should fail (duplicate)
+        response = authenticated_client.post(
+            reverse("provider-list"), data=provider_json_payload, format="json"
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+
+        mock_delete_task.reset_mock()
+        mock_delete_task.return_value = task_mock
+
+        # 5. Delete the second provider
+        response = authenticated_client.delete(
+            reverse("provider-detail", kwargs={"pk": provider_id})
+        )
+        assert response.status_code == status.HTTP_202_ACCEPTED
+        assert Provider.objects.count() == 0
+        assert Provider.all_objects.count() == 2
+
+        # 6. Creating a provider with the same UID should succeed again
+        response = authenticated_client.post(
+            reverse("provider-list"), data=provider_json_payload, format="json"
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+        assert Provider.objects.count() == 1
+        assert Provider.all_objects.count() == 3
+
     @pytest.mark.parametrize(
         "provider_json_payload, error_code, error_pointer",
         (
@@ -1140,6 +1467,51 @@ class TestProviderViewSet:
                     "github-uid",
                     "uid",
                 ),
+                (
+                    {
+                        "provider": "iac",
+                        "uid": "not-a-url",
+                        "alias": "test",
+                    },
+                    "iac-uid",
+                    "uid",
+                ),
+                (
+                    {
+                        "provider": "iac",
+                        "uid": "ftp://invalid-protocol.com/repo",
+                        "alias": "test",
+                    },
+                    "iac-uid",
+                    "uid",
+                ),
+                (
+                    {
+                        "provider": "iac",
+                        "uid": "http://",
+                        "alias": "test",
+                    },
+                    "iac-uid",
+                    "uid",
+                ),
+                (
+                    {
+                        "provider": "mongodbatlas",
+                        "uid": "64b1d3c0e4b03b123456789g",
+                        "alias": "test",
+                    },
+                    "mongodbatlas-uid",
+                    "uid",
+                ),
+                (
+                    {
+                        "provider": "mongodbatlas",
+                        "uid": "1234",
+                        "alias": "test",
+                    },
+                    "mongodbatlas-uid",
+                    "uid",
+                ),
             ]
         ),
     )
@@ -1310,13 +1682,25 @@ class TestProviderViewSet:
                 ("provider", "aws", 2),
                 ("provider.in", "azure,gcp", 2),
                 ("uid", "123456789012", 1),
-                ("uid.icontains", "1", 5),
+                (
+                    "uid.icontains",
+                    "1",
+                    7,
+                ),
                 ("alias", "aws_testing_1", 1),
                 ("alias.icontains", "aws", 2),
-                ("inserted_at", TODAY, 6),
-                ("inserted_at.gte", "2024-01-01", 6),
+                ("inserted_at", TODAY, 8),
+                (
+                    "inserted_at.gte",
+                    "2024-01-01",
+                    8,
+                ),
                 ("inserted_at.lte", "2024-01-01", 0),
-                ("updated_at.gte", "2024-01-01", 6),
+                (
+                    "updated_at.gte",
+                    "2024-01-01",
+                    8,
+                ),
                 ("updated_at.lte", "2024-01-01", 0),
             ]
         ),
@@ -1795,39 +2179,7 @@ class TestProviderSecretViewSet:
                     "kubeconfig_content": "kubeconfig-content",
                 },
             ),
-            # M365 with STATIC secret - no user or password
-            (
-                Provider.ProviderChoices.M365.value,
-                ProviderSecret.TypeChoices.STATIC,
-                {
-                    "client_id": "client-id",
-                    "client_secret": "client-secret",
-                    "tenant_id": "tenant-id",
-                },
-            ),
-            # M365 with user only
-            (
-                Provider.ProviderChoices.M365.value,
-                ProviderSecret.TypeChoices.STATIC,
-                {
-                    "client_id": "client-id",
-                    "client_secret": "client-secret",
-                    "tenant_id": "tenant-id",
-                    "user": "test@domain.com",
-                },
-            ),
-            # M365 with password only
-            (
-                Provider.ProviderChoices.M365.value,
-                ProviderSecret.TypeChoices.STATIC,
-                {
-                    "client_id": "client-id",
-                    "client_secret": "client-secret",
-                    "tenant_id": "tenant-id",
-                    "password": "supersecret",
-                },
-            ),
-            # M365 with user and password
+            # M365 client secret credentials
             (
                 Provider.ProviderChoices.M365.value,
                 ProviderSecret.TypeChoices.STATIC,
@@ -1839,6 +2191,64 @@ class TestProviderSecretViewSet:
                     "password": "supersecret",
                 },
             ),
+            # M365 certificate credentials (valid base64)
+            (
+                Provider.ProviderChoices.M365.value,
+                ProviderSecret.TypeChoices.STATIC,
+                {
+                    "client_id": "client-id",
+                    "tenant_id": "tenant-id",
+                    "certificate_content": "VGVzdCBjZXJ0aWZpY2F0ZSBjb250ZW50",
+                    "user": "test@domain.com",
+                    "password": "supersecret",
+                },
+            ),
+            # OCI with API key credentials (with key_content)
+            (
+                Provider.ProviderChoices.ORACLECLOUD.value,
+                ProviderSecret.TypeChoices.STATIC,
+                {
+                    "user": "ocid1.user.oc1..aaaaaaaakldibrbov4ubh25aqdeiroklxjngwka7u6w7no3glmdq3n5sxtkq",
+                    "fingerprint": "aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99",
+                    "key_content": "-----BEGIN RSA PRIVATE KEY-----\ntest-key-content\n-----END RSA PRIVATE KEY-----",
+                    "tenancy": "ocid1.tenancy.oc1..aaaaaaaa3dwoazoox4q7wrvriywpokp5grlhgnkwtyt6dmwyou7no6mdmzda",
+                    "region": "us-ashburn-1",
+                },
+            ),
+            # OCI with API key credentials (with key_file)
+            (
+                Provider.ProviderChoices.ORACLECLOUD.value,
+                ProviderSecret.TypeChoices.STATIC,
+                {
+                    "user": "ocid1.user.oc1..aaaaaaaakldibrbov4ubh25aqdeiroklxjngwka7u6w7no3glmdq3n5sxtkq",
+                    "fingerprint": "aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99",
+                    "key_file": "/path/to/oci_api_key.pem",
+                    "tenancy": "ocid1.tenancy.oc1..aaaaaaaa3dwoazoox4q7wrvriywpokp5grlhgnkwtyt6dmwyou7no6mdmzda",
+                    "region": "us-ashburn-1",
+                },
+            ),
+            # OCI with API key credentials (with passphrase)
+            (
+                Provider.ProviderChoices.ORACLECLOUD.value,
+                ProviderSecret.TypeChoices.STATIC,
+                {
+                    "user": "ocid1.user.oc1..aaaaaaaakldibrbov4ubh25aqdeiroklxjngwka7u6w7no3glmdq3n5sxtkq",
+                    "fingerprint": "aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99",
+                    "key_content": "-----BEGIN RSA PRIVATE KEY-----\ntest-encrypted-key\n-----END RSA PRIVATE KEY-----",
+                    "tenancy": "ocid1.tenancy.oc1..aaaaaaaa3dwoazoox4q7wrvriywpokp5grlhgnkwtyt6dmwyou7no6mdmzda",
+                    "region": "us-ashburn-1",
+                    "pass_phrase": "my-secure-passphrase",
+                },
+            ),
+            # MongoDB Atlas credentials
+            (
+                Provider.ProviderChoices.MONGODBATLAS.value,
+                ProviderSecret.TypeChoices.STATIC,
+                {
+                    "atlas_public_key": "public-key",
+                    "atlas_private_key": "private-key",
+                },
+            ),
         ],
     )
     def test_provider_secrets_create_valid(
@@ -2204,6 +2614,50 @@ class TestProviderSecretViewSet:
         )
         assert response.status_code == status.HTTP_400_BAD_REQUEST
 
+    def test_m365_provider_secrets_invalid_certificate_base64(
+        self, authenticated_client, providers_fixture
+    ):
+        """Test M365 provider secret creation with invalid base64 certificate content"""
+        # Find M365 provider from fixture
+        m365_provider = None
+        for provider in providers_fixture:
+            if provider.provider == Provider.ProviderChoices.M365.value:
+                m365_provider = provider
+                break
+
+        assert m365_provider is not None, "M365 provider not found in fixture"
+
+        data = {
+            "data": {
+                "type": "provider-secrets",
+                "attributes": {
+                    "name": "M365 Certificate Invalid Base64",
+                    "secret_type": "static",
+                    "secret": {
+                        "client_id": "client-id",
+                        "tenant_id": "tenant-id",
+                        "certificate_content": "invalid-base64-content!@#$%",
+                        "user": "test@domain.com",
+                        "password": "supersecret",
+                    },
+                },
+                "relationships": {
+                    "provider": {
+                        "data": {"type": "providers", "id": str(m365_provider.id)}
+                    }
+                },
+            }
+        }
+        response = authenticated_client.post(
+            reverse("providersecret-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+        assert "certificate content is not valid base64 encoded data" in str(
+            response.json()
+        )
+
 
 @pytest.mark.django_db
 class TestScanViewSet:
@@ -2589,6 +3043,55 @@ class TestScanViewSet:
             == "There is a problem with credentials."
         )
 
+    @patch("api.v1.views.ScanViewSet._get_task_status")
+    @patch("api.v1.views.get_s3_client")
+    @patch("api.v1.views.env.str")
+    def test_threatscore_s3_wildcard(
+        self,
+        mock_env_str,
+        mock_get_s3_client,
+        mock_get_task_status,
+        authenticated_client,
+        scans_fixture,
+    ):
+        """
+        When the threatscore endpoint is called with an S3 output_location,
+        the view should list objects in S3 using wildcard pattern matching,
+        retrieve the matching PDF file, and return it with HTTP 200 and proper headers.
+        """
+        scan = scans_fixture[0]
+        scan.state = StateChoices.COMPLETED
+        bucket = "test-bucket"
+        zip_key = "tenant-id/scan-id/prowler-output-foo.zip"
+        scan.output_location = f"s3://{bucket}/{zip_key}"
+        scan.save()
+
+        pdf_key = os.path.join(
+            os.path.dirname(zip_key),
+            "threatscore",
+            "prowler-output-123_threatscore_report.pdf",
+        )
+
+        mock_s3_client = Mock()
+        mock_s3_client.list_objects_v2.return_value = {"Contents": [{"Key": pdf_key}]}
+        mock_s3_client.get_object.return_value = {"Body": io.BytesIO(b"pdf-bytes")}
+
+        mock_env_str.return_value = bucket
+        mock_get_s3_client.return_value = mock_s3_client
+        mock_get_task_status.return_value = None
+
+        url = reverse("scan-threatscore", kwargs={"pk": scan.id})
+        response = authenticated_client.get(url)
+
+        assert response.status_code == status.HTTP_200_OK
+        assert response["Content-Type"] == "application/pdf"
+        assert response["Content-Disposition"].endswith(
+            '"prowler-output-123_threatscore_report.pdf"'
+        )
+        assert response.content == b"pdf-bytes"
+        mock_s3_client.list_objects_v2.assert_called_once()
+        mock_s3_client.get_object.assert_called_once_with(Bucket=bucket, Key=pdf_key)
+
     def test_report_s3_success(self, authenticated_client, scans_fixture, monkeypatch):
         """
         When output_location is an S3 URL and the S3 client returns the file successfully,
@@ -3042,6 +3545,9 @@ class TestResourceViewSet:
         )
         assert response.status_code == status.HTTP_200_OK
         assert len(response.json()["data"]) == len(resources_fixture)
+        assert "metadata" in response.json()["data"][0]["attributes"]
+        assert "details" in response.json()["data"][0]["attributes"]
+        assert "partition" in response.json()["data"][0]["attributes"]
 
     @pytest.mark.parametrize(
         "include_values, expected_resources",
@@ -4720,6 +5226,36 @@ class TestRoleViewSet:
         assert role.users.count() == 0
         assert role.provider_groups.count() == 0
 
+    def test_cannot_remove_own_assignment_via_role_update(
+        self, authenticated_client, roles_fixture
+    ):
+        role = roles_fixture[0]
+        # Ensure the authenticated user is assigned to this role
+        user = User.objects.get(email=TEST_USER)
+        if not UserRoleRelationship.objects.filter(user=user, role=role).exists():
+            UserRoleRelationship.objects.create(
+                user=user, role=role, tenant_id=role.tenant_id
+            )
+
+        # Attempt to update role users to exclude the current user
+        data = {
+            "data": {
+                "id": str(role.id),
+                "type": "roles",
+                "relationships": {"users": {"data": []}},
+            }
+        }
+        response = authenticated_client.patch(
+            reverse("role-detail", kwargs={"pk": role.id}),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+        assert (
+            "cannot remove their own role"
+            in response.json()["errors"][0]["detail"].lower()
+        )
+
     def test_role_create_with_invalid_user_relationship(
         self, authenticated_client, provider_groups_fixture
     ):
@@ -4841,15 +5377,134 @@ class TestUserRoleRelationshipViewSet:
             roles_fixture[2].id,
         }
 
-    def test_destroy_relationship(
-        self, authenticated_client, roles_fixture, create_test_user
+    def test_destroy_relationship_other_user(
+        self, authenticated_client, roles_fixture, create_test_user, tenants_fixture
     ):
+        # Create another user in same tenant and assign a role
+        tenant = tenants_fixture[0]
+        other_user = User.objects.create_user(
+            name="other",
+            email="other_user@prowler.com",
+            password="TmpPass123@",
+        )
+        Membership.objects.create(user=other_user, tenant=tenant)
+        UserRoleRelationship.objects.create(
+            user=other_user, role=roles_fixture[0], tenant_id=tenant.id
+        )
+
+        # Delete roles for the other user (allowed)
+        response = authenticated_client.delete(
+            reverse("user-roles-relationship", kwargs={"pk": other_user.id}),
+        )
+        assert response.status_code == status.HTTP_204_NO_CONTENT
+        relationships = UserRoleRelationship.objects.filter(user=other_user.id)
+        assert relationships.count() == 0
+
+    def test_cannot_delete_own_roles(self, authenticated_client, create_test_user):
+        # Attempt to delete own roles should be forbidden
         response = authenticated_client.delete(
             reverse("user-roles-relationship", kwargs={"pk": create_test_user.id}),
         )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+
+    def test_prevent_removing_last_manage_account_on_patch(
+        self, authenticated_client, roles_fixture, create_test_user, tenants_fixture
+    ):
+        # roles_fixture[1] has manage_account=False
+        limited_role = roles_fixture[1]
+
+        # Ensure there is no other user with MANAGE_ACCOUNT in the tenant
+        tenant = tenants_fixture[0]
+        # Create a secondary user without MANAGE_ACCOUNT
+        user2 = User.objects.create_user(
+            name="limited_user",
+            email="limited_user@prowler.com",
+            password="TmpPass123@",
+        )
+        Membership.objects.create(user=user2, tenant=tenant)
+        UserRoleRelationship.objects.create(
+            user=user2, role=limited_role, tenant_id=tenant.id
+        )
+
+        # Attempt to switch the only MANAGE_ACCOUNT user to a role without it
+        data = {"data": [{"type": "roles", "id": str(limited_role.id)}]}
+        response = authenticated_client.patch(
+            reverse("user-roles-relationship", kwargs={"pk": create_test_user.id}),
+            data=data,
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+        assert "MANAGE_ACCOUNT" in response.json()["errors"][0]["detail"]
+
+    def test_allow_role_change_when_other_user_has_manage_account_on_patch(
+        self, authenticated_client, roles_fixture, create_test_user, tenants_fixture
+    ):
+        # roles_fixture[1] has manage_account=False, roles_fixture[0] has manage_account=True
+        limited_role = roles_fixture[1]
+        ma_role = roles_fixture[0]
+
+        tenant = tenants_fixture[0]
+        # Create another user with MANAGE_ACCOUNT
+        user2 = User.objects.create_user(
+            name="ma_user",
+            email="ma_user@prowler.com",
+            password="TmpPass123@",
+        )
+        Membership.objects.create(user=user2, tenant=tenant)
+        UserRoleRelationship.objects.create(
+            user=user2, role=ma_role, tenant_id=tenant.id
+        )
+
+        # Now changing the first user's roles to a non-MA role should succeed
+        data = {"data": [{"type": "roles", "id": str(limited_role.id)}]}
+        response = authenticated_client.patch(
+            reverse("user-roles-relationship", kwargs={"pk": create_test_user.id}),
+            data=data,
+            content_type="application/vnd.api+json",
+        )
         assert response.status_code == status.HTTP_204_NO_CONTENT
-        relationships = UserRoleRelationship.objects.filter(role=roles_fixture[0].id)
-        assert relationships.count() == 0
+
+    def test_role_destroy_only_manage_account_blocked(
+        self, authenticated_client, tenants_fixture
+    ):
+        # Use a tenant without default admin role (tenant3)
+        tenant = tenants_fixture[2]
+        user = User.objects.get(email=TEST_USER)
+        # Add membership for this tenant
+        Membership.objects.create(user=user, tenant=tenant)
+
+        # Create a single MANAGE_ACCOUNT role in this tenant
+        only_role = Role.objects.create(
+            name="only_ma",
+            tenant=tenant,
+            manage_users=True,
+            manage_account=True,
+            manage_billing=False,
+            manage_providers=False,
+            manage_integrations=False,
+            manage_scans=False,
+            unlimited_visibility=False,
+        )
+
+        # Switch token to this tenant
+        serializer = TokenSerializer(
+            data={
+                "type": "tokens",
+                "email": TEST_USER,
+                "password": TEST_PASSWORD,
+                "tenant_id": str(tenant.id),
+            }
+        )
+        serializer.is_valid(raise_exception=True)
+        access_token = serializer.validated_data["access"]
+        authenticated_client.defaults["HTTP_AUTHORIZATION"] = f"Bearer {access_token}"
+
+        # Attempt to delete the only MANAGE_ACCOUNT role
+        response = authenticated_client.delete(
+            reverse("role-detail", kwargs={"pk": only_role.id})
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+        assert Role.objects.filter(id=only_role.id).exists()
 
     def test_invalid_provider_group_id(self, authenticated_client, create_test_user):
         invalid_id = "non-existent-id"
@@ -5165,16 +5820,44 @@ class TestProviderGroupMembershipViewSet:
 
 @pytest.mark.django_db
 class TestComplianceOverviewViewSet:
-    def test_compliance_overview_list_none(self, authenticated_client):
+    @pytest.fixture(autouse=True)
+    def mock_backfill_task(self):
+        with patch("api.v1.views.backfill_compliance_summaries_task.delay") as mock:
+            yield mock
+
+    def test_compliance_overview_list_none(
+        self,
+        authenticated_client,
+        tenants_fixture,
+        providers_fixture,
+        mock_backfill_task,
+    ):
+        tenant = tenants_fixture[0]
+        provider = providers_fixture[0]
+        scan = Scan.objects.create(
+            name="empty-compliance-scan",
+            provider=provider,
+            trigger=Scan.TriggerChoices.MANUAL,
+            state=StateChoices.COMPLETED,
+            tenant=tenant,
+        )
+
         response = authenticated_client.get(
             reverse("complianceoverview-list"),
-            {"filter[scan_id]": "8d20ac7d-4cbc-435e-85f4-359be37af821"},
+            {"filter[scan_id]": str(scan.id)},
         )
         assert response.status_code == status.HTTP_200_OK
         assert len(response.json()["data"]) == 0
+        mock_backfill_task.assert_called_once()
+        _, kwargs = mock_backfill_task.call_args
+        assert kwargs["scan_id"] == str(scan.id)
+        assert str(kwargs["tenant_id"]) == str(tenant.id)
 
     def test_compliance_overview_list(
-        self, authenticated_client, compliance_requirements_overviews_fixture
+        self,
+        authenticated_client,
+        compliance_requirements_overviews_fixture,
+        mock_backfill_task,
     ):
         # List compliance overviews with existing data
         requirement_overview1 = compliance_requirements_overviews_fixture[0]
@@ -5204,6 +5887,112 @@ class TestComplianceOverviewViewSet:
             assert "requirements_failed" in attributes
             assert "requirements_manual" in attributes
             assert "total_requirements" in attributes
+        mock_backfill_task.assert_called_once()
+        _, kwargs = mock_backfill_task.call_args
+        assert kwargs["scan_id"] == scan_id
+
+    def test_compliance_overview_list_uses_preaggregated_summaries(
+        self,
+        authenticated_client,
+        tenants_fixture,
+        providers_fixture,
+        mock_backfill_task,
+    ):
+        tenant = tenants_fixture[0]
+        provider = providers_fixture[0]
+        scan = Scan.objects.create(
+            name="preaggregated-scan",
+            provider=provider,
+            trigger=Scan.TriggerChoices.MANUAL,
+            state=StateChoices.COMPLETED,
+            tenant=tenant,
+        )
+
+        ComplianceRequirementOverview.objects.create(
+            tenant=tenant,
+            scan=scan,
+            compliance_id="cis_1.4_aws",
+            framework="CIS-1.4-AWS",
+            version="1.4",
+            description="CIS AWS Foundations Benchmark v1.4.0",
+            region="eu-west-1",
+            requirement_id="framework-metadata",
+            requirement_status=StatusChoices.PASS,
+            passed_checks=1,
+            failed_checks=0,
+            total_checks=1,
+        )
+
+        ComplianceOverviewSummary.objects.create(
+            tenant=tenant,
+            scan=scan,
+            compliance_id="cis_1.4_aws",
+            requirements_passed=5,
+            requirements_failed=1,
+            requirements_manual=2,
+            total_requirements=8,
+        )
+
+        response = authenticated_client.get(
+            reverse("complianceoverview-list"),
+            {"filter[scan_id]": str(scan.id)},
+        )
+
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert len(data) == 1
+        overview = data[0]
+        assert overview["id"] == "cis_1.4_aws"
+        assert overview["attributes"]["requirements_passed"] == 5
+        assert overview["attributes"]["requirements_failed"] == 1
+        assert overview["attributes"]["requirements_manual"] == 2
+        assert overview["attributes"]["total_requirements"] == 8
+        assert "framework" in overview["attributes"]
+        assert "version" in overview["attributes"]
+        mock_backfill_task.assert_not_called()
+
+    def test_compliance_overview_region_filter_skips_backfill(
+        self,
+        authenticated_client,
+        compliance_requirements_overviews_fixture,
+        mock_backfill_task,
+    ):
+        requirement_overview = compliance_requirements_overviews_fixture[0]
+        scan_id = str(requirement_overview.scan.id)
+
+        response = authenticated_client.get(
+            reverse("complianceoverview-list"),
+            {
+                "filter[scan_id]": scan_id,
+                "filter[region]": requirement_overview.region,
+            },
+        )
+
+        assert response.status_code == status.HTTP_200_OK
+        assert len(response.json()["data"]) >= 1
+        mock_backfill_task.assert_not_called()
+
+    def test_compliance_overview_list_without_scan_id(
+        self, authenticated_client, compliance_requirements_overviews_fixture
+    ):
+        # Ensure the endpoint works without passing a scan filter
+        response = authenticated_client.get(reverse("complianceoverview-list"))
+
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert len(data) == 3
+
+        # Validate payload structure
+        first_item = data[0]
+        assert "id" in first_item
+        assert "attributes" in first_item
+        attributes = first_item["attributes"]
+        assert "framework" in attributes
+        assert "version" in attributes
+        assert "requirements_passed" in attributes
+        assert "requirements_failed" in attributes
+        assert "requirements_manual" in attributes
+        assert "total_requirements" in attributes
 
     def test_compliance_overview_metadata(
         self, authenticated_client, compliance_requirements_overviews_fixture
@@ -5357,6 +6146,11 @@ class TestComplianceOverviewViewSet:
         requirement_overview1 = compliance_requirements_overviews_fixture[0]
         scan_id = str(requirement_overview1.scan.id)
 
+        # Remove existing compliance data so the view falls back to task checks
+        scan = requirement_overview1.scan
+        ComplianceOverviewSummary.objects.filter(scan=scan).delete()
+        ComplianceRequirementOverview.objects.filter(scan=scan).delete()
+
         # Mock a running task
         with patch.object(
             ComplianceOverviewViewSet, "get_task_response_if_running"
@@ -5384,6 +6178,11 @@ class TestComplianceOverviewViewSet:
         requirement_overview1 = compliance_requirements_overviews_fixture[0]
         scan_id = str(requirement_overview1.scan.id)
 
+        # Remove existing compliance data so the view falls back to task checks
+        scan = requirement_overview1.scan
+        ComplianceOverviewSummary.objects.filter(scan=scan).delete()
+        ComplianceRequirementOverview.objects.filter(scan=scan).delete()
+
         # Mock a failed task
         with patch.object(
             ComplianceOverviewViewSet, "get_task_response_if_running"
@@ -5407,6 +6206,8 @@ class TestComplianceOverviewViewSet:
             ("framework", "framework", 1),
             ("version", "version", 1),
             ("region", "region", 1),
+            ("region__in", "region", 1),
+            ("region.in", "region", 1),
         ],
     )
     def test_compliance_overview_filters(
@@ -5483,14 +6284,505 @@ class TestOverviewViewSet:
         assert response.json()["data"][0]["attributes"]["findings"]["pass"] == 2
         assert response.json()["data"][0]["attributes"]["findings"]["fail"] == 1
         assert response.json()["data"][0]["attributes"]["findings"]["muted"] == 1
-        # Since we rely on completed scans, there are only 2 resources now
-        assert response.json()["data"][0]["attributes"]["resources"]["total"] == 2
+        # Aggregated resources include all AWS providers present in the tenant
+        assert response.json()["data"][0]["attributes"]["resources"]["total"] == 3
+
+    def test_overview_providers_aggregates_same_provider_type(
+        self,
+        authenticated_client,
+        scan_summaries_fixture,
+        resources_fixture,
+        providers_fixture,
+        tenants_fixture,
+    ):
+        tenant = tenants_fixture[0]
+        _provider1, provider2, *_ = providers_fixture
+
+        scan = Scan.objects.create(
+            name="overview scan aws account 2",
+            provider=provider2,
+            trigger=Scan.TriggerChoices.MANUAL,
+            state=StateChoices.COMPLETED,
+            tenant=tenant,
+        )
+
+        ScanSummary.objects.create(
+            tenant=tenant,
+            scan=scan,
+            check_id="check-aws-two",
+            service="service-extra",
+            severity="medium",
+            region="region-extra",
+            _pass=3,
+            fail=2,
+            muted=1,
+            total=6,
+        )
+
+        Resource.objects.create(
+            tenant_id=tenant.id,
+            provider=provider2,
+            uid="arn:aws:ec2:us-west-2:123456789013:instance/i-aggregation",
+            name="Aggregated Instance",
+            region="us-west-2",
+            service="ec2",
+            type="prowler-test",
+        )
+
+        response = authenticated_client.get(reverse("overview-providers"))
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert len(data) == 1
+        attributes = data[0]["attributes"]
+
+        assert attributes["findings"]["total"] == 10
+        assert attributes["findings"]["pass"] == 5
+        assert attributes["findings"]["fail"] == 3
+        assert attributes["findings"]["muted"] == 2
+        assert attributes["resources"]["total"] == 4
+
+    def test_overview_providers_count(
+        self,
+        authenticated_client,
+        scan_summaries_fixture,
+        resources_fixture,
+        providers_fixture,
+        tenants_fixture,
+    ):
+        tenant = tenants_fixture[0]
+
+        default_response = authenticated_client.get(reverse("overview-providers"))
+        assert default_response.status_code == status.HTTP_200_OK
+        default_data = default_response.json()["data"]
+        assert len(default_data) == 1
+        assert all("count" not in item["attributes"] for item in default_data)
+        grouped_response = authenticated_client.get(reverse("overview-providers-count"))
+        assert grouped_response.status_code == status.HTTP_200_OK
+        grouped_data = grouped_response.json()["data"]
+        assert len(grouped_data) >= 1
+
+        aggregated = {
+            entry["id"]: entry["attributes"]["count"] for entry in grouped_data
+        }
+        db_counts = (
+            Provider.objects.filter(tenant_id=tenant.id, is_deleted=False)
+            .values("provider")
+            .annotate(count=Count("id"))
+        )
+        expected = {row["provider"]: row["count"] for row in db_counts}
+
+        assert aggregated == expected
+        for entry in grouped_data:
+            assert "findings" not in entry["attributes"]
+
+    def _create_scan(self, tenant, provider, name, started_at=None):
+        scan_started = started_at or datetime.now(timezone.utc) - timedelta(hours=1)
+        return Scan.objects.create(
+            tenant=tenant,
+            provider=provider,
+            name=name,
+            trigger=Scan.TriggerChoices.MANUAL,
+            state=StateChoices.COMPLETED,
+            started_at=scan_started,
+            completed_at=scan_started + timedelta(minutes=30),
+        )
+
+    def _create_threatscore_snapshot(
+        self,
+        tenant,
+        scan,
+        provider,
+        *,
+        compliance_id,
+        overall_score,
+        score_delta,
+        section_scores,
+        critical_requirements,
+        total_requirements,
+        passed_requirements,
+        failed_requirements,
+        manual_requirements,
+        total_findings,
+        passed_findings,
+        failed_findings,
+    ):
+        return ThreatScoreSnapshot.objects.create(
+            tenant=tenant,
+            scan=scan,
+            provider=provider,
+            compliance_id=compliance_id,
+            overall_score=Decimal(overall_score),
+            score_delta=Decimal(score_delta) if score_delta is not None else None,
+            section_scores=section_scores,
+            critical_requirements=critical_requirements,
+            total_requirements=total_requirements,
+            passed_requirements=passed_requirements,
+            failed_requirements=failed_requirements,
+            manual_requirements=manual_requirements,
+            total_findings=total_findings,
+            passed_findings=passed_findings,
+            failed_findings=failed_findings,
+        )
+
+    def test_overview_threatscore_returns_weighted_aggregate_snapshot(
+        self, authenticated_client, tenants_fixture, providers_fixture
+    ):
+        tenant = tenants_fixture[0]
+        provider1, provider2, *_ = providers_fixture
+
+        scan1 = self._create_scan(tenant, provider1, "agg-scan-one")
+        scan2 = self._create_scan(tenant, provider2, "agg-scan-two")
+
+        snapshot1 = self._create_threatscore_snapshot(
+            tenant,
+            scan1,
+            provider1,
+            compliance_id="prowler_threatscore_aws",
+            overall_score="80.00",
+            score_delta="5.00",
+            section_scores={"1. IAM": "70.00", "2. Attack Surface": "60.00"},
+            critical_requirements=[
+                {
+                    "requirement_id": "req_shared",
+                    "title": "Shared requirement (preferred)",
+                    "section": "1. IAM",
+                    "subsection": "Sub IAM",
+                    "risk_level": 5,
+                    "weight": 150,
+                    "passed_findings": 14,
+                    "total_findings": 20,
+                    "description": "Higher risk duplicate",
+                },
+                {
+                    "requirement_id": "req_unique_one",
+                    "title": "Unique provider one",
+                    "section": "2. Attack Surface",
+                    "subsection": "Sub Attack",
+                    "risk_level": 4,
+                    "weight": 90,
+                    "passed_findings": 20,
+                    "total_findings": 30,
+                    "description": "Lower risk",
+                },
+            ],
+            total_requirements=120,
+            passed_requirements=90,
+            failed_requirements=30,
+            manual_requirements=0,
+            total_findings=100,
+            passed_findings=70,
+            failed_findings=30,
+        )
+
+        snapshot2 = self._create_threatscore_snapshot(
+            tenant,
+            scan2,
+            provider2,
+            compliance_id="prowler_threatscore_aws",
+            overall_score="20.00",
+            score_delta="-2.00",
+            section_scores={
+                "1. IAM": "10.00",
+                "2. Attack Surface": "40.00",
+                "3. Logging": "30.00",
+            },
+            critical_requirements=[
+                {
+                    "requirement_id": "req_shared",
+                    "title": "Shared requirement (secondary)",
+                    "section": "1. IAM",
+                    "subsection": "Sub IAM",
+                    "risk_level": 4,
+                    "weight": 120,
+                    "passed_findings": 8,
+                    "total_findings": 12,
+                    "description": "Lower risk duplicate",
+                },
+                {
+                    "requirement_id": "req_unique_two",
+                    "title": "Unique provider two",
+                    "section": "3. Logging",
+                    "subsection": "Sub Logging",
+                    "risk_level": 5,
+                    "weight": 110,
+                    "passed_findings": 6,
+                    "total_findings": 10,
+                    "description": "Another critical requirement",
+                },
+            ],
+            total_requirements=80,
+            passed_requirements=30,
+            failed_requirements=50,
+            manual_requirements=0,
+            total_findings=50,
+            passed_findings=15,
+            failed_findings=35,
+        )
+
+        older_inserted = datetime(2025, 1, 1, 12, 0, tzinfo=timezone.utc)
+        newer_inserted = datetime(2025, 1, 2, 12, 0, tzinfo=timezone.utc)
+        ThreatScoreSnapshot.objects.filter(id=snapshot1.id).update(
+            inserted_at=older_inserted
+        )
+        ThreatScoreSnapshot.objects.filter(id=snapshot2.id).update(
+            inserted_at=newer_inserted
+        )
+        snapshot2.refresh_from_db()
+
+        response = authenticated_client.get(reverse("overview-threatscore"))
+
+        assert response.status_code == status.HTTP_200_OK
+        body = response.json()
+        assert len(body["data"]) == 1
+        aggregated = body["data"][0]
+
+        assert aggregated["id"] == "n/a"
+        assert aggregated["relationships"]["scan"]["data"] is None
+        assert aggregated["relationships"]["provider"]["data"] is None
+
+        attrs = aggregated["attributes"]
+        assert Decimal(attrs["overall_score"]) == Decimal("60.00")
+        assert Decimal(attrs["score_delta"]) == Decimal("2.67")
+        assert attrs["inserted_at"] == snapshot2.inserted_at.isoformat().replace(
+            "+00:00", "Z"
+        )
+        assert attrs["total_findings"] == 150
+        assert attrs["passed_findings"] == 85
+        assert attrs["failed_findings"] == 65
+        assert attrs["total_requirements"] == 200
+        assert attrs["passed_requirements"] == 120
+        assert attrs["failed_requirements"] == 80
+        assert attrs["manual_requirements"] == 0
+
+        assert attrs["section_scores"] == {
+            "1. IAM": "50.00",
+            "2. Attack Surface": "53.33",
+            "3. Logging": "30.00",
+        }
+
+        expected_critical = [
+            {
+                "requirement_id": "req_shared",
+                "title": "Shared requirement (preferred)",
+                "section": "1. IAM",
+                "subsection": "Sub IAM",
+                "risk_level": 5,
+                "weight": 150,
+                "passed_findings": 14,
+                "total_findings": 20,
+                "description": "Higher risk duplicate",
+            },
+            {
+                "requirement_id": "req_unique_two",
+                "title": "Unique provider two",
+                "section": "3. Logging",
+                "subsection": "Sub Logging",
+                "risk_level": 5,
+                "weight": 110,
+                "passed_findings": 6,
+                "total_findings": 10,
+                "description": "Another critical requirement",
+            },
+            {
+                "requirement_id": "req_unique_one",
+                "title": "Unique provider one",
+                "section": "2. Attack Surface",
+                "subsection": "Sub Attack",
+                "risk_level": 4,
+                "weight": 90,
+                "passed_findings": 20,
+                "total_findings": 30,
+                "description": "Lower risk",
+            },
+        ]
+        assert attrs["critical_requirements"] == expected_critical
+
+    def test_overview_threatscore_weight_fallback_to_requirements(
+        self, authenticated_client, tenants_fixture, providers_fixture
+    ):
+        tenant = tenants_fixture[0]
+        provider1, provider2, *_ = providers_fixture
+
+        scan1 = self._create_scan(tenant, provider1, "fallback-scan-1")
+        scan2 = self._create_scan(tenant, provider2, "fallback-scan-2")
+
+        self._create_threatscore_snapshot(
+            tenant,
+            scan1,
+            provider1,
+            compliance_id="prowler_threatscore_aws",
+            overall_score="90.00",
+            score_delta="4.00",
+            section_scores={"1. IAM": "90.00"},
+            critical_requirements=[],
+            total_requirements=10,
+            passed_requirements=8,
+            failed_requirements=0,
+            manual_requirements=2,
+            total_findings=0,
+            passed_findings=0,
+            failed_findings=0,
+        )
+        self._create_threatscore_snapshot(
+            tenant,
+            scan2,
+            provider2,
+            compliance_id="prowler_threatscore_aws",
+            overall_score="50.00",
+            score_delta="1.00",
+            section_scores={"1. IAM": "40.00"},
+            critical_requirements=[],
+            total_requirements=12,
+            passed_requirements=5,
+            failed_requirements=7,
+            manual_requirements=0,
+            total_findings=10,
+            passed_findings=4,
+            failed_findings=6,
+        )
+
+        response = authenticated_client.get(reverse("overview-threatscore"))
+        assert response.status_code == status.HTTP_200_OK
+        aggregate = response.json()["data"][0]["attributes"]
+
+        assert Decimal(aggregate["overall_score"]) == Decimal("67.78")
+        assert Decimal(aggregate["score_delta"]) == Decimal("2.33")
+        assert aggregate["total_findings"] == 10
+        assert aggregate["total_requirements"] == 22
+        assert aggregate["manual_requirements"] == 2
+        assert aggregate["section_scores"] == {"1. IAM": "62.22"}
+
+    def test_overview_threatscore_filter_by_scan_id_returns_snapshot(
+        self, authenticated_client, tenants_fixture, providers_fixture
+    ):
+        tenant = tenants_fixture[0]
+        provider1, *_ = providers_fixture
+        scan = self._create_scan(tenant, provider1, "filter-scan")
+
+        snapshot = self._create_threatscore_snapshot(
+            tenant,
+            scan,
+            provider1,
+            compliance_id="prowler_threatscore_aws",
+            overall_score="75.00",
+            score_delta="3.00",
+            section_scores={"1. IAM": "70.00"},
+            critical_requirements=[],
+            total_requirements=50,
+            passed_requirements=30,
+            failed_requirements=20,
+            manual_requirements=0,
+            total_findings=25,
+            passed_findings=15,
+            failed_findings=10,
+        )
+
+        response = authenticated_client.get(
+            reverse("overview-threatscore"), {"filter[scan_id]": str(scan.id)}
+        )
+
+        assert response.status_code == status.HTTP_200_OK
+        body = response.json()
+        assert len(body["data"]) == 1
+        assert body["data"][0]["id"] == str(snapshot.id)
+        assert body["data"][0]["attributes"]["overall_score"] == "75.00"
+
+    def test_overview_threatscore_snapshot_id_returns_specific_snapshot(
+        self, authenticated_client, tenants_fixture, providers_fixture
+    ):
+        tenant = tenants_fixture[0]
+        provider1, *_ = providers_fixture
+        scan = self._create_scan(tenant, provider1, "snapshot-id-scan")
+
+        snapshot = self._create_threatscore_snapshot(
+            tenant,
+            scan,
+            provider1,
+            compliance_id="prowler_threatscore_aws",
+            overall_score="88.50",
+            score_delta=None,
+            section_scores={"1. IAM": "80.00"},
+            critical_requirements=[],
+            total_requirements=60,
+            passed_requirements=45,
+            failed_requirements=15,
+            manual_requirements=0,
+            total_findings=30,
+            passed_findings=25,
+            failed_findings=5,
+        )
+
+        response = authenticated_client.get(
+            reverse("overview-threatscore"), {"snapshot_id": str(snapshot.id)}
+        )
+
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()
+        assert data["data"]["id"] == str(snapshot.id)
+        assert data["data"]["attributes"]["score_delta"] is None
+
+    def test_overview_threatscore_provider_filter_returns_unaggregated_snapshot(
+        self, authenticated_client, tenants_fixture, providers_fixture
+    ):
+        tenant = tenants_fixture[0]
+        provider1, provider2, *_ = providers_fixture
+
+        scan1 = self._create_scan(tenant, provider1, "provider-filter-scan-1")
+        scan2 = self._create_scan(tenant, provider2, "provider-filter-scan-2")
+
+        snapshot1 = self._create_threatscore_snapshot(
+            tenant,
+            scan1,
+            provider1,
+            compliance_id="prowler_threatscore_aws",
+            overall_score="55.55",
+            score_delta="1.10",
+            section_scores={"1. IAM": "50.00"},
+            critical_requirements=[],
+            total_requirements=40,
+            passed_requirements=25,
+            failed_requirements=15,
+            manual_requirements=0,
+            total_findings=12,
+            passed_findings=7,
+            failed_findings=5,
+        )
+        self._create_threatscore_snapshot(
+            tenant,
+            scan2,
+            provider2,
+            compliance_id="prowler_threatscore_aws",
+            overall_score="44.44",
+            score_delta="0.80",
+            section_scores={"1. IAM": "40.00"},
+            critical_requirements=[],
+            total_requirements=30,
+            passed_requirements=18,
+            failed_requirements=12,
+            manual_requirements=0,
+            total_findings=10,
+            passed_findings=6,
+            failed_findings=4,
+        )
+
+        response = authenticated_client.get(
+            reverse("overview-threatscore"),
+            {"filter[provider_id__in]": str(provider1.id)},
+        )
+
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert len(data) == 1
+        assert data[0]["id"] == str(snapshot1.id)
+        assert data[0]["attributes"]["overall_score"] == "55.55"
 
     def test_overview_services_list_no_required_filters(
         self, authenticated_client, scan_summaries_fixture
     ):
         response = authenticated_client.get(reverse("overview-services"))
-        assert response.status_code == status.HTTP_400_BAD_REQUEST
+        assert response.status_code == status.HTTP_200_OK
+        # Should return services from latest scans
+        assert len(response.json()["data"]) == 2
 
     def test_overview_services_list(self, authenticated_client, scan_summaries_fixture):
         response = authenticated_client.get(
@@ -5518,6 +6810,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:
@@ -5557,10 +7014,12 @@ class TestScheduleViewSet:
         )
         assert response.status_code == status.HTTP_404_NOT_FOUND
 
+    @patch("tasks.beat.perform_scheduled_scan_task.apply_async")
     @patch("api.v1.views.Task.objects.get")
     def test_schedule_daily_already_scheduled(
         self,
         mock_task_get,
+        mock_apply_async,
         authenticated_client,
         providers_fixture,
         tasks_fixture,
@@ -5568,6 +7027,7 @@ class TestScheduleViewSet:
         provider, *_ = providers_fixture
         prowler_task = tasks_fixture[0]
         mock_task_get.return_value = prowler_task
+        mock_apply_async.return_value.id = prowler_task.id
         json_payload = {
             "provider_id": str(provider.id),
         }
@@ -5708,6 +7168,47 @@ class TestIntegrationViewSet:
             == data["data"]["relationships"]["providers"]["data"][0]["id"]
         )
 
+    def test_integrations_create_valid_jira(
+        self,
+        authenticated_client,
+    ):
+        """Jira integrations are special"""
+        data = {
+            "data": {
+                "type": "integrations",
+                "attributes": {
+                    "integration_type": Integration.IntegrationChoices.JIRA,
+                    "configuration": {},
+                    "credentials": {
+                        "domain": "prowlerdomain",
+                        "api_token": "this-is-an-api-token-for-jira-that-works-for-sure",
+                        "user_mail": "testing@prowler.com",
+                    },
+                    "enabled": True,
+                },
+            }
+        }
+        response = authenticated_client.post(
+            reverse("integration-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+        assert Integration.objects.count() == 1
+        integration = Integration.objects.first()
+        integration_configuration = response.json()["data"]["attributes"][
+            "configuration"
+        ]
+        assert "projects" in integration_configuration
+        assert "issue_types" in integration_configuration
+        assert "domain" in integration_configuration
+        assert integration.enabled == data["data"]["attributes"]["enabled"]
+        assert (
+            integration.integration_type
+            == data["data"]["attributes"]["integration_type"]
+        )
+        assert "credentials" not in response.json()["data"]["attributes"]
+
     def test_integrations_create_valid_relationships(
         self,
         authenticated_client,
@@ -5806,6 +7307,46 @@ class TestIntegrationViewSet:
                     "invalid",
                     None,
                 ),
+                (
+                    {
+                        "integration_type": "jira",
+                        "configuration": {
+                            "projects": ["JIRA"],
+                        },
+                        "credentials": {"domain": "prowlerdomain"},
+                    },
+                    "invalid",
+                    "configuration",
+                ),
+                (
+                    {
+                        "integration_type": "jira",
+                        "credentialss": {
+                            "domain": "prowlerdomain",
+                            "api_token": "api-token",
+                            "user_mail": "test@prowler.com",
+                        },
+                    },
+                    "required",
+                    "configuration",
+                ),
+                (
+                    {
+                        "integration_type": "jira",
+                        "configuration": {},
+                    },
+                    "required",
+                    "credentials",
+                ),
+                (
+                    {
+                        "integration_type": "jira",
+                        "configuration": {},
+                        "credentials": {"api_token": "api-token"},
+                    },
+                    "invalid",
+                    "credentials",
+                ),
             ]
         ),
     )
@@ -5995,6 +7536,217 @@ class TestIntegrationViewSet:
         )
         assert response.status_code == status.HTTP_400_BAD_REQUEST
 
+    def test_integrations_create_duplicate_amazon_s3(
+        self, authenticated_client, providers_fixture
+    ):
+        provider = providers_fixture[0]
+
+        # Create first S3 integration
+        data = {
+            "data": {
+                "type": "integrations",
+                "attributes": {
+                    "integration_type": Integration.IntegrationChoices.AMAZON_S3,
+                    "configuration": {
+                        "bucket_name": "test-bucket",
+                        "output_directory": "test-output",
+                    },
+                    "credentials": {
+                        "role_arn": "arn:aws:iam::123456789012:role/test-role",
+                        "external_id": "test-external-id",
+                    },
+                    "enabled": True,
+                },
+                "relationships": {
+                    "providers": {
+                        "data": [{"type": "providers", "id": str(provider.id)}]
+                    }
+                },
+            }
+        }
+
+        # First creation should succeed
+        response = authenticated_client.post(
+            reverse("integration-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+
+        # Attempt to create duplicate should return 409
+        response = authenticated_client.post(
+            reverse("integration-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_409_CONFLICT
+        assert (
+            "This integration already exists" in response.json()["errors"][0]["detail"]
+        )
+        assert (
+            response.json()["errors"][0]["source"]["pointer"]
+            == "/data/attributes/configuration"
+        )
+
+    def test_integrations_create_duplicate_jira(self, authenticated_client):
+        # Create first JIRA integration
+        data = {
+            "data": {
+                "type": "integrations",
+                "attributes": {
+                    "integration_type": Integration.IntegrationChoices.JIRA,
+                    "configuration": {},
+                    "credentials": {
+                        "user_mail": "test@example.com",
+                        "api_token": "test-api-token",
+                        "domain": "prowlerdomain",
+                    },
+                    "enabled": True,
+                },
+            }
+        }
+
+        # First creation should succeed
+        response = authenticated_client.post(
+            reverse("integration-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+
+        # Attempt to create duplicate should return 409
+        response = authenticated_client.post(
+            reverse("integration-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_409_CONFLICT
+        assert (
+            "This integration already exists" in response.json()["errors"][0]["detail"]
+        )
+        assert (
+            response.json()["errors"][0]["source"]["pointer"]
+            == "/data/attributes/configuration"
+        )
+
+    def test_integrations_update_jira_configuration_readonly(
+        self, authenticated_client
+    ):
+        # Create JIRA integration first
+        create_data = {
+            "data": {
+                "type": "integrations",
+                "attributes": {
+                    "integration_type": Integration.IntegrationChoices.JIRA,
+                    "configuration": {},
+                    "credentials": {
+                        "user_mail": "test@example.com",
+                        "api_token": "test-api-token",
+                        "domain": "initial-domain",
+                    },
+                    "enabled": True,
+                },
+            }
+        }
+
+        # Create the integration
+        response = authenticated_client.post(
+            reverse("integration-list"),
+            data=json.dumps(create_data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+        integration_id = response.json()["data"]["id"]
+
+        # Attempt to update configuration - should be ignored/not allowed
+        update_data = {
+            "data": {
+                "type": "integrations",
+                "id": integration_id,
+                "attributes": {
+                    "configuration": {
+                        "projects": {"NEW_PROJECT": "New Project"},
+                        "issue_types": ["Epic", "Story"],
+                        "domain": "malicious-domain",
+                    }
+                },
+            }
+        }
+
+        response = authenticated_client.patch(
+            reverse("integration-detail", kwargs={"pk": integration_id}),
+            data=json.dumps(update_data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+
+    def test_integrations_update_jira_credentials_domain_reflects_in_configuration(
+        self, authenticated_client
+    ):
+        # Create JIRA integration first
+        create_data = {
+            "data": {
+                "type": "integrations",
+                "attributes": {
+                    "integration_type": Integration.IntegrationChoices.JIRA,
+                    "configuration": {},
+                    "credentials": {
+                        "user_mail": "test@example.com",
+                        "api_token": "test-api-token",
+                        "domain": "original-domain",
+                    },
+                    "enabled": True,
+                },
+            }
+        }
+
+        # Create the integration
+        response = authenticated_client.post(
+            reverse("integration-list"),
+            data=json.dumps(create_data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+        integration_id = response.json()["data"]["id"]
+
+        # Verify initial domain in configuration
+        initial_integration = response.json()["data"]
+        assert (
+            initial_integration["attributes"]["configuration"]["domain"]
+            == "original-domain"
+        )
+
+        # Update credentials with new domain
+        update_data = {
+            "data": {
+                "type": "integrations",
+                "id": integration_id,
+                "attributes": {
+                    "credentials": {
+                        "user_mail": "updated@example.com",
+                        "api_token": "updated-api-token",
+                        "domain": "updated-domain",
+                    }
+                },
+            }
+        }
+
+        response = authenticated_client.patch(
+            reverse("integration-detail", kwargs={"pk": integration_id}),
+            data=json.dumps(update_data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_200_OK
+
+        # Verify the new domain is reflected in configuration
+        updated_integration = response.json()["data"]
+        configuration = updated_integration["attributes"]["configuration"]
+        assert configuration["domain"] == "updated-domain"
+
+        # Verify other configuration fields are preserved
+        assert "projects" in configuration
+        assert "issue_types" in configuration
+
 
 @pytest.mark.django_db
 class TestSAMLTokenValidation:
@@ -6376,6 +8128,188 @@ class TestTenantFinishACSView:
             assert response.status_code == 302
             assert "sso_saml_failed=true" in response.url
 
+    def test_dispatch_skips_role_mapping_when_single_manage_account_user(
+        self, create_test_user, tenants_fixture, saml_setup, settings, monkeypatch
+    ):
+        """Test that role mapping is skipped when tenant has only one user with MANAGE_ACCOUNT role"""
+        monkeypatch.setenv("SAML_SSO_CALLBACK_URL", "http://localhost/sso-complete")
+        user = create_test_user
+        tenant = tenants_fixture[0]
+
+        # Create a single role with manage_account=True for the user
+        admin_role = Role.objects.using(MainRouter.admin_db).create(
+            name="admin",
+            tenant=tenant,
+            manage_account=True,
+            manage_users=True,
+            manage_billing=True,
+            manage_providers=True,
+            manage_integrations=True,
+            manage_scans=True,
+            unlimited_visibility=True,
+        )
+        UserRoleRelationship.objects.using(MainRouter.admin_db).create(
+            user=user, role=admin_role, tenant_id=tenant.id
+        )
+
+        social_account = SocialAccount(
+            user=user,
+            provider="saml",
+            extra_data={
+                "firstName": ["John"],
+                "lastName": ["Doe"],
+                "organization": ["testing_company"],
+                "userType": ["no_permissions"],  # This should be ignored
+            },
+        )
+
+        request = RequestFactory().get(
+            reverse("saml_finish_acs", kwargs={"organization_slug": "testtenant"})
+        )
+        request.user = user
+        request.session = {}
+
+        with (
+            patch(
+                "allauth.socialaccount.providers.saml.views.get_app_or_404"
+            ) as mock_get_app_or_404,
+            patch(
+                "allauth.socialaccount.models.SocialApp.objects.get"
+            ) as mock_socialapp_get,
+            patch(
+                "allauth.socialaccount.models.SocialAccount.objects.get"
+            ) as mock_sa_get,
+            patch("api.models.SAMLDomainIndex.objects.get") as mock_saml_domain_get,
+            patch("api.models.SAMLConfiguration.objects.get") as mock_saml_config_get,
+            patch("api.models.User.objects.get") as mock_user_get,
+        ):
+            mock_get_app_or_404.return_value = MagicMock(
+                provider="saml", client_id="testtenant", name="Test App", settings={}
+            )
+            mock_sa_get.return_value = social_account
+            mock_socialapp_get.return_value = MagicMock(provider_id="saml")
+            mock_saml_domain_get.return_value = SimpleNamespace(tenant_id=tenant.id)
+            mock_saml_config_get.return_value = MagicMock()
+            mock_user_get.return_value = user
+
+            view = TenantFinishACSView.as_view()
+            response = view(request, organization_slug="testtenant")
+
+        assert response.status_code == 302
+
+        # Verify the admin role is still assigned (not changed to no_permissions)
+        assert (
+            UserRoleRelationship.objects.using(MainRouter.admin_db)
+            .filter(user=user, role=admin_role, tenant_id=tenant.id)
+            .exists()
+        )
+
+        # Verify no_permissions role was NOT created in the database
+        assert (
+            not Role.objects.using(MainRouter.admin_db)
+            .filter(name="no_permissions", tenant=tenant)
+            .exists()
+        )
+
+        # Verify no_permissions role was NOT assigned to the user
+        assert not (
+            UserRoleRelationship.objects.using(MainRouter.admin_db)
+            .filter(user=user, role__name="no_permissions", tenant_id=tenant.id)
+            .exists()
+        )
+
+    def test_dispatch_applies_role_mapping_when_multiple_manage_account_users(
+        self, create_test_user, tenants_fixture, saml_setup, settings, monkeypatch
+    ):
+        """Test that role mapping is applied when tenant has multiple users with MANAGE_ACCOUNT role"""
+        monkeypatch.setenv("SAML_SSO_CALLBACK_URL", "http://localhost/sso-complete")
+        user = create_test_user
+        tenant = tenants_fixture[0]
+
+        # Create a second user with manage_account=True
+        second_admin = User.objects.using(MainRouter.admin_db).create(
+            email="admin2@prowler.com", name="Second Admin"
+        )
+        admin_role = Role.objects.using(MainRouter.admin_db).create(
+            name="admin",
+            tenant=tenant,
+            manage_account=True,
+            manage_users=True,
+            manage_billing=True,
+            manage_providers=True,
+            manage_integrations=True,
+            manage_scans=True,
+            unlimited_visibility=True,
+        )
+        UserRoleRelationship.objects.using(MainRouter.admin_db).create(
+            user=user, role=admin_role, tenant_id=tenant.id
+        )
+        UserRoleRelationship.objects.using(MainRouter.admin_db).create(
+            user=second_admin, role=admin_role, tenant_id=tenant.id
+        )
+
+        social_account = SocialAccount(
+            user=user,
+            provider="saml",
+            extra_data={
+                "firstName": ["John"],
+                "lastName": ["Doe"],
+                "organization": ["testing_company"],
+                "userType": ["viewer"],  # This SHOULD be applied
+            },
+        )
+
+        request = RequestFactory().get(
+            reverse("saml_finish_acs", kwargs={"organization_slug": "testtenant"})
+        )
+        request.user = user
+        request.session = {}
+
+        with (
+            patch(
+                "allauth.socialaccount.providers.saml.views.get_app_or_404"
+            ) as mock_get_app_or_404,
+            patch(
+                "allauth.socialaccount.models.SocialApp.objects.get"
+            ) as mock_socialapp_get,
+            patch(
+                "allauth.socialaccount.models.SocialAccount.objects.get"
+            ) as mock_sa_get,
+            patch("api.models.SAMLDomainIndex.objects.get") as mock_saml_domain_get,
+            patch("api.models.SAMLConfiguration.objects.get") as mock_saml_config_get,
+            patch("api.models.User.objects.get") as mock_user_get,
+        ):
+            mock_get_app_or_404.return_value = MagicMock(
+                provider="saml", client_id="testtenant", name="Test App", settings={}
+            )
+            mock_sa_get.return_value = social_account
+            mock_socialapp_get.return_value = MagicMock(provider_id="saml")
+            mock_saml_domain_get.return_value = SimpleNamespace(tenant_id=tenant.id)
+            mock_saml_config_get.return_value = MagicMock()
+            mock_user_get.return_value = user
+
+            view = TenantFinishACSView.as_view()
+            response = view(request, organization_slug="testtenant")
+
+        assert response.status_code == 302
+
+        # Verify the viewer role was created and assigned (role mapping was applied)
+        viewer_role = Role.objects.using(MainRouter.admin_db).get(
+            name="viewer", tenant=tenant
+        )
+        assert (
+            UserRoleRelationship.objects.using(MainRouter.admin_db)
+            .filter(user=user, role=viewer_role, tenant_id=tenant.id)
+            .exists()
+        )
+
+        # Verify the admin role was removed (replaced by viewer)
+        assert not (
+            UserRoleRelationship.objects.using(MainRouter.admin_db)
+            .filter(user=user, role=admin_role, tenant_id=tenant.id)
+            .exists()
+        )
+
 
 @pytest.mark.django_db
 class TestLighthouseConfigViewSet:
@@ -6890,3 +8824,2287 @@ class TestProcessorViewSet:
             content_type="application/vnd.api+json",
         )
         assert response.status_code == status.HTTP_400_BAD_REQUEST
+
+
+@pytest.mark.django_db
+class TestTenantApiKeyViewSet:
+    """Tests for TenantAPIKey endpoints."""
+
+    def test_api_keys_list(self, authenticated_client, api_keys_fixture):
+        """Test listing all API keys for the tenant."""
+        response = authenticated_client.get(reverse("api-key-list"))
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert len(data) == len(api_keys_fixture)
+
+    def test_api_keys_list_empty(self, authenticated_client, tenants_fixture):
+        """Test listing API keys when none exist returns empty list."""
+        response = authenticated_client.get(reverse("api-key-list"))
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert len(data) == 0
+        assert isinstance(data, list)
+
+    def test_api_keys_list_default_ordering(
+        self, authenticated_client, api_keys_fixture
+    ):
+        """Test that API keys are ordered by -created (newest first) by default."""
+        response = authenticated_client.get(reverse("api-key-list"))
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+
+        # Verify ordering by comparing inserted_at timestamps
+        # (newest should be first since ordering = ["-created"])
+        if len(data) >= 2:
+            first_date = data[0]["attributes"]["inserted_at"]
+            second_date = data[1]["attributes"]["inserted_at"]
+            assert first_date >= second_date
+
+    def test_api_keys_list_pagination_page_size(
+        self, authenticated_client, api_keys_fixture
+    ):
+        """Test pagination with custom page size."""
+        page_size = 1
+        response = authenticated_client.get(
+            reverse("api-key-list"), {"page[size]": page_size}
+        )
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert len(data) == page_size
+        assert response.json()["meta"]["pagination"]["page"] == 1
+        assert response.json()["meta"]["pagination"]["pages"] == 3
+
+    def test_api_keys_list_pagination_page_number(
+        self, authenticated_client, api_keys_fixture
+    ):
+        """Test pagination with specific page number."""
+        page_size = 1
+        page_number = 2
+        response = authenticated_client.get(
+            reverse("api-key-list"),
+            {"page[size]": page_size, "page[number]": page_number},
+        )
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert len(data) == page_size
+        assert response.json()["meta"]["pagination"]["page"] == page_number
+
+    def test_api_keys_list_pagination_invalid_page(self, authenticated_client):
+        """Test pagination with invalid page number returns 404."""
+        response = authenticated_client.get(
+            reverse("api-key-list"), {"page[number]": 999}
+        )
+        assert response.status_code == status.HTTP_404_NOT_FOUND
+
+    def test_api_keys_retrieve(self, authenticated_client, api_keys_fixture):
+        """Test retrieving a single API key by ID."""
+        api_key = api_keys_fixture[0]
+        response = authenticated_client.get(
+            reverse("api-key-detail", kwargs={"pk": api_key.id})
+        )
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert data["id"] == str(api_key.id)
+        assert data["attributes"]["name"] == api_key.name
+        assert data["attributes"]["prefix"] == api_key.prefix
+        assert data["attributes"]["revoked"] == api_key.revoked
+        assert "expires_at" in data["attributes"]
+        assert "inserted_at" in data["attributes"]
+        assert "last_used_at" in data["attributes"]
+        # Verify api_key field is NOT in response (only on creation)
+        assert "api_key" not in data["attributes"]
+
+    def test_api_keys_retrieve_invalid(self, authenticated_client):
+        """Test retrieving non-existent API key returns 404."""
+        response = authenticated_client.get(
+            reverse(
+                "api-key-detail",
+                kwargs={"pk": "f498b103-c760-4785-9a3e-e23fafbb7b02"},
+            )
+        )
+        assert response.status_code == status.HTTP_404_NOT_FOUND
+
+    def test_api_keys_retrieve_field_mapping(
+        self, authenticated_client, api_keys_fixture
+    ):
+        """Test that field names are correctly mapped (expires_at, inserted_at)."""
+        api_key = api_keys_fixture[0]
+        response = authenticated_client.get(
+            reverse("api-key-detail", kwargs={"pk": api_key.id})
+        )
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]["attributes"]
+
+        # Verify field mapping: expires_at -> expiry_date
+        assert "expires_at" in data
+        assert "expiry_date" not in data
+
+        # Verify field mapping: inserted_at -> created
+        assert "inserted_at" in data
+        assert "created" not in data
+
+    @pytest.mark.parametrize(
+        "api_key_payload",
+        (
+            [
+                {"name": "New API Key"},
+            ]
+        ),
+    )
+    def test_api_keys_create_valid(
+        self, authenticated_client, create_test_user, api_key_payload
+    ):
+        data = {
+            "data": {
+                "type": "api-keys",
+                "attributes": api_key_payload,
+            }
+        }
+        response = authenticated_client.post(
+            reverse("api-key-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+        response_data = response.json()["data"]
+        assert "prefix" in response_data["attributes"]
+        assert "api_key" in response_data["attributes"]
+        assert response_data["attributes"]["api_key"] is not None
+        # Verify the raw API key is returned (only on creation)
+        assert (
+            response_data["attributes"]["prefix"]
+            in response_data["attributes"]["api_key"]
+        )
+        # Verify entity is set to current user
+        assert response_data["relationships"]["entity"]["data"]["id"] == str(
+            create_test_user.id
+        )
+
+    @pytest.mark.parametrize(
+        "api_key_payload, error_pointer",
+        (
+            [
+                (
+                    {"name": "Invalid Expiry", "expires_at": "not-a-date"},
+                    "expires_at",
+                ),
+                (
+                    {"name": ""},
+                    "name",
+                ),
+                (
+                    {},
+                    "name",
+                ),
+                (
+                    {"name": "AB"},  # Too short (min length is 3)
+                    "name",
+                ),
+            ]
+        ),
+    )
+    def test_api_keys_create_invalid(
+        self,
+        authenticated_client,
+        create_test_user,
+        api_key_payload,
+        error_pointer,
+    ):
+        data = {
+            "data": {
+                "type": "api-keys",
+                "attributes": api_key_payload,
+            }
+        }
+        response = authenticated_client.post(
+            reverse("api-key-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+        assert "errors" in response.json()
+        assert (
+            response.json()["errors"][0]["source"]["pointer"]
+            == f"/data/attributes/{error_pointer}"
+        )
+
+    def test_api_keys_create_duplicate_name(
+        self, authenticated_client, api_keys_fixture
+    ):
+        """Test creating an API key with a duplicate name fails."""
+        # Use the name of an existing API key
+        existing_name = api_keys_fixture[0].name
+        data = {
+            "data": {
+                "type": "api-keys",
+                "attributes": {
+                    "name": existing_name,
+                },
+            }
+        }
+        response = authenticated_client.post(
+            reverse("api-key-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+        assert "errors" in response.json()
+        error_detail = response.json()["errors"][0]["detail"]
+        assert "already exists" in error_detail.lower()
+
+    def test_api_keys_update_duplicate_name(
+        self, authenticated_client, api_keys_fixture
+    ):
+        """Test updating an API key with a duplicate name fails."""
+        # Get two different API keys
+        first_api_key = api_keys_fixture[0]
+        second_api_key = api_keys_fixture[1]
+
+        # Try to update the second API key to have the same name as the first one
+        data = {
+            "data": {
+                "type": "api-keys",
+                "id": str(second_api_key.id),
+                "attributes": {
+                    "name": first_api_key.name,
+                },
+            }
+        }
+        response = authenticated_client.patch(
+            reverse("api-key-detail", kwargs={"pk": second_api_key.id}),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+        assert "errors" in response.json()
+        error_detail = response.json()["errors"][0]["detail"]
+        assert "already exists" in error_detail.lower()
+
+    def test_api_keys_create_multiple_unique_prefixes(
+        self, authenticated_client, api_keys_fixture
+    ):
+        """Test creating multiple API keys generates unique prefixes."""
+        prefixes = set()
+        for i in range(3):
+            data = {
+                "data": {
+                    "type": "api-keys",
+                    "attributes": {
+                        "name": f"Unique Key {i}",
+                    },
+                }
+            }
+            response = authenticated_client.post(
+                reverse("api-key-list"),
+                data=json.dumps(data),
+                content_type="application/vnd.api+json",
+            )
+            assert response.status_code == status.HTTP_201_CREATED
+            prefix = response.json()["data"]["attributes"]["prefix"]
+            prefixes.add(prefix)
+        # Verify all prefixes are unique
+        assert len(prefixes) == 3
+
+    def test_api_keys_create_invalid_content_type(
+        self, authenticated_client, create_test_user
+    ):
+        """Test creating an API key with wrong content type returns 415."""
+        data = {"name": "Test Key"}
+        response = authenticated_client.post(
+            reverse("api-key-list"),
+            data=data,
+            content_type="application/json",
+        )
+        assert response.status_code == status.HTTP_415_UNSUPPORTED_MEDIA_TYPE
+
+    def test_api_keys_create_malformed_json(
+        self, authenticated_client, create_test_user
+    ):
+        """Test creating an API key with malformed JSON returns 400."""
+        response = authenticated_client.post(
+            reverse("api-key-list"),
+            data="not valid json",
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+
+    def test_api_keys_create_invalid_structure(
+        self, authenticated_client, create_test_user
+    ):
+        """Test creating an API key with invalid JSON:API structure."""
+        data = {"invalid": "structure"}
+        response = authenticated_client.post(
+            reverse("api-key-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+        assert "errors" in response.json()
+
+    def test_api_keys_revoke(self, authenticated_client, api_keys_fixture):
+        """Test revoking an API key."""
+        api_key = api_keys_fixture[0]  # Not revoked
+        assert api_key.revoked is False
+
+        response = authenticated_client.delete(
+            reverse("api-key-revoke", kwargs={"pk": api_key.id})
+        )
+        assert response.status_code == status.HTTP_200_OK
+        response_data = response.json()["data"]
+        assert response_data["attributes"]["revoked"] is True
+
+        # Verify in database
+        api_key.refresh_from_db()
+        assert api_key.revoked is True
+
+    def test_api_keys_revoke_preserves_created_field(
+        self, authenticated_client, api_keys_fixture
+    ):
+        """Test that revoking an API key preserves the created timestamp."""
+        api_key = api_keys_fixture[0]  # Not revoked
+        assert api_key.revoked is False
+
+        # Record the original created timestamp
+        original_created = api_key.created
+
+        response = authenticated_client.delete(
+            reverse("api-key-revoke", kwargs={"pk": api_key.id})
+        )
+        assert response.status_code == status.HTTP_200_OK
+
+        # Verify in database
+        api_key.refresh_from_db()
+        assert api_key.revoked is True
+        # Verify created field has not changed
+        assert api_key.created == original_created
+
+    def test_api_keys_revoke_already_revoked(
+        self, authenticated_client, api_keys_fixture
+    ):
+        """Test revoking an already revoked API key returns validation error."""
+        api_key = api_keys_fixture[2]  # Already revoked
+        api_key.refresh_from_db()
+        assert api_key.revoked is True
+
+        response = authenticated_client.delete(
+            reverse("api-key-revoke", kwargs={"pk": api_key.id})
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+        assert "already revoked" in response.json()["errors"][0]["detail"]
+
+    def test_api_keys_revoke_nonexistent(self, authenticated_client):
+        """Test revoking non-existent API key returns 404."""
+        response = authenticated_client.delete(
+            reverse(
+                "api-key-revoke",
+                kwargs={"pk": "f498b103-c760-4785-9a3e-e23fafbb7b02"},
+            )
+        )
+        assert response.status_code == status.HTTP_404_NOT_FOUND
+
+    def test_api_keys_destroy_not_allowed(self, authenticated_client, api_keys_fixture):
+        """Test that DELETE (destroy) endpoint is disabled."""
+        api_key = api_keys_fixture[0]
+        response = authenticated_client.delete(
+            reverse("api-key-detail", kwargs={"pk": api_key.id})
+        )
+        assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED
+
+    def test_api_keys_put_not_allowed(self, authenticated_client, api_keys_fixture):
+        """Test that PUT is not allowed."""
+        api_key = api_keys_fixture[0]
+        data = {
+            "data": {
+                "type": "api-keys",
+                "id": str(api_key.id),
+                "attributes": {
+                    "name": "Updated Name",
+                },
+            }
+        }
+        response = authenticated_client.put(
+            reverse("api-key-detail", kwargs={"pk": api_key.id}),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED
+
+    @pytest.mark.parametrize(
+        "filter_name, filter_value, expected_min_count",
+        (
+            [
+                ("name", "Test API Key 1", 1),
+                ("name__icontains", "test", 2),
+                ("revoked", "true", 1),
+                ("revoked", "false", 2),
+                ("inserted_at", TODAY, 1),
+                ("inserted_at__gte", "2024-01-01", 3),
+                ("inserted_at__lte", "2099-12-31", 3),
+                ("expires_at__gte", today_after_n_days(50), 1),
+            ]
+        ),
+    )
+    def test_api_keys_filters(
+        self,
+        authenticated_client,
+        api_keys_fixture,
+        filter_name,
+        filter_value,
+        expected_min_count,
+    ):
+        response = authenticated_client.get(
+            reverse("api-key-list"),
+            {f"filter[{filter_name}]": filter_value},
+        )
+
+        assert response.status_code == status.HTTP_200_OK
+        assert len(response.json()["data"]) >= expected_min_count
+
+    def test_api_keys_filter_combined(self, authenticated_client, api_keys_fixture):
+        """Test combining multiple filters."""
+        response = authenticated_client.get(
+            reverse("api-key-list"),
+            {
+                "filter[revoked]": "false",
+                "filter[name__icontains]": "test",
+            },
+        )
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert all(item["attributes"]["revoked"] is False for item in data)
+        assert all("test" in item["attributes"]["name"].lower() for item in data)
+
+    @pytest.mark.parametrize(
+        "filter_name",
+        (
+            [
+                "invalid_field",
+                "nonexistent",
+            ]
+        ),
+    )
+    def test_api_keys_filters_invalid(self, authenticated_client, filter_name):
+        response = authenticated_client.get(
+            reverse("api-key-list"),
+            {f"filter[{filter_name}]": "whatever"},
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+
+    def test_api_keys_filter_invalid_date_format(self, authenticated_client):
+        """Test filtering with invalid date format returns 400."""
+        response = authenticated_client.get(
+            reverse("api-key-list"),
+            {"filter[inserted_at]": "not-a-date"},
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+
+    def test_api_keys_filter_empty_result(self, authenticated_client, api_keys_fixture):
+        """Test filter that returns no results."""
+        response = authenticated_client.get(
+            reverse("api-key-list"),
+            {"filter[name]": "NonExistent Key Name"},
+        )
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert len(data) == 0
+        assert isinstance(data, list)
+
+    @pytest.mark.parametrize(
+        "sort_field",
+        (
+            [
+                "name",
+                "prefix",
+                "revoked",
+                "inserted_at",
+                "expires_at",
+                "-name",
+                "-inserted_at",
+            ]
+        ),
+    )
+    def test_api_keys_sort(self, authenticated_client, api_keys_fixture, sort_field):
+        response = authenticated_client.get(
+            reverse("api-key-list"), {"sort": sort_field}
+        )
+        assert response.status_code == status.HTTP_200_OK
+
+    def test_api_keys_sort_invalid(self, authenticated_client):
+        """Test invalid sort parameter returns 400."""
+        response = authenticated_client.get(
+            reverse("api-key-list"),
+            {"sort": "invalid_field"},
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+
+    def test_api_keys_rbac_manage_account_required(
+        self, authenticated_client_rbac_manage_users_only, api_keys_fixture
+    ):
+        """Test that users without MANAGE_ACCOUNT permission are denied."""
+        response = authenticated_client_rbac_manage_users_only.get(
+            reverse("api-key-list")
+        )
+        assert response.status_code == status.HTTP_403_FORBIDDEN
+
+    def test_api_keys_rbac_manage_account_allowed(
+        self, authenticated_client_rbac_manage_account, tenants_fixture
+    ):
+        """Test that users with MANAGE_ACCOUNT permission can access API keys."""
+        response = authenticated_client_rbac_manage_account.get(reverse("api-key-list"))
+        assert response.status_code == status.HTTP_200_OK
+
+    def test_api_keys_rbac_create_requires_permission(
+        self, authenticated_client_rbac_manage_users_only
+    ):
+        """Test that creating API keys requires MANAGE_ACCOUNT permission."""
+        data = {
+            "data": {
+                "type": "api-keys",
+                "attributes": {
+                    "name": "Test Key",
+                },
+            }
+        }
+        response = authenticated_client_rbac_manage_users_only.post(
+            reverse("api-key-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_403_FORBIDDEN
+
+    def test_api_keys_rbac_revoke_requires_permission(
+        self, authenticated_client_rbac_manage_users_only, api_keys_fixture
+    ):
+        """Test that revoking API keys requires MANAGE_ACCOUNT permission."""
+        api_key = api_keys_fixture[0]
+        response = authenticated_client_rbac_manage_users_only.delete(
+            reverse("api-key-revoke", kwargs={"pk": api_key.id})
+        )
+        assert response.status_code == status.HTTP_403_FORBIDDEN
+
+    def test_api_keys_tenant_isolation(
+        self, authenticated_client, api_keys_fixture, tenants_fixture
+    ):
+        """Test that API keys are isolated by tenant (RLS enforcement)."""
+        # Create a second tenant with different user
+
+        tenant2 = Tenant.objects.create(name="Another Tenant")
+        user2 = User.objects.create_user(
+            name="Another User",
+            email="another@example.com",
+            password=TEST_PASSWORD,
+        )
+        Membership.objects.create(
+            user=user2,
+            tenant=tenant2,
+            role=Membership.RoleChoices.OWNER,
+        )
+
+        # Create API key for tenant2
+        TenantAPIKey.objects.create_api_key(
+            name="Tenant 2 Key",
+            tenant_id=tenant2.id,
+            entity=user2,
+        )
+
+        # Authenticate as user from tenant 1
+        response = authenticated_client.get(reverse("api-key-list"))
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+
+        # Should only see keys from tenant 1
+        assert len(data) == len(api_keys_fixture)
+        assert all(item["attributes"]["name"] != "Tenant 2 Key" for item in data)
+
+    def test_api_keys_tenant_isolation_retrieve(
+        self, authenticated_client, tenants_fixture
+    ):
+        """Test that retrieving API key from another tenant returns 404."""
+        # Create a second tenant with API key
+        tenant2 = Tenant.objects.create(name="Another Tenant")
+        user2 = User.objects.create_user(
+            name="Another User",
+            email="another2@example.com",
+            password=TEST_PASSWORD,
+        )
+        Membership.objects.create(
+            user=user2,
+            tenant=tenant2,
+            role=Membership.RoleChoices.OWNER,
+        )
+
+        api_key2, _ = TenantAPIKey.objects.create_api_key(
+            name="Tenant 2 Key",
+            tenant_id=tenant2.id,
+            entity=user2,
+        )
+
+        # Try to retrieve tenant2's API key as tenant1 user
+        response = authenticated_client.get(
+            reverse("api-key-detail", kwargs={"pk": api_key2.id})
+        )
+        # Should return 404 due to RLS filtering
+        assert response.status_code == status.HTTP_404_NOT_FOUND
+
+    def test_api_keys_tenant_isolation_revoke(
+        self, authenticated_client, tenants_fixture
+    ):
+        """Test that revoking API key from another tenant returns 404."""
+        # Create a second tenant with API key
+        tenant2 = Tenant.objects.create(name="Another Tenant")
+        user2 = User.objects.create_user(
+            name="Another User",
+            email="another3@example.com",
+            password=TEST_PASSWORD,
+        )
+        Membership.objects.create(
+            user=user2,
+            tenant=tenant2,
+            role=Membership.RoleChoices.OWNER,
+        )
+
+        api_key2, _ = TenantAPIKey.objects.create_api_key(
+            name="Tenant 2 Key",
+            tenant_id=tenant2.id,
+            entity=user2,
+        )
+
+        # Try to revoke tenant2's API key as tenant1 user
+        response = authenticated_client.delete(
+            reverse("api-key-revoke", kwargs={"pk": api_key2.id})
+        )
+        # Should return 404 due to RLS filtering
+        assert response.status_code == status.HTTP_404_NOT_FOUND
+
+    def test_api_keys_read_only_fields_on_create(
+        self, authenticated_client, create_test_user
+    ):
+        """Test that read-only fields are ignored during creation."""
+        # Note: Fields not in serializer (like 'prefix', 'revoked') will cause 400
+        # So we only test that the response has correct read-only values
+        data = {
+            "data": {
+                "type": "api-keys",
+                "attributes": {
+                    "name": "Test Read-Only",
+                },
+            }
+        }
+        response = authenticated_client.post(
+            reverse("api-key-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+        response_data = response.json()["data"]
+
+        # Verify read-only fields have correct default/auto-generated values
+        # Prefix should be auto-generated (not empty, not None)
+        assert response_data["attributes"]["prefix"] is not None
+        assert len(response_data["attributes"]["prefix"]) > 0
+
+        # Revoked should be False (default)
+        assert response_data["attributes"]["revoked"] is False
+
+        # Entity should be set to current user (auto-assigned)
+        assert response_data["relationships"]["entity"]["data"]["id"] == str(
+            create_test_user.id
+        )
+
+    def test_api_keys_entity_relationship_included(
+        self, authenticated_client, api_keys_fixture
+    ):
+        """Test that entity (user) relationship is included correctly."""
+        api_key = api_keys_fixture[0]
+        response = authenticated_client.get(
+            reverse("api-key-detail", kwargs={"pk": api_key.id})
+        )
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert "entity" in data["relationships"]
+        assert data["relationships"]["entity"]["data"]["type"] == "users"
+        assert data["relationships"]["entity"]["data"]["id"] == str(api_key.entity.id)
+
+    def test_api_keys_retrieve_with_entity_include(
+        self, authenticated_client, api_keys_fixture
+    ):
+        """Test retrieving API key with ?include=entity returns user data without memberships."""
+        api_key = api_keys_fixture[0]
+        response = authenticated_client.get(
+            reverse("api-key-detail", kwargs={"pk": api_key.id}),
+            {"include": "entity"},
+        )
+        assert response.status_code == status.HTTP_200_OK
+        response_data = response.json()
+
+        # Verify the main data contains the entity relationship
+        data = response_data["data"]
+        assert "entity" in data["relationships"]
+        assert data["relationships"]["entity"]["data"]["type"] == "users"
+        assert data["relationships"]["entity"]["data"]["id"] == str(api_key.entity.id)
+
+        # Verify included section exists
+        assert "included" in response_data
+        assert len(response_data["included"]) == 1
+
+        # Verify included user data
+        included_user = response_data["included"][0]
+        assert included_user["type"] == "users"
+        assert included_user["id"] == str(api_key.entity.id)
+
+        # Refresh entity from database to get current state
+        # (in case other tests modified the shared session-scoped user fixture)
+        api_key.entity.refresh_from_db()
+
+        # Verify UserIncludeSerializer fields are present
+        user_attrs = included_user["attributes"]
+        assert "name" in user_attrs
+        assert "email" in user_attrs
+        assert "company_name" in user_attrs
+        assert "date_joined" in user_attrs
+        assert user_attrs["name"] == api_key.entity.name
+        assert user_attrs["email"] == api_key.entity.email
+
+        # Verify memberships field is NOT included (excluded by UserIncludeSerializer)
+        assert "memberships" not in user_attrs
+
+        # Verify roles relationship is present
+        assert "relationships" in included_user
+        assert "roles" in included_user["relationships"]
+
+    def test_api_keys_entity_auto_assigned_on_create(
+        self, authenticated_client, create_test_user
+    ):
+        """Test that entity is automatically assigned to current user on creation."""
+        data = {
+            "data": {
+                "type": "api-keys",
+                "attributes": {
+                    "name": "Auto Entity Key",
+                },
+            }
+        }
+        response = authenticated_client.post(
+            reverse("api-key-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+        response_data = response.json()["data"]
+
+        # Entity should be set to authenticated user
+        assert response_data["relationships"]["entity"]["data"]["id"] == str(
+            create_test_user.id
+        )
+
+        # Verify in database
+        api_key_id = response_data["id"]
+        api_key = TenantAPIKey.objects.get(id=api_key_id)
+        assert api_key.entity.id == create_test_user.id
+
+    def test_api_keys_list_response_structure(
+        self, authenticated_client, api_keys_fixture
+    ):
+        """Test that list response follows JSON:API structure."""
+        response = authenticated_client.get(reverse("api-key-list"))
+        assert response.status_code == status.HTTP_200_OK
+        response_data = response.json()
+
+        # Verify top-level structure
+        assert "data" in response_data
+        assert "meta" in response_data
+        assert isinstance(response_data["data"], list)
+
+        # Verify pagination meta
+        assert "pagination" in response_data["meta"]
+        assert "count" in response_data["meta"]["pagination"]
+        assert "page" in response_data["meta"]["pagination"]
+        assert "pages" in response_data["meta"]["pagination"]
+
+    def test_api_keys_retrieve_response_structure(
+        self, authenticated_client, api_keys_fixture
+    ):
+        """Test that retrieve response follows JSON:API structure."""
+        api_key = api_keys_fixture[0]
+        response = authenticated_client.get(
+            reverse("api-key-detail", kwargs={"pk": api_key.id})
+        )
+        assert response.status_code == status.HTTP_200_OK
+        response_data = response.json()
+
+        # Verify top-level structure
+        assert "data" in response_data
+        data = response_data["data"]
+
+        # Verify resource object structure
+        assert "type" in data
+        assert data["type"] == "api-keys"
+        assert "id" in data
+        assert "attributes" in data
+        assert "relationships" in data
+
+    def test_api_keys_create_response_structure(
+        self, authenticated_client, create_test_user
+    ):
+        """Test that create response follows JSON:API structure."""
+        data = {
+            "data": {
+                "type": "api-keys",
+                "attributes": {
+                    "name": "Structure Test Key",
+                },
+            }
+        }
+        response = authenticated_client.post(
+            reverse("api-key-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+        response_data = response.json()
+
+        # Verify top-level structure
+        assert "data" in response_data
+        data = response_data["data"]
+
+        # Verify resource object structure
+        assert "type" in data
+        assert data["type"] == "api-keys"
+        assert "id" in data
+        assert "attributes" in data
+        assert "relationships" in data
+
+        # Verify api_key is included in creation response only
+        assert "api_key" in data["attributes"]
+        assert data["attributes"]["api_key"] is not None
+
+    def test_api_keys_error_response_structure(self, authenticated_client):
+        """Test that error responses follow JSON:API structure."""
+        response = authenticated_client.get(
+            reverse(
+                "api-key-detail",
+                kwargs={"pk": "f498b103-c760-4785-9a3e-e23fafbb7b02"},
+            )
+        )
+        assert response.status_code == status.HTTP_404_NOT_FOUND
+        response_data = response.json()
+
+        # Verify error structure
+        assert "errors" in response_data
+        assert isinstance(response_data["errors"], list)
+        assert len(response_data["errors"]) > 0
+
+        # Verify error object structure
+        error = response_data["errors"][0]
+        assert "detail" in error or "title" in error
+
+
+@pytest.mark.django_db
+class TestLighthouseTenantConfigViewSet:
+    """Test Lighthouse tenant configuration endpoint (singleton pattern)"""
+
+    def test_lighthouse_tenant_config_create_via_patch(self, authenticated_client):
+        """Test creating a tenant config successfully via PATCH (upsert)"""
+        payload = {
+            "data": {
+                "type": "lighthouse-configurations",
+                "attributes": {
+                    "business_context": "Test business context for security analysis",
+                    "default_provider": "",
+                    "default_models": {},
+                },
+            }
+        }
+        response = authenticated_client.patch(
+            reverse("lighthouse-configurations"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert (
+            data["attributes"]["business_context"]
+            == "Test business context for security analysis"
+        )
+        assert data["attributes"]["default_provider"] == ""
+        assert data["attributes"]["default_models"] == {}
+
+    def test_lighthouse_tenant_config_upsert_behavior(self, authenticated_client):
+        """Test that PATCH creates config if not exists and updates if exists (upsert)"""
+        payload = {
+            "data": {
+                "type": "lighthouse-configurations",
+                "attributes": {
+                    "business_context": "First config",
+                },
+            }
+        }
+
+        # First PATCH creates the config
+        response = authenticated_client.patch(
+            reverse("lighthouse-configurations"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert response.status_code == status.HTTP_200_OK
+        first_data = response.json()["data"]
+        assert first_data["attributes"]["business_context"] == "First config"
+
+        # Second PATCH updates the same config (not creating a duplicate)
+        payload["data"]["attributes"]["business_context"] = "Updated config"
+        response = authenticated_client.patch(
+            reverse("lighthouse-configurations"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert response.status_code == status.HTTP_200_OK
+        second_data = response.json()["data"]
+        assert second_data["attributes"]["business_context"] == "Updated config"
+        # Verify it's the same config (same ID)
+        assert first_data["id"] == second_data["id"]
+
+    @patch("openai.OpenAI")
+    def test_lighthouse_tenant_config_retrieve(
+        self, mock_openai_client, authenticated_client, tenants_fixture
+    ):
+        """Test retrieving the singleton tenant config with proper provider and model validation"""
+
+        # Mock OpenAI client and models response
+        mock_models_response = Mock()
+        mock_models_response.data = [
+            Mock(id="gpt-4o"),
+            Mock(id="gpt-4o-mini"),
+            Mock(id="gpt-5"),
+        ]
+        mock_openai_client.return_value.models.list.return_value = mock_models_response
+
+        # Create OpenAI provider configuration
+        provider_config = LighthouseProviderConfiguration.objects.create(
+            tenant_id=tenants_fixture[0].id,
+            provider_type="openai",
+            credentials=b'{"api_key": "sk-test1234567890T3BlbkFJtest1234567890"}',
+            is_active=True,
+        )
+
+        # Create provider models (simulating refresh)
+        LighthouseProviderModels.objects.create(
+            tenant_id=tenants_fixture[0].id,
+            provider_configuration=provider_config,
+            model_id="gpt-4o",
+            default_parameters={},
+        )
+        LighthouseProviderModels.objects.create(
+            tenant_id=tenants_fixture[0].id,
+            provider_configuration=provider_config,
+            model_id="gpt-4o-mini",
+            default_parameters={},
+        )
+
+        # Create tenant configuration with valid provider and model
+        config = LighthouseTenantConfiguration.objects.create(
+            tenant_id=tenants_fixture[0].id,
+            business_context="Test context",
+            default_provider="openai",
+            default_models={"openai": "gpt-4o"},
+        )
+
+        # Retrieve and verify the configuration
+        response = authenticated_client.get(reverse("lighthouse-configurations"))
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert data["id"] == str(config.id)
+        assert data["attributes"]["business_context"] == "Test context"
+        assert data["attributes"]["default_provider"] == "openai"
+        assert data["attributes"]["default_models"] == {"openai": "gpt-4o"}
+
+    def test_lighthouse_tenant_config_retrieve_not_found(self, authenticated_client):
+        """Test GET when config doesn't exist returns 404"""
+        response = authenticated_client.get(reverse("lighthouse-configurations"))
+        assert response.status_code == status.HTTP_404_NOT_FOUND
+        assert "not found" in response.json()["errors"][0]["detail"].lower()
+
+    def test_lighthouse_tenant_config_partial_update(
+        self, authenticated_client, tenants_fixture
+    ):
+        """Test updating tenant config fields"""
+        from api.models import LighthouseTenantConfiguration
+
+        # Create config first
+        config = LighthouseTenantConfiguration.objects.create(
+            tenant_id=tenants_fixture[0].id,
+            business_context="Original context",
+            default_provider="",
+            default_models={},
+        )
+
+        # Update it
+        payload = {
+            "data": {
+                "type": "lighthouse-configurations",
+                "attributes": {
+                    "business_context": "Updated context for cloud security",
+                },
+            }
+        }
+        response = authenticated_client.patch(
+            reverse("lighthouse-configurations"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert response.status_code == status.HTTP_200_OK
+
+        # Verify update
+        config.refresh_from_db()
+        assert config.business_context == "Updated context for cloud security"
+
+    def test_lighthouse_tenant_config_update_invalid_provider(
+        self, authenticated_client, tenants_fixture
+    ):
+        """Test validation fails when default_provider is not configured and active"""
+        from api.models import LighthouseTenantConfiguration
+
+        # Create config first
+        LighthouseTenantConfiguration.objects.create(
+            tenant_id=tenants_fixture[0].id,
+            business_context="Test",
+        )
+
+        # Try to set invalid provider
+        payload = {
+            "data": {
+                "type": "lighthouse-configurations",
+                "attributes": {
+                    "default_provider": "nonexistent-provider",
+                },
+            }
+        }
+        response = authenticated_client.patch(
+            reverse("lighthouse-configurations"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+        assert "provider" in response.json()["errors"][0]["detail"].lower()
+
+    def test_lighthouse_tenant_config_update_invalid_json_format(
+        self, authenticated_client, tenants_fixture
+    ):
+        """Test that invalid JSON payload is rejected"""
+        from api.models import LighthouseTenantConfiguration
+
+        # Create config first
+        LighthouseTenantConfiguration.objects.create(
+            tenant_id=tenants_fixture[0].id,
+            business_context="Test",
+        )
+
+        # Send invalid JSON
+        response = authenticated_client.patch(
+            reverse("lighthouse-configurations"),
+            data="invalid json",
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+
+
+@pytest.mark.django_db
+class TestLighthouseProviderConfigViewSet:
+    """Tests for LighthouseProviderConfiguration create validations"""
+
+    def test_invalid_provider_type(self, authenticated_client):
+        """Add invalid provider (testprovider) should error"""
+        payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "attributes": {
+                    "provider_type": "testprovider",
+                    "credentials": {"api_key": "sk-testT3BlbkFJkey"},
+                },
+            }
+        }
+        resp = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert resp.status_code == status.HTTP_400_BAD_REQUEST
+
+    def test_openai_missing_credentials(self, authenticated_client):
+        """OpenAI provider without credentials should error"""
+        payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "attributes": {
+                    "provider_type": "openai",
+                },
+            }
+        }
+        resp = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert resp.status_code == status.HTTP_400_BAD_REQUEST
+
+    @pytest.mark.parametrize(
+        "credentials",
+        [
+            {},  # empty credentials
+            {"token": "sk-testT3BlbkFJkey"},  # wrong key name
+            {"api_key": "ks-invalid-format"},  # wrong format
+        ],
+    )
+    def test_openai_invalid_credentials(self, authenticated_client, credentials):
+        """OpenAI provider with invalid credentials should error"""
+        payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "attributes": {
+                    "provider_type": "openai",
+                    "credentials": credentials,
+                },
+            }
+        }
+        resp = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert resp.status_code == status.HTTP_400_BAD_REQUEST
+
+    def test_openai_valid_credentials_success(self, authenticated_client):
+        """OpenAI provider with valid sk-xxx format should succeed"""
+        valid_key = "sk-abc123T3BlbkFJxyz456"
+        payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "attributes": {
+                    "provider_type": "openai",
+                    "credentials": {"api_key": valid_key},
+                },
+            }
+        }
+        resp = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert resp.status_code == status.HTTP_201_CREATED
+        data = resp.json()["data"]
+
+        masked_creds = data["attributes"].get("credentials")
+        assert masked_creds is not None
+        assert "api_key" in masked_creds
+        assert masked_creds["api_key"] == ("*" * len(valid_key))
+
+    def test_openai_provider_duplicate_per_tenant(self, authenticated_client):
+        """If an OpenAI provider exists for tenant, creating again should error"""
+        valid_key = "sk-dup123T3BlbkFJdup456"
+        payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "attributes": {
+                    "provider_type": "openai",
+                    "credentials": {"api_key": valid_key},
+                },
+            }
+        }
+        # First creation succeeds
+        resp1 = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert resp1.status_code == status.HTTP_201_CREATED
+
+        # Second creation should fail with validation error
+        resp2 = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert resp2.status_code == status.HTTP_400_BAD_REQUEST
+        assert "already exists" in str(resp2.json()).lower()
+
+    def test_openai_patch_base_url_and_is_active(self, authenticated_client):
+        """After creating, should be able to patch base_url and is_active"""
+        valid_key = "sk-patch123T3BlbkFJpatch456"
+        create_payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "attributes": {
+                    "provider_type": "openai",
+                    "credentials": {"api_key": valid_key},
+                },
+            }
+        }
+        create_resp = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=create_payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert create_resp.status_code == status.HTTP_201_CREATED
+        provider_id = create_resp.json()["data"]["id"]
+
+        patch_payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "id": provider_id,
+                "attributes": {
+                    "base_url": "https://api.example.com/v1",
+                    "is_active": False,
+                },
+            }
+        }
+        patch_resp = authenticated_client.patch(
+            reverse("lighthouse-providers-detail", kwargs={"pk": provider_id}),
+            data=patch_payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert patch_resp.status_code == status.HTTP_200_OK
+        updated = patch_resp.json()["data"]["attributes"]
+        assert updated["base_url"] == "https://api.example.com/v1"
+        assert updated["is_active"] is False
+
+    def test_openai_patch_invalid_credentials(self, authenticated_client):
+        """PATCH with invalid credentials.api_key should error (400)"""
+        valid_key = "sk-ok123T3BlbkFJok456"
+        create_payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "attributes": {
+                    "provider_type": "openai",
+                    "credentials": {"api_key": valid_key},
+                },
+            }
+        }
+        create_resp = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=create_payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert create_resp.status_code == status.HTTP_201_CREATED
+        provider_id = create_resp.json()["data"]["id"]
+
+        # Try patch with invalid api_key format
+        patch_payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "id": provider_id,
+                "attributes": {
+                    "credentials": {"api_key": "ks-invalid-format"},
+                },
+            }
+        }
+        patch_resp = authenticated_client.patch(
+            reverse("lighthouse-providers-detail", kwargs={"pk": provider_id}),
+            data=patch_payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert patch_resp.status_code == status.HTTP_400_BAD_REQUEST
+
+    def test_openai_get_masking_and_fields_filter(self, authenticated_client):
+        valid_key = "sk-get123T3BlbkFJget456"
+        create_payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "attributes": {
+                    "provider_type": "openai",
+                    "credentials": {"api_key": valid_key},
+                },
+            }
+        }
+        create_resp = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=create_payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert create_resp.status_code == status.HTTP_201_CREATED
+        provider_id = create_resp.json()["data"]["id"]
+
+        # Default GET should return masked credentials
+        get_resp = authenticated_client.get(
+            reverse("lighthouse-providers-detail", kwargs={"pk": provider_id})
+        )
+        assert get_resp.status_code == status.HTTP_200_OK
+        masked = get_resp.json()["data"]["attributes"]["credentials"]["api_key"]
+        assert masked == ("*" * len(valid_key))
+
+        # Fields filter should return decrypted credentials structure
+        get_full = authenticated_client.get(
+            reverse("lighthouse-providers-detail", kwargs={"pk": provider_id})
+            + "?fields[lighthouse-providers]=credentials"
+        )
+        assert get_full.status_code == status.HTTP_200_OK
+        creds = get_full.json()["data"]["attributes"]["credentials"]
+        assert creds["api_key"] == valid_key
+
+    def test_delete_provider_updates_tenant_defaults(
+        self, authenticated_client, tenants_fixture
+    ):
+        """Deleting a provider config should clear tenant default_provider and its default_model entry."""
+
+        tenant = tenants_fixture[0]
+
+        # Create provider configuration to delete
+        provider = LighthouseProviderConfiguration.objects.create(
+            tenant_id=tenant.id,
+            provider_type="openai",
+            credentials=b'{"api_key":"sk-test123T3BlbkFJ"}',
+            is_active=True,
+        )
+
+        # Seed tenant defaults referencing the provider we will delete
+        cfg = LighthouseTenantConfiguration.objects.create(
+            tenant_id=tenant.id,
+            business_context="Test",
+            default_provider="openai",
+            default_models={"openai": "gpt-4o", "other": "model-x"},
+        )
+
+        # Delete via API and validate response
+        url = reverse("lighthouse-providers-detail", kwargs={"pk": str(provider.id)})
+        resp = authenticated_client.delete(url)
+        assert resp.status_code in (
+            status.HTTP_204_NO_CONTENT,
+            status.HTTP_200_OK,
+        )
+
+        # Tenant defaults should be updated
+        cfg.refresh_from_db()
+        assert cfg.default_provider == ""
+        assert "openai" not in cfg.default_models
+
+        # Unrelated entries should remain untouched
+        assert cfg.default_models.get("other") == "model-x"
+
+
+@pytest.mark.django_db
+class TestMuteRuleViewSet:
+    """Tests for MuteRule endpoints."""
+
+    def test_mute_rules_list(self, authenticated_client, mute_rules_fixture):
+        """Test listing all mute rules for the tenant."""
+        response = authenticated_client.get(reverse("mute-rule-list"))
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert len(data) == len(mute_rules_fixture)
+
+    def test_mute_rules_list_empty(self, authenticated_client, tenants_fixture):
+        """Test listing mute rules when none exist returns empty list."""
+        response = authenticated_client.get(reverse("mute-rule-list"))
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert len(data) == 0
+        assert isinstance(data, list)
+
+    def test_mute_rules_list_default_ordering(
+        self, authenticated_client, mute_rules_fixture
+    ):
+        """Test that mute rules are ordered by -inserted_at by default."""
+        response = authenticated_client.get(reverse("mute-rule-list"))
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+
+        if len(data) >= 2:
+            first_date = data[0]["attributes"]["inserted_at"]
+            second_date = data[1]["attributes"]["inserted_at"]
+            assert first_date >= second_date
+
+    def test_mute_rules_retrieve(self, authenticated_client, mute_rules_fixture):
+        """Test retrieving a single mute rule by ID."""
+        mute_rule = mute_rules_fixture[0]
+        response = authenticated_client.get(
+            reverse("mute-rule-detail", kwargs={"pk": mute_rule.id})
+        )
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert data["id"] == str(mute_rule.id)
+        assert data["attributes"]["name"] == mute_rule.name
+        assert data["attributes"]["reason"] == mute_rule.reason
+        assert data["attributes"]["enabled"] == mute_rule.enabled
+        assert "finding_uids" in data["attributes"]
+        assert "inserted_at" in data["attributes"]
+        assert "updated_at" in data["attributes"]
+
+    def test_mute_rules_retrieve_invalid(self, authenticated_client):
+        """Test retrieving non-existent mute rule returns 404."""
+        response = authenticated_client.get(
+            reverse(
+                "mute-rule-detail",
+                kwargs={"pk": "f498b103-c760-4785-9a3e-e23fafbb7b02"},
+            )
+        )
+        assert response.status_code == status.HTTP_404_NOT_FOUND
+
+    @pytest.mark.parametrize(
+        "filter_name, filter_value, expected_count",
+        (
+            [
+                ("name", "Test Rule 1", 1),
+                ("name.icontains", "rule", 2),
+                ("reason.icontains", "security", 1),
+                ("enabled", True, 1),
+                ("enabled", False, 1),
+            ]
+        ),
+    )
+    def test_mute_rule_filters(
+        self,
+        authenticated_client,
+        mute_rules_fixture,
+        filter_name,
+        filter_value,
+        expected_count,
+    ):
+        """Test filtering mute rules by various fields."""
+        filters = {f"filter[{filter_name}]": filter_value}
+        response = authenticated_client.get(reverse("mute-rule-list"), filters)
+        assert response.status_code == status.HTTP_200_OK
+        assert len(response.json()["data"]) == expected_count
+
+    def test_mute_rule_filter_by_created_by(
+        self, authenticated_client, mute_rules_fixture, create_test_user
+    ):
+        """Test filtering mute rules by creator."""
+        response = authenticated_client.get(
+            reverse("mute-rule-list"),
+            {"filter[created_by]": create_test_user.id},
+        )
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert len(data) == 2
+
+    def test_mute_rule_search(self, authenticated_client, mute_rules_fixture):
+        """Test searching mute rules by name and reason."""
+        response = authenticated_client.get(
+            reverse("mute-rule-list"), {"filter[search]": "Rule 1"}
+        )
+        assert response.status_code == status.HTTP_200_OK
+        assert len(response.json()["data"]) == 1
+
+    @pytest.mark.parametrize(
+        "sort_field, first_index",
+        (
+            [
+                ("name", 0),
+                ("-name", 1),
+                ("inserted_at", 0),
+                ("-inserted_at", 1),
+            ]
+        ),
+    )
+    def test_mute_rule_ordering(
+        self, authenticated_client, mute_rules_fixture, sort_field, first_index
+    ):
+        """Test ordering mute rules by various fields."""
+        response = authenticated_client.get(
+            reverse("mute-rule-list"), {"sort": sort_field}
+        )
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert len(data) == 2
+        assert data[0]["id"] == str(mute_rules_fixture[first_index].id)
+
+    @patch("tasks.tasks.mute_historical_findings_task.apply_async")
+    def test_mute_rules_create_valid(
+        self,
+        mock_task,
+        authenticated_client,
+        findings_fixture,
+        create_test_user,
+    ):
+        """Test creating a valid mute rule."""
+        finding_ids = [str(findings_fixture[0].id)]
+        data = {
+            "data": {
+                "type": "mute-rules",
+                "attributes": {
+                    "name": "New Mute Rule",
+                    "reason": "Security exception approved",
+                    "finding_ids": finding_ids,
+                },
+            }
+        }
+        response = authenticated_client.post(
+            reverse("mute-rule-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+
+        # Verify response contains the created mute rule
+        response_data = response.json()["data"]
+        assert response_data["type"] == "mute-rules"
+        assert response_data["attributes"]["name"] == "New Mute Rule"
+        assert response_data["attributes"]["reason"] == "Security exception approved"
+
+        # Verify the finding was immediately muted
+        from api.models import Finding
+
+        finding = Finding.objects.get(id=findings_fixture[0].id)
+        assert finding.muted is True
+        assert finding.muted_at is not None
+        assert finding.muted_reason == "Security exception approved"
+
+        # Verify background task was called
+        mock_task.assert_called_once()
+
+    @patch("tasks.tasks.mute_historical_findings_task.apply_async")
+    def test_mute_rules_create_converts_finding_ids_to_uids(
+        self,
+        mock_task,
+        authenticated_client,
+        findings_fixture,
+    ):
+        """Test that finding_ids are converted to finding UIDs."""
+        finding_ids = [str(findings_fixture[0].id), str(findings_fixture[1].id)]
+        data = {
+            "data": {
+                "type": "mute-rules",
+                "attributes": {
+                    "name": "UID Conversion Test",
+                    "reason": "Testing UID conversion",
+                    "finding_ids": finding_ids,
+                },
+            }
+        }
+        response = authenticated_client.post(
+            reverse("mute-rule-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+
+        # Verify finding_uids contains the UIDs, not IDs
+        from api.models import MuteRule
+
+        mute_rule = MuteRule.objects.get(name="UID Conversion Test")
+        expected_uids = [
+            findings_fixture[0].uid,
+            findings_fixture[1].uid,
+        ]
+        assert set(mute_rule.finding_uids) == set(expected_uids)
+
+    @patch("tasks.tasks.mute_historical_findings_task.apply_async")
+    def test_mute_rules_deduplicates_uids(
+        self,
+        mock_task,
+        authenticated_client,
+        tenants_fixture,
+        providers_fixture,
+        scans_fixture,
+    ):
+        """Test that multiple findings with same UID result in only one UID in the rule."""
+        tenant = tenants_fixture[0]
+        scan = scans_fixture[0]
+
+        shared_uid = "prowler-aws-dedupe-test-001"
+
+        finding1 = Finding.objects.create(
+            tenant=tenant,
+            uid=shared_uid,
+            scan=scan,
+            status=Status.FAIL,
+            status_extended="test",
+            severity=Severity.high,
+            impact=Severity.high,
+            check_id="test_check",
+            check_metadata={"CheckId": "test_check"},
+            raw_result={},
+        )
+
+        finding2 = Finding.objects.create(
+            tenant=tenant,
+            uid=shared_uid,
+            scan=scan,
+            status=Status.FAIL,
+            status_extended="test",
+            severity=Severity.high,
+            impact=Severity.high,
+            check_id="test_check",
+            check_metadata={"CheckId": "test_check"},
+            raw_result={},
+        )
+
+        finding_ids = [str(finding1.id), str(finding2.id)]
+        data = {
+            "data": {
+                "type": "mute-rules",
+                "attributes": {
+                    "name": "Dedupe Test Rule",
+                    "reason": "Testing UID deduplication",
+                    "finding_ids": finding_ids,
+                },
+            }
+        }
+        response = authenticated_client.post(
+            reverse("mute-rule-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+
+        from api.models import MuteRule
+
+        mute_rule = MuteRule.objects.get(name="Dedupe Test Rule")
+        assert len(mute_rule.finding_uids) == 1
+        assert mute_rule.finding_uids[0] == shared_uid
+
+        finding1.refresh_from_db()
+        finding2.refresh_from_db()
+        assert finding1.muted is True
+        assert finding2.muted is True
+
+    @patch("tasks.tasks.mute_historical_findings_task.apply_async")
+    def test_mute_rules_create_overlap_detection_active(
+        self,
+        mock_task,
+        authenticated_client,
+        mute_rules_fixture,
+        findings_fixture,
+    ):
+        """Test that creating a rule with overlapping UIDs in active rule fails."""
+        # mute_rules_fixture[0] is active and has findings_fixture[0] UID
+        finding_ids = [str(findings_fixture[0].id)]
+        data = {
+            "data": {
+                "type": "mute-rules",
+                "attributes": {
+                    "name": "Overlapping Rule",
+                    "reason": "This should fail",
+                    "finding_ids": finding_ids,
+                },
+            }
+        }
+        response = authenticated_client.post(
+            reverse("mute-rule-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_409_CONFLICT
+        assert "errors" in response.json()
+        error_detail = response.json()["errors"][0]["detail"]
+        assert (
+            "already muted" in error_detail.lower() or "overlap" in error_detail.lower()
+        )
+
+    @patch("tasks.tasks.mute_historical_findings_task.apply_async")
+    def test_mute_rules_create_no_overlap_with_inactive(
+        self,
+        mock_task,
+        authenticated_client,
+        mute_rules_fixture,
+        findings_fixture,
+    ):
+        """Test that disabled rules don't prevent new rules with same UIDs."""
+        # mute_rules_fixture[1] is disabled
+        # Disable the enabled rule first
+        mute_rules_fixture[0].enabled = False
+        mute_rules_fixture[0].save()
+
+        finding_ids = [str(findings_fixture[0].id)]
+        data = {
+            "data": {
+                "type": "mute-rules",
+                "attributes": {
+                    "name": "Non-overlapping Rule",
+                    "reason": "Inactive rules don't block",
+                    "finding_ids": finding_ids,
+                },
+            }
+        }
+        response = authenticated_client.post(
+            reverse("mute-rule-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_201_CREATED
+
+    def test_mute_rules_create_invalid_empty_finding_ids(self, authenticated_client):
+        """Test creating mute rule with empty finding_ids fails."""
+        data = {
+            "data": {
+                "type": "mute-rules",
+                "attributes": {
+                    "name": "Valid",
+                    "reason": "Valid",
+                    "finding_ids": [],
+                },
+            }
+        }
+        response = authenticated_client.post(
+            reverse("mute-rule-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+        assert "errors" in response.json()
+        assert (
+            response.json()["errors"][0]["source"]["pointer"]
+            == "/data/attributes/finding_ids"
+        )
+
+    @patch("tasks.tasks.mute_historical_findings_task.apply_async")
+    def test_mute_rules_create_invalid_finding_ids(
+        self, mock_task, authenticated_client
+    ):
+        """Test creating mute rule with non-existent finding IDs fails."""
+        data = {
+            "data": {
+                "type": "mute-rules",
+                "attributes": {
+                    "name": "Invalid Findings",
+                    "reason": "This should fail",
+                    "finding_ids": ["f498b103-c760-4785-9a3e-e23fafbb7b02"],
+                },
+            }
+        }
+        response = authenticated_client.post(
+            reverse("mute-rule-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+        assert "errors" in response.json()
+
+    def test_mute_rules_create_duplicate_name(
+        self, authenticated_client, mute_rules_fixture
+    ):
+        """Test creating a mute rule with duplicate name fails."""
+        existing_name = mute_rules_fixture[0].name
+        data = {
+            "data": {
+                "type": "mute-rules",
+                "attributes": {
+                    "name": existing_name,
+                    "reason": "Duplicate name test",
+                    "finding_ids": ["f498b103-c760-4785-9a3e-e23fafbb7b02"],
+                },
+            }
+        }
+        response = authenticated_client.post(
+            reverse("mute-rule-list"),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+        assert "errors" in response.json()
+
+    def test_mute_rules_update_name(self, authenticated_client, mute_rules_fixture):
+        """Test updating mute rule name."""
+        mute_rule = mute_rules_fixture[0]
+        data = {
+            "data": {
+                "type": "mute-rules",
+                "id": str(mute_rule.id),
+                "attributes": {
+                    "name": "Updated Name",
+                },
+            }
+        }
+        response = authenticated_client.patch(
+            reverse("mute-rule-detail", kwargs={"pk": mute_rule.id}),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_200_OK
+        response_data = response.json()["data"]
+        assert response_data["attributes"]["name"] == "Updated Name"
+
+        # Verify database was updated
+        mute_rule.refresh_from_db()
+        assert mute_rule.name == "Updated Name"
+
+    def test_mute_rules_update_reason(self, authenticated_client, mute_rules_fixture):
+        """Test updating mute rule reason."""
+        mute_rule = mute_rules_fixture[0]
+        data = {
+            "data": {
+                "type": "mute-rules",
+                "id": str(mute_rule.id),
+                "attributes": {
+                    "reason": "Updated reason for muting",
+                },
+            }
+        }
+        response = authenticated_client.patch(
+            reverse("mute-rule-detail", kwargs={"pk": mute_rule.id}),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_200_OK
+        response_data = response.json()["data"]
+        assert response_data["attributes"]["reason"] == "Updated reason for muting"
+
+        mute_rule.refresh_from_db()
+        assert mute_rule.reason == "Updated reason for muting"
+
+    def test_mute_rules_update_enabled(self, authenticated_client, mute_rules_fixture):
+        """Test disabling a mute rule."""
+        mute_rule = mute_rules_fixture[0]
+        assert mute_rule.enabled is True
+
+        data = {
+            "data": {
+                "type": "mute-rules",
+                "id": str(mute_rule.id),
+                "attributes": {
+                    "enabled": False,
+                },
+            }
+        }
+        response = authenticated_client.patch(
+            reverse("mute-rule-detail", kwargs={"pk": mute_rule.id}),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_200_OK
+        response_data = response.json()["data"]
+        assert response_data["attributes"]["enabled"] is False
+
+        mute_rule.refresh_from_db()
+        assert mute_rule.enabled is False
+
+    def test_mute_rules_update_duplicate_name(
+        self, authenticated_client, mute_rules_fixture
+    ):
+        """Test updating mute rule with duplicate name fails."""
+        first_rule = mute_rules_fixture[0]
+        second_rule = mute_rules_fixture[1]
+
+        data = {
+            "data": {
+                "type": "mute-rules",
+                "id": str(second_rule.id),
+                "attributes": {
+                    "name": first_rule.name,
+                },
+            }
+        }
+        response = authenticated_client.patch(
+            reverse("mute-rule-detail", kwargs={"pk": second_rule.id}),
+            data=json.dumps(data),
+            content_type="application/vnd.api+json",
+        )
+        assert response.status_code == status.HTTP_400_BAD_REQUEST
+        assert "errors" in response.json()
+
+    def test_mute_rules_delete(self, authenticated_client, mute_rules_fixture):
+        """Test deleting a mute rule."""
+        mute_rule = mute_rules_fixture[0]
+        response = authenticated_client.delete(
+            reverse("mute-rule-detail", kwargs={"pk": mute_rule.id})
+        )
+        assert response.status_code == status.HTTP_204_NO_CONTENT
+
+        # Verify rule was deleted
+        from api.models import MuteRule
+
+        assert not MuteRule.objects.filter(id=mute_rule.id).exists()
+
+    def test_mute_rules_tenant_isolation(
+        self, authenticated_client, mute_rules_fixture, tenants_fixture
+    ):
+        """Test that users can only access mute rules from their tenant."""
+        # Create a second tenant with a mute rule
+        from api.models import MuteRule, Tenant
+
+        other_tenant = Tenant.objects.create(name="Other Tenant")
+        other_rule = MuteRule.objects.create(
+            tenant=other_tenant,
+            name="Other Tenant Rule",
+            reason="Should not be visible",
+            finding_uids=["test-uid"],
+        )
+
+        # Try to access other tenant's rule
+        response = authenticated_client.get(
+            reverse("mute-rule-detail", kwargs={"pk": other_rule.id})
+        )
+        assert response.status_code == status.HTTP_404_NOT_FOUND
+
+        # List should only show current tenant's rules
+        response = authenticated_client.get(reverse("mute-rule-list"))
+        assert response.status_code == status.HTTP_200_OK
+        data = response.json()["data"]
+        assert len(data) == len(mute_rules_fixture)
+        for rule_data in data:
+            assert rule_data["id"] != str(other_rule.id)
+
+    @pytest.mark.parametrize(
+        "credentials",
+        [
+            {},  # empty credentials
+            {
+                "access_key_id": "AKIAIOSFODNN7EXAMPLE"
+            },  # missing secret_access_key and region
+            {
+                "secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
+            },  # missing access_key_id and region
+            {
+                "access_key_id": "AKIAIOSFODNN7EXAMPLE",
+                "secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
+            },  # missing region
+            {  # invalid access_key_id format (not starting with AKIA)
+                "access_key_id": "ABCD0123456789ABCDEF",
+                "secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
+                "region": "us-east-1",
+            },
+            {  # invalid access_key_id format (wrong length)
+                "access_key_id": "AKIAIOSFODNN7EXAMPL",
+                "secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
+                "region": "us-east-1",
+            },
+            {  # invalid secret_access_key format (wrong length)
+                "access_key_id": "AKIAIOSFODNN7EXAMPLE",
+                "secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEK",
+                "region": "us-east-1",
+            },
+            {  # invalid region format
+                "access_key_id": "AKIAIOSFODNN7EXAMPLE",
+                "secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
+                "region": "invalid-region",
+            },
+            {  # invalid region format (uppercase)
+                "access_key_id": "AKIAIOSFODNN7EXAMPLE",
+                "secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
+                "region": "US-EAST-1",
+            },
+        ],
+    )
+    def test_bedrock_invalid_credentials(self, authenticated_client, credentials):
+        """Bedrock provider with invalid credentials should error"""
+        payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "attributes": {
+                    "provider_type": "bedrock",
+                    "credentials": credentials,
+                },
+            }
+        }
+        resp = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert resp.status_code == status.HTTP_400_BAD_REQUEST
+
+    def test_bedrock_valid_credentials_success(self, authenticated_client):
+        """Bedrock provider with valid AWS credentials should succeed and mask credentials"""
+        valid_credentials = {
+            "access_key_id": "AKIAIOSFODNN7EXAMPLE",
+            "secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
+            "region": "us-east-1",
+        }
+        payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "attributes": {
+                    "provider_type": "bedrock",
+                    "credentials": valid_credentials,
+                },
+            }
+        }
+        resp = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert resp.status_code == status.HTTP_201_CREATED
+        data = resp.json()["data"]
+
+        # Verify credentials are returned masked
+        masked_creds = data["attributes"].get("credentials")
+        assert masked_creds is not None
+        assert "access_key_id" in masked_creds
+        assert "secret_access_key" in masked_creds
+        assert "region" in masked_creds
+        # Verify all characters are masked with asterisks
+        assert all(c == "*" for c in masked_creds["access_key_id"])
+        assert all(c == "*" for c in masked_creds["secret_access_key"])
+
+    def test_bedrock_provider_duplicate_per_tenant(self, authenticated_client):
+        """Creating a second Bedrock provider for same tenant should fail"""
+        valid_credentials = {
+            "access_key_id": "AKIAIOSFODNN7EXAMPLE",
+            "secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
+            "region": "us-west-2",
+        }
+        payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "attributes": {
+                    "provider_type": "bedrock",
+                    "credentials": valid_credentials,
+                },
+            }
+        }
+        # First creation succeeds
+        resp1 = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert resp1.status_code == status.HTTP_201_CREATED
+
+        # Second creation should fail with validation error
+        resp2 = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert resp2.status_code == status.HTTP_400_BAD_REQUEST
+        assert "already exists" in str(resp2.json()).lower()
+
+    def test_bedrock_patch_credentials_and_fields_filter(self, authenticated_client):
+        """PATCH credentials and verify fields filter returns decrypted values"""
+        valid_credentials = {
+            "access_key_id": "AKIAIOSFODNN7EXAMPLE",
+            "secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
+            "region": "eu-west-1",
+        }
+        create_payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "attributes": {
+                    "provider_type": "bedrock",
+                    "credentials": valid_credentials,
+                },
+            }
+        }
+        create_resp = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=create_payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert create_resp.status_code == status.HTTP_201_CREATED
+        provider_id = create_resp.json()["data"]["id"]
+
+        # Update credentials with new valid ones
+        new_credentials = {
+            "access_key_id": "AKIAZZZZZZZZZZZZZZZZ",
+            "secret_access_key": "aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789+/==",
+            "region": "ap-south-1",
+        }
+        patch_payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "id": provider_id,
+                "attributes": {
+                    "credentials": new_credentials,
+                    "is_active": False,
+                },
+            }
+        }
+        patch_resp = authenticated_client.patch(
+            reverse("lighthouse-providers-detail", kwargs={"pk": provider_id}),
+            data=patch_payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert patch_resp.status_code == status.HTTP_200_OK
+        updated = patch_resp.json()["data"]["attributes"]
+        assert updated["is_active"] is False
+
+        # Default GET should return masked credentials
+        get_resp = authenticated_client.get(
+            reverse("lighthouse-providers-detail", kwargs={"pk": provider_id})
+        )
+        assert get_resp.status_code == status.HTTP_200_OK
+        masked = get_resp.json()["data"]["attributes"]["credentials"]
+        assert all(c == "*" for c in masked["access_key_id"])
+        assert all(c == "*" for c in masked["secret_access_key"])
+
+        # Fields filter should return decrypted credentials
+        get_full = authenticated_client.get(
+            reverse("lighthouse-providers-detail", kwargs={"pk": provider_id})
+            + "?fields[lighthouse-providers]=credentials"
+        )
+        assert get_full.status_code == status.HTTP_200_OK
+        creds = get_full.json()["data"]["attributes"]["credentials"]
+        assert creds["access_key_id"] == new_credentials["access_key_id"]
+        assert creds["secret_access_key"] == new_credentials["secret_access_key"]
+        assert creds["region"] == new_credentials["region"]
+
+    def test_bedrock_partial_credential_update(self, authenticated_client):
+        """Test partial update of Bedrock credentials (e.g., only region)"""
+        # Create provider with full credentials
+        initial_credentials = {
+            "access_key_id": "AKIAIOSFODNN7EXAMPLE",
+            "secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
+            "region": "us-east-1",
+        }
+        create_payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "attributes": {
+                    "provider_type": "bedrock",
+                    "credentials": initial_credentials,
+                },
+            }
+        }
+        create_resp = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=create_payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert create_resp.status_code == status.HTTP_201_CREATED
+        provider_id = create_resp.json()["data"]["id"]
+
+        # Update only the region field
+        partial_update = {
+            "region": "eu-west-1",
+        }
+        patch_payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "id": provider_id,
+                "attributes": {
+                    "credentials": partial_update,
+                },
+            }
+        }
+        patch_resp = authenticated_client.patch(
+            reverse("lighthouse-providers-detail", kwargs={"pk": provider_id}),
+            data=patch_payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert patch_resp.status_code == status.HTTP_200_OK
+
+        # Verify credentials with fields filter - region should be updated, keys preserved
+        get_full = authenticated_client.get(
+            reverse("lighthouse-providers-detail", kwargs={"pk": provider_id})
+            + "?fields[lighthouse-providers]=credentials"
+        )
+        assert get_full.status_code == status.HTTP_200_OK
+        creds = get_full.json()["data"]["attributes"]["credentials"]
+
+        # Original keys should be preserved
+        assert creds["access_key_id"] == initial_credentials["access_key_id"]
+        assert creds["secret_access_key"] == initial_credentials["secret_access_key"]
+        # Region should be updated
+        assert creds["region"] == "eu-west-1"
+
+    @pytest.mark.parametrize(
+        "attributes",
+        [
+            pytest.param(
+                {
+                    "provider_type": "openai_compatible",
+                    "credentials": {"api_key": "compat-key"},
+                },
+                id="missing",
+            ),
+            pytest.param(
+                {
+                    "provider_type": "openai_compatible",
+                    "credentials": {"api_key": "compat-key"},
+                    "base_url": "",
+                },
+                id="empty",
+            ),
+        ],
+    )
+    def test_openai_compatible_missing_base_url(self, authenticated_client, attributes):
+        payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "attributes": attributes,
+            }
+        }
+
+        resp = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert resp.status_code == status.HTTP_400_BAD_REQUEST
+        error_detail = str(resp.json()).lower()
+        assert "base_url" in error_detail
+
+    def test_openai_compatible_invalid_credentials(self, authenticated_client):
+        payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "attributes": {
+                    "provider_type": "openai_compatible",
+                    "base_url": "https://compat.example/v1",
+                    "credentials": {"api_key": ""},
+                },
+            }
+        }
+
+        resp = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert resp.status_code == status.HTTP_400_BAD_REQUEST
+        errors = resp.json().get("errors", [])
+        assert any(
+            error.get("source", {}).get("pointer")
+            == "/data/attributes/credentials/api_key"
+            for error in errors
+        )
+        assert any(
+            "may not be blank" in error.get("detail", "").lower() for error in errors
+        )
+
+    def test_openai_compatible_patch_credentials_and_fields(self, authenticated_client):
+        create_payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "attributes": {
+                    "provider_type": "openai_compatible",
+                    "base_url": "https://compat.example/v1",
+                    "credentials": {"api_key": "compat-key-123"},
+                },
+            }
+        }
+
+        create_resp = authenticated_client.post(
+            reverse("lighthouse-providers-list"),
+            data=create_payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert create_resp.status_code == status.HTTP_201_CREATED
+        provider_id = create_resp.json()["data"]["id"]
+
+        updated_base_url = "https://compat.example/v2"
+        updated_api_key = "compat-key-456"
+        patch_payload = {
+            "data": {
+                "type": "lighthouse-providers",
+                "id": provider_id,
+                "attributes": {
+                    "base_url": updated_base_url,
+                    "credentials": {"api_key": updated_api_key},
+                },
+            }
+        }
+
+        patch_resp = authenticated_client.patch(
+            reverse("lighthouse-providers-detail", kwargs={"pk": provider_id}),
+            data=patch_payload,
+            content_type=API_JSON_CONTENT_TYPE,
+        )
+        assert patch_resp.status_code == status.HTTP_200_OK
+        updated_attrs = patch_resp.json()["data"]["attributes"]
+        assert updated_attrs["base_url"] == updated_base_url
+        assert updated_attrs["credentials"]["api_key"] == "*" * len(updated_api_key)
+
+        get_resp = authenticated_client.get(
+            reverse("lighthouse-providers-detail", kwargs={"pk": provider_id})
+        )
+        assert get_resp.status_code == status.HTTP_200_OK
+        masked = get_resp.json()["data"]["attributes"]["credentials"]["api_key"]
+        assert masked == "*" * len(updated_api_key)
+
+        get_full = authenticated_client.get(
+            reverse("lighthouse-providers-detail", kwargs={"pk": provider_id})
+            + "?fields[lighthouse-providers]=credentials"
+        )
+        assert get_full.status_code == status.HTTP_200_OK
+        creds = get_full.json()["data"]["attributes"]["credentials"]
+        assert creds["api_key"] == updated_api_key
diff --git a/api/src/backend/api/utils.py b/api/src/backend/api/utils.py
index 7cbb7a0247..958f24b3f0 100644
--- a/api/src/backend/api/utils.py
+++ b/api/src/backend/api/utils.py
@@ -6,9 +6,11 @@ from django.db.models import Subquery
 from rest_framework.exceptions import NotFound, ValidationError
 
 from api.db_router import MainRouter
+from api.db_utils import rls_transaction
 from api.exceptions import InvitationTokenExpiredException
 from api.models import Integration, Invitation, Processor, Provider, Resource
 from api.v1.serializers import FindingMetadataSerializer
+from prowler.lib.outputs.jira.jira import Jira, JiraBasicAuthError
 from prowler.providers.aws.aws_provider import AwsProvider
 from prowler.providers.aws.lib.s3.s3 import S3
 from prowler.providers.aws.lib.security_hub.security_hub import SecurityHub
@@ -16,8 +18,11 @@ from prowler.providers.azure.azure_provider import AzureProvider
 from prowler.providers.common.models import Connection
 from prowler.providers.gcp.gcp_provider import GcpProvider
 from prowler.providers.github.github_provider import GithubProvider
+from prowler.providers.iac.iac_provider import IacProvider
 from prowler.providers.kubernetes.kubernetes_provider import KubernetesProvider
 from prowler.providers.m365.m365_provider import M365Provider
+from prowler.providers.mongodbatlas.mongodbatlas_provider import MongodbatlasProvider
+from prowler.providers.oraclecloud.oraclecloud_provider import OraclecloudProvider
 
 
 class CustomOAuth2Client(OAuth2Client):
@@ -63,8 +68,11 @@ def return_prowler_provider(
     | AzureProvider
     | GcpProvider
     | GithubProvider
+    | IacProvider
     | KubernetesProvider
     | M365Provider
+    | MongodbatlasProvider
+    | OraclecloudProvider
 ]:
     """Return the Prowler provider class based on the given provider type.
 
@@ -72,7 +80,7 @@ def return_prowler_provider(
         provider (Provider): The provider object containing the provider type and associated secrets.
 
     Returns:
-        AwsProvider | AzureProvider | GcpProvider | GithubProvider | KubernetesProvider | M365Provider: The corresponding provider class.
+        AwsProvider | AzureProvider | GcpProvider | GithubProvider | IacProvider | KubernetesProvider | M365Provider | OraclecloudProvider | MongodbatlasProvider: The corresponding provider class.
 
     Raises:
         ValueError: If the provider type specified in `provider.provider` is not supported.
@@ -90,6 +98,12 @@ def return_prowler_provider(
             prowler_provider = M365Provider
         case Provider.ProviderChoices.GITHUB.value:
             prowler_provider = GithubProvider
+        case Provider.ProviderChoices.MONGODBATLAS.value:
+            prowler_provider = MongodbatlasProvider
+        case Provider.ProviderChoices.IAC.value:
+            prowler_provider = IacProvider
+        case Provider.ProviderChoices.ORACLECLOUD.value:
+            prowler_provider = OraclecloudProvider
         case _:
             raise ValueError(f"Provider type {provider.provider} not supported")
     return prowler_provider
@@ -120,6 +134,27 @@ def get_prowler_provider_kwargs(
         }
     elif provider.provider == Provider.ProviderChoices.KUBERNETES.value:
         prowler_provider_kwargs = {**prowler_provider_kwargs, "context": provider.uid}
+    elif provider.provider == Provider.ProviderChoices.GITHUB.value:
+        if provider.uid:
+            prowler_provider_kwargs = {
+                **prowler_provider_kwargs,
+                "organizations": [provider.uid],
+            }
+    elif provider.provider == Provider.ProviderChoices.IAC.value:
+        # For IaC provider, uid contains the repository URL
+        # Extract the access token if present in the secret
+        prowler_provider_kwargs = {
+            "scan_repository_url": provider.uid,
+        }
+        if "access_token" in provider.secret.secret:
+            prowler_provider_kwargs["oauth_app_token"] = provider.secret.secret[
+                "access_token"
+            ]
+    elif provider.provider == Provider.ProviderChoices.MONGODBATLAS.value:
+        prowler_provider_kwargs = {
+            **prowler_provider_kwargs,
+            "atlas_organization_id": provider.uid,
+        }
 
     if mutelist_processor:
         mutelist_content = mutelist_processor.configuration.get("Mutelist", {})
@@ -137,8 +172,11 @@ def initialize_prowler_provider(
     | AzureProvider
     | GcpProvider
     | GithubProvider
+    | IacProvider
     | KubernetesProvider
     | M365Provider
+    | MongodbatlasProvider
+    | OraclecloudProvider
 ):
     """Initialize a Prowler provider instance based on the given provider type.
 
@@ -147,8 +185,8 @@ def initialize_prowler_provider(
         mutelist_processor (Processor): The mutelist processor object containing the mutelist configuration.
 
     Returns:
-        AwsProvider | AzureProvider | GcpProvider | GithubProvider | KubernetesProvider | M365Provider: An instance of the corresponding provider class
-            (`AwsProvider`, `AzureProvider`, `GcpProvider`, `GithubProvider`, `KubernetesProvider` or `M365Provider`) initialized with the
+        AwsProvider | AzureProvider | GcpProvider | GithubProvider | IacProvider | KubernetesProvider | M365Provider | OraclecloudProvider | MongodbatlasProvider: An instance of the corresponding provider class
+            (`AwsProvider`, `AzureProvider`, `GcpProvider`, `GithubProvider`, `IacProvider`, `KubernetesProvider`, `M365Provider`, `OraclecloudProvider` or `MongodbatlasProvider`) initialized with the
             provider's secrets.
     """
     prowler_provider = return_prowler_provider(provider)
@@ -172,9 +210,23 @@ def prowler_provider_connection_test(provider: Provider) -> Connection:
     except Provider.secret.RelatedObjectDoesNotExist as secret_error:
         return Connection(is_connected=False, error=secret_error)
 
-    return prowler_provider.test_connection(
-        **prowler_provider_kwargs, provider_id=provider.uid, raise_on_exception=False
-    )
+    # For IaC provider, construct the kwargs properly for test_connection
+    if provider.provider == Provider.ProviderChoices.IAC.value:
+        # Don't pass repository_url from secret, use scan_repository_url with the UID
+        iac_test_kwargs = {
+            "scan_repository_url": provider.uid,
+            "raise_on_exception": False,
+        }
+        # Add access_token if present in the secret
+        if "access_token" in prowler_provider_kwargs:
+            iac_test_kwargs["access_token"] = prowler_provider_kwargs["access_token"]
+        return prowler_provider.test_connection(**iac_test_kwargs)
+    else:
+        return prowler_provider.test_connection(
+            **prowler_provider_kwargs,
+            provider_id=provider.uid,
+            raise_on_exception=False,
+        )
 
 
 def prowler_integration_connection_test(integration: Integration) -> Connection:
@@ -193,7 +245,8 @@ def prowler_integration_connection_test(integration: Integration) -> Connection:
             raise_on_exception=False,
         )
     # TODO: It is possible that we can unify the connection test for all integrations, but need refactoring
-    # to avoid code duplication. Actually the AWS integrations are similar, so SecurityHub and S3 can be unified making some changes in the SDK.
+    # to avoid code duplication. Actually the AWS integrations are similar, so SecurityHub and S3 can be unified
+    # making some changes in the SDK.
     elif (
         integration.integration_type == Integration.IntegrationChoices.AWS_SECURITY_HUB
     ):
@@ -223,10 +276,22 @@ def prowler_integration_connection_test(integration: Integration) -> Connection:
             # Save regions information in the integration configuration
             integration.configuration["regions"] = regions_status
             integration.save()
+        else:
+            # Reset regions information if connection fails
+            integration.configuration["regions"] = {}
+            integration.save()
 
         return connection
     elif integration.integration_type == Integration.IntegrationChoices.JIRA:
-        pass
+        jira_connection = Jira.test_connection(
+            **integration.credentials,
+            raise_on_exception=False,
+        )
+        project_keys = jira_connection.projects if jira_connection.is_connected else {}
+        with rls_transaction(str(integration.tenant_id)):
+            integration.configuration["projects"] = project_keys
+            integration.save()
+        return jira_connection
     elif integration.integration_type == Integration.IntegrationChoices.SLACK:
         pass
     else:
@@ -326,3 +391,17 @@ def get_findings_metadata_no_aggregations(tenant_id: str, filtered_queryset):
     serializer.is_valid(raise_exception=True)
 
     return serializer.data
+
+
+def initialize_prowler_integration(integration: Integration) -> Jira:
+    # TODO Refactor other integrations to use this function
+    if integration.integration_type == Integration.IntegrationChoices.JIRA:
+        try:
+            return Jira(**integration.credentials)
+        except JiraBasicAuthError as jira_auth_error:
+            with rls_transaction(str(integration.tenant_id)):
+                integration.configuration["projects"] = {}
+                integration.connected = False
+                integration.connection_last_checked_at = datetime.now(tz=timezone.utc)
+                integration.save()
+            raise jira_auth_error
diff --git a/api/src/backend/api/v1/mixins.py b/api/src/backend/api/v1/mixins.py
index 1cef76a84c..e1a5d3470f 100644
--- a/api/src/backend/api/v1/mixins.py
+++ b/api/src/backend/api/v1/mixins.py
@@ -12,6 +12,24 @@ from api.models import StateChoices, Task
 from api.v1.serializers import TaskSerializer
 
 
+class DisablePaginationMixin:
+    disable_pagination_query_param = "page[disable]"
+    disable_pagination_truthy_values = {"true"}
+
+    def should_disable_pagination(self) -> bool:
+        if not hasattr(self, "request"):
+            return False
+        value = self.request.query_params.get(self.disable_pagination_query_param)
+        if value is None:
+            return False
+        return str(value).lower() in self.disable_pagination_truthy_values
+
+    def paginate_queryset(self, queryset):
+        if self.should_disable_pagination():
+            return None
+        return super().paginate_queryset(queryset)
+
+
 class PaginateByPkMixin:
     """
     Mixin to paginate on a list of PKs (cheaper than heavy JOINs),
diff --git a/api/src/backend/api/v1/serializer_utils/integrations.py b/api/src/backend/api/v1/serializer_utils/integrations.py
index d15eee88ff..b389085886 100644
--- a/api/src/backend/api/v1/serializer_utils/integrations.py
+++ b/api/src/backend/api/v1/serializer_utils/integrations.py
@@ -67,6 +67,17 @@ class SecurityHubConfigSerializer(BaseValidateSerializer):
         resource_name = "integrations"
 
 
+class JiraConfigSerializer(BaseValidateSerializer):
+    domain = serializers.CharField(read_only=True)
+    issue_types = serializers.ListField(
+        read_only=True, child=serializers.CharField(), default=["Task"]
+    )
+    projects = serializers.DictField(read_only=True)
+
+    class Meta:
+        resource_name = "integrations"
+
+
 class AWSCredentialSerializer(BaseValidateSerializer):
     role_arn = serializers.CharField(required=False)
     external_id = serializers.CharField(required=False)
@@ -82,6 +93,15 @@ class AWSCredentialSerializer(BaseValidateSerializer):
         resource_name = "integrations"
 
 
+class JiraCredentialSerializer(BaseValidateSerializer):
+    user_mail = serializers.EmailField(required=True)
+    api_token = serializers.CharField(required=True)
+    domain = serializers.CharField(required=True)
+
+    class Meta:
+        resource_name = "integrations"
+
+
 @extend_schema_field(
     {
         "oneOf": [
@@ -133,6 +153,27 @@ class AWSCredentialSerializer(BaseValidateSerializer):
                     },
                 },
             },
+            {
+                "type": "object",
+                "title": "JIRA Credentials",
+                "properties": {
+                    "user_mail": {
+                        "type": "string",
+                        "format": "email",
+                        "description": "The email address of the JIRA user account.",
+                    },
+                    "api_token": {
+                        "type": "string",
+                        "description": "The API token for authentication with JIRA. This can be generated from your "
+                        "Atlassian account settings.",
+                    },
+                    "domain": {
+                        "type": "string",
+                        "description": "The JIRA domain/instance URL (e.g., 'your-domain.atlassian.net').",
+                    },
+                },
+                "required": ["user_mail", "api_token", "domain"],
+            },
         ]
     }
 )
@@ -153,7 +194,10 @@ class IntegrationCredentialField(serializers.JSONField):
                     },
                     "output_directory": {
                         "type": "string",
-                        "description": 'The directory path within the bucket where files will be saved. Optional - defaults to "output" if not provided. Path will be normalized to remove excessive slashes and invalid characters are not allowed (< > : " | ? *). Maximum length is 900 characters.',
+                        "description": "The directory path within the bucket where files will be saved. Optional - "
+                        'defaults to "output" if not provided. Path will be normalized to remove '
+                        'excessive slashes and invalid characters are not allowed (< > : " | ? *). '
+                        "Maximum length is 900 characters.",
                         "maxLength": 900,
                         "pattern": '^[^<>:"|?*]+$',
                         "default": "output",
@@ -177,6 +221,14 @@ class IntegrationCredentialField(serializers.JSONField):
                     },
                 },
             },
+            {
+                "type": "object",
+                "title": "JIRA",
+                "description": "JIRA integration does not accept any configuration in the payload. Leave it as an "
+                "empty JSON object (`{}`).",
+                "properties": {},
+                "additionalProperties": False,
+            },
         ]
     }
 )
diff --git a/api/src/backend/api/v1/serializer_utils/lighthouse.py b/api/src/backend/api/v1/serializer_utils/lighthouse.py
new file mode 100644
index 0000000000..e29c679ce6
--- /dev/null
+++ b/api/src/backend/api/v1/serializer_utils/lighthouse.py
@@ -0,0 +1,209 @@
+import re
+
+from drf_spectacular.utils import extend_schema_field
+from rest_framework_json_api import serializers
+
+
+class OpenAICredentialsSerializer(serializers.Serializer):
+    api_key = serializers.CharField()
+
+    def validate_api_key(self, value: str) -> str:
+        pattern = r"^sk-[\w-]+$"
+        if not re.match(pattern, value or ""):
+            raise serializers.ValidationError("Invalid OpenAI API key format.")
+        return value
+
+    def to_internal_value(self, data):
+        """Check for unknown fields before DRF filters them out."""
+        if not isinstance(data, dict):
+            raise serializers.ValidationError(
+                {"non_field_errors": ["Credentials must be an object"]}
+            )
+
+        allowed_fields = set(self.fields.keys())
+        provided_fields = set(data.keys())
+        extra_fields = provided_fields - allowed_fields
+
+        if extra_fields:
+            raise serializers.ValidationError(
+                {
+                    "non_field_errors": [
+                        f"Unknown fields in credentials: {', '.join(sorted(extra_fields))}"
+                    ]
+                }
+            )
+
+        return super().to_internal_value(data)
+
+
+class BedrockCredentialsSerializer(serializers.Serializer):
+    """
+    Serializer for AWS Bedrock credentials validation.
+
+    Validates long-term AWS credentials (AKIA) and region format.
+    """
+
+    access_key_id = serializers.CharField()
+    secret_access_key = serializers.CharField()
+    region = serializers.CharField()
+
+    def validate_access_key_id(self, value: str) -> str:
+        """Validate AWS access key ID format (AKIA for long-term credentials)."""
+        pattern = r"^AKIA[0-9A-Z]{16}$"
+        if not re.match(pattern, value or ""):
+            raise serializers.ValidationError(
+                "Invalid AWS access key ID format. Must be AKIA followed by 16 alphanumeric characters."
+            )
+        return value
+
+    def validate_secret_access_key(self, value: str) -> str:
+        """Validate AWS secret access key format (40 base64 characters)."""
+        pattern = r"^[A-Za-z0-9/+=]{40}$"
+        if not re.match(pattern, value or ""):
+            raise serializers.ValidationError(
+                "Invalid AWS secret access key format. Must be 40 base64 characters."
+            )
+        return value
+
+    def validate_region(self, value: str) -> str:
+        """Validate AWS region format."""
+        pattern = r"^[a-z]{2}-[a-z]+-\d+$"
+        if not re.match(pattern, value or ""):
+            raise serializers.ValidationError(
+                "Invalid AWS region format. Expected format like 'us-east-1' or 'eu-west-2'."
+            )
+        return value
+
+    def to_internal_value(self, data):
+        """Check for unknown fields before DRF filters them out."""
+        if not isinstance(data, dict):
+            raise serializers.ValidationError(
+                {"non_field_errors": ["Credentials must be an object"]}
+            )
+
+        allowed_fields = set(self.fields.keys())
+        provided_fields = set(data.keys())
+        extra_fields = provided_fields - allowed_fields
+
+        if extra_fields:
+            raise serializers.ValidationError(
+                {
+                    "non_field_errors": [
+                        f"Unknown fields in credentials: {', '.join(sorted(extra_fields))}"
+                    ]
+                }
+            )
+
+        return super().to_internal_value(data)
+
+
+class BedrockCredentialsUpdateSerializer(BedrockCredentialsSerializer):
+    """
+    Serializer for AWS Bedrock credentials during UPDATE operations.
+
+    Inherits all validation logic from BedrockCredentialsSerializer but makes
+    all fields optional to support partial updates.
+    """
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        # Make all fields optional for updates
+        for field in self.fields.values():
+            field.required = False
+
+
+class OpenAICompatibleCredentialsSerializer(serializers.Serializer):
+    """
+    Minimal serializer for OpenAI-compatible credentials.
+
+    Many OpenAI-compatible providers do not use the same key format as OpenAI.
+    We only require a non-empty API key string. Additional fields can be added later
+    without breaking existing configurations.
+    """
+
+    api_key = serializers.CharField()
+
+    def validate_api_key(self, value: str) -> str:
+        if not isinstance(value, str) or not value.strip():
+            raise serializers.ValidationError("API key is required.")
+        return value.strip()
+
+    def to_internal_value(self, data):
+        """Check for unknown fields before DRF filters them out."""
+        if not isinstance(data, dict):
+            raise serializers.ValidationError(
+                {"non_field_errors": ["Credentials must be an object"]}
+            )
+
+        allowed_fields = set(self.fields.keys())
+        provided_fields = set(data.keys())
+        extra_fields = provided_fields - allowed_fields
+
+        if extra_fields:
+            raise serializers.ValidationError(
+                {
+                    "non_field_errors": [
+                        f"Unknown fields in credentials: {', '.join(sorted(extra_fields))}"
+                    ]
+                }
+            )
+
+        return super().to_internal_value(data)
+
+
+@extend_schema_field(
+    {
+        "oneOf": [
+            {
+                "type": "object",
+                "title": "OpenAI Credentials",
+                "properties": {
+                    "api_key": {
+                        "type": "string",
+                        "description": "OpenAI API key. Must start with 'sk-' followed by alphanumeric characters, "
+                        "hyphens, or underscores.",
+                        "pattern": "^sk-[\\w-]+$",
+                    }
+                },
+                "required": ["api_key"],
+            },
+            {
+                "type": "object",
+                "title": "AWS Bedrock Credentials",
+                "properties": {
+                    "access_key_id": {
+                        "type": "string",
+                        "description": "AWS access key ID.",
+                        "pattern": "^AKIA[0-9A-Z]{16}$",
+                    },
+                    "secret_access_key": {
+                        "type": "string",
+                        "description": "AWS secret access key.",
+                        "pattern": "^[A-Za-z0-9/+=]{40}$",
+                    },
+                    "region": {
+                        "type": "string",
+                        "description": "AWS region identifier where Bedrock is available. Examples: us-east-1, "
+                        "us-west-2, eu-west-1, ap-northeast-1.",
+                        "pattern": "^[a-z]{2}-[a-z]+-\\d+$",
+                    },
+                },
+                "required": ["access_key_id", "secret_access_key", "region"],
+            },
+            {
+                "type": "object",
+                "title": "OpenAI Compatible Credentials",
+                "properties": {
+                    "api_key": {
+                        "type": "string",
+                        "description": "API key for OpenAI-compatible provider. The format varies by provider. "
+                        "Note: The 'base_url' field (separate from credentials) is required when using this provider type.",
+                    }
+                },
+                "required": ["api_key"],
+            },
+        ]
+    }
+)
+class LighthouseCredentialsField(serializers.JSONField):
+    pass
diff --git a/api/src/backend/api/v1/serializer_utils/providers.py b/api/src/backend/api/v1/serializer_utils/providers.py
index 76fa0b4911..4ec772e02f 100644
--- a/api/src/backend/api/v1/serializer_utils/providers.py
+++ b/api/src/backend/api/v1/serializer_utils/providers.py
@@ -105,23 +105,25 @@ from rest_framework_json_api import serializers
                         "type": "string",
                         "description": "The Azure application (client) ID for authentication in Azure AD.",
                     },
-                    "client_secret": {
-                        "type": "string",
-                        "description": "The client secret associated with the application (client) ID, providing "
-                        "secure access.",
-                    },
                     "tenant_id": {
                         "type": "string",
                         "description": "The Azure tenant ID, representing the directory where the application is "
                         "registered.",
                     },
+                    "client_secret": {
+                        "type": "string",
+                        "description": "The client secret associated with the application (client) ID, providing "
+                        "secure access.",
+                    },
                     "user": {
                         "type": "email",
                         "description": "User microsoft email address.",
+                        "deprecated": True,
                     },
                     "password": {
                         "type": "string",
                         "description": "User password.",
+                        "deprecated": True,
                     },
                 },
                 "required": [
@@ -132,6 +134,30 @@ from rest_framework_json_api import serializers
                     "password",
                 ],
             },
+            {
+                "type": "object",
+                "title": "M365 Certificate Credentials",
+                "properties": {
+                    "client_id": {
+                        "type": "string",
+                        "description": "The Azure application (client) ID for authentication in Azure AD.",
+                    },
+                    "tenant_id": {
+                        "type": "string",
+                        "description": "The Azure tenant ID, representing the directory where the application is "
+                        "registered.",
+                    },
+                    "certificate_content": {
+                        "type": "string",
+                        "description": "The certificate content in base64 format for certificate-based authentication.",
+                    },
+                },
+                "required": [
+                    "client_id",
+                    "tenant_id",
+                    "certificate_content",
+                ],
+            },
             {
                 "type": "object",
                 "title": "GCP Static Credentials",
@@ -213,6 +239,71 @@ from rest_framework_json_api import serializers
                 },
                 "required": ["github_app_id", "github_app_key"],
             },
+            {
+                "type": "object",
+                "title": "IaC Repository Credentials",
+                "properties": {
+                    "repository_url": {
+                        "type": "string",
+                        "description": "Repository URL to scan for IaC files.",
+                    },
+                    "access_token": {
+                        "type": "string",
+                        "description": "Optional access token for private repositories.",
+                    },
+                },
+                "required": ["repository_url"],
+            },
+            {
+                "type": "object",
+                "title": "Oracle Cloud Infrastructure (OCI) API Key Credentials",
+                "properties": {
+                    "user": {
+                        "type": "string",
+                        "description": "The OCID of the user to authenticate with.",
+                    },
+                    "fingerprint": {
+                        "type": "string",
+                        "description": "The fingerprint of the API signing key.",
+                    },
+                    "key_file": {
+                        "type": "string",
+                        "description": "The path to the private key file for API signing. Either key_file or key_content must be provided.",
+                    },
+                    "key_content": {
+                        "type": "string",
+                        "description": "The content of the private key for API signing (base64 encoded). Either key_file or key_content must be provided.",
+                    },
+                    "tenancy": {
+                        "type": "string",
+                        "description": "The OCID of the tenancy.",
+                    },
+                    "region": {
+                        "type": "string",
+                        "description": "The OCI region identifier (e.g., us-ashburn-1, us-phoenix-1).",
+                    },
+                    "pass_phrase": {
+                        "type": "string",
+                        "description": "The passphrase for the private key, if encrypted.",
+                    },
+                },
+                "required": ["user", "fingerprint", "tenancy", "region"],
+            },
+            {
+                "type": "object",
+                "title": "MongoDB Atlas API Key",
+                "properties": {
+                    "atlas_public_key": {
+                        "type": "string",
+                        "description": "MongoDB Atlas API public key.",
+                    },
+                    "atlas_private_key": {
+                        "type": "string",
+                        "description": "MongoDB Atlas API private key.",
+                    },
+                },
+                "required": ["atlas_public_key", "atlas_private_key"],
+            },
         ]
     }
 )
diff --git a/api/src/backend/api/v1/serializers.py b/api/src/backend/api/v1/serializers.py
index 30f942b04d..b2d95a2609 100644
--- a/api/src/backend/api/v1/serializers.py
+++ b/api/src/backend/api/v1/serializers.py
@@ -1,3 +1,4 @@
+import base64
 import json
 from datetime import datetime, timedelta, timezone
 
@@ -5,8 +6,10 @@ from django.conf import settings
 from django.contrib.auth import authenticate
 from django.contrib.auth.models import update_last_login
 from django.contrib.auth.password_validation import validate_password
+from django.db import IntegrityError
 from drf_spectacular.utils import extend_schema_field
 from jwt.exceptions import InvalidKeyError
+from rest_framework.reverse import reverse
 from rest_framework.validators import UniqueTogetherValidator
 from rest_framework_json_api import serializers
 from rest_framework_json_api.relations import SerializerMethodResourceRelatedField
@@ -15,6 +18,8 @@ from rest_framework_simplejwt.exceptions import TokenError
 from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
 from rest_framework_simplejwt.tokens import RefreshToken
 
+from api.db_router import MainRouter
+from api.exceptions import ConflictException
 from api.models import (
     Finding,
     Integration,
@@ -22,7 +27,11 @@ from api.models import (
     Invitation,
     InvitationRoleRelationship,
     LighthouseConfiguration,
+    LighthouseProviderConfiguration,
+    LighthouseProviderModels,
+    LighthouseTenantConfiguration,
     Membership,
+    MuteRule,
     Processor,
     Provider,
     ProviderGroup,
@@ -37,6 +46,8 @@ from api.models import (
     StateChoices,
     StatusChoices,
     Task,
+    TenantAPIKey,
+    ThreatScoreSnapshot,
     User,
     UserRoleRelationship,
 )
@@ -45,9 +56,18 @@ from api.v1.serializer_utils.integrations import (
     AWSCredentialSerializer,
     IntegrationConfigField,
     IntegrationCredentialField,
+    JiraConfigSerializer,
+    JiraCredentialSerializer,
     S3ConfigSerializer,
     SecurityHubConfigSerializer,
 )
+from api.v1.serializer_utils.lighthouse import (
+    BedrockCredentialsSerializer,
+    BedrockCredentialsUpdateSerializer,
+    LighthouseCredentialsField,
+    OpenAICompatibleCredentialsSerializer,
+    OpenAICredentialsSerializer,
+)
 from api.v1.serializer_utils.processors import ProcessorConfigField
 from api.v1.serializer_utils.providers import ProviderSecretField
 from prowler.lib.mutelist.mutelist import Mutelist
@@ -256,8 +276,15 @@ class UserSerializer(BaseSerializerV1):
     Serializer for the User model.
     """
 
-    memberships = serializers.ResourceRelatedField(many=True, read_only=True)
-    roles = serializers.ResourceRelatedField(many=True, read_only=True)
+    # We use SerializerMethodResourceRelatedField so includes (e.g. ?include=roles)
+    # respect RBAC and do not leak relationships of other users when the requester
+    # lacks manage_account. The visibility logic lives in get_roles/get_memberships.
+    memberships = SerializerMethodResourceRelatedField(
+        many=True, read_only=True, source="memberships", method_name="get_memberships"
+    )
+    roles = SerializerMethodResourceRelatedField(
+        many=True, read_only=True, source="roles", method_name="get_roles"
+    )
 
     class Meta:
         model = User
@@ -275,7 +302,50 @@ class UserSerializer(BaseSerializerV1):
         }
 
     included_serializers = {
-        "roles": "api.v1.serializers.RoleSerializer",
+        "roles": "api.v1.serializers.RoleIncludeSerializer",
+        "memberships": "api.v1.serializers.MembershipIncludeSerializer",
+    }
+
+    def _can_view_relationships(self, instance) -> bool:
+        """Allow self to view own relationships. Require manage_account to view others."""
+        role = self.context.get("role")
+        request = self.context.get("request")
+        is_self = bool(
+            request
+            and getattr(request, "user", None)
+            and getattr(instance, "id", None) == request.user.id
+        )
+        return is_self or (role and role.manage_account)
+
+    def get_roles(self, instance):
+        return (
+            instance.roles.all()
+            if self._can_view_relationships(instance)
+            else Role.objects.none()
+        )
+
+    def get_memberships(self, instance):
+        return (
+            instance.memberships.all()
+            if self._can_view_relationships(instance)
+            else Membership.objects.none()
+        )
+
+
+class UserIncludeSerializer(UserSerializer):
+    class Meta:
+        model = User
+        fields = [
+            "id",
+            "name",
+            "email",
+            "company_name",
+            "date_joined",
+            "roles",
+        ]
+
+    included_serializers = {
+        "roles": "api.v1.serializers.RoleIncludeSerializer",
     }
 
 
@@ -385,6 +455,34 @@ class UserRoleRelationshipSerializer(RLSSerializer, BaseWriteSerializer):
         roles = Role.objects.filter(id__in=role_ids)
         tenant_id = self.context.get("tenant_id")
 
+        # Safeguard: A tenant must always have at least one user with MANAGE_ACCOUNT.
+        # If the target roles do NOT include MANAGE_ACCOUNT, and the current user is
+        # the only one in the tenant with MANAGE_ACCOUNT, block the update.
+        target_includes_manage_account = roles.filter(manage_account=True).exists()
+        if not target_includes_manage_account:
+            # Check if any other user has MANAGE_ACCOUNT
+            other_users_have_manage_account = (
+                UserRoleRelationship.objects.filter(
+                    tenant_id=tenant_id, role__manage_account=True
+                )
+                .exclude(user_id=instance.id)
+                .exists()
+            )
+
+            # Check if the current user has MANAGE_ACCOUNT
+            instance_has_manage_account = instance.roles.filter(
+                tenant_id=tenant_id, manage_account=True
+            ).exists()
+
+            # If the current user is the last holder of MANAGE_ACCOUNT, prevent removal
+            if instance_has_manage_account and not other_users_have_manage_account:
+                raise serializers.ValidationError(
+                    {
+                        "roles": "At least one user in the tenant must retain MANAGE_ACCOUNT. "
+                        "Assign MANAGE_ACCOUNT to another user before removing it here."
+                    }
+                )
+
         instance.roles.clear()
         new_relationships = [
             UserRoleRelationship(user=instance, role=r, tenant_id=tenant_id)
@@ -499,6 +597,12 @@ class TenantSerializer(BaseSerializerV1):
         fields = ["id", "name", "memberships"]
 
 
+class TenantIncludeSerializer(BaseSerializerV1):
+    class Meta:
+        model = Tenant
+        fields = ["id", "name"]
+
+
 # Memberships
 
 
@@ -520,6 +624,29 @@ class MembershipSerializer(serializers.ModelSerializer):
         fields = ["id", "user", "tenant", "role", "date_joined"]
 
 
+class MembershipIncludeSerializer(serializers.ModelSerializer):
+    """
+    Include-oriented Membership serializer that enables including tenant objects with names
+    without altering the base MembershipSerializer behavior.
+    """
+
+    role = MemberRoleEnumSerializerField()
+    user = serializers.ResourceRelatedField(read_only=True)
+    tenant = SerializerMethodResourceRelatedField(read_only=True, source="tenant")
+
+    class Meta:
+        model = Membership
+        fields = ["id", "user", "tenant", "role", "date_joined"]
+
+    included_serializers = {"tenant": "api.v1.serializers.TenantIncludeSerializer"}
+
+    def get_tenant(self, instance):
+        try:
+            return Tenant.objects.using(MainRouter.admin_db).get(id=instance.tenant_id)
+        except Tenant.DoesNotExist:
+            return None
+
+
 # Provider Groups
 class ProviderGroupSerializer(RLSSerializer, BaseWriteSerializer):
     providers = serializers.ResourceRelatedField(
@@ -814,6 +941,17 @@ class ProviderCreateSerializer(RLSSerializer, BaseWriteSerializer):
             "uid",
             # "scanner_args"
         ]
+        extra_kwargs = {
+            "alias": {
+                "help_text": "Human readable name to identify the provider, e.g. 'Production AWS Account', 'Dev Environment'",
+            },
+            "provider": {
+                "help_text": "Type of provider to create.",
+            },
+            "uid": {
+                "help_text": "Unique identifier for the provider, set by the provider, e.g. AWS account ID, Azure subscription ID, GCP project ID, etc.",
+            },
+        }
 
 
 class ProviderUpdateSerializer(BaseWriteSerializer):
@@ -828,6 +966,11 @@ class ProviderUpdateSerializer(BaseWriteSerializer):
             "alias",
             # "scanner_args"
         ]
+        extra_kwargs = {
+            "alias": {
+                "help_text": "Human readable name to identify the provider, e.g. 'Production AWS Account', 'Dev Environment'",
+            }
+        }
 
 
 # Scans
@@ -1024,11 +1167,17 @@ class ResourceSerializer(RLSSerializer):
             "findings",
             "failed_findings_count",
             "url",
+            "metadata",
+            "details",
+            "partition",
         ]
         extra_kwargs = {
             "id": {"read_only": True},
             "inserted_at": {"read_only": True},
             "updated_at": {"read_only": True},
+            "metadata": {"read_only": True},
+            "details": {"read_only": True},
+            "partition": {"read_only": True},
         }
 
     included_serializers = {
@@ -1085,11 +1234,15 @@ class ResourceIncludeSerializer(RLSSerializer):
             "service",
             "type_",
             "tags",
+            "details",
+            "partition",
         ]
         extra_kwargs = {
             "id": {"read_only": True},
             "inserted_at": {"read_only": True},
             "updated_at": {"read_only": True},
+            "details": {"read_only": True},
+            "partition": {"read_only": True},
         }
 
     @extend_schema_field(
@@ -1220,10 +1373,16 @@ class BaseWriteProviderSecretSerializer(BaseWriteSerializer):
                 serializer = GCPProviderSecret(data=secret)
             elif provider_type == Provider.ProviderChoices.GITHUB.value:
                 serializer = GithubProviderSecret(data=secret)
+            elif provider_type == Provider.ProviderChoices.IAC.value:
+                serializer = IacProviderSecret(data=secret)
             elif provider_type == Provider.ProviderChoices.KUBERNETES.value:
                 serializer = KubernetesProviderSecret(data=secret)
             elif provider_type == Provider.ProviderChoices.M365.value:
                 serializer = M365ProviderSecret(data=secret)
+            elif provider_type == Provider.ProviderChoices.ORACLECLOUD.value:
+                serializer = OracleCloudProviderSecret(data=secret)
+            elif provider_type == Provider.ProviderChoices.MONGODBATLAS.value:
+                serializer = MongoDBAtlasProviderSecret(data=secret)
             else:
                 raise serializers.ValidationError(
                     {"provider": f"Provider type not supported {provider_type}"}
@@ -1267,10 +1426,38 @@ class AzureProviderSecret(serializers.Serializer):
 
 class M365ProviderSecret(serializers.Serializer):
     client_id = serializers.CharField()
-    client_secret = serializers.CharField()
+    client_secret = serializers.CharField(required=False)
     tenant_id = serializers.CharField()
     user = serializers.EmailField(required=False)
     password = serializers.CharField(required=False)
+    certificate_content = serializers.CharField(required=False)
+
+    def validate(self, attrs):
+        if attrs.get("client_secret") and attrs.get("certificate_content"):
+            raise serializers.ValidationError(
+                "You cannot provide both client_secret and certificate_content."
+            )
+        if not attrs.get("client_secret") and not attrs.get("certificate_content"):
+            raise serializers.ValidationError(
+                "You must provide either client_secret or certificate_content."
+            )
+        return super().validate(attrs)
+
+    def validate_certificate_content(self, certificate_content):
+        """Validate that M365 certificate content is valid base64 encoded data."""
+        if certificate_content:
+            try:
+                base64.b64decode(certificate_content, validate=True)
+            except Exception as e:
+                raise ValidationError(
+                    {
+                        "certificate_content": [
+                            f"The provided certificate content is not valid base64 encoded data: {str(e)}"
+                        ]
+                    },
+                    code="m365-certificate-content",
+                )
+        return certificate_content
 
     class Meta:
         resource_name = "provider-secrets"
@@ -1292,6 +1479,14 @@ class GCPServiceAccountProviderSecret(serializers.Serializer):
         resource_name = "provider-secrets"
 
 
+class MongoDBAtlasProviderSecret(serializers.Serializer):
+    atlas_public_key = serializers.CharField()
+    atlas_private_key = serializers.CharField()
+
+    class Meta:
+        resource_name = "provider-secrets"
+
+
 class KubernetesProviderSecret(serializers.Serializer):
     kubeconfig_content = serializers.CharField()
 
@@ -1309,6 +1504,27 @@ class GithubProviderSecret(serializers.Serializer):
         resource_name = "provider-secrets"
 
 
+class IacProviderSecret(serializers.Serializer):
+    repository_url = serializers.CharField()
+    access_token = serializers.CharField(required=False)
+
+    class Meta:
+        resource_name = "provider-secrets"
+
+
+class OracleCloudProviderSecret(serializers.Serializer):
+    user = serializers.CharField()
+    fingerprint = serializers.CharField()
+    key_file = serializers.CharField(required=False)
+    key_content = serializers.CharField(required=False)
+    tenancy = serializers.CharField()
+    region = serializers.CharField()
+    pass_phrase = serializers.CharField(required=False)
+
+    class Meta:
+        resource_name = "provider-secrets"
+
+
 class AWSRoleAssumptionProviderSecret(serializers.Serializer):
     role_arn = serializers.CharField()
     external_id = serializers.CharField()
@@ -1675,6 +1891,37 @@ class RoleUpdateSerializer(RoleSerializer):
 
         if "users" in validated_data:
             users = validated_data.pop("users")
+            # Prevent a user from removing their own role assignment via Role update
+            request = self.context.get("request")
+            if request and getattr(request, "user", None):
+                request_user = request.user
+                is_currently_assigned = instance.users.filter(
+                    id=request_user.id
+                ).exists()
+                will_be_assigned = any(u.id == request_user.id for u in users)
+                if is_currently_assigned and not will_be_assigned:
+                    raise serializers.ValidationError(
+                        {"users": "Users cannot remove their own role."}
+                    )
+
+            # Safeguard MANAGE_ACCOUNT coverage when updating users of this role
+            if instance.manage_account:
+                # Existing MANAGE_ACCOUNT assignments on other roles within the tenant
+                other_ma_exists = (
+                    UserRoleRelationship.objects.filter(
+                        tenant_id=tenant_id, role__manage_account=True
+                    )
+                    .exclude(role_id=instance.id)
+                    .exists()
+                )
+
+                if not other_ma_exists and len(users) == 0:
+                    raise serializers.ValidationError(
+                        {
+                            "users": "At least one user in the tenant must retain MANAGE_ACCOUNT. "
+                            "Assign this MANAGE_ACCOUNT role to at least one user or ensure another user has it."
+                        }
+                    )
             instance.users.clear()
             through_model_instances = [
                 UserRoleRelationship(
@@ -1689,6 +1936,37 @@ class RoleUpdateSerializer(RoleSerializer):
         return super().update(instance, validated_data)
 
 
+class RoleIncludeSerializer(RLSSerializer):
+    permission_state = serializers.SerializerMethodField()
+
+    def get_permission_state(self, obj) -> str:
+        return obj.permission_state
+
+    class Meta:
+        model = Role
+        fields = [
+            "id",
+            "name",
+            "manage_users",
+            "manage_account",
+            # Disable for the first release
+            # "manage_billing",
+            # /Disable for the first release
+            "manage_integrations",
+            "manage_providers",
+            "manage_scans",
+            "permission_state",
+            "unlimited_visibility",
+            "inserted_at",
+            "updated_at",
+        ]
+        extra_kwargs = {
+            "id": {"read_only": True},
+            "inserted_at": {"read_only": True},
+            "updated_at": {"read_only": True},
+        }
+
+
 class ProviderGroupResourceIdentifierSerializer(serializers.Serializer):
     resource_type = serializers.CharField(source="type")
     id = serializers.UUIDField()
@@ -1801,8 +2079,20 @@ class ComplianceOverviewDetailSerializer(serializers.Serializer):
         resource_name = "compliance-requirements-details"
 
 
+class ComplianceOverviewDetailThreatscoreSerializer(ComplianceOverviewDetailSerializer):
+    """
+    Serializer for detailed compliance requirement information for Threatscore.
+
+    Includes additional fields specific to the Threatscore framework.
+    """
+
+    passed_findings = serializers.IntegerField()
+    total_findings = serializers.IntegerField()
+
+
 class ComplianceOverviewAttributesSerializer(serializers.Serializer):
     id = serializers.CharField()
+    compliance_name = serializers.CharField()
     framework_description = serializers.CharField()
     name = serializers.CharField()
     framework = serializers.CharField()
@@ -1868,6 +2158,17 @@ class OverviewProviderSerializer(serializers.Serializer):
         }
 
 
+class OverviewProviderCountSerializer(serializers.Serializer):
+    id = serializers.CharField(source="provider")
+    count = serializers.IntegerField()
+
+    class JSONAPIMeta:
+        resource_name = "providers-count-overview"
+
+    def get_root_meta(self, _resource, _many):
+        return {"version": "v1"}
+
+
 class OverviewFindingSerializer(serializers.Serializer):
     id = serializers.CharField(default="n/a")
     new = serializers.IntegerField()
@@ -1952,18 +2253,33 @@ class ScheduleDailyCreateSerializer(serializers.Serializer):
 
 class BaseWriteIntegrationSerializer(BaseWriteSerializer):
     def validate(self, attrs):
+        integration_type = attrs.get("integration_type")
+
         if (
-            attrs.get("integration_type") == Integration.IntegrationChoices.AMAZON_S3
+            integration_type == Integration.IntegrationChoices.AMAZON_S3
             and Integration.objects.filter(
                 configuration=attrs.get("configuration")
             ).exists()
         ):
-            raise serializers.ValidationError(
-                {"configuration": "This integration already exists."}
+            raise ConflictException(
+                detail="This integration already exists.",
+                pointer="/data/attributes/configuration",
+            )
+
+        if (
+            integration_type == Integration.IntegrationChoices.JIRA
+            and Integration.objects.filter(
+                configuration__contains={
+                    "domain": attrs.get("configuration").get("domain")
+                }
+            ).exists()
+        ):
+            raise ConflictException(
+                detail="This integration already exists.",
+                pointer="/data/attributes/configuration",
             )
 
         # Check if any provider already has a SecurityHub integration
-        integration_type = attrs.get("integration_type")
         if hasattr(self, "instance") and self.instance and not integration_type:
             integration_type = self.instance.integration_type
 
@@ -1984,10 +2300,10 @@ class BaseWriteIntegrationSerializer(BaseWriteSerializer):
                     query = query.exclude(integration=self.instance)
 
                 if query.exists():
-                    raise serializers.ValidationError(
-                        {
-                            "providers": f"Provider {provider.id} already has a Security Hub integration. Only one Security Hub integration is allowed per provider."
-                        }
+                    raise ConflictException(
+                        detail=f"Provider {provider.id} already has a Security Hub integration. Only one "
+                        "Security Hub integration is allowed per provider.",
+                        pointer="/data/relationships/providers",
                     )
 
         return super().validate(attrs)
@@ -2018,6 +2334,30 @@ class BaseWriteIntegrationSerializer(BaseWriteSerializer):
                     )
             config_serializer = SecurityHubConfigSerializer
             credentials_serializers = [AWSCredentialSerializer]
+        elif integration_type == Integration.IntegrationChoices.JIRA:
+            if providers:
+                raise serializers.ValidationError(
+                    {
+                        "providers": "Relationship field is not accepted. This integration applies to all providers."
+                    }
+                )
+            if configuration:
+                raise serializers.ValidationError(
+                    {
+                        "configuration": "This integration does not support custom configuration."
+                    }
+                )
+            config_serializer = JiraConfigSerializer
+            # Create non-editable configuration for JIRA integration
+            default_jira_issue_types = ["Task"]
+            configuration.update(
+                {
+                    "projects": {},
+                    "issue_types": default_jira_issue_types,
+                    "domain": credentials.get("domain"),
+                }
+            )
+            credentials_serializers = [JiraCredentialSerializer]
         else:
             raise serializers.ValidationError(
                 {
@@ -2081,6 +2421,10 @@ class IntegrationSerializer(RLSSerializer):
                 for provider in representation["providers"]
                 if provider["id"] in allowed_provider_ids
             ]
+        if instance.integration_type == Integration.IntegrationChoices.JIRA:
+            representation["configuration"].update(
+                {"domain": instance.credentials.get("domain")}
+            )
         return representation
 
 
@@ -2122,9 +2466,7 @@ class IntegrationCreateSerializer(BaseWriteIntegrationSerializer):
             and integration_type == Integration.IntegrationChoices.AWS_SECURITY_HUB
         ):
             raise serializers.ValidationError(
-                {
-                    "providers": "At least one provider is required for the Security Hub integration."
-                }
+                {"providers": "At least one provider is required for this integration."}
             )
 
         self.validate_integration_data(
@@ -2183,7 +2525,10 @@ class IntegrationUpdateSerializer(BaseWriteIntegrationSerializer):
     def validate(self, attrs):
         integration_type = self.instance.integration_type
         providers = attrs.get("providers")
-        configuration = attrs.get("configuration") or self.instance.configuration
+        if integration_type != Integration.IntegrationChoices.JIRA:
+            configuration = attrs.get("configuration") or self.instance.configuration
+        else:
+            configuration = attrs.get("configuration", {})
         credentials = attrs.get("credentials") or self.instance.credentials
 
         self.validate_integration_data(
@@ -2213,6 +2558,53 @@ class IntegrationUpdateSerializer(BaseWriteIntegrationSerializer):
 
         return super().update(instance, validated_data)
 
+    def to_representation(self, instance):
+        representation = super().to_representation(instance)
+        # Ensure JIRA integrations show updated domain in configuration from credentials
+        if instance.integration_type == Integration.IntegrationChoices.JIRA:
+            representation["configuration"].update(
+                {"domain": instance.credentials.get("domain")}
+            )
+        return representation
+
+
+class IntegrationJiraDispatchSerializer(serializers.Serializer):
+    """
+    Serializer for dispatching findings to JIRA integration.
+    """
+
+    project_key = serializers.CharField(required=True)
+    issue_type = serializers.ChoiceField(required=True, choices=["Task"])
+
+    class JSONAPIMeta:
+        resource_name = "integrations-jira-dispatches"
+
+    def validate(self, attrs):
+        validated_attrs = super().validate(attrs)
+        integration_instance = Integration.objects.get(
+            id=self.context.get("integration_id")
+        )
+        if integration_instance.integration_type != Integration.IntegrationChoices.JIRA:
+            raise ValidationError(
+                {"integration_type": "The given integration is not a JIRA integration"}
+            )
+
+        if not integration_instance.enabled:
+            raise ValidationError(
+                {"integration": "The given integration is not enabled"}
+            )
+
+        project_key = attrs.get("project_key")
+        if project_key not in integration_instance.configuration.get("projects", {}):
+            raise ValidationError(
+                {
+                    "project_key": "The given project key is not available for this JIRA integration. Refresh the "
+                    "connection if this is an error."
+                }
+            )
+
+        return validated_attrs
+
 
 # Processors
 
@@ -2428,6 +2820,16 @@ class LighthouseConfigCreateSerializer(RLSSerializer, BaseWriteSerializer):
             "updated_at": {"read_only": True},
         }
 
+    def validate_temperature(self, value):
+        if not 0 <= value <= 1:
+            raise ValidationError("Temperature must be between 0 and 1.")
+        return value
+
+    def validate_max_tokens(self, value):
+        if not 500 <= value <= 5000:
+            raise ValidationError("Max tokens must be between 500 and 5000.")
+        return value
+
     def validate(self, attrs):
         tenant_id = self.context.get("request").tenant_id
         if LighthouseConfiguration.objects.filter(tenant_id=tenant_id).exists():
@@ -2436,6 +2838,11 @@ class LighthouseConfigCreateSerializer(RLSSerializer, BaseWriteSerializer):
                     "tenant_id": "Lighthouse configuration already exists for this tenant."
                 }
             )
+        api_key = attrs.get("api_key")
+        if api_key is not None:
+            OpenAICredentialsSerializer(data={"api_key": api_key}).is_valid(
+                raise_exception=True
+            )
         return super().validate(attrs)
 
     def create(self, validated_data):
@@ -2480,6 +2887,24 @@ class LighthouseConfigUpdateSerializer(BaseWriteSerializer):
             "max_tokens": {"required": False},
         }
 
+    def validate_temperature(self, value):
+        if not 0 <= value <= 1:
+            raise ValidationError("Temperature must be between 0 and 1.")
+        return value
+
+    def validate_max_tokens(self, value):
+        if not 500 <= value <= 5000:
+            raise ValidationError("Max tokens must be between 500 and 5000.")
+        return value
+
+    def validate(self, attrs):
+        api_key = attrs.get("api_key", None)
+        if api_key is not None:
+            OpenAICredentialsSerializer(data={"api_key": api_key}).is_valid(
+                raise_exception=True
+            )
+        return super().validate(attrs)
+
     def update(self, instance, validated_data):
         api_key = validated_data.pop("api_key", None)
         instance = super().update(instance, validated_data)
@@ -2487,3 +2912,789 @@ class LighthouseConfigUpdateSerializer(BaseWriteSerializer):
             instance.api_key_decoded = api_key
             instance.save()
         return instance
+
+
+# API Keys
+
+
+class TenantApiKeySerializer(RLSSerializer):
+    """
+    Serializer for the TenantApiKey model.
+    """
+
+    # Map database field names to API field names for consistency
+    expires_at = serializers.DateTimeField(source="expiry_date", read_only=True)
+    inserted_at = serializers.DateTimeField(source="created", read_only=True)
+
+    class Meta:
+        model = TenantAPIKey
+        fields = [
+            "id",
+            "name",
+            "prefix",
+            "expires_at",
+            "revoked",
+            "inserted_at",
+            "last_used_at",
+            "entity",
+        ]
+
+    included_serializers = {
+        "entity": "api.v1.serializers.UserIncludeSerializer",
+    }
+
+
+class TenantApiKeyCreateSerializer(RLSSerializer, BaseWriteSerializer):
+    """Serializer for creating new API keys."""
+
+    # Map database field names to API field names for consistency
+    expires_at = serializers.DateTimeField(source="expiry_date", required=False)
+    inserted_at = serializers.DateTimeField(source="created", read_only=True)
+    api_key = serializers.SerializerMethodField()
+
+    class Meta:
+        model = TenantAPIKey
+        fields = [
+            "id",
+            "name",
+            "prefix",
+            "expires_at",
+            "revoked",
+            "entity",
+            "inserted_at",
+            "last_used_at",
+            "api_key",
+        ]
+        extra_kwargs = {
+            "id": {"read_only": True},
+            "prefix": {"read_only": True},
+            "revoked": {"read_only": True},
+            "entity": {"read_only": True},
+            "inserted_at": {"read_only": True},
+            "last_used_at": {"read_only": True},
+            "api_key": {"read_only": True},
+        }
+
+    def validate_name(self, value):
+        """Validate that the name is unique within the tenant."""
+        tenant_id = self.context.get("tenant_id")
+        if TenantAPIKey.objects.filter(tenant_id=tenant_id, name=value).exists():
+            raise ValidationError("An API key with this name already exists.")
+        return value
+
+    def get_api_key(self, obj):
+        """Return the raw API key if it was stored during creation."""
+        return getattr(obj, "_raw_api_key", None)
+
+    def create(self, validated_data):
+        instance, raw_api_key = TenantAPIKey.objects.create_api_key(
+            **validated_data,
+            tenant_id=self.context.get("tenant_id"),
+            entity=self.context.get("request").user,
+        )
+        # Store the raw API key temporarily on the instance for the serializer
+        instance._raw_api_key = raw_api_key
+        return instance
+
+
+class TenantApiKeyUpdateSerializer(RLSSerializer, BaseWriteSerializer):
+    """Serializer for updating API keys - only allows changing the name."""
+
+    # Map database field names to API field names for consistency
+    expires_at = serializers.DateTimeField(source="expiry_date", read_only=True)
+    inserted_at = serializers.DateTimeField(source="created", read_only=True)
+
+    class Meta:
+        model = TenantAPIKey
+        fields = [
+            "id",
+            "name",
+            "prefix",
+            "expires_at",
+            "entity",
+            "inserted_at",
+            "last_used_at",
+        ]
+        extra_kwargs = {
+            "id": {"read_only": True},
+            "prefix": {"read_only": True},
+            "entity": {"read_only": True},
+            "expires_at": {"read_only": True},
+            "inserted_at": {"read_only": True},
+            "last_used_at": {"read_only": True},
+        }
+
+    def validate_name(self, value):
+        """Validate that the name is unique within the tenant, excluding current instance."""
+        tenant_id = self.context.get("tenant_id")
+        if (
+            TenantAPIKey.objects.filter(tenant_id=tenant_id, name=value)
+            .exclude(id=self.instance.id)
+            .exists()
+        ):
+            raise ValidationError("An API key with this name already exists.")
+        return value
+
+
+# Lighthouse: Provider configurations
+
+
+class LighthouseProviderConfigSerializer(RLSSerializer):
+    """
+    Read serializer for LighthouseProviderConfiguration.
+    """
+
+    # Decrypted credentials are only returned in to_representation when requested
+    credentials = serializers.JSONField(required=False, read_only=True)
+
+    class Meta:
+        model = LighthouseProviderConfiguration
+        fields = [
+            "id",
+            "inserted_at",
+            "updated_at",
+            "provider_type",
+            "base_url",
+            "is_active",
+            "credentials",
+            "url",
+        ]
+        extra_kwargs = {
+            "id": {"read_only": True},
+            "inserted_at": {"read_only": True},
+            "updated_at": {"read_only": True},
+            "is_active": {"read_only": True},
+            "url": {"read_only": True, "view_name": "lighthouse-providers-detail"},
+        }
+
+    class JSONAPIMeta:
+        resource_name = "lighthouse-providers"
+
+    def to_representation(self, instance):
+        data = super().to_representation(instance)
+        # Support JSON:API fields filter: fields[lighthouse-providers]=credentials,base_url
+        fields_param = self.context.get("request", None) and self.context[
+            "request"
+        ].query_params.get("fields[lighthouse-providers]", "")
+
+        creds = instance.credentials_decoded
+
+        requested_fields = (
+            [f.strip() for f in fields_param.split(",")] if fields_param else []
+        )
+
+        if "credentials" in requested_fields:
+            # Return full decrypted credentials JSON
+            data["credentials"] = creds
+        else:
+            # Return masked credentials by default
+            def mask_value(value):
+                if isinstance(value, str):
+                    return "*" * len(value)
+                if isinstance(value, dict):
+                    return {k: mask_value(v) for k, v in value.items()}
+                if isinstance(value, list):
+                    return [mask_value(v) for v in value]
+                return value
+
+            # Always return masked credentials, even if creds is None
+            if creds is not None:
+                data["credentials"] = mask_value(creds)
+            else:
+                # If credentials_decoded returns None, return None for credentials field
+                data["credentials"] = None
+
+        return data
+
+
+class LighthouseProviderConfigCreateSerializer(RLSSerializer, BaseWriteSerializer):
+    """
+    Create serializer for LighthouseProviderConfiguration.
+    Accepts credentials as JSON; stored encrypted via credentials_decoded.
+    """
+
+    credentials = LighthouseCredentialsField(write_only=True, required=True)
+    base_url = serializers.URLField(
+        required=False,
+        allow_null=True,
+        help_text="Base URL for the LLM provider API. Required for 'openai_compatible' provider type.",
+    )
+
+    class Meta:
+        model = LighthouseProviderConfiguration
+        fields = [
+            "provider_type",
+            "base_url",
+            "credentials",
+            "is_active",
+        ]
+        extra_kwargs = {
+            "is_active": {"required": False},
+            "provider_type": {
+                "help_text": "LLM provider type. Determines which credential format to use. "
+                "See 'credentials' field documentation for provider-specific requirements."
+            },
+        }
+
+    def create(self, validated_data):
+        credentials = validated_data.pop("credentials")
+
+        instance = LighthouseProviderConfiguration(**validated_data)
+        instance.tenant_id = self.context.get("tenant_id")
+        instance.credentials_decoded = credentials
+
+        try:
+            instance.save()
+            return instance
+        except IntegrityError:
+            raise ValidationError(
+                {
+                    "provider_type": "Configuration for this provider already exists for the tenant."
+                }
+            )
+
+    def validate(self, attrs):
+        provider_type = attrs.get("provider_type")
+        credentials = attrs.get("credentials") or {}
+        base_url = attrs.get("base_url")
+
+        if provider_type == LighthouseProviderConfiguration.LLMProviderChoices.OPENAI:
+            try:
+                OpenAICredentialsSerializer(data=credentials).is_valid(
+                    raise_exception=True
+                )
+            except ValidationError as e:
+                details = e.detail.copy()
+                for key, value in details.items():
+                    e.detail[f"credentials/{key}"] = value
+                    del e.detail[key]
+                raise e
+        elif (
+            provider_type == LighthouseProviderConfiguration.LLMProviderChoices.BEDROCK
+        ):
+            try:
+                BedrockCredentialsSerializer(data=credentials).is_valid(
+                    raise_exception=True
+                )
+            except ValidationError as e:
+                details = e.detail.copy()
+                for key, value in details.items():
+                    e.detail[f"credentials/{key}"] = value
+                    del e.detail[key]
+                raise e
+        elif (
+            provider_type
+            == LighthouseProviderConfiguration.LLMProviderChoices.OPENAI_COMPATIBLE
+        ):
+            if not base_url:
+                raise ValidationError({"base_url": "Base URL is required."})
+            try:
+                OpenAICompatibleCredentialsSerializer(data=credentials).is_valid(
+                    raise_exception=True
+                )
+            except ValidationError as e:
+                details = e.detail.copy()
+                for key, value in details.items():
+                    e.detail[f"credentials/{key}"] = value
+                    del e.detail[key]
+                raise e
+
+        return super().validate(attrs)
+
+
+class LighthouseProviderConfigUpdateSerializer(BaseWriteSerializer):
+    """
+    Update serializer for LighthouseProviderConfiguration.
+    """
+
+    credentials = LighthouseCredentialsField(write_only=True, required=False)
+    base_url = serializers.URLField(
+        required=False,
+        allow_null=True,
+        help_text="Base URL for the LLM provider API. Required for 'openai_compatible' provider type.",
+    )
+
+    class Meta:
+        model = LighthouseProviderConfiguration
+        fields = [
+            "id",
+            "provider_type",
+            "base_url",
+            "credentials",
+            "is_active",
+        ]
+        extra_kwargs = {
+            "id": {"read_only": True},
+            "provider_type": {"read_only": True},
+            "is_active": {"required": False},
+        }
+
+    def update(self, instance, validated_data):
+        credentials = validated_data.pop("credentials", None)
+
+        for attr, value in validated_data.items():
+            setattr(instance, attr, value)
+
+        if credentials is not None:
+            # Merge partial credentials with existing ones
+            # New values overwrite existing ones, but unspecified fields are preserved
+            existing_credentials = instance.credentials_decoded or {}
+            merged_credentials = {**existing_credentials, **credentials}
+            instance.credentials_decoded = merged_credentials
+
+        instance.save()
+        return instance
+
+    def validate(self, attrs):
+        provider_type = getattr(self.instance, "provider_type", None)
+        credentials = attrs.get("credentials", None)
+        base_url = attrs.get("base_url", None)
+
+        if (
+            credentials is not None
+            and provider_type
+            == LighthouseProviderConfiguration.LLMProviderChoices.OPENAI
+        ):
+            try:
+                OpenAICredentialsSerializer(data=credentials).is_valid(
+                    raise_exception=True
+                )
+            except ValidationError as e:
+                details = e.detail.copy()
+                for key, value in details.items():
+                    e.detail[f"credentials/{key}"] = value
+                    del e.detail[key]
+                raise e
+        elif (
+            credentials is not None
+            and provider_type
+            == LighthouseProviderConfiguration.LLMProviderChoices.BEDROCK
+        ):
+            try:
+                BedrockCredentialsUpdateSerializer(data=credentials).is_valid(
+                    raise_exception=True
+                )
+            except ValidationError as e:
+                details = e.detail.copy()
+                for key, value in details.items():
+                    e.detail[f"credentials/{key}"] = value
+                    del e.detail[key]
+                raise e
+        elif (
+            credentials is not None
+            and provider_type
+            == LighthouseProviderConfiguration.LLMProviderChoices.OPENAI_COMPATIBLE
+        ):
+            if base_url is None:
+                pass
+            elif not base_url:
+                raise ValidationError({"base_url": "Base URL cannot be empty."})
+            try:
+                OpenAICompatibleCredentialsSerializer(data=credentials).is_valid(
+                    raise_exception=True
+                )
+            except ValidationError as e:
+                details = e.detail.copy()
+                for key, value in details.items():
+                    e.detail[f"credentials/{key}"] = value
+                    del e.detail[key]
+                raise e
+
+        return super().validate(attrs)
+
+
+# Lighthouse: Tenant configuration
+
+
+class LighthouseTenantConfigSerializer(RLSSerializer):
+    """
+    Read serializer for LighthouseTenantConfiguration.
+    """
+
+    # Build singleton URL without pk
+    url = serializers.SerializerMethodField()
+
+    def get_url(self, obj):
+        request = self.context.get("request")
+        return reverse("lighthouse-configurations", request=request)
+
+    class Meta:
+        model = LighthouseTenantConfiguration
+        fields = [
+            "id",
+            "inserted_at",
+            "updated_at",
+            "business_context",
+            "default_provider",
+            "default_models",
+            "url",
+        ]
+        extra_kwargs = {
+            "id": {"read_only": True},
+            "inserted_at": {"read_only": True},
+            "updated_at": {"read_only": True},
+            "url": {"read_only": True},
+        }
+
+
+class LighthouseTenantConfigUpdateSerializer(BaseWriteSerializer):
+    class Meta:
+        model = LighthouseTenantConfiguration
+        fields = [
+            "id",
+            "business_context",
+            "default_provider",
+            "default_models",
+        ]
+        extra_kwargs = {
+            "id": {"read_only": True},
+        }
+
+    def validate(self, attrs):
+        request = self.context.get("request")
+        tenant_id = self.context.get("tenant_id") or (
+            getattr(request, "tenant_id", None) if request else None
+        )
+
+        default_provider = attrs.get(
+            "default_provider", getattr(self.instance, "default_provider", "")
+        )
+        default_models = attrs.get(
+            "default_models", getattr(self.instance, "default_models", {})
+        )
+
+        if default_provider:
+            supported = set(LighthouseProviderConfiguration.LLMProviderChoices.values)
+            if default_provider not in supported:
+                raise ValidationError(
+                    {"default_provider": f"Unsupported provider '{default_provider}'."}
+                )
+            if not LighthouseProviderConfiguration.objects.filter(
+                tenant_id=tenant_id, provider_type=default_provider, is_active=True
+            ).exists():
+                raise ValidationError(
+                    {
+                        "default_provider": f"No active configuration found for '{default_provider}'."
+                    }
+                )
+
+        if default_models is not None and not isinstance(default_models, dict):
+            raise ValidationError(
+                {"default_models": "Must be an object mapping provider -> model_id."}
+            )
+
+        for provider_type, model_id in (default_models or {}).items():
+            provider_cfg = LighthouseProviderConfiguration.objects.filter(
+                tenant_id=tenant_id, provider_type=provider_type, is_active=True
+            ).first()
+            if not provider_cfg:
+                raise ValidationError(
+                    {
+                        "default_models": f"No active configuration for provider '{provider_type}'."
+                    }
+                )
+            if not LighthouseProviderModels.objects.filter(
+                tenant_id=tenant_id,
+                provider_configuration=provider_cfg,
+                model_id=model_id,
+            ).exists():
+                raise ValidationError(
+                    {
+                        "default_models": f"Invalid model '{model_id}' for provider '{provider_type}'."
+                    }
+                )
+
+        return super().validate(attrs)
+
+
+# Lighthouse: Provider models
+
+
+class LighthouseProviderModelsSerializer(RLSSerializer):
+    """
+    Read serializer for LighthouseProviderModels.
+    """
+
+    provider_configuration = serializers.ResourceRelatedField(read_only=True)
+
+    class Meta:
+        model = LighthouseProviderModels
+        fields = [
+            "id",
+            "inserted_at",
+            "updated_at",
+            "provider_configuration",
+            "model_id",
+            "model_name",
+            "default_parameters",
+            "url",
+        ]
+        extra_kwargs = {
+            "id": {"read_only": True},
+            "inserted_at": {"read_only": True},
+            "updated_at": {"read_only": True},
+            "url": {"read_only": True, "view_name": "lighthouse-models-detail"},
+        }
+
+
+class LighthouseProviderModelsCreateSerializer(RLSSerializer, BaseWriteSerializer):
+    provider_configuration = serializers.ResourceRelatedField(
+        queryset=LighthouseProviderConfiguration.objects.all()
+    )
+
+    class Meta:
+        model = LighthouseProviderModels
+        fields = [
+            "provider_configuration",
+            "model_id",
+            "default_parameters",
+        ]
+        extra_kwargs = {
+            "default_parameters": {"required": False},
+        }
+
+
+class LighthouseProviderModelsUpdateSerializer(BaseWriteSerializer):
+    class Meta:
+        model = LighthouseProviderModels
+        fields = [
+            "id",
+            "default_parameters",
+        ]
+        extra_kwargs = {
+            "id": {"read_only": True},
+        }
+
+
+# Mute Rules
+
+
+class MuteRuleSerializer(RLSSerializer):
+    """
+    Serializer for reading MuteRule instances.
+    """
+
+    finding_uids = serializers.ListField(
+        child=serializers.CharField(),
+        read_only=True,
+        help_text="List of finding UIDs that are muted by this rule",
+    )
+
+    class Meta:
+        model = MuteRule
+        fields = [
+            "id",
+            "inserted_at",
+            "updated_at",
+            "name",
+            "reason",
+            "enabled",
+            "created_by",
+            "finding_uids",
+        ]
+
+    included_serializers = {
+        "created_by": "api.v1.serializers.UserIncludeSerializer",
+    }
+
+
+class MuteRuleCreateSerializer(RLSSerializer, BaseWriteSerializer):
+    """
+    Serializer for creating new MuteRule instances.
+
+    Accepts finding_ids in the request, converts them to UIDs, and stores in finding_uids.
+    """
+
+    finding_ids = serializers.ListField(
+        child=serializers.UUIDField(),
+        write_only=True,
+        required=True,
+        help_text="List of Finding IDs to mute (will be converted to UIDs)",
+    )
+    finding_uids = serializers.ListField(
+        child=serializers.CharField(),
+        read_only=True,
+        help_text="List of finding UIDs that are muted by this rule",
+    )
+
+    class Meta:
+        model = MuteRule
+        fields = [
+            "id",
+            "inserted_at",
+            "updated_at",
+            "name",
+            "reason",
+            "enabled",
+            "created_by",
+            "finding_ids",
+            "finding_uids",
+        ]
+        extra_kwargs = {
+            "id": {"read_only": True},
+            "inserted_at": {"read_only": True},
+            "updated_at": {"read_only": True},
+            "enabled": {"read_only": True},
+            "created_by": {"read_only": True},
+        }
+
+    def validate_name(self, value):
+        """Validate that the name is unique within the tenant."""
+        tenant_id = self.context.get("tenant_id")
+        if MuteRule.objects.filter(tenant_id=tenant_id, name=value).exists():
+            raise ValidationError("A mute rule with this name already exists.")
+        return value
+
+    def validate_finding_ids(self, value):
+        """Validate that all finding IDs exist and belong to the tenant."""
+        if not value:
+            raise ValidationError("At least one finding_id must be provided.")
+
+        tenant_id = self.context.get("tenant_id")
+
+        # Check that all findings exist and belong to this tenant
+        findings = Finding.all_objects.filter(tenant_id=tenant_id, id__in=value)
+        found_ids = set(findings.values_list("id", flat=True))
+        provided_ids = set(value)
+
+        missing_ids = provided_ids - found_ids
+        if missing_ids:
+            raise ValidationError(
+                f"The following finding IDs do not exist or do not belong to your tenant: {missing_ids}"
+            )
+
+        return value
+
+    def validate(self, data):
+        """Validate the entire mute rule, including overlap detection."""
+        data = super().validate(data)
+
+        tenant_id = self.context.get("tenant_id")
+        finding_ids = data.get("finding_ids", [])
+
+        if not finding_ids:
+            return data
+
+        # Convert finding IDs to UIDs (deduplicate in case multiple findings have same UID)
+        findings = Finding.all_objects.filter(id__in=finding_ids, tenant_id=tenant_id)
+        finding_uids = list(set(findings.values_list("uid", flat=True)))
+
+        # Check for overlaps with existing enabled rules
+        existing_rules = MuteRule.objects.filter(tenant_id=tenant_id, enabled=True)
+
+        for rule in existing_rules:
+            overlap = set(finding_uids) & set(rule.finding_uids)
+            if overlap:
+                raise ConflictException(
+                    detail=f"The following finding UIDs are already muted by rule '{rule.name}': {overlap}"
+                )
+
+        # Store finding_uids in validated_data for create
+        data["finding_uids"] = finding_uids
+
+        return data
+
+    def create(self, validated_data):
+        """Create a new mute rule and set created_by."""
+        # Remove finding_ids from validated_data (we've already converted to finding_uids)
+        validated_data.pop("finding_ids", None)
+
+        # Set created_by to the current user
+        request = self.context.get("request")
+        if request and hasattr(request, "user"):
+            validated_data["created_by"] = request.user
+
+        return super().create(validated_data)
+
+
+class MuteRuleUpdateSerializer(BaseWriteSerializer):
+    """
+    Serializer for updating MuteRule instances.
+    """
+
+    class Meta:
+        model = MuteRule
+        fields = [
+            "id",
+            "name",
+            "reason",
+            "enabled",
+        ]
+        extra_kwargs = {
+            "id": {"read_only": True},
+            "name": {"required": False},
+            "reason": {"required": False},
+            "enabled": {"required": False},
+        }
+
+    def validate_name(self, value):
+        """Validate that the name is unique within the tenant, excluding current instance."""
+        tenant_id = self.context.get("tenant_id")
+        if (
+            MuteRule.objects.filter(tenant_id=tenant_id, name=value)
+            .exclude(id=self.instance.id)
+            .exists()
+        ):
+            raise ValidationError("A mute rule with this name already exists.")
+        return value
+
+
+# ThreatScore Snapshots
+
+
+class ThreatScoreSnapshotSerializer(RLSSerializer):
+    """
+    Serializer for ThreatScore snapshots.
+    Read-only serializer for retrieving historical ThreatScore metrics.
+    """
+
+    id = serializers.SerializerMethodField()
+
+    class Meta:
+        model = ThreatScoreSnapshot
+        fields = [
+            "id",
+            "inserted_at",
+            "scan",
+            "provider",
+            "compliance_id",
+            "overall_score",
+            "score_delta",
+            "section_scores",
+            "critical_requirements",
+            "total_requirements",
+            "passed_requirements",
+            "failed_requirements",
+            "manual_requirements",
+            "total_findings",
+            "passed_findings",
+            "failed_findings",
+        ]
+        extra_kwargs = {
+            "id": {"read_only": True},
+            "inserted_at": {"read_only": True},
+            "scan": {"read_only": True},
+            "provider": {"read_only": True},
+            "compliance_id": {"read_only": True},
+            "overall_score": {"read_only": True},
+            "score_delta": {"read_only": True},
+            "section_scores": {"read_only": True},
+            "critical_requirements": {"read_only": True},
+            "total_requirements": {"read_only": True},
+            "passed_requirements": {"read_only": True},
+            "failed_requirements": {"read_only": True},
+            "manual_requirements": {"read_only": True},
+            "total_findings": {"read_only": True},
+            "passed_findings": {"read_only": True},
+            "failed_findings": {"read_only": True},
+        }
+
+    included_serializers = {
+        "scan": "api.v1.serializers.ScanIncludeSerializer",
+        "provider": "api.v1.serializers.ProviderIncludeSerializer",
+    }
+
+    def get_id(self, obj):
+        if getattr(obj, "_aggregated", False):
+            return "n/a"
+        return str(obj.id)
diff --git a/api/src/backend/api/v1/urls.py b/api/src/backend/api/v1/urls.py
index 8ee4458fc1..d879d1476b 100644
--- a/api/src/backend/api/v1/urls.py
+++ b/api/src/backend/api/v1/urls.py
@@ -12,11 +12,16 @@ from api.v1.views import (
     FindingViewSet,
     GithubSocialLoginView,
     GoogleSocialLoginView,
+    IntegrationJiraViewSet,
     IntegrationViewSet,
     InvitationAcceptViewSet,
     InvitationViewSet,
     LighthouseConfigViewSet,
+    LighthouseProviderConfigViewSet,
+    LighthouseProviderModelsViewSet,
+    LighthouseTenantConfigViewSet,
     MembershipViewSet,
+    MuteRuleViewSet,
     OverviewViewSet,
     ProcessorViewSet,
     ProviderGroupProvidersRelationshipView,
@@ -33,6 +38,7 @@ from api.v1.views import (
     ScheduleViewSet,
     SchemaView,
     TaskViewSet,
+    TenantApiKeyViewSet,
     TenantFinishACSView,
     TenantMembersViewSet,
     TenantViewSet,
@@ -64,6 +70,18 @@ router.register(
     LighthouseConfigViewSet,
     basename="lighthouseconfiguration",
 )
+router.register(r"api-keys", TenantApiKeyViewSet, basename="api-key")
+router.register(
+    r"lighthouse/providers",
+    LighthouseProviderConfigViewSet,
+    basename="lighthouse-providers",
+)
+router.register(
+    r"lighthouse/models",
+    LighthouseProviderModelsViewSet,
+    basename="lighthouse-models",
+)
+router.register(r"mute-rules", MuteRuleViewSet, basename="mute-rule")
 
 tenants_router = routers.NestedSimpleRouter(router, r"tenants", lookup="tenant")
 tenants_router.register(
@@ -73,6 +91,13 @@ tenants_router.register(
 users_router = routers.NestedSimpleRouter(router, r"users", lookup="user")
 users_router.register(r"memberships", MembershipViewSet, basename="user-membership")
 
+integrations_router = routers.NestedSimpleRouter(
+    router, r"integrations", lookup="integration"
+)
+integrations_router.register(
+    r"jira", IntegrationJiraViewSet, basename="integration-jira"
+)
+
 urlpatterns = [
     path("tokens", CustomTokenObtainView.as_view(), name="token-obtain"),
     path("tokens/refresh", CustomTokenRefreshView.as_view(), name="token-refresh"),
@@ -127,6 +152,13 @@ urlpatterns = [
         ),
         name="provider_group-providers-relationship",
     ),
+    path(
+        "lighthouse/configuration",
+        LighthouseTenantConfigViewSet.as_view(
+            {"get": "list", "patch": "partial_update"}
+        ),
+        name="lighthouse-configurations",
+    ),
     # API endpoint to start SAML SSO flow
     path(
         "auth/saml/initiate/", SAMLInitiateAPIView.as_view(), name="api_saml_initiate"
@@ -162,6 +194,7 @@ urlpatterns = [
     path("", include(router.urls)),
     path("", include(tenants_router.urls)),
     path("", include(users_router.urls)),
+    path("", include(integrations_router.urls)),
     path("schema", SchemaView.as_view(), name="schema"),
     path("docs", SpectacularRedocView.as_view(url_name="schema"), name="docs"),
 ]
diff --git a/api/src/backend/api/v1/views.py b/api/src/backend/api/v1/views.py
index 28cbc3ab5f..700550e4e4 100644
--- a/api/src/backend/api/v1/views.py
+++ b/api/src/backend/api/v1/views.py
@@ -1,7 +1,12 @@
+import fnmatch
 import glob
+import json
 import logging
 import os
+from collections import defaultdict
+from copy import deepcopy
 from datetime import datetime, timedelta, timezone
+from decimal import ROUND_HALF_UP, Decimal, InvalidOperation
 from urllib.parse import urljoin
 
 import sentry_sdk
@@ -22,9 +27,23 @@ from django.conf import settings as django_settings
 from django.contrib.postgres.aggregates import ArrayAgg
 from django.contrib.postgres.search import SearchQuery
 from django.db import transaction
-from django.db.models import Count, F, Prefetch, Q, Subquery, Sum
+from django.db.models import (
+    Case,
+    Count,
+    DecimalField,
+    ExpressionWrapper,
+    F,
+    IntegerField,
+    Max,
+    Prefetch,
+    Q,
+    Subquery,
+    Sum,
+    Value,
+    When,
+)
 from django.db.models.functions import Coalesce
-from django.http import HttpResponse
+from django.http import HttpResponse, QueryDict
 from django.shortcuts import redirect
 from django.urls import reverse
 from django.utils.dateparse import parse_date
@@ -56,13 +75,18 @@ from rest_framework_simplejwt.exceptions import InvalidToken, TokenError
 from tasks.beat import schedule_provider_scan
 from tasks.jobs.export import get_s3_client
 from tasks.tasks import (
+    backfill_compliance_summaries_task,
     backfill_scan_resource_summaries_task,
     check_integration_connection_task,
     check_lighthouse_connection_task,
+    check_lighthouse_provider_connection_task,
     check_provider_connection_task,
     delete_provider_task,
     delete_tenant_task,
+    jira_integration_task,
+    mute_historical_findings_task,
     perform_scan_task,
+    refresh_lighthouse_provider_models_task,
 )
 
 from api.base_views import BaseRLSViewSet, BaseTenantViewset, BaseUserViewset
@@ -75,12 +99,17 @@ from api.db_utils import rls_transaction
 from api.exceptions import TaskFailedException
 from api.filters import (
     ComplianceOverviewFilter,
+    CustomDjangoFilterBackend,
     FindingFilter,
     IntegrationFilter,
+    IntegrationJiraFindingsFilter,
     InvitationFilter,
     LatestFindingFilter,
     LatestResourceFilter,
+    LighthouseProviderConfigFilter,
+    LighthouseProviderModelsFilter,
     MembershipFilter,
+    MuteRuleFilter,
     ProcessorFilter,
     ProviderFilter,
     ProviderGroupFilter,
@@ -89,18 +118,25 @@ from api.filters import (
     RoleFilter,
     ScanFilter,
     ScanSummaryFilter,
-    ServiceOverviewFilter,
+    ScanSummarySeverityFilter,
     TaskFilter,
+    TenantApiKeyFilter,
     TenantFilter,
+    ThreatScoreSnapshotFilter,
     UserFilter,
 )
 from api.models import (
+    ComplianceOverviewSummary,
     ComplianceRequirementOverview,
     Finding,
     Integration,
     Invitation,
     LighthouseConfiguration,
+    LighthouseProviderConfiguration,
+    LighthouseProviderModels,
+    LighthouseTenantConfiguration,
     Membership,
+    MuteRule,
     Processor,
     Provider,
     ProviderGroup,
@@ -120,6 +156,8 @@ from api.models import (
     SeverityChoices,
     StateChoices,
     Task,
+    TenantAPIKey,
+    ThreatScoreSnapshot,
     User,
     UserRoleRelationship,
 )
@@ -132,16 +170,18 @@ from api.utils import (
     validate_invitation,
 )
 from api.uuid_utils import datetime_to_uuid7, uuid7_start
-from api.v1.mixins import PaginateByPkMixin, TaskManagementMixin
+from api.v1.mixins import DisablePaginationMixin, PaginateByPkMixin, TaskManagementMixin
 from api.v1.serializers import (
     ComplianceOverviewAttributesSerializer,
     ComplianceOverviewDetailSerializer,
+    ComplianceOverviewDetailThreatscoreSerializer,
     ComplianceOverviewMetadataSerializer,
     ComplianceOverviewSerializer,
     FindingDynamicFilterSerializer,
     FindingMetadataSerializer,
     FindingSerializer,
     IntegrationCreateSerializer,
+    IntegrationJiraDispatchSerializer,
     IntegrationSerializer,
     IntegrationUpdateSerializer,
     InvitationAcceptSerializer,
@@ -151,8 +191,18 @@ from api.v1.serializers import (
     LighthouseConfigCreateSerializer,
     LighthouseConfigSerializer,
     LighthouseConfigUpdateSerializer,
+    LighthouseProviderConfigCreateSerializer,
+    LighthouseProviderConfigSerializer,
+    LighthouseProviderConfigUpdateSerializer,
+    LighthouseProviderModelsSerializer,
+    LighthouseTenantConfigSerializer,
+    LighthouseTenantConfigUpdateSerializer,
     MembershipSerializer,
+    MuteRuleCreateSerializer,
+    MuteRuleSerializer,
+    MuteRuleUpdateSerializer,
     OverviewFindingSerializer,
+    OverviewProviderCountSerializer,
     OverviewProviderSerializer,
     OverviewServiceSerializer,
     OverviewSeveritySerializer,
@@ -184,7 +234,11 @@ from api.v1.serializers import (
     ScanUpdateSerializer,
     ScheduleDailyCreateSerializer,
     TaskSerializer,
+    TenantApiKeyCreateSerializer,
+    TenantApiKeySerializer,
+    TenantApiKeyUpdateSerializer,
     TenantSerializer,
+    ThreatScoreSnapshotSerializer,
     TokenRefreshSerializer,
     TokenSerializer,
     TokenSocialLoginSerializer,
@@ -214,6 +268,8 @@ class RelationshipViewSchema(JsonApiAutoSchema):
     description="Obtain a token by providing valid credentials and an optional tenant ID.",
 )
 class CustomTokenObtainView(GenericAPIView):
+    throttle_scope = "token-obtain"
+
     resource_name = "tokens"
     serializer_class = TokenSerializer
     http_method_names = ["post"]
@@ -293,7 +349,7 @@ class SchemaView(SpectacularAPIView):
 
     def get(self, request, *args, **kwargs):
         spectacular_settings.TITLE = "Prowler API"
-        spectacular_settings.VERSION = "1.12.0"
+        spectacular_settings.VERSION = "1.15.0"
         spectacular_settings.DESCRIPTION = (
             "Prowler API specification.\n\nThis file is auto-generated."
         )
@@ -313,6 +369,11 @@ class SchemaView(SpectacularAPIView):
                 "description": "Endpoints for tenant invitations management, allowing retrieval and filtering of "
                 "invitations, creating new invitations, accepting and revoking them.",
             },
+            {
+                "name": "Role",
+                "description": "Endpoints for managing RBAC roles within tenants, allowing creation, retrieval, "
+                "updating, and deletion of role configurations and permissions.",
+            },
             {
                 "name": "Provider",
                 "description": "Endpoints for managing providers (AWS, GCP, Azure, etc...).",
@@ -321,10 +382,20 @@ class SchemaView(SpectacularAPIView):
                 "name": "Provider Group",
                 "description": "Endpoints for managing provider groups.",
             },
+            {
+                "name": "Task",
+                "description": "Endpoints for task management, allowing retrieval of task status and "
+                "revoking tasks that have not started.",
+            },
             {
                 "name": "Scan",
                 "description": "Endpoints for triggering manual scans and viewing scan results.",
             },
+            {
+                "name": "Schedule",
+                "description": "Endpoints for managing scan schedules, allowing configuration of automated "
+                "scans with different scheduling options.",
+            },
             {
                 "name": "Resource",
                 "description": "Endpoints for managing resources discovered by scans, allowing "
@@ -336,8 +407,9 @@ class SchemaView(SpectacularAPIView):
                 "findings that result from scans.",
             },
             {
-                "name": "Overview",
-                "description": "Endpoints for retrieving aggregated summaries of resources from the system.",
+                "name": "Processor",
+                "description": "Endpoints for managing post-processors used to process Prowler findings, including "
+                "registration, configuration, and deletion of post-processing actions.",
             },
             {
                 "name": "Compliance Overview",
@@ -345,9 +417,8 @@ class SchemaView(SpectacularAPIView):
                 " compliance framework ID.",
             },
             {
-                "name": "Task",
-                "description": "Endpoints for task management, allowing retrieval of task status and "
-                "revoking tasks that have not started.",
+                "name": "Overview",
+                "description": "Endpoints for retrieving aggregated summaries of resources from the system.",
             },
             {
                 "name": "Integration",
@@ -355,14 +426,26 @@ class SchemaView(SpectacularAPIView):
                 " retrieval, and deletion of integrations such as S3, JIRA, or other services.",
             },
             {
-                "name": "Lighthouse",
-                "description": "Endpoints for managing Lighthouse configurations, including creation, retrieval, "
-                "updating, and deletion of configurations such as OpenAI keys, models, and business context.",
+                "name": "Lighthouse AI",
+                "description": "Endpoints for managing Lighthouse AI configurations, including creation, retrieval, "
+                "updating, and deletion of configurations such as OpenAI keys, models, and business "
+                "context.",
             },
             {
-                "name": "Processor",
-                "description": "Endpoints for managing post-processors used to process Prowler findings, including "
-                "registration, configuration, and deletion of post-processing actions.",
+                "name": "SAML",
+                "description": "Endpoints for Single Sign-On authentication management via SAML for seamless user "
+                "authentication.",
+            },
+            {
+                "name": "API Keys",
+                "description": "Endpoints for API keys management. These can be used as an alternative to JWT "
+                "authorization.",
+            },
+            {
+                "name": "Mute Rules",
+                "description": "Endpoints for simple mute rules management. These can be used as an alternative to the"
+                " Mutelist Processor if you need to mute specific findings across your tenant with a "
+                "specific reason.",
             },
         ]
         return super().get(request, *args, **kwargs)
@@ -632,36 +715,48 @@ class TenantFinishACSView(FinishACSView):
             .get(email_domain=email_domain)
             .tenant
         )
-        role_name = (
-            extra.get("userType", ["no_permissions"])[0].strip()
-            if extra.get("userType")
-            else "no_permissions"
+
+        # Check if tenant has only one user with MANAGE_ACCOUNT role
+        users_with_manage_account = (
+            UserRoleRelationship.objects.using(MainRouter.admin_db)
+            .filter(role__manage_account=True, tenant_id=tenant.id)
+            .values("user")
+            .distinct()
+            .count()
         )
-        try:
-            role = Role.objects.using(MainRouter.admin_db).get(
-                name=role_name, tenant=tenant
+
+        # Only apply role mapping from userType if tenant does NOT have exactly one user with MANAGE_ACCOUNT
+        if users_with_manage_account != 1:
+            role_name = (
+                extra.get("userType", ["no_permissions"])[0].strip()
+                if extra.get("userType")
+                else "no_permissions"
             )
-        except Role.DoesNotExist:
-            role = Role.objects.using(MainRouter.admin_db).create(
-                name=role_name,
-                tenant=tenant,
-                manage_users=False,
-                manage_account=False,
-                manage_billing=False,
-                manage_providers=False,
-                manage_integrations=False,
-                manage_scans=False,
-                unlimited_visibility=False,
+            try:
+                role = Role.objects.using(MainRouter.admin_db).get(
+                    name=role_name, tenant=tenant
+                )
+            except Role.DoesNotExist:
+                role = Role.objects.using(MainRouter.admin_db).create(
+                    name=role_name,
+                    tenant=tenant,
+                    manage_users=False,
+                    manage_account=False,
+                    manage_billing=False,
+                    manage_providers=False,
+                    manage_integrations=False,
+                    manage_scans=False,
+                    unlimited_visibility=False,
+                )
+            UserRoleRelationship.objects.using(MainRouter.admin_db).filter(
+                user=user,
+                tenant_id=tenant.id,
+            ).delete()
+            UserRoleRelationship.objects.using(MainRouter.admin_db).create(
+                user=user,
+                role=role,
+                tenant_id=tenant.id,
             )
-        UserRoleRelationship.objects.using(MainRouter.admin_db).filter(
-            user=user,
-            tenant_id=tenant.id,
-        ).delete()
-        UserRoleRelationship.objects.using(MainRouter.admin_db).create(
-            user=user,
-            role=role,
-            tenant_id=tenant.id,
-        )
         membership, _ = Membership.objects.using(MainRouter.admin_db).get_or_create(
             user=user,
             tenant=tenant,
@@ -745,11 +840,13 @@ class UserViewSet(BaseUserViewset):
         # If called during schema generation, return an empty queryset
         if getattr(self, "swagger_fake_view", False):
             return User.objects.none()
+
         queryset = (
             User.objects.filter(membership__tenant__id=self.request.tenant_id)
             if hasattr(self.request, "tenant_id")
             else User.objects.all()
         )
+
         return queryset.prefetch_related("memberships", "roles")
 
     def get_permissions(self):
@@ -767,6 +864,12 @@ class UserViewSet(BaseUserViewset):
         else:
             return UserSerializer
 
+    def get_serializer_context(self):
+        context = super().get_serializer_context()
+        if self.request.user.is_authenticated:
+            context["role"] = get_role(self.request.user)
+        return context
+
     @action(detail=False, methods=["get"], url_name="me")
     def me(self, request):
         user = self.request.user
@@ -780,7 +883,9 @@ class UserViewSet(BaseUserViewset):
         if kwargs["pk"] != str(self.request.user.id):
             raise ValidationError("Only the current user can be deleted.")
 
-        return super().destroy(request, *args, **kwargs)
+        user = self.get_object()
+        user.delete(using=MainRouter.admin_db)
+        return Response(status=status.HTTP_204_NO_CONTENT)
 
     @extend_schema(
         parameters=[
@@ -871,7 +976,11 @@ class UserViewSet(BaseUserViewset):
     partial_update=extend_schema(
         tags=["User"],
         summary="Partially update a user-roles relationship",
-        description="Update the user-roles relationship information without affecting other fields.",
+        description=(
+            "Update the user-roles relationship information without affecting other fields. "
+            "If the update would remove MANAGE_ACCOUNT from the last remaining user in the "
+            "tenant, the API rejects the request with a 400 response."
+        ),
         responses={
             204: OpenApiResponse(
                 response=None, description="Relationship updated successfully"
@@ -881,7 +990,12 @@ class UserViewSet(BaseUserViewset):
     destroy=extend_schema(
         tags=["User"],
         summary="Delete a user-roles relationship",
-        description="Remove the user-roles relationship from the system by their ID.",
+        description=(
+            "Remove the user-roles relationship from the system by their ID. If removing "
+            "MANAGE_ACCOUNT would take it away from the last remaining user in the tenant, "
+            "the API rejects the request with a 400 response. Users also cannot delete their "
+            "own role assignments; attempting to do so returns a 400 response."
+        ),
         responses={
             204: OpenApiResponse(
                 response=None, description="Relationship deleted successfully"
@@ -896,11 +1010,48 @@ class UserRoleRelationshipView(RelationshipView, BaseRLSViewSet):
     http_method_names = ["post", "patch", "delete"]
     schema = RelationshipViewSchema()
     # RBAC required permissions
-    required_permissions = [Permissions.MANAGE_USERS]
+    required_permissions = [Permissions.MANAGE_ACCOUNT]
 
     def get_queryset(self):
         return User.objects.filter(membership__tenant__id=self.request.tenant_id)
 
+    def destroy(self, request, *args, **kwargs):
+        """
+        Prevent deleting role relationships if it would leave the tenant with no
+        users having MANAGE_ACCOUNT. Supports deleting specific roles via JSON:API
+        relationship payload or clearing all roles for the user when no payload.
+        """
+        user = self.get_object()
+        # Disallow deleting own roles
+        if str(user.id) == str(request.user.id):
+            return Response(
+                data={
+                    "detail": "Users cannot delete the relationship with their role."
+                },
+                status=status.HTTP_400_BAD_REQUEST,
+            )
+        tenant_id = self.request.tenant_id
+        payload = request.data if isinstance(request.data, dict) else None
+
+        # If a user has more than one role, we will delete the relationship with the roles in the payload
+        data = payload.get("data") if payload else None
+        if data:
+            try:
+                role_ids = [item["id"] for item in data]
+            except KeyError:
+                role_ids = []
+            roles_to_remove = Role.objects.filter(id__in=role_ids, tenant_id=tenant_id)
+        else:
+            roles_to_remove = user.roles.filter(tenant_id=tenant_id)
+
+        UserRoleRelationship.objects.filter(
+            user=user,
+            tenant_id=tenant_id,
+            role_id__in=roles_to_remove.values_list("id", flat=True),
+        ).delete()
+
+        return Response(status=status.HTTP_204_NO_CONTENT)
+
     def create(self, request, *args, **kwargs):
         user = self.get_object()
 
@@ -939,12 +1090,6 @@ class UserRoleRelationshipView(RelationshipView, BaseRLSViewSet):
         serializer.save()
         return Response(status=status.HTTP_204_NO_CONTENT)
 
-    def destroy(self, request, *args, **kwargs):
-        user = self.get_object()
-        user.roles.clear()
-
-        return Response(status=status.HTTP_204_NO_CONTENT)
-
 
 @extend_schema_view(
     list=extend_schema(
@@ -1320,7 +1465,7 @@ class ProviderGroupProvidersRelationshipView(RelationshipView, BaseRLSViewSet):
 )
 @method_decorator(CACHE_DECORATOR, name="list")
 @method_decorator(CACHE_DECORATOR, name="retrieve")
-class ProviderViewSet(BaseRLSViewSet):
+class ProviderViewSet(DisablePaginationMixin, BaseRLSViewSet):
     queryset = Provider.objects.all()
     serializer_class = ProviderSerializer
     http_method_names = ["get", "post", "patch", "delete"]
@@ -1497,6 +1642,25 @@ class ProviderViewSet(BaseRLSViewSet):
         },
         request=None,
     ),
+    threatscore=extend_schema(
+        tags=["Scan"],
+        summary="Retrieve threatscore report",
+        description="Download a specific threatscore report (e.g., 'prowler_threatscore_aws') as a PDF file.",
+        request=None,
+        responses={
+            200: OpenApiResponse(
+                description="PDF file containing the threatscore report"
+            ),
+            202: OpenApiResponse(description="The task is in progress"),
+            401: OpenApiResponse(
+                description="API key missing or user not Authenticated"
+            ),
+            403: OpenApiResponse(description="There is a problem with credentials"),
+            404: OpenApiResponse(
+                description="The scan has no threatscore reports, or the threatscore report generation task has not started yet"
+            ),
+        },
+    ),
 )
 @method_decorator(CACHE_DECORATOR, name="list")
 @method_decorator(CACHE_DECORATOR, name="retrieve")
@@ -1553,6 +1717,9 @@ class ScanViewSet(BaseRLSViewSet):
             if hasattr(self, "response_serializer_class"):
                 return self.response_serializer_class
             return ScanComplianceReportSerializer
+        elif self.action == "threatscore":
+            if hasattr(self, "response_serializer_class"):
+                return self.response_serializer_class
         return super().get_serializer_class()
 
     def partial_update(self, request, *args, **kwargs):
@@ -1657,7 +1824,18 @@ class ScanViewSet(BaseRLSViewSet):
                         status=status.HTTP_502_BAD_GATEWAY,
                     )
                 contents = resp.get("Contents", [])
-                keys = [obj["Key"] for obj in contents if obj["Key"].endswith(suffix)]
+                keys = []
+                for obj in contents:
+                    key = obj["Key"]
+                    key_basename = os.path.basename(key)
+                    if any(ch in suffix for ch in ("*", "?", "[")):
+                        if fnmatch.fnmatch(key_basename, suffix):
+                            keys.append(key)
+                    elif key_basename == suffix:
+                        keys.append(key)
+                    elif key.endswith(suffix):
+                        # Backward compatibility if suffix already includes directories
+                        keys.append(key)
                 if not keys:
                     return Response(
                         {
@@ -1784,6 +1962,45 @@ class ScanViewSet(BaseRLSViewSet):
         content, filename = loader
         return self._serve_file(content, filename, "text/csv")
 
+    @action(
+        detail=True,
+        methods=["get"],
+        url_name="threatscore",
+    )
+    def threatscore(self, request, pk=None):
+        scan = self.get_object()
+        running_resp = self._get_task_status(scan)
+        if running_resp:
+            return running_resp
+
+        if not scan.output_location:
+            return Response(
+                {
+                    "detail": "The scan has no reports, or the threatscore report generation task has not started yet."
+                },
+                status=status.HTTP_404_NOT_FOUND,
+            )
+
+        if scan.output_location.startswith("s3://"):
+            bucket = env.str("DJANGO_OUTPUT_S3_AWS_OUTPUT_BUCKET", "")
+            key_prefix = scan.output_location.removeprefix(f"s3://{bucket}/")
+            prefix = os.path.join(
+                os.path.dirname(key_prefix),
+                "threatscore",
+                "*_threatscore_report.pdf",
+            )
+            loader = self._load_file(prefix, s3=True, bucket=bucket, list_objects=True)
+        else:
+            base = os.path.dirname(scan.output_location)
+            pattern = os.path.join(base, "threatscore", "*_threatscore_report.pdf")
+            loader = self._load_file(pattern, s3=False)
+
+        if isinstance(loader, Response):
+            return loader
+
+        content, filename = loader
+        return self._serve_file(content, filename, "application/pdf")
+
     def create(self, request, *args, **kwargs):
         input_serializer = self.get_serializer(data=request.data)
         input_serializer.is_valid(raise_exception=True)
@@ -2849,13 +3066,11 @@ class InvitationAcceptViewSet(BaseRLSViewSet):
     partial_update=extend_schema(
         tags=["Role"],
         summary="Partially update a role",
-        description="Update certain fields of an existing role's information without affecting other fields.",
         responses={200: RoleSerializer},
     ),
     destroy=extend_schema(
         tags=["Role"],
         summary="Delete a role",
-        description="Remove a role from the system by their ID.",
     ),
 )
 class RoleViewSet(BaseRLSViewSet):
@@ -2877,6 +3092,14 @@ class RoleViewSet(BaseRLSViewSet):
             return RoleUpdateSerializer
         return super().get_serializer_class()
 
+    @extend_schema(
+        description=(
+            "Update selected fields on an existing role. When changing the `users` "
+            "relationship of a role that grants MANAGE_ACCOUNT, the API blocks attempts "
+            "that would leave the tenant without any MANAGE_ACCOUNT assignees and prevents "
+            "callers from removing their own assignment to that role."
+        )
+    )
     def partial_update(self, request, *args, **kwargs):
         user_role = get_role(request.user)
         # If the user is the owner of the role, the manage_account field is not editable
@@ -2884,6 +3107,12 @@ class RoleViewSet(BaseRLSViewSet):
             request.data["manage_account"] = str(user_role.manage_account).lower()
         return super().partial_update(request, *args, **kwargs)
 
+    @extend_schema(
+        description=(
+            "Delete the specified role. The API rejects deletion of the last role "
+            "in the tenant that grants MANAGE_ACCOUNT."
+        )
+    )
     def destroy(self, request, *args, **kwargs):
         instance = self.get_object()
         if (
@@ -2891,6 +3120,21 @@ class RoleViewSet(BaseRLSViewSet):
         ):  # TODO: Move to a constant/enum (in case other roles are created by default)
             raise ValidationError(detail="The admin role cannot be deleted.")
 
+        # Prevent deleting the last MANAGE_ACCOUNT role in the tenant
+        if instance.manage_account:
+            has_other_ma = (
+                Role.objects.filter(tenant_id=instance.tenant_id, manage_account=True)
+                .exclude(id=instance.id)
+                .exists()
+            )
+            if not has_other_ma:
+                return Response(
+                    data={
+                        "detail": "Cannot delete the only role with MANAGE_ACCOUNT in the tenant."
+                    },
+                    status=status.HTTP_400_BAD_REQUEST,
+                )
+
         return super().destroy(request, *args, **kwargs)
 
 
@@ -2990,15 +3234,50 @@ class RoleProviderGroupRelationshipView(RelationshipView, BaseRLSViewSet):
 @extend_schema_view(
     list=extend_schema(
         tags=["Compliance Overview"],
-        summary="List compliance overviews for a scan",
-        description="Retrieve an overview of all the compliance in a given scan.",
+        summary="List compliance overviews",
+        description=(
+            "Retrieve an overview of all compliance frameworks. "
+            "If scan_id is provided, returns compliance data for that specific scan. "
+            "If scan_id is omitted, returns compliance data aggregated from the latest completed scan of each provider."
+        ),
         parameters=[
             OpenApiParameter(
                 name="filter[scan_id]",
-                required=True,
+                required=False,
                 type=OpenApiTypes.UUID,
                 location=OpenApiParameter.QUERY,
-                description="Related scan ID.",
+                description=(
+                    "Optional scan ID. If provided, returns compliance for that scan. "
+                    "If omitted, returns compliance for the latest completed scan per provider."
+                ),
+            ),
+            OpenApiParameter(
+                name="filter[provider_id]",
+                required=False,
+                type=OpenApiTypes.UUID,
+                location=OpenApiParameter.QUERY,
+                description="Filter by specific provider ID.",
+            ),
+            OpenApiParameter(
+                name="filter[provider_id__in]",
+                required=False,
+                type={"type": "array", "items": {"type": "string", "format": "uuid"}},
+                location=OpenApiParameter.QUERY,
+                description="Filter by multiple provider IDs (comma-separated).",
+            ),
+            OpenApiParameter(
+                name="filter[provider_type]",
+                required=False,
+                type=OpenApiTypes.STR,
+                location=OpenApiParameter.QUERY,
+                description="Filter by provider type (e.g., aws, azure, gcp).",
+            ),
+            OpenApiParameter(
+                name="filter[provider_type__in]",
+                required=False,
+                type={"type": "array", "items": {"type": "string"}},
+                location=OpenApiParameter.QUERY,
+                description="Filter by multiple provider types (comma-separated).",
             ),
         ],
         responses={
@@ -3033,7 +3312,9 @@ class RoleProviderGroupRelationshipView(RelationshipView, BaseRLSViewSet):
                 description="Compliance overviews metadata obtained successfully",
                 response=ComplianceOverviewMetadataSerializer,
             ),
-            202: OpenApiResponse(description="The task is in progress"),
+            202: OpenApiResponse(
+                description="The task is in progress", response=TaskSerializer
+            ),
             500: OpenApiResponse(
                 description="Compliance overviews generation task failed"
             ),
@@ -3065,7 +3346,9 @@ class RoleProviderGroupRelationshipView(RelationshipView, BaseRLSViewSet):
                 description="Compliance requirement details obtained successfully",
                 response=ComplianceOverviewDetailSerializer(many=True),
             ),
-            202: OpenApiResponse(description="The task is in progress"),
+            202: OpenApiResponse(
+                description="The task is in progress", response=TaskSerializer
+            ),
             500: OpenApiResponse(
                 description="Compliance overviews generation task failed"
             ),
@@ -3151,33 +3434,45 @@ class ComplianceOverviewViewSet(BaseRLSViewSet, TaskManagementMixin):
     def retrieve(self, request, *args, **kwargs):
         raise MethodNotAllowed(method="GET")
 
-    def list(self, request, *args, **kwargs):
-        scan_id = request.query_params.get("filter[scan_id]")
-        if not scan_id:
-            raise ValidationError(
-                [
-                    {
-                        "detail": "This query parameter is required.",
-                        "status": 400,
-                        "source": {"pointer": "filter[scan_id]"},
-                        "code": "required",
-                    }
-                ]
-            )
-        try:
-            if task := self.get_task_response_if_running(
-                task_name="scan-compliance-overviews",
-                task_kwargs={"tenant_id": self.request.tenant_id, "scan_id": scan_id},
-                raise_on_not_found=False,
-            ):
-                return task
-        except TaskFailedException:
-            return Response(
-                {"detail": "Task failed to generate compliance overview data."},
-                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
-            )
-        queryset = self.filter_queryset(self.filter_queryset(self.get_queryset()))
+    def _compliance_summaries_queryset(self, scan_id):
+        """Return pre-aggregated summaries constrained by RBAC visibility."""
+        role = get_role(self.request.user)
+        unlimited_visibility = getattr(
+            role, Permissions.UNLIMITED_VISIBILITY.value, False
+        )
+        summaries = ComplianceOverviewSummary.objects.filter(
+            tenant_id=self.request.tenant_id,
+            scan_id=scan_id,
+        )
 
+        if not unlimited_visibility:
+            providers = Provider.all_objects.filter(
+                provider_groups__in=role.provider_groups.all()
+            ).distinct()
+            summaries = summaries.filter(scan__provider__in=providers)
+
+        return summaries
+
+    def _get_compliance_template(self, *, provider=None, scan_id=None):
+        """Return the compliance template for the given provider or scan."""
+        if provider is None and scan_id is not None:
+            scan = Scan.all_objects.select_related("provider").get(pk=scan_id)
+            provider = scan.provider
+
+        if not provider:
+            return {}
+
+        return PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE.get(provider.provider, {})
+
+    def _aggregate_compliance_overview(self, queryset, template_metadata=None):
+        """
+        Aggregate requirement rows into compliance overview dictionaries.
+
+        Args:
+            queryset: ComplianceRequirementOverview queryset already filtered.
+            template_metadata: Optional dict mapping compliance_id -> metadata.
+        """
+        template_metadata = template_metadata or {}
         requirement_status_subquery = queryset.values(
             "compliance_id", "requirement_id"
         ).annotate(
@@ -3187,13 +3482,15 @@ class ComplianceOverviewViewSet(BaseRLSViewSet, TaskManagementMixin):
         )
 
         compliance_data = {}
-        framework_info = {}
-
-        for item in queryset.values("compliance_id", "framework", "version").distinct():
-            framework_info[item["compliance_id"]] = {
+        fallback_metadata = {
+            item["compliance_id"]: {
                 "framework": item["framework"],
                 "version": item["version"],
             }
+            for item in queryset.values(
+                "compliance_id", "framework", "version"
+            ).distinct()
+        }
 
         for item in requirement_status_subquery:
             compliance_id = item["compliance_id"]
@@ -3205,32 +3502,36 @@ class ComplianceOverviewViewSet(BaseRLSViewSet, TaskManagementMixin):
             else:
                 req_status = "MANUAL"
 
-            if compliance_id not in compliance_data:
-                compliance_data[compliance_id] = {
+            compliance_status = compliance_data.setdefault(
+                compliance_id,
+                {
                     "total_requirements": 0,
                     "requirements_passed": 0,
                     "requirements_failed": 0,
                     "requirements_manual": 0,
-                }
+                },
+            )
 
-            compliance_data[compliance_id]["total_requirements"] += 1
+            compliance_status["total_requirements"] += 1
             if req_status == "PASS":
-                compliance_data[compliance_id]["requirements_passed"] += 1
+                compliance_status["requirements_passed"] += 1
             elif req_status == "FAIL":
-                compliance_data[compliance_id]["requirements_failed"] += 1
+                compliance_status["requirements_failed"] += 1
             else:
-                compliance_data[compliance_id]["requirements_manual"] += 1
+                compliance_status["requirements_manual"] += 1
 
         response_data = []
         for compliance_id, data in compliance_data.items():
-            framework = framework_info.get(compliance_id, {})
+            template = template_metadata.get(compliance_id, {})
+            fallback = fallback_metadata.get(compliance_id, {})
 
             response_data.append(
                 {
                     "id": compliance_id,
                     "compliance_id": compliance_id,
-                    "framework": framework.get("framework", ""),
-                    "version": framework.get("version", ""),
+                    "framework": template.get("framework")
+                    or fallback.get("framework", ""),
+                    "version": template.get("version") or fallback.get("version", ""),
                     "requirements_passed": data["requirements_passed"],
                     "requirements_failed": data["requirements_failed"],
                     "requirements_manual": data["requirements_manual"],
@@ -3239,7 +3540,151 @@ class ComplianceOverviewViewSet(BaseRLSViewSet, TaskManagementMixin):
             )
 
         serializer = self.get_serializer(response_data, many=True)
-        return Response(serializer.data)
+        return serializer.data
+
+    def _task_response_if_running(self, scan_id):
+        """Check for an in-progress task only when no compliance data exists."""
+        try:
+            return self.get_task_response_if_running(
+                task_name="scan-compliance-overviews",
+                task_kwargs={"tenant_id": self.request.tenant_id, "scan_id": scan_id},
+                raise_on_not_found=False,
+            )
+        except TaskFailedException:
+            return Response(
+                {"detail": "Task failed to generate compliance overview data."},
+                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
+            )
+
+    def _list_with_region_filter(self, scan_id, region_filter):
+        """
+        Fall back to detailed ComplianceRequirementOverview query when region filter is applied.
+        This uses the original aggregation logic across filtered regions.
+        """
+        regions = region_filter.split(",") if "," in region_filter else [region_filter]
+        queryset = self.filter_queryset(self.get_queryset()).filter(
+            scan_id=scan_id,
+            region__in=regions,
+        )
+
+        data = self._aggregate_compliance_overview(queryset)
+        if data:
+            return Response(data)
+
+        task_response = self._task_response_if_running(scan_id)
+        if task_response:
+            return task_response
+
+        return Response(data)
+
+    def _list_without_region_aggregation(self, scan_id):
+        """
+        Fall back aggregation when compliance summaries don't exist yet.
+        Aggregates ComplianceRequirementOverview data across ALL regions.
+        """
+        queryset = self.filter_queryset(self.get_queryset()).filter(scan_id=scan_id)
+        compliance_template = self._get_compliance_template(scan_id=scan_id)
+        data = self._aggregate_compliance_overview(
+            queryset, template_metadata=compliance_template
+        )
+        if data:
+            return Response(data)
+
+        task_response = self._task_response_if_running(scan_id)
+        if task_response:
+            return task_response
+
+        return Response(data)
+
+    def list(self, request, *args, **kwargs):
+        scan_id = request.query_params.get("filter[scan_id]")
+        tenant_id = self.request.tenant_id
+
+        if scan_id:
+            # Specific scan requested - use optimized summaries with region support
+            region_filter = request.query_params.get(
+                "filter[region]"
+            ) or request.query_params.get("filter[region__in]")
+
+            if region_filter:
+                # Fall back to detailed query with region filtering
+                return self._list_with_region_filter(scan_id, region_filter)
+
+            summaries = list(self._compliance_summaries_queryset(scan_id))
+            if not summaries:
+                # Trigger async backfill for next time
+                backfill_compliance_summaries_task.delay(
+                    tenant_id=self.request.tenant_id, scan_id=scan_id
+                )
+                # Use fallback aggregation for this request
+                return self._list_without_region_aggregation(scan_id)
+
+            # Get compliance template for provider to enrich with framework/version
+            compliance_template = self._get_compliance_template(scan_id=scan_id)
+
+            # Convert to response format with framework/version enrichment
+            response_data = []
+            for summary in summaries:
+                compliance_metadata = compliance_template.get(summary.compliance_id, {})
+                response_data.append(
+                    {
+                        "id": summary.compliance_id,
+                        "compliance_id": summary.compliance_id,
+                        "framework": compliance_metadata.get("framework", ""),
+                        "version": compliance_metadata.get("version", ""),
+                        "requirements_passed": summary.requirements_passed,
+                        "requirements_failed": summary.requirements_failed,
+                        "requirements_manual": summary.requirements_manual,
+                        "total_requirements": summary.total_requirements,
+                    }
+                )
+
+            serializer = self.get_serializer(response_data, many=True)
+            return Response(serializer.data)
+        else:
+            # No scan_id provided - use latest scans per provider
+            # First, check if provider filters are present
+            provider_id = request.query_params.get("filter[provider_id]")
+            provider_id__in = request.query_params.get("filter[provider_id__in]")
+            provider_type = request.query_params.get("filter[provider_type]")
+            provider_type__in = request.query_params.get("filter[provider_type__in]")
+
+            scan_filters = {"tenant_id": tenant_id, "state": StateChoices.COMPLETED}
+
+            # Apply provider ID filters
+            if provider_id:
+                scan_filters["provider_id"] = provider_id
+            elif provider_id__in:
+                # Convert comma-separated string to list
+                provider_ids = [pid.strip() for pid in provider_id__in.split(",")]
+                scan_filters["provider_id__in"] = provider_ids
+
+            # Apply provider type filters
+            if provider_type:
+                scan_filters["provider__provider"] = provider_type
+            elif provider_type__in:
+                # Convert comma-separated string to list
+                provider_types = [pt.strip() for pt in provider_type__in.split(",")]
+                scan_filters["provider__provider__in"] = provider_types
+
+            latest_scan_ids = (
+                Scan.all_objects.filter(**scan_filters)
+                .order_by("provider_id", "-inserted_at")
+                .distinct("provider_id")
+                .values_list("id", flat=True)
+            )
+
+            base_queryset = self.get_queryset()
+            queryset = self.filter_queryset(
+                base_queryset.filter(scan_id__in=latest_scan_ids)
+            )
+
+            # Aggregate compliance data across latest scans
+            compliance_template = self._get_compliance_template()
+            data = self._aggregate_compliance_overview(
+                queryset, template_metadata=compliance_template
+            )
+            return Response(data)
 
     @action(detail=False, methods=["get"], url_name="metadata")
     def metadata(self, request):
@@ -3255,18 +3700,6 @@ class ComplianceOverviewViewSet(BaseRLSViewSet, TaskManagementMixin):
                     }
                 ]
             )
-        try:
-            if task := self.get_task_response_if_running(
-                task_name="scan-compliance-overviews",
-                task_kwargs={"tenant_id": self.request.tenant_id, "scan_id": scan_id},
-                raise_on_not_found=False,
-            ):
-                return task
-        except TaskFailedException:
-            return Response(
-                {"detail": "Task failed to generate compliance overview data."},
-                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
-            )
         regions = list(
             self.get_queryset()
             .filter(scan_id=scan_id)
@@ -3276,6 +3709,15 @@ class ComplianceOverviewViewSet(BaseRLSViewSet, TaskManagementMixin):
         )
         result = {"regions": regions}
 
+        if regions:
+            serializer = self.get_serializer(data=result)
+            serializer.is_valid(raise_exception=True)
+            return Response(serializer.data, status=status.HTTP_200_OK)
+
+        task_response = self._task_response_if_running(scan_id)
+        if task_response:
+            return task_response
+
         serializer = self.get_serializer(data=result)
         serializer.is_valid(raise_exception=True)
         return Response(serializer.data, status=status.HTTP_200_OK)
@@ -3308,29 +3750,18 @@ class ComplianceOverviewViewSet(BaseRLSViewSet, TaskManagementMixin):
                     }
                 ]
             )
-        try:
-            if task := self.get_task_response_if_running(
-                task_name="scan-compliance-overviews",
-                task_kwargs={"tenant_id": self.request.tenant_id, "scan_id": scan_id},
-                raise_on_not_found=False,
-            ):
-                return task
-        except TaskFailedException:
-            return Response(
-                {"detail": "Task failed to generate compliance overview data."},
-                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
-            )
         filtered_queryset = self.filter_queryset(self.get_queryset())
 
-        all_requirements = (
-            filtered_queryset.values(
-                "requirement_id", "framework", "version", "description"
-            )
-            .distinct()
-            .annotate(
-                total_instances=Count("id"),
-                manual_count=Count("id", filter=Q(requirement_status="MANUAL")),
-            )
+        all_requirements = filtered_queryset.values(
+            "requirement_id",
+            "framework",
+            "version",
+            "description",
+        ).annotate(
+            total_instances=Count("id"),
+            manual_count=Count("id", filter=Q(requirement_status="MANUAL")),
+            passed_findings_sum=Sum("passed_findings"),
+            total_findings_sum=Sum("total_findings"),
         )
 
         passed_instances = (
@@ -3349,6 +3780,8 @@ class ComplianceOverviewViewSet(BaseRLSViewSet, TaskManagementMixin):
             total_instances = requirement["total_instances"]
             passed_count = passed_counts.get(requirement_id, 0)
             is_manual = requirement["manual_count"] == total_instances
+            passed_findings = requirement["passed_findings_sum"] or 0
+            total_findings = requirement["total_findings_sum"] or 0
             if is_manual:
                 requirement_status = "MANUAL"
             elif passed_count == total_instances:
@@ -3363,10 +3796,26 @@ class ComplianceOverviewViewSet(BaseRLSViewSet, TaskManagementMixin):
                     "version": requirement["version"],
                     "description": requirement["description"],
                     "status": requirement_status,
+                    "passed_findings": passed_findings,
+                    "total_findings": total_findings,
                 }
             )
 
-        serializer = self.get_serializer(requirements_summary, many=True)
+        # Use different serializer for threatscore framework
+        if "threatscore" not in compliance_id:
+            serializer = self.get_serializer(requirements_summary, many=True)
+        else:
+            serializer = ComplianceOverviewDetailThreatscoreSerializer(
+                requirements_summary, many=True
+            )
+
+        if requirements_summary:
+            return Response(serializer.data, status=status.HTTP_200_OK)
+
+        task_response = self._task_response_if_running(scan_id)
+        if task_response:
+            return task_response
+
         return Response(serializer.data, status=status.HTTP_200_OK)
 
     @action(detail=False, methods=["get"], url_name="attributes")
@@ -3385,15 +3834,6 @@ class ComplianceOverviewViewSet(BaseRLSViewSet, TaskManagementMixin):
             )
 
         provider_type = None
-        try:
-            sample_requirement = (
-                self.get_queryset().filter(compliance_id=compliance_id).first()
-            )
-
-            if sample_requirement:
-                provider_type = sample_requirement.scan.provider.provider
-        except Exception:
-            pass
 
         # If we couldn't determine from database, try each provider type
         if not provider_type:
@@ -3443,6 +3883,7 @@ class ComplianceOverviewViewSet(BaseRLSViewSet, TaskManagementMixin):
                     ),
                     "name": requirement.get("name", ""),
                     "framework": compliance_framework.get("framework", ""),
+                    "compliance_name": compliance_framework.get("name", ""),
                     "version": compliance_framework.get("version", ""),
                     "description": requirement.get("description", ""),
                     "attributes": base_attributes,
@@ -3464,6 +3905,13 @@ class ComplianceOverviewViewSet(BaseRLSViewSet, TaskManagementMixin):
             "each provider are considered in the aggregation to ensure accurate and up-to-date insights."
         ),
     ),
+    providers_count=extend_schema(
+        summary="Get provider counts grouped by type",
+        description=(
+            "Retrieve the number of providers grouped by provider type. "
+            "This endpoint counts every provider in the tenant, including those without completed scans."
+        ),
+    ),
     findings=extend_schema(
         summary="Get aggregated findings data",
         description=(
@@ -3488,8 +3936,7 @@ class ComplianceOverviewViewSet(BaseRLSViewSet, TaskManagementMixin):
         summary="Get findings data by service",
         description=(
             "Retrieve an aggregated summary of findings grouped by service. The response includes the total count "
-            "of findings for each service, as long as there are at least one finding for that service. At least "
-            "one of the `inserted_at` filters must be provided."
+            "of findings for each service, as long as there are at least one finding for that service."
         ),
         filters=True,
     ),
@@ -3515,21 +3962,27 @@ class OverviewViewSet(BaseRLSViewSet):
     def get_serializer_class(self):
         if self.action == "providers":
             return OverviewProviderSerializer
+        elif self.action == "providers_count":
+            return OverviewProviderCountSerializer
         elif self.action == "findings":
             return OverviewFindingSerializer
         elif self.action == "findings_severity":
             return OverviewSeveritySerializer
         elif self.action == "services":
             return OverviewServiceSerializer
+        elif self.action == "threatscore":
+            return ThreatScoreSnapshotSerializer
         return super().get_serializer_class()
 
     def get_filterset_class(self):
         if self.action == "providers":
             return None
-        elif self.action in ["findings", "findings_severity"]:
+        elif self.action == "findings":
             return ScanSummaryFilter
+        elif self.action == "findings_severity":
+            return ScanSummarySeverityFilter
         elif self.action == "services":
-            return ServiceOverviewFilter
+            return ScanSummaryFilter
         return None
 
     @extend_schema(exclude=True)
@@ -3561,10 +4014,7 @@ class OverviewViewSet(BaseRLSViewSet):
 
         findings_aggregated = (
             queryset.filter(scan_id__in=latest_scan_ids)
-            .values(
-                "scan__provider_id",
-                provider=F("scan__provider__provider"),
-            )
+            .values(provider=F("scan__provider__provider"))
             .annotate(
                 findings_passed=Coalesce(Sum("_pass"), 0),
                 findings_failed=Coalesce(Sum("fail"), 0),
@@ -3573,13 +4023,16 @@ class OverviewViewSet(BaseRLSViewSet):
             )
         )
 
-        resources_aggregated = (
-            Resource.all_objects.filter(tenant_id=tenant_id)
-            .values("provider_id")
-            .annotate(total_resources=Count("id"))
-        )
+        resources_queryset = Resource.all_objects.filter(tenant_id=tenant_id)
+        if hasattr(self, "allowed_providers"):
+            resources_queryset = resources_queryset.filter(
+                provider__in=self.allowed_providers
+            )
+        resources_aggregated = resources_queryset.values(
+            provider_type=F("provider__provider")
+        ).annotate(total_resources=Count("id"))
         resource_map = {
-            row["provider_id"]: row["total_resources"] for row in resources_aggregated
+            row["provider_type"]: row["total_resources"] for row in resources_aggregated
         }
 
         overview = []
@@ -3587,7 +4040,7 @@ class OverviewViewSet(BaseRLSViewSet):
             overview.append(
                 {
                     "provider": row["provider"],
-                    "total_resources": resource_map.get(row["scan__provider_id"], 0),
+                    "total_resources": resource_map.get(row["provider"], 0),
                     "total_findings": row["total_findings"],
                     "findings_passed": row["findings_passed"],
                     "findings_failed": row["findings_failed"],
@@ -3600,6 +4053,36 @@ class OverviewViewSet(BaseRLSViewSet):
             status=status.HTTP_200_OK,
         )
 
+    @action(
+        detail=False,
+        methods=["get"],
+        url_path="providers/count",
+        url_name="providers-count",
+    )
+    def providers_count(self, request):
+        tenant_id = self.request.tenant_id
+        providers_qs = Provider.objects.filter(tenant_id=tenant_id)
+
+        if hasattr(self, "allowed_providers"):
+            allowed_ids = list(self.allowed_providers.values_list("id", flat=True))
+            if not allowed_ids:
+                overview = []
+                return Response(
+                    self.get_serializer(overview, many=True).data,
+                    status=status.HTTP_200_OK,
+                )
+            providers_qs = providers_qs.filter(id__in=allowed_ids)
+
+        overview = (
+            providers_qs.values("provider")
+            .annotate(count=Count("id"))
+            .order_by("provider")
+        )
+        return Response(
+            self.get_serializer(overview, many=True).data,
+            status=status.HTTP_200_OK,
+        )
+
     @action(detail=False, methods=["get"], url_name="findings")
     def findings(self, request):
         tenant_id = self.request.tenant_id
@@ -3649,7 +4132,12 @@ class OverviewViewSet(BaseRLSViewSet):
     @action(detail=False, methods=["get"], url_name="findings_severity")
     def findings_severity(self, request):
         tenant_id = self.request.tenant_id
-        queryset = self.get_queryset()
+
+        # Load only required fields
+        queryset = self.get_queryset().only(
+            "tenant_id", "scan_id", "severity", "fail", "_pass", "total"
+        )
+
         filtered_queryset = self.filter_queryset(queryset)
         provider_filter = (
             {"provider__in": self.allowed_providers}
@@ -3669,16 +4157,22 @@ class OverviewViewSet(BaseRLSViewSet):
             tenant_id=tenant_id, scan_id__in=latest_scan_ids
         )
 
+        # The filter will have added a status_count annotation if any status filter was used
+        if "status_count" in filtered_queryset.query.annotations:
+            sum_expression = Sum("status_count")
+        else:
+            sum_expression = Sum("total")
+
         severity_counts = (
             filtered_queryset.values("severity")
-            .annotate(count=Sum("total"))
+            .annotate(count=sum_expression)
             .order_by("severity")
         )
 
         severity_data = {sev[0]: 0 for sev in SeverityChoices}
-
-        for item in severity_counts:
-            severity_data[item["severity"]] = item["count"]
+        severity_data.update(
+            {item["severity"]: item["count"] for item in severity_counts}
+        )
 
         serializer = self.get_serializer(severity_data)
         return Response(serializer.data, status=status.HTTP_200_OK)
@@ -3719,6 +4213,332 @@ class OverviewViewSet(BaseRLSViewSet):
 
         return Response(serializer.data, status=status.HTTP_200_OK)
 
+    @extend_schema(
+        summary="Get ThreatScore snapshots",
+        description=(
+            "Retrieve ThreatScore metrics. By default, returns the latest snapshot for each provider. "
+            "Use snapshot_id to retrieve a specific historical snapshot."
+        ),
+        tags=["Overviews"],
+        parameters=[
+            OpenApiParameter(
+                name="snapshot_id",
+                type=OpenApiTypes.UUID,
+                location=OpenApiParameter.QUERY,
+                description="Retrieve a specific snapshot by ID. If not provided, returns latest snapshots.",
+            ),
+            OpenApiParameter(
+                name="provider_id",
+                type=OpenApiTypes.UUID,
+                location=OpenApiParameter.QUERY,
+                description="Filter by specific provider ID",
+            ),
+            OpenApiParameter(
+                name="provider_id__in",
+                type=OpenApiTypes.STR,
+                location=OpenApiParameter.QUERY,
+                description="Filter by multiple provider IDs (comma-separated UUIDs)",
+            ),
+            OpenApiParameter(
+                name="provider_type",
+                type=OpenApiTypes.STR,
+                location=OpenApiParameter.QUERY,
+                description="Filter by provider type (aws, azure, gcp, etc.)",
+            ),
+            OpenApiParameter(
+                name="provider_type__in",
+                type=OpenApiTypes.STR,
+                location=OpenApiParameter.QUERY,
+                description="Filter by multiple provider types (comma-separated)",
+            ),
+        ],
+    )
+    @action(detail=False, methods=["get"], url_name="threatscore")
+    def threatscore(self, request):
+        """
+        Get ThreatScore snapshots.
+
+        Default behavior: Returns the latest snapshot for each provider.
+        With snapshot_id: Returns the specific snapshot requested.
+        """
+        tenant_id = self.request.tenant_id
+        snapshot_id = request.query_params.get("snapshot_id")
+
+        # Base queryset with RLS
+        base_queryset = ThreatScoreSnapshot.objects.filter(tenant_id=tenant_id)
+
+        # Apply RBAC filtering
+        if hasattr(self, "allowed_providers"):
+            base_queryset = base_queryset.filter(provider__in=self.allowed_providers)
+
+        # Case 1: Specific snapshot requested
+        if snapshot_id:
+            try:
+                snapshot = base_queryset.get(id=snapshot_id)
+                serializer = ThreatScoreSnapshotSerializer(
+                    snapshot, context={"request": request}
+                )
+                return Response(serializer.data, status=status.HTTP_200_OK)
+            except ThreatScoreSnapshot.DoesNotExist:
+                raise NotFound(detail="ThreatScore snapshot not found")
+
+        # Case 2: Latest snapshot per provider (default)
+        # Apply filters manually: this @action is outside the standard list endpoint flow,
+        # so DRF's filter backends don't execute and we must flatten JSON:API params ourselves.
+        normalized_params = QueryDict(mutable=True)
+        for param_key, values in request.query_params.lists():
+            normalized_key = param_key
+            if param_key.startswith("filter[") and param_key.endswith("]"):
+                normalized_key = param_key[7:-1]
+            if normalized_key == "snapshot_id":
+                continue
+            normalized_params.setlist(normalized_key, values)
+
+        filterset = ThreatScoreSnapshotFilter(normalized_params, queryset=base_queryset)
+        filtered_queryset = filterset.qs
+
+        # Get distinct provider IDs from filtered queryset
+        # Pick the latest snapshot per provider using Postgres DISTINCT ON pattern.
+        # This avoids issuing one query per provider (N+1) when the filtered dataset is large.
+        latest_snapshot_ids = list(
+            filtered_queryset.order_by("provider_id", "-inserted_at")
+            .distinct("provider_id")
+            .values_list("id", flat=True)
+        )
+        latest_snapshot_map = {
+            snapshot.id: snapshot
+            for snapshot in filtered_queryset.filter(id__in=latest_snapshot_ids)
+        }
+        latest_snapshots = [
+            latest_snapshot_map[snapshot_id]
+            for snapshot_id in latest_snapshot_ids
+            if snapshot_id in latest_snapshot_map
+        ]
+
+        if len(latest_snapshots) <= 1:
+            serializer = ThreatScoreSnapshotSerializer(
+                latest_snapshots, many=True, context={"request": request}
+            )
+            return Response(serializer.data, status=status.HTTP_200_OK)
+
+        snapshot_ids = [
+            snapshot.id for snapshot in latest_snapshots if snapshot and snapshot.id
+        ]
+        aggregated_snapshot = self._build_threatscore_overview_snapshot(
+            snapshot_ids, tenant_id
+        )
+        serializer = ThreatScoreSnapshotSerializer(
+            [aggregated_snapshot], many=True, context={"request": request}
+        )
+        return Response(serializer.data, status=status.HTTP_200_OK)
+
+    def _build_threatscore_overview_snapshot(self, snapshot_ids, tenant_id):
+        """
+        Aggregate the latest snapshots into a single overview snapshot for the tenant.
+        """
+        if not snapshot_ids:
+            raise ValueError(
+                "Snapshot id list cannot be empty when aggregating threatscore overview"
+            )
+
+        base_queryset = ThreatScoreSnapshot.objects.filter(
+            tenant_id=tenant_id, id__in=snapshot_ids
+        )
+
+        annotated_queryset = (
+            base_queryset.annotate(
+                active_requirements=ExpressionWrapper(
+                    F("total_requirements") - F("manual_requirements"),
+                    output_field=IntegerField(),
+                )
+            )
+            .annotate(
+                weight=Case(
+                    When(total_findings__gt=0, then=F("total_findings")),
+                    When(
+                        active_requirements__gt=0,
+                        then=F("active_requirements"),
+                    ),
+                    default=Value(1, output_field=IntegerField()),
+                    output_field=IntegerField(),
+                )
+            )
+            .order_by()
+        )
+
+        aggregated_metrics = annotated_queryset.aggregate(
+            total_requirements=Sum("total_requirements"),
+            passed_requirements=Sum("passed_requirements"),
+            failed_requirements=Sum("failed_requirements"),
+            manual_requirements=Sum("manual_requirements"),
+            total_findings=Sum("total_findings"),
+            passed_findings=Sum("passed_findings"),
+            failed_findings=Sum("failed_findings"),
+            weighted_overall_sum=Sum(
+                ExpressionWrapper(
+                    F("overall_score") * F("weight"),
+                    output_field=DecimalField(max_digits=14, decimal_places=4),
+                )
+            ),
+            overall_weight=Sum("weight"),
+            unweighted_overall_sum=Sum("overall_score"),
+            weighted_delta_sum=Sum(
+                Case(
+                    When(
+                        score_delta__isnull=False,
+                        then=ExpressionWrapper(
+                            F("score_delta") * F("weight"),
+                            output_field=DecimalField(max_digits=14, decimal_places=4),
+                        ),
+                    ),
+                    default=Value(
+                        Decimal("0"),
+                        output_field=DecimalField(max_digits=14, decimal_places=4),
+                    ),
+                    output_field=DecimalField(max_digits=14, decimal_places=4),
+                )
+            ),
+            delta_weight=Sum(
+                Case(
+                    When(score_delta__isnull=False, then=F("weight")),
+                    default=Value(0, output_field=IntegerField()),
+                    output_field=IntegerField(),
+                )
+            ),
+            provider_count=Count("id"),
+            latest_inserted_at=Max("inserted_at"),
+        )
+
+        total_requirements = aggregated_metrics["total_requirements"] or 0
+        passed_requirements = aggregated_metrics["passed_requirements"] or 0
+        failed_requirements = aggregated_metrics["failed_requirements"] or 0
+        manual_requirements = aggregated_metrics["manual_requirements"] or 0
+        total_findings = aggregated_metrics["total_findings"] or 0
+        passed_findings = aggregated_metrics["passed_findings"] or 0
+        failed_findings = aggregated_metrics["failed_findings"] or 0
+
+        weighted_overall_sum = aggregated_metrics["weighted_overall_sum"]
+        if weighted_overall_sum is None:
+            weighted_overall_sum = Decimal("0")
+        unweighted_overall_sum = aggregated_metrics["unweighted_overall_sum"]
+        if unweighted_overall_sum is None:
+            unweighted_overall_sum = Decimal("0")
+
+        overall_weight = aggregated_metrics["overall_weight"] or 0
+        provider_count = aggregated_metrics["provider_count"] or 0
+
+        weighted_delta_sum = aggregated_metrics["weighted_delta_sum"]
+        if weighted_delta_sum is None:
+            weighted_delta_sum = Decimal("0")
+        delta_weight = aggregated_metrics["delta_weight"] or 0
+
+        if overall_weight > 0:
+            overall_score = (weighted_overall_sum / Decimal(overall_weight)).quantize(
+                Decimal("0.01"), rounding=ROUND_HALF_UP
+            )
+        elif provider_count > 0:
+            overall_score = (unweighted_overall_sum / Decimal(provider_count)).quantize(
+                Decimal("0.01"), rounding=ROUND_HALF_UP
+            )
+        else:
+            overall_score = Decimal("0.00")
+
+        if delta_weight > 0:
+            score_delta = (weighted_delta_sum / Decimal(delta_weight)).quantize(
+                Decimal("0.01"), rounding=ROUND_HALF_UP
+            )
+        else:
+            score_delta = None
+
+        section_weighted_sums = defaultdict(lambda: Decimal("0"))
+        section_weights = defaultdict(lambda: Decimal("0"))
+
+        combined_critical_requirements = {}
+
+        snapshots_with_weight = list(annotated_queryset)
+
+        for snapshot in snapshots_with_weight:
+            weight_value = getattr(snapshot, "weight", None)
+            try:
+                weight_decimal = Decimal(weight_value)
+            except (InvalidOperation, TypeError):
+                weight_decimal = Decimal("1")
+            if weight_decimal <= 0:
+                weight_decimal = Decimal("1")
+
+            section_scores = snapshot.section_scores or {}
+            for section, score in section_scores.items():
+                try:
+                    score_decimal = Decimal(str(score))
+                except (InvalidOperation, TypeError):
+                    continue
+                section_weighted_sums[section] += score_decimal * weight_decimal
+                section_weights[section] += weight_decimal
+
+            for requirement in snapshot.critical_requirements or []:
+                key = requirement.get("requirement_id") or requirement.get("title")
+                if not key:
+                    continue
+                existing = combined_critical_requirements.get(key)
+
+                def requirement_sort_key(item):
+                    return (
+                        item.get("risk_level") or 0,
+                        item.get("weight") or 0,
+                    )
+
+                if existing is None or requirement_sort_key(
+                    requirement
+                ) > requirement_sort_key(existing):
+                    combined_critical_requirements[key] = deepcopy(requirement)
+
+        aggregated_section_scores = {}
+        for section, total in section_weighted_sums.items():
+            weight_total = section_weights[section]
+            if weight_total > 0:
+                aggregated_section_scores[section] = str(
+                    (total / weight_total).quantize(
+                        Decimal("0.01"), rounding=ROUND_HALF_UP
+                    )
+                )
+
+        aggregated_section_scores = dict(sorted(aggregated_section_scores.items()))
+
+        aggregated_critical_requirements = sorted(
+            combined_critical_requirements.values(),
+            key=lambda item: (
+                item.get("risk_level") or 0,
+                item.get("weight") or 0,
+            ),
+            reverse=True,
+        )
+
+        aggregated_snapshot = ThreatScoreSnapshot(
+            tenant_id=tenant_id,
+            scan=None,
+            provider=None,
+            compliance_id="prowler_threatscore_overview",
+            overall_score=overall_score,
+            score_delta=score_delta,
+            section_scores=aggregated_section_scores,
+            critical_requirements=aggregated_critical_requirements,
+            total_requirements=total_requirements,
+            passed_requirements=passed_requirements,
+            failed_requirements=failed_requirements,
+            manual_requirements=manual_requirements,
+            total_findings=total_findings,
+            passed_findings=passed_findings,
+            failed_findings=failed_findings,
+        )
+
+        latest_inserted_at = aggregated_metrics["latest_inserted_at"]
+        if latest_inserted_at is not None:
+            aggregated_snapshot.inserted_at = latest_inserted_at
+
+        aggregated_snapshot._aggregated = True
+
+        return aggregated_snapshot
+
 
 @extend_schema(tags=["Schedule"])
 @extend_schema_view(
@@ -3866,33 +4686,118 @@ class IntegrationViewSet(BaseRLSViewSet):
         )
 
 
+@extend_schema_view(
+    dispatches=extend_schema(
+        tags=["Integration"],
+        summary="Send findings to a Jira integration",
+        description="Send a set of filtered findings to the given integration. At least one finding filter must be "
+        "provided.",
+        responses={202: OpenApiResponse(response=TaskSerializer)},
+        filters=True,
+    )
+)
+class IntegrationJiraViewSet(BaseRLSViewSet):
+    queryset = Finding.all_objects.all()
+    serializer_class = IntegrationJiraDispatchSerializer
+    http_method_names = ["post"]
+    filter_backends = [CustomDjangoFilterBackend]
+    filterset_class = IntegrationJiraFindingsFilter
+    # RBAC required permissions
+    required_permissions = [Permissions.MANAGE_INTEGRATIONS]
+
+    @extend_schema(exclude=True)
+    def create(self, request, *args, **kwargs):
+        raise MethodNotAllowed(method="POST")
+
+    def get_queryset(self):
+        tenant_id = self.request.tenant_id
+        user_roles = get_role(self.request.user)
+        if user_roles.unlimited_visibility:
+            # User has unlimited visibility, return all findings
+            queryset = Finding.all_objects.filter(tenant_id=tenant_id)
+        else:
+            # User lacks permission, filter findings based on provider groups associated with the role
+            queryset = Finding.all_objects.filter(
+                scan__provider__in=get_providers(user_roles)
+            )
+
+        return queryset
+
+    @action(detail=False, methods=["post"], url_name="dispatches")
+    def dispatches(self, request, integration_pk=None):
+        get_object_or_404(Integration, pk=integration_pk)
+        serializer = self.get_serializer(
+            data=request.data, context={"integration_id": integration_pk}
+        )
+        serializer.is_valid(raise_exception=True)
+
+        if self.filter_queryset(self.get_queryset()).count() == 0:
+            raise ValidationError(
+                {"findings": "No findings match the provided filters"}
+            )
+
+        finding_ids = [
+            str(finding_id)
+            for finding_id in self.filter_queryset(self.get_queryset()).values_list(
+                "id", flat=True
+            )
+        ]
+        project_key = serializer.validated_data["project_key"]
+        issue_type = serializer.validated_data["issue_type"]
+
+        with transaction.atomic():
+            task = jira_integration_task.delay(
+                tenant_id=self.request.tenant_id,
+                integration_id=integration_pk,
+                project_key=project_key,
+                issue_type=issue_type,
+                finding_ids=finding_ids,
+            )
+        prowler_task = Task.objects.get(id=task.id)
+        serializer = TaskSerializer(prowler_task)
+        return Response(
+            data=serializer.data,
+            status=status.HTTP_202_ACCEPTED,
+            headers={
+                "Content-Location": reverse(
+                    "task-detail", kwargs={"pk": prowler_task.id}
+                )
+            },
+        )
+
+
 @extend_schema_view(
     list=extend_schema(
-        tags=["Lighthouse"],
-        summary="List all Lighthouse configurations",
-        description="Retrieve a list of all Lighthouse configurations.",
+        tags=["Lighthouse AI"],
+        summary="List all Lighthouse AI configurations",
+        description="Retrieve a list of all Lighthouse AI configurations.",
+        deprecated=True,
     ),
     create=extend_schema(
-        tags=["Lighthouse"],
-        summary="Create a new Lighthouse configuration",
-        description="Create a new Lighthouse configuration with the specified details.",
+        tags=["Lighthouse AI"],
+        summary="Create a new Lighthouse AI configuration",
+        description="Create a new Lighthouse AI configuration with the specified details.",
+        deprecated=True,
     ),
     partial_update=extend_schema(
-        tags=["Lighthouse"],
-        summary="Partially update a Lighthouse configuration",
-        description="Update certain fields of an existing Lighthouse configuration.",
+        tags=["Lighthouse AI"],
+        summary="Partially update a Lighthouse AI configuration",
+        description="Update certain fields of an existing Lighthouse AI configuration.",
+        deprecated=True,
     ),
     destroy=extend_schema(
-        tags=["Lighthouse"],
-        summary="Delete a Lighthouse configuration",
-        description="Remove a Lighthouse configuration by its ID.",
+        tags=["Lighthouse AI"],
+        summary="Delete a Lighthouse AI configuration",
+        description="Remove a Lighthouse AI configuration by its ID.",
+        deprecated=True,
     ),
     connection=extend_schema(
-        tags=["Lighthouse"],
+        tags=["Lighthouse AI"],
         summary="Check the connection to the OpenAI API",
-        description="Verify the connection to the OpenAI API for a specific Lighthouse configuration.",
+        description="Verify the connection to the OpenAI API for a specific Lighthouse AI configuration.",
         request=None,
         responses={202: OpenApiResponse(response=TaskSerializer)},
+        deprecated=True,
     ),
 )
 class LighthouseConfigViewSet(BaseRLSViewSet):
@@ -3943,6 +4848,255 @@ class LighthouseConfigViewSet(BaseRLSViewSet):
         )
 
 
+@extend_schema_view(
+    list=extend_schema(
+        tags=["Lighthouse AI"],
+        summary="List all LLM provider configurations",
+        description="Retrieve all LLM provider configurations for the current tenant",
+    ),
+    retrieve=extend_schema(
+        tags=["Lighthouse AI"],
+        summary="Retrieve LLM provider configuration",
+        description="Get details for a specific provider configuration in the current tenant.",
+    ),
+    create=extend_schema(
+        tags=["Lighthouse AI"],
+        summary="Create LLM provider configuration",
+        description="Create a per-tenant configuration for an LLM provider. Only one configuration per provider type "
+        "is allowed per tenant.",
+    ),
+    partial_update=extend_schema(
+        tags=["Lighthouse AI"],
+        summary="Update LLM provider configuration",
+        description="Partially update a provider configuration (e.g., base_url, is_active).",
+    ),
+    destroy=extend_schema(
+        tags=["Lighthouse AI"],
+        summary="Delete LLM provider configuration",
+        description="Delete a provider configuration. Any tenant defaults that reference this provider are cleared "
+        "during deletion.",
+    ),
+)
+class LighthouseProviderConfigViewSet(BaseRLSViewSet):
+    queryset = LighthouseProviderConfiguration.objects.all()
+    serializer_class = LighthouseProviderConfigSerializer
+    http_method_names = ["get", "post", "patch", "delete"]
+    filterset_class = LighthouseProviderConfigFilter
+
+    def get_queryset(self):
+        if getattr(self, "swagger_fake_view", False):
+            return LighthouseProviderConfiguration.objects.none()
+        return LighthouseProviderConfiguration.objects.filter(
+            tenant_id=self.request.tenant_id
+        )
+
+    def get_serializer_class(self):
+        if self.action == "create":
+            return LighthouseProviderConfigCreateSerializer
+        elif self.action == "partial_update":
+            return LighthouseProviderConfigUpdateSerializer
+        elif self.action in ["connection", "refresh_models"]:
+            return TaskSerializer
+        return super().get_serializer_class()
+
+    def create(self, request, *args, **kwargs):
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        instance = serializer.save()
+
+        read_serializer = LighthouseProviderConfigSerializer(
+            instance, context=self.get_serializer_context()
+        )
+        headers = self.get_success_headers(read_serializer.data)
+        return Response(
+            data=read_serializer.data,
+            status=status.HTTP_201_CREATED,
+            headers=headers,
+        )
+
+    def partial_update(self, request, *args, **kwargs):
+        instance = self.get_object()
+        serializer = self.get_serializer(
+            instance,
+            data=request.data,
+            partial=True,
+            context=self.get_serializer_context(),
+        )
+        serializer.is_valid(raise_exception=True)
+        serializer.save()
+        read_serializer = LighthouseProviderConfigSerializer(
+            instance, context=self.get_serializer_context()
+        )
+        return Response(data=read_serializer.data, status=status.HTTP_200_OK)
+
+    @extend_schema(
+        tags=["Lighthouse AI"],
+        summary="Check LLM provider connection",
+        description="Validate provider credentials asynchronously and toggle is_active.",
+        request=None,
+        responses={202: OpenApiResponse(response=TaskSerializer)},
+    )
+    @action(detail=True, methods=["post"], url_name="connection")
+    def connection(self, request, pk=None):
+        instance = self.get_object()
+
+        with transaction.atomic():
+            task = check_lighthouse_provider_connection_task.delay(
+                provider_config_id=str(instance.id), tenant_id=self.request.tenant_id
+            )
+
+        prowler_task = Task.objects.get(id=task.id)
+        serializer = TaskSerializer(prowler_task)
+        return Response(
+            data=serializer.data,
+            status=status.HTTP_202_ACCEPTED,
+            headers={
+                "Content-Location": reverse(
+                    "task-detail", kwargs={"pk": prowler_task.id}
+                )
+            },
+        )
+
+    @extend_schema(
+        tags=["Lighthouse AI"],
+        summary="Refresh LLM models catalog",
+        description="Fetch available models for this provider configuration and upsert into catalog. Supports OpenAI, OpenAI-compatible, and AWS Bedrock providers.",
+        request=None,
+        responses={202: OpenApiResponse(response=TaskSerializer)},
+    )
+    @action(
+        detail=True,
+        methods=["post"],
+        url_path="refresh-models",
+        url_name="refresh-models",
+    )
+    def refresh_models(self, request, pk=None):
+        instance = self.get_object()
+
+        with transaction.atomic():
+            task = refresh_lighthouse_provider_models_task.delay(
+                provider_config_id=str(instance.id), tenant_id=self.request.tenant_id
+            )
+
+        prowler_task = Task.objects.get(id=task.id)
+        serializer = TaskSerializer(prowler_task)
+        return Response(
+            data=serializer.data,
+            status=status.HTTP_202_ACCEPTED,
+            headers={
+                "Content-Location": reverse(
+                    "task-detail", kwargs={"pk": prowler_task.id}
+                )
+            },
+        )
+
+
+@extend_schema_view(
+    list=extend_schema(
+        tags=["Lighthouse AI"],
+        summary="Get Lighthouse AI Tenant config",
+        description="Retrieve current tenant-level Lighthouse AI settings. Returns a single configuration object.",
+    ),
+    partial_update=extend_schema(
+        tags=["Lighthouse AI"],
+        summary="Update Lighthouse AI Tenant config",
+        description="Update tenant-level settings. Validates that the default provider is configured and active and that default model IDs exist for the chosen providers. Auto-creates configuration if it doesn't exist.",
+    ),
+)
+class LighthouseTenantConfigViewSet(BaseRLSViewSet):
+    """
+    Singleton endpoint for tenant-level Lighthouse AI configuration.
+
+    This viewset implements a true singleton pattern:
+    - GET returns the single configuration object (or 404 if not found)
+    - PATCH updates/creates the configuration (upsert semantics)
+    - No ID is required in the URL
+    """
+
+    queryset = LighthouseTenantConfiguration.objects.all()
+    serializer_class = LighthouseTenantConfigSerializer
+    http_method_names = ["get", "patch"]
+
+    def get_queryset(self):
+        if getattr(self, "swagger_fake_view", False):
+            return LighthouseTenantConfiguration.objects.none()
+        return LighthouseTenantConfiguration.objects.filter(
+            tenant_id=self.request.tenant_id
+        )
+
+    def get_serializer_class(self):
+        if self.action == "partial_update":
+            return LighthouseTenantConfigUpdateSerializer
+        return super().get_serializer_class()
+
+    def get_object(self):
+        """Retrieve the singleton instance for the current tenant."""
+        obj = LighthouseTenantConfiguration.objects.filter(
+            tenant_id=self.request.tenant_id
+        ).first()
+        if obj is None:
+            raise NotFound("Tenant Lighthouse configuration not found")
+        self.check_object_permissions(self.request, obj)
+        return obj
+
+    def list(self, request, *args, **kwargs):
+        """GET endpoint for singleton - returns single object, not an array."""
+        instance = self.get_object()
+        serializer = self.get_serializer(instance)
+        return Response(serializer.data)
+
+    def partial_update(self, request, *args, **kwargs):
+        """PATCH endpoint for singleton - no pk required. Auto-creates if not exists."""
+        # Auto-create tenant config if it doesn't exist (upsert semantics)
+        instance, created = LighthouseTenantConfiguration.objects.get_or_create(
+            tenant_id=self.request.tenant_id,
+            defaults={},
+        )
+
+        # Extract attributes from JSON:API payload
+        try:
+            payload = json.loads(request.body)
+            attributes = payload.get("data", {}).get("attributes", {})
+        except (json.JSONDecodeError, AttributeError):
+            raise ValidationError("Invalid JSON:API payload")
+
+        serializer = self.get_serializer(instance, data=attributes, partial=True)
+        serializer.is_valid(raise_exception=True)
+        serializer.save()
+        read_serializer = LighthouseTenantConfigSerializer(
+            instance, context=self.get_serializer_context()
+        )
+        return Response(read_serializer.data, status=status.HTTP_200_OK)
+
+
+@extend_schema_view(
+    list=extend_schema(
+        tags=["Lighthouse AI"],
+        summary="List all LLM models",
+        description="List available LLM models per configured provider for the current tenant.",
+    ),
+    retrieve=extend_schema(
+        tags=["Lighthouse AI"],
+        summary="Retrieve LLM model details",
+        description="Get details for a specific LLM model.",
+    ),
+)
+class LighthouseProviderModelsViewSet(BaseRLSViewSet):
+    queryset = LighthouseProviderModels.objects.all()
+    serializer_class = LighthouseProviderModelsSerializer
+    filterset_class = LighthouseProviderModelsFilter
+    # Expose as read-only catalog collection
+    http_method_names = ["get"]
+
+    def get_queryset(self):
+        if getattr(self, "swagger_fake_view", False):
+            return LighthouseProviderModels.objects.none()
+        return LighthouseProviderModels.objects.filter(tenant_id=self.request.tenant_id)
+
+    def get_serializer_class(self):
+        return super().get_serializer_class()
+
+
 @extend_schema_view(
     list=extend_schema(
         tags=["Processor"],
@@ -3992,3 +5146,176 @@ class ProcessorViewSet(BaseRLSViewSet):
         elif self.action == "partial_update":
             return ProcessorUpdateSerializer
         return super().get_serializer_class()
+
+
+@extend_schema_view(
+    list=extend_schema(
+        tags=["API Keys"],
+        summary="List API keys",
+        description="Retrieve a list of API keys for the tenant, with filtering support.",
+    ),
+    retrieve=extend_schema(
+        tags=["API Keys"],
+        summary="Retrieve API key details",
+        description="Fetch detailed information about a specific API key by its ID.",
+    ),
+    create=extend_schema(
+        tags=["API Keys"],
+        summary="Create a new API key",
+        description="Create a new API key for the tenant.",
+    ),
+    partial_update=extend_schema(
+        tags=["API Keys"],
+        summary="Partially update an API key",
+        description="Modify certain fields of an existing API key without affecting other settings.",
+    ),
+    revoke=extend_schema(
+        tags=["API Keys"],
+        summary="Revoke an API key",
+        description="Revoke an API key by its ID. This action is irreversible and will prevent the key from being "
+        "used.",
+        request=None,
+        responses={
+            200: OpenApiResponse(
+                response=TenantApiKeySerializer,
+                description="API key was successfully revoked",
+            )
+        },
+    ),
+)
+class TenantApiKeyViewSet(BaseRLSViewSet):
+    queryset = TenantAPIKey.objects.all()
+    serializer_class = TenantApiKeySerializer
+    filterset_class = TenantApiKeyFilter
+    http_method_names = ["get", "post", "patch", "delete"]
+    ordering = ["revoked", "-created"]
+    ordering_fields = ["name", "prefix", "revoked", "inserted_at", "expires_at"]
+    # RBAC required permissions
+    required_permissions = [Permissions.MANAGE_ACCOUNT]
+
+    def get_queryset(self):
+        queryset = TenantAPIKey.objects.filter(
+            tenant_id=self.request.tenant_id
+        ).annotate(inserted_at=F("created"), expires_at=F("expiry_date"))
+        return queryset
+
+    def get_serializer_class(self):
+        if self.action == "create":
+            return TenantApiKeyCreateSerializer
+        elif self.action == "partial_update":
+            return TenantApiKeyUpdateSerializer
+        return super().get_serializer_class()
+
+    @extend_schema(exclude=True)
+    def destroy(self, request, *args, **kwargs):
+        raise MethodNotAllowed(method="DESTROY")
+
+    @action(detail=True, methods=["delete"])
+    def revoke(self, request, *args, **kwargs):
+        instance = self.get_object()
+
+        # Check if already revoked
+        if instance.revoked:
+            raise ValidationError(
+                {
+                    "detail": "API key is already revoked",
+                }
+            )
+
+        TenantAPIKey.objects.revoke_api_key(instance.pk)
+        instance.refresh_from_db()
+
+        serializer = self.get_serializer(instance)
+        return Response(data=serializer.data, status=status.HTTP_200_OK)
+
+
+# MuteRules
+@extend_schema_view(
+    list=extend_schema(
+        tags=["Mute Rules"],
+        summary="List all mute rules",
+        description="Retrieve a list of all mute rules with filtering options.",
+    ),
+    retrieve=extend_schema(
+        tags=["Mute Rules"],
+        summary="Retrieve a mute rule",
+        description="Fetch detailed information about a specific mute rule by ID.",
+    ),
+    create=extend_schema(
+        tags=["Mute Rules"],
+        summary="Create a new mute rule",
+        description="Create a new mute rule by providing finding IDs, name, and reason. "
+        "The rule will immediately mute the selected findings and launch a background task "
+        "to mute all historical findings with matching UIDs.",
+        request=MuteRuleCreateSerializer,
+    ),
+    partial_update=extend_schema(
+        tags=["Mute Rules"],
+        summary="Partially update a mute rule",
+        description="Update certain fields of an existing mute rule (e.g., name, reason, enabled).",
+        request=MuteRuleUpdateSerializer,
+        responses={200: MuteRuleSerializer},
+    ),
+    destroy=extend_schema(
+        tags=["Mute Rules"],
+        summary="Delete a mute rule",
+        description="Remove a mute rule from the system. Note: Previously muted findings remain muted.",
+    ),
+)
+class MuteRuleViewSet(BaseRLSViewSet):
+    queryset = MuteRule.objects.all()
+    serializer_class = MuteRuleSerializer
+    filterset_class = MuteRuleFilter
+    http_method_names = ["get", "post", "patch", "delete"]
+    search_fields = ["name", "reason"]
+    ordering = ["-inserted_at"]
+    ordering_fields = [
+        "name",
+        "enabled",
+        "inserted_at",
+        "updated_at",
+    ]
+    required_permissions = [Permissions.MANAGE_SCANS]
+
+    def get_queryset(self):
+        queryset = MuteRule.objects.filter(tenant_id=self.request.tenant_id)
+        return queryset.select_related("created_by")
+
+    def get_serializer_class(self):
+        if self.action == "create":
+            return MuteRuleCreateSerializer
+        elif self.action == "partial_update":
+            return MuteRuleUpdateSerializer
+        return super().get_serializer_class()
+
+    def create(self, request, *args, **kwargs):
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+
+        # Create the mute rule
+        mute_rule = serializer.save()
+
+        tenant_id = str(request.tenant_id)
+        finding_ids = request.data.get("finding_ids", [])
+
+        # Immediately mute the selected findings
+        Finding.all_objects.filter(
+            id__in=finding_ids, tenant_id=tenant_id, muted=False
+        ).update(
+            muted=True,
+            muted_at=mute_rule.inserted_at,
+            muted_reason=mute_rule.reason,
+        )
+
+        # Launch background task for historical muting
+        with transaction.atomic():
+            mute_historical_findings_task.apply_async(
+                kwargs={"tenant_id": tenant_id, "mute_rule_id": str(mute_rule.id)}
+            )
+
+        # Return the created mute rule
+        serializer = self.get_serializer(mute_rule)
+        return Response(
+            data=serializer.data,
+            status=status.HTTP_201_CREATED,
+        )
diff --git a/api/src/backend/config/custom_logging.py b/api/src/backend/config/custom_logging.py
index 83bc94f023..fb04930679 100644
--- a/api/src/backend/config/custom_logging.py
+++ b/api/src/backend/config/custom_logging.py
@@ -48,6 +48,10 @@ class NDJSONFormatter(logging.Formatter):
             log_record["user_id"] = record.user_id
         if hasattr(record, "tenant_id"):
             log_record["tenant_id"] = record.tenant_id
+        if hasattr(record, "api_key_prefix"):
+            log_record["api_key_prefix"] = (
+                record.api_key_prefix if record.api_key_prefix != "N/A" else None
+            )
         if hasattr(record, "method"):
             log_record["method"] = record.method
         if hasattr(record, "path"):
@@ -90,6 +94,9 @@ class HumanReadableFormatter(logging.Formatter):
         # Add REST API extra fields
         if hasattr(record, "user_id"):
             log_components.append(f"({record.user_id})")
+        if hasattr(record, "api_key_prefix"):
+            if record.api_key_prefix != "N/A":
+                log_components.append(f"(API-Key {record.api_key_prefix})")
         if hasattr(record, "tenant_id"):
             log_components.append(f"[{record.tenant_id}]")
         if hasattr(record, "method"):
diff --git a/api/src/backend/config/django/base.py b/api/src/backend/config/django/base.py
index 514dcfc6ff..80b96952d7 100644
--- a/api/src/backend/config/django/base.py
+++ b/api/src/backend/config/django/base.py
@@ -43,6 +43,7 @@ INSTALLED_APPS = [
     "allauth.socialaccount.providers.saml",
     "dj_rest_auth.registration",
     "rest_framework.authtoken",
+    "drf_simple_apikey",
 ]
 
 MIDDLEWARE = [
@@ -84,7 +85,7 @@ TEMPLATES = [
 REST_FRAMEWORK = {
     "DEFAULT_SCHEMA_CLASS": "drf_spectacular_jsonapi.schemas.openapi.JsonApiAutoSchema",
     "DEFAULT_AUTHENTICATION_CLASSES": (
-        "rest_framework_simplejwt.authentication.JWTAuthentication",
+        "api.authentication.CombinedJWTOrAPIKeyAuthentication",
     ),
     "PAGE_SIZE": 10,
     "EXCEPTION_HANDLER": "api.exceptions.custom_exception_handler",
@@ -108,6 +109,13 @@ REST_FRAMEWORK = {
     ),
     "TEST_REQUEST_DEFAULT_FORMAT": "vnd.api+json",
     "JSON_API_UNIFORM_EXCEPTIONS": True,
+    "DEFAULT_THROTTLE_CLASSES": [
+        "rest_framework.throttling.ScopedRateThrottle",
+    ],
+    "DEFAULT_THROTTLE_RATES": {
+        "token-obtain": env("DJANGO_THROTTLE_TOKEN_OBTAIN", default=None),
+        "dj_rest_auth": None,
+    },
 }
 
 SPECTACULAR_SETTINGS = {
@@ -116,6 +124,9 @@ SPECTACULAR_SETTINGS = {
     "PREPROCESSING_HOOKS": [
         "drf_spectacular_jsonapi.hooks.fix_nested_path_parameters",
     ],
+    "POSTPROCESSING_HOOKS": [
+        "api.schema_hooks.attach_task_202_examples",
+    ],
     "TITLE": "API Reference - Prowler",
 }
 
@@ -210,7 +221,8 @@ SIMPLE_JWT = {
     "JTI_CLAIM": "jti",
     "USER_ID_FIELD": "id",
     "USER_ID_CLAIM": "sub",
-    # Issuer and Audience claims, for the moment we will keep these values as default values, they may change in the future.
+    # Issuer and Audience claims, for the moment we will keep these values as default values, they may change in the
+    # future.
     "AUDIENCE": env.str("DJANGO_JWT_AUDIENCE", "https://api.prowler.com"),
     "ISSUER": env.str("DJANGO_JWT_ISSUER", "https://api.prowler.com"),
     # Additional security settings
@@ -219,6 +231,13 @@ SIMPLE_JWT = {
 
 SECRETS_ENCRYPTION_KEY = env.str("DJANGO_SECRETS_ENCRYPTION_KEY", "")
 
+# DRF Simple API Key settings
+DRF_API_KEY = {
+    "FERNET_SECRET": SECRETS_ENCRYPTION_KEY,
+    "API_KEY_LIFETIME": 365,
+    "AUTHENTICATION_KEYWORD_HEADER": "Api-Key",
+}
+
 # Internationalization
 # https://docs.djangoproject.com/en/5.0/topics/i18n/
 
diff --git a/api/src/backend/config/django/devel.py b/api/src/backend/config/django/devel.py
index 825e1ce36a..12c3c384c7 100644
--- a/api/src/backend/config/django/devel.py
+++ b/api/src/backend/config/django/devel.py
@@ -5,24 +5,39 @@ DEBUG = env.bool("DJANGO_DEBUG", default=True)
 ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=["*"])
 
 # Database
+default_db_name = env("POSTGRES_DB", default="prowler_db")
+default_db_user = env("POSTGRES_USER", default="prowler_user")
+default_db_password = env("POSTGRES_PASSWORD", default="prowler")
+default_db_host = env("POSTGRES_HOST", default="postgres-db")
+default_db_port = env("POSTGRES_PORT", default="5432")
+
 DATABASES = {
     "prowler_user": {
         "ENGINE": "psqlextra.backend",
-        "NAME": env("POSTGRES_DB", default="prowler_db"),
-        "USER": env("POSTGRES_USER", default="prowler_user"),
-        "PASSWORD": env("POSTGRES_PASSWORD", default="prowler"),
-        "HOST": env("POSTGRES_HOST", default="postgres-db"),
-        "PORT": env("POSTGRES_PORT", default="5432"),
+        "NAME": default_db_name,
+        "USER": default_db_user,
+        "PASSWORD": default_db_password,
+        "HOST": default_db_host,
+        "PORT": default_db_port,
     },
     "admin": {
         "ENGINE": "psqlextra.backend",
-        "NAME": env("POSTGRES_DB", default="prowler_db"),
+        "NAME": default_db_name,
         "USER": env("POSTGRES_ADMIN_USER", default="prowler"),
         "PASSWORD": env("POSTGRES_ADMIN_PASSWORD", default="S3cret"),
-        "HOST": env("POSTGRES_HOST", default="postgres-db"),
-        "PORT": env("POSTGRES_PORT", default="5432"),
+        "HOST": default_db_host,
+        "PORT": default_db_port,
+    },
+    "replica": {
+        "ENGINE": "psqlextra.backend",
+        "NAME": env("POSTGRES_REPLICA_DB", default=default_db_name),
+        "USER": env("POSTGRES_REPLICA_USER", default=default_db_user),
+        "PASSWORD": env("POSTGRES_REPLICA_PASSWORD", default=default_db_password),
+        "HOST": env("POSTGRES_REPLICA_HOST", default=default_db_host),
+        "PORT": env("POSTGRES_REPLICA_PORT", default=default_db_port),
     },
 }
+
 DATABASES["default"] = DATABASES["prowler_user"]
 
 REST_FRAMEWORK["DEFAULT_RENDERER_CLASSES"] = tuple(  # noqa: F405
diff --git a/api/src/backend/config/django/production.py b/api/src/backend/config/django/production.py
index 0f9479625c..5a4cc73044 100644
--- a/api/src/backend/config/django/production.py
+++ b/api/src/backend/config/django/production.py
@@ -6,22 +6,37 @@ ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=["localhost", "127.0.0.
 
 # Database
 # TODO Use Django database routers https://docs.djangoproject.com/en/5.0/topics/db/multi-db/#automatic-database-routing
+default_db_name = env("POSTGRES_DB")
+default_db_user = env("POSTGRES_USER")
+default_db_password = env("POSTGRES_PASSWORD")
+default_db_host = env("POSTGRES_HOST")
+default_db_port = env("POSTGRES_PORT")
+
 DATABASES = {
     "prowler_user": {
-        "ENGINE": "django.db.backends.postgresql",
-        "NAME": env("POSTGRES_DB"),
-        "USER": env("POSTGRES_USER"),
-        "PASSWORD": env("POSTGRES_PASSWORD"),
-        "HOST": env("POSTGRES_HOST"),
-        "PORT": env("POSTGRES_PORT"),
+        "ENGINE": "psqlextra.backend",
+        "NAME": default_db_name,
+        "USER": default_db_user,
+        "PASSWORD": default_db_password,
+        "HOST": default_db_host,
+        "PORT": default_db_port,
     },
     "admin": {
         "ENGINE": "psqlextra.backend",
-        "NAME": env("POSTGRES_DB"),
+        "NAME": default_db_name,
         "USER": env("POSTGRES_ADMIN_USER"),
         "PASSWORD": env("POSTGRES_ADMIN_PASSWORD"),
-        "HOST": env("POSTGRES_HOST"),
-        "PORT": env("POSTGRES_PORT"),
+        "HOST": default_db_host,
+        "PORT": default_db_port,
+    },
+    "replica": {
+        "ENGINE": "psqlextra.backend",
+        "NAME": env("POSTGRES_REPLICA_DB", default=default_db_name),
+        "USER": env("POSTGRES_REPLICA_USER", default=default_db_user),
+        "PASSWORD": env("POSTGRES_REPLICA_PASSWORD", default=default_db_password),
+        "HOST": env("POSTGRES_REPLICA_HOST", default=default_db_host),
+        "PORT": env("POSTGRES_REPLICA_PORT", default=default_db_port),
     },
 }
+
 DATABASES["default"] = DATABASES["prowler_user"]
diff --git a/api/src/backend/config/django/testing.py b/api/src/backend/config/django/testing.py
index d7f1f941ff..5289f067fa 100644
--- a/api/src/backend/config/django/testing.py
+++ b/api/src/backend/config/django/testing.py
@@ -20,6 +20,13 @@ DATABASE_ROUTERS = []
 TESTING = True
 SECRETS_ENCRYPTION_KEY = "ZMiYVo7m4Fbe2eXXPyrwxdJss2WSalXSv3xHBcJkPl0="
 
+# DRF Simple API Key settings
+DRF_API_KEY = {
+    "FERNET_SECRET": SECRETS_ENCRYPTION_KEY,
+    "API_KEY_LIFETIME": 365,
+    "AUTHENTICATION_KEYWORD_HEADER": "Api-Key",
+}
+
 # JWT
 
 SIMPLE_JWT["ALGORITHM"] = "HS256"  # noqa: F405
diff --git a/api/src/backend/config/urls.py b/api/src/backend/config/urls.py
index 195329d171..c307bcc310 100644
--- a/api/src/backend/config/urls.py
+++ b/api/src/backend/config/urls.py
@@ -1,7 +1,5 @@
-from django.contrib import admin
 from django.urls import include, path
 
 urlpatterns = [
-    path("admin/", admin.site.urls),
     path("api/v1/", include("api.v1.urls")),
 ]
diff --git a/api/src/backend/conftest.py b/api/src/backend/conftest.py
index fbbca7aea4..d5fa21a787 100644
--- a/api/src/backend/conftest.py
+++ b/api/src/backend/conftest.py
@@ -23,6 +23,7 @@ from api.models import (
     Invitation,
     LighthouseConfiguration,
     Membership,
+    MuteRule,
     Processor,
     Provider,
     ProviderGroup,
@@ -38,6 +39,7 @@ from api.models import (
     StateChoices,
     StatusChoices,
     Task,
+    TenantAPIKey,
     User,
     UserRoleRelationship,
 )
@@ -191,6 +193,108 @@ def create_test_user_rbac_limited(django_db_setup, django_db_blocker):
     return user
 
 
+@pytest.fixture(scope="function")
+def create_test_user_rbac_manage_account(django_db_setup, django_db_blocker):
+    """User with only manage_account permission (no manage_users)."""
+    with django_db_blocker.unblock():
+        user = User.objects.create_user(
+            name="testing_manage_account",
+            email="rbac_manage_account@rbac.com",
+            password=TEST_PASSWORD,
+        )
+        tenant = Tenant.objects.create(
+            name="Tenant Test Manage Account",
+        )
+        Membership.objects.create(
+            user=user,
+            tenant=tenant,
+            role=Membership.RoleChoices.OWNER,
+        )
+        role = Role.objects.create(
+            name="manage_account",
+            tenant_id=tenant.id,
+            manage_users=False,
+            manage_account=True,
+            manage_billing=False,
+            manage_providers=False,
+            manage_integrations=False,
+            manage_scans=False,
+            unlimited_visibility=False,
+        )
+        UserRoleRelationship.objects.create(
+            user=user,
+            role=role,
+            tenant_id=tenant.id,
+        )
+    return user
+
+
+@pytest.fixture
+def authenticated_client_rbac_manage_account(
+    create_test_user_rbac_manage_account, tenants_fixture, client
+):
+    client.user = create_test_user_rbac_manage_account
+    serializer = TokenSerializer(
+        data={
+            "type": "tokens",
+            "email": "rbac_manage_account@rbac.com",
+            "password": TEST_PASSWORD,
+        }
+    )
+    serializer.is_valid()
+    access_token = serializer.validated_data["access"]
+    client.defaults["HTTP_AUTHORIZATION"] = f"Bearer {access_token}"
+    return client
+
+
+@pytest.fixture(scope="function")
+def create_test_user_rbac_manage_users_only(django_db_setup, django_db_blocker):
+    """User with only manage_users permission (no manage_account)."""
+    with django_db_blocker.unblock():
+        user = User.objects.create_user(
+            name="testing_manage_users_only",
+            email="rbac_manage_users_only@rbac.com",
+            password=TEST_PASSWORD,
+        )
+        tenant = Tenant.objects.create(name="Tenant Test Manage Users Only")
+        Membership.objects.create(
+            user=user,
+            tenant=tenant,
+            role=Membership.RoleChoices.OWNER,
+        )
+        role = Role.objects.create(
+            name="manage_users_only",
+            tenant_id=tenant.id,
+            manage_users=True,
+            manage_account=False,
+            manage_billing=False,
+            manage_providers=False,
+            manage_integrations=False,
+            manage_scans=False,
+            unlimited_visibility=False,
+        )
+        UserRoleRelationship.objects.create(user=user, role=role, tenant_id=tenant.id)
+    return user
+
+
+@pytest.fixture
+def authenticated_client_rbac_manage_users_only(
+    create_test_user_rbac_manage_users_only, client
+):
+    client.user = create_test_user_rbac_manage_users_only
+    serializer = TokenSerializer(
+        data={
+            "type": "tokens",
+            "email": "rbac_manage_users_only@rbac.com",
+            "password": TEST_PASSWORD,
+        }
+    )
+    serializer.is_valid()
+    access_token = serializer.validated_data["access"]
+    client.defaults["HTTP_AUTHORIZATION"] = f"Bearer {access_token}"
+    return client
+
+
 @pytest.fixture
 def authenticated_client_rbac(create_test_user_rbac, tenants_fixture, client):
     client.user = create_test_user_rbac
@@ -396,8 +500,29 @@ def providers_fixture(tenants_fixture):
         alias="m365_testing",
         tenant_id=tenant.id,
     )
+    provider7 = Provider.objects.create(
+        provider="oraclecloud",
+        uid="ocid1.tenancy.oc1..aaaaaaaa3dwoazoox4q7wrvriywpokp5grlhgnkwtyt6dmwyou7no6mdmzda",
+        alias="oci_testing",
+        tenant_id=tenant.id,
+    )
+    provider8 = Provider.objects.create(
+        provider="mongodbatlas",
+        uid="64b1d3c0e4b03b1234567890",
+        alias="mongodbatlas_testing",
+        tenant_id=tenant.id,
+    )
 
-    return provider1, provider2, provider3, provider4, provider5, provider6
+    return (
+        provider1,
+        provider2,
+        provider3,
+        provider4,
+        provider5,
+        provider6,
+        provider7,
+        provider8,
+    )
 
 
 @pytest.fixture
@@ -1266,6 +1391,84 @@ def saml_sociallogin(users_fixture):
     return sociallogin
 
 
+@pytest.fixture
+def api_keys_fixture(tenants_fixture, create_test_user):
+    """Create test API keys for testing."""
+    tenant = tenants_fixture[0]
+    user = create_test_user
+
+    # Create and assign role to user for API key authentication
+    role = Role.objects.create(
+        tenant_id=tenant.id,
+        name="Test API Key Role",
+        unlimited_visibility=True,
+        manage_account=True,
+    )
+    UserRoleRelationship.objects.create(
+        user=user,
+        role=role,
+        tenant_id=tenant.id,
+    )
+
+    # Create API keys with different states
+    api_key1, raw_key1 = TenantAPIKey.objects.create_api_key(
+        name="Test API Key 1",
+        tenant_id=tenant.id,
+        entity=user,
+    )
+
+    api_key2, raw_key2 = TenantAPIKey.objects.create_api_key(
+        name="Test API Key 2",
+        tenant_id=tenant.id,
+        entity=user,
+        expiry_date=datetime.now(timezone.utc) + timedelta(days=60),
+    )
+
+    # Revoked API key
+    api_key3, raw_key3 = TenantAPIKey.objects.create_api_key(
+        name="Revoked API Key",
+        tenant_id=tenant.id,
+        entity=user,
+    )
+    api_key3.revoked = True
+    api_key3.save()
+
+    # Store raw keys on instances for testing
+    api_key1._raw_key = raw_key1
+    api_key2._raw_key = raw_key2
+    api_key3._raw_key = raw_key3
+
+    return [api_key1, api_key2, api_key3]
+
+
+@pytest.fixture
+def mute_rules_fixture(tenants_fixture, create_test_user, findings_fixture):
+    """Create test mute rules for testing."""
+    tenant = tenants_fixture[0]
+    user = create_test_user
+
+    # Create two mute rules: one enabled, one disabled
+    mute_rule1 = MuteRule.objects.create(
+        tenant_id=tenant.id,
+        name="Test Rule 1",
+        reason="Security exception for testing",
+        enabled=True,
+        created_by=user,
+        finding_uids=[findings_fixture[0].uid],
+    )
+
+    mute_rule2 = MuteRule.objects.create(
+        tenant_id=tenant.id,
+        name="Test Rule 2",
+        reason="Compliance exception approved",
+        enabled=False,
+        created_by=user,
+        finding_uids=[findings_fixture[1].uid],
+    )
+
+    return mute_rule1, mute_rule2
+
+
 def get_authorization_header(access_token: str) -> dict:
     return {"Authorization": f"Bearer {access_token}"}
 
diff --git a/api/src/backend/tasks/assets/fonts/FiraCode-Regular.ttf b/api/src/backend/tasks/assets/fonts/FiraCode-Regular.ttf
new file mode 100644
index 0000000000..3a57209a97
Binary files /dev/null and b/api/src/backend/tasks/assets/fonts/FiraCode-Regular.ttf differ
diff --git a/api/src/backend/tasks/assets/fonts/PlusJakartaSans-Regular.ttf b/api/src/backend/tasks/assets/fonts/PlusJakartaSans-Regular.ttf
new file mode 100644
index 0000000000..f43b5f4356
Binary files /dev/null and b/api/src/backend/tasks/assets/fonts/PlusJakartaSans-Regular.ttf differ
diff --git a/api/src/backend/tasks/assets/img/prowler_logo.png b/api/src/backend/tasks/assets/img/prowler_logo.png
new file mode 100644
index 0000000000..b9bdc4c088
Binary files /dev/null and b/api/src/backend/tasks/assets/img/prowler_logo.png differ
diff --git a/api/src/backend/tasks/jobs/backfill.py b/api/src/backend/tasks/jobs/backfill.py
index 6c83e6a69b..39fcd41fe1 100644
--- a/api/src/backend/tasks/jobs/backfill.py
+++ b/api/src/backend/tasks/jobs/backfill.py
@@ -1,5 +1,10 @@
+from collections import defaultdict
+
+from api.db_router import READ_REPLICA_ALIAS
 from api.db_utils import rls_transaction
 from api.models import (
+    ComplianceOverviewSummary,
+    ComplianceRequirementOverview,
     Resource,
     ResourceFindingMapping,
     ResourceScanSummary,
@@ -9,7 +14,7 @@ from api.models import (
 
 
 def backfill_resource_scan_summaries(tenant_id: str, scan_id: str):
-    with rls_transaction(tenant_id):
+    with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS):
         if ResourceScanSummary.objects.filter(
             tenant_id=tenant_id, scan_id=scan_id
         ).exists():
@@ -59,3 +64,114 @@ def backfill_resource_scan_summaries(tenant_id: str, scan_id: str):
             )
 
     return {"status": "backfilled", "inserted": len(summaries)}
+
+
+def backfill_compliance_summaries(tenant_id: str, scan_id: str):
+    """
+    Backfill ComplianceOverviewSummary records for a completed scan.
+
+    This function checks if summary records already exist for the scan.
+    If not, it aggregates compliance requirement data and creates the summaries.
+
+    Args:
+        tenant_id: Target tenant UUID
+        scan_id: Scan UUID to backfill
+
+    Returns:
+        dict: Status indicating whether backfill was performed
+    """
+    with rls_transaction(tenant_id):
+        if ComplianceOverviewSummary.objects.filter(
+            tenant_id=tenant_id, scan_id=scan_id
+        ).exists():
+            return {"status": "already backfilled"}
+
+    with rls_transaction(tenant_id):
+        if not Scan.objects.filter(
+            tenant_id=tenant_id,
+            id=scan_id,
+            state__in=(StateChoices.COMPLETED, StateChoices.FAILED),
+        ).exists():
+            return {"status": "scan is not completed"}
+
+        # Fetch all compliance requirement overview rows for this scan
+        requirement_rows = ComplianceRequirementOverview.objects.filter(
+            tenant_id=tenant_id, scan_id=scan_id
+        ).values(
+            "compliance_id",
+            "requirement_id",
+            "requirement_status",
+        )
+
+        if not requirement_rows:
+            return {"status": "no compliance data to backfill"}
+
+        # Group by (compliance_id, requirement_id) across regions
+        requirement_statuses = defaultdict(
+            lambda: {"fail_count": 0, "pass_count": 0, "total_count": 0}
+        )
+
+        for row in requirement_rows:
+            compliance_id = row["compliance_id"]
+            requirement_id = row["requirement_id"]
+            requirement_status = row["requirement_status"]
+
+            # Aggregate requirement status across regions
+            key = (compliance_id, requirement_id)
+            requirement_statuses[key]["total_count"] += 1
+
+            if requirement_status == "FAIL":
+                requirement_statuses[key]["fail_count"] += 1
+            elif requirement_status == "PASS":
+                requirement_statuses[key]["pass_count"] += 1
+
+        # Determine per-requirement status and aggregate to compliance level
+        compliance_summaries = defaultdict(
+            lambda: {
+                "total_requirements": 0,
+                "requirements_passed": 0,
+                "requirements_failed": 0,
+                "requirements_manual": 0,
+            }
+        )
+
+        for (compliance_id, requirement_id), counts in requirement_statuses.items():
+            # Apply business rule: any FAIL → requirement fails
+            if counts["fail_count"] > 0:
+                req_status = "FAIL"
+            elif counts["pass_count"] == counts["total_count"]:
+                req_status = "PASS"
+            else:
+                req_status = "MANUAL"
+
+            # Aggregate to compliance level
+            compliance_summaries[compliance_id]["total_requirements"] += 1
+            if req_status == "PASS":
+                compliance_summaries[compliance_id]["requirements_passed"] += 1
+            elif req_status == "FAIL":
+                compliance_summaries[compliance_id]["requirements_failed"] += 1
+            else:
+                compliance_summaries[compliance_id]["requirements_manual"] += 1
+
+        # Create summary objects
+        summary_objects = []
+        for compliance_id, data in compliance_summaries.items():
+            summary_objects.append(
+                ComplianceOverviewSummary(
+                    tenant_id=tenant_id,
+                    scan_id=scan_id,
+                    compliance_id=compliance_id,
+                    requirements_passed=data["requirements_passed"],
+                    requirements_failed=data["requirements_failed"],
+                    requirements_manual=data["requirements_manual"],
+                    total_requirements=data["total_requirements"],
+                )
+            )
+
+        # Bulk insert summaries
+        if summary_objects:
+            ComplianceOverviewSummary.objects.bulk_create(
+                summary_objects, batch_size=500, ignore_conflicts=True
+            )
+
+    return {"status": "backfilled", "inserted": len(summary_objects)}
diff --git a/api/src/backend/tasks/jobs/export.py b/api/src/backend/tasks/jobs/export.py
index 441b7a95d4..a3aee7bfc9 100644
--- a/api/src/backend/tasks/jobs/export.py
+++ b/api/src/backend/tasks/jobs/export.py
@@ -20,12 +20,19 @@ from prowler.lib.outputs.asff.asff import ASFF
 from prowler.lib.outputs.compliance.aws_well_architected.aws_well_architected import (
     AWSWellArchitected,
 )
+from prowler.lib.outputs.compliance.c5.c5_aws import AWSC5
+from prowler.lib.outputs.compliance.c5.c5_azure import AzureC5
+from prowler.lib.outputs.compliance.c5.c5_gcp import GCPC5
+from prowler.lib.outputs.compliance.ccc.ccc_aws import CCC_AWS
+from prowler.lib.outputs.compliance.ccc.ccc_azure import CCC_Azure
+from prowler.lib.outputs.compliance.ccc.ccc_gcp import CCC_GCP
 from prowler.lib.outputs.compliance.cis.cis_aws import AWSCIS
 from prowler.lib.outputs.compliance.cis.cis_azure import AzureCIS
 from prowler.lib.outputs.compliance.cis.cis_gcp import GCPCIS
 from prowler.lib.outputs.compliance.cis.cis_github import GithubCIS
 from prowler.lib.outputs.compliance.cis.cis_kubernetes import KubernetesCIS
 from prowler.lib.outputs.compliance.cis.cis_m365 import M365CIS
+from prowler.lib.outputs.compliance.cis.cis_oraclecloud import OracleCloudCIS
 from prowler.lib.outputs.compliance.ens.ens_aws import AWSENS
 from prowler.lib.outputs.compliance.ens.ens_azure import AzureENS
 from prowler.lib.outputs.compliance.ens.ens_gcp import GCPENS
@@ -73,13 +80,17 @@ COMPLIANCE_CLASS_MAP = {
         (lambda name: name.startswith("iso27001_"), AWSISO27001),
         (lambda name: name.startswith("kisa"), AWSKISAISMSP),
         (lambda name: name == "prowler_threatscore_aws", ProwlerThreatScoreAWS),
+        (lambda name: name == "ccc_aws", CCC_AWS),
+        (lambda name: name.startswith("c5_"), AWSC5),
     ],
     "azure": [
         (lambda name: name.startswith("cis_"), AzureCIS),
         (lambda name: name == "mitre_attack_azure", AzureMitreAttack),
         (lambda name: name.startswith("ens_"), AzureENS),
         (lambda name: name.startswith("iso27001_"), AzureISO27001),
+        (lambda name: name == "ccc_azure", CCC_Azure),
         (lambda name: name == "prowler_threatscore_azure", ProwlerThreatScoreAzure),
+        (lambda name: name == "c5_azure", AzureC5),
     ],
     "gcp": [
         (lambda name: name.startswith("cis_"), GCPCIS),
@@ -87,6 +98,8 @@ COMPLIANCE_CLASS_MAP = {
         (lambda name: name.startswith("ens_"), GCPENS),
         (lambda name: name.startswith("iso27001_"), GCPISO27001),
         (lambda name: name == "prowler_threatscore_gcp", ProwlerThreatScoreGCP),
+        (lambda name: name == "ccc_gcp", CCC_GCP),
+        (lambda name: name == "c5_gcp", GCPC5),
     ],
     "kubernetes": [
         (lambda name: name.startswith("cis_"), KubernetesCIS),
@@ -100,6 +113,13 @@ COMPLIANCE_CLASS_MAP = {
     "github": [
         (lambda name: name.startswith("cis_"), GithubCIS),
     ],
+    "iac": [
+        # IaC provider doesn't have specific compliance frameworks yet
+        # Trivy handles its own compliance checks
+    ],
+    "oraclecloud": [
+        (lambda name: name.startswith("cis_"), OracleCloudCIS),
+    ],
 }
 
 
@@ -175,18 +195,21 @@ def get_s3_client():
     return s3_client
 
 
-def _upload_to_s3(tenant_id: str, zip_path: str, scan_id: str) -> str | None:
+def _upload_to_s3(
+    tenant_id: str, scan_id: str, local_path: str, relative_key: str
+) -> str | None:
     """
-    Upload the specified ZIP file to an S3 bucket.
-    If the S3 bucket environment variables are not configured,
-    the function returns None without performing an upload.
+    Upload a local artifact to an S3 bucket under the tenant/scan prefix.
+
     Args:
-        tenant_id (str): The tenant identifier, used as part of the S3 key prefix.
-        zip_path (str): The local file system path to the ZIP file to be uploaded.
-        scan_id (str): The scan identifier, used as part of the S3 key prefix.
+        tenant_id (str): The tenant identifier used as the first segment of the S3 key.
+        scan_id (str): The scan identifier used as the second segment of the S3 key.
+        local_path (str): Filesystem path to the artifact to upload.
+        relative_key (str): Object key relative to `//`.
+
     Returns:
-        str: The S3 URI of the uploaded file (e.g., "s3:///") if successful.
-        None: If the required environment variables for the S3 bucket are not set.
+        str | None: S3 URI of the uploaded artifact, or None if the upload is skipped.
+
     Raises:
         botocore.exceptions.ClientError: If the upload attempt to S3 fails for any reason.
     """
@@ -194,34 +217,26 @@ def _upload_to_s3(tenant_id: str, zip_path: str, scan_id: str) -> str | None:
     if not bucket:
         return
 
+    if not relative_key:
+        return
+
+    if not os.path.isfile(local_path):
+        return
+
     try:
         s3 = get_s3_client()
 
-        # Upload the ZIP file (outputs) to the S3 bucket
-        zip_key = f"{tenant_id}/{scan_id}/{os.path.basename(zip_path)}"
-        s3.upload_file(
-            Filename=zip_path,
-            Bucket=bucket,
-            Key=zip_key,
-        )
+        s3_key = f"{tenant_id}/{scan_id}/{relative_key}"
+        s3.upload_file(Filename=local_path, Bucket=bucket, Key=s3_key)
 
-        # Upload the compliance directory to the S3 bucket
-        compliance_dir = os.path.join(os.path.dirname(zip_path), "compliance")
-        for filename in os.listdir(compliance_dir):
-            local_path = os.path.join(compliance_dir, filename)
-            if not os.path.isfile(local_path):
-                continue
-            file_key = f"{tenant_id}/{scan_id}/compliance/{filename}"
-            s3.upload_file(Filename=local_path, Bucket=bucket, Key=file_key)
-
-        return f"s3://{base.DJANGO_OUTPUT_S3_AWS_OUTPUT_BUCKET}/{zip_key}"
+        return f"s3://{base.DJANGO_OUTPUT_S3_AWS_OUTPUT_BUCKET}/{s3_key}"
     except (ClientError, NoCredentialsError, ParamValidationError, ValueError) as e:
         logger.error(f"S3 upload failed: {str(e)}")
 
 
 def _generate_output_directory(
     output_directory, prowler_provider: object, tenant_id: str, scan_id: str
-) -> tuple[str, str]:
+) -> tuple[str, str, str]:
     """
     Generate a file system path for the output directory of a prowler scan.
 
@@ -248,6 +263,7 @@ def _generate_output_directory(
         >>> _generate_output_directory("/tmp", "aws", "tenant-1234", "scan-5678")
         '/tmp/tenant-1234/aws/scan-5678/prowler-output-2023-02-15T12:34:56',
         '/tmp/tenant-1234/aws/scan-5678/compliance/prowler-output-2023-02-15T12:34:56'
+        '/tmp/tenant-1234/aws/scan-5678/threatscore/prowler-output-2023-02-15T12:34:56'
     """
     # Sanitize the prowler provider name to ensure it is a valid directory name
     prowler_provider_sanitized = re.sub(r"[^\w\-]", "-", prowler_provider)
@@ -268,4 +284,10 @@ def _generate_output_directory(
     )
     os.makedirs("/".join(compliance_path.split("/")[:-1]), exist_ok=True)
 
-    return path, compliance_path
+    threatscore_path = (
+        f"{output_directory}/{tenant_id}/{scan_id}/threatscore/prowler-output-"
+        f"{prowler_provider_sanitized}-{timestamp}"
+    )
+    os.makedirs("/".join(threatscore_path.split("/")[:-1]), exist_ok=True)
+
+    return path, compliance_path, threatscore_path
diff --git a/api/src/backend/tasks/jobs/integrations.py b/api/src/backend/tasks/jobs/integrations.py
index 5cc25d09a8..71d2185deb 100644
--- a/api/src/backend/tasks/jobs/integrations.py
+++ b/api/src/backend/tasks/jobs/integrations.py
@@ -5,9 +5,10 @@ from celery.utils.log import get_task_logger
 from config.django.base import DJANGO_FINDINGS_BATCH_SIZE
 from tasks.utils import batched
 
+from api.db_router import READ_REPLICA_ALIAS, MainRouter
 from api.db_utils import rls_transaction
 from api.models import Finding, Integration, Provider
-from api.utils import initialize_prowler_provider
+from api.utils import initialize_prowler_integration, initialize_prowler_provider
 from prowler.lib.outputs.asff.asff import ASFF
 from prowler.lib.outputs.compliance.generic.generic import GenericCompliance
 from prowler.lib.outputs.csv.csv import CSV
@@ -178,7 +179,7 @@ def get_security_hub_client_from_integration(
         if the connection was successful and the SecurityHub client or connection object.
     """
     # Get the provider associated with this integration
-    with rls_transaction(tenant_id):
+    with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS):
         provider_relationship = integration.integrationproviderrelationship_set.first()
         if not provider_relationship:
             return Connection(
@@ -207,7 +208,7 @@ def get_security_hub_client_from_integration(
             regions_status[region] = region in connection.enabled_regions
 
         # Save regions information in the integration configuration
-        with rls_transaction(tenant_id):
+        with rls_transaction(tenant_id, using=MainRouter.default_db):
             integration.configuration["regions"] = regions_status
             integration.save()
 
@@ -220,6 +221,11 @@ def get_security_hub_client_from_integration(
             **credentials,
         )
         return True, security_hub
+    else:
+        # Reset regions information if connection fails
+        with rls_transaction(tenant_id, using=MainRouter.default_db):
+            integration.configuration["regions"] = {}
+            integration.save()
 
     return False, connection
 
@@ -284,7 +290,7 @@ def upload_security_hub_integration(
                 has_findings = False
                 batch_number = 0
 
-                with rls_transaction(tenant_id):
+                with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS):
                     qs = (
                         Finding.all_objects.filter(tenant_id=tenant_id, scan_id=scan_id)
                         .order_by("uid")
@@ -325,15 +331,20 @@ def upload_security_hub_integration(
 
                                 if not connected:
                                     logger.error(
-                                        f"Security Hub connection failed for integration {integration.id}: {security_hub.error}"
+                                        f"Security Hub connection failed for integration {integration.id}: "
+                                        f"{security_hub.error}"
                                     )
-                                    integration.connected = False
-                                    integration.save()
+                                    with rls_transaction(
+                                        tenant_id, using=MainRouter.default_db
+                                    ):
+                                        integration.connected = False
+                                        integration.save()
                                     break  # Skip this integration
 
                                 security_hub_client = security_hub
                                 logger.info(
-                                    f"Sending {'fail' if send_only_fails else 'all'} findings to Security Hub via integration {integration.id}"
+                                    f"Sending {'fail' if send_only_fails else 'all'} findings to Security Hub via "
+                                    f"integration {integration.id}"
                                 )
                             else:
                                 # Update findings in existing client for this batch
@@ -422,3 +433,78 @@ def upload_security_hub_integration(
             f"Security Hub integrations failed for provider {provider_id}: {str(e)}"
         )
         return False
+
+
+def send_findings_to_jira(
+    tenant_id: str,
+    integration_id: str,
+    project_key: str,
+    issue_type: str,
+    finding_ids: list[str],
+):
+    with rls_transaction(tenant_id):
+        integration = Integration.objects.get(id=integration_id)
+        jira_integration = initialize_prowler_integration(integration)
+
+    num_tickets_created = 0
+    for finding_id in finding_ids:
+        with rls_transaction(tenant_id):
+            finding_instance = (
+                Finding.all_objects.select_related("scan__provider")
+                .prefetch_related("resources")
+                .get(id=finding_id)
+            )
+
+            # Extract resource information
+            resource = (
+                finding_instance.resources.first()
+                if finding_instance.resources.exists()
+                else None
+            )
+            resource_uid = resource.uid if resource else ""
+            resource_name = resource.name if resource else ""
+            resource_tags = {}
+            if resource and hasattr(resource, "tags"):
+                resource_tags = resource.get_tags(tenant_id)
+
+            # Get region
+            region = resource.region if resource and resource.region else ""
+
+            # Extract remediation information from check_metadata
+            check_metadata = finding_instance.check_metadata
+            remediation = check_metadata.get("remediation", {})
+            recommendation = remediation.get("recommendation", {})
+            remediation_code = remediation.get("code", {})
+
+            # Send the individual finding to Jira
+            result = jira_integration.send_finding(
+                check_id=finding_instance.check_id,
+                check_title=check_metadata.get("checktitle", ""),
+                severity=finding_instance.severity,
+                status=finding_instance.status,
+                status_extended=finding_instance.status_extended or "",
+                provider=finding_instance.scan.provider.provider,
+                region=region,
+                resource_uid=resource_uid,
+                resource_name=resource_name,
+                risk=check_metadata.get("risk", ""),
+                recommendation_text=recommendation.get("text", ""),
+                recommendation_url=recommendation.get("url", ""),
+                remediation_code_native_iac=remediation_code.get("nativeiac", ""),
+                remediation_code_terraform=remediation_code.get("terraform", ""),
+                remediation_code_cli=remediation_code.get("cli", ""),
+                remediation_code_other=remediation_code.get("other", ""),
+                resource_tags=resource_tags,
+                compliance=finding_instance.compliance or {},
+                project_key=project_key,
+                issue_type=issue_type,
+            )
+            if result:
+                num_tickets_created += 1
+            else:
+                logger.error(f"Failed to send finding {finding_id} to Jira")
+
+    return {
+        "created_count": num_tickets_created,
+        "failed_count": len(finding_ids) - num_tickets_created,
+    }
diff --git a/api/src/backend/tasks/jobs/lighthouse_providers.py b/api/src/backend/tasks/jobs/lighthouse_providers.py
new file mode 100644
index 0000000000..53f9e4dd97
--- /dev/null
+++ b/api/src/backend/tasks/jobs/lighthouse_providers.py
@@ -0,0 +1,452 @@
+from typing import Dict
+
+import boto3
+import openai
+from botocore.exceptions import BotoCoreError, ClientError
+from celery.utils.log import get_task_logger
+
+from api.models import LighthouseProviderConfiguration, LighthouseProviderModels
+
+logger = get_task_logger(__name__)
+
+
+def _extract_openai_api_key(
+    provider_cfg: LighthouseProviderConfiguration,
+) -> str | None:
+    """
+    Safely extract the OpenAI API key from a provider configuration.
+
+    Args:
+        provider_cfg (LighthouseProviderConfiguration): The provider configuration instance
+            containing the credentials.
+
+    Returns:
+        str | None: The API key string if present and valid, otherwise None.
+    """
+    creds = provider_cfg.credentials_decoded
+    if not isinstance(creds, dict):
+        return None
+    api_key = creds.get("api_key")
+    if not isinstance(api_key, str) or not api_key:
+        return None
+    return api_key
+
+
+def _extract_openai_compatible_params(
+    provider_cfg: LighthouseProviderConfiguration,
+) -> Dict[str, str] | None:
+    """
+    Extract base_url and api_key for OpenAI-compatible providers.
+    """
+    creds = provider_cfg.credentials_decoded
+    base_url = provider_cfg.base_url
+    if not isinstance(creds, dict):
+        return None
+    api_key = creds.get("api_key")
+    if not isinstance(api_key, str) or not api_key:
+        return None
+    if not isinstance(base_url, str) or not base_url:
+        return None
+    return {"base_url": base_url, "api_key": api_key}
+
+
+def _extract_bedrock_credentials(
+    provider_cfg: LighthouseProviderConfiguration,
+) -> Dict[str, str] | None:
+    """
+    Safely extract AWS Bedrock credentials from a provider configuration.
+
+    Args:
+        provider_cfg (LighthouseProviderConfiguration): The provider configuration instance
+            containing the credentials.
+
+    Returns:
+        Dict[str, str] | None: Dictionary with 'access_key_id', 'secret_access_key', and
+            'region' if present and valid, otherwise None.
+    """
+    creds = provider_cfg.credentials_decoded
+    if not isinstance(creds, dict):
+        return None
+
+    access_key_id = creds.get("access_key_id")
+    secret_access_key = creds.get("secret_access_key")
+    region = creds.get("region")
+
+    # Validate all required fields are present and are strings
+    if (
+        not isinstance(access_key_id, str)
+        or not access_key_id
+        or not isinstance(secret_access_key, str)
+        or not secret_access_key
+        or not isinstance(region, str)
+        or not region
+    ):
+        return None
+
+    return {
+        "access_key_id": access_key_id,
+        "secret_access_key": secret_access_key,
+        "region": region,
+    }
+
+
+def check_lighthouse_provider_connection(provider_config_id: str) -> Dict:
+    """
+    Validate a Lighthouse provider configuration by calling the provider API and
+    toggle its active state accordingly.
+
+    Args:
+        provider_config_id: The primary key of the `LighthouseProviderConfiguration`
+            to validate.
+
+    Returns:
+        dict: A result dictionary with the following keys:
+            - "connected" (bool): Whether the provider credentials are valid.
+            - "error" (str | None): The error message when not connected, otherwise None.
+
+    Side Effects:
+        - Updates and persists `is_active` on the `LighthouseProviderConfiguration`.
+
+    Raises:
+        LighthouseProviderConfiguration.DoesNotExist: If no configuration exists with the given ID.
+    """
+    provider_cfg = LighthouseProviderConfiguration.objects.get(pk=provider_config_id)
+
+    try:
+        if (
+            provider_cfg.provider_type
+            == LighthouseProviderConfiguration.LLMProviderChoices.OPENAI
+        ):
+            api_key = _extract_openai_api_key(provider_cfg)
+            if not api_key:
+                provider_cfg.is_active = False
+                provider_cfg.save()
+                return {"connected": False, "error": "API key is invalid or missing"}
+
+            # Test connection by listing models
+            client = openai.OpenAI(api_key=api_key)
+            _ = client.models.list()
+
+        elif (
+            provider_cfg.provider_type
+            == LighthouseProviderConfiguration.LLMProviderChoices.BEDROCK
+        ):
+            bedrock_creds = _extract_bedrock_credentials(provider_cfg)
+            if not bedrock_creds:
+                provider_cfg.is_active = False
+                provider_cfg.save()
+                return {
+                    "connected": False,
+                    "error": "AWS credentials are invalid or missing",
+                }
+
+            # Test connection by listing foundation models
+            bedrock_client = boto3.client(
+                "bedrock",
+                aws_access_key_id=bedrock_creds["access_key_id"],
+                aws_secret_access_key=bedrock_creds["secret_access_key"],
+                region_name=bedrock_creds["region"],
+            )
+            _ = bedrock_client.list_foundation_models()
+
+        elif (
+            provider_cfg.provider_type
+            == LighthouseProviderConfiguration.LLMProviderChoices.OPENAI_COMPATIBLE
+        ):
+            params = _extract_openai_compatible_params(provider_cfg)
+            if not params:
+                provider_cfg.is_active = False
+                provider_cfg.save()
+                return {
+                    "connected": False,
+                    "error": "Base URL or API key is invalid or missing",
+                }
+
+            # Test connection using OpenAI SDK with custom base_url
+            # Note: base_url should include version (e.g., https://openrouter.ai/api/v1)
+            client = openai.OpenAI(
+                api_key=params["api_key"],
+                base_url=params["base_url"],
+            )
+            _ = client.models.list()
+
+        else:
+            return {"connected": False, "error": "Unsupported provider type"}
+
+        # Connection successful
+        provider_cfg.is_active = True
+        provider_cfg.save()
+        return {"connected": True, "error": None}
+
+    except Exception as e:
+        logger.warning(
+            "%s connection check failed: %s", provider_cfg.provider_type, str(e)
+        )
+        provider_cfg.is_active = False
+        provider_cfg.save()
+        return {"connected": False, "error": str(e)}
+
+
+def _fetch_openai_models(api_key: str) -> Dict[str, str]:
+    """
+    Fetch available models from OpenAI API.
+
+    Args:
+        api_key: OpenAI API key for authentication.
+
+    Returns:
+        Dict mapping model_id to model_name. For OpenAI, both are the same
+        as the API doesn't provide separate display names.
+
+    Raises:
+        Exception: If the API call fails.
+    """
+    client = openai.OpenAI(api_key=api_key)
+    models = client.models.list()
+    # OpenAI uses model.id for both ID and display name
+    return {m.id: m.id for m in getattr(models, "data", [])}
+
+
+def _fetch_openai_compatible_models(base_url: str, api_key: str) -> Dict[str, str]:
+    """
+    Fetch available models from an OpenAI-compatible API using the OpenAI SDK.
+
+    Returns a mapping of model_id -> model_name. Prefers the 'name' attribute
+    if available (e.g., from OpenRouter), otherwise falls back to 'id'.
+
+    Note: base_url should include version (e.g., https://openrouter.ai/api/v1)
+    """
+    client = openai.OpenAI(api_key=api_key, base_url=base_url)
+    models = client.models.list()
+
+    available_models: Dict[str, str] = {}
+    for model in models.data:
+        model_id = model.id
+        # Prefer provider-supplied human-friendly name when available
+        name = getattr(model, "name", None)
+        if name:
+            available_models[model_id] = name
+        else:
+            available_models[model_id] = model_id
+
+    return available_models
+
+
+def _fetch_bedrock_models(bedrock_creds: Dict[str, str]) -> Dict[str, str]:
+    """
+    Fetch available models from AWS Bedrock with entitlement verification.
+
+    This function:
+    1. Lists foundation models with TEXT modality support
+    2. Lists inference profiles with TEXT modality support
+    3. Verifies user has entitlement access to each model
+
+    Args:
+        bedrock_creds: Dictionary with 'access_key_id', 'secret_access_key', and 'region'.
+
+    Returns:
+        Dict mapping model_id to model_name for all accessible models.
+
+    Raises:
+        BotoCoreError, ClientError: If AWS API calls fail.
+    """
+    bedrock_client = boto3.client(
+        "bedrock",
+        aws_access_key_id=bedrock_creds["access_key_id"],
+        aws_secret_access_key=bedrock_creds["secret_access_key"],
+        region_name=bedrock_creds["region"],
+    )
+
+    models_to_check: Dict[str, str] = {}
+
+    # Step 1: Get foundation models with TEXT modality
+    foundation_response = bedrock_client.list_foundation_models()
+    model_summaries = foundation_response.get("modelSummaries", [])
+
+    for model in model_summaries:
+        # Check if model supports TEXT input and output modality
+        input_modalities = model.get("inputModalities", [])
+        output_modalities = model.get("outputModalities", [])
+
+        if "TEXT" not in input_modalities or "TEXT" not in output_modalities:
+            continue
+
+        model_id = model.get("modelId")
+        if not model_id:
+            continue
+
+        inference_types = model.get("inferenceTypesSupported", [])
+
+        # Only include models with ON_DEMAND inference support
+        if "ON_DEMAND" in inference_types:
+            models_to_check[model_id] = model["modelName"]
+
+    # Step 2: Get inference profiles
+    try:
+        inference_profiles_response = bedrock_client.list_inference_profiles()
+        inference_profiles = inference_profiles_response.get(
+            "inferenceProfileSummaries", []
+        )
+
+        for profile in inference_profiles:
+            # Check if profile supports TEXT modality
+            input_modalities = profile.get("inputModalities", [])
+            output_modalities = profile.get("outputModalities", [])
+
+            if "TEXT" not in input_modalities or "TEXT" not in output_modalities:
+                continue
+
+            profile_id = profile.get("inferenceProfileId")
+            if profile_id:
+                models_to_check[profile_id] = profile["inferenceProfileName"]
+
+    except (BotoCoreError, ClientError) as e:
+        logger.info(
+            "Could not fetch inference profiles in %s: %s",
+            bedrock_creds["region"],
+            str(e),
+        )
+
+    # Step 3: Verify entitlement availability for each model
+    available_models: Dict[str, str] = {}
+
+    for model_id, model_name in models_to_check.items():
+        try:
+            availability = bedrock_client.get_foundation_model_availability(
+                modelId=model_id
+            )
+
+            entitlement = availability.get("entitlementAvailability")
+
+            # Only include models user has access to
+            if entitlement == "AVAILABLE":
+                available_models[model_id] = model_name
+            else:
+                logger.debug(
+                    "Skipping model %s - entitlement status: %s", model_id, entitlement
+                )
+
+        except (BotoCoreError, ClientError) as e:
+            logger.debug(
+                "Could not check availability for model %s: %s", model_id, str(e)
+            )
+            continue
+
+    return available_models
+
+
+def refresh_lighthouse_provider_models(provider_config_id: str) -> Dict:
+    """
+    Refresh the catalog of models for a Lighthouse provider configuration.
+
+    Fetches the current list of models from the provider, upserts entries into
+    `LighthouseProviderModels`, and deletes stale entries no longer returned.
+
+    Args:
+        provider_config_id: The primary key of the `LighthouseProviderConfiguration`
+            whose models should be refreshed.
+
+    Returns:
+        dict: A result dictionary with the following keys on success:
+            - "created" (int): Number of new model rows created.
+            - "updated" (int): Number of existing model rows updated.
+            - "deleted" (int): Number of stale model rows removed.
+        If an error occurs, the dictionary will contain an "error" (str) field instead.
+
+    Raises:
+        LighthouseProviderConfiguration.DoesNotExist: If no configuration exists with the given ID.
+    """
+    provider_cfg = LighthouseProviderConfiguration.objects.get(pk=provider_config_id)
+    fetched_models: Dict[str, str] = {}
+
+    # Fetch models from the appropriate provider
+    try:
+        if (
+            provider_cfg.provider_type
+            == LighthouseProviderConfiguration.LLMProviderChoices.OPENAI
+        ):
+            api_key = _extract_openai_api_key(provider_cfg)
+            if not api_key:
+                return {
+                    "created": 0,
+                    "updated": 0,
+                    "deleted": 0,
+                    "error": "API key is invalid or missing",
+                }
+            fetched_models = _fetch_openai_models(api_key)
+
+        elif (
+            provider_cfg.provider_type
+            == LighthouseProviderConfiguration.LLMProviderChoices.BEDROCK
+        ):
+            bedrock_creds = _extract_bedrock_credentials(provider_cfg)
+            if not bedrock_creds:
+                return {
+                    "created": 0,
+                    "updated": 0,
+                    "deleted": 0,
+                    "error": "AWS credentials are invalid or missing",
+                }
+            fetched_models = _fetch_bedrock_models(bedrock_creds)
+
+        elif (
+            provider_cfg.provider_type
+            == LighthouseProviderConfiguration.LLMProviderChoices.OPENAI_COMPATIBLE
+        ):
+            params = _extract_openai_compatible_params(provider_cfg)
+            if not params:
+                return {
+                    "created": 0,
+                    "updated": 0,
+                    "deleted": 0,
+                    "error": "Base URL or API key is invalid or missing",
+                }
+            fetched_models = _fetch_openai_compatible_models(
+                params["base_url"], params["api_key"]
+            )
+
+        else:
+            return {
+                "created": 0,
+                "updated": 0,
+                "deleted": 0,
+                "error": "Unsupported provider type",
+            }
+
+    except Exception as e:
+        logger.warning(
+            "Unexpected error refreshing %s models: %s",
+            provider_cfg.provider_type,
+            str(e),
+        )
+        return {"created": 0, "updated": 0, "deleted": 0, "error": str(e)}
+
+    # Upsert models into the catalog
+    created = 0
+    updated = 0
+
+    for model_id, model_name in fetched_models.items():
+        obj, was_created = LighthouseProviderModels.objects.update_or_create(
+            tenant_id=provider_cfg.tenant_id,
+            provider_configuration=provider_cfg,
+            model_id=model_id,
+            defaults={
+                "model_name": model_name,
+                "default_parameters": {},
+            },
+        )
+        if was_created:
+            created += 1
+        else:
+            updated += 1
+
+    # Delete stale models not present anymore
+    deleted, _ = (
+        LighthouseProviderModels.objects.filter(
+            tenant_id=provider_cfg.tenant_id, provider_configuration=provider_cfg
+        )
+        .exclude(model_id__in=fetched_models.keys())
+        .delete()
+    )
+
+    return {"created": created, "updated": updated, "deleted": deleted}
diff --git a/api/src/backend/tasks/jobs/muting.py b/api/src/backend/tasks/jobs/muting.py
new file mode 100644
index 0000000000..6ef4d127f5
--- /dev/null
+++ b/api/src/backend/tasks/jobs/muting.py
@@ -0,0 +1,64 @@
+from celery.utils.log import get_task_logger
+from config.django.base import DJANGO_FINDINGS_BATCH_SIZE
+from tasks.utils import batched
+
+from api.db_utils import rls_transaction
+from api.models import Finding, MuteRule
+
+logger = get_task_logger(__name__)
+
+
+def mute_historical_findings(tenant_id: str, mute_rule_id: str):
+    """
+    Mute historical findings that match the given mute rule.
+
+    This function processes findings in batches, updating their muted status
+    and adding the mute reason.
+
+    Args:
+        tenant_id (str): The tenant ID for RLS context
+        mute_rule_id (str): The ID of the mute rule to apply
+
+    Returns:
+        dict: Summary of the muting operation with findings_muted count
+    """
+    findings_muted_count = 0
+
+    # Get the list of UIDs to mute and the reason
+    with rls_transaction(tenant_id):
+        mute_rule = MuteRule.objects.get(id=mute_rule_id, tenant_id=tenant_id)
+        finding_uids = mute_rule.finding_uids
+        mute_reason = mute_rule.reason
+        muted_at = mute_rule.inserted_at
+
+    # Query findings that match the UIDs and are not already muted
+    with rls_transaction(tenant_id):
+        findings_to_mute = Finding.objects.filter(
+            tenant_id=tenant_id, uid__in=finding_uids, muted=False
+        )
+        total_findings = findings_to_mute.count()
+
+        logger.info(
+            f"Processing {total_findings} findings for mute rule {mute_rule_id}"
+        )
+
+        if total_findings > 0:
+            for batch, is_last in batched(
+                findings_to_mute.iterator(), DJANGO_FINDINGS_BATCH_SIZE
+            ):
+                batch_ids = [f.id for f in batch]
+                updated_count = Finding.all_objects.filter(
+                    id__in=batch_ids, tenant_id=tenant_id
+                ).update(
+                    muted=True,
+                    muted_at=muted_at,
+                    muted_reason=mute_reason,
+                )
+                findings_muted_count += updated_count
+
+    logger.info(f"Muted {findings_muted_count} findings for rule {mute_rule_id}")
+
+    return {
+        "findings_muted": findings_muted_count,
+        "rule_id": mute_rule_id,
+    }
diff --git a/api/src/backend/tasks/jobs/report.py b/api/src/backend/tasks/jobs/report.py
new file mode 100644
index 0000000000..4136cd3748
--- /dev/null
+++ b/api/src/backend/tasks/jobs/report.py
@@ -0,0 +1,1280 @@
+import io
+import os
+from collections import defaultdict
+from pathlib import Path
+from shutil import rmtree
+
+import matplotlib.pyplot as plt
+from celery.utils.log import get_task_logger
+from config.django.base import DJANGO_FINDINGS_BATCH_SIZE, DJANGO_TMP_OUTPUT_DIRECTORY
+from reportlab.lib import colors
+from reportlab.lib.enums import TA_CENTER
+from reportlab.lib.pagesizes import letter
+from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
+from reportlab.lib.units import inch
+from reportlab.pdfbase import pdfmetrics
+from reportlab.pdfbase.ttfonts import TTFont
+from reportlab.pdfgen import canvas
+from reportlab.platypus import (
+    Image,
+    PageBreak,
+    Paragraph,
+    SimpleDocTemplate,
+    Spacer,
+    Table,
+    TableStyle,
+)
+from tasks.jobs.export import _generate_output_directory, _upload_to_s3
+from tasks.jobs.threatscore import compute_threatscore_metrics
+from tasks.jobs.threatscore_utils import (
+    _aggregate_requirement_statistics_from_database,
+    _calculate_requirements_data_from_statistics,
+)
+from tasks.utils import batched
+
+from api.db_router import READ_REPLICA_ALIAS
+from api.db_utils import rls_transaction
+from api.models import (
+    Finding,
+    Provider,
+    ScanSummary,
+    StatusChoices,
+    ThreatScoreSnapshot,
+)
+from api.utils import initialize_prowler_provider
+from prowler.lib.check.compliance_models import Compliance
+from prowler.lib.outputs.finding import Finding as FindingOutput
+
+pdfmetrics.registerFont(
+    TTFont(
+        "PlusJakartaSans",
+        os.path.join(
+            os.path.dirname(__file__), "../assets/fonts/PlusJakartaSans-Regular.ttf"
+        ),
+    )
+)
+
+pdfmetrics.registerFont(
+    TTFont(
+        "FiraCode",
+        os.path.join(os.path.dirname(__file__), "../assets/fonts/FiraCode-Regular.ttf"),
+    )
+)
+
+logger = get_task_logger(__name__)
+
+
+def _create_pdf_styles() -> dict[str, ParagraphStyle]:
+    """
+    Create and return PDF paragraph styles used throughout the report.
+
+    Returns:
+        dict[str, ParagraphStyle]: A dictionary containing the following styles:
+            - 'title': Title style with prowler green color
+            - 'h1': Heading 1 style with blue color and background
+            - 'h2': Heading 2 style with light blue color
+            - 'h3': Heading 3 style for sub-headings
+            - 'normal': Normal text style with left indent
+            - 'normal_center': Normal text style without indent
+    """
+    styles = getSampleStyleSheet()
+    prowler_dark_green = colors.Color(0.1, 0.5, 0.2)
+
+    title_style = ParagraphStyle(
+        "CustomTitle",
+        parent=styles["Title"],
+        fontSize=24,
+        textColor=prowler_dark_green,
+        spaceAfter=20,
+        fontName="PlusJakartaSans",
+        alignment=TA_CENTER,
+    )
+
+    h1 = ParagraphStyle(
+        "CustomH1",
+        parent=styles["Heading1"],
+        fontSize=18,
+        textColor=colors.Color(0.2, 0.4, 0.6),
+        spaceBefore=20,
+        spaceAfter=12,
+        fontName="PlusJakartaSans",
+        leftIndent=0,
+        borderWidth=2,
+        borderColor=colors.Color(0.2, 0.4, 0.6),
+        borderPadding=8,
+        backColor=colors.Color(0.95, 0.97, 1.0),
+    )
+
+    h2 = ParagraphStyle(
+        "CustomH2",
+        parent=styles["Heading2"],
+        fontSize=14,
+        textColor=colors.Color(0.3, 0.5, 0.7),
+        spaceBefore=15,
+        spaceAfter=8,
+        fontName="PlusJakartaSans",
+        leftIndent=10,
+        borderWidth=1,
+        borderColor=colors.Color(0.7, 0.8, 0.9),
+        borderPadding=5,
+        backColor=colors.Color(0.98, 0.99, 1.0),
+    )
+
+    h3 = ParagraphStyle(
+        "CustomH3",
+        parent=styles["Heading3"],
+        fontSize=12,
+        textColor=colors.Color(0.4, 0.6, 0.8),
+        spaceBefore=10,
+        spaceAfter=6,
+        fontName="PlusJakartaSans",
+        leftIndent=20,
+    )
+
+    normal = ParagraphStyle(
+        "CustomNormal",
+        parent=styles["Normal"],
+        fontSize=10,
+        textColor=colors.Color(0.2, 0.2, 0.2),
+        spaceBefore=4,
+        spaceAfter=4,
+        leftIndent=30,
+        fontName="PlusJakartaSans",
+    )
+
+    normal_center = ParagraphStyle(
+        "CustomNormalCenter",
+        parent=styles["Normal"],
+        fontSize=10,
+        textColor=colors.Color(0.2, 0.2, 0.2),
+        fontName="PlusJakartaSans",
+    )
+
+    return {
+        "title": title_style,
+        "h1": h1,
+        "h2": h2,
+        "h3": h3,
+        "normal": normal,
+        "normal_center": normal_center,
+    }
+
+
+def _create_risk_component(risk_level: int, weight: int, score: int = 0) -> Table:
+    """
+    Create a visual risk component table for the PDF report.
+
+    Args:
+        risk_level (int): The risk level (0-5), where higher values indicate higher risk.
+        weight (int): The weight of the risk component.
+        score (int): The calculated score. Defaults to 0.
+
+    Returns:
+        Table: A ReportLab Table object with colored cells representing risk, weight, and score.
+    """
+    if risk_level >= 4:
+        risk_color = colors.Color(0.8, 0.2, 0.2)
+    elif risk_level >= 3:
+        risk_color = colors.Color(0.9, 0.6, 0.2)
+    elif risk_level >= 2:
+        risk_color = colors.Color(0.9, 0.9, 0.2)
+    else:
+        risk_color = colors.Color(0.2, 0.8, 0.2)
+
+    if weight <= 50:
+        weight_color = colors.Color(0.2, 0.8, 0.2)
+    elif weight <= 100:
+        weight_color = colors.Color(0.9, 0.9, 0.2)
+    else:
+        weight_color = colors.Color(0.8, 0.2, 0.2)
+
+    score_color = colors.Color(0.4, 0.4, 0.4)
+
+    data = [
+        [
+            "Risk Level:",
+            str(risk_level),
+            "Weight:",
+            str(weight),
+            "Score:",
+            str(score),
+        ]
+    ]
+
+    table = Table(
+        data,
+        colWidths=[
+            0.8 * inch,
+            0.4 * inch,
+            0.6 * inch,
+            0.4 * inch,
+            0.5 * inch,
+            0.4 * inch,
+        ],
+    )
+
+    table.setStyle(
+        TableStyle(
+            [
+                ("BACKGROUND", (0, 0), (0, 0), colors.Color(0.9, 0.9, 0.9)),
+                ("BACKGROUND", (1, 0), (1, 0), risk_color),
+                ("TEXTCOLOR", (1, 0), (1, 0), colors.white),
+                ("FONTNAME", (1, 0), (1, 0), "FiraCode"),
+                ("BACKGROUND", (2, 0), (2, 0), colors.Color(0.9, 0.9, 0.9)),
+                ("BACKGROUND", (3, 0), (3, 0), weight_color),
+                ("TEXTCOLOR", (3, 0), (3, 0), colors.white),
+                ("FONTNAME", (3, 0), (3, 0), "FiraCode"),
+                ("BACKGROUND", (4, 0), (4, 0), colors.Color(0.9, 0.9, 0.9)),
+                ("BACKGROUND", (5, 0), (5, 0), score_color),
+                ("TEXTCOLOR", (5, 0), (5, 0), colors.white),
+                ("FONTNAME", (5, 0), (5, 0), "FiraCode"),
+                ("ALIGN", (0, 0), (-1, -1), "CENTER"),
+                ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
+                ("FONTSIZE", (0, 0), (-1, -1), 10),
+                ("GRID", (0, 0), (-1, -1), 0.5, colors.black),
+                ("LEFTPADDING", (0, 0), (-1, -1), 6),
+                ("RIGHTPADDING", (0, 0), (-1, -1), 6),
+                ("TOPPADDING", (0, 0), (-1, -1), 8),
+                ("BOTTOMPADDING", (0, 0), (-1, -1), 8),
+            ]
+        )
+    )
+
+    return table
+
+
+def _create_status_component(status: str) -> Table:
+    """
+    Create a visual status component with colored background.
+
+    Args:
+        status (str): The status value (e.g., "PASS", "FAIL", "MANUAL").
+
+    Returns:
+        Table: A ReportLab Table object displaying the status with appropriate color coding.
+    """
+    if status.upper() == "PASS":
+        status_color = colors.Color(0.2, 0.8, 0.2)
+    elif status.upper() == "FAIL":
+        status_color = colors.Color(0.8, 0.2, 0.2)
+    else:
+        status_color = colors.Color(0.4, 0.4, 0.4)
+
+    data = [["State:", status.upper()]]
+
+    table = Table(data, colWidths=[0.6 * inch, 0.8 * inch])
+
+    table.setStyle(
+        TableStyle(
+            [
+                ("BACKGROUND", (0, 0), (0, 0), colors.Color(0.9, 0.9, 0.9)),
+                ("FONTNAME", (0, 0), (0, 0), "PlusJakartaSans"),
+                ("BACKGROUND", (1, 0), (1, 0), status_color),
+                ("TEXTCOLOR", (1, 0), (1, 0), colors.white),
+                ("FONTNAME", (1, 0), (1, 0), "FiraCode"),
+                ("ALIGN", (0, 0), (-1, -1), "CENTER"),
+                ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
+                ("FONTSIZE", (0, 0), (-1, -1), 12),
+                ("GRID", (0, 0), (-1, -1), 0.5, colors.black),
+                ("LEFTPADDING", (0, 0), (-1, -1), 8),
+                ("RIGHTPADDING", (0, 0), (-1, -1), 8),
+                ("TOPPADDING", (0, 0), (-1, -1), 10),
+                ("BOTTOMPADDING", (0, 0), (-1, -1), 10),
+            ]
+        )
+    )
+
+    return table
+
+
+def _create_section_score_chart(
+    requirements_list: list[dict], attributes_by_requirement_id: dict
+) -> io.BytesIO:
+    """
+    Create a bar chart showing compliance score by section using ThreatScore formula.
+
+    Args:
+        requirements_list (list[dict]): List of requirement dictionaries with status and findings data.
+        attributes_by_requirement_id (dict): Mapping of requirement IDs to their attributes including risk level and weight.
+
+    Returns:
+        io.BytesIO: A BytesIO buffer containing the chart image in PNG format.
+    """
+    # Define expected sections
+    expected_sections = [
+        "1. IAM",
+        "2. Attack Surface",
+        "3. Logging and Monitoring",
+        "4. Encryption",
+    ]
+
+    # Initialize all expected sections with default values
+    sections_data = {
+        section: {
+            "numerator": 0,
+            "denominator": 0,
+            "has_findings": False,
+        }
+        for section in expected_sections
+    }
+
+    # Collect data from requirements
+    for requirement in requirements_list:
+        requirement_id = requirement["id"]
+        requirement_attributes = attributes_by_requirement_id.get(requirement_id, {})
+
+        metadata = requirement_attributes.get("attributes", {}).get(
+            "req_attributes", []
+        )
+        if metadata:
+            m = metadata[0]
+            section = getattr(m, "Section", "Unknown")
+
+            # Add section if not in expected list (for flexibility)
+            if section not in sections_data:
+                sections_data[section] = {
+                    "numerator": 0,
+                    "denominator": 0,
+                    "has_findings": False,
+                }
+
+            # Get findings data
+            passed_findings = requirement["attributes"].get("passed_findings", 0)
+            total_findings = requirement["attributes"].get("total_findings", 0)
+
+            if total_findings > 0:
+                sections_data[section]["has_findings"] = True
+                risk_level = getattr(m, "LevelOfRisk", 0)
+                weight = getattr(m, "Weight", 0)
+
+                # Calculate using ThreatScore formula from UI
+                rate_i = passed_findings / total_findings
+                rfac_i = 1 + 0.25 * risk_level
+
+                sections_data[section]["numerator"] += (
+                    rate_i * total_findings * weight * rfac_i
+                )
+                sections_data[section]["denominator"] += (
+                    total_findings * weight * rfac_i
+                )
+
+    section_names = []
+    compliance_percentages = []
+
+    for section, data in sections_data.items():
+        if data["has_findings"] and data["denominator"] > 0:
+            compliance_percentage = (data["numerator"] / data["denominator"]) * 100
+        else:
+            compliance_percentage = 100  # No findings = 100% (PASS)
+
+        section_names.append(section)
+        compliance_percentages.append(compliance_percentage)
+
+    # Sort alphabetically by section name
+    sorted_data = sorted(
+        zip(section_names, compliance_percentages),
+        key=lambda x: x[0],
+    )
+    section_names, compliance_percentages = (
+        zip(*sorted_data) if sorted_data else ([], [])
+    )
+
+    fig, ax = plt.subplots(figsize=(12, 8))
+
+    colors_list = []
+    for percentage in compliance_percentages:
+        if percentage >= 80:
+            color = "#4CAF50"
+        elif percentage >= 60:
+            color = "#8BC34A"
+        elif percentage >= 40:
+            color = "#FFEB3B"
+        elif percentage >= 20:
+            color = "#FF9800"
+        else:
+            color = "#F44336"
+        colors_list.append(color)
+
+    bars = ax.bar(section_names, compliance_percentages, color=colors_list)
+
+    ax.set_ylabel("Compliance Score (%)", fontsize=12)
+    ax.set_xlabel("Section", fontsize=12)
+    ax.set_ylim(0, 100)
+
+    for bar, percentage in zip(bars, compliance_percentages):
+        height = bar.get_height()
+        ax.text(
+            bar.get_x() + bar.get_width() / 2.0,
+            height + 1,
+            f"{percentage:.1f}%",
+            ha="center",
+            va="bottom",
+            fontweight="bold",
+        )
+
+    plt.xticks(rotation=45, ha="right")
+
+    ax.grid(True, alpha=0.3, axis="y")
+
+    plt.tight_layout()
+
+    buffer = io.BytesIO()
+    plt.savefig(buffer, format="png", dpi=300, bbox_inches="tight")
+    buffer.seek(0)
+    plt.close()
+
+    return buffer
+
+
+def _add_pdf_footer(canvas_obj: canvas.Canvas, doc: SimpleDocTemplate) -> None:
+    """
+    Add footer with page number and branding to each page of the PDF.
+
+    Args:
+        canvas_obj (canvas.Canvas): The ReportLab canvas object for drawing.
+        doc (SimpleDocTemplate): The document template containing page information.
+    """
+    width, height = doc.pagesize
+    page_num_text = f"Page {doc.page}"
+    canvas_obj.setFont("PlusJakartaSans", 9)
+    canvas_obj.setFillColorRGB(0.4, 0.4, 0.4)
+    canvas_obj.drawString(30, 20, page_num_text)
+    powered_text = "Powered by Prowler"
+    text_width = canvas_obj.stringWidth(powered_text, "PlusJakartaSans", 9)
+    canvas_obj.drawString(width - text_width - 30, 20, powered_text)
+
+
+def _load_findings_for_requirement_checks(
+    tenant_id: str, scan_id: str, check_ids: list[str], prowler_provider
+) -> dict[str, list[FindingOutput]]:
+    """
+    Load findings for specific check IDs on-demand.
+
+    This function loads only the findings needed for a specific set of checks,
+    minimizing memory usage by avoiding loading all findings at once. This is used
+    when generating detailed findings tables for specific requirements in the PDF.
+
+    Args:
+        tenant_id (str): The tenant ID for Row-Level Security context.
+        scan_id (str): The ID of the scan to retrieve findings for.
+        check_ids (list[str]): List of check IDs to load findings for.
+        prowler_provider: The initialized Prowler provider instance.
+
+    Returns:
+        dict[str, list[FindingOutput]]: Dictionary mapping check_id to list of FindingOutput objects.
+
+    Example:
+        {
+            'aws_iam_user_mfa_enabled': [FindingOutput(...), FindingOutput(...)],
+            'aws_s3_bucket_public_access': [FindingOutput(...)]
+        }
+    """
+    findings_by_check_id = defaultdict(list)
+
+    if not check_ids:
+        return dict(findings_by_check_id)
+
+    logger.info(f"Loading findings for {len(check_ids)} checks on-demand")
+
+    findings_queryset = (
+        Finding.all_objects.filter(
+            tenant_id=tenant_id, scan_id=scan_id, check_id__in=check_ids
+        )
+        .order_by("uid")
+        .iterator()
+    )
+
+    with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS):
+        for batch, is_last_batch in batched(
+            findings_queryset, DJANGO_FINDINGS_BATCH_SIZE
+        ):
+            for finding_model in batch:
+                finding_output = FindingOutput.transform_api_finding(
+                    finding_model, prowler_provider
+                )
+                findings_by_check_id[finding_output.check_id].append(finding_output)
+
+    total_findings_loaded = sum(
+        len(findings) for findings in findings_by_check_id.values()
+    )
+    logger.info(
+        f"Loaded {total_findings_loaded} findings for {len(findings_by_check_id)} checks"
+    )
+
+    return dict(findings_by_check_id)
+
+
+def generate_threatscore_report(
+    tenant_id: str,
+    scan_id: str,
+    compliance_id: str,
+    output_path: str,
+    provider_id: str,
+    only_failed: bool = True,
+    min_risk_level: int = 4,
+) -> None:
+    """
+    Generate a PDF compliance report based on Prowler ThreatScore framework.
+
+    This function creates a comprehensive PDF report containing:
+    - Compliance overview and metadata
+    - Section-by-section compliance scores with charts
+    - Overall ThreatScore calculation
+    - Critical failed requirements
+    - Detailed findings for each requirement
+
+    Args:
+        tenant_id (str): The tenant ID for Row-Level Security context.
+        scan_id (str): ID of the scan executed by Prowler.
+        compliance_id (str): ID of the compliance framework (e.g., "prowler_threatscore_aws").
+        output_path (str): Output PDF file path (e.g., "/tmp/threatscore_report.pdf").
+        provider_id (str): Provider ID for the scan.
+        only_failed (bool): If True, only requirements with status "FAIL" will be included
+            in the detailed requirements section. Defaults to True.
+        min_risk_level (int): Minimum risk level for critical failed requirements. Defaults to 4.
+
+    Raises:
+        Exception: If any error occurs during PDF generation, it will be logged and re-raised.
+    """
+    logger.info(
+        f"Generating the report for the scan {scan_id} with provider {provider_id}"
+    )
+    try:
+        # Get PDF styles
+        pdf_styles = _create_pdf_styles()
+        title_style = pdf_styles["title"]
+        h1 = pdf_styles["h1"]
+        h2 = pdf_styles["h2"]
+        h3 = pdf_styles["h3"]
+        normal = pdf_styles["normal"]
+        normal_center = pdf_styles["normal_center"]
+
+        # Get compliance and provider information
+        with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS):
+            provider_obj = Provider.objects.get(id=provider_id)
+            prowler_provider = initialize_prowler_provider(provider_obj)
+            provider_type = provider_obj.provider
+
+            frameworks_bulk = Compliance.get_bulk(provider_type)
+            compliance_obj = frameworks_bulk[compliance_id]
+            compliance_framework = getattr(compliance_obj, "Framework", "N/A")
+            compliance_version = getattr(compliance_obj, "Version", "N/A")
+            compliance_name = getattr(compliance_obj, "Name", "N/A")
+            compliance_description = getattr(compliance_obj, "Description", "")
+
+        # Aggregate requirement statistics from database (memory-efficient)
+        logger.info(f"Aggregating requirement statistics for scan {scan_id}")
+        requirement_statistics_by_check_id = (
+            _aggregate_requirement_statistics_from_database(tenant_id, scan_id)
+        )
+
+        # Calculate requirements data using aggregated statistics
+        attributes_by_requirement_id, requirements_list = (
+            _calculate_requirements_data_from_statistics(
+                compliance_obj, requirement_statistics_by_check_id
+            )
+        )
+
+        # Initialize PDF document
+        doc = SimpleDocTemplate(
+            output_path,
+            pagesize=letter,
+            title=f"Prowler ThreatScore Report - {compliance_framework}",
+            author="Prowler",
+            subject=f"Compliance Report for {compliance_framework}",
+            creator="Prowler Engineering Team",
+            keywords=f"compliance,{compliance_framework},security,framework,prowler",
+        )
+
+        elements = []
+
+        # Add logo
+        img_path = os.path.join(
+            os.path.dirname(__file__), "../assets/img/prowler_logo.png"
+        )
+        logo = Image(
+            img_path,
+            width=5 * inch,
+            height=1 * inch,
+        )
+        elements.append(logo)
+
+        elements.append(Spacer(1, 0.5 * inch))
+        elements.append(Paragraph("Prowler ThreatScore Report", title_style))
+        elements.append(Spacer(1, 0.5 * inch))
+
+        # Add compliance information table
+        info_data = [
+            ["Framework:", compliance_framework],
+            ["ID:", compliance_id],
+            ["Name:", Paragraph(compliance_name, normal_center)],
+            ["Version:", compliance_version],
+            ["Scan ID:", scan_id],
+            ["Description:", Paragraph(compliance_description, normal_center)],
+        ]
+        info_table = Table(info_data, colWidths=[2 * inch, 4 * inch])
+        info_table.setStyle(
+            TableStyle(
+                [
+                    ("BACKGROUND", (0, 0), (0, 5), colors.Color(0.2, 0.4, 0.6)),
+                    ("TEXTCOLOR", (0, 0), (0, 5), colors.white),
+                    ("FONTNAME", (0, 0), (0, 5), "FiraCode"),
+                    ("BACKGROUND", (1, 0), (1, 5), colors.Color(0.95, 0.97, 1.0)),
+                    ("TEXTCOLOR", (1, 0), (1, 5), colors.Color(0.2, 0.2, 0.2)),
+                    ("FONTNAME", (1, 0), (1, 5), "PlusJakartaSans"),
+                    ("ALIGN", (0, 0), (-1, -1), "LEFT"),
+                    ("VALIGN", (0, 0), (-1, -1), "TOP"),
+                    ("FONTSIZE", (0, 0), (-1, -1), 11),
+                    ("GRID", (0, 0), (-1, -1), 1, colors.Color(0.7, 0.8, 0.9)),
+                    ("LEFTPADDING", (0, 0), (-1, -1), 10),
+                    ("RIGHTPADDING", (0, 0), (-1, -1), 10),
+                    ("TOPPADDING", (0, 0), (-1, -1), 8),
+                    ("BOTTOMPADDING", (0, 0), (-1, -1), 8),
+                ]
+            )
+        )
+
+        elements.append(info_table)
+        elements.append(PageBreak())
+
+        # Add compliance score chart
+        elements.append(Paragraph("Compliance Score by Sections", h1))
+        elements.append(Spacer(1, 0.2 * inch))
+
+        chart_buffer = _create_section_score_chart(
+            requirements_list, attributes_by_requirement_id
+        )
+        chart_image = Image(chart_buffer, width=7 * inch, height=5.5 * inch)
+        elements.append(chart_image)
+
+        # Calculate overall ThreatScore using the same formula as the UI
+        numerator = 0
+        denominator = 0
+        has_findings = False
+
+        for requirement in requirements_list:
+            requirement_id = requirement["id"]
+            requirement_attributes = attributes_by_requirement_id.get(
+                requirement_id, {}
+            )
+
+            # Get findings data
+            passed_findings = requirement["attributes"].get("passed_findings", 0)
+            total_findings = requirement["attributes"].get("total_findings", 0)
+
+            # Skip if no findings (avoid division by zero)
+            if total_findings == 0:
+                continue
+
+            has_findings = True
+            metadata = requirement_attributes.get("attributes", {}).get(
+                "req_attributes", []
+            )
+            if metadata and len(metadata) > 0:
+                m = metadata[0]
+                risk_level = getattr(m, "LevelOfRisk", 0)
+                weight = getattr(m, "Weight", 0)
+
+                # Calculate using ThreatScore formula from UI
+                rate_i = passed_findings / total_findings
+                rfac_i = 1 + 0.25 * risk_level
+
+                numerator += rate_i * total_findings * weight * rfac_i
+                denominator += total_findings * weight * rfac_i
+
+        # Calculate ThreatScore (percentualScore)
+        # If no findings exist, consider it 100% (PASS)
+        if not has_findings:
+            overall_compliance = 100
+        elif denominator > 0:
+            overall_compliance = (numerator / denominator) * 100
+        else:
+            overall_compliance = 0
+
+        elements.append(Spacer(1, 0.3 * inch))
+
+        summary_data = [
+            ["ThreatScore:", f"{overall_compliance:.2f}%"],
+        ]
+
+        if overall_compliance >= 80:
+            compliance_color = colors.Color(0.2, 0.8, 0.2)
+        elif overall_compliance >= 60:
+            compliance_color = colors.Color(0.8, 0.8, 0.2)
+        else:
+            compliance_color = colors.Color(0.8, 0.2, 0.2)
+
+        summary_table = Table(summary_data, colWidths=[2.5 * inch, 2 * inch])
+        summary_table.setStyle(
+            TableStyle(
+                [
+                    ("BACKGROUND", (0, 0), (0, 0), colors.Color(0.1, 0.3, 0.5)),
+                    ("TEXTCOLOR", (0, 0), (0, 0), colors.white),
+                    ("FONTNAME", (0, 0), (0, 0), "FiraCode"),
+                    ("FONTSIZE", (0, 0), (0, 0), 12),
+                    ("BACKGROUND", (1, 0), (1, 0), compliance_color),
+                    ("TEXTCOLOR", (1, 0), (1, 0), colors.white),
+                    ("FONTNAME", (1, 0), (1, 0), "FiraCode"),
+                    ("FONTSIZE", (1, 0), (1, 0), 16),
+                    ("ALIGN", (0, 0), (-1, -1), "CENTER"),
+                    ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
+                    ("GRID", (0, 0), (-1, -1), 1.5, colors.Color(0.5, 0.6, 0.7)),
+                    ("LEFTPADDING", (0, 0), (-1, -1), 12),
+                    ("RIGHTPADDING", (0, 0), (-1, -1), 12),
+                    ("TOPPADDING", (0, 0), (-1, -1), 10),
+                    ("BOTTOMPADDING", (0, 0), (-1, -1), 10),
+                ]
+            )
+        )
+
+        elements.append(summary_table)
+        elements.append(PageBreak())
+
+        # Add requirements index
+        elements.append(Paragraph("Requirements Index", h1))
+
+        sections = {}
+        for (
+            requirement_id,
+            requirement_attributes,
+        ) in attributes_by_requirement_id.items():
+            meta = requirement_attributes["attributes"]["req_attributes"][0]
+            section = getattr(meta, "Section", "N/A")
+            subsection = getattr(meta, "SubSection", "N/A")
+            title = getattr(meta, "Title", "N/A")
+
+            if section not in sections:
+                sections[section] = {}
+            if subsection not in sections[section]:
+                sections[section][subsection] = []
+
+            sections[section][subsection].append({"id": requirement_id, "title": title})
+
+        section_num = 1
+        for section_name, subsections in sections.items():
+            elements.append(Paragraph(f"{section_num}. {section_name}", h2))
+
+            subsection_num = 1
+            for subsection_name, requirements in subsections.items():
+                elements.append(Paragraph(f"{subsection_name}", h3))
+
+                req_num = 1
+                for req in requirements:
+                    elements.append(Paragraph(f"{req['id']} - {req['title']}", normal))
+                    req_num += 1
+
+                subsection_num += 1
+
+            section_num += 1
+            elements.append(Spacer(1, 0.1 * inch))
+
+        elements.append(PageBreak())
+
+        # Add critical failed requirements section
+        elements.append(Paragraph("Top Requirements by Level of Risk", h1))
+        elements.append(Spacer(1, 0.1 * inch))
+        elements.append(
+            Paragraph(
+                f"Critical Failed Requirements (Risk Level ≄ {min_risk_level})", h2
+            )
+        )
+        elements.append(Spacer(1, 0.2 * inch))
+
+        critical_failed_requirements = []
+        for requirement in requirements_list:
+            requirement_status = requirement["attributes"]["status"]
+            if requirement_status == StatusChoices.FAIL:
+                requirement_id = requirement["id"]
+                metadata = (
+                    attributes_by_requirement_id.get(requirement_id, {})
+                    .get("attributes", {})
+                    .get("req_attributes", [{}])[0]
+                )
+                if metadata:
+                    risk_level = getattr(metadata, "LevelOfRisk", 0)
+                    weight = getattr(metadata, "Weight", 0)
+
+                    if risk_level >= min_risk_level:
+                        critical_failed_requirements.append(
+                            {
+                                "requirement": requirement,
+                                "attributes": attributes_by_requirement_id[
+                                    requirement_id
+                                ],
+                                "risk_level": risk_level,
+                                "weight": weight,
+                                "metadata": metadata,
+                            }
+                        )
+
+        critical_failed_requirements.sort(
+            key=lambda x: (x["risk_level"], x["weight"]), reverse=True
+        )
+
+        if not critical_failed_requirements:
+            elements.append(
+                Paragraph(
+                    "āœ… No critical failed requirements found. Great job!", normal
+                )
+            )
+        else:
+            elements.append(
+                Paragraph(
+                    f"Found {len(critical_failed_requirements)} critical failed requirements that require immediate attention:",
+                    normal,
+                )
+            )
+            elements.append(Spacer(1, 0.5 * inch))
+
+            table_data = [["Risk", "Weight", "Requirement ID", "Title", "Section"]]
+
+            for idx, critical_failed_requirement in enumerate(
+                critical_failed_requirements
+            ):
+                requirement_id = critical_failed_requirement["requirement"]["id"]
+                risk_level = critical_failed_requirement["risk_level"]
+                weight = critical_failed_requirement["weight"]
+                title = getattr(critical_failed_requirement["metadata"], "Title", "N/A")
+                section = getattr(
+                    critical_failed_requirement["metadata"], "Section", "N/A"
+                )
+
+                if len(title) > 50:
+                    title = title[:47] + "..."
+
+                table_data.append(
+                    [str(risk_level), str(weight), requirement_id, title, section]
+                )
+
+            critical_table = Table(
+                table_data,
+                colWidths=[0.7 * inch, 0.9 * inch, 1.3 * inch, 3.1 * inch, 1.5 * inch],
+            )
+
+            critical_table.setStyle(
+                TableStyle(
+                    [
+                        ("BACKGROUND", (0, 0), (-1, 0), colors.Color(0.8, 0.2, 0.2)),
+                        ("TEXTCOLOR", (0, 0), (-1, 0), colors.white),
+                        ("FONTNAME", (0, 0), (-1, 0), "FiraCode"),
+                        ("FONTSIZE", (0, 0), (-1, 0), 10),
+                        ("BACKGROUND", (0, 1), (0, -1), colors.Color(0.8, 0.2, 0.2)),
+                        ("TEXTCOLOR", (0, 1), (0, -1), colors.white),
+                        ("FONTNAME", (0, 1), (0, -1), "FiraCode"),
+                        ("ALIGN", (0, 1), (0, -1), "CENTER"),
+                        ("FONTSIZE", (0, 1), (0, -1), 12),
+                        ("ALIGN", (1, 1), (1, -1), "CENTER"),
+                        ("FONTNAME", (1, 1), (1, -1), "FiraCode"),
+                        ("FONTNAME", (2, 1), (2, -1), "FiraCode"),
+                        ("FONTSIZE", (2, 1), (2, -1), 9),
+                        ("FONTNAME", (3, 1), (-1, -1), "PlusJakartaSans"),
+                        ("FONTSIZE", (3, 1), (-1, -1), 8),
+                        ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
+                        ("GRID", (0, 0), (-1, -1), 1, colors.Color(0.7, 0.7, 0.7)),
+                        ("LEFTPADDING", (0, 0), (-1, -1), 6),
+                        ("RIGHTPADDING", (0, 0), (-1, -1), 6),
+                        ("TOPPADDING", (0, 0), (-1, -1), 8),
+                        ("BOTTOMPADDING", (0, 0), (-1, -1), 8),
+                        (
+                            "BACKGROUND",
+                            (1, 1),
+                            (-1, -1),
+                            colors.Color(0.98, 0.98, 0.98),
+                        ),
+                    ]
+                )
+            )
+
+            for idx, critical_failed_requirement in enumerate(
+                critical_failed_requirements
+            ):
+                row_idx = idx + 1
+                weight = critical_failed_requirement["weight"]
+
+                if weight >= 150:
+                    weight_color = colors.Color(0.8, 0.2, 0.2)
+                elif weight >= 100:
+                    weight_color = colors.Color(0.9, 0.6, 0.2)
+                else:
+                    weight_color = colors.Color(0.9, 0.9, 0.2)
+
+                critical_table.setStyle(
+                    TableStyle(
+                        [
+                            ("BACKGROUND", (1, row_idx), (1, row_idx), weight_color),
+                            ("TEXTCOLOR", (1, row_idx), (1, row_idx), colors.white),
+                        ]
+                    )
+                )
+
+            elements.append(critical_table)
+            elements.append(Spacer(1, 0.2 * inch))
+
+            # Get styles for warning
+            styles = getSampleStyleSheet()
+            warning_text = """
+            IMMEDIATE ACTION REQUIRED:
+ These requirements have the highest risk levels and have failed compliance checks. + Please prioritize addressing these issues to improve your security posture. + """ + + warning_style = ParagraphStyle( + "Warning", + parent=styles["Normal"], + fontSize=11, + textColor=colors.Color(0.8, 0.2, 0.2), + spaceBefore=10, + spaceAfter=10, + leftIndent=20, + rightIndent=20, + fontName="PlusJakartaSans", + backColor=colors.Color(1.0, 0.95, 0.95), + borderWidth=2, + borderColor=colors.Color(0.8, 0.2, 0.2), + borderPadding=10, + ) + + elements.append(Paragraph(warning_text, warning_style)) + + elements.append(PageBreak()) + + # Add detailed requirements section + def get_weight_for_requirement(requirement_dict): + requirement_id = requirement_dict["id"] + requirement_attributes = attributes_by_requirement_id.get( + requirement_id, {} + ) + metadata = requirement_attributes.get("attributes", {}).get( + "req_attributes", [] + ) + if metadata: + return getattr(metadata[0], "Weight", 0) + return 0 + + sorted_requirements = sorted( + requirements_list, key=get_weight_for_requirement, reverse=True + ) + + if only_failed: + sorted_requirements = [ + requirement + for requirement in sorted_requirements + if requirement["attributes"]["status"] == StatusChoices.FAIL + ] + + # Collect all check IDs for requirements that will be displayed + # This allows us to load only the findings we actually need (memory optimization) + check_ids_to_load = [] + for requirement in sorted_requirements: + requirement_id = requirement["id"] + requirement_attributes = attributes_by_requirement_id.get( + requirement_id, {} + ) + check_ids = requirement_attributes.get("attributes", {}).get("checks", []) + check_ids_to_load.extend(check_ids) + + # Load findings on-demand only for the checks that will be displayed + logger.info( + f"Loading findings on-demand for {len(sorted_requirements)} requirements" + ) + findings_by_check_id = _load_findings_for_requirement_checks( + tenant_id, scan_id, check_ids_to_load, prowler_provider + ) + + for requirement in sorted_requirements: + requirement_id = requirement["id"] + requirement_attributes = attributes_by_requirement_id.get( + requirement_id, {} + ) + requirement_description = requirement["attributes"]["description"] + requirement_status = requirement["attributes"]["status"] + + elements.append( + Paragraph( + f"{requirement_id}: {requirement_attributes.get('description', requirement_description)}", + h1, + ) + ) + + status_component = _create_status_component(requirement_status) + elements.append(status_component) + elements.append(Spacer(1, 0.1 * inch)) + + metadata = requirement_attributes.get("attributes", {}).get( + "req_attributes", [] + ) + if metadata and len(metadata) > 0: + m = metadata[0] + elements.append(Paragraph("Title: ", h3)) + elements.append(Paragraph(f"{getattr(m, 'Title', 'N/A')}", normal)) + elements.append(Paragraph("Section: ", h3)) + elements.append(Paragraph(f"{getattr(m, 'Section', 'N/A')}", normal)) + elements.append(Paragraph("SubSection: ", h3)) + elements.append(Paragraph(f"{getattr(m, 'SubSection', 'N/A')}", normal)) + elements.append(Paragraph("Description: ", h3)) + elements.append( + Paragraph(f"{getattr(m, 'AttributeDescription', 'N/A')}", normal) + ) + elements.append(Paragraph("Additional Information: ", h3)) + elements.append( + Paragraph(f"{getattr(m, 'AdditionalInformation', 'N/A')}", normal) + ) + elements.append(Spacer(1, 0.1 * inch)) + + risk_level = getattr(m, "LevelOfRisk", 0) + weight = getattr(m, "Weight", 0) + + if requirement_status == StatusChoices.PASS: + score = risk_level * weight + else: + score = 0 + + risk_component = _create_risk_component(risk_level, weight, score) + elements.append(risk_component) + elements.append(Spacer(1, 0.1 * inch)) + + # Get findings for this requirement's checks (loaded on-demand earlier) + requirement_check_ids = requirement_attributes.get("attributes", {}).get( + "checks", [] + ) + for check_id in requirement_check_ids: + elements.append(Paragraph(f"Check: {check_id}", h2)) + elements.append(Spacer(1, 0.1 * inch)) + + # Get findings for this check (already loaded on-demand) + check_findings = findings_by_check_id.get(check_id, []) + + if not check_findings: + elements.append( + Paragraph("- No information for this finding currently", normal) + ) + else: + findings_table_data = [ + [ + "Finding", + "Resource name", + "Severity", + "Status", + "Region", + ] + ] + for finding_output in check_findings: + check_metadata = getattr(finding_output, "metadata", {}) + finding_title = getattr( + check_metadata, + "CheckTitle", + getattr(finding_output, "check_id", ""), + ) + resource_name = getattr(finding_output, "resource_name", "") + if not resource_name: + resource_name = getattr(finding_output, "resource_uid", "") + severity = getattr(check_metadata, "Severity", "").capitalize() + finding_status = getattr(finding_output, "status", "").upper() + region = getattr(finding_output, "region", "global") + + findings_table_data.append( + [ + Paragraph(finding_title, normal_center), + Paragraph(resource_name, normal_center), + Paragraph(severity, normal_center), + Paragraph(finding_status, normal_center), + Paragraph(region, normal_center), + ] + ) + findings_table = Table( + findings_table_data, + colWidths=[ + 2.5 * inch, + 3 * inch, + 0.9 * inch, + 0.9 * inch, + 0.9 * inch, + ], + ) + findings_table.setStyle( + TableStyle( + [ + ( + "BACKGROUND", + (0, 0), + (-1, 0), + colors.Color(0.2, 0.4, 0.6), + ), + ("TEXTCOLOR", (0, 0), (-1, 0), colors.white), + ("FONTNAME", (0, 0), (-1, 0), "FiraCode"), + ("ALIGN", (0, 0), (0, 0), "CENTER"), + ("VALIGN", (0, 0), (-1, -1), "MIDDLE"), + ("FONTSIZE", (0, 0), (-1, -1), 9), + ( + "GRID", + (0, 0), + (-1, -1), + 0.1, + colors.Color(0.7, 0.8, 0.9), + ), + ("LEFTPADDING", (0, 0), (0, 0), 0), + ("RIGHTPADDING", (0, 0), (0, 0), 0), + ("TOPPADDING", (0, 0), (-1, -1), 4), + ("BOTTOMPADDING", (0, 0), (-1, -1), 4), + ] + ) + ) + elements.append(findings_table) + elements.append(Spacer(1, 0.1 * inch)) + + elements.append(PageBreak()) + + # Build the PDF + doc.build(elements, onFirstPage=_add_pdf_footer, onLaterPages=_add_pdf_footer) + except Exception as e: + logger.info( + f"Error building the document, line {e.__traceback__.tb_lineno} -- {e}" + ) + raise e + + +def generate_threatscore_report_job( + tenant_id: str, scan_id: str, provider_id: str +) -> dict[str, bool | str]: + """ + Job function to generate a threatscore report and upload it to S3. + + This function orchestrates the complete report generation workflow: + 1. Validates that the scan has findings + 2. Checks provider type compatibility + 3. Generates the output directory + 4. Calls generate_threatscore_report to create the PDF + 5. Computes and stores ThreatScore metrics snapshot + 6. Uploads the PDF to S3 + 7. Cleans up temporary files + + Args: + tenant_id (str): The tenant ID for Row-Level Security context. + scan_id (str): The ID of the scan to generate a report for. + provider_id (str): The ID of the provider used in the scan. + + Returns: + dict[str, bool | str]: A dictionary containing: + - 'upload' (bool): True if the report was successfully uploaded to S3, False otherwise. + - 'error' (str): Error message if an exception occurred (only present on error). + """ + # Check if the scan has findings and get provider info + with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS): + if not ScanSummary.objects.filter(scan_id=scan_id).exists(): + logger.info(f"No findings found for scan {scan_id}") + return {"upload": False} + + provider_obj = Provider.objects.get(id=provider_id) + provider_uid = provider_obj.uid + provider_type = provider_obj.provider + + if provider_type not in ["aws", "azure", "gcp", "m365"]: + logger.info( + f"Provider {provider_id} is not supported for threatscore report" + ) + return {"upload": False} + + # This compliance is hardcoded because is the only one that is available for the threatscore report + compliance_id = f"prowler_threatscore_{provider_type}" + logger.info( + f"Generating threatscore report for scan {scan_id} with compliance {compliance_id} inside the job" + ) + try: + logger.info("Generating the output directory") + out_dir, _, threatscore_path = _generate_output_directory( + DJANGO_TMP_OUTPUT_DIRECTORY, provider_uid, tenant_id, scan_id + ) + except Exception as e: + logger.error(f"Error generating output directory: {e}") + return {"error": str(e)} + + pdf_path = f"{threatscore_path}_threatscore_report.pdf" + logger.info(f"The path for the threatscore report is {pdf_path}") + generate_threatscore_report( + tenant_id=tenant_id, + scan_id=scan_id, + compliance_id=compliance_id, + output_path=pdf_path, + provider_id=provider_id, + only_failed=True, + min_risk_level=4, + ) + + # Compute and store ThreatScore metrics snapshot + logger.info(f"Computing ThreatScore metrics for scan {scan_id}") + try: + metrics = compute_threatscore_metrics( + tenant_id=tenant_id, + scan_id=scan_id, + provider_id=provider_id, + compliance_id=compliance_id, + min_risk_level=4, + ) + + # Create snapshot in database + with rls_transaction(tenant_id): + # Get previous snapshot for the same provider to calculate delta + previous_snapshot = ( + ThreatScoreSnapshot.objects.filter( + tenant_id=tenant_id, + provider_id=provider_id, + compliance_id=compliance_id, + ) + .order_by("-inserted_at") + .first() + ) + + # Calculate score delta (improvement) + score_delta = None + if previous_snapshot: + score_delta = metrics["overall_score"] - float( + previous_snapshot.overall_score + ) + + snapshot = ThreatScoreSnapshot.objects.create( + tenant_id=tenant_id, + scan_id=scan_id, + provider_id=provider_id, + compliance_id=compliance_id, + overall_score=metrics["overall_score"], + score_delta=score_delta, + section_scores=metrics["section_scores"], + critical_requirements=metrics["critical_requirements"], + total_requirements=metrics["total_requirements"], + passed_requirements=metrics["passed_requirements"], + failed_requirements=metrics["failed_requirements"], + manual_requirements=metrics["manual_requirements"], + total_findings=metrics["total_findings"], + passed_findings=metrics["passed_findings"], + failed_findings=metrics["failed_findings"], + ) + + delta_msg = ( + f" (delta: {score_delta:+.2f}%)" if score_delta is not None else "" + ) + logger.info( + f"ThreatScore snapshot created with ID {snapshot.id} " + f"(score: {snapshot.overall_score}%{delta_msg})" + ) + except Exception as e: + # Log error but don't fail the job if snapshot creation fails + logger.error(f"Error creating ThreatScore snapshot: {e}") + + upload_uri = _upload_to_s3( + tenant_id, + scan_id, + pdf_path, + f"threatscore/{Path(pdf_path).name}", + ) + if upload_uri: + try: + rmtree(Path(pdf_path).parent, ignore_errors=True) + except Exception as e: + logger.error(f"Error deleting output files: {e}") + final_location, did_upload = upload_uri, True + else: + final_location, did_upload = out_dir, False + + logger.info(f"Threatscore report outputs at {final_location}") + + return {"upload": did_upload} diff --git a/api/src/backend/tasks/jobs/scan.py b/api/src/backend/tasks/jobs/scan.py index 311b1478c3..c4cf413301 100644 --- a/api/src/backend/tasks/jobs/scan.py +++ b/api/src/backend/tasks/jobs/scan.py @@ -1,31 +1,39 @@ +import csv +import io import json +import re import time +import uuid from collections import defaultdict -from copy import deepcopy from datetime import datetime, timezone +from typing import Any from celery.utils.log import get_task_logger +from config.env import env from config.settings.celery import CELERY_DEADLOCK_ATTEMPTS from django.db import IntegrityError, OperationalError from django.db.models import Case, Count, IntegerField, Prefetch, Sum, When from tasks.utils import CustomEncoder -from api.compliance import ( - PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE, - generate_scan_compliance, -) +from api.compliance import PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE +from api.db_router import READ_REPLICA_ALIAS, MainRouter from api.db_utils import ( - create_objects_in_batches, + POSTGRES_TENANT_VAR, + SET_CONFIG_QUERY, + psycopg_connection, rls_transaction, update_objects_in_batches, ) from api.exceptions import ProviderConnectionError from api.models import ( + ComplianceOverviewSummary, ComplianceRequirementOverview, Finding, + MuteRule, Processor, Provider, Resource, + ResourceFindingMapping, ResourceScanSummary, ResourceTag, Scan, @@ -40,6 +48,32 @@ from prowler.lib.scan.scan import Scan as ProwlerScan logger = get_task_logger(__name__) +# Column order must match `ComplianceRequirementOverview` schema in +# `api/models.py`. Keep this list minimal but sufficient to populate all +# non-nullable fields plus the counters we care about. +COMPLIANCE_REQUIREMENT_COPY_COLUMNS = ( + "id", + "tenant_id", + "inserted_at", + "compliance_id", + "framework", + "version", + "description", + "region", + "requirement_id", + "requirement_status", + "passed_checks", + "failed_checks", + "total_checks", + "passed_findings", + "total_findings", + "scan_id", +) +# Controls how many findings we process per micro-batch before flushing to DB writes +FINDINGS_MICRO_BATCH_SIZE = env.int("DJANGO_FINDINGS_MICRO_BATCH_SIZE", default=3000) +# Controls how many rows each ORM bulk_create/bulk_update call sends to Postgres +SCAN_DB_BATCH_SIZE = env.int("DJANGO_SCAN_DB_BATCH_SIZE", default=500) + def _create_finding_delta( last_status: FindingStatus | None | str, new_status: FindingStatus | None @@ -107,6 +141,497 @@ def _store_resources( return resource_instance, (resource_instance.uid, resource_instance.region) +def _copy_compliance_requirement_rows( + tenant_id: str, rows: list[dict[str, Any]] +) -> None: + """Stream compliance requirement rows into Postgres using COPY. + + We leverage the admin connection (when available) to bypass the COPY + RLS + restriction, writing only the fields required by + ``ComplianceRequirementOverview``. + + Args: + tenant_id: Target tenant UUID. + rows: List of row dictionaries prepared by + :func:`create_compliance_requirements`. + """ + + csv_buffer = io.StringIO() + writer = csv.writer(csv_buffer) + + datetime_now = datetime.now(tz=timezone.utc) + for row in rows: + writer.writerow( + [ + str(row.get("id")), + str(row.get("tenant_id")), + (row.get("inserted_at") or datetime_now).isoformat(), + row.get("compliance_id") or "", + row.get("framework") or "", + row.get("version") or "", + row.get("description") or "", + row.get("region") or "", + row.get("requirement_id") or "", + row.get("requirement_status") or "", + row.get("passed_checks", 0), + row.get("failed_checks", 0), + row.get("total_checks", 0), + row.get("passed_findings", 0), + row.get("total_findings", 0), + str(row.get("scan_id")), + ] + ) + + csv_buffer.seek(0) + copy_sql = ( + "COPY compliance_requirements_overviews (" + + ", ".join(COMPLIANCE_REQUIREMENT_COPY_COLUMNS) + + ") FROM STDIN WITH (FORMAT CSV, DELIMITER ',', QUOTE '\"', ESCAPE '\"', NULL '\\N')" + ) + + try: + with psycopg_connection(MainRouter.admin_db) as connection: + connection.autocommit = False + try: + with connection.cursor() as cursor: + cursor.execute(SET_CONFIG_QUERY, [POSTGRES_TENANT_VAR, tenant_id]) + cursor.copy_expert(copy_sql, csv_buffer) + connection.commit() + except Exception: + connection.rollback() + raise + finally: + csv_buffer.close() + + +def _persist_compliance_requirement_rows( + tenant_id: str, rows: list[dict[str, Any]], batch_size: int = 10000 +) -> None: + """Persist compliance requirement rows using batched COPY with ORM fallback. + + Splits large row sets into batches to reduce lock duration and improve concurrency. + + Args: + tenant_id: Target tenant UUID. + rows: Precomputed row dictionaries that reflect the compliance + overview state for a scan. + batch_size: Number of rows per COPY batch (default: 10000). + """ + if not rows: + return + + total_rows = len(rows) + total_batches = (total_rows + batch_size - 1) // batch_size + + try: + # Process rows in batches to reduce lock duration + for batch_num in range(total_batches): + start_idx = batch_num * batch_size + end_idx = min(start_idx + batch_size, total_rows) + batch = rows[start_idx:end_idx] + + _copy_compliance_requirement_rows(tenant_id, batch) + + logger.info( + f"Compliance COPY batch {batch_num + 1}/{total_batches}: " + f"inserted {len(batch)} rows ({start_idx + len(batch)}/{total_rows} total)" + ) + except Exception as error: + logger.exception( + "COPY bulk insert for compliance requirements failed; falling back to ORM bulk_create", + exc_info=error, + ) + # Fallback: use ORM bulk_create for all remaining rows + fallback_objects = [ + ComplianceRequirementOverview( + id=row["id"], + tenant_id=row["tenant_id"], + inserted_at=row["inserted_at"], + compliance_id=row["compliance_id"], + framework=row["framework"], + version=row["version"], + description=row["description"], + region=row["region"], + requirement_id=row["requirement_id"], + requirement_status=row["requirement_status"], + passed_checks=row["passed_checks"], + failed_checks=row["failed_checks"], + total_checks=row["total_checks"], + passed_findings=row.get("passed_findings", 0), + total_findings=row.get("total_findings", 0), + scan_id=row["scan_id"], + ) + for row in rows + ] + with rls_transaction(tenant_id): + ComplianceRequirementOverview.objects.bulk_create( + fallback_objects, batch_size=500 + ) + + +def _create_compliance_summaries( + tenant_id: str, scan_id: str, requirement_statuses: dict +) -> None: + """ + Create pre-aggregated compliance summaries from pre-computed requirement statuses. + + This computes the overall compliance scores across all regions for fast + lookup in the main compliance overview endpoint. + + Args: + tenant_id: Target tenant UUID + scan_id: Scan UUID + requirement_statuses: Pre-computed dict of {(compliance_id, requirement_id): {fail_count, pass_count, total_count}} + """ + # Determine per-requirement status and aggregate to compliance level + compliance_summaries = defaultdict( + lambda: { + "total_requirements": 0, + "requirements_passed": 0, + "requirements_failed": 0, + "requirements_manual": 0, + } + ) + + for (compliance_id, requirement_id), counts in requirement_statuses.items(): + # Apply business rule: any FAIL → requirement fails + if counts["fail_count"] > 0: + req_status = "FAIL" + elif counts["pass_count"] == counts["total_count"]: + req_status = "PASS" + else: + req_status = "MANUAL" + + # Aggregate to compliance level + compliance_summaries[compliance_id]["total_requirements"] += 1 + if req_status == "PASS": + compliance_summaries[compliance_id]["requirements_passed"] += 1 + elif req_status == "FAIL": + compliance_summaries[compliance_id]["requirements_failed"] += 1 + else: + compliance_summaries[compliance_id]["requirements_manual"] += 1 + + # Create summary objects + summary_objects = [] + for compliance_id, data in compliance_summaries.items(): + summary_objects.append( + ComplianceOverviewSummary( + tenant_id=tenant_id, + scan_id=scan_id, + compliance_id=compliance_id, + requirements_passed=data["requirements_passed"], + requirements_failed=data["requirements_failed"], + requirements_manual=data["requirements_manual"], + total_requirements=data["total_requirements"], + ) + ) + + # Bulk insert summaries + if summary_objects: + with rls_transaction(tenant_id): + ComplianceOverviewSummary.objects.bulk_create( + summary_objects, batch_size=500 + ) + + +def _normalized_compliance_key(framework: str | None, version: str | None) -> str: + """Return normalized identifier used to group compliance totals.""" + + def _normalize(value: str | None) -> str: + if not value: + return "" + return re.sub(r"[^a-z0-9]", "", value.lower()) + + return f"{_normalize(framework)}{_normalize(version)}" + + +def _process_finding_micro_batch( + tenant_id: str, + findings_batch: list[ProwlerFinding], + scan_instance: Scan, + provider_instance: Provider, + resource_cache: dict, + tag_cache: dict, + last_status_cache: dict, + resource_failed_findings_cache: dict, + unique_resources: set, + scan_resource_cache: set, + mute_rules_cache: dict, +) -> None: + """ + Process a micro-batch of findings and persist them using bulk operations. + + Each batch reuses caches (resources, tags, last statuses, mute rules) to avoid + redundant queries, updates denormalized resource data, and writes findings plus + resource mappings in as few transactions as possible. + + Args: + tenant_id: Tenant owning the scan. + findings_batch: Findings yielded by the Prowler scanner for this slice. + scan_instance: Scan ORM instance being updated. + provider_instance: Provider tied to the scan. + resource_cache: In-memory cache of provider resources indexed by UID. + tag_cache: Cache of `ResourceTag` instances keyed by (key, value). + last_status_cache: Cache of prior finding statuses keyed by finding UID. + resource_failed_findings_cache: Mutable counter of failed findings per resource. + unique_resources: Set tracking (uid, region) pairs seen in the scan. + scan_resource_cache: Set of tuples used to create `ResourceScanSummary` rows. + mute_rules_cache: Map of finding UID -> mute reason gathered before the scan. + """ + # Accumulate objects for bulk operations + findings_to_create = [] + mappings_to_create = [] + dirty_resources = {} + resource_denormalized_data = [] # (finding_instance, resource_instance) pairs + skipped_findings_count = 0 # Track findings skipped due to UID length + + # Prefetch last statuses for all findings in this batch + # TEMPORARY WORKAROUND: Filter out UIDs > 300 chars to avoid query errors + finding_uids = [ + f.uid for f in findings_batch if f is not None and len(f.uid) <= 300 + ] + with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS): + last_statuses = { + item["uid"]: (item["status"], item["first_seen_at"]) + for item in Finding.all_objects.filter( + tenant_id=tenant_id, uid__in=finding_uids + ) + .values("uid", "status", "first_seen_at") + .order_by("uid", "-inserted_at") + .distinct("uid") + } + # Update cache + for uid, data in last_statuses.items(): + if uid not in last_status_cache: + last_status_cache[uid] = data + + # Process each finding in the batch + for finding in findings_batch: + if finding is None: + logger.error(f"None finding detected on scan {scan_instance.id}.") + continue + + # Process resource with deadlock retry + for attempt in range(CELERY_DEADLOCK_ATTEMPTS): + try: + with rls_transaction(tenant_id): + resource_uid = finding.resource_uid + if resource_uid not in resource_cache: + resource_instance, _ = Resource.objects.get_or_create( + tenant_id=tenant_id, + provider=provider_instance, + uid=resource_uid, + defaults={ + "region": finding.region, + "service": finding.service_name, + "type": finding.resource_type, + "name": finding.resource_name, + }, + ) + resource_cache[resource_uid] = resource_instance + resource_failed_findings_cache[resource_uid] = 0 + else: + resource_instance = resource_cache[resource_uid] + break + except (OperationalError, IntegrityError) as db_err: + if attempt < CELERY_DEADLOCK_ATTEMPTS - 1: + logger.warning( + f"{'Deadlock error' if isinstance(db_err, OperationalError) else 'Integrity error'} " + f"detected when processing resource {resource_uid} on scan {scan_instance.id}. Retrying..." + ) + time.sleep(0.1 * (2**attempt)) + continue + else: + raise db_err + + # Track resource field changes (defer save) + updated = False + if finding.region and resource_instance.region != finding.region: + resource_instance.region = finding.region + updated = True + if resource_instance.service != finding.service_name: + resource_instance.service = finding.service_name + updated = True + if resource_instance.type != finding.resource_type: + resource_instance.type = finding.resource_type + updated = True + if resource_instance.metadata != finding.resource_metadata: + resource_instance.metadata = json.dumps( + finding.resource_metadata, cls=CustomEncoder + ) + updated = True + if resource_instance.details != finding.resource_details: + resource_instance.details = finding.resource_details + updated = True + if resource_instance.partition != finding.partition: + resource_instance.partition = finding.partition + updated = True + + if updated: + dirty_resources[resource_uid] = resource_instance + + # Process tags + tags = [] + with rls_transaction(tenant_id): + for key, value in finding.resource_tags.items(): + tag_key = (key, value) + if tag_key not in tag_cache: + tag_instance, _ = ResourceTag.objects.get_or_create( + tenant_id=tenant_id, key=key, value=value + ) + tag_cache[tag_key] = tag_instance + else: + tag_instance = tag_cache[tag_key] + tags.append(tag_instance) + resource_instance.upsert_or_delete_tags(tags=tags) + + unique_resources.add((resource_instance.uid, resource_instance.region)) + + # Prepare finding data + finding_uid = finding.uid + + # TEMPORARY WORKAROUND: Skip findings with UID > 300 chars + # TODO: Remove this after implementing text field migration for finding.uid + if len(finding_uid) > 300: + skipped_findings_count += 1 + logger.warning( + f"Skipping finding with UID exceeding 300 characters. " + f"Length: {len(finding_uid)}, " + f"Check: {finding.check_id}, " + f"Resource: {finding.resource_name}, " + f"UID: {finding_uid}" + ) + continue + + last_status, last_first_seen_at = last_status_cache.get( + finding_uid, (None, None) + ) + + status = FindingStatus[finding.status] + delta = _create_finding_delta(last_status, status) + + if not last_first_seen_at: + last_first_seen_at = datetime.now(tz=timezone.utc) + + # Determine if finding should be muted and why + # Priority: mutelist processor (highest) > manual mute rules + is_muted = False + muted_reason = None + + # Check mutelist processor first (highest priority) + if finding.muted: + is_muted = True + muted_reason = "Muted by mutelist" + # If not muted by mutelist, check manual mute rules + elif finding_uid in mute_rules_cache: + is_muted = True + muted_reason = mute_rules_cache[finding_uid] + + # Increment failed_findings_count cache if needed + if status == FindingStatus.FAIL and not is_muted: + resource_failed_findings_cache[resource_uid] += 1 + + # Create finding object (don't save yet) + finding_instance = Finding( + tenant_id=tenant_id, + uid=finding_uid, + delta=delta, + check_metadata=finding.get_metadata(), + status=status, + status_extended=finding.status_extended, + severity=finding.severity, + impact=finding.severity, + raw_result=finding.raw, + check_id=finding.check_id, + scan=scan_instance, + first_seen_at=last_first_seen_at, + muted=is_muted, + muted_at=datetime.now(tz=timezone.utc) if is_muted else None, + muted_reason=muted_reason, + compliance=finding.compliance, + ) + findings_to_create.append(finding_instance) + resource_denormalized_data.append((finding_instance, resource_instance)) + + # Track for scan summary + scan_resource_cache.add( + ( + str(resource_instance.id), + resource_instance.service, + resource_instance.region, + resource_instance.type, + ) + ) + + # Bulk operations within single transaction + with rls_transaction(tenant_id): + # Bulk create findings + if findings_to_create: + Finding.objects.bulk_create( + findings_to_create, batch_size=SCAN_DB_BATCH_SIZE + ) + + # Bulk create resource-finding mappings + for finding_instance, resource_instance in resource_denormalized_data: + mappings_to_create.append( + ResourceFindingMapping( + tenant_id=tenant_id, + resource=resource_instance, + finding=finding_instance, + ) + ) + + if mappings_to_create: + ResourceFindingMapping.objects.bulk_create( + mappings_to_create, + batch_size=SCAN_DB_BATCH_SIZE, + ignore_conflicts=True, + ) + + # Update finding denormalized arrays + findings_to_update = [] + for finding_instance, resource_instance in resource_denormalized_data: + if not finding_instance.resource_regions: + finding_instance.resource_regions = [] + if not finding_instance.resource_services: + finding_instance.resource_services = [] + if not finding_instance.resource_types: + finding_instance.resource_types = [] + + if resource_instance.region not in finding_instance.resource_regions: + finding_instance.resource_regions.append(resource_instance.region) + if resource_instance.service not in finding_instance.resource_services: + finding_instance.resource_services.append(resource_instance.service) + if resource_instance.type not in finding_instance.resource_types: + finding_instance.resource_types.append(resource_instance.type) + + findings_to_update.append(finding_instance) + + if findings_to_update: + Finding.objects.bulk_update( + findings_to_update, + ["resource_regions", "resource_services", "resource_types"], + batch_size=SCAN_DB_BATCH_SIZE, + ) + + # Bulk update dirty resources + if dirty_resources: + update_objects_in_batches( + tenant_id=tenant_id, + model=Resource, + objects=list(dirty_resources.values()), + fields=["metadata", "details", "partition", "region", "service", "type"], + batch_size=1000, + ) + + # Log skipped findings summary + if skipped_findings_count > 0: + logger.warning( + f"Scan {scan_instance.id}: Skipped {skipped_findings_count} finding(s) " + f"due to UID length exceeding 300 characters in this micro-batch." + ) + + def perform_prowler_scan( tenant_id: str, scan_id: str, @@ -114,20 +639,25 @@ def perform_prowler_scan( checks_to_execute: list[str] | None = None, ): """ - Perform a scan using Prowler and store the findings and resources in the database. + Run a Prowler scan and persist all generated resources, findings, and summaries. + + The scan stream is processed in micro-batches to keep memory bounded while still + benefiting from bulk writes. When the scan completes we also derive + `ResourceScanSummary` rows and return the serialized `Scan` payload used by the + API layer. Args: - tenant_id (str): The ID of the tenant for which the scan is performed. - scan_id (str): The ID of the scan instance. - provider_id (str): The ID of the provider to scan. - checks_to_execute (list[str], optional): A list of specific checks to execute. Defaults to None. + tenant_id: Tenant that owns the scan. + scan_id: UUID of the `Scan` row being executed. + provider_id: Provider to authenticate against. + checks_to_execute: Optional subset of check IDs to run. Returns: - dict: Serialized data of the completed scan instance. + Serialized `ScanTaskSerializer` data for the updated scan. Raises: - ValueError: If the provider cannot be connected. - + ProviderConnectionError: If the provider cannot be validated before scanning. + Exception: Any downstream persistence/processing error (re-raised after cleanup). """ exception = None unique_resources = set() @@ -143,7 +673,7 @@ def perform_prowler_scan( scan_instance.save() # Find the mutelist processor if it exists - with rls_transaction(tenant_id): + with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS): try: mutelist_processor = Processor.objects.get( tenant_id=tenant_id, processor_type=Processor.ProcessorChoices.MUTELIST @@ -154,6 +684,21 @@ def perform_prowler_scan( logger.error(f"Error processing mutelist rules: {e}") mutelist_processor = None + # Load enabled mute rules for this tenant + with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS): + try: + active_mute_rules = MuteRule.objects.filter( + tenant_id=tenant_id, enabled=True + ).values_list("finding_uids", "reason") + + mute_rules_cache = {} + for finding_uids, reason in active_mute_rules: + for uid in finding_uids: + mute_rules_cache[uid] = reason + except Exception as e: + logger.error(f"Error loading mute rules: {e}") + mute_rules_cache = {} + try: with rls_transaction(tenant_id): try: @@ -186,158 +731,26 @@ def perform_prowler_scan( resource_failed_findings_cache = defaultdict(int) for progress, findings in prowler_scan.scan(): - for finding in findings: - if finding is None: - logger.error(f"None finding detected on scan {scan_id}.") - continue - for attempt in range(CELERY_DEADLOCK_ATTEMPTS): - try: - with rls_transaction(tenant_id): - # Process resource - resource_uid = finding.resource_uid - if resource_uid not in resource_cache: - # Get or create the resource - resource_instance, _ = Resource.objects.get_or_create( - tenant_id=tenant_id, - provider=provider_instance, - uid=resource_uid, - defaults={ - "region": finding.region, - "service": finding.service_name, - "type": finding.resource_type, - "name": finding.resource_name, - }, - ) - resource_cache[resource_uid] = resource_instance + # Process findings in micro-batches + findings_list = list(findings) + total_findings = len(findings_list) - # Initialize all processed resources in the cache - resource_failed_findings_cache[resource_uid] = 0 - else: - resource_instance = resource_cache[resource_uid] + # Chunk findings into micro-batches + for i in range(0, total_findings, FINDINGS_MICRO_BATCH_SIZE): + micro_batch = findings_list[i : i + FINDINGS_MICRO_BATCH_SIZE] - # Update resource fields if necessary - updated_fields = [] - if ( - finding.region - and resource_instance.region != finding.region - ): - resource_instance.region = finding.region - updated_fields.append("region") - if resource_instance.service != finding.service_name: - resource_instance.service = finding.service_name - updated_fields.append("service") - if resource_instance.type != finding.resource_type: - resource_instance.type = finding.resource_type - updated_fields.append("type") - if resource_instance.metadata != finding.resource_metadata: - resource_instance.metadata = json.dumps( - finding.resource_metadata, cls=CustomEncoder - ) - updated_fields.append("metadata") - if resource_instance.details != finding.resource_details: - resource_instance.details = finding.resource_details - updated_fields.append("details") - if resource_instance.partition != finding.partition: - resource_instance.partition = finding.partition - updated_fields.append("partition") - if updated_fields: - with rls_transaction(tenant_id): - resource_instance.save(update_fields=updated_fields) - except (OperationalError, IntegrityError) as db_err: - if attempt < CELERY_DEADLOCK_ATTEMPTS - 1: - logger.warning( - f"{'Deadlock error' if isinstance(db_err, OperationalError) else 'Integrity error'} " - f"detected when processing resource {resource_uid} on scan {scan_id}. Retrying..." - ) - time.sleep(0.1 * (2**attempt)) - continue - else: - raise db_err - - # Update tags - tags = [] - with rls_transaction(tenant_id): - for key, value in finding.resource_tags.items(): - tag_key = (key, value) - if tag_key not in tag_cache: - tag_instance, _ = ResourceTag.objects.get_or_create( - tenant_id=tenant_id, key=key, value=value - ) - tag_cache[tag_key] = tag_instance - else: - tag_instance = tag_cache[tag_key] - tags.append(tag_instance) - resource_instance.upsert_or_delete_tags(tags=tags) - - unique_resources.add((resource_instance.uid, resource_instance.region)) - - # Process finding - with rls_transaction(tenant_id): - finding_uid = finding.uid - last_first_seen_at = None - if finding_uid not in last_status_cache: - most_recent_finding = ( - Finding.all_objects.filter( - tenant_id=tenant_id, uid=finding_uid - ) - .order_by("-inserted_at") - .values("status", "first_seen_at") - .first() - ) - last_status = None - if most_recent_finding: - last_status = most_recent_finding["status"] - last_first_seen_at = most_recent_finding["first_seen_at"] - last_status_cache[finding_uid] = last_status, last_first_seen_at - else: - last_status, last_first_seen_at = last_status_cache[finding_uid] - - status = FindingStatus[finding.status] - delta = _create_finding_delta(last_status, status) - # For the findings prior to the change, when a first finding is found with delta!="new" it will be - # assigned a current date as first_seen_at and the successive findings with the same UID will - # always get the date of the previous finding. - # For new findings, when a finding (delta="new") is found for the first time, the first_seen_at - # attribute will be assigned the current date, the following findings will get that date. - if not last_first_seen_at: - last_first_seen_at = datetime.now(tz=timezone.utc) - - # If the finding is muted at this time the reason must be the configured Mutelist - muted_reason = "Muted by mutelist" if finding.muted else None - - # Create the finding - finding_instance = Finding.objects.create( - tenant_id=tenant_id, - uid=finding_uid, - delta=delta, - check_metadata=finding.get_metadata(), - status=status, - status_extended=finding.status_extended, - severity=finding.severity, - impact=finding.severity, - raw_result=finding.raw, - check_id=finding.check_id, - scan=scan_instance, - first_seen_at=last_first_seen_at, - muted=finding.muted, - muted_reason=muted_reason, - compliance=finding.compliance, - ) - finding_instance.add_resources([resource_instance]) - - # Increment failed_findings_count cache if the finding status is FAIL and not muted - if status == FindingStatus.FAIL and not finding.muted: - resource_uid = finding.resource_uid - resource_failed_findings_cache[resource_uid] += 1 - - # Update scan resource summaries - scan_resource_cache.add( - ( - str(resource_instance.id), - resource_instance.service, - resource_instance.region, - resource_instance.type, - ) + _process_finding_micro_batch( + tenant_id=tenant_id, + findings_batch=micro_batch, + scan_instance=scan_instance, + provider_instance=provider_instance, + resource_cache=resource_cache, + tag_cache=tag_cache, + last_status_cache=last_status_cache, + resource_failed_findings_cache=resource_failed_findings_cache, + unique_resources=unique_resources, + scan_resource_cache=scan_resource_cache, + mute_rules_cache=mute_rules_cache, ) # Update scan progress @@ -410,36 +823,17 @@ def perform_prowler_scan( def aggregate_findings(tenant_id: str, scan_id: str): """ - Aggregates findings for a given scan and stores the results in the ScanSummary table. + Aggregate findings for a scan and populate `ScanSummary` rows. - This function retrieves all findings associated with a given `scan_id` and calculates various - metrics such as counts of failed, passed, and muted findings, as well as their deltas (new, - changed, unchanged). The results are grouped by `check_id`, `service`, `severity`, and `region`. - These aggregated metrics are then stored in the `ScanSummary` table. - - Additionally, it updates the failed_findings_count field for each resource based on the most - recent findings for each finding.uid. + We group findings by check/service/severity/region and compute pass/fail/muted + totals plus delta counts (new/changed/unchanged). The summary dataset feeds the + overview API and dashboards, so it is recomputed every time a scan finishes. Args: - tenant_id (str): The ID of the tenant to which the scan belongs. - scan_id (str): The ID of the scan for which findings need to be aggregated. - - Aggregated Metrics: - - fail: Total number of failed findings. - - _pass: Total number of passed findings. - - muted: Total number of muted findings. - - total: Total number of findings. - - new: Total number of new findings. - - changed: Total number of changed findings. - - unchanged: Total number of unchanged findings. - - fail_new: Failed findings with a delta of 'new'. - - fail_changed: Failed findings with a delta of 'changed'. - - pass_new: Passed findings with a delta of 'new'. - - pass_changed: Passed findings with a delta of 'changed'. - - muted_new: Muted findings with a delta of 'new'. - - muted_changed: Muted findings with a delta of 'changed'. + tenant_id: Tenant that owns the scan. + scan_id: Scan UUID whose findings should be aggregated. """ - with rls_transaction(tenant_id): + with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS): findings = Finding.objects.filter(tenant_id=tenant_id, scan_id=scan_id) aggregation = findings.values( @@ -563,34 +957,35 @@ def aggregate_findings(tenant_id: str, scan_id: str): ScanSummary.objects.bulk_create(scan_aggregations, batch_size=3000) -def create_compliance_requirements(tenant_id: str, scan_id: str): +def _aggregate_findings_by_region( + tenant_id: str, scan_id: str, modeled_threatscore_compliance_id: str +) -> tuple[dict, dict]: """ - Create detailed compliance requirement overview records for a scan. + Aggregate findings by region using optimized ORM queries. - This function processes the compliance data collected during a scan and creates - individual records for each compliance requirement in each region. These detailed - records provide a granular view of compliance status. + Replaces nested Python loops with efficient queries and aggregation. Args: - tenant_id (str): The ID of the tenant for which to create records. - scan_id (str): The ID of the scan for which to create records. + tenant_id: Tenant UUID + scan_id: Scan UUID + modeled_threatscore_compliance_id: ID for ThreatScore compliance framework Returns: - dict: A dictionary containing the number of requirements created and the regions processed. - - Raises: - ValidationError: If tenant_id is not a valid UUID. + tuple: (check_status_by_region, findings_count_by_compliance) + - check_status_by_region: {region: {check_id: status}} + - findings_count_by_compliance: {region: {normalized_id: {requirement_id: {total, pass}}}} """ - try: - with rls_transaction(tenant_id): - scan_instance = Scan.objects.get(pk=scan_id) - provider_instance = scan_instance.provider - prowler_provider = return_prowler_provider(provider_instance) + check_status_by_region = {} + findings_count_by_compliance = {} - # Get check status data by region from findings + with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS): + # Fetch findings with resources in a single efficient query + # Use select_related for finding fields and prefetch_related for many-to-many resources findings = ( - Finding.all_objects.filter(scan_id=scan_id, muted=False) - .only("id", "check_id", "status") + Finding.all_objects.filter( + tenant_id=tenant_id, scan_id=scan_id, muted=False + ) + .only("id", "check_id", "status", "compliance") .prefetch_related( Prefetch( "resources", @@ -598,83 +993,198 @@ def create_compliance_requirements(tenant_id: str, scan_id: str): to_attr="small_resources", ) ) - .iterator(chunk_size=1000) ) - check_status_by_region = {} - with rls_transaction(tenant_id): - for finding in findings: - for resource in finding.small_resources: - region = resource.region - current_status = check_status_by_region.setdefault(region, {}) - if current_status.get(finding.check_id) != "FAIL": - current_status[finding.check_id] = finding.status + # Process findings in a single pass (more efficient than original nested loops) + normalized_id = re.sub( + r"[^a-z0-9]", "", modeled_threatscore_compliance_id.lower() + ) - try: - # Try to get regions from provider - regions = prowler_provider.get_regions() - except (AttributeError, Exception): - # If not available, use regions from findings - regions = set(check_status_by_region.keys()) + for finding in findings: + for resource in finding.small_resources: + region = resource.region + + # Aggregate check status by region + current_status = check_status_by_region.setdefault(region, {}) + # Priority: FAIL > any other status + if current_status.get(finding.check_id) != "FAIL": + current_status[finding.check_id] = finding.status + + # Aggregate ThreatScore compliance counts + if modeled_threatscore_compliance_id in (finding.compliance or {}): + compliance_key = findings_count_by_compliance.setdefault( + region, {} + ).setdefault(normalized_id, {}) + + for requirement_id in finding.compliance[ + modeled_threatscore_compliance_id + ]: + requirement_stats = compliance_key.setdefault( + requirement_id, {"total": 0, "pass": 0} + ) + requirement_stats["total"] += 1 + if finding.status == "PASS": + requirement_stats["pass"] += 1 + + return check_status_by_region, findings_count_by_compliance + + +def create_compliance_requirements(tenant_id: str, scan_id: str): + """ + Materialize per-requirement compliance rows (and summaries) for a scan. + + Using the provider’s compliance template plus the scan’s findings, we compute a + row per (region, compliance, requirement) and write it to + `ComplianceRequirementOverview` via COPY. The same pass tally requirement + statuses so we can persist `ComplianceOverviewSummary` records for the fast + overview endpoint. + + Args: + tenant_id: Tenant running the scan. + scan_id: Scan identifier whose findings should be translated into compliance data. + + Returns: + dict: Counts/metadata about the generated rows (e.g., frameworks touched, regions processed). + """ + try: + with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS): + scan_instance = Scan.objects.get(pk=scan_id) + provider_instance = scan_instance.provider + return_prowler_provider(provider_instance) - # Get compliance template for the provider compliance_template = PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE[ provider_instance.provider ] + modeled_threatscore_compliance_id = "ProwlerThreatScore-1.0" - # Create compliance data by region - compliance_overview_by_region = { - region: deepcopy(compliance_template) for region in regions - } - - # Apply check statuses to compliance data - for region, check_status in check_status_by_region.items(): - compliance_data = compliance_overview_by_region.setdefault( - region, deepcopy(compliance_template) - ) - for check_name, status in check_status.items(): - generate_scan_compliance( - compliance_data, - provider_instance.provider, - check_name, - status, - ) - - # Prepare compliance requirement objects - compliance_requirement_objects = [] - for region, compliance_data in compliance_overview_by_region.items(): - for compliance_id, compliance in compliance_data.items(): - # Create an overview record for each requirement within each compliance framework - for requirement_id, requirement in compliance["requirements"].items(): - compliance_requirement_objects.append( - ComplianceRequirementOverview( - tenant_id=tenant_id, - scan=scan_instance, - region=region, - compliance_id=compliance_id, - framework=compliance["framework"], - version=compliance["version"], - requirement_id=requirement_id, - description=requirement["description"], - passed_checks=requirement["checks_status"]["pass"], - failed_checks=requirement["checks_status"]["fail"], - total_checks=requirement["checks_status"]["total"], - requirement_status=requirement["status"], - ) + requirement_lookup: dict[str, list[tuple[str, str]]] = {} + for compliance_id, compliance in compliance_template.items(): + for requirement_id, requirement in compliance["requirements"].items(): + for check_id in requirement["checks"].keys(): + requirement_lookup.setdefault(check_id, []).append( + (compliance_id, requirement_id) ) - # Bulk create requirement records - create_objects_in_batches( - tenant_id, ComplianceRequirementOverview, compliance_requirement_objects + compliance_requirement_rows: list[dict[str, Any]] = [] + regions = [] + requirement_statuses = defaultdict( + lambda: {"fail_count": 0, "pass_count": 0, "total_count": 0} ) + # Skip if provider has no compliance frameworks + if compliance_template: + # Aggregate findings by region using SQL for optimal performance + check_status_by_region, findings_count_by_compliance = ( + _aggregate_findings_by_region( + tenant_id, scan_id, modeled_threatscore_compliance_id + ) + ) + + # Only process regions that have findings (optimization: reduces row count) + regions = list(check_status_by_region.keys()) + + region_requirement_stats: dict[ + str, dict[str, dict[str, dict[str, int]]] + ] = defaultdict(lambda: defaultdict(dict)) + for region, check_status in check_status_by_region.items(): + for check_name, status in check_status.items(): + targets = requirement_lookup.get(check_name) + if not targets: + continue + status_lower = (status or "").lower() + if status_lower not in {"pass", "fail"}: + continue + for compliance_id, requirement_id in targets: + compliance_stats = region_requirement_stats[region].setdefault( + compliance_id, {} + ) + requirement_stats = compliance_stats.setdefault( + requirement_id, {"passed_checks": 0, "failed_checks": 0} + ) + if status_lower == "pass": + requirement_stats["passed_checks"] += 1 + else: + requirement_stats["failed_checks"] += 1 + + # Prepare compliance requirement rows and compute summaries in single pass + utc_datetime_now = datetime.now(tz=timezone.utc) + + # Pre-compute shared strings (optimization: reduces string conversions) + tenant_id_str = str(tenant_id) + scan_id_str = str(scan_instance.id) + + for region in regions: + region_stats = region_requirement_stats.get(region, {}) + for compliance_id, compliance in compliance_template.items(): + modeled_compliance_id = _normalized_compliance_key( + compliance["framework"], compliance["version"] + ) + compliance_stats = region_stats.get(compliance_id, {}) + # Create an overview record for each requirement within each compliance framework + for requirement_id, requirement in compliance[ + "requirements" + ].items(): + stats = compliance_stats.get(requirement_id) + passed_checks = stats["passed_checks"] if stats else 0 + failed_checks = stats["failed_checks"] if stats else 0 + total_checks = len(requirement["checks"]) + if total_checks == 0: + requirement_status = "MANUAL" + elif failed_checks > 0: + requirement_status = "FAIL" + else: + requirement_status = "PASS" + + compliance_requirement_rows.append( + { + "id": uuid.uuid4(), + "tenant_id": tenant_id_str, + "inserted_at": utc_datetime_now, + "compliance_id": compliance_id, + "framework": compliance["framework"], + "version": compliance["version"] or "", + "description": requirement.get("description") or "", + "region": region, + "requirement_id": requirement_id, + "requirement_status": requirement_status, + "passed_checks": passed_checks, + "failed_checks": failed_checks, + "total_checks": total_checks, + "scan_id": scan_id_str, + "passed_findings": findings_count_by_compliance.get( + region, {} + ) + .get(modeled_compliance_id, {}) + .get(requirement_id, {}) + .get("pass", 0), + "total_findings": findings_count_by_compliance.get( + region, {} + ) + .get(modeled_compliance_id, {}) + .get(requirement_id, {}) + .get("total", 0), + } + ) + + # Update summary tracking (single-pass optimization) + key = (compliance_id, requirement_id) + requirement_statuses[key]["total_count"] += 1 + if requirement_status == "FAIL": + requirement_statuses[key]["fail_count"] += 1 + elif requirement_status == "PASS": + requirement_statuses[key]["pass_count"] += 1 + + # Bulk create requirement records using PostgreSQL COPY + _persist_compliance_requirement_rows(tenant_id, compliance_requirement_rows) + + # Create pre-aggregated summaries for fast compliance overview lookups + _create_compliance_summaries(tenant_id, scan_id, requirement_statuses) + return { - "requirements_created": len(compliance_requirement_objects), + "requirements_created": len(compliance_requirement_rows), "regions_processed": list(regions), "compliance_frameworks": ( - list(compliance_overview_by_region.get(list(regions)[0], {}).keys()) - if regions - else [] + list(compliance_template.keys()) if regions else [] ), } diff --git a/api/src/backend/tasks/jobs/threatscore.py b/api/src/backend/tasks/jobs/threatscore.py new file mode 100644 index 0000000000..414f2d20f2 --- /dev/null +++ b/api/src/backend/tasks/jobs/threatscore.py @@ -0,0 +1,214 @@ +from celery.utils.log import get_task_logger +from tasks.jobs.threatscore_utils import ( + _aggregate_requirement_statistics_from_database, + _calculate_requirements_data_from_statistics, +) + +from api.db_router import READ_REPLICA_ALIAS +from api.db_utils import rls_transaction +from api.models import Provider, StatusChoices +from prowler.lib.check.compliance_models import Compliance + +logger = get_task_logger(__name__) + + +def compute_threatscore_metrics( + tenant_id: str, + scan_id: str, + provider_id: str, + compliance_id: str, + min_risk_level: int = 4, +) -> dict: + """ + Compute ThreatScore metrics for a given scan. + + This function calculates all the metrics needed for a ThreatScore snapshot: + - Overall ThreatScore percentage + - Section-by-section scores + - Critical failed requirements (risk >= min_risk_level) + - Summary statistics (requirements and findings counts) + + Args: + tenant_id (str): The tenant ID for Row-Level Security context. + scan_id (str): The ID of the scan to analyze. + provider_id (str): The ID of the provider used in the scan. + compliance_id (str): Compliance framework ID (e.g., "prowler_threatscore_aws"). + min_risk_level (int): Minimum risk level for critical requirements. Defaults to 4. + + Returns: + dict: A dictionary containing: + - overall_score (float): Overall ThreatScore percentage (0-100) + - section_scores (dict): Section name -> score percentage mapping + - critical_requirements (list): List of critical failed requirement dicts + - total_requirements (int): Total number of requirements + - passed_requirements (int): Number of PASS requirements + - failed_requirements (int): Number of FAIL requirements + - manual_requirements (int): Number of MANUAL requirements + - total_findings (int): Total findings count + - passed_findings (int): Passed findings count + - failed_findings (int): Failed findings count + + Example: + >>> metrics = compute_threatscore_metrics( + ... tenant_id="tenant-123", + ... scan_id="scan-456", + ... provider_id="provider-789", + ... compliance_id="prowler_threatscore_aws" + ... ) + >>> print(f"Overall ThreatScore: {metrics['overall_score']:.2f}%") + """ + # Get provider and compliance information + with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS): + provider_obj = Provider.objects.get(id=provider_id) + provider_type = provider_obj.provider + + frameworks_bulk = Compliance.get_bulk(provider_type) + compliance_obj = frameworks_bulk[compliance_id] + + # Aggregate requirement statistics from database + requirement_statistics_by_check_id = ( + _aggregate_requirement_statistics_from_database(tenant_id, scan_id) + ) + + # Calculate requirements data using aggregated statistics + attributes_by_requirement_id, requirements_list = ( + _calculate_requirements_data_from_statistics( + compliance_obj, requirement_statistics_by_check_id + ) + ) + + # Initialize metrics + overall_numerator = 0 + overall_denominator = 0 + overall_has_findings = False + + sections_data = {} + + total_requirements = len(requirements_list) + passed_requirements = 0 + failed_requirements = 0 + manual_requirements = 0 + total_findings = 0 + passed_findings = 0 + failed_findings = 0 + + critical_requirements_list = [] + + # Process each requirement + for requirement in requirements_list: + requirement_id = requirement["id"] + requirement_status = requirement["attributes"]["status"] + requirement_attributes = attributes_by_requirement_id.get(requirement_id, {}) + + # Count requirements by status + if requirement_status == StatusChoices.PASS: + passed_requirements += 1 + elif requirement_status == StatusChoices.FAIL: + failed_requirements += 1 + elif requirement_status == StatusChoices.MANUAL: + manual_requirements += 1 + + # Get findings data + req_passed_findings = requirement["attributes"].get("passed_findings", 0) + req_total_findings = requirement["attributes"].get("total_findings", 0) + + # Accumulate findings counts + total_findings += req_total_findings + passed_findings += req_passed_findings + failed_findings += req_total_findings - req_passed_findings + + # Skip requirements with no findings + if req_total_findings == 0: + continue + + overall_has_findings = True + + # Get requirement metadata + metadata = requirement_attributes.get("attributes", {}).get( + "req_attributes", [] + ) + if not metadata or len(metadata) == 0: + continue + + m = metadata[0] + risk_level = getattr(m, "LevelOfRisk", 0) + weight = getattr(m, "Weight", 0) + section = getattr(m, "Section", "Unknown") + + # Calculate ThreatScore components using formula from UI + rate_i = req_passed_findings / req_total_findings + rfac_i = 1 + 0.25 * risk_level + + # Update overall score + overall_numerator += rate_i * req_total_findings * weight * rfac_i + overall_denominator += req_total_findings * weight * rfac_i + + # Update section scores + if section not in sections_data: + sections_data[section] = { + "numerator": 0, + "denominator": 0, + "has_findings": False, + } + + sections_data[section]["has_findings"] = True + sections_data[section]["numerator"] += ( + rate_i * req_total_findings * weight * rfac_i + ) + sections_data[section]["denominator"] += req_total_findings * weight * rfac_i + + # Identify critical failed requirements + if requirement_status == StatusChoices.FAIL and risk_level >= min_risk_level: + critical_requirements_list.append( + { + "requirement_id": requirement_id, + "title": getattr(m, "Title", "N/A"), + "section": section, + "subsection": getattr(m, "SubSection", "N/A"), + "risk_level": risk_level, + "weight": weight, + "passed_findings": req_passed_findings, + "total_findings": req_total_findings, + "description": getattr(m, "AttributeDescription", "N/A"), + } + ) + + # Calculate overall ThreatScore + if not overall_has_findings: + overall_score = 100.0 + elif overall_denominator > 0: + overall_score = (overall_numerator / overall_denominator) * 100 + else: + overall_score = 0.0 + + # Calculate section scores + section_scores = {} + for section, data in sections_data.items(): + if data["has_findings"] and data["denominator"] > 0: + section_scores[section] = (data["numerator"] / data["denominator"]) * 100 + else: + section_scores[section] = 100.0 + + # Sort critical requirements by risk level (desc) and weight (desc) + critical_requirements_list.sort( + key=lambda x: (x["risk_level"], x["weight"]), reverse=True + ) + + logger.info( + f"ThreatScore computed: {overall_score:.2f}% " + f"({passed_requirements}/{total_requirements} requirements passed, " + f"{len(critical_requirements_list)} critical failures)" + ) + + return { + "overall_score": round(overall_score, 2), + "section_scores": {k: round(v, 2) for k, v in section_scores.items()}, + "critical_requirements": critical_requirements_list, + "total_requirements": total_requirements, + "passed_requirements": passed_requirements, + "failed_requirements": failed_requirements, + "manual_requirements": manual_requirements, + "total_findings": total_findings, + "passed_findings": passed_findings, + "failed_findings": failed_findings, + } diff --git a/api/src/backend/tasks/jobs/threatscore_utils.py b/api/src/backend/tasks/jobs/threatscore_utils.py new file mode 100644 index 0000000000..bc2cb009a2 --- /dev/null +++ b/api/src/backend/tasks/jobs/threatscore_utils.py @@ -0,0 +1,127 @@ +from celery.utils.log import get_task_logger +from django.db.models import Count, Q + +from api.db_router import READ_REPLICA_ALIAS +from api.db_utils import rls_transaction +from api.models import Finding, StatusChoices + +logger = get_task_logger(__name__) + + +def _aggregate_requirement_statistics_from_database( + tenant_id: str, scan_id: str +) -> dict[str, dict[str, int]]: + """ + Aggregate finding statistics by check_id using database aggregation. + + This function uses Django ORM aggregation to calculate pass/fail statistics + entirely in the database, avoiding the need to load findings into memory. + + Args: + tenant_id (str): The tenant ID for Row-Level Security context. + scan_id (str): The ID of the scan to retrieve findings for. + + Returns: + dict[str, dict[str, int]]: Dictionary mapping check_id to statistics: + - 'passed' (int): Number of passed findings for this check + - 'total' (int): Total number of findings for this check + + Example: + { + 'aws_iam_user_mfa_enabled': {'passed': 10, 'total': 15}, + 'aws_s3_bucket_public_access': {'passed': 0, 'total': 5} + } + """ + requirement_statistics_by_check_id = {} + + with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS): + aggregated_statistics_queryset = ( + Finding.all_objects.filter(tenant_id=tenant_id, scan_id=scan_id) + .values("check_id") + .annotate( + total_findings=Count("id"), + passed_findings=Count("id", filter=Q(status=StatusChoices.PASS)), + ) + ) + + for aggregated_stat in aggregated_statistics_queryset: + check_id = aggregated_stat["check_id"] + requirement_statistics_by_check_id[check_id] = { + "passed": aggregated_stat["passed_findings"], + "total": aggregated_stat["total_findings"], + } + + logger.info( + f"Aggregated statistics for {len(requirement_statistics_by_check_id)} unique checks" + ) + return requirement_statistics_by_check_id + + +def _calculate_requirements_data_from_statistics( + compliance_obj, requirement_statistics_by_check_id: dict[str, dict[str, int]] +) -> tuple[dict[str, dict], list[dict]]: + """ + Calculate requirement status and statistics using pre-aggregated database statistics. + + Args: + compliance_obj: The compliance framework object containing requirements. + requirement_statistics_by_check_id (dict[str, dict[str, int]]): Pre-aggregated statistics + mapping check_id to {'passed': int, 'total': int} counts. + + Returns: + tuple[dict[str, dict], list[dict]]: A tuple containing: + - attributes_by_requirement_id: Dictionary mapping requirement IDs to their attributes. + - requirements_list: List of requirement dictionaries with status and statistics. + """ + attributes_by_requirement_id = {} + requirements_list = [] + + compliance_framework = getattr(compliance_obj, "Framework", "N/A") + compliance_version = getattr(compliance_obj, "Version", "N/A") + + for requirement in compliance_obj.Requirements: + requirement_id = requirement.Id + requirement_description = getattr(requirement, "Description", "") + requirement_checks = getattr(requirement, "Checks", []) + requirement_attributes = getattr(requirement, "Attributes", []) + + attributes_by_requirement_id[requirement_id] = { + "attributes": { + "req_attributes": requirement_attributes, + "checks": requirement_checks, + }, + "description": requirement_description, + } + + total_passed_findings = 0 + total_findings_count = 0 + + for check_id in requirement_checks: + if check_id in requirement_statistics_by_check_id: + check_statistics = requirement_statistics_by_check_id[check_id] + total_findings_count += check_statistics["total"] + total_passed_findings += check_statistics["passed"] + + if total_findings_count > 0: + if total_passed_findings == total_findings_count: + requirement_status = StatusChoices.PASS + else: + requirement_status = StatusChoices.FAIL + else: + requirement_status = StatusChoices.MANUAL + + requirements_list.append( + { + "id": requirement_id, + "attributes": { + "framework": compliance_framework, + "version": compliance_version, + "status": requirement_status, + "description": requirement_description, + "passed_findings": total_passed_findings, + "total_findings": total_findings_count, + }, + } + ) + + return attributes_by_requirement_id, requirements_list diff --git a/api/src/backend/tasks/tasks.py b/api/src/backend/tasks/tasks.py index 872db504fb..9524a1b985 100644 --- a/api/src/backend/tasks/tasks.py +++ b/api/src/backend/tasks/tasks.py @@ -1,3 +1,4 @@ +import os from datetime import datetime, timedelta, timezone from pathlib import Path from shutil import rmtree @@ -7,7 +8,10 @@ from celery.utils.log import get_task_logger from config.celery import RLSTask from config.django.base import DJANGO_FINDINGS_BATCH_SIZE, DJANGO_TMP_OUTPUT_DIRECTORY from django_celery_beat.models import PeriodicTask -from tasks.jobs.backfill import backfill_resource_scan_summaries +from tasks.jobs.backfill import ( + backfill_compliance_summaries, + backfill_resource_scan_summaries, +) from tasks.jobs.connection import ( check_integration_connection, check_lighthouse_connection, @@ -22,9 +26,16 @@ from tasks.jobs.export import ( _upload_to_s3, ) from tasks.jobs.integrations import ( + send_findings_to_jira, upload_s3_integration, upload_security_hub_integration, ) +from tasks.jobs.lighthouse_providers import ( + check_lighthouse_provider_connection, + refresh_lighthouse_provider_models, +) +from tasks.jobs.muting import mute_historical_findings +from tasks.jobs.report import generate_threatscore_report_job from tasks.jobs.scan import ( aggregate_findings, create_compliance_requirements, @@ -33,6 +44,7 @@ from tasks.jobs.scan import ( from tasks.utils import batched, get_next_execution_datetime from api.compliance import get_compliance_frameworks +from api.db_router import READ_REPLICA_ALIAS from api.db_utils import rls_transaction from api.decorators import set_tenant from api.models import Finding, Integration, Provider, Scan, ScanSummary, StateChoices @@ -62,10 +74,15 @@ def _perform_scan_complete_tasks(tenant_id: str, scan_id: str, provider_id: str) generate_outputs_task.si( scan_id=scan_id, provider_id=provider_id, tenant_id=tenant_id ), - check_integrations_task.si( - tenant_id=tenant_id, - provider_id=provider_id, - scan_id=scan_id, + group( + generate_threatscore_report_task.si( + tenant_id=tenant_id, scan_id=scan_id, provider_id=provider_id + ), + check_integrations_task.si( + tenant_id=tenant_id, + provider_id=provider_id, + scan_id=scan_id, + ), ), ).apply_async() @@ -302,7 +319,7 @@ def generate_outputs_task(scan_id: str, provider_id: str, tenant_id: str): frameworks_bulk = Compliance.get_bulk(provider_type) frameworks_avail = get_compliance_frameworks(provider_type) - out_dir, comp_dir = _generate_output_directory( + out_dir, comp_dir, _ = _generate_output_directory( DJANGO_TMP_OUTPUT_DIRECTORY, provider_uid, tenant_id, scan_id ) @@ -342,70 +359,90 @@ def generate_outputs_task(scan_id: str, provider_id: str, tenant_id: str): .order_by("uid") .iterator() ) - for batch, is_last in batched(qs, DJANGO_FINDINGS_BATCH_SIZE): - fos = [FindingOutput.transform_api_finding(f, prowler_provider) for f in batch] + with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS): + for batch, is_last in batched(qs, DJANGO_FINDINGS_BATCH_SIZE): + fos = [ + FindingOutput.transform_api_finding(f, prowler_provider) for f in batch + ] - # Outputs - for mode, cfg in OUTPUT_FORMATS_MAPPING.items(): - # Skip ASFF generation if not needed - if mode == "json-asff" and not generate_asff: - continue + # Outputs + for mode, cfg in OUTPUT_FORMATS_MAPPING.items(): + # Skip ASFF generation if not needed + if mode == "json-asff" and not generate_asff: + continue - cls = cfg["class"] - suffix = cfg["suffix"] - extra = cfg.get("kwargs", {}).copy() - if mode == "html": - extra.update(provider=prowler_provider, stats=scan_summary) + cls = cfg["class"] + suffix = cfg["suffix"] + extra = cfg.get("kwargs", {}).copy() + if mode == "html": + extra.update(provider=prowler_provider, stats=scan_summary) - writer, initialization = get_writer( - output_writers, - cls, - lambda cls=cls, fos=fos, suffix=suffix: cls( - findings=fos, - file_path=out_dir, - file_extension=suffix, - from_cli=False, - ), - is_last, - ) - if not initialization: - writer.transform(fos) - writer.batch_write_data_to_file(**extra) - writer._data.clear() + writer, initialization = get_writer( + output_writers, + cls, + lambda cls=cls, fos=fos, suffix=suffix: cls( + findings=fos, + file_path=out_dir, + file_extension=suffix, + from_cli=False, + ), + is_last, + ) + if not initialization: + writer.transform(fos) + writer.batch_write_data_to_file(**extra) + writer._data.clear() - # Compliance CSVs - for name in frameworks_avail: - compliance_obj = frameworks_bulk[name] + # Compliance CSVs + for name in frameworks_avail: + compliance_obj = frameworks_bulk[name] - klass = GenericCompliance - for condition, cls in COMPLIANCE_CLASS_MAP.get(provider_type, []): - if condition(name): - klass = cls - break + klass = GenericCompliance + for condition, cls in COMPLIANCE_CLASS_MAP.get(provider_type, []): + if condition(name): + klass = cls + break - filename = f"{comp_dir}_{name}.csv" + filename = f"{comp_dir}_{name}.csv" - writer, initialization = get_writer( - compliance_writers, - name, - lambda klass=klass, fos=fos: klass( - findings=fos, - compliance=compliance_obj, - file_path=filename, - from_cli=False, - ), - is_last, - ) - if not initialization: - writer.transform(fos, compliance_obj, name) - writer.batch_write_data_to_file() - writer._data.clear() + writer, initialization = get_writer( + compliance_writers, + name, + lambda klass=klass, fos=fos: klass( + findings=fos, + compliance=compliance_obj, + file_path=filename, + from_cli=False, + ), + is_last, + ) + if not initialization: + writer.transform(fos, compliance_obj, name) + writer.batch_write_data_to_file() + writer._data.clear() compressed = _compress_output_files(out_dir) - upload_uri = _upload_to_s3(tenant_id, compressed, scan_id) + + upload_uri = _upload_to_s3( + tenant_id, + scan_id, + compressed, + os.path.basename(compressed), + ) + + compliance_dir_path = Path(comp_dir).parent + if compliance_dir_path.exists(): + for artifact_path in sorted(compliance_dir_path.iterdir()): + if artifact_path.is_file(): + _upload_to_s3( + tenant_id, + scan_id, + str(artifact_path), + f"compliance/{artifact_path.name}", + ) # S3 integrations (need output_directory) - with rls_transaction(tenant_id): + with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS): s3_integrations = Integration.objects.filter( integrationproviderrelationship__provider_id=provider_id, integration_type=Integration.IntegrationChoices.AMAZON_S3, @@ -460,7 +497,22 @@ def backfill_scan_resource_summaries_task(tenant_id: str, scan_id: str): return backfill_resource_scan_summaries(tenant_id=tenant_id, scan_id=scan_id) -@shared_task(base=RLSTask, name="scan-compliance-overviews", queue="overview") +@shared_task(name="backfill-compliance-summaries", queue="backfill") +def backfill_compliance_summaries_task(tenant_id: str, scan_id: str): + """ + Tries to backfill compliance overview summaries for a completed scan. + + This task aggregates compliance requirement data across regions + to create pre-computed summary records for fast compliance overview queries. + + Args: + tenant_id (str): The tenant identifier. + scan_id (str): The scan identifier. + """ + return backfill_compliance_summaries(tenant_id=tenant_id, scan_id=scan_id) + + +@shared_task(base=RLSTask, name="scan-compliance-overviews", queue="compliance") def create_compliance_requirements_task(tenant_id: str, scan_id: str): """ Creates detailed compliance requirement records for a scan. @@ -495,6 +547,24 @@ def check_lighthouse_connection_task(lighthouse_config_id: str, tenant_id: str = return check_lighthouse_connection(lighthouse_config_id=lighthouse_config_id) +@shared_task(base=RLSTask, name="lighthouse-provider-connection-check") +@set_tenant +def check_lighthouse_provider_connection_task( + provider_config_id: str, tenant_id: str | None = None +) -> dict: + """Task wrapper to validate provider credentials and set is_active.""" + return check_lighthouse_provider_connection(provider_config_id=provider_config_id) + + +@shared_task(base=RLSTask, name="lighthouse-provider-models-refresh") +@set_tenant +def refresh_lighthouse_provider_models_task( + provider_config_id: str, tenant_id: str | None = None +) -> dict: + """Task wrapper to refresh provider models catalog for the given configuration.""" + return refresh_lighthouse_provider_models(provider_config_id=provider_config_id) + + @shared_task(name="integration-check") def check_integrations_task(tenant_id: str, provider_id: str, scan_id: str = None): """ @@ -595,3 +665,60 @@ def security_hub_integration_task( scan_id (str): The scan identifier """ return upload_security_hub_integration(tenant_id, provider_id, scan_id) + + +@shared_task( + base=RLSTask, + name="integration-jira", + queue="integrations", +) +def jira_integration_task( + tenant_id: str, + integration_id: str, + project_key: str, + issue_type: str, + finding_ids: list[str], +): + return send_findings_to_jira( + tenant_id, integration_id, project_key, issue_type, finding_ids + ) + + +@shared_task( + base=RLSTask, + name="scan-threatscore-report", + queue="scan-reports", +) +def generate_threatscore_report_task(tenant_id: str, scan_id: str, provider_id: str): + """ + Task to generate a threatscore report for a given scan. + Args: + tenant_id (str): The tenant identifier. + scan_id (str): The scan identifier. + provider_id (str): The provider identifier. + """ + return generate_threatscore_report_job( + tenant_id=tenant_id, scan_id=scan_id, provider_id=provider_id + ) + + +@shared_task(name="findings-mute-historical") +def mute_historical_findings_task(tenant_id: str, mute_rule_id: str): + """ + Background task to mute all historical findings matching a mute rule. + + This task processes findings in batches to avoid memory issues with large datasets. + It updates the Finding.muted, Finding.muted_at, and Finding.muted_reason fields + for all findings whose UID is in the mute rule's finding_uids list. + + Args: + tenant_id (str): The tenant ID for RLS context. + mute_rule_id (str): The primary key of the MuteRule to apply. + + Returns: + dict: A dictionary containing: + - 'findings_muted' (int): Total number of findings muted. + - 'rule_id' (str): The mute rule ID. + - 'status' (str): Final status ('completed'). + """ + return mute_historical_findings(tenant_id, mute_rule_id) diff --git a/api/src/backend/tasks/tests/test_backfill.py b/api/src/backend/tasks/tests/test_backfill.py index b436f13151..13fa481b2e 100644 --- a/api/src/backend/tasks/tests/test_backfill.py +++ b/api/src/backend/tasks/tests/test_backfill.py @@ -1,43 +1,53 @@ from uuid import uuid4 import pytest -from tasks.jobs.backfill import backfill_resource_scan_summaries +from tasks.jobs.backfill import ( + backfill_compliance_summaries, + backfill_resource_scan_summaries, +) -from api.models import ResourceScanSummary, Scan, StateChoices +from api.models import ( + ComplianceOverviewSummary, + ResourceScanSummary, + Scan, + StateChoices, +) + + +@pytest.fixture(scope="function") +def resource_scan_summary_data(scans_fixture): + scan = scans_fixture[0] + return ResourceScanSummary.objects.create( + tenant_id=scan.tenant_id, + scan_id=scan.id, + resource_id=str(uuid4()), + service="aws", + region="us-east-1", + resource_type="instance", + ) + + +@pytest.fixture(scope="function") +def get_not_completed_scans(providers_fixture): + provider_id = providers_fixture[0].id + tenant_id = providers_fixture[0].tenant_id + scan_1 = Scan.objects.create( + tenant_id=tenant_id, + trigger=Scan.TriggerChoices.MANUAL, + state=StateChoices.EXECUTING, + provider_id=provider_id, + ) + scan_2 = Scan.objects.create( + tenant_id=tenant_id, + trigger=Scan.TriggerChoices.MANUAL, + state=StateChoices.AVAILABLE, + provider_id=provider_id, + ) + return scan_1, scan_2 @pytest.mark.django_db class TestBackfillResourceScanSummaries: - @pytest.fixture(scope="function") - def resource_scan_summary_data(self, scans_fixture): - scan = scans_fixture[0] - return ResourceScanSummary.objects.create( - tenant_id=scan.tenant_id, - scan_id=scan.id, - resource_id=str(uuid4()), - service="aws", - region="us-east-1", - resource_type="instance", - ) - - @pytest.fixture(scope="function") - def get_not_completed_scans(self, providers_fixture): - provider_id = providers_fixture[0].id - tenant_id = providers_fixture[0].tenant_id - scan_1 = Scan.objects.create( - tenant_id=tenant_id, - trigger=Scan.TriggerChoices.MANUAL, - state=StateChoices.EXECUTING, - provider_id=provider_id, - ) - scan_2 = Scan.objects.create( - tenant_id=tenant_id, - trigger=Scan.TriggerChoices.MANUAL, - state=StateChoices.AVAILABLE, - provider_id=provider_id, - ) - return scan_1, scan_2 - def test_already_backfilled(self, resource_scan_summary_data): tenant_id = resource_scan_summary_data.tenant_id scan_id = resource_scan_summary_data.scan_id @@ -77,3 +87,88 @@ class TestBackfillResourceScanSummaries: assert summary.service == resource.service assert summary.region == resource.region assert summary.resource_type == resource.type + + def test_no_resources_to_backfill(self, scans_fixture): + scan = scans_fixture[1] # Failed scan with no findings/resources + tenant_id = str(scan.tenant_id) + scan_id = str(scan.id) + + result = backfill_resource_scan_summaries(tenant_id, scan_id) + + assert result == {"status": "no resources to backfill"} + + +@pytest.mark.django_db +class TestBackfillComplianceSummaries: + def test_already_backfilled(self, scans_fixture): + scan = scans_fixture[0] + tenant_id = str(scan.tenant_id) + ComplianceOverviewSummary.objects.create( + tenant_id=scan.tenant_id, + scan=scan, + compliance_id="aws_account_security_onboarding_aws", + requirements_passed=1, + requirements_failed=0, + requirements_manual=0, + total_requirements=1, + ) + + result = backfill_compliance_summaries(tenant_id, str(scan.id)) + + assert result == {"status": "already backfilled"} + + def test_not_completed_scan(self, get_not_completed_scans): + for scan in get_not_completed_scans: + result = backfill_compliance_summaries(str(scan.tenant_id), str(scan.id)) + assert result == {"status": "scan is not completed"} + + def test_no_compliance_data(self, scans_fixture): + scan = scans_fixture[1] # Failed scan with no compliance rows + + result = backfill_compliance_summaries(str(scan.tenant_id), str(scan.id)) + + assert result == {"status": "no compliance data to backfill"} + + def test_backfill_creates_compliance_summaries( + self, tenants_fixture, scans_fixture, compliance_requirements_overviews_fixture + ): + tenant = tenants_fixture[0] + scan = scans_fixture[0] + + result = backfill_compliance_summaries(str(tenant.id), str(scan.id)) + + expected = { + "aws_account_security_onboarding_aws": { + "requirements_passed": 1, + "requirements_failed": 1, + "requirements_manual": 1, + "total_requirements": 3, + }, + "cis_1.4_aws": { + "requirements_passed": 0, + "requirements_failed": 1, + "requirements_manual": 0, + "total_requirements": 1, + }, + "mitre_attack_aws": { + "requirements_passed": 0, + "requirements_failed": 1, + "requirements_manual": 0, + "total_requirements": 1, + }, + } + + assert result == {"status": "backfilled", "inserted": len(expected)} + + summaries = ComplianceOverviewSummary.objects.filter( + tenant_id=str(tenant.id), scan_id=str(scan.id) + ) + assert summaries.count() == len(expected) + + for summary in summaries: + assert summary.compliance_id in expected + expected_counts = expected[summary.compliance_id] + assert summary.requirements_passed == expected_counts["requirements_passed"] + assert summary.requirements_failed == expected_counts["requirements_failed"] + assert summary.requirements_manual == expected_counts["requirements_manual"] + assert summary.total_requirements == expected_counts["total_requirements"] diff --git a/api/src/backend/tasks/tests/test_export.py b/api/src/backend/tasks/tests/test_export.py index c10f20774b..f1e7120989 100644 --- a/api/src/backend/tasks/tests/test_export.py +++ b/api/src/backend/tasks/tests/test_export.py @@ -72,17 +72,26 @@ class TestOutputs: client_mock = MagicMock() mock_get_client.return_value = client_mock - result = _upload_to_s3("tenant-id", str(zip_path), "scan-id") + result = _upload_to_s3( + "tenant-id", + "scan-id", + str(zip_path), + "outputs.zip", + ) expected_uri = "s3://test-bucket/tenant-id/scan-id/outputs.zip" assert result == expected_uri - assert client_mock.upload_file.call_count == 2 + client_mock.upload_file.assert_called_once_with( + Filename=str(zip_path), + Bucket="test-bucket", + Key="tenant-id/scan-id/outputs.zip", + ) @patch("tasks.jobs.export.get_s3_client") @patch("tasks.jobs.export.base") def test_upload_to_s3_missing_bucket(self, mock_base, mock_get_client): mock_base.DJANGO_OUTPUT_S3_AWS_OUTPUT_BUCKET = "" - result = _upload_to_s3("tenant", "/tmp/fake.zip", "scan") + result = _upload_to_s3("tenant", "scan", "/tmp/fake.zip", "fake.zip") assert result is None @patch("tasks.jobs.export.get_s3_client") @@ -101,11 +110,15 @@ class TestOutputs: client_mock = MagicMock() mock_get_client.return_value = client_mock - result = _upload_to_s3("tenant", str(zip_path), "scan") + result = _upload_to_s3( + "tenant", + "scan", + str(compliance_dir / "subdir"), + "compliance/subdir", + ) - expected_uri = "s3://test-bucket/tenant/scan/results.zip" - assert result == expected_uri - client_mock.upload_file.assert_called_once() + assert result is None + client_mock.upload_file.assert_not_called() @patch( "tasks.jobs.export.get_s3_client", @@ -126,7 +139,12 @@ class TestOutputs: compliance_dir.mkdir() (compliance_dir / "report.csv").write_text("csv") - _upload_to_s3("tenant", str(zip_path), "scan") + _upload_to_s3( + "tenant", + "scan", + str(zip_path), + "zipfile.zip", + ) mock_logger.assert_called() @patch("tasks.jobs.export.rls_transaction") @@ -150,15 +168,17 @@ class TestOutputs: provider = "aws" expected_timestamp = "20230615103045" - path, compliance = _generate_output_directory( + path, compliance, threatscore = _generate_output_directory( base_dir, provider, tenant_id, scan_id ) assert os.path.isdir(os.path.dirname(path)) assert os.path.isdir(os.path.dirname(compliance)) + assert os.path.isdir(os.path.dirname(threatscore)) assert path.endswith(f"{provider}-{expected_timestamp}") assert compliance.endswith(f"{provider}-{expected_timestamp}") + assert threatscore.endswith(f"{provider}-{expected_timestamp}") @patch("tasks.jobs.export.rls_transaction") @patch("tasks.jobs.export.Scan") @@ -181,12 +201,14 @@ class TestOutputs: provider = "aws/test@check" expected_timestamp = "20230615103045" - path, compliance = _generate_output_directory( + path, compliance, threatscore = _generate_output_directory( base_dir, provider, tenant_id, scan_id ) assert os.path.isdir(os.path.dirname(path)) assert os.path.isdir(os.path.dirname(compliance)) + assert os.path.isdir(os.path.dirname(threatscore)) assert path.endswith(f"aws-test-check-{expected_timestamp}") assert compliance.endswith(f"aws-test-check-{expected_timestamp}") + assert threatscore.endswith(f"aws-test-check-{expected_timestamp}") diff --git a/api/src/backend/tasks/tests/test_integrations.py b/api/src/backend/tasks/tests/test_integrations.py index 4dd68b9f95..75f07677a0 100644 --- a/api/src/backend/tasks/tests/test_integrations.py +++ b/api/src/backend/tasks/tests/test_integrations.py @@ -4,10 +4,12 @@ import pytest from tasks.jobs.integrations import ( get_s3_client_from_integration, get_security_hub_client_from_integration, + send_findings_to_jira, upload_s3_integration, upload_security_hub_integration, ) +from api.db_router import READ_REPLICA_ALIAS, MainRouter from api.models import Integration from api.utils import prowler_integration_connection_test from prowler.providers.aws.lib.security_hub.security_hub import SecurityHubConnection @@ -492,14 +494,17 @@ class TestProwlerIntegrationConnectionTest: def test_aws_security_hub_integration_connection_failure( self, mock_security_hub_class ): - """Test AWS Security Hub integration connection failure.""" + """Test AWS Security Hub integration connection failure resets regions.""" integration = MagicMock() integration.integration_type = Integration.IntegrationChoices.AWS_SECURITY_HUB integration.credentials = { "aws_access_key_id": "invalid_key", "aws_secret_access_key": "invalid_secret", } - integration.configuration = {"send_only_fails": False} + integration.configuration = { + "send_only_fails": False, + "regions": {"us-east-1": True, "us-west-2": False}, # Existing regions + } # Mock integration provider relationship mock_provider = MagicMock() @@ -524,8 +529,9 @@ class TestProwlerIntegrationConnectionTest: assert result.is_connected is False assert result.error == test_exception - # Verify regions were not saved when connection failed - integration.save.assert_not_called() + # Verify regions were reset to empty dict when connection failed + assert integration.configuration["regions"] == {} + integration.save.assert_called_once() @patch("api.utils.SecurityHub") def test_aws_security_hub_integration_with_provider_credentials( @@ -575,6 +581,72 @@ class TestProwlerIntegrationConnectionTest: assert not integration.configuration["regions"]["ap-south-1"] integration.save.assert_called_once() + @patch("api.utils.SecurityHub") + def test_aws_security_hub_connection_failure_with_multiple_regions_clears_all( + self, mock_security_hub_class + ): + """Test that SecurityHub connection failure clears all existing regions data.""" + integration = MagicMock() + integration.integration_type = Integration.IntegrationChoices.AWS_SECURITY_HUB + integration.credentials = { + "aws_access_key_id": "test_key", + "aws_secret_access_key": "test_secret", + } + # Start with complex regions configuration + integration.configuration = { + "send_only_fails": True, + "regions": { + "us-east-1": True, + "us-east-2": False, + "us-west-1": True, + "us-west-2": True, + "eu-west-1": False, + "eu-west-2": True, + "eu-central-1": True, + "ap-northeast-1": False, + "ap-southeast-1": True, + "ap-southeast-2": False, + }, + } + + # Mock integration provider relationship + mock_provider = MagicMock() + mock_provider.uid = "987654321098" + mock_relationship = MagicMock() + mock_relationship.provider = mock_provider + integration.integrationproviderrelationship_set.first.return_value = ( + mock_relationship + ) + + # Mock failed SecurityHub connection + mock_connection = SecurityHubConnection( + is_connected=False, + error=Exception("Invalid credentials or permissions"), + enabled_regions=set(), + disabled_regions=set(), + ) + mock_security_hub_class.test_connection.return_value = mock_connection + + result = prowler_integration_connection_test(integration) + + assert result.is_connected is False + assert str(result.error) == "Invalid credentials or permissions" + + # Verify all regions were completely cleared + assert integration.configuration["regions"] == {} + assert len(integration.configuration["regions"]) == 0 + + # Verify save was called to persist the cleared regions + integration.save.assert_called_once() + + # Verify the test_connection was called with correct parameters + mock_security_hub_class.test_connection.assert_called_once_with( + aws_account_id="987654321098", + raise_on_exception=False, + aws_access_key_id="test_key", + aws_secret_access_key="test_secret", + ) + def test_unsupported_integration_type(self): """Test unsupported integration type raises ValueError.""" integration = MagicMock() @@ -674,15 +746,19 @@ class TestSecurityHubIntegrationUploads: "us-west-2", ] + @patch("tasks.jobs.integrations.rls_transaction") @patch("tasks.jobs.integrations.SecurityHub.test_connection") @patch("tasks.jobs.integrations.initialize_prowler_provider") def test_get_security_hub_client_from_integration_failure( - self, mock_initialize_provider, mock_test_connection + self, mock_initialize_provider, mock_test_connection, mock_rls ): - """Test SecurityHub client creation failure.""" + """Test SecurityHub client creation failure resets regions.""" # Mock integration mock_integration = MagicMock() - mock_integration.configuration = {"send_only_fails": False} + mock_integration.configuration = { + "send_only_fails": False, + "regions": {"us-east-1": True, "us-west-2": False}, # Existing regions + } mock_integration.credentials = {} # Empty credentials, use provider # Mock tenant_id @@ -710,6 +786,9 @@ class TestSecurityHubIntegrationUploads: # Mock findings mock_findings = [{"finding": "test"}] + # Mock RLS context manager + mock_rls.return_value.__enter__.return_value = None + connected, connection = get_security_hub_client_from_integration( mock_integration, tenant_id, mock_findings ) @@ -725,6 +804,94 @@ class TestSecurityHubIntegrationUploads: aws_secret_access_key="test_secret_key", ) + # Verify regions were reset to empty when connection failed + assert mock_integration.configuration["regions"] == {} + mock_integration.save.assert_called_once() + # Verify RLS transaction was used for the reset + assert ( + mock_rls.call_count == 2 + ) # Once for getting provider, once for resetting regions + + @patch("tasks.jobs.integrations.rls_transaction") + @patch("tasks.jobs.integrations.SecurityHub.test_connection") + def test_get_security_hub_client_from_integration_failure_clears_existing_regions( + self, mock_test_connection, mock_rls + ): + """Test that SecurityHub client creation failure clears existing regions configuration.""" + # Mock integration with pre-existing regions configuration + mock_integration = MagicMock() + mock_integration.configuration = { + "send_only_fails": True, + "regions": { + "us-east-1": True, + "us-west-2": True, + "eu-west-1": False, + "ap-south-1": False, + }, # Pre-existing regions configuration + } + mock_integration.credentials = { + "aws_access_key_id": "test_key_id", + "aws_secret_access_key": "test_secret_key", + } + + # Mock tenant_id + tenant_id = "550e8400-e29b-41d4-a716-446655440000" + + # Mock provider relationship + mock_provider = MagicMock() + mock_provider.uid = "123456789012" + mock_provider.secret.secret = { + "aws_access_key_id": "provider_key", + "aws_secret_access_key": "provider_secret", + } + mock_relationship = MagicMock() + mock_relationship.provider = mock_provider + mock_integration.integrationproviderrelationship_set.first.return_value = ( + mock_relationship + ) + + # Mock failed connection with specific error + mock_connection = MagicMock() + mock_connection.is_connected = False + mock_connection.error = "Access denied: SecurityHub not enabled in region" + mock_test_connection.return_value = mock_connection + + # Mock findings + mock_findings = [{"finding": "test1"}, {"finding": "test2"}] + + # Mock RLS context manager + mock_rls.return_value.__enter__.return_value = None + + # Call the function + connected, connection = get_security_hub_client_from_integration( + mock_integration, tenant_id, mock_findings + ) + + # Assertions + assert connected is False + assert connection == mock_connection + assert connection.error == "Access denied: SecurityHub not enabled in region" + + # Verify that regions configuration was completely cleared + assert mock_integration.configuration["regions"] == {} + + # Verify save was called to persist the change + mock_integration.save.assert_called_once() + + # Verify RLS transaction was used correctly + # Should be called twice: once for getting provider info, once for resetting regions + assert mock_rls.call_count == 2 + mock_rls.assert_any_call(tenant_id, using=READ_REPLICA_ALIAS) + mock_rls.assert_any_call(tenant_id, using=MainRouter.default_db) + + # Verify test_connection was called with integration credentials (not provider's) + mock_test_connection.assert_called_once_with( + aws_account_id="123456789012", + raise_on_exception=False, + aws_access_key_id="test_key_id", + aws_secret_access_key="test_secret_key", + ) + @patch("tasks.jobs.integrations.AwsProvider") @patch("tasks.jobs.integrations.SecurityHub.test_connection") @patch("tasks.jobs.integrations.initialize_prowler_provider") @@ -1393,3 +1560,354 @@ class TestSecurityHubIntegrationUploads: mock_security_hub.batch_send_to_security_hub.assert_called_once() mock_security_hub.archive_previous_findings.assert_called_once() + + +@pytest.mark.django_db +class TestJiraIntegration: + @patch("tasks.jobs.integrations.rls_transaction") + @patch("tasks.jobs.integrations.Finding") + @patch("tasks.jobs.integrations.Integration") + @patch("tasks.jobs.integrations.initialize_prowler_integration") + def test_send_findings_to_jira_success( + self, + mock_initialize_integration, + mock_integration_model, + mock_finding_model, + mock_rls_transaction, + ): + """Test successful sending of findings to Jira using send_finding method""" + tenant_id = "tenant-123" + integration_id = "integration-456" + project_key = "PROJ" + issue_type = "Task" + finding_ids = ["finding-1", "finding-2"] + + # Mock RLS transaction + mock_rls_transaction.return_value.__enter__ = MagicMock() + mock_rls_transaction.return_value.__exit__ = MagicMock() + + # Mock integration + integration = MagicMock() + mock_integration_model.objects.get.return_value = integration + + # Mock Jira integration + mock_jira_integration = MagicMock() + mock_jira_integration.send_finding.side_effect = [True, True] # Both succeed + mock_initialize_integration.return_value = mock_jira_integration + + # Mock findings with resources + resource1 = MagicMock() + resource1.uid = "resource-uid-1" + resource1.name = "resource-name-1" + resource1.region = "us-east-1" + resource1.get_tags.return_value = {"env": "prod", "team": "security"} + + resource2 = MagicMock() + resource2.uid = "resource-uid-2" + resource2.name = "resource-name-2" + resource2.region = "eu-west-1" + resource2.get_tags.return_value = {"env": "dev"} + + finding1 = MagicMock() + finding1.id = "finding-1" + finding1.check_id = "check_001" + finding1.severity = "high" + finding1.status = "FAIL" + finding1.status_extended = "Resource is not compliant" + finding1.resource_regions = ["us-east-1"] + finding1.compliance = {"cis": ["1.1", "1.2"]} + finding1.resources.exists.return_value = True + finding1.resources.first.return_value = resource1 + finding1.scan.provider.provider = "aws" + finding1.check_metadata = { + "checktitle": "Check Title 1", + "risk": "High risk finding", + "remediation": { + "recommendation": { + "text": "Fix this issue", + "url": "https://docs.example.com/fix", + }, + "code": { + "nativeiac": "native code", + "terraform": "terraform code", + "cli": "aws cli command", + "other": "", + }, + }, + } + + finding2 = MagicMock() + finding2.id = "finding-2" + finding2.check_id = "check_002" + finding2.severity = "medium" + finding2.status = "PASS" + finding2.status_extended = None + finding2.resource_regions = [] + finding2.compliance = {} + finding2.resources.exists.return_value = True + finding2.resources.first.return_value = resource2 + finding2.scan.provider.provider = "azure" + finding2.check_metadata = { + "checktitle": "Check Title 2", + "risk": "Medium risk", + "remediation": { + "recommendation": {"text": "Consider fixing", "url": ""}, + "code": {}, + }, + } + + mock_finding_model.all_objects.select_related.return_value.prefetch_related.return_value.get.side_effect = [ + finding1, + finding2, + ] + + # Call the function + result = send_findings_to_jira( + tenant_id, integration_id, project_key, issue_type, finding_ids + ) + + # Assertions + assert result == {"created_count": 2, "failed_count": 0} + + # Verify Jira integration was initialized + mock_initialize_integration.assert_called_once_with(integration) + + # Verify send_finding was called twice with correct parameters + assert mock_jira_integration.send_finding.call_count == 2 + + # Verify first call + first_call = mock_jira_integration.send_finding.call_args_list[0] + assert first_call.kwargs["check_id"] == "check_001" + assert first_call.kwargs["check_title"] == "Check Title 1" + assert first_call.kwargs["severity"] == "high" + assert first_call.kwargs["status"] == "FAIL" + assert first_call.kwargs["resource_uid"] == "resource-uid-1" + assert first_call.kwargs["resource_name"] == "resource-name-1" + assert first_call.kwargs["region"] == "us-east-1" + assert first_call.kwargs["provider"] == "aws" + assert first_call.kwargs["project_key"] == project_key + assert first_call.kwargs["issue_type"] == issue_type + + # Verify second call + second_call = mock_jira_integration.send_finding.call_args_list[1] + assert second_call.kwargs["check_id"] == "check_002" + assert second_call.kwargs["severity"] == "medium" + assert second_call.kwargs["status"] == "PASS" + + @patch("tasks.jobs.integrations.rls_transaction") + @patch("tasks.jobs.integrations.Finding") + @patch("tasks.jobs.integrations.Integration") + @patch("tasks.jobs.integrations.initialize_prowler_integration") + @patch("tasks.jobs.integrations.logger") + def test_send_findings_to_jira_partial_failure( + self, + mock_logger, + mock_initialize_integration, + mock_integration_model, + mock_finding_model, + mock_rls_transaction, + ): + """Test partial failure when sending findings to Jira""" + tenant_id = "tenant-123" + integration_id = "integration-456" + project_key = "PROJ" + issue_type = "Task" + finding_ids = ["finding-1", "finding-2", "finding-3"] + + # Mock RLS transaction + mock_rls_transaction.return_value.__enter__ = MagicMock() + mock_rls_transaction.return_value.__exit__ = MagicMock() + + # Mock integration + integration = MagicMock() + mock_integration_model.objects.get.return_value = integration + + # Mock Jira integration with mixed results + mock_jira_integration = MagicMock() + mock_jira_integration.send_finding.side_effect = [ + True, + False, + True, + ] # Second fails + mock_initialize_integration.return_value = mock_jira_integration + + # Mock findings (simplified for this test) + findings = [] + for i in range(3): + finding = MagicMock() + finding.id = f"finding-{i + 1}" + finding.check_id = f"check_{i + 1:03d}" + finding.severity = "low" + finding.status = "FAIL" + finding.status_extended = "" + finding.resource_regions = [] + finding.compliance = {} + + finding.resources.exists.return_value = False + finding.resources.first.return_value = None + finding.scan.provider.provider = "aws" + finding.check_metadata = { + "checktitle": f"Check {i + 1}", + "risk": "Low risk", + "remediation": {"recommendation": {}, "code": {}}, + } + findings.append(finding) + + mock_finding_model.all_objects.select_related.return_value.prefetch_related.return_value.get.side_effect = findings + + # Call the function + result = send_findings_to_jira( + tenant_id, integration_id, project_key, issue_type, finding_ids + ) + + # Assertions + assert result == {"created_count": 2, "failed_count": 1} + + # Verify error was logged for the failed finding + mock_logger.error.assert_called_with("Failed to send finding finding-2 to Jira") + + @patch("tasks.jobs.integrations.rls_transaction") + @patch("tasks.jobs.integrations.Finding") + @patch("tasks.jobs.integrations.Integration") + @patch("tasks.jobs.integrations.initialize_prowler_integration") + def test_send_findings_to_jira_no_resources( + self, + mock_initialize_integration, + mock_integration_model, + mock_finding_model, + mock_rls_transaction, + ): + """Test sending findings to Jira when finding has no resources""" + tenant_id = "tenant-123" + integration_id = "integration-456" + project_key = "PROJ" + issue_type = "Task" + finding_ids = ["finding-1"] + + # Mock RLS transaction + mock_rls_transaction.return_value.__enter__ = MagicMock() + mock_rls_transaction.return_value.__exit__ = MagicMock() + + # Mock integration + integration = MagicMock() + mock_integration_model.objects.get.return_value = integration + + # Mock Jira integration + mock_jira_integration = MagicMock() + mock_jira_integration.send_finding.return_value = True + mock_initialize_integration.return_value = mock_jira_integration + + # Mock finding without resources + finding = MagicMock() + finding.id = "finding-1" + finding.check_id = "check_001" + finding.severity = "critical" + finding.status = "FAIL" + finding.status_extended = "Critical issue found" + finding.resource_regions = None + finding.compliance = {"pci": ["3.1"]} + + finding.resources.exists.return_value = False + finding.resources.first.return_value = None + finding.scan.provider.provider = "gcp" + finding.check_metadata = { + "checktitle": "Critical Check", + "risk": "Very high risk", + "remediation": { + "recommendation": { + "text": "Immediate action required", + "url": "https://example.com/critical", + }, + "code": { + "nativeiac": "", + "terraform": "terraform fix", + "cli": "", + "other": "manual fix", + }, + }, + } + + mock_finding_model.all_objects.select_related.return_value.prefetch_related.return_value.get.return_value = finding + + # Call the function + result = send_findings_to_jira( + tenant_id, integration_id, project_key, issue_type, finding_ids + ) + + # Assertions + assert result == {"created_count": 1, "failed_count": 0} + + # Verify send_finding was called with empty resource fields + call_kwargs = mock_jira_integration.send_finding.call_args.kwargs + assert call_kwargs["resource_uid"] == "" + assert call_kwargs["resource_name"] == "" + assert call_kwargs["resource_tags"] == {} + assert call_kwargs["region"] == "" + + @patch("tasks.jobs.integrations.rls_transaction") + @patch("tasks.jobs.integrations.Finding") + @patch("tasks.jobs.integrations.Integration") + @patch("tasks.jobs.integrations.initialize_prowler_integration") + def test_send_findings_to_jira_with_empty_check_metadata( + self, + mock_initialize_integration, + mock_integration_model, + mock_finding_model, + mock_rls_transaction, + ): + """Test sending findings to Jira when check_metadata is empty or missing fields""" + tenant_id = "tenant-123" + integration_id = "integration-456" + project_key = "PROJ" + issue_type = "Task" + finding_ids = ["finding-1"] + + # Mock RLS transaction + mock_rls_transaction.return_value.__enter__ = MagicMock() + mock_rls_transaction.return_value.__exit__ = MagicMock() + + # Mock integration + integration = MagicMock() + mock_integration_model.objects.get.return_value = integration + + # Mock Jira integration + mock_jira_integration = MagicMock() + mock_jira_integration.send_finding.return_value = True + mock_initialize_integration.return_value = mock_jira_integration + + # Mock finding with minimal/empty check_metadata + finding = MagicMock() + finding.id = "finding-1" + finding.check_id = "check_001" + finding.severity = "low" + finding.status = "PASS" + finding.status_extended = None + finding.resource_regions = [] + finding.compliance = None + + finding.resources.exists.return_value = False + finding.resources.first.return_value = None + finding.scan.provider.provider = "kubernetes" + finding.check_metadata = {} # Empty metadata + + mock_finding_model.all_objects.select_related.return_value.prefetch_related.return_value.get.return_value = finding + + # Call the function + result = send_findings_to_jira( + tenant_id, integration_id, project_key, issue_type, finding_ids + ) + + # Assertions + assert result == {"created_count": 1, "failed_count": 0} + + # Verify send_finding was called with default/empty values + call_kwargs = mock_jira_integration.send_finding.call_args.kwargs + assert call_kwargs["check_title"] == "" + assert call_kwargs["risk"] == "" + assert call_kwargs["recommendation_text"] == "" + assert call_kwargs["recommendation_url"] == "" + assert call_kwargs["remediation_code_native_iac"] == "" + assert call_kwargs["remediation_code_terraform"] == "" + assert call_kwargs["remediation_code_cli"] == "" + assert call_kwargs["remediation_code_other"] == "" + assert call_kwargs["compliance"] == {} diff --git a/api/src/backend/tasks/tests/test_muting.py b/api/src/backend/tasks/tests/test_muting.py new file mode 100644 index 0000000000..d8ae310f2e --- /dev/null +++ b/api/src/backend/tasks/tests/test_muting.py @@ -0,0 +1,532 @@ +from datetime import datetime, timezone +from uuid import uuid4 + +import pytest +from django.core.exceptions import ObjectDoesNotExist +from tasks.jobs.muting import mute_historical_findings + +from api.models import Finding, MuteRule +from prowler.lib.check.models import Severity +from prowler.lib.outputs.finding import Status + + +@pytest.mark.django_db +class TestMuteHistoricalFindings: + """ + Test suite for the mute_historical_findings function. + + This class tests the batch processing of findings to update their muted status + based on MuteRule criteria. + """ + + @pytest.fixture(scope="function") + def test_user(self, create_test_user): + """Create a test user for mute rule creation.""" + return create_test_user + + @pytest.fixture(scope="function") + def mute_rule_with_findings(self, tenants_fixture, findings_fixture, test_user): + """ + Create a mute rule that targets the first finding in the fixture. + """ + tenant = tenants_fixture[0] + finding = findings_fixture[0] + + mute_rule = MuteRule.objects.create( + tenant_id=tenant.id, + name="Test Mute Rule", + reason="Testing mute functionality", + enabled=True, + created_by=test_user, + finding_uids=[finding.uid], + ) + + return mute_rule + + @pytest.fixture(scope="function") + def mute_rule_multiple_findings(self, scans_fixture, test_user): + """ + Create multiple unmuted findings and a mute rule targeting all of them. + """ + scan = scans_fixture[0] + tenant_id = scan.tenant_id + + # Create 5 unmuted findings + finding_uids = [] + for i in range(5): + finding = Finding.objects.create( + tenant_id=tenant_id, + uid=f"test_finding_uid_mute_{i}", + scan=scan, + status=Status.FAIL, + status_extended=f"Test status {i}", + impact=Severity.high, + severity=Severity.high, + raw_result={ + "status": Status.FAIL, + "impact": Severity.high, + "severity": Severity.high, + }, + check_id=f"test_check_id_{i}", + check_metadata={ + "CheckId": f"test_check_id_{i}", + "Description": f"Test description {i}", + }, + muted=False, + ) + finding_uids.append(finding.uid) + + # Create mute rule targeting all findings + mute_rule = MuteRule.objects.create( + tenant_id=tenant_id, + name="Test Multiple Findings Mute Rule", + reason="Testing batch muting", + enabled=True, + created_by=test_user, + finding_uids=finding_uids, + ) + + return mute_rule, finding_uids + + @pytest.fixture(scope="function") + def mute_rule_already_muted(self, findings_fixture, test_user): + """ + Create a mute rule that targets an already-muted finding. + """ + tenant_id = findings_fixture[1].tenant_id + already_muted_finding = findings_fixture[1] + + mute_rule = MuteRule.objects.create( + tenant_id=tenant_id, + name="Test Already Muted Rule", + reason="Testing already muted findings", + enabled=True, + created_by=test_user, + finding_uids=[already_muted_finding.uid], + ) + + return mute_rule + + @pytest.fixture(scope="function") + def mute_rule_mixed_findings(self, scans_fixture, test_user): + """ + Create a mute rule with a mix of muted and unmuted findings. + """ + scan = scans_fixture[0] + tenant_id = scan.tenant_id + + # Create 3 unmuted findings + unmuted_uids = [] + for i in range(3): + finding = Finding.objects.create( + tenant_id=tenant_id, + uid=f"unmuted_finding_{i}", + scan=scan, + status=Status.FAIL, + status_extended=f"Unmuted status {i}", + impact=Severity.medium, + severity=Severity.medium, + raw_result={ + "status": Status.FAIL, + "impact": Severity.medium, + "severity": Severity.medium, + }, + check_id=f"unmuted_check_{i}", + check_metadata={ + "CheckId": f"unmuted_check_{i}", + "Description": f"Unmuted description {i}", + }, + muted=False, + ) + unmuted_uids.append(finding.uid) + + # Create 2 already muted findings + muted_uids = [] + for i in range(2): + finding = Finding.objects.create( + tenant_id=tenant_id, + uid=f"muted_finding_{i}", + scan=scan, + status=Status.FAIL, + status_extended=f"Muted status {i}", + impact=Severity.low, + severity=Severity.low, + raw_result={ + "status": Status.FAIL, + "impact": Severity.low, + "severity": Severity.low, + }, + check_id=f"muted_check_{i}", + check_metadata={ + "CheckId": f"muted_check_{i}", + "Description": f"Muted description {i}", + }, + muted=True, + muted_at=datetime.now(timezone.utc), + muted_reason="Already muted", + ) + muted_uids.append(finding.uid) + + # Create mute rule targeting all findings + all_uids = unmuted_uids + muted_uids + mute_rule = MuteRule.objects.create( + tenant_id=tenant_id, + name="Test Mixed Findings Rule", + reason="Testing mixed muted/unmuted findings", + enabled=True, + created_by=test_user, + finding_uids=all_uids, + ) + + return mute_rule, unmuted_uids, muted_uids + + @pytest.fixture(scope="function") + def mute_rule_batch_test(self, scans_fixture, test_user): + """ + Create enough findings to test batch processing (>1000 for default batch size). + """ + scan = scans_fixture[0] + tenant_id = scan.tenant_id + + # Create 1500 findings to exceed default batch size of 1000 + finding_uids = [] + for i in range(1500): + finding = Finding.objects.create( + tenant_id=tenant_id, + uid=f"batch_test_finding_{i}", + scan=scan, + status=Status.FAIL, + status_extended=f"Batch test status {i}", + impact=Severity.critical, + severity=Severity.critical, + raw_result={ + "status": Status.FAIL, + "impact": Severity.critical, + "severity": Severity.critical, + }, + check_id=f"batch_test_check_{i}", + check_metadata={ + "CheckId": f"batch_test_check_{i}", + "Description": f"Batch test description {i}", + }, + muted=False, + ) + finding_uids.append(finding.uid) + + # Create mute rule targeting all findings + mute_rule = MuteRule.objects.create( + tenant_id=tenant_id, + name="Test Batch Processing Rule", + reason="Testing batch processing functionality", + enabled=True, + created_by=test_user, + finding_uids=finding_uids, + ) + + return mute_rule, finding_uids + + def test_mute_historical_findings_single_finding( + self, mute_rule_with_findings, findings_fixture + ): + """ + Test muting a single historical finding. + """ + mute_rule = mute_rule_with_findings + tenant_id = str(mute_rule.tenant_id) + finding = findings_fixture[0] + + # Ensure the finding is not muted before execution + finding.refresh_from_db() + assert finding.muted is False + assert finding.muted_at is None + assert finding.muted_reason is None + + # Execute the muting function + result = mute_historical_findings(tenant_id, str(mute_rule.id)) + + # Verify return value + assert result["findings_muted"] == 1 + assert result["rule_id"] == str(mute_rule.id) + + # Verify the finding was muted + finding.refresh_from_db() + assert finding.muted is True + assert finding.muted_at == mute_rule.inserted_at + assert finding.muted_reason == mute_rule.reason + + def test_mute_historical_findings_multiple_findings( + self, mute_rule_multiple_findings + ): + """ + Test muting multiple historical findings. + """ + mute_rule, finding_uids = mute_rule_multiple_findings + tenant_id = str(mute_rule.tenant_id) + + # Verify all findings are unmuted + findings = Finding.objects.filter(tenant_id=tenant_id, uid__in=finding_uids) + assert findings.count() == 5 + for finding in findings: + assert finding.muted is False + + # Execute the muting function + result = mute_historical_findings(tenant_id, str(mute_rule.id)) + + # Verify return value + assert result["findings_muted"] == 5 + assert result["rule_id"] == str(mute_rule.id) + + # Verify all findings were muted + findings = Finding.objects.filter(tenant_id=tenant_id, uid__in=finding_uids) + for finding in findings: + assert finding.muted is True + assert finding.muted_at == mute_rule.inserted_at + assert finding.muted_reason == mute_rule.reason + + def test_mute_historical_findings_already_muted( + self, mute_rule_already_muted, findings_fixture + ): + """ + Test that already-muted findings are not counted or updated. + """ + mute_rule = mute_rule_already_muted + tenant_id = str(mute_rule.tenant_id) + finding = findings_fixture[1] + + # Verify the finding is already muted + finding.refresh_from_db() + assert finding.muted is True + original_muted_at = finding.muted_at + original_muted_reason = finding.muted_reason + + # Execute the muting function + result = mute_historical_findings(tenant_id, str(mute_rule.id)) + + # Verify no findings were muted + assert result["findings_muted"] == 0 + assert result["rule_id"] == str(mute_rule.id) + + # Verify the finding's mute status did not change + finding.refresh_from_db() + assert finding.muted is True + assert finding.muted_at == original_muted_at + assert finding.muted_reason == original_muted_reason + + def test_mute_historical_findings_mixed_status(self, mute_rule_mixed_findings): + """ + Test muting when some findings are already muted and others are not. + """ + mute_rule, unmuted_uids, muted_uids = mute_rule_mixed_findings + tenant_id = str(mute_rule.tenant_id) + + # Execute the muting function + result = mute_historical_findings(tenant_id, str(mute_rule.id)) + + # Verify only unmuted findings were counted + assert result["findings_muted"] == 3 + assert result["rule_id"] == str(mute_rule.id) + + # Verify unmuted findings are now muted + unmuted_findings = Finding.objects.filter( + tenant_id=tenant_id, uid__in=unmuted_uids + ) + for finding in unmuted_findings: + assert finding.muted is True + assert finding.muted_at == mute_rule.inserted_at + assert finding.muted_reason == mute_rule.reason + + # Verify already-muted findings remained unchanged + already_muted_findings = Finding.objects.filter( + tenant_id=tenant_id, uid__in=muted_uids + ) + for finding in already_muted_findings: + assert finding.muted is True + assert finding.muted_reason == "Already muted" + + def test_mute_historical_findings_nonexistent_rule(self, tenants_fixture): + """ + Test that a nonexistent mute rule raises ObjectDoesNotExist. + """ + tenant_id = str(tenants_fixture[0].id) + nonexistent_rule_id = str(uuid4()) + + with pytest.raises(ObjectDoesNotExist): + mute_historical_findings(tenant_id, nonexistent_rule_id) + + def test_mute_historical_findings_no_matching_findings( + self, tenants_fixture, test_user + ): + """ + Test muting when no findings match the rule's UIDs. + """ + tenant_id = str(tenants_fixture[0].id) + + # Create a mute rule with non-existent finding UIDs + mute_rule = MuteRule.objects.create( + tenant_id=tenant_id, + name="Test No Match Rule", + reason="Testing no matching findings", + enabled=True, + created_by=test_user, + finding_uids=[ + "nonexistent_uid_1", + "nonexistent_uid_2", + "nonexistent_uid_3", + ], + ) + + # Execute the muting function + result = mute_historical_findings(tenant_id, str(mute_rule.id)) + + # Verify no findings were muted + assert result["findings_muted"] == 0 + assert result["rule_id"] == str(mute_rule.id) + + def test_mute_historical_findings_batch_processing(self, mute_rule_batch_test): + """ + Test that large numbers of findings are processed in batches correctly. + """ + mute_rule, finding_uids = mute_rule_batch_test + tenant_id = str(mute_rule.tenant_id) + + # Verify all findings exist and are unmuted + findings = Finding.objects.filter(tenant_id=tenant_id, uid__in=finding_uids) + assert findings.count() == 1500 + for finding in findings: + assert finding.muted is False + + # Execute the muting function + result = mute_historical_findings(tenant_id, str(mute_rule.id)) + + # Verify return value + assert result["findings_muted"] == 1500 + assert result["rule_id"] == str(mute_rule.id) + + # Verify all findings were muted + findings = Finding.objects.filter(tenant_id=tenant_id, uid__in=finding_uids) + for finding in findings: + assert finding.muted is True + assert finding.muted_at == mute_rule.inserted_at + assert finding.muted_reason == mute_rule.reason + + def test_mute_historical_findings_preserves_muted_at_timestamp( + self, mute_rule_with_findings, findings_fixture + ): + """ + Test that muted_at is set to the rule's inserted_at, not the current time. + """ + mute_rule = mute_rule_with_findings + tenant_id = str(mute_rule.tenant_id) + finding = findings_fixture[0] + + # Execute the muting function + result = mute_historical_findings(tenant_id, str(mute_rule.id)) + + # Verify the finding was muted + assert result["findings_muted"] == 1 + + # Verify muted_at matches the rule's inserted_at timestamp + finding.refresh_from_db() + assert finding.muted_at == mute_rule.inserted_at + assert finding.muted_at is not None + + def test_mute_historical_findings_partial_match(self, scans_fixture, test_user): + """ + Test muting when only some of the rule's UIDs exist as findings. + """ + scan = scans_fixture[0] + tenant_id = str(scan.tenant_id) + + # Create 3 findings + existing_uids = [] + for i in range(3): + finding = Finding.objects.create( + tenant_id=tenant_id, + uid=f"partial_match_finding_{i}", + scan=scan, + status=Status.FAIL, + status_extended=f"Partial match status {i}", + impact=Severity.high, + severity=Severity.high, + raw_result={ + "status": Status.FAIL, + "impact": Severity.high, + "severity": Severity.high, + }, + check_id=f"partial_match_check_{i}", + check_metadata={ + "CheckId": f"partial_match_check_{i}", + "Description": f"Partial match description {i}", + }, + muted=False, + ) + existing_uids.append(finding.uid) + + # Create a mute rule with both existing and non-existing UIDs + all_uids = existing_uids + [ + "nonexistent_uid_1", + "nonexistent_uid_2", + ] + mute_rule = MuteRule.objects.create( + tenant_id=tenant_id, + name="Test Partial Match Rule", + reason="Testing partial matching", + enabled=True, + created_by=test_user, + finding_uids=all_uids, + ) + + # Execute the muting function + result = mute_historical_findings(tenant_id, str(mute_rule.id)) + + # Verify only existing findings were muted + assert result["findings_muted"] == 3 + assert result["rule_id"] == str(mute_rule.id) + + # Verify the existing findings were muted + findings = Finding.objects.filter(tenant_id=tenant_id, uid__in=existing_uids) + assert findings.count() == 3 + for finding in findings: + assert finding.muted is True + assert finding.muted_at == mute_rule.inserted_at + assert finding.muted_reason == mute_rule.reason + + def test_mute_historical_findings_empty_uids(self, tenants_fixture, test_user): + """ + Test muting when the rule has an empty finding_uids array. + """ + tenant_id = str(tenants_fixture[0].id) + + # Create a mute rule with empty finding_uids + mute_rule = MuteRule.objects.create( + tenant_id=tenant_id, + name="Test Empty UIDs Rule", + reason="Testing empty UIDs", + enabled=True, + created_by=test_user, + finding_uids=[], + ) + + # Execute the muting function + result = mute_historical_findings(tenant_id, str(mute_rule.id)) + + # Verify no findings were muted + assert result["findings_muted"] == 0 + assert result["rule_id"] == str(mute_rule.id) + + def test_mute_historical_findings_return_format(self, mute_rule_with_findings): + """ + Test that the return value has the correct format and fields. + """ + mute_rule = mute_rule_with_findings + tenant_id = str(mute_rule.tenant_id) + + result = mute_historical_findings(tenant_id, str(mute_rule.id)) + + # Verify return value structure + assert isinstance(result, dict) + assert "findings_muted" in result + assert "rule_id" in result + assert isinstance(result["findings_muted"], int) + assert isinstance(result["rule_id"], str) + assert result["rule_id"] == str(mute_rule.id) diff --git a/api/src/backend/tasks/tests/test_report.py b/api/src/backend/tasks/tests/test_report.py new file mode 100644 index 0000000000..91d3b1145d --- /dev/null +++ b/api/src/backend/tasks/tests/test_report.py @@ -0,0 +1,1108 @@ +import uuid +from datetime import timedelta +from decimal import Decimal +from pathlib import Path +from unittest.mock import MagicMock, patch + +import matplotlib +import pytest +from django.utils import timezone +from freezegun import freeze_time +from tasks.jobs.report import ( + _load_findings_for_requirement_checks, + generate_threatscore_report, + generate_threatscore_report_job, +) +from tasks.jobs.threatscore_utils import ( + _aggregate_requirement_statistics_from_database, + _calculate_requirements_data_from_statistics, +) +from tasks.tasks import generate_threatscore_report_task + +from api.models import Finding, Scan, StateChoices, StatusChoices, ThreatScoreSnapshot +from prowler.lib.check.models import Severity + +matplotlib.use("Agg") # Use non-interactive backend for tests + + +@pytest.mark.django_db +class TestGenerateThreatscoreReport: + def setup_method(self): + self.scan_id = str(uuid.uuid4()) + self.provider_id = str(uuid.uuid4()) + self.tenant_id = str(uuid.uuid4()) + + def test_no_findings_returns_early(self): + with patch("tasks.jobs.report.ScanSummary.objects.filter") as mock_filter: + mock_filter.return_value.exists.return_value = False + + result = generate_threatscore_report_job( + tenant_id=self.tenant_id, + scan_id=self.scan_id, + provider_id=self.provider_id, + ) + + assert result == {"upload": False} + mock_filter.assert_called_once_with(scan_id=self.scan_id) + + @patch("tasks.jobs.report.ThreatScoreSnapshot.objects.create") + @patch("tasks.jobs.report.rmtree") + @patch("tasks.jobs.report._upload_to_s3") + @patch("tasks.jobs.report.generate_threatscore_report") + @patch("tasks.jobs.report._generate_output_directory") + @patch("tasks.jobs.report.Provider.objects.get") + @patch("tasks.jobs.report.ScanSummary.objects.filter") + def test_generate_threatscore_report_happy_path( + self, + mock_scan_summary_filter, + mock_provider_get, + mock_generate_output_directory, + mock_generate_report, + mock_upload, + mock_rmtree, + mock_snapshot_create, + ): + mock_scan_summary_filter.return_value.exists.return_value = True + + mock_provider = MagicMock() + mock_provider.uid = "provider-uid" + mock_provider.provider = "aws" + mock_provider_get.return_value = mock_provider + + mock_generate_output_directory.return_value = ( + "/tmp/output", + "/tmp/compressed", + "/tmp/threatscore_path", + ) + + mock_upload.return_value = "s3://bucket/threatscore_report.pdf" + + result = generate_threatscore_report_job( + tenant_id=self.tenant_id, + scan_id=self.scan_id, + provider_id=self.provider_id, + ) + + assert result == {"upload": True} + mock_generate_report.assert_called_once_with( + tenant_id=self.tenant_id, + scan_id=self.scan_id, + compliance_id="prowler_threatscore_aws", + output_path="/tmp/threatscore_path_threatscore_report.pdf", + provider_id=self.provider_id, + only_failed=True, + min_risk_level=4, + ) + mock_upload.assert_called_once_with( + self.tenant_id, + self.scan_id, + "/tmp/threatscore_path_threatscore_report.pdf", + "threatscore/threatscore_path_threatscore_report.pdf", + ) + mock_rmtree.assert_called_once_with( + Path("/tmp/threatscore_path_threatscore_report.pdf").parent, + ignore_errors=True, + ) + mock_snapshot_create.assert_called_once() + + @patch("tasks.jobs.report.ThreatScoreSnapshot.objects.create") + def test_generate_threatscore_report_fails_upload(self, mock_snapshot_create): + with ( + patch("tasks.jobs.report.ScanSummary.objects.filter") as mock_filter, + patch("tasks.jobs.report.Provider.objects.get") as mock_provider_get, + patch("tasks.jobs.report._generate_output_directory") as mock_gen_dir, + patch("tasks.jobs.report.generate_threatscore_report"), + patch("tasks.jobs.report._upload_to_s3", return_value=None), + ): + mock_filter.return_value.exists.return_value = True + + # Mock provider + mock_provider = MagicMock() + mock_provider.uid = "aws-provider-uid" + mock_provider.provider = "aws" + mock_provider_get.return_value = mock_provider + + mock_gen_dir.return_value = ( + "/tmp/output", + "/tmp/compressed", + "/tmp/threatscore_path", + ) + + result = generate_threatscore_report_job( + tenant_id=self.tenant_id, + scan_id=self.scan_id, + provider_id=self.provider_id, + ) + + assert result == {"upload": False} + mock_snapshot_create.assert_called_once() + + @patch("tasks.jobs.report.ThreatScoreSnapshot.objects.create") + def test_generate_threatscore_report_logs_rmtree_exception( + self, mock_snapshot_create, caplog + ): + with ( + patch("tasks.jobs.report.ScanSummary.objects.filter") as mock_filter, + patch("tasks.jobs.report.Provider.objects.get") as mock_provider_get, + patch("tasks.jobs.report._generate_output_directory") as mock_gen_dir, + patch("tasks.jobs.report.generate_threatscore_report"), + patch( + "tasks.jobs.report._upload_to_s3", return_value="s3://bucket/report.pdf" + ), + patch( + "tasks.jobs.report.rmtree", side_effect=Exception("Test deletion error") + ), + ): + mock_filter.return_value.exists.return_value = True + + # Mock provider + mock_provider = MagicMock() + mock_provider.uid = "aws-provider-uid" + mock_provider.provider = "aws" + mock_provider_get.return_value = mock_provider + + mock_gen_dir.return_value = ( + "/tmp/output", + "/tmp/compressed", + "/tmp/threatscore_path", + ) + + with caplog.at_level("ERROR"): + generate_threatscore_report_job( + tenant_id=self.tenant_id, + scan_id=self.scan_id, + provider_id=self.provider_id, + ) + assert "Error deleting output files" in caplog.text + mock_snapshot_create.assert_called_once() + + @patch("tasks.jobs.report.ThreatScoreSnapshot.objects.create") + def test_generate_threatscore_report_azure_provider(self, mock_snapshot_create): + with ( + patch("tasks.jobs.report.ScanSummary.objects.filter") as mock_filter, + patch("tasks.jobs.report.Provider.objects.get") as mock_provider_get, + patch("tasks.jobs.report._generate_output_directory") as mock_gen_dir, + patch("tasks.jobs.report.generate_threatscore_report") as mock_generate, + patch( + "tasks.jobs.report._upload_to_s3", return_value="s3://bucket/report.pdf" + ), + patch("tasks.jobs.report.rmtree"), + ): + mock_filter.return_value.exists.return_value = True + + mock_provider = MagicMock() + mock_provider.uid = "azure-provider-uid" + mock_provider.provider = "azure" + mock_provider_get.return_value = mock_provider + + mock_gen_dir.return_value = ( + "/tmp/output", + "/tmp/compressed", + "/tmp/threatscore_path", + ) + + generate_threatscore_report_job( + tenant_id=self.tenant_id, + scan_id=self.scan_id, + provider_id=self.provider_id, + ) + + mock_generate.assert_called_once_with( + tenant_id=self.tenant_id, + scan_id=self.scan_id, + compliance_id="prowler_threatscore_azure", + output_path="/tmp/threatscore_path_threatscore_report.pdf", + provider_id=self.provider_id, + only_failed=True, + min_risk_level=4, + ) + mock_snapshot_create.assert_called_once() + + @patch("tasks.jobs.report.rmtree") + @patch( + "tasks.jobs.report._upload_to_s3", + return_value="s3://bucket/threatscore/threatscore_report.pdf", + ) + @patch("tasks.jobs.report.generate_threatscore_report") + @patch("tasks.jobs.report._generate_output_directory") + @patch("tasks.jobs.report.ScanSummary.objects.filter") + @patch("tasks.jobs.report.compute_threatscore_metrics") + @pytest.mark.django_db + @freeze_time("2025-01-10T12:00:00Z") + def test_generate_threatscore_report_persists_snapshot_and_delta( + self, + mock_compute_metrics, + mock_scan_summary_filter, + mock_generate_output_directory, + mock_generate_report, + mock_upload, + mock_rmtree, + tenants_fixture, + providers_fixture, + ): + tenant = tenants_fixture[0] + provider = providers_fixture[0] + + scan_previous = Scan.objects.create( + tenant=tenant, + provider=provider, + name="previous-threatscore-scan", + trigger=Scan.TriggerChoices.MANUAL, + state=StateChoices.COMPLETED, + started_at=timezone.now() - timedelta(hours=4), + completed_at=timezone.now() - timedelta(hours=3), + ) + ThreatScoreSnapshot.objects.create( + tenant=tenant, + scan=scan_previous, + provider=provider, + compliance_id="prowler_threatscore_aws", + overall_score=Decimal("70.00"), + score_delta=None, + section_scores={"1. IAM": "65.00"}, + critical_requirements=[], + total_requirements=50, + passed_requirements=35, + failed_requirements=15, + manual_requirements=0, + total_findings=40, + passed_findings=25, + failed_findings=15, + ) + + scan_current = Scan.objects.create( + tenant=tenant, + provider=provider, + name="current-threatscore-scan", + trigger=Scan.TriggerChoices.MANUAL, + state=StateChoices.COMPLETED, + started_at=timezone.now() - timedelta(hours=2), + completed_at=timezone.now() - timedelta(hours=1), + ) + + mock_scan_summary_filter.return_value.exists.return_value = True + mock_generate_output_directory.return_value = ( + "/tmp/output", + "/tmp/compressed", + "/tmp/threatscore_path", + ) + + metrics = { + "overall_score": 85.5, + "score_delta": 10.0, + "section_scores": {"1. IAM": 82.3, "2. Attack Surface": 60.0}, + "critical_requirements": [ + { + "requirement_id": "req_new", + "title": "New high-risk requirement", + "section": "1. IAM", + "subsection": "Root Account", + "risk_level": 5, + "weight": 150, + "passed_findings": 7, + "total_findings": 10, + "description": "Critical requirement description", + } + ], + "total_requirements": 140, + "passed_requirements": 100, + "failed_requirements": 40, + "manual_requirements": 0, + "total_findings": 200, + "passed_findings": 150, + "failed_findings": 50, + } + mock_compute_metrics.return_value = metrics + + result = generate_threatscore_report_job( + tenant_id=str(tenant.id), + scan_id=str(scan_current.id), + provider_id=str(provider.id), + ) + + assert result == {"upload": True} + mock_compute_metrics.assert_called_once_with( + tenant_id=str(tenant.id), + scan_id=str(scan_current.id), + provider_id=str(provider.id), + compliance_id="prowler_threatscore_aws", + min_risk_level=4, + ) + mock_generate_report.assert_called_once() + mock_upload.assert_called_once() + mock_rmtree.assert_called_once() + + snapshots = ThreatScoreSnapshot.objects.filter( + tenant=tenant, provider=provider + ).order_by("inserted_at") + assert snapshots.count() == 2 + + new_snapshot = ThreatScoreSnapshot.objects.get(scan=scan_current) + assert new_snapshot.compliance_id == "prowler_threatscore_aws" + assert Decimal(new_snapshot.overall_score) == Decimal("85.50") + assert Decimal(new_snapshot.score_delta) == Decimal("15.50") + assert new_snapshot.section_scores == metrics["section_scores"] + assert new_snapshot.critical_requirements == metrics["critical_requirements"] + assert new_snapshot.total_requirements == metrics["total_requirements"] + assert new_snapshot.total_findings == metrics["total_findings"] + + +@pytest.mark.django_db +class TestAggregateRequirementStatistics: + """Test suite for _aggregate_requirement_statistics_from_database function.""" + + def test_aggregates_findings_correctly(self, tenants_fixture, scans_fixture): + """Verify correct pass/total counts per check are aggregated from database.""" + tenant = tenants_fixture[0] + scan = scans_fixture[0] + + # Create findings with different check_ids and statuses + Finding.objects.create( + tenant_id=tenant.id, + scan=scan, + uid="finding-1", + check_id="check_1", + status=StatusChoices.PASS, + severity=Severity.high, + impact=Severity.high, + check_metadata={}, + raw_result={}, + ) + Finding.objects.create( + tenant_id=tenant.id, + scan=scan, + uid="finding-2", + check_id="check_1", + status=StatusChoices.FAIL, + severity=Severity.high, + impact=Severity.high, + check_metadata={}, + raw_result={}, + ) + Finding.objects.create( + tenant_id=tenant.id, + scan=scan, + uid="finding-3", + check_id="check_2", + status=StatusChoices.PASS, + severity=Severity.medium, + impact=Severity.medium, + check_metadata={}, + raw_result={}, + ) + + result = _aggregate_requirement_statistics_from_database( + str(tenant.id), str(scan.id) + ) + + assert result == { + "check_1": {"passed": 1, "total": 2}, + "check_2": {"passed": 1, "total": 1}, + } + + def test_handles_empty_scan(self, tenants_fixture, scans_fixture): + """Return empty dict when no findings exist for the scan.""" + tenant = tenants_fixture[0] + scan = scans_fixture[0] + + result = _aggregate_requirement_statistics_from_database( + str(tenant.id), str(scan.id) + ) + + assert result == {} + + def test_multiple_findings_same_check(self, tenants_fixture, scans_fixture): + """Aggregate multiple findings for same check_id correctly.""" + tenant = tenants_fixture[0] + scan = scans_fixture[0] + + # Create 5 findings for same check, 3 passed + for i in range(3): + Finding.objects.create( + tenant_id=tenant.id, + scan=scan, + uid=f"finding-pass-{i}", + check_id="check_same", + status=StatusChoices.PASS, + severity=Severity.medium, + impact=Severity.medium, + check_metadata={}, + raw_result={}, + ) + + for i in range(2): + Finding.objects.create( + tenant_id=tenant.id, + scan=scan, + uid=f"finding-fail-{i}", + check_id="check_same", + status=StatusChoices.FAIL, + severity=Severity.medium, + impact=Severity.medium, + check_metadata={}, + raw_result={}, + ) + + result = _aggregate_requirement_statistics_from_database( + str(tenant.id), str(scan.id) + ) + + assert result == {"check_same": {"passed": 3, "total": 5}} + + def test_only_failed_findings(self, tenants_fixture, scans_fixture): + """Correctly count when all findings are FAIL status.""" + tenant = tenants_fixture[0] + scan = scans_fixture[0] + + Finding.objects.create( + tenant_id=tenant.id, + scan=scan, + uid="finding-fail-1", + check_id="check_fail", + status=StatusChoices.FAIL, + severity=Severity.medium, + impact=Severity.medium, + check_metadata={}, + raw_result={}, + ) + Finding.objects.create( + tenant_id=tenant.id, + scan=scan, + uid="finding-fail-2", + check_id="check_fail", + status=StatusChoices.FAIL, + severity=Severity.medium, + impact=Severity.medium, + check_metadata={}, + raw_result={}, + ) + + result = _aggregate_requirement_statistics_from_database( + str(tenant.id), str(scan.id) + ) + + assert result == {"check_fail": {"passed": 0, "total": 2}} + + def test_mixed_statuses(self, tenants_fixture, scans_fixture): + """Test with PASS, FAIL, and MANUAL statuses mixed.""" + tenant = tenants_fixture[0] + scan = scans_fixture[0] + + Finding.objects.create( + tenant_id=tenant.id, + scan=scan, + uid="finding-pass", + check_id="check_mixed", + status=StatusChoices.PASS, + severity=Severity.medium, + impact=Severity.medium, + check_metadata={}, + raw_result={}, + ) + Finding.objects.create( + tenant_id=tenant.id, + scan=scan, + uid="finding-fail", + check_id="check_mixed", + status=StatusChoices.FAIL, + severity=Severity.medium, + impact=Severity.medium, + check_metadata={}, + raw_result={}, + ) + Finding.objects.create( + tenant_id=tenant.id, + scan=scan, + uid="finding-manual", + check_id="check_mixed", + status=StatusChoices.MANUAL, + severity=Severity.medium, + impact=Severity.medium, + check_metadata={}, + raw_result={}, + ) + + result = _aggregate_requirement_statistics_from_database( + str(tenant.id), str(scan.id) + ) + + # Only PASS status is counted as passed + assert result == {"check_mixed": {"passed": 1, "total": 3}} + + +@pytest.mark.django_db +class TestLoadFindingsForChecks: + """Test suite for _load_findings_for_requirement_checks function.""" + + def test_loads_only_requested_checks( + self, tenants_fixture, scans_fixture, providers_fixture + ): + """Verify only findings for specified check_ids are loaded.""" + tenant = tenants_fixture[0] + scan = scans_fixture[0] + providers_fixture[0] + + # Create findings with different check_ids + Finding.objects.create( + tenant_id=tenant.id, + scan=scan, + uid="finding-1", + check_id="check_requested", + status=StatusChoices.PASS, + severity=Severity.medium, + impact=Severity.medium, + check_metadata={}, + raw_result={}, + ) + Finding.objects.create( + tenant_id=tenant.id, + scan=scan, + uid="finding-2", + check_id="check_not_requested", + status=StatusChoices.FAIL, + severity=Severity.medium, + impact=Severity.medium, + check_metadata={}, + raw_result={}, + ) + + mock_provider = MagicMock() + + with patch( + "tasks.jobs.report.FindingOutput.transform_api_finding" + ) as mock_transform: + mock_finding_output = MagicMock() + mock_finding_output.check_id = "check_requested" + mock_transform.return_value = mock_finding_output + + result = _load_findings_for_requirement_checks( + str(tenant.id), str(scan.id), ["check_requested"], mock_provider + ) + + # Only one finding should be loaded + assert "check_requested" in result + assert "check_not_requested" not in result + assert len(result["check_requested"]) == 1 + assert mock_transform.call_count == 1 + + def test_empty_check_ids_returns_empty( + self, tenants_fixture, scans_fixture, providers_fixture + ): + """Return empty dict when check_ids list is empty.""" + tenant = tenants_fixture[0] + scan = scans_fixture[0] + mock_provider = MagicMock() + + result = _load_findings_for_requirement_checks( + str(tenant.id), str(scan.id), [], mock_provider + ) + + assert result == {} + + def test_groups_by_check_id( + self, tenants_fixture, scans_fixture, providers_fixture + ): + """Multiple findings for same check are grouped correctly.""" + tenant = tenants_fixture[0] + scan = scans_fixture[0] + + # Create multiple findings for same check + for i in range(3): + Finding.objects.create( + tenant_id=tenant.id, + scan=scan, + uid=f"finding-{i}", + check_id="check_group", + status=StatusChoices.PASS, + severity=Severity.medium, + impact=Severity.medium, + check_metadata={}, + raw_result={}, + ) + + mock_provider = MagicMock() + + with patch( + "tasks.jobs.report.FindingOutput.transform_api_finding" + ) as mock_transform: + mock_finding_output = MagicMock() + mock_finding_output.check_id = "check_group" + mock_transform.return_value = mock_finding_output + + result = _load_findings_for_requirement_checks( + str(tenant.id), str(scan.id), ["check_group"], mock_provider + ) + + assert len(result["check_group"]) == 3 + + def test_transforms_to_finding_output( + self, tenants_fixture, scans_fixture, providers_fixture + ): + """Findings are transformed using FindingOutput.transform_api_finding.""" + tenant = tenants_fixture[0] + scan = scans_fixture[0] + + Finding.objects.create( + tenant_id=tenant.id, + scan=scan, + uid="finding-transform", + check_id="check_transform", + status=StatusChoices.PASS, + severity=Severity.medium, + impact=Severity.medium, + check_metadata={}, + raw_result={}, + ) + + mock_provider = MagicMock() + + with patch( + "tasks.jobs.report.FindingOutput.transform_api_finding" + ) as mock_transform: + mock_finding_output = MagicMock() + mock_finding_output.check_id = "check_transform" + mock_transform.return_value = mock_finding_output + + result = _load_findings_for_requirement_checks( + str(tenant.id), str(scan.id), ["check_transform"], mock_provider + ) + + # Verify transform was called + mock_transform.assert_called_once() + # Verify the transformed output is in the result + assert result["check_transform"][0] == mock_finding_output + + def test_batched_iteration(self, tenants_fixture, scans_fixture, providers_fixture): + """Works correctly with multiple batches of findings.""" + tenant = tenants_fixture[0] + scan = scans_fixture[0] + + # Create enough findings to ensure batching (assuming batch size > 1) + for i in range(10): + Finding.objects.create( + tenant_id=tenant.id, + scan=scan, + uid=f"finding-batch-{i}", + check_id="check_batch", + status=StatusChoices.PASS, + severity=Severity.medium, + impact=Severity.medium, + check_metadata={}, + raw_result={}, + ) + + mock_provider = MagicMock() + + with patch( + "tasks.jobs.report.FindingOutput.transform_api_finding" + ) as mock_transform: + mock_finding_output = MagicMock() + mock_finding_output.check_id = "check_batch" + mock_transform.return_value = mock_finding_output + + result = _load_findings_for_requirement_checks( + str(tenant.id), str(scan.id), ["check_batch"], mock_provider + ) + + # All 10 findings should be loaded regardless of batching + assert len(result["check_batch"]) == 10 + assert mock_transform.call_count == 10 + + +@pytest.mark.django_db +class TestCalculateRequirementsData: + """Test suite for _calculate_requirements_data_from_statistics function.""" + + def test_requirement_status_all_pass(self): + """Status is PASS when all findings for requirement checks pass.""" + mock_compliance = MagicMock() + mock_compliance.Framework = "TestFramework" + mock_compliance.Version = "1.0" + + mock_requirement = MagicMock() + mock_requirement.Id = "req_1" + mock_requirement.Description = "Test requirement" + mock_requirement.Checks = ["check_1", "check_2"] + mock_requirement.Attributes = [MagicMock()] + + mock_compliance.Requirements = [mock_requirement] + + requirement_statistics = { + "check_1": {"passed": 5, "total": 5}, + "check_2": {"passed": 3, "total": 3}, + } + + attributes_by_id, requirements_list = ( + _calculate_requirements_data_from_statistics( + mock_compliance, requirement_statistics + ) + ) + + assert len(requirements_list) == 1 + assert requirements_list[0]["attributes"]["status"] == StatusChoices.PASS + assert requirements_list[0]["attributes"]["passed_findings"] == 8 + assert requirements_list[0]["attributes"]["total_findings"] == 8 + + def test_requirement_status_some_fail(self): + """Status is FAIL when some findings fail.""" + mock_compliance = MagicMock() + mock_compliance.Framework = "TestFramework" + mock_compliance.Version = "1.0" + + mock_requirement = MagicMock() + mock_requirement.Id = "req_2" + mock_requirement.Description = "Test requirement with failures" + mock_requirement.Checks = ["check_3"] + mock_requirement.Attributes = [MagicMock()] + + mock_compliance.Requirements = [mock_requirement] + + requirement_statistics = { + "check_3": {"passed": 2, "total": 5}, + } + + attributes_by_id, requirements_list = ( + _calculate_requirements_data_from_statistics( + mock_compliance, requirement_statistics + ) + ) + + assert len(requirements_list) == 1 + assert requirements_list[0]["attributes"]["status"] == StatusChoices.FAIL + assert requirements_list[0]["attributes"]["passed_findings"] == 2 + assert requirements_list[0]["attributes"]["total_findings"] == 5 + + def test_requirement_status_no_findings(self): + """Status is MANUAL when no findings exist for requirement.""" + mock_compliance = MagicMock() + mock_compliance.Framework = "TestFramework" + mock_compliance.Version = "1.0" + + mock_requirement = MagicMock() + mock_requirement.Id = "req_3" + mock_requirement.Description = "Manual requirement" + mock_requirement.Checks = ["check_nonexistent"] + mock_requirement.Attributes = [MagicMock()] + + mock_compliance.Requirements = [mock_requirement] + + requirement_statistics = {} + + attributes_by_id, requirements_list = ( + _calculate_requirements_data_from_statistics( + mock_compliance, requirement_statistics + ) + ) + + assert len(requirements_list) == 1 + assert requirements_list[0]["attributes"]["status"] == StatusChoices.MANUAL + assert requirements_list[0]["attributes"]["passed_findings"] == 0 + assert requirements_list[0]["attributes"]["total_findings"] == 0 + + def test_aggregates_multiple_checks(self): + """Correctly sum stats across multiple checks in requirement.""" + mock_compliance = MagicMock() + mock_compliance.Framework = "TestFramework" + mock_compliance.Version = "1.0" + + mock_requirement = MagicMock() + mock_requirement.Id = "req_4" + mock_requirement.Description = "Multi-check requirement" + mock_requirement.Checks = ["check_a", "check_b", "check_c"] + mock_requirement.Attributes = [MagicMock()] + + mock_compliance.Requirements = [mock_requirement] + + requirement_statistics = { + "check_a": {"passed": 10, "total": 15}, + "check_b": {"passed": 5, "total": 10}, + "check_c": {"passed": 0, "total": 5}, + } + + attributes_by_id, requirements_list = ( + _calculate_requirements_data_from_statistics( + mock_compliance, requirement_statistics + ) + ) + + assert len(requirements_list) == 1 + # 10 + 5 + 0 = 15 passed + assert requirements_list[0]["attributes"]["passed_findings"] == 15 + # 15 + 10 + 5 = 30 total + assert requirements_list[0]["attributes"]["total_findings"] == 30 + # Not all passed, so should be FAIL + assert requirements_list[0]["attributes"]["status"] == StatusChoices.FAIL + + def test_returns_correct_structure(self): + """Verify tuple structure and dict keys are correct.""" + mock_compliance = MagicMock() + mock_compliance.Framework = "TestFramework" + mock_compliance.Version = "1.0" + + mock_attribute = MagicMock() + mock_requirement = MagicMock() + mock_requirement.Id = "req_5" + mock_requirement.Description = "Structure test" + mock_requirement.Checks = ["check_struct"] + mock_requirement.Attributes = [mock_attribute] + + mock_compliance.Requirements = [mock_requirement] + + requirement_statistics = {"check_struct": {"passed": 1, "total": 1}} + + attributes_by_id, requirements_list = ( + _calculate_requirements_data_from_statistics( + mock_compliance, requirement_statistics + ) + ) + + # Verify attributes_by_id structure + assert "req_5" in attributes_by_id + assert "attributes" in attributes_by_id["req_5"] + assert "description" in attributes_by_id["req_5"] + assert "req_attributes" in attributes_by_id["req_5"]["attributes"] + assert "checks" in attributes_by_id["req_5"]["attributes"] + + # Verify requirements_list structure + assert len(requirements_list) == 1 + req = requirements_list[0] + assert "id" in req + assert "attributes" in req + assert "framework" in req["attributes"] + assert "version" in req["attributes"] + assert "status" in req["attributes"] + assert "description" in req["attributes"] + assert "passed_findings" in req["attributes"] + assert "total_findings" in req["attributes"] + + +@pytest.mark.django_db +class TestGenerateThreatscoreReportFunction: + def setup_method(self): + self.scan_id = str(uuid.uuid4()) + self.provider_id = str(uuid.uuid4()) + self.tenant_id = str(uuid.uuid4()) + self.compliance_id = "prowler_threatscore_aws" + self.output_path = "/tmp/test_threatscore_report.pdf" + + @patch("tasks.jobs.report.initialize_prowler_provider") + @patch("tasks.jobs.report.Provider.objects.get") + @patch("tasks.jobs.report.Compliance.get_bulk") + @patch("tasks.jobs.report._aggregate_requirement_statistics_from_database") + @patch("tasks.jobs.report._calculate_requirements_data_from_statistics") + @patch("tasks.jobs.report._load_findings_for_requirement_checks") + @patch("tasks.jobs.report.SimpleDocTemplate") + @patch("tasks.jobs.report.Image") + @patch("tasks.jobs.report.Spacer") + @patch("tasks.jobs.report.Paragraph") + @patch("tasks.jobs.report.PageBreak") + @patch("tasks.jobs.report.Table") + @patch("tasks.jobs.report.TableStyle") + @patch("tasks.jobs.report.plt.subplots") + @patch("tasks.jobs.report.plt.savefig") + @patch("tasks.jobs.report.io.BytesIO") + def test_generate_threatscore_report_success( + self, + mock_bytesio, + mock_savefig, + mock_subplots, + mock_table_style, + mock_table, + mock_page_break, + mock_paragraph, + mock_spacer, + mock_image, + mock_doc_template, + mock_load_findings, + mock_calculate_requirements, + mock_aggregate_statistics, + mock_compliance_get_bulk, + mock_provider_get, + mock_initialize_provider, + ): + """Test the updated generate_threatscore_report using new memory-efficient architecture.""" + mock_provider = MagicMock() + mock_provider.provider = "aws" + mock_provider_get.return_value = mock_provider + + prowler_provider = MagicMock() + mock_initialize_provider.return_value = prowler_provider + + # Mock compliance object with requirements + mock_compliance_obj = MagicMock() + mock_compliance_obj.Framework = "ProwlerThreatScore" + mock_compliance_obj.Version = "1.0" + mock_compliance_obj.Description = "Test Description" + + # Configure requirement with properly set numeric attributes for chart generation + mock_requirement = MagicMock() + mock_requirement.Id = "req_1" + mock_requirement.Description = "Test requirement" + mock_requirement.Checks = ["check_1"] + + # Create a properly configured attribute mock with numeric values + mock_requirement_attr = MagicMock() + mock_requirement_attr.Section = "1. IAM" + mock_requirement_attr.SubSection = "1.1 Identity" + mock_requirement_attr.Title = "Test Requirement Title" + mock_requirement_attr.LevelOfRisk = 3 + mock_requirement_attr.Weight = 100 + mock_requirement_attr.AttributeDescription = "Test requirement description" + mock_requirement_attr.AdditionalInformation = "Additional test information" + + mock_requirement.Attributes = [mock_requirement_attr] + mock_compliance_obj.Requirements = [mock_requirement] + + mock_compliance_get_bulk.return_value = { + self.compliance_id: mock_compliance_obj + } + + # Mock the aggregated statistics from database + mock_aggregate_statistics.return_value = {"check_1": {"passed": 5, "total": 10}} + + # Mock the calculated requirements data with properly configured attributes + mock_attributes_by_id = { + "req_1": { + "attributes": { + "req_attributes": [mock_requirement_attr], + "checks": ["check_1"], + }, + "description": "Test requirement", + } + } + mock_requirements_list = [ + { + "id": "req_1", + "attributes": { + "framework": "ProwlerThreatScore", + "version": "1.0", + "status": StatusChoices.FAIL, + "description": "Test requirement", + "passed_findings": 5, + "total_findings": 10, + }, + } + ] + mock_calculate_requirements.return_value = ( + mock_attributes_by_id, + mock_requirements_list, + ) + + # Mock the on-demand loaded findings + mock_finding_output = MagicMock() + mock_finding_output.check_id = "check_1" + mock_finding_output.status = "FAIL" + mock_finding_output.metadata = MagicMock() + mock_finding_output.metadata.CheckTitle = "Test Check" + mock_finding_output.metadata.Severity = "HIGH" + mock_finding_output.resource_name = "test-resource" + mock_finding_output.region = "us-east-1" + + mock_load_findings.return_value = {"check_1": [mock_finding_output]} + + # Mock PDF generation components + mock_doc = MagicMock() + mock_doc_template.return_value = mock_doc + + mock_fig, mock_ax = MagicMock(), MagicMock() + mock_subplots.return_value = (mock_fig, mock_ax) + mock_buffer = MagicMock() + mock_bytesio.return_value = mock_buffer + + mock_image.return_value = MagicMock() + mock_spacer.return_value = MagicMock() + mock_paragraph.return_value = MagicMock() + mock_page_break.return_value = MagicMock() + mock_table.return_value = MagicMock() + mock_table_style.return_value = MagicMock() + + # Execute the function + generate_threatscore_report( + tenant_id=self.tenant_id, + scan_id=self.scan_id, + compliance_id=self.compliance_id, + output_path=self.output_path, + provider_id=self.provider_id, + only_failed=True, + min_risk_level=4, + ) + + # Verify the new workflow was followed + mock_provider_get.assert_called_once_with(id=self.provider_id) + mock_initialize_provider.assert_called_once_with(mock_provider) + mock_compliance_get_bulk.assert_called_once_with("aws") + + # Verify the new functions were called in correct order with correct parameters + mock_aggregate_statistics.assert_called_once_with(self.tenant_id, self.scan_id) + mock_calculate_requirements.assert_called_once_with( + mock_compliance_obj, {"check_1": {"passed": 5, "total": 10}} + ) + mock_load_findings.assert_called_once_with( + self.tenant_id, self.scan_id, ["check_1"], prowler_provider + ) + + # Verify PDF was built + mock_doc_template.assert_called_once() + mock_doc.build.assert_called_once() + + @patch("tasks.jobs.report.initialize_prowler_provider") + @patch("tasks.jobs.report.Provider.objects.get") + @patch("tasks.jobs.report.Compliance.get_bulk") + @patch("tasks.jobs.report.Finding.all_objects.filter") + def test_generate_threatscore_report_exception_handling( + self, + mock_finding_filter, + mock_compliance_get_bulk, + mock_provider_get, + mock_initialize_provider, + ): + mock_provider_get.side_effect = Exception("Provider not found") + + with pytest.raises(Exception, match="Provider not found"): + generate_threatscore_report( + tenant_id=self.tenant_id, + scan_id=self.scan_id, + compliance_id=self.compliance_id, + output_path=self.output_path, + provider_id=self.provider_id, + only_failed=True, + min_risk_level=4, + ) + + +@pytest.mark.django_db +class TestGenerateThreatscoreReportTask: + def setup_method(self): + self.scan_id = str(uuid.uuid4()) + self.provider_id = str(uuid.uuid4()) + self.tenant_id = str(uuid.uuid4()) + + @patch("tasks.tasks.generate_threatscore_report_job") + def test_generate_threatscore_report_task_calls_job(self, mock_generate_job): + mock_generate_job.return_value = {"upload": True} + + result = generate_threatscore_report_task( + tenant_id=self.tenant_id, + scan_id=self.scan_id, + provider_id=self.provider_id, + ) + + assert result == {"upload": True} + mock_generate_job.assert_called_once_with( + tenant_id=self.tenant_id, + scan_id=self.scan_id, + provider_id=self.provider_id, + ) + + @patch("tasks.tasks.generate_threatscore_report_job") + def test_generate_threatscore_report_task_handles_job_exception( + self, mock_generate_job + ): + mock_generate_job.side_effect = Exception("Job failed") + + with pytest.raises(Exception, match="Job failed"): + generate_threatscore_report_task( + tenant_id=self.tenant_id, + scan_id=self.scan_id, + provider_id=self.provider_id, + ) diff --git a/api/src/backend/tasks/tests/test_scan.py b/api/src/backend/tasks/tests/test_scan.py index dcbec12956..f2724de4e6 100644 --- a/api/src/backend/tasks/tests/test_scan.py +++ b/api/src/backend/tasks/tests/test_scan.py @@ -1,20 +1,64 @@ +import csv import json +import re import uuid -from datetime import datetime +from contextlib import contextmanager +from datetime import datetime, timezone +from io import StringIO from unittest.mock import MagicMock, patch import pytest from tasks.jobs.scan import ( + _aggregate_findings_by_region, + _copy_compliance_requirement_rows, + _create_compliance_summaries, _create_finding_delta, + _normalized_compliance_key, + _persist_compliance_requirement_rows, + _process_finding_micro_batch, _store_resources, + aggregate_findings, create_compliance_requirements, perform_prowler_scan, ) from tasks.utils import CustomEncoder +from api.db_router import MainRouter from api.exceptions import ProviderConnectionError -from api.models import Finding, Provider, Resource, Scan, StateChoices, StatusChoices +from api.models import ( + Finding, + MuteRule, + Provider, + Resource, + Scan, + StateChoices, + StatusChoices, +) from prowler.lib.check.models import Severity +from prowler.lib.outputs.finding import Status + + +@contextmanager +def noop_rls_transaction(*args, **kwargs): + yield + + +class FakeFinding: + def __init__(self, **attrs): + self.metadata = attrs.pop("metadata", {}) + for key, value in attrs.items(): + setattr(self, key, value) + + self.resource_tags = getattr(self, "resource_tags", {}) + self.resource_metadata = getattr(self, "resource_metadata", {}) + self.resource_details = getattr(self, "resource_details", {}) + self.compliance = getattr(self, "compliance", {}) + self.raw = getattr(self, "raw", {}) + self.partition = getattr(self, "partition", "") + self.muted = getattr(self, "muted", False) + + def get_metadata(self): + return self.metadata @pytest.mark.django_db @@ -734,10 +778,874 @@ class TestPerformScan: # Assert that failed_findings_count was reset to 0 during the scan assert resource.failed_findings_count == 0 + def test_perform_prowler_scan_with_active_mute_rules( + self, + tenants_fixture, + scans_fixture, + providers_fixture, + ): + """Test active MuteRule mutes findings with correct reason""" + with ( + patch("api.db_utils.rls_transaction"), + patch( + "tasks.jobs.scan.initialize_prowler_provider" + ) as mock_initialize_prowler_provider, + patch("tasks.jobs.scan.ProwlerScan") as mock_prowler_scan_class, + patch( + "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE", + new_callable=dict, + ), + patch("api.compliance.PROWLER_CHECKS", new_callable=dict), + ): + tenant = tenants_fixture[0] + scan = scans_fixture[0] + provider = providers_fixture[0] + + provider.provider = Provider.ProviderChoices.AWS + provider.save() + + tenant_id = str(tenant.id) + scan_id = str(scan.id) + provider_id = str(provider.id) + + # Create active MuteRule with specific finding UIDs + mute_rule_reason = "Accepted risk - production exception" + finding_uid_1 = "finding_to_mute_1" + finding_uid_2 = "finding_to_mute_2" + + MuteRule.objects.create( + tenant_id=tenant_id, + name="Production Exception Rule", + reason=mute_rule_reason, + enabled=True, + finding_uids=[finding_uid_1, finding_uid_2], + ) + + # Mock findings: one FAIL and one PASS, both should be muted + muted_fail_finding = MagicMock() + muted_fail_finding.uid = finding_uid_1 + muted_fail_finding.status = StatusChoices.FAIL + muted_fail_finding.status_extended = "muted fail" + muted_fail_finding.severity = Severity.high + muted_fail_finding.check_id = "muted_fail_check" + muted_fail_finding.get_metadata.return_value = {"key": "value"} + muted_fail_finding.resource_uid = "resource_uid_1" + muted_fail_finding.resource_name = "resource_1" + muted_fail_finding.region = "us-east-1" + muted_fail_finding.service_name = "ec2" + muted_fail_finding.resource_type = "instance" + muted_fail_finding.resource_tags = {} + muted_fail_finding.muted = False + muted_fail_finding.raw = {} + muted_fail_finding.resource_metadata = {} + muted_fail_finding.resource_details = {} + muted_fail_finding.partition = "aws" + muted_fail_finding.compliance = {} + + muted_pass_finding = MagicMock() + muted_pass_finding.uid = finding_uid_2 + muted_pass_finding.status = StatusChoices.PASS + muted_pass_finding.status_extended = "muted pass" + muted_pass_finding.severity = Severity.medium + muted_pass_finding.check_id = "muted_pass_check" + muted_pass_finding.get_metadata.return_value = {"key": "value"} + muted_pass_finding.resource_uid = "resource_uid_2" + muted_pass_finding.resource_name = "resource_2" + muted_pass_finding.region = "us-east-1" + muted_pass_finding.service_name = "s3" + muted_pass_finding.resource_type = "bucket" + muted_pass_finding.resource_tags = {} + muted_pass_finding.muted = False + muted_pass_finding.raw = {} + muted_pass_finding.resource_metadata = {} + muted_pass_finding.resource_details = {} + muted_pass_finding.partition = "aws" + muted_pass_finding.compliance = {} + + # Mock the ProwlerScan instance + mock_prowler_scan_instance = MagicMock() + mock_prowler_scan_instance.scan.return_value = [ + (100, [muted_fail_finding, muted_pass_finding]) + ] + mock_prowler_scan_class.return_value = mock_prowler_scan_instance + + # Mock prowler_provider + mock_prowler_provider_instance = MagicMock() + mock_prowler_provider_instance.get_regions.return_value = ["us-east-1"] + mock_initialize_prowler_provider.return_value = ( + mock_prowler_provider_instance + ) + + # Call the function under test + perform_prowler_scan(tenant_id, scan_id, provider_id, []) + + # Verify findings are muted with correct reason + fail_finding_db = Finding.objects.get(uid=finding_uid_1) + pass_finding_db = Finding.objects.get(uid=finding_uid_2) + + assert fail_finding_db.muted + assert fail_finding_db.muted_reason == mute_rule_reason + assert fail_finding_db.muted_at is not None + + assert pass_finding_db.muted + assert pass_finding_db.muted_reason == mute_rule_reason + assert pass_finding_db.muted_at is not None + + # Verify failed_findings_count is 0 for muted FAIL finding + resource_1 = Resource.objects.get(uid="resource_uid_1") + assert resource_1.failed_findings_count == 0 + + def test_perform_prowler_scan_with_inactive_mute_rules( + self, + tenants_fixture, + scans_fixture, + providers_fixture, + ): + """Test inactive MuteRule does not mute findings""" + with ( + patch("api.db_utils.rls_transaction"), + patch( + "tasks.jobs.scan.initialize_prowler_provider" + ) as mock_initialize_prowler_provider, + patch("tasks.jobs.scan.ProwlerScan") as mock_prowler_scan_class, + patch( + "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE", + new_callable=dict, + ), + patch("api.compliance.PROWLER_CHECKS", new_callable=dict), + ): + tenant = tenants_fixture[0] + scan = scans_fixture[0] + provider = providers_fixture[0] + + provider.provider = Provider.ProviderChoices.AWS + provider.save() + + tenant_id = str(tenant.id) + scan_id = str(scan.id) + provider_id = str(provider.id) + + # Create inactive MuteRule + finding_uid = "finding_inactive_rule" + MuteRule.objects.create( + tenant_id=tenant_id, + name="Inactive Rule", + reason="Should not apply", + enabled=False, + finding_uids=[finding_uid], + ) + + # Mock FAIL finding + fail_finding = MagicMock() + fail_finding.uid = finding_uid + fail_finding.status = StatusChoices.FAIL + fail_finding.status_extended = "test fail" + fail_finding.severity = Severity.high + fail_finding.check_id = "fail_check" + fail_finding.get_metadata.return_value = {"key": "value"} + fail_finding.resource_uid = "resource_uid_inactive" + fail_finding.resource_name = "resource_inactive" + fail_finding.region = "us-east-1" + fail_finding.service_name = "ec2" + fail_finding.resource_type = "instance" + fail_finding.resource_tags = {} + fail_finding.muted = False + fail_finding.raw = {} + fail_finding.resource_metadata = {} + fail_finding.resource_details = {} + fail_finding.partition = "aws" + fail_finding.compliance = {} + + # Mock the ProwlerScan instance + mock_prowler_scan_instance = MagicMock() + mock_prowler_scan_instance.scan.return_value = [(100, [fail_finding])] + mock_prowler_scan_class.return_value = mock_prowler_scan_instance + + # Mock prowler_provider + mock_prowler_provider_instance = MagicMock() + mock_prowler_provider_instance.get_regions.return_value = ["us-east-1"] + mock_initialize_prowler_provider.return_value = ( + mock_prowler_provider_instance + ) + + # Call the function under test + perform_prowler_scan(tenant_id, scan_id, provider_id, []) + + # Verify finding is NOT muted + finding_db = Finding.objects.get(uid=finding_uid) + assert not finding_db.muted + assert finding_db.muted_reason is None + assert finding_db.muted_at is None + + # Verify failed_findings_count increments for FAIL finding + resource = Resource.objects.get(uid="resource_uid_inactive") + assert resource.failed_findings_count == 1 + + def test_perform_prowler_scan_mutelist_overrides_mute_rules( + self, + tenants_fixture, + scans_fixture, + providers_fixture, + ): + """Test mutelist processor takes precedence over MuteRule""" + with ( + patch("api.db_utils.rls_transaction"), + patch( + "tasks.jobs.scan.initialize_prowler_provider" + ) as mock_initialize_prowler_provider, + patch("tasks.jobs.scan.ProwlerScan") as mock_prowler_scan_class, + patch( + "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE", + new_callable=dict, + ), + patch("api.compliance.PROWLER_CHECKS", new_callable=dict), + ): + tenant = tenants_fixture[0] + scan = scans_fixture[0] + provider = providers_fixture[0] + + provider.provider = Provider.ProviderChoices.AWS + provider.save() + + tenant_id = str(tenant.id) + scan_id = str(scan.id) + provider_id = str(provider.id) + + # Create active MuteRule + finding_uid = "finding_both_rules" + MuteRule.objects.create( + tenant_id=tenant_id, + name="Manual Mute Rule", + reason="Muted by manual rule", + enabled=True, + finding_uids=[finding_uid], + ) + + # Mock finding with mutelist processor muted=True + muted_finding = MagicMock() + muted_finding.uid = finding_uid + muted_finding.status = StatusChoices.FAIL + muted_finding.status_extended = "test" + muted_finding.severity = Severity.high + muted_finding.check_id = "test_check" + muted_finding.get_metadata.return_value = {"key": "value"} + muted_finding.resource_uid = "resource_both" + muted_finding.resource_name = "resource_both" + muted_finding.region = "us-east-1" + muted_finding.service_name = "ec2" + muted_finding.resource_type = "instance" + muted_finding.resource_tags = {} + muted_finding.muted = True + muted_finding.raw = {} + muted_finding.resource_metadata = {} + muted_finding.resource_details = {} + muted_finding.partition = "aws" + muted_finding.compliance = {} + + # Mock the ProwlerScan instance + mock_prowler_scan_instance = MagicMock() + mock_prowler_scan_instance.scan.return_value = [(100, [muted_finding])] + mock_prowler_scan_class.return_value = mock_prowler_scan_instance + + # Mock prowler_provider + mock_prowler_provider_instance = MagicMock() + mock_prowler_provider_instance.get_regions.return_value = ["us-east-1"] + mock_initialize_prowler_provider.return_value = ( + mock_prowler_provider_instance + ) + + # Call the function under test + perform_prowler_scan(tenant_id, scan_id, provider_id, []) + + # Verify mutelist reason takes precedence + finding_db = Finding.objects.get(uid=finding_uid) + assert finding_db.muted + assert finding_db.muted_reason == "Muted by mutelist" + assert finding_db.muted_at is not None + + # Verify failed_findings_count is 0 + resource = Resource.objects.get(uid="resource_both") + assert resource.failed_findings_count == 0 + + def test_perform_prowler_scan_mute_rules_multiple_findings( + self, + tenants_fixture, + scans_fixture, + providers_fixture, + ): + """Test MuteRule with multiple finding UIDs mutes all findings""" + with ( + patch("api.db_utils.rls_transaction"), + patch( + "tasks.jobs.scan.initialize_prowler_provider" + ) as mock_initialize_prowler_provider, + patch("tasks.jobs.scan.ProwlerScan") as mock_prowler_scan_class, + patch( + "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE", + new_callable=dict, + ), + patch("api.compliance.PROWLER_CHECKS", new_callable=dict), + ): + tenant = tenants_fixture[0] + scan = scans_fixture[0] + provider = providers_fixture[0] + + provider.provider = Provider.ProviderChoices.AWS + provider.save() + + tenant_id = str(tenant.id) + scan_id = str(scan.id) + provider_id = str(provider.id) + + # Create MuteRule with multiple finding UIDs + mute_rule_reason = "Bulk exception for dev environment" + finding_uids = [ + "bulk_finding_1", + "bulk_finding_2", + "bulk_finding_3", + "bulk_finding_4", + ] + MuteRule.objects.create( + tenant_id=tenant_id, + name="Bulk Mute Rule", + reason=mute_rule_reason, + enabled=True, + finding_uids=finding_uids, + ) + + # Mock multiple findings with mixed statuses + findings = [] + for i, uid in enumerate(finding_uids): + finding = MagicMock() + finding.uid = uid + finding.status = ( + StatusChoices.FAIL if i % 2 == 0 else StatusChoices.PASS + ) + finding.status_extended = f"test {i}" + finding.severity = Severity.medium + finding.check_id = f"check_{i}" + finding.get_metadata.return_value = {"key": f"value_{i}"} + finding.resource_uid = f"resource_bulk_{i}" + finding.resource_name = f"resource_{i}" + finding.region = "us-west-2" + finding.service_name = "lambda" + finding.resource_type = "function" + finding.resource_tags = {} + finding.muted = False + finding.raw = {} + finding.resource_metadata = {} + finding.resource_details = {} + finding.partition = "aws" + finding.compliance = {} + findings.append(finding) + + # Mock the ProwlerScan instance + mock_prowler_scan_instance = MagicMock() + mock_prowler_scan_instance.scan.return_value = [(100, findings)] + mock_prowler_scan_class.return_value = mock_prowler_scan_instance + + # Mock prowler_provider + mock_prowler_provider_instance = MagicMock() + mock_prowler_provider_instance.get_regions.return_value = ["us-west-2"] + mock_initialize_prowler_provider.return_value = ( + mock_prowler_provider_instance + ) + + # Call the function under test + perform_prowler_scan(tenant_id, scan_id, provider_id, []) + + # Verify all findings are muted with same reason + for uid in finding_uids: + finding_db = Finding.objects.get(uid=uid) + assert finding_db.muted + assert finding_db.muted_reason == mute_rule_reason + assert finding_db.muted_at is not None + + # Verify all resources have failed_findings_count = 0 + for i in range(len(finding_uids)): + resource = Resource.objects.get(uid=f"resource_bulk_{i}") + assert resource.failed_findings_count == 0 + + def test_perform_prowler_scan_mute_rules_error_handling( + self, + tenants_fixture, + scans_fixture, + providers_fixture, + ): + """Test scan continues when MuteRule loading fails""" + with ( + patch("api.db_utils.rls_transaction"), + patch( + "tasks.jobs.scan.initialize_prowler_provider" + ) as mock_initialize_prowler_provider, + patch("tasks.jobs.scan.ProwlerScan") as mock_prowler_scan_class, + patch( + "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE", + new_callable=dict, + ), + patch("api.compliance.PROWLER_CHECKS", new_callable=dict), + patch("api.models.MuteRule.objects.filter") as mock_mute_rule_filter, + ): + tenant = tenants_fixture[0] + scan = scans_fixture[0] + provider = providers_fixture[0] + + provider.provider = Provider.ProviderChoices.AWS + provider.save() + + tenant_id = str(tenant.id) + scan_id = str(scan.id) + provider_id = str(provider.id) + + # Mock MuteRule.objects.filter to raise exception + mock_mute_rule_filter.side_effect = Exception("Database error") + + # Mock finding + finding = MagicMock() + finding.uid = "finding_error_handling" + finding.status = StatusChoices.FAIL + finding.status_extended = "test" + finding.severity = Severity.high + finding.check_id = "test_check" + finding.get_metadata.return_value = {"key": "value"} + finding.resource_uid = "resource_error" + finding.resource_name = "resource_error" + finding.region = "us-east-1" + finding.service_name = "ec2" + finding.resource_type = "instance" + finding.resource_tags = {} + finding.muted = False + finding.raw = {} + finding.resource_metadata = {} + finding.resource_details = {} + finding.partition = "aws" + finding.compliance = {} + + # Mock the ProwlerScan instance + mock_prowler_scan_instance = MagicMock() + mock_prowler_scan_instance.scan.return_value = [(100, [finding])] + mock_prowler_scan_class.return_value = mock_prowler_scan_instance + + # Mock prowler_provider + mock_prowler_provider_instance = MagicMock() + mock_prowler_provider_instance.get_regions.return_value = ["us-east-1"] + mock_initialize_prowler_provider.return_value = ( + mock_prowler_provider_instance + ) + + # Call the function under test - should not raise + perform_prowler_scan(tenant_id, scan_id, provider_id, []) + + # Verify scan completed successfully + scan.refresh_from_db() + assert scan.state == StateChoices.COMPLETED + + # Verify finding is not muted (mute_rules_cache was empty dict) + finding_db = Finding.objects.get(uid="finding_error_handling") + assert not finding_db.muted + assert finding_db.muted_reason is None + + # Verify failed_findings_count increments + resource = Resource.objects.get(uid="resource_error") + assert resource.failed_findings_count == 1 + + def test_perform_prowler_scan_muted_at_timestamp( + self, + tenants_fixture, + scans_fixture, + providers_fixture, + ): + """Test muted_at timestamp is set correctly for muted findings""" + with ( + patch("api.db_utils.rls_transaction"), + patch( + "tasks.jobs.scan.initialize_prowler_provider" + ) as mock_initialize_prowler_provider, + patch("tasks.jobs.scan.ProwlerScan") as mock_prowler_scan_class, + patch( + "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE", + new_callable=dict, + ), + patch("api.compliance.PROWLER_CHECKS", new_callable=dict), + ): + tenant = tenants_fixture[0] + scan = scans_fixture[0] + provider = providers_fixture[0] + + provider.provider = Provider.ProviderChoices.AWS + provider.save() + + tenant_id = str(tenant.id) + scan_id = str(scan.id) + provider_id = str(provider.id) + + # Create active MuteRule + finding_uid = "finding_timestamp_test" + MuteRule.objects.create( + tenant_id=tenant_id, + name="Timestamp Test Rule", + reason="Testing timestamp", + enabled=True, + finding_uids=[finding_uid], + ) + + # Mock finding + finding = MagicMock() + finding.uid = finding_uid + finding.status = StatusChoices.FAIL + finding.status_extended = "test" + finding.severity = Severity.high + finding.check_id = "test_check" + finding.get_metadata.return_value = {"key": "value"} + finding.resource_uid = "resource_timestamp" + finding.resource_name = "resource_timestamp" + finding.region = "us-east-1" + finding.service_name = "ec2" + finding.resource_type = "instance" + finding.resource_tags = {} + finding.muted = False + finding.raw = {} + finding.resource_metadata = {} + finding.resource_details = {} + finding.partition = "aws" + finding.compliance = {} + + # Mock the ProwlerScan instance + mock_prowler_scan_instance = MagicMock() + mock_prowler_scan_instance.scan.return_value = [(100, [finding])] + mock_prowler_scan_class.return_value = mock_prowler_scan_instance + + # Mock prowler_provider + mock_prowler_provider_instance = MagicMock() + mock_prowler_provider_instance.get_regions.return_value = ["us-east-1"] + mock_initialize_prowler_provider.return_value = ( + mock_prowler_provider_instance + ) + + # Capture time before and after scan + before_scan = datetime.now(timezone.utc) + perform_prowler_scan(tenant_id, scan_id, provider_id, []) + after_scan = datetime.now(timezone.utc) + + # Verify muted_at is within the scan time window + finding_db = Finding.objects.get(uid=finding_uid) + assert finding_db.muted + assert finding_db.muted_at is not None + assert before_scan <= finding_db.muted_at <= after_scan + # TODO Add tests for aggregations +@pytest.mark.django_db +class TestProcessFindingMicroBatch: + def test_process_finding_micro_batch_creates_records_and_updates_caches( + self, tenants_fixture, scans_fixture + ): + tenant = tenants_fixture[0] + scan = scans_fixture[0] + provider = scan.provider + + finding = FakeFinding( + uid="finding-new", + status=StatusChoices.PASS, + status_extended="all good", + severity=Severity.low, + check_id="s3_public_buckets", + resource_uid="arn:aws:s3:::bucket-1", + resource_name="bucket-1", + region="us-east-1", + service_name="s3", + resource_type="bucket", + resource_tags={"env": "dev", "team": "security"}, + resource_metadata={"owner": "secops"}, + resource_details={"arn": "arn:aws:s3:::bucket-1"}, + partition="aws", + raw={"status": "PASS"}, + compliance={"cis": {"1.1": "PASS"}}, + metadata={"source": "prowler"}, + muted=False, + ) + + resource_cache = {} + tag_cache = {} + last_status_cache = {} + resource_failed_findings_cache = {} + unique_resources: set[tuple[str, str]] = set() + scan_resource_cache: set[tuple[str, str, str, str]] = set() + mute_rules_cache = {} + + with ( + patch("tasks.jobs.scan.rls_transaction", new=noop_rls_transaction), + patch("api.db_utils.rls_transaction", new=noop_rls_transaction), + ): + _process_finding_micro_batch( + str(tenant.id), + [finding], + scan, + provider, + resource_cache, + tag_cache, + last_status_cache, + resource_failed_findings_cache, + unique_resources, + scan_resource_cache, + mute_rules_cache, + ) + + created_finding = Finding.objects.get(uid=finding.uid) + resource = Resource.objects.get(uid=finding.resource_uid) + + assert created_finding.scan_id == scan.id + assert created_finding.status == StatusChoices.PASS + assert created_finding.delta == Finding.DeltaChoices.NEW + assert created_finding.muted is False + assert created_finding.check_metadata == finding.metadata + assert created_finding.resource_regions == [finding.region] + assert created_finding.resource_services == [finding.service_name] + assert created_finding.resource_types == [finding.resource_type] + assert created_finding.first_seen_at is not None + assert created_finding.compliance == finding.compliance + + assert resource.provider_id == provider.id + assert resource.region == finding.region + assert resource.service == finding.service_name + assert resource.type == finding.resource_type + assert resource.name == finding.resource_name + assert resource.metadata == json.dumps( + finding.resource_metadata, cls=CustomEncoder + ) + assert resource.details == f"{finding.resource_details}" + assert resource.partition == finding.partition + assert set(resource.tags.values_list("key", "value")) == set( + finding.resource_tags.items() + ) + assert resource.findings.filter(uid=finding.uid).exists() + + assert resource_cache[finding.resource_uid].id == resource.id + assert resource_failed_findings_cache[finding.resource_uid] == 0 + assert (resource.uid, resource.region) in unique_resources + assert ( + str(resource.id), + resource.service, + resource.region, + resource.type, + ) in scan_resource_cache + assert set(tag_cache.keys()) == set(finding.resource_tags.items()) + + def test_process_finding_micro_batch_manual_mute_and_dirty_resources( + self, tenants_fixture, scans_fixture + ): + tenant = tenants_fixture[0] + scan = scans_fixture[0] + provider = scan.provider + + existing_resource = Resource.objects.create( + tenant_id=tenant.id, + provider=provider, + uid="arn:aws:ec2:us-east-1:123456789012:instance/i-001", + name="i-001", + region="us-east-1", + service="ec2", + type="instance", + metadata=json.dumps({"old": "meta"}), + details="old-details", + partition="aws-old", + ) + + previous_first_seen = datetime(2024, 1, 1, tzinfo=timezone.utc) + + finding = FakeFinding( + uid="finding-muted", + status=StatusChoices.FAIL, + status_extended="failing", + severity=Severity.high, + check_id="ec2_public_instance", + resource_uid=existing_resource.uid, + resource_name=existing_resource.name, + region="eu-west-1", + service_name="eks", + resource_type="cluster", + resource_tags={"team": "devsec"}, + resource_metadata={"owner": "platform"}, + resource_details={"id": existing_resource.name}, + partition="aws", + raw={"status": "FAIL"}, + compliance={"cis": {"1.2": "FAIL"}}, + metadata={"source": "prowler"}, + muted=False, + ) + + resource_cache = {existing_resource.uid: existing_resource} + tag_cache = {} + last_status_cache = {finding.uid: (StatusChoices.PASS, previous_first_seen)} + resource_failed_findings_cache = {existing_resource.uid: 2} + unique_resources: set[tuple[str, str]] = set() + scan_resource_cache: set[tuple[str, str, str, str]] = set() + mute_rules_cache = {finding.uid: "Muted via rule"} + + with ( + patch("tasks.jobs.scan.rls_transaction", new=noop_rls_transaction), + patch("api.db_utils.rls_transaction", new=noop_rls_transaction), + ): + _process_finding_micro_batch( + str(tenant.id), + [finding], + scan, + provider, + resource_cache, + tag_cache, + last_status_cache, + resource_failed_findings_cache, + unique_resources, + scan_resource_cache, + mute_rules_cache, + ) + + existing_resource.refresh_from_db() + created_finding = Finding.objects.get(uid=finding.uid) + + assert created_finding.delta == Finding.DeltaChoices.CHANGED + assert created_finding.status == StatusChoices.FAIL + assert created_finding.muted is True + assert created_finding.muted_reason == "Muted via rule" + assert created_finding.muted_at is not None + assert created_finding.first_seen_at == previous_first_seen + assert created_finding.compliance == finding.compliance + assert created_finding.resource_regions == [finding.region] + assert created_finding.resource_services == [finding.service_name] + assert created_finding.resource_types == [finding.resource_type] + assert created_finding.scan_id == scan.id + + assert resource_failed_findings_cache[finding.resource_uid] == 2 + assert (finding.resource_uid, finding.region) in unique_resources + assert ( + str(existing_resource.id), + finding.service_name, + finding.region, + finding.resource_type, + ) in scan_resource_cache + + assert existing_resource.region == finding.region + assert existing_resource.service == finding.service_name + assert existing_resource.type == finding.resource_type + assert existing_resource.metadata == json.dumps( + finding.resource_metadata, cls=CustomEncoder + ) + assert existing_resource.details == f"{finding.resource_details}" + assert existing_resource.partition == finding.partition + assert set(existing_resource.tags.values_list("key", "value")) == { + ("team", "devsec") + } + assert existing_resource.findings.filter(uid=finding.uid).exists() + + assert resource_cache[finding.resource_uid].region == finding.region + assert resource_cache[finding.resource_uid].service == finding.service_name + assert tag_cache.keys() == {("team", "devsec")} + + def test_process_finding_micro_batch_skips_long_uid( + self, tenants_fixture, scans_fixture + ): + """Test that findings with UID > 300 chars are skipped (temporary workaround).""" + tenant = tenants_fixture[0] + scan = scans_fixture[0] + provider = scan.provider + + # Create a finding with UID > 300 chars + long_uid = ( + "prowler-aws-ec2_instance_public_ip-123456789012-us-east-1-" + "x" * 250 + ) + assert len(long_uid) > 300 + + finding_with_long_uid = FakeFinding( + uid=long_uid, + status=StatusChoices.FAIL, + status_extended="public instance", + severity=Severity.high, + check_id="ec2_instance_public_ip", + resource_uid="arn:aws:ec2:us-east-1:123456789012:instance/i-long", + resource_name="i-long-uid-instance", + region="us-east-1", + service_name="ec2", + resource_type="instance", + resource_tags={}, + resource_metadata={}, + resource_details={}, + partition="aws", + raw={}, + compliance={}, + metadata={}, + muted=False, + ) + + # Create a normal finding that should be processed + normal_finding = FakeFinding( + uid="finding-normal", + status=StatusChoices.PASS, + status_extended="all good", + severity=Severity.low, + check_id="s3_bucket_encryption", + resource_uid="arn:aws:s3:::bucket-normal", + resource_name="bucket-normal", + region="us-east-1", + service_name="s3", + resource_type="bucket", + resource_tags={}, + resource_metadata={}, + resource_details={}, + partition="aws", + raw={}, + compliance={}, + metadata={}, + muted=False, + ) + + resource_cache = {} + tag_cache = {} + last_status_cache = {} + resource_failed_findings_cache = {} + unique_resources: set[tuple[str, str]] = set() + scan_resource_cache: set[tuple[str, str, str, str]] = set() + mute_rules_cache = {} + + with ( + patch("tasks.jobs.scan.rls_transaction", new=noop_rls_transaction), + patch("api.db_utils.rls_transaction", new=noop_rls_transaction), + patch("tasks.jobs.scan.logger") as mock_logger, + ): + _process_finding_micro_batch( + str(tenant.id), + [finding_with_long_uid, normal_finding], + scan, + provider, + resource_cache, + tag_cache, + last_status_cache, + resource_failed_findings_cache, + unique_resources, + scan_resource_cache, + mute_rules_cache, + ) + + # Verify the long UID finding was NOT created + assert not Finding.objects.filter(uid=long_uid).exists() + + # Verify the normal finding WAS created + assert Finding.objects.filter(uid=normal_finding.uid).exists() + + # Verify logging was called for skipped finding + assert mock_logger.warning.called + warning_calls = [str(call) for call in mock_logger.warning.call_args_list] + assert any( + "Skipping finding with UID exceeding 300 characters" in str(call) + for call in warning_calls + ) + assert any( + f"Scan {scan.id}: Skipped 1 finding(s)" in str(call) + for call in warning_calls + ) + + @pytest.mark.django_db class TestCreateComplianceRequirements: def test_create_compliance_requirements_success( @@ -748,12 +1656,9 @@ class TestCreateComplianceRequirements: findings_fixture, resources_fixture, ): - with ( - patch( - "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE" - ) as mock_compliance_template, - patch("tasks.jobs.scan.generate_scan_compliance"), - ): + with patch( + "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE" + ) as mock_compliance_template: tenant_id = str(tenants_fixture[0].id) scan_id = str(scans_fixture[0].id) @@ -764,6 +1669,7 @@ class TestCreateComplianceRequirements: "requirements": { "1.1": { "description": "Ensure root access key does not exist", + "checks": {"test_check_id": None}, "checks_status": { "pass": 0, "fail": 0, @@ -774,6 +1680,7 @@ class TestCreateComplianceRequirements: }, "1.2": { "description": "Ensure MFA is enabled for root account", + "checks": {"test_check_id": None}, "checks_status": { "pass": 0, "fail": 1, @@ -799,12 +1706,9 @@ class TestCreateComplianceRequirements: providers_fixture, findings_fixture, ): - with ( - patch( - "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE" - ) as mock_compliance_template, - patch("tasks.jobs.scan.generate_scan_compliance"), - ): + with patch( + "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE" + ) as mock_compliance_template: tenant_id = str(tenants_fixture[0].id) scan_id = str(scans_fixture[0].id) @@ -815,6 +1719,7 @@ class TestCreateComplianceRequirements: "requirements": { "req_1": { "description": "Test Requirement 1", + "checks": {"test_check_id": None}, "checks_status": { "pass": 2, "fail": 1, @@ -838,12 +1743,9 @@ class TestCreateComplianceRequirements: providers_fixture, findings_fixture, ): - with ( - patch( - "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE" - ) as mock_compliance_template, - patch("tasks.jobs.scan.generate_scan_compliance"), - ): + with patch( + "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE" + ) as mock_compliance_template: tenant = tenants_fixture[0] scan = scans_fixture[0] provider = providers_fixture[0] @@ -863,6 +1765,7 @@ class TestCreateComplianceRequirements: "requirements": { "1.1": { "description": "Test requirement", + "checks": {"test_check_id": None}, "checks_status": { "pass": 0, "fail": 0, @@ -886,12 +1789,9 @@ class TestCreateComplianceRequirements: providers_fixture, findings_fixture, ): - with ( - patch( - "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE" - ) as mock_compliance_template, - patch("tasks.jobs.scan.generate_scan_compliance"), - ): + with patch( + "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE" + ) as mock_compliance_template: tenant_id = str(tenants_fixture[0].id) scan_id = str(scans_fixture[0].id) @@ -920,18 +1820,41 @@ class TestCreateComplianceRequirements: create_compliance_requirements(tenant_id, scan_id) def test_create_compliance_requirements_check_status_priority( - self, tenants_fixture, scans_fixture, providers_fixture, findings_fixture + self, tenants_fixture, scans_fixture, findings_fixture ): with ( patch( "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE" ) as mock_compliance_template, patch( - "tasks.jobs.scan.generate_scan_compliance" - ) as mock_generate_compliance, + "tasks.jobs.scan._persist_compliance_requirement_rows" + ) as mock_persist, + patch("tasks.jobs.scan._create_compliance_summaries"), ): tenant_id = str(tenants_fixture[0].id) - scan_id = str(scans_fixture[0].id) + scan = scans_fixture[0] + scan_id = str(scan.id) + existing_finding = findings_fixture[0] + + pass_finding = Finding.objects.create( + tenant_id=scan.tenant_id, + uid="pass-finding", + scan=scan, + delta=None, + status=Status.PASS, + status_extended="pass status", + impact=Severity.low, + impact_extended="", + severity=Severity.low, + raw_result={"status": Status.PASS}, + tags={}, + check_id=existing_finding.check_id, + check_metadata={"CheckId": existing_finding.check_id}, + first_seen_at=datetime.now(timezone.utc), + muted=False, + ) + resource = existing_finding.resources.first() + pass_finding.add_resources([resource]) mock_compliance_template.__getitem__.return_value = { "cis_1.4_aws": { @@ -940,6 +1863,7 @@ class TestCreateComplianceRequirements: "requirements": { "1.1": { "description": "Test requirement", + "checks": {existing_finding.check_id: None}, "checks_status": { "pass": 0, "fail": 0, @@ -954,7 +1878,12 @@ class TestCreateComplianceRequirements: create_compliance_requirements(tenant_id, scan_id) - assert mock_generate_compliance.call_count == 1 + mock_persist.assert_called_once() + persisted_rows = mock_persist.call_args[0][1] + requirement_row = next( + row for row in persisted_rows if row["requirement_id"] == "1.1" + ) + assert requirement_row["requirement_status"] == "FAIL" def test_create_compliance_requirements_multiple_regions( self, @@ -963,12 +1892,9 @@ class TestCreateComplianceRequirements: providers_fixture, findings_fixture, ): - with ( - patch( - "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE" - ) as mock_compliance_template, - patch("tasks.jobs.scan.generate_scan_compliance"), - ): + with patch( + "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE" + ) as mock_compliance_template: tenant_id = str(tenants_fixture[0].id) scan_id = str(scans_fixture[0].id) @@ -979,6 +1905,7 @@ class TestCreateComplianceRequirements: "requirements": { "req_1": { "description": "Test Requirement 1", + "checks": {"test_check_id": None}, "checks_status": { "pass": 2, "fail": 0, @@ -1003,12 +1930,9 @@ class TestCreateComplianceRequirements: providers_fixture, findings_fixture, ): - with ( - patch( - "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE" - ) as mock_compliance_template, - patch("tasks.jobs.scan.generate_scan_compliance"), - ): + with patch( + "tasks.jobs.scan.PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE" + ) as mock_compliance_template: tenant_id = str(tenants_fixture[0].id) scan_id = str(scans_fixture[0].id) @@ -1019,6 +1943,7 @@ class TestCreateComplianceRequirements: "requirements": { "req_1": { "description": "Test Requirement 1", + "checks": {"test_check_id": None}, "checks_status": { "pass": 2, "fail": 0, @@ -1029,6 +1954,7 @@ class TestCreateComplianceRequirements: }, "req_2": { "description": "Test Requirement 2", + "checks": {"test_check_id": None}, "checks_status": { "pass": 1, "fail": 1, @@ -1045,3 +1971,1503 @@ class TestCreateComplianceRequirements: assert "requirements_created" in result assert result["requirements_created"] >= 0 + + +class TestComplianceRequirementCopy: + @patch("tasks.jobs.scan.psycopg_connection") + def test_copy_compliance_requirement_rows_streams_csv( + self, mock_psycopg_connection, settings + ): + settings.DATABASES.setdefault("admin", settings.DATABASES["default"]) + + connection = MagicMock() + cursor = MagicMock() + cursor_context = MagicMock() + cursor_context.__enter__.return_value = cursor + cursor_context.__exit__.return_value = False + connection.cursor.return_value = cursor_context + connection.__enter__.return_value = connection + connection.__exit__.return_value = False + + context_manager = MagicMock() + context_manager.__enter__.return_value = connection + context_manager.__exit__.return_value = False + mock_psycopg_connection.return_value = context_manager + + captured = {} + + def copy_side_effect(sql, file_obj): + captured["sql"] = sql + captured["data"] = file_obj.read() + + cursor.copy_expert.side_effect = copy_side_effect + + row = { + "id": uuid.uuid4(), + "tenant_id": str(uuid.uuid4()), + "compliance_id": "cisa_aws", + "framework": "CISA", + "version": None, + "description": "desc", + "region": "us-east-1", + "requirement_id": "req-1", + "requirement_status": "PASS", + "passed_checks": 1, + "failed_checks": 0, + "total_checks": 1, + "scan_id": uuid.uuid4(), + } + + with patch.object(MainRouter, "admin_db", "admin"): + _copy_compliance_requirement_rows(str(row["tenant_id"]), [row]) + + mock_psycopg_connection.assert_called_once_with("admin") + connection.cursor.assert_called_once() + cursor.execute.assert_called_once() + cursor.copy_expert.assert_called_once() + + csv_rows = list(csv.reader(StringIO(captured["data"]))) + assert csv_rows[0][0] == str(row["id"]) + assert csv_rows[0][5] == "" + assert csv_rows[0][-1] == str(row["scan_id"]) + + @patch("tasks.jobs.scan.ComplianceRequirementOverview.objects.bulk_create") + @patch("tasks.jobs.scan.rls_transaction") + @patch( + "tasks.jobs.scan._copy_compliance_requirement_rows", + side_effect=Exception("copy failed"), + ) + def test_persist_compliance_requirement_rows_fallback( + self, mock_copy, mock_rls_transaction, mock_bulk_create + ): + inserted_at = datetime.now(timezone.utc) + row = { + "id": uuid.uuid4(), + "tenant_id": str(uuid.uuid4()), + "inserted_at": inserted_at, + "compliance_id": "cisa_aws", + "framework": "CISA", + "version": "1.0", + "description": "desc", + "region": "us-east-1", + "requirement_id": "req-1", + "requirement_status": "PASS", + "passed_checks": 1, + "failed_checks": 0, + "total_checks": 1, + "scan_id": uuid.uuid4(), + } + + tenant_id = row["tenant_id"] + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + + _persist_compliance_requirement_rows(tenant_id, [row]) + + mock_copy.assert_called_once_with(tenant_id, [row]) + mock_rls_transaction.assert_called_once_with(tenant_id) + mock_bulk_create.assert_called_once() + + args, kwargs = mock_bulk_create.call_args + objects = args[0] + assert len(objects) == 1 + fallback = objects[0] + assert fallback.version == row["version"] + assert fallback.compliance_id == row["compliance_id"] + + @patch("tasks.jobs.scan.ComplianceRequirementOverview.objects.bulk_create") + @patch("tasks.jobs.scan.rls_transaction") + @patch("tasks.jobs.scan._copy_compliance_requirement_rows") + def test_persist_compliance_requirement_rows_no_rows( + self, mock_copy, mock_rls_transaction, mock_bulk_create + ): + _persist_compliance_requirement_rows(str(uuid.uuid4()), []) + + mock_copy.assert_not_called() + mock_rls_transaction.assert_not_called() + mock_bulk_create.assert_not_called() + + @patch("tasks.jobs.scan.psycopg_connection") + def test_copy_compliance_requirement_rows_multiple_rows( + self, mock_psycopg_connection, settings + ): + """Test COPY with multiple rows to ensure batch processing works correctly.""" + settings.DATABASES.setdefault("admin", settings.DATABASES["default"]) + + connection = MagicMock() + cursor = MagicMock() + cursor_context = MagicMock() + cursor_context.__enter__.return_value = cursor + cursor_context.__exit__.return_value = False + connection.cursor.return_value = cursor_context + connection.__enter__.return_value = connection + connection.__exit__.return_value = False + + context_manager = MagicMock() + context_manager.__enter__.return_value = connection + context_manager.__exit__.return_value = False + mock_psycopg_connection.return_value = context_manager + + captured = {} + + def copy_side_effect(sql, file_obj): + captured["sql"] = sql + captured["data"] = file_obj.read() + + cursor.copy_expert.side_effect = copy_side_effect + + tenant_id = str(uuid.uuid4()) + scan_id = uuid.uuid4() + inserted_at = datetime.now(timezone.utc) + + rows = [ + { + "id": uuid.uuid4(), + "tenant_id": tenant_id, + "inserted_at": inserted_at, + "compliance_id": "cisa_aws", + "framework": "CISA", + "version": "1.0", + "description": "First requirement", + "region": "us-east-1", + "requirement_id": "req-1", + "requirement_status": "PASS", + "passed_checks": 5, + "failed_checks": 0, + "total_checks": 5, + "scan_id": scan_id, + }, + { + "id": uuid.uuid4(), + "tenant_id": tenant_id, + "inserted_at": inserted_at, + "compliance_id": "cisa_aws", + "framework": "CISA", + "version": "1.0", + "description": "Second requirement", + "region": "us-west-2", + "requirement_id": "req-2", + "requirement_status": "FAIL", + "passed_checks": 3, + "failed_checks": 2, + "total_checks": 5, + "scan_id": scan_id, + }, + { + "id": uuid.uuid4(), + "tenant_id": tenant_id, + "inserted_at": inserted_at, + "compliance_id": "aws_foundational_security_aws", + "framework": "AWS-Foundational-Security-Best-Practices", + "version": "2.0", + "description": "Third requirement", + "region": "eu-west-1", + "requirement_id": "req-3", + "requirement_status": "MANUAL", + "passed_checks": 0, + "failed_checks": 0, + "total_checks": 3, + "scan_id": scan_id, + }, + ] + + with patch.object(MainRouter, "admin_db", "admin"): + _copy_compliance_requirement_rows(tenant_id, rows) + + mock_psycopg_connection.assert_called_once_with("admin") + connection.cursor.assert_called_once() + cursor.execute.assert_called_once() + cursor.copy_expert.assert_called_once() + + csv_rows = list(csv.reader(StringIO(captured["data"]))) + assert len(csv_rows) == 3 + + # Validate first row + assert csv_rows[0][0] == str(rows[0]["id"]) + assert csv_rows[0][1] == tenant_id + assert csv_rows[0][3] == "cisa_aws" + assert csv_rows[0][4] == "CISA" + assert csv_rows[0][6] == "First requirement" + assert csv_rows[0][7] == "us-east-1" + assert csv_rows[0][10] == "5" + assert csv_rows[0][11] == "0" + assert csv_rows[0][12] == "5" + + # Validate second row + assert csv_rows[1][0] == str(rows[1]["id"]) + assert csv_rows[1][7] == "us-west-2" + assert csv_rows[1][9] == "FAIL" + assert csv_rows[1][10] == "3" + assert csv_rows[1][11] == "2" + + # Validate third row + assert csv_rows[2][0] == str(rows[2]["id"]) + assert csv_rows[2][3] == "aws_foundational_security_aws" + assert csv_rows[2][5] == "2.0" + assert csv_rows[2][9] == "MANUAL" + + @patch("tasks.jobs.scan.psycopg_connection") + def test_copy_compliance_requirement_rows_null_values( + self, mock_psycopg_connection, settings + ): + """Test COPY handles NULL/None values correctly in nullable fields.""" + settings.DATABASES.setdefault("admin", settings.DATABASES["default"]) + + connection = MagicMock() + cursor = MagicMock() + cursor_context = MagicMock() + cursor_context.__enter__.return_value = cursor + cursor_context.__exit__.return_value = False + connection.cursor.return_value = cursor_context + connection.__enter__.return_value = connection + connection.__exit__.return_value = False + + context_manager = MagicMock() + context_manager.__enter__.return_value = connection + context_manager.__exit__.return_value = False + mock_psycopg_connection.return_value = context_manager + + captured = {} + + def copy_side_effect(sql, file_obj): + captured["sql"] = sql + captured["data"] = file_obj.read() + + cursor.copy_expert.side_effect = copy_side_effect + + # Row with all nullable fields set to None/empty + row = { + "id": uuid.uuid4(), + "tenant_id": str(uuid.uuid4()), + "compliance_id": "test_framework", + "framework": "Test", + "version": None, # nullable + "description": None, # nullable + "region": "", + "requirement_id": "req-1", + "requirement_status": "PASS", + "passed_checks": 0, + "failed_checks": 0, + "total_checks": 0, + "scan_id": uuid.uuid4(), + } + + with patch.object(MainRouter, "admin_db", "admin"): + _copy_compliance_requirement_rows(str(row["tenant_id"]), [row]) + + csv_rows = list(csv.reader(StringIO(captured["data"]))) + assert len(csv_rows) == 1 + + # Validate that None values are converted to empty strings in CSV + assert csv_rows[0][5] == "" # version + assert csv_rows[0][6] == "" # description + + @patch("tasks.jobs.scan.psycopg_connection") + def test_copy_compliance_requirement_rows_special_characters( + self, mock_psycopg_connection, settings + ): + """Test COPY correctly escapes special characters in CSV.""" + settings.DATABASES.setdefault("admin", settings.DATABASES["default"]) + + connection = MagicMock() + cursor = MagicMock() + cursor_context = MagicMock() + cursor_context.__enter__.return_value = cursor + cursor_context.__exit__.return_value = False + connection.cursor.return_value = cursor_context + connection.__enter__.return_value = connection + connection.__exit__.return_value = False + + context_manager = MagicMock() + context_manager.__enter__.return_value = connection + context_manager.__exit__.return_value = False + mock_psycopg_connection.return_value = context_manager + + captured = {} + + def copy_side_effect(sql, file_obj): + captured["sql"] = sql + captured["data"] = file_obj.read() + + cursor.copy_expert.side_effect = copy_side_effect + + # Row with special characters that need escaping + row = { + "id": uuid.uuid4(), + "tenant_id": str(uuid.uuid4()), + "compliance_id": 'framework"with"quotes', + "framework": "Framework,with,commas", + "version": "1.0", + "description": 'Description with "quotes", commas, and\nnewlines', + "region": "us-east-1", + "requirement_id": "req-1", + "requirement_status": "PASS", + "passed_checks": 1, + "failed_checks": 0, + "total_checks": 1, + "scan_id": uuid.uuid4(), + } + + with patch.object(MainRouter, "admin_db", "admin"): + _copy_compliance_requirement_rows(str(row["tenant_id"]), [row]) + + # Verify CSV was generated (csv module handles escaping automatically) + csv_rows = list(csv.reader(StringIO(captured["data"]))) + assert len(csv_rows) == 1 + + # Verify special characters are preserved after CSV parsing + assert csv_rows[0][3] == 'framework"with"quotes' + assert csv_rows[0][4] == "Framework,with,commas" + assert "quotes" in csv_rows[0][6] + assert "commas" in csv_rows[0][6] + + @patch("tasks.jobs.scan.psycopg_connection") + def test_copy_compliance_requirement_rows_missing_inserted_at( + self, mock_psycopg_connection, settings + ): + """Test COPY uses current datetime when inserted_at is missing.""" + settings.DATABASES.setdefault("admin", settings.DATABASES["default"]) + + connection = MagicMock() + cursor = MagicMock() + cursor_context = MagicMock() + cursor_context.__enter__.return_value = cursor + cursor_context.__exit__.return_value = False + connection.cursor.return_value = cursor_context + connection.__enter__.return_value = connection + connection.__exit__.return_value = False + + context_manager = MagicMock() + context_manager.__enter__.return_value = connection + context_manager.__exit__.return_value = False + mock_psycopg_connection.return_value = context_manager + + captured = {} + + def copy_side_effect(sql, file_obj): + captured["sql"] = sql + captured["data"] = file_obj.read() + + cursor.copy_expert.side_effect = copy_side_effect + + # Row without inserted_at field + row = { + "id": uuid.uuid4(), + "tenant_id": str(uuid.uuid4()), + "compliance_id": "test_framework", + "framework": "Test", + "version": "1.0", + "description": "desc", + "region": "us-east-1", + "requirement_id": "req-1", + "requirement_status": "PASS", + "passed_checks": 1, + "failed_checks": 0, + "total_checks": 1, + "scan_id": uuid.uuid4(), + # Note: inserted_at is intentionally missing + } + + before_call = datetime.now(timezone.utc) + with patch.object(MainRouter, "admin_db", "admin"): + _copy_compliance_requirement_rows(str(row["tenant_id"]), [row]) + after_call = datetime.now(timezone.utc) + + csv_rows = list(csv.reader(StringIO(captured["data"]))) + assert len(csv_rows) == 1 + + # Verify inserted_at was auto-generated and is a valid ISO datetime + inserted_at_str = csv_rows[0][2] + inserted_at = datetime.fromisoformat(inserted_at_str) + assert before_call <= inserted_at <= after_call + + @patch("tasks.jobs.scan.psycopg_connection") + def test_copy_compliance_requirement_rows_transaction_rollback_on_copy_error( + self, mock_psycopg_connection, settings + ): + """Test transaction is rolled back when copy_expert fails.""" + settings.DATABASES.setdefault("admin", settings.DATABASES["default"]) + + connection = MagicMock() + cursor = MagicMock() + cursor_context = MagicMock() + cursor_context.__enter__.return_value = cursor + cursor_context.__exit__.return_value = False + connection.cursor.return_value = cursor_context + connection.__enter__.return_value = connection + connection.__exit__.return_value = False + + context_manager = MagicMock() + context_manager.__enter__.return_value = connection + context_manager.__exit__.return_value = False + mock_psycopg_connection.return_value = context_manager + + # Simulate copy_expert failure + cursor.copy_expert.side_effect = Exception("COPY command failed") + + row = { + "id": uuid.uuid4(), + "tenant_id": str(uuid.uuid4()), + "compliance_id": "test", + "framework": "Test", + "version": "1.0", + "description": "desc", + "region": "us-east-1", + "requirement_id": "req-1", + "requirement_status": "PASS", + "passed_checks": 1, + "failed_checks": 0, + "total_checks": 1, + "scan_id": uuid.uuid4(), + } + + with patch.object(MainRouter, "admin_db", "admin"): + with pytest.raises(Exception, match="COPY command failed"): + _copy_compliance_requirement_rows(str(row["tenant_id"]), [row]) + + # Verify rollback was called + connection.rollback.assert_called_once() + connection.commit.assert_not_called() + + @patch("tasks.jobs.scan.psycopg_connection") + def test_copy_compliance_requirement_rows_transaction_rollback_on_set_config_error( + self, mock_psycopg_connection, settings + ): + """Test transaction is rolled back when SET_CONFIG fails.""" + settings.DATABASES.setdefault("admin", settings.DATABASES["default"]) + + connection = MagicMock() + cursor = MagicMock() + cursor_context = MagicMock() + cursor_context.__enter__.return_value = cursor + cursor_context.__exit__.return_value = False + connection.cursor.return_value = cursor_context + connection.__enter__.return_value = connection + connection.__exit__.return_value = False + + context_manager = MagicMock() + context_manager.__enter__.return_value = connection + context_manager.__exit__.return_value = False + mock_psycopg_connection.return_value = context_manager + + # Simulate cursor.execute failure + cursor.execute.side_effect = Exception("SET prowler.tenant_id failed") + + row = { + "id": uuid.uuid4(), + "tenant_id": str(uuid.uuid4()), + "compliance_id": "test", + "framework": "Test", + "version": "1.0", + "description": "desc", + "region": "us-east-1", + "requirement_id": "req-1", + "requirement_status": "PASS", + "passed_checks": 1, + "failed_checks": 0, + "total_checks": 1, + "scan_id": uuid.uuid4(), + } + + with patch.object(MainRouter, "admin_db", "admin"): + with pytest.raises(Exception, match="SET prowler.tenant_id failed"): + _copy_compliance_requirement_rows(str(row["tenant_id"]), [row]) + + # Verify rollback was called + connection.rollback.assert_called_once() + connection.commit.assert_not_called() + + @patch("tasks.jobs.scan.psycopg_connection") + def test_copy_compliance_requirement_rows_commit_on_success( + self, mock_psycopg_connection, settings + ): + """Test transaction is committed on successful COPY.""" + settings.DATABASES.setdefault("admin", settings.DATABASES["default"]) + + connection = MagicMock() + cursor = MagicMock() + cursor_context = MagicMock() + cursor_context.__enter__.return_value = cursor + cursor_context.__exit__.return_value = False + connection.cursor.return_value = cursor_context + connection.__enter__.return_value = connection + connection.__exit__.return_value = False + + context_manager = MagicMock() + context_manager.__enter__.return_value = connection + context_manager.__exit__.return_value = False + mock_psycopg_connection.return_value = context_manager + + cursor.copy_expert.return_value = None # Success + + row = { + "id": uuid.uuid4(), + "tenant_id": str(uuid.uuid4()), + "compliance_id": "test", + "framework": "Test", + "version": "1.0", + "description": "desc", + "region": "us-east-1", + "requirement_id": "req-1", + "requirement_status": "PASS", + "passed_checks": 1, + "failed_checks": 0, + "total_checks": 1, + "scan_id": uuid.uuid4(), + } + + with patch.object(MainRouter, "admin_db", "admin"): + _copy_compliance_requirement_rows(str(row["tenant_id"]), [row]) + + # Verify commit was called and rollback was not + connection.commit.assert_called_once() + connection.rollback.assert_not_called() + # Verify autocommit was disabled + assert connection.autocommit is False + + @patch("tasks.jobs.scan._copy_compliance_requirement_rows") + def test_persist_compliance_requirement_rows_success(self, mock_copy): + """Test successful COPY path without fallback to ORM.""" + mock_copy.return_value = None # Success, no exception + + tenant_id = str(uuid.uuid4()) + rows = [ + { + "id": uuid.uuid4(), + "tenant_id": tenant_id, + "inserted_at": datetime.now(timezone.utc), + "compliance_id": "test", + "framework": "Test", + "version": "1.0", + "description": "desc", + "region": "us-east-1", + "requirement_id": "req-1", + "requirement_status": "PASS", + "passed_checks": 1, + "failed_checks": 0, + "total_checks": 1, + "scan_id": uuid.uuid4(), + } + ] + + _persist_compliance_requirement_rows(tenant_id, rows) + + # Verify COPY was called + mock_copy.assert_called_once_with(tenant_id, rows) + + @patch("tasks.jobs.scan.logger") + @patch("tasks.jobs.scan.ComplianceRequirementOverview.objects.bulk_create") + @patch("tasks.jobs.scan.rls_transaction") + @patch( + "tasks.jobs.scan._copy_compliance_requirement_rows", + side_effect=Exception("COPY failed"), + ) + def test_persist_compliance_requirement_rows_fallback_logging( + self, mock_copy, mock_rls_transaction, mock_bulk_create, mock_logger + ): + """Test logger.exception is called when COPY fails and fallback occurs.""" + tenant_id = str(uuid.uuid4()) + row = { + "id": uuid.uuid4(), + "tenant_id": tenant_id, + "inserted_at": datetime.now(timezone.utc), + "compliance_id": "test", + "framework": "Test", + "version": "1.0", + "description": "desc", + "region": "us-east-1", + "requirement_id": "req-1", + "requirement_status": "PASS", + "passed_checks": 1, + "failed_checks": 0, + "total_checks": 1, + "scan_id": uuid.uuid4(), + } + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + + _persist_compliance_requirement_rows(tenant_id, [row]) + + # Verify logger.exception was called + mock_logger.exception.assert_called_once() + args, kwargs = mock_logger.exception.call_args + assert "COPY bulk insert" in args[0] + assert "falling back to ORM" in args[0] + assert kwargs.get("exc_info") is not None + + @patch("tasks.jobs.scan.ComplianceRequirementOverview.objects.bulk_create") + @patch("tasks.jobs.scan.rls_transaction") + @patch( + "tasks.jobs.scan._copy_compliance_requirement_rows", + side_effect=Exception("copy failed"), + ) + def test_persist_compliance_requirement_rows_fallback_multiple_rows( + self, mock_copy, mock_rls_transaction, mock_bulk_create + ): + """Test ORM fallback with multiple rows.""" + tenant_id = str(uuid.uuid4()) + scan_id = uuid.uuid4() + inserted_at = datetime.now(timezone.utc) + + rows = [ + { + "id": uuid.uuid4(), + "tenant_id": tenant_id, + "inserted_at": inserted_at, + "compliance_id": "cisa_aws", + "framework": "CISA", + "version": "1.0", + "description": "First requirement", + "region": "us-east-1", + "requirement_id": "req-1", + "requirement_status": "PASS", + "passed_checks": 5, + "failed_checks": 0, + "total_checks": 5, + "scan_id": scan_id, + }, + { + "id": uuid.uuid4(), + "tenant_id": tenant_id, + "inserted_at": inserted_at, + "compliance_id": "cisa_aws", + "framework": "CISA", + "version": "1.0", + "description": "Second requirement", + "region": "us-west-2", + "requirement_id": "req-2", + "requirement_status": "FAIL", + "passed_checks": 2, + "failed_checks": 3, + "total_checks": 5, + "scan_id": scan_id, + }, + ] + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + + _persist_compliance_requirement_rows(tenant_id, rows) + + mock_copy.assert_called_once_with(tenant_id, rows) + mock_rls_transaction.assert_called_once_with(tenant_id) + mock_bulk_create.assert_called_once() + + args, kwargs = mock_bulk_create.call_args + objects = args[0] + assert len(objects) == 2 + assert kwargs["batch_size"] == 500 + + # Validate first object + assert objects[0].id == rows[0]["id"] + assert objects[0].tenant_id == rows[0]["tenant_id"] + assert objects[0].compliance_id == rows[0]["compliance_id"] + assert objects[0].framework == rows[0]["framework"] + assert objects[0].region == rows[0]["region"] + assert objects[0].passed_checks == 5 + assert objects[0].failed_checks == 0 + + # Validate second object + assert objects[1].id == rows[1]["id"] + assert objects[1].requirement_id == rows[1]["requirement_id"] + assert objects[1].requirement_status == rows[1]["requirement_status"] + assert objects[1].passed_checks == 2 + assert objects[1].failed_checks == 3 + + @patch("tasks.jobs.scan.ComplianceRequirementOverview.objects.bulk_create") + @patch("tasks.jobs.scan.rls_transaction") + @patch( + "tasks.jobs.scan._copy_compliance_requirement_rows", + side_effect=Exception("copy failed"), + ) + def test_persist_compliance_requirement_rows_fallback_all_fields( + self, mock_copy, mock_rls_transaction, mock_bulk_create + ): + """Test ORM fallback correctly maps all fields from row dict to model.""" + tenant_id = str(uuid.uuid4()) + row_id = uuid.uuid4() + scan_id = uuid.uuid4() + inserted_at = datetime.now(timezone.utc) + + row = { + "id": row_id, + "tenant_id": tenant_id, + "inserted_at": inserted_at, + "compliance_id": "aws_foundational_security_aws", + "framework": "AWS-Foundational-Security-Best-Practices", + "version": "2.0", + "description": "Ensure MFA is enabled", + "region": "eu-west-1", + "requirement_id": "iam.1", + "requirement_status": "FAIL", + "passed_checks": 10, + "failed_checks": 5, + "total_checks": 15, + "scan_id": scan_id, + } + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + + _persist_compliance_requirement_rows(tenant_id, [row]) + + args, kwargs = mock_bulk_create.call_args + objects = args[0] + assert len(objects) == 1 + + obj = objects[0] + # Validate ALL fields are correctly mapped + assert obj.id == row_id + assert obj.tenant_id == tenant_id + assert obj.inserted_at == inserted_at + assert obj.compliance_id == "aws_foundational_security_aws" + assert obj.framework == "AWS-Foundational-Security-Best-Practices" + assert obj.version == "2.0" + assert obj.description == "Ensure MFA is enabled" + assert obj.region == "eu-west-1" + assert obj.requirement_id == "iam.1" + assert obj.requirement_status == "FAIL" + assert obj.passed_checks == 10 + assert obj.failed_checks == 5 + assert obj.total_checks == 15 + assert obj.scan_id == scan_id + + +@pytest.mark.django_db +class TestCreateComplianceSummaries: + """Test _create_compliance_summaries function.""" + + @patch("tasks.jobs.scan.ComplianceOverviewSummary.objects.bulk_create") + @patch("tasks.jobs.scan.rls_transaction") + def test_create_compliance_summaries_mixed_statuses( + self, mock_rls_transaction, mock_bulk_create + ): + """Test creating summaries with mixed requirement statuses (PASS/FAIL/MANUAL).""" + tenant_id = str(uuid.uuid4()) + scan_id = str(uuid.uuid4()) + + # Simulate pre-computed requirement statuses + requirement_statuses = { + ("compliance1", "req1"): { + "fail_count": 0, + "pass_count": 5, + "total_count": 5, + }, + ("compliance1", "req2"): { + "fail_count": 2, + "pass_count": 3, + "total_count": 5, + }, + ("compliance1", "req3"): { + "fail_count": 0, + "pass_count": 3, + "total_count": 5, + }, + ("compliance2", "req1"): { + "fail_count": 1, + "pass_count": 0, + "total_count": 5, + }, + } + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + + _create_compliance_summaries(tenant_id, scan_id, requirement_statuses) + + mock_rls_transaction.assert_called_once_with(tenant_id) + mock_bulk_create.assert_called_once() + + args, kwargs = mock_bulk_create.call_args + objects = args[0] + assert len(objects) == 2 + assert kwargs["batch_size"] == 500 + + # Find compliance1 and compliance2 summaries + comp1 = next(obj for obj in objects if obj.compliance_id == "compliance1") + comp2 = next(obj for obj in objects if obj.compliance_id == "compliance2") + + # compliance1: req1=PASS, req2=FAIL (has fail_count), req3=MANUAL (pass < total) + assert comp1.total_requirements == 3 + assert comp1.requirements_passed == 1 + assert comp1.requirements_failed == 1 + assert comp1.requirements_manual == 1 + + # compliance2: req1=FAIL (has fail_count) + assert comp2.total_requirements == 1 + assert comp2.requirements_passed == 0 + assert comp2.requirements_failed == 1 + assert comp2.requirements_manual == 0 + + @patch("tasks.jobs.scan.ComplianceOverviewSummary.objects.bulk_create") + @patch("tasks.jobs.scan.rls_transaction") + def test_create_compliance_summaries_empty_input( + self, mock_rls_transaction, mock_bulk_create + ): + """Test with empty requirement_statuses dict - should not create any summaries.""" + tenant_id = str(uuid.uuid4()) + scan_id = str(uuid.uuid4()) + requirement_statuses = {} + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + + _create_compliance_summaries(tenant_id, scan_id, requirement_statuses) + + # Should not call bulk_create with empty list + mock_bulk_create.assert_not_called() + + @patch("tasks.jobs.scan.ComplianceOverviewSummary.objects.bulk_create") + @patch("tasks.jobs.scan.rls_transaction") + def test_create_compliance_summaries_all_pass( + self, mock_rls_transaction, mock_bulk_create + ): + """Test creating summaries when all requirements pass.""" + tenant_id = str(uuid.uuid4()) + scan_id = str(uuid.uuid4()) + + requirement_statuses = { + ("comp1", "req1"): {"fail_count": 0, "pass_count": 10, "total_count": 10}, + ("comp1", "req2"): {"fail_count": 0, "pass_count": 5, "total_count": 5}, + } + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + + _create_compliance_summaries(tenant_id, scan_id, requirement_statuses) + + args, kwargs = mock_bulk_create.call_args + objects = args[0] + assert len(objects) == 1 + + obj = objects[0] + assert obj.compliance_id == "comp1" + assert obj.total_requirements == 2 + assert obj.requirements_passed == 2 + assert obj.requirements_failed == 0 + assert obj.requirements_manual == 0 + + @patch("tasks.jobs.scan.ComplianceOverviewSummary.objects.bulk_create") + @patch("tasks.jobs.scan.rls_transaction") + def test_create_compliance_summaries_all_fail( + self, mock_rls_transaction, mock_bulk_create + ): + """Test creating summaries when all requirements fail.""" + tenant_id = str(uuid.uuid4()) + scan_id = str(uuid.uuid4()) + + requirement_statuses = { + ("comp1", "req1"): {"fail_count": 3, "pass_count": 7, "total_count": 10}, + ("comp1", "req2"): {"fail_count": 1, "pass_count": 4, "total_count": 5}, + } + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + + _create_compliance_summaries(tenant_id, scan_id, requirement_statuses) + + args, kwargs = mock_bulk_create.call_args + objects = args[0] + assert len(objects) == 1 + + obj = objects[0] + assert obj.compliance_id == "comp1" + assert obj.total_requirements == 2 + assert obj.requirements_passed == 0 + assert obj.requirements_failed == 2 + assert obj.requirements_manual == 0 + + @patch("tasks.jobs.scan.ComplianceOverviewSummary.objects.bulk_create") + @patch("tasks.jobs.scan.rls_transaction") + def test_create_compliance_summaries_correct_aggregation( + self, mock_rls_transaction, mock_bulk_create + ): + """Test that requirements are correctly aggregated to compliance level.""" + tenant_id = str(uuid.uuid4()) + scan_id = str(uuid.uuid4()) + + requirement_statuses = { + ("compliance_a", "req1"): { + "fail_count": 0, + "pass_count": 10, + "total_count": 10, + }, + ("compliance_a", "req2"): { + "fail_count": 1, + "pass_count": 9, + "total_count": 10, + }, + ("compliance_a", "req3"): { + "fail_count": 0, + "pass_count": 5, + "total_count": 10, + }, + ("compliance_b", "req1"): { + "fail_count": 0, + "pass_count": 8, + "total_count": 8, + }, + } + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + + _create_compliance_summaries(tenant_id, scan_id, requirement_statuses) + + args, kwargs = mock_bulk_create.call_args + objects = args[0] + assert len(objects) == 2 + + comp_a = next(obj for obj in objects if obj.compliance_id == "compliance_a") + comp_b = next(obj for obj in objects if obj.compliance_id == "compliance_b") + + # compliance_a: req1=PASS, req2=FAIL, req3=MANUAL + assert comp_a.total_requirements == 3 + assert comp_a.requirements_passed == 1 + assert comp_a.requirements_failed == 1 + assert comp_a.requirements_manual == 1 + + # compliance_b: req1=PASS + assert comp_b.total_requirements == 1 + assert comp_b.requirements_passed == 1 + assert comp_b.requirements_failed == 0 + assert comp_b.requirements_manual == 0 + + +@pytest.mark.django_db +class TestNormalizedComplianceKey: + """Test _normalized_compliance_key function.""" + + def test_normalized_compliance_key_normal_strings(self): + """Test normalization with normal framework and version strings.""" + result = _normalized_compliance_key("AWS-Foundational-Security", "2.0") + assert result == "awsfoundationalsecurity20" + + def test_normalized_compliance_key_with_underscores(self): + """Test normalization removes underscores.""" + result = _normalized_compliance_key("CIS_AWS_Foundations", "1_5_0") + assert result == "cisawsfoundations150" + + def test_normalized_compliance_key_none_framework(self): + """Test normalization with None framework.""" + result = _normalized_compliance_key(None, "1.0") + assert result == "10" + + def test_normalized_compliance_key_none_version(self): + """Test normalization with None version.""" + result = _normalized_compliance_key("AWS-Security", None) + assert result == "awssecurity" + + def test_normalized_compliance_key_both_none(self): + """Test normalization with both framework and version as None.""" + result = _normalized_compliance_key(None, None) + assert result == "" + + def test_normalized_compliance_key_empty_strings(self): + """Test normalization with empty strings.""" + result = _normalized_compliance_key("", "") + assert result == "" + + def test_normalized_compliance_key_mixed_case(self): + """Test normalization lowercases strings.""" + result = _normalized_compliance_key("AWS-FOUNDATIONAL", "V2.0") + assert result == "awsfoundationalv20" + + def test_normalized_compliance_key_complex_pattern(self): + """Test normalization with complex patterns.""" + result = _normalized_compliance_key("PCI-DSS_v3-2-1", "2023-Update") + assert result == "pcidssv3212023update" + + +@pytest.mark.django_db +class TestAggregateFindings: + """Test aggregate_findings function.""" + + @patch("tasks.jobs.scan.ScanSummary.objects.bulk_create") + @patch("tasks.jobs.scan.rls_transaction") + def test_aggregate_findings_creates_scan_summaries( + self, + mock_rls_transaction, + mock_bulk_create, + tenants_fixture, + scans_fixture, + findings_fixture, + ): + """Test that aggregate_findings creates ScanSummary records.""" + tenant = tenants_fixture[0] + scan = scans_fixture[0] + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + + aggregate_findings(str(tenant.id), str(scan.id)) + + mock_rls_transaction.assert_called() + mock_bulk_create.assert_called_once() + + args, kwargs = mock_bulk_create.call_args + objects = args[0] + assert kwargs["batch_size"] == 3000 + # Should have created at least one summary + assert len(objects) > 0 + + @patch("tasks.jobs.scan.Finding.objects.filter") + @patch("tasks.jobs.scan.ScanSummary.objects.bulk_create") + @patch("tasks.jobs.scan.rls_transaction") + def test_aggregate_findings_excludes_muted_from_counts( + self, mock_rls_transaction, mock_bulk_create, mock_findings_filter + ): + """Test that muted findings are excluded from fail/pass counts but counted separately.""" + tenant_id = str(uuid.uuid4()) + scan_id = str(uuid.uuid4()) + + # Mock findings queryset + mock_queryset = MagicMock() + mock_queryset.values.return_value = mock_queryset + mock_queryset.annotate.return_value = [ + { + "check_id": "check1", + "resources__service": "s3", + "severity": "high", + "resources__region": "us-east-1", + "fail": 5, + "_pass": 10, + "muted_count": 3, + "total": 18, + "new": 2, + "changed": 1, + "unchanged": 12, + "fail_new": 1, + "fail_changed": 0, + "pass_new": 1, + "pass_changed": 0, + "muted_new": 0, + "muted_changed": 1, + } + ] + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + mock_findings_filter.return_value = mock_queryset + + aggregate_findings(tenant_id, scan_id) + + mock_bulk_create.assert_called_once() + args, kwargs = mock_bulk_create.call_args + objects = args[0] + + summary = list(objects)[0] + assert summary.fail == 5 + assert summary._pass == 10 + assert summary.muted == 3 + assert summary.total == 18 + + @patch("tasks.jobs.scan.Finding.objects.filter") + @patch("tasks.jobs.scan.ScanSummary.objects.bulk_create") + @patch("tasks.jobs.scan.rls_transaction") + def test_aggregate_findings_computes_deltas_correctly( + self, mock_rls_transaction, mock_bulk_create, mock_findings_filter + ): + """Test that delta counts (new, changed, unchanged) are computed correctly.""" + tenant_id = str(uuid.uuid4()) + scan_id = str(uuid.uuid4()) + + mock_queryset = MagicMock() + mock_queryset.values.return_value = mock_queryset + mock_queryset.annotate.return_value = [ + { + "check_id": "check1", + "resources__service": "ec2", + "severity": "critical", + "resources__region": "us-west-2", + "fail": 8, + "_pass": 12, + "muted_count": 2, + "total": 22, + "new": 5, + "changed": 3, + "unchanged": 12, + "fail_new": 3, + "fail_changed": 2, + "pass_new": 2, + "pass_changed": 1, + "muted_new": 1, + "muted_changed": 0, + } + ] + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + mock_findings_filter.return_value = mock_queryset + + aggregate_findings(tenant_id, scan_id) + + args, kwargs = mock_bulk_create.call_args + objects = args[0] + + summary = list(objects)[0] + assert summary.new == 5 + assert summary.changed == 3 + assert summary.unchanged == 12 + assert summary.fail_new == 3 + assert summary.fail_changed == 2 + assert summary.pass_new == 2 + assert summary.pass_changed == 1 + assert summary.muted_new == 1 + assert summary.muted_changed == 0 + + @patch("tasks.jobs.scan.Finding.objects.filter") + @patch("tasks.jobs.scan.ScanSummary.objects.bulk_create") + @patch("tasks.jobs.scan.rls_transaction") + def test_aggregate_findings_groups_by_dimensions( + self, mock_rls_transaction, mock_bulk_create, mock_findings_filter + ): + """Test that findings are grouped by check_id, service, severity, and region.""" + tenant_id = str(uuid.uuid4()) + scan_id = str(uuid.uuid4()) + + mock_queryset = MagicMock() + mock_queryset.values.return_value = mock_queryset + mock_queryset.annotate.return_value = [ + { + "check_id": "check1", + "resources__service": "s3", + "severity": "high", + "resources__region": "us-east-1", + "fail": 5, + "_pass": 10, + "muted_count": 0, + "total": 15, + "new": 2, + "changed": 1, + "unchanged": 12, + "fail_new": 1, + "fail_changed": 0, + "pass_new": 1, + "pass_changed": 1, + "muted_new": 0, + "muted_changed": 0, + }, + { + "check_id": "check1", + "resources__service": "s3", + "severity": "high", + "resources__region": "us-west-2", + "fail": 3, + "_pass": 7, + "muted_count": 1, + "total": 11, + "new": 1, + "changed": 0, + "unchanged": 9, + "fail_new": 1, + "fail_changed": 0, + "pass_new": 0, + "pass_changed": 0, + "muted_new": 0, + "muted_changed": 1, + }, + ] + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + mock_findings_filter.return_value = mock_queryset + + aggregate_findings(tenant_id, scan_id) + + args, kwargs = mock_bulk_create.call_args + objects = args[0] + + # Should create 2 summaries (different regions) + assert len(list(objects)) == 2 + + summaries = list(objects) + assert all(s.check_id == "check1" for s in summaries) + assert all(s.service == "s3" for s in summaries) + assert all(s.severity == "high" for s in summaries) + + regions = {s.region for s in summaries} + assert regions == {"us-east-1", "us-west-2"} + + +@pytest.mark.django_db +class TestAggregateFindingsByRegion: + """Test _aggregate_findings_by_region function.""" + + @patch("tasks.jobs.scan.Finding.all_objects.filter") + @patch("tasks.jobs.scan.rls_transaction") + def test_aggregate_findings_by_region_returns_correct_structure( + self, mock_rls_transaction, mock_findings_filter + ): + """Test function returns correct data structure.""" + tenant_id = str(uuid.uuid4()) + scan_id = str(uuid.uuid4()) + modeled_threatscore_compliance_id = "ProwlerThreatScore-1.0" + + # Mock findings with resources + mock_finding1 = MagicMock() + mock_finding1.check_id = "check1" + mock_finding1.status = "FAIL" + mock_finding1.compliance = {modeled_threatscore_compliance_id: ["req1", "req2"]} + + mock_resource1 = MagicMock() + mock_resource1.region = "us-east-1" + mock_finding1.small_resources = [mock_resource1] + + mock_queryset = MagicMock() + mock_queryset.only.return_value = mock_queryset + mock_queryset.prefetch_related.return_value = [mock_finding1] + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + mock_findings_filter.return_value = mock_queryset + + check_status_by_region, findings_count_by_compliance = ( + _aggregate_findings_by_region( + tenant_id, scan_id, modeled_threatscore_compliance_id + ) + ) + + # Verify structure of check_status_by_region + assert isinstance(check_status_by_region, dict) + assert "us-east-1" in check_status_by_region + assert "check1" in check_status_by_region["us-east-1"] + assert check_status_by_region["us-east-1"]["check1"] == "FAIL" + + # Verify structure of findings_count_by_compliance + assert isinstance(findings_count_by_compliance, dict) + + @patch("tasks.jobs.scan.Finding.all_objects.filter") + @patch("tasks.jobs.scan.rls_transaction") + def test_aggregate_findings_by_region_fail_status_priority( + self, mock_rls_transaction, mock_findings_filter + ): + """Test that FAIL status takes priority over other statuses.""" + tenant_id = str(uuid.uuid4()) + scan_id = str(uuid.uuid4()) + modeled_threatscore_compliance_id = "ProwlerThreatScore-1.0" + + # First finding with PASS status + mock_finding1 = MagicMock() + mock_finding1.check_id = "check1" + mock_finding1.status = "PASS" + mock_finding1.compliance = {} + mock_resource1 = MagicMock() + mock_resource1.region = "us-east-1" + mock_finding1.small_resources = [mock_resource1] + + # Second finding with FAIL status for same check/region + mock_finding2 = MagicMock() + mock_finding2.check_id = "check1" + mock_finding2.status = "FAIL" + mock_finding2.compliance = {} + mock_resource2 = MagicMock() + mock_resource2.region = "us-east-1" + mock_finding2.small_resources = [mock_resource2] + + mock_queryset = MagicMock() + mock_queryset.only.return_value = mock_queryset + mock_queryset.prefetch_related.return_value = [mock_finding1, mock_finding2] + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + mock_findings_filter.return_value = mock_queryset + + check_status_by_region, _ = _aggregate_findings_by_region( + tenant_id, scan_id, modeled_threatscore_compliance_id + ) + + # FAIL should override PASS + assert check_status_by_region["us-east-1"]["check1"] == "FAIL" + + @patch("tasks.jobs.scan.Finding.all_objects.filter") + @patch("tasks.jobs.scan.rls_transaction") + def test_aggregate_findings_by_region_filters_muted( + self, mock_rls_transaction, mock_findings_filter + ): + """Test that muted findings are filtered out (muted=False in query).""" + tenant_id = str(uuid.uuid4()) + scan_id = str(uuid.uuid4()) + modeled_threatscore_compliance_id = "ProwlerThreatScore-1.0" + + mock_queryset = MagicMock() + mock_queryset.only.return_value = mock_queryset + mock_queryset.prefetch_related.return_value = [] + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + mock_findings_filter.return_value = mock_queryset + + _aggregate_findings_by_region( + tenant_id, scan_id, modeled_threatscore_compliance_id + ) + + # Verify filter was called with muted=False + mock_findings_filter.assert_called_once_with( + tenant_id=tenant_id, scan_id=scan_id, muted=False + ) + + @patch("tasks.jobs.scan.Finding.all_objects.filter") + @patch("tasks.jobs.scan.rls_transaction") + def test_aggregate_findings_by_region_processes_compliance_counts( + self, mock_rls_transaction, mock_findings_filter + ): + """Test that ThreatScore compliance counts are processed correctly.""" + tenant_id = str(uuid.uuid4()) + scan_id = str(uuid.uuid4()) + modeled_threatscore_compliance_id = "ProwlerThreatScore-1.0" + + # Finding with PASS status + mock_finding1 = MagicMock() + mock_finding1.check_id = "check1" + mock_finding1.status = "PASS" + mock_finding1.compliance = {modeled_threatscore_compliance_id: ["req1"]} + mock_resource1 = MagicMock() + mock_resource1.region = "us-east-1" + mock_finding1.small_resources = [mock_resource1] + + # Finding with FAIL status + mock_finding2 = MagicMock() + mock_finding2.check_id = "check2" + mock_finding2.status = "FAIL" + mock_finding2.compliance = {modeled_threatscore_compliance_id: ["req1"]} + mock_resource2 = MagicMock() + mock_resource2.region = "us-east-1" + mock_finding2.small_resources = [mock_resource2] + + mock_queryset = MagicMock() + mock_queryset.only.return_value = mock_queryset + mock_queryset.prefetch_related.return_value = [mock_finding1, mock_finding2] + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + mock_findings_filter.return_value = mock_queryset + + _, findings_count_by_compliance = _aggregate_findings_by_region( + tenant_id, scan_id, modeled_threatscore_compliance_id + ) + + # Verify compliance counts + normalized_id = re.sub( + r"[^a-z0-9]", "", modeled_threatscore_compliance_id.lower() + ) + assert "us-east-1" in findings_count_by_compliance + assert normalized_id in findings_count_by_compliance["us-east-1"] + assert "req1" in findings_count_by_compliance["us-east-1"][normalized_id] + + req_stats = findings_count_by_compliance["us-east-1"][normalized_id]["req1"] + assert req_stats["total"] == 2 + assert req_stats["pass"] == 1 + + @patch("tasks.jobs.scan.Finding.all_objects.filter") + @patch("tasks.jobs.scan.rls_transaction") + def test_aggregate_findings_by_region_multiple_regions( + self, mock_rls_transaction, mock_findings_filter + ): + """Test aggregation across multiple regions.""" + tenant_id = str(uuid.uuid4()) + scan_id = str(uuid.uuid4()) + modeled_threatscore_compliance_id = "ProwlerThreatScore-1.0" + + # Finding in us-east-1 + mock_finding1 = MagicMock() + mock_finding1.check_id = "check1" + mock_finding1.status = "FAIL" + mock_finding1.compliance = {} + mock_resource1 = MagicMock() + mock_resource1.region = "us-east-1" + mock_finding1.small_resources = [mock_resource1] + + # Finding in us-west-2 + mock_finding2 = MagicMock() + mock_finding2.check_id = "check1" + mock_finding2.status = "PASS" + mock_finding2.compliance = {} + mock_resource2 = MagicMock() + mock_resource2.region = "us-west-2" + mock_finding2.small_resources = [mock_resource2] + + mock_queryset = MagicMock() + mock_queryset.only.return_value = mock_queryset + mock_queryset.prefetch_related.return_value = [mock_finding1, mock_finding2] + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + mock_findings_filter.return_value = mock_queryset + + check_status_by_region, _ = _aggregate_findings_by_region( + tenant_id, scan_id, modeled_threatscore_compliance_id + ) + + # Verify both regions are present with correct statuses + assert "us-east-1" in check_status_by_region + assert "us-west-2" in check_status_by_region + assert check_status_by_region["us-east-1"]["check1"] == "FAIL" + assert check_status_by_region["us-west-2"]["check1"] == "PASS" + + @patch("tasks.jobs.scan.Finding.all_objects.filter") + @patch("tasks.jobs.scan.rls_transaction") + def test_aggregate_findings_by_region_empty_findings( + self, mock_rls_transaction, mock_findings_filter + ): + """Test with no findings - should return empty dicts.""" + tenant_id = str(uuid.uuid4()) + scan_id = str(uuid.uuid4()) + modeled_threatscore_compliance_id = "ProwlerThreatScore-1.0" + + mock_queryset = MagicMock() + mock_queryset.only.return_value = mock_queryset + mock_queryset.prefetch_related.return_value = [] + + ctx = MagicMock() + ctx.__enter__.return_value = None + ctx.__exit__.return_value = False + mock_rls_transaction.return_value = ctx + mock_findings_filter.return_value = mock_queryset + + check_status_by_region, findings_count_by_compliance = ( + _aggregate_findings_by_region( + tenant_id, scan_id, modeled_threatscore_compliance_id + ) + ) + + assert check_status_by_region == {} + assert findings_count_by_compliance == {} diff --git a/api/src/backend/tasks/tests/test_tasks.py b/api/src/backend/tasks/tests/test_tasks.py index b4262027f6..b2d8b7bc2b 100644 --- a/api/src/backend/tasks/tests/test_tasks.py +++ b/api/src/backend/tasks/tests/test_tasks.py @@ -1,16 +1,24 @@ import uuid from unittest.mock import MagicMock, patch +import openai import pytest +from botocore.exceptions import ClientError from tasks.tasks import ( _perform_scan_complete_tasks, check_integrations_task, + check_lighthouse_provider_connection_task, generate_outputs_task, + refresh_lighthouse_provider_models_task, s3_integration_task, security_hub_integration_task, ) -from api.models import Integration +from api.models import ( + Integration, + LighthouseProviderConfiguration, + LighthouseProviderModels, +) # TODO Move this to outputs/reports jobs @@ -98,7 +106,11 @@ class TestGenerateOutputs: ), patch( "tasks.tasks._generate_output_directory", - return_value=("out-dir", "comp-dir"), + return_value=( + "/tmp/test/out-dir", + "/tmp/test/comp-dir", + "/tmp/test/threat-dir", + ), ), patch("tasks.tasks.Scan.all_objects.filter") as mock_scan_update, patch("tasks.tasks.rmtree"), @@ -126,7 +138,8 @@ class TestGenerateOutputs: patch("tasks.tasks.get_compliance_frameworks"), patch("tasks.tasks.Finding.all_objects.filter") as mock_findings, patch( - "tasks.tasks._generate_output_directory", return_value=("out", "comp") + "tasks.tasks._generate_output_directory", + return_value=("/tmp/test/out", "/tmp/test/comp", "/tmp/test/threat"), ), patch("tasks.tasks.FindingOutput._transform_findings_stats"), patch("tasks.tasks.FindingOutput.transform_api_finding"), @@ -168,15 +181,35 @@ class TestGenerateOutputs: mock_finding_output = MagicMock() mock_finding_output.compliance = {"cis": ["requirement-1", "requirement-2"]} + html_writer_mock = MagicMock() + html_writer_mock._data = [] + html_writer_mock.close_file = False + html_writer_mock.transform = MagicMock() + html_writer_mock.batch_write_data_to_file = MagicMock() + + compliance_writer_mock = MagicMock() + compliance_writer_mock._data = [] + compliance_writer_mock.close_file = False + compliance_writer_mock.transform = MagicMock() + compliance_writer_mock.batch_write_data_to_file = MagicMock() + + # Create a mock class that returns our mock instance when called + mock_compliance_class = MagicMock(return_value=compliance_writer_mock) + + mock_provider = MagicMock() + mock_provider.provider = "aws" + mock_provider.uid = "test-provider-uid" + with ( patch("tasks.tasks.ScanSummary.objects.filter") as mock_filter, - patch("tasks.tasks.Provider.objects.get"), + patch("tasks.tasks.Provider.objects.get", return_value=mock_provider), patch("tasks.tasks.initialize_prowler_provider"), patch("tasks.tasks.Compliance.get_bulk", return_value={"cis": MagicMock()}), patch("tasks.tasks.get_compliance_frameworks", return_value=["cis"]), patch("tasks.tasks.Finding.all_objects.filter") as mock_findings, patch( - "tasks.tasks._generate_output_directory", return_value=("out", "comp") + "tasks.tasks._generate_output_directory", + return_value=("/tmp/test/out", "/tmp/test/comp", "/tmp/test/threat"), ), patch( "tasks.tasks.FindingOutput._transform_findings_stats", @@ -190,6 +223,20 @@ class TestGenerateOutputs: patch("tasks.tasks._upload_to_s3", return_value="s3://bucket/f.zip"), patch("tasks.tasks.Scan.all_objects.filter"), patch("tasks.tasks.rmtree"), + patch( + "tasks.tasks.OUTPUT_FORMATS_MAPPING", + { + "html": { + "class": lambda *args, **kwargs: html_writer_mock, + "suffix": ".html", + "kwargs": {}, + } + }, + ), + patch( + "tasks.tasks.COMPLIANCE_CLASS_MAP", + {"aws": [(lambda x: True, mock_compliance_class)]}, + ), ): mock_filter.return_value.exists.return_value = True mock_findings.return_value.order_by.return_value.iterator.return_value = [ @@ -197,29 +244,12 @@ class TestGenerateOutputs: True, ] - html_writer_mock = MagicMock() - with ( - patch( - "tasks.tasks.OUTPUT_FORMATS_MAPPING", - { - "html": { - "class": lambda *args, **kwargs: html_writer_mock, - "suffix": ".html", - "kwargs": {}, - } - }, - ), - patch( - "tasks.tasks.COMPLIANCE_CLASS_MAP", - {"aws": [(lambda x: True, MagicMock())]}, - ), - ): - generate_outputs_task( - scan_id=self.scan_id, - provider_id=self.provider_id, - tenant_id=self.tenant_id, - ) - html_writer_mock.batch_write_data_to_file.assert_called_once() + generate_outputs_task( + scan_id=self.scan_id, + provider_id=self.provider_id, + tenant_id=self.tenant_id, + ) + html_writer_mock.batch_write_data_to_file.assert_called_once() def test_transform_called_only_on_second_batch(self): raw1 = MagicMock() @@ -256,7 +286,11 @@ class TestGenerateOutputs: ), patch( "tasks.tasks._generate_output_directory", - return_value=("outdir", "compdir"), + return_value=( + "/tmp/test/outdir", + "/tmp/test/compdir", + "/tmp/test/threatdir", + ), ), patch("tasks.tasks._compress_output_files", return_value="outdir.zip"), patch("tasks.tasks._upload_to_s3", return_value="s3://bucket/outdir.zip"), @@ -303,12 +337,14 @@ class TestGenerateOutputs: def __init__(self, *args, **kwargs): self.transform_calls = [] self._data = [] + self.close_file = False writer_instances.append(self) def transform(self, fos, comp_obj, name): self.transform_calls.append((fos, comp_obj, name)) def batch_write_data_to_file(self): + # Mock implementation - do nothing pass two_batches = [ @@ -329,7 +365,11 @@ class TestGenerateOutputs: patch("tasks.tasks.get_compliance_frameworks", return_value=["cis"]), patch( "tasks.tasks._generate_output_directory", - return_value=("outdir", "compdir"), + return_value=( + "/tmp/test/outdir", + "/tmp/test/compdir", + "/tmp/test/threatdir", + ), ), patch("tasks.tasks.FindingOutput._transform_findings_stats"), patch( @@ -368,15 +408,35 @@ class TestGenerateOutputs: mock_finding_output = MagicMock() mock_finding_output.compliance = {"cis": ["requirement-1", "requirement-2"]} + json_writer_mock = MagicMock() + json_writer_mock._data = [] + json_writer_mock.close_file = False + json_writer_mock.transform = MagicMock() + json_writer_mock.batch_write_data_to_file = MagicMock() + + compliance_writer_mock = MagicMock() + compliance_writer_mock._data = [] + compliance_writer_mock.close_file = False + compliance_writer_mock.transform = MagicMock() + compliance_writer_mock.batch_write_data_to_file = MagicMock() + + # Create a mock class that returns our mock instance when called + mock_compliance_class = MagicMock(return_value=compliance_writer_mock) + + mock_provider = MagicMock() + mock_provider.provider = "aws" + mock_provider.uid = "test-provider-uid" + with ( patch("tasks.tasks.ScanSummary.objects.filter") as mock_filter, - patch("tasks.tasks.Provider.objects.get"), + patch("tasks.tasks.Provider.objects.get", return_value=mock_provider), patch("tasks.tasks.initialize_prowler_provider"), patch("tasks.tasks.Compliance.get_bulk", return_value={"cis": MagicMock()}), patch("tasks.tasks.get_compliance_frameworks", return_value=["cis"]), patch("tasks.tasks.Finding.all_objects.filter") as mock_findings, patch( - "tasks.tasks._generate_output_directory", return_value=("out", "comp") + "tasks.tasks._generate_output_directory", + return_value=("/tmp/test/out", "/tmp/test/comp", "/tmp/test/threat"), ), patch( "tasks.tasks.FindingOutput._transform_findings_stats", @@ -390,6 +450,20 @@ class TestGenerateOutputs: patch("tasks.tasks._upload_to_s3", return_value="s3://bucket/file.zip"), patch("tasks.tasks.Scan.all_objects.filter"), patch("tasks.tasks.rmtree", side_effect=Exception("Test deletion error")), + patch( + "tasks.tasks.OUTPUT_FORMATS_MAPPING", + { + "json": { + "class": lambda *args, **kwargs: json_writer_mock, + "suffix": ".json", + "kwargs": {}, + } + }, + ), + patch( + "tasks.tasks.COMPLIANCE_CLASS_MAP", + {"aws": [(lambda x: True, mock_compliance_class)]}, + ), ): mock_filter.return_value.exists.return_value = True mock_findings.return_value.order_by.return_value.iterator.return_value = [ @@ -397,29 +471,13 @@ class TestGenerateOutputs: True, ] - with ( - patch( - "tasks.tasks.OUTPUT_FORMATS_MAPPING", - { - "json": { - "class": lambda *args, **kwargs: MagicMock(), - "suffix": ".json", - "kwargs": {}, - } - }, - ), - patch( - "tasks.tasks.COMPLIANCE_CLASS_MAP", - {"aws": [(lambda x: True, MagicMock())]}, - ), - ): - with caplog.at_level("ERROR"): - generate_outputs_task( - scan_id=self.scan_id, - provider_id=self.provider_id, - tenant_id=self.tenant_id, - ) - assert "Error deleting output files" in caplog.text + with caplog.at_level("ERROR"): + generate_outputs_task( + scan_id=self.scan_id, + provider_id=self.provider_id, + tenant_id=self.tenant_id, + ) + assert "Error deleting output files" in caplog.text @patch("tasks.tasks.rls_transaction") @patch("tasks.tasks.Integration.objects.filter") @@ -435,7 +493,8 @@ class TestGenerateOutputs: patch("tasks.tasks.get_compliance_frameworks", return_value=[]), patch("tasks.tasks.Finding.all_objects.filter") as mock_findings, patch( - "tasks.tasks._generate_output_directory", return_value=("out", "comp") + "tasks.tasks._generate_output_directory", + return_value=("/tmp/test/out", "/tmp/test/comp", "/tmp/test/threat"), ), patch("tasks.tasks.FindingOutput._transform_findings_stats"), patch("tasks.tasks.FindingOutput.transform_api_finding"), @@ -476,8 +535,15 @@ class TestScanCompleteTasks: @patch("tasks.tasks.create_compliance_requirements_task.apply_async") @patch("tasks.tasks.perform_scan_summary_task.si") @patch("tasks.tasks.generate_outputs_task.si") + @patch("tasks.tasks.generate_threatscore_report_task.si") + @patch("tasks.tasks.check_integrations_task.si") def test_scan_complete_tasks( - self, mock_outputs_task, mock_scan_summary_task, mock_compliance_tasks + self, + mock_check_integrations_task, + mock_threatscore_task, + mock_outputs_task, + mock_scan_summary_task, + mock_compliance_tasks, ): _perform_scan_complete_tasks("tenant-id", "scan-id", "provider-id") mock_compliance_tasks.assert_called_once_with( @@ -492,6 +558,16 @@ class TestScanCompleteTasks: provider_id="provider-id", tenant_id="tenant-id", ) + mock_threatscore_task.assert_called_once_with( + tenant_id="tenant-id", + scan_id="scan-id", + provider_id="provider-id", + ) + mock_check_integrations_task.assert_called_once_with( + tenant_id="tenant-id", + provider_id="provider-id", + scan_id="scan-id", + ) @pytest.mark.django_db @@ -662,7 +738,7 @@ class TestCheckIntegrationsTask: mock_initialize_provider.return_value = MagicMock() mock_compliance_bulk.return_value = {} mock_get_frameworks.return_value = [] - mock_generate_dir.return_value = ("out-dir", "comp-dir") + mock_generate_dir.return_value = ("out-dir", "comp-dir", "threat-dir") mock_transform_stats.return_value = {"stats": "data"} # Mock findings @@ -787,7 +863,7 @@ class TestCheckIntegrationsTask: mock_initialize_provider.return_value = MagicMock() mock_compliance_bulk.return_value = {} mock_get_frameworks.return_value = [] - mock_generate_dir.return_value = ("out-dir", "comp-dir") + mock_generate_dir.return_value = ("out-dir", "comp-dir", "threat-dir") mock_transform_stats.return_value = {"stats": "data"} # Mock findings @@ -903,7 +979,7 @@ class TestCheckIntegrationsTask: mock_initialize_provider.return_value = MagicMock() mock_compliance_bulk.return_value = {} mock_get_frameworks.return_value = [] - mock_generate_dir.return_value = ("out-dir", "comp-dir") + mock_generate_dir.return_value = ("out-dir", "comp-dir", "threat-dir") mock_transform_stats.return_value = {"stats": "data"} # Mock findings @@ -1029,3 +1105,363 @@ class TestCheckIntegrationsTask: assert result is False mock_upload.assert_called_once_with(self.tenant_id, self.provider_id, scan_id) + + +@pytest.mark.django_db +class TestCheckLighthouseProviderConnectionTask: + def setup_method(self): + self.tenant_id = str(uuid.uuid4()) + + @pytest.mark.parametrize( + "provider_type,credentials,base_url,expected_result", + [ + ( + LighthouseProviderConfiguration.LLMProviderChoices.OPENAI, + {"api_key": "sk-test123"}, + None, + {"connected": True, "error": None}, + ), + ( + LighthouseProviderConfiguration.LLMProviderChoices.OPENAI_COMPATIBLE, + {"api_key": "sk-test123"}, + "https://openrouter.ai/api/v1", + {"connected": True, "error": None}, + ), + ( + LighthouseProviderConfiguration.LLMProviderChoices.BEDROCK, + { + "access_key_id": "AKIA123", + "secret_access_key": "secret", + "region": "us-east-1", + }, + None, + {"connected": True, "error": None}, + ), + ], + ) + def test_check_connection_success_all_providers( + self, tenants_fixture, provider_type, credentials, base_url, expected_result + ): + """Test successful connection check for all provider types.""" + # Create provider configuration + provider_cfg = LighthouseProviderConfiguration( + tenant_id=tenants_fixture[0].id, + provider_type=provider_type, + base_url=base_url, + is_active=False, + ) + provider_cfg.credentials_decoded = credentials + provider_cfg.save() + + # Mock the appropriate API calls + with ( + patch("tasks.jobs.lighthouse_providers.openai.OpenAI") as mock_openai, + patch("tasks.jobs.lighthouse_providers.boto3.client") as mock_boto3, + ): + mock_client = MagicMock() + mock_client.models.list.return_value = MagicMock() + mock_client.list_foundation_models.return_value = {} + mock_openai.return_value = mock_client + mock_boto3.return_value = mock_client + + # Execute + result = check_lighthouse_provider_connection_task( + provider_config_id=str(provider_cfg.id), + tenant_id=str(tenants_fixture[0].id), + ) + + # Assert + assert result == expected_result + provider_cfg.refresh_from_db() + assert provider_cfg.is_active is True + + @pytest.mark.parametrize( + "provider_type,credentials,base_url,exception_to_raise", + [ + ( + LighthouseProviderConfiguration.LLMProviderChoices.OPENAI, + {"api_key": "sk-invalid"}, + None, + openai.AuthenticationError( + "Invalid API key", response=MagicMock(), body=None + ), + ), + ( + LighthouseProviderConfiguration.LLMProviderChoices.OPENAI_COMPATIBLE, + {"api_key": "sk-invalid"}, + "https://openrouter.ai/api/v1", + openai.APIConnectionError(request=MagicMock()), + ), + ( + LighthouseProviderConfiguration.LLMProviderChoices.BEDROCK, + { + "access_key_id": "AKIA123", + "secret_access_key": "secret", + "region": "us-east-1", + }, + None, + ClientError( + {"Error": {"Code": "AccessDenied", "Message": "Access Denied"}}, + "list_foundation_models", + ), + ), + ], + ) + def test_check_connection_api_failure( + self, + tenants_fixture, + provider_type, + credentials, + base_url, + exception_to_raise, + ): + """Test connection check when API calls fail.""" + # Create provider configuration + provider_cfg = LighthouseProviderConfiguration( + tenant_id=tenants_fixture[0].id, + provider_type=provider_type, + base_url=base_url, + is_active=True, + ) + provider_cfg.credentials_decoded = credentials + provider_cfg.save() + + # Mock the API to raise exception + with ( + patch("tasks.jobs.lighthouse_providers.openai.OpenAI") as mock_openai, + patch("tasks.jobs.lighthouse_providers.boto3.client") as mock_boto3, + ): + mock_client = MagicMock() + if ( + provider_type + == LighthouseProviderConfiguration.LLMProviderChoices.BEDROCK + ): + mock_client.list_foundation_models.side_effect = exception_to_raise + mock_boto3.return_value = mock_client + else: + mock_client.models.list.side_effect = exception_to_raise + mock_openai.return_value = mock_client + + # Execute + result = check_lighthouse_provider_connection_task( + provider_config_id=str(provider_cfg.id), + tenant_id=str(tenants_fixture[0].id), + ) + + # Assert + assert result["connected"] is False + assert result["error"] is not None + provider_cfg.refresh_from_db() + assert provider_cfg.is_active is False + + def test_check_connection_updates_active_status(self, tenants_fixture): + """Test that connection check toggles is_active from True to False on failure.""" + # Create provider with is_active=True + provider_cfg = LighthouseProviderConfiguration( + tenant_id=tenants_fixture[0].id, + provider_type=LighthouseProviderConfiguration.LLMProviderChoices.OPENAI, + base_url=None, + is_active=True, + ) + provider_cfg.credentials_decoded = {"api_key": "sk-test123"} + provider_cfg.save() + + # Mock API to fail + with patch("tasks.jobs.lighthouse_providers.openai.OpenAI") as mock_openai: + mock_client = MagicMock() + mock_client.models.list.side_effect = openai.AuthenticationError( + "Invalid", response=MagicMock(), body=None + ) + mock_openai.return_value = mock_client + + # Execute + result = check_lighthouse_provider_connection_task( + provider_config_id=str(provider_cfg.id), + tenant_id=str(tenants_fixture[0].id), + ) + + # Assert status changed + assert result["connected"] is False + provider_cfg.refresh_from_db() + assert provider_cfg.is_active is False + + def test_check_connection_provider_does_not_exist(self, tenants_fixture): + """Test that checking non-existent provider raises DoesNotExist.""" + non_existent_id = str(uuid.uuid4()) + + with pytest.raises(LighthouseProviderConfiguration.DoesNotExist): + check_lighthouse_provider_connection_task( + provider_config_id=non_existent_id, + tenant_id=str(tenants_fixture[0].id), + ) + + +@pytest.mark.django_db +class TestRefreshLighthouseProviderModelsTask: + def setup_method(self): + self.tenant_id = str(uuid.uuid4()) + + @pytest.mark.parametrize( + "provider_type,credentials,base_url,mock_models,expected_count", + [ + ( + LighthouseProviderConfiguration.LLMProviderChoices.OPENAI, + {"api_key": "sk-test123"}, + None, + {"gpt-5": "gpt-5", "gpt-4o": "gpt-4o"}, + 2, + ), + ( + LighthouseProviderConfiguration.LLMProviderChoices.OPENAI_COMPATIBLE, + {"api_key": "sk-test123"}, + "https://openrouter.ai/api/v1", + {"model-1": "Model One", "model-2": "Model Two"}, + 2, + ), + ( + LighthouseProviderConfiguration.LLMProviderChoices.BEDROCK, + { + "access_key_id": "AKIA123", + "secret_access_key": "secret", + "region": "us-east-1", + }, + None, + {"openai.gpt-oss-120b-1:0": "gpt-oss-120b"}, + 1, + ), + ], + ) + def test_refresh_models_create_new( + self, + tenants_fixture, + provider_type, + credentials, + base_url, + mock_models, + expected_count, + ): + """Test creating new models for all provider types.""" + # Create provider configuration + provider_cfg = LighthouseProviderConfiguration( + tenant_id=tenants_fixture[0].id, + provider_type=provider_type, + base_url=base_url, + is_active=True, + ) + provider_cfg.credentials_decoded = credentials + provider_cfg.save() + + # Mock the fetch functions + with ( + patch( + "tasks.jobs.lighthouse_providers._fetch_openai_models", + return_value=mock_models, + ), + patch( + "tasks.jobs.lighthouse_providers._fetch_openai_compatible_models", + return_value=mock_models, + ), + patch( + "tasks.jobs.lighthouse_providers._fetch_bedrock_models", + return_value=mock_models, + ), + ): + # Execute + result = refresh_lighthouse_provider_models_task( + provider_config_id=str(provider_cfg.id), + tenant_id=str(tenants_fixture[0].id), + ) + + # Assert + assert result["created"] == expected_count + assert result["updated"] == 0 + assert result["deleted"] == 0 + assert ( + LighthouseProviderModels.objects.filter( + provider_configuration=provider_cfg + ).count() + == expected_count + ) + + def test_refresh_models_mixed_operations(self, tenants_fixture): + """Test mixed create, update, and delete operations.""" + # Create provider configuration + provider_cfg = LighthouseProviderConfiguration( + tenant_id=tenants_fixture[0].id, + provider_type=LighthouseProviderConfiguration.LLMProviderChoices.OPENAI, + base_url=None, + is_active=True, + ) + provider_cfg.credentials_decoded = {"api_key": "sk-test123"} + provider_cfg.save() + + # Create 2 existing models (A, B) + LighthouseProviderModels.objects.create( + tenant_id=tenants_fixture[0].id, + provider_configuration=provider_cfg, + model_id="model-a", + model_name="Model A", + ) + LighthouseProviderModels.objects.create( + tenant_id=tenants_fixture[0].id, + provider_configuration=provider_cfg, + model_id="model-b", + model_name="Model B", + ) + + # Mock API to return models B (existing), C (new) - A will be deleted + mock_models = {"model-b": "Model B", "model-c": "Model C"} + with patch( + "tasks.jobs.lighthouse_providers._fetch_openai_models", + return_value=mock_models, + ): + # Execute + result = refresh_lighthouse_provider_models_task( + provider_config_id=str(provider_cfg.id), + tenant_id=str(tenants_fixture[0].id), + ) + + # Assert + assert result["created"] == 1 # model-c created + assert result["updated"] == 1 # model-b updated + assert result["deleted"] == 1 # model-a deleted + + # Verify only B and C exist + remaining_models = LighthouseProviderModels.objects.filter( + provider_configuration=provider_cfg + ) + assert remaining_models.count() == 2 + assert set(remaining_models.values_list("model_id", flat=True)) == { + "model-b", + "model-c", + } + + def test_refresh_models_api_exception(self, tenants_fixture): + """Test refresh when API raises an exception.""" + # Create provider configuration + provider_cfg = LighthouseProviderConfiguration( + tenant_id=tenants_fixture[0].id, + provider_type=LighthouseProviderConfiguration.LLMProviderChoices.OPENAI, + base_url=None, + is_active=True, + ) + provider_cfg.credentials_decoded = {"api_key": "sk-test123"} + provider_cfg.save() + + # Mock fetch to raise exception + with patch( + "tasks.jobs.lighthouse_providers._fetch_openai_models", + side_effect=openai.APIError("API Error", request=MagicMock(), body=None), + ): + # Execute + result = refresh_lighthouse_provider_models_task( + provider_config_id=str(provider_cfg.id), + tenant_id=str(tenants_fixture[0].id), + ) + + # Assert + assert result["created"] == 0 + assert result["updated"] == 0 + assert result["deleted"] == 0 + assert "error" in result + assert result["error"] is not None diff --git a/dashboard/__main__.py b/dashboard/__main__.py index dac536ccdf..304e4afdf2 100644 --- a/dashboard/__main__.py +++ b/dashboard/__main__.py @@ -35,7 +35,8 @@ dashboard = dash.Dash( # Logo prowler_logo = html.Img( - src="https://prowler.com/wp-content/uploads/logo-dashboard.png", alt="Prowler Logo" + src="https://cdn.prod.website-files.com/68c4ec3f9fb7b154fbcb6e36/68ffb46d40ed7faa37a592a5_prowler-logo.png", + alt="Prowler Logo", ) menu_icons = { diff --git a/dashboard/assets/markdown-styles.css b/dashboard/assets/markdown-styles.css new file mode 100644 index 0000000000..66eacfe597 --- /dev/null +++ b/dashboard/assets/markdown-styles.css @@ -0,0 +1,34 @@ +/* Override Tailwind CSS reset for markdown content */ +.markdown-content ul { + list-style: disc !important; + margin-left: 20px !important; + padding-left: 10px !important; + margin-bottom: 8px !important; +} + +.markdown-content ol { + list-style: decimal !important; + margin-left: 20px !important; + padding-left: 10px !important; + margin-bottom: 8px !important; +} + +.markdown-content li { + margin-bottom: 4px !important; + display: list-item !important; +} + +.markdown-content p { + margin-bottom: 8px !important; +} + +/* Ensure nested lists work properly */ +.markdown-content ul ul { + margin-top: 4px !important; + margin-bottom: 4px !important; +} + +.markdown-content ol ol { + margin-top: 4px !important; + margin-bottom: 4px !important; +} diff --git a/dashboard/compliance/c5_aws.py b/dashboard/compliance/c5_aws.py new file mode 100644 index 0000000000..8baac9a9a5 --- /dev/null +++ b/dashboard/compliance/c5_aws.py @@ -0,0 +1,43 @@ +import warnings + +from dashboard.common_methods import get_section_containers_3_levels + +warnings.filterwarnings("ignore") + + +def get_table(data): + data["REQUIREMENTS_DESCRIPTION"] = ( + data["REQUIREMENTS_ID"] + " - " + data["REQUIREMENTS_DESCRIPTION"] + ) + + data["REQUIREMENTS_DESCRIPTION"] = data["REQUIREMENTS_DESCRIPTION"].apply( + lambda x: x[:150] + "..." if len(str(x)) > 150 else x + ) + + data["REQUIREMENTS_ATTRIBUTES_SECTION"] = data[ + "REQUIREMENTS_ATTRIBUTES_SECTION" + ].apply(lambda x: x[:80] + "..." if len(str(x)) > 80 else x) + + data["REQUIREMENTS_ATTRIBUTES_SUBSECTION"] = data[ + "REQUIREMENTS_ATTRIBUTES_SUBSECTION" + ].apply(lambda x: x[:150] + "..." if len(str(x)) > 150 else x) + + aux = data[ + [ + "REQUIREMENTS_DESCRIPTION", + "REQUIREMENTS_ATTRIBUTES_SECTION", + "REQUIREMENTS_ATTRIBUTES_SUBSECTION", + "CHECKID", + "STATUS", + "REGION", + "ACCOUNTID", + "RESOURCEID", + ] + ] + + return get_section_containers_3_levels( + aux, + "REQUIREMENTS_ATTRIBUTES_SECTION", + "REQUIREMENTS_ATTRIBUTES_SUBSECTION", + "REQUIREMENTS_DESCRIPTION", + ) diff --git a/dashboard/compliance/c5_azure.py b/dashboard/compliance/c5_azure.py new file mode 100644 index 0000000000..8baac9a9a5 --- /dev/null +++ b/dashboard/compliance/c5_azure.py @@ -0,0 +1,43 @@ +import warnings + +from dashboard.common_methods import get_section_containers_3_levels + +warnings.filterwarnings("ignore") + + +def get_table(data): + data["REQUIREMENTS_DESCRIPTION"] = ( + data["REQUIREMENTS_ID"] + " - " + data["REQUIREMENTS_DESCRIPTION"] + ) + + data["REQUIREMENTS_DESCRIPTION"] = data["REQUIREMENTS_DESCRIPTION"].apply( + lambda x: x[:150] + "..." if len(str(x)) > 150 else x + ) + + data["REQUIREMENTS_ATTRIBUTES_SECTION"] = data[ + "REQUIREMENTS_ATTRIBUTES_SECTION" + ].apply(lambda x: x[:80] + "..." if len(str(x)) > 80 else x) + + data["REQUIREMENTS_ATTRIBUTES_SUBSECTION"] = data[ + "REQUIREMENTS_ATTRIBUTES_SUBSECTION" + ].apply(lambda x: x[:150] + "..." if len(str(x)) > 150 else x) + + aux = data[ + [ + "REQUIREMENTS_DESCRIPTION", + "REQUIREMENTS_ATTRIBUTES_SECTION", + "REQUIREMENTS_ATTRIBUTES_SUBSECTION", + "CHECKID", + "STATUS", + "REGION", + "ACCOUNTID", + "RESOURCEID", + ] + ] + + return get_section_containers_3_levels( + aux, + "REQUIREMENTS_ATTRIBUTES_SECTION", + "REQUIREMENTS_ATTRIBUTES_SUBSECTION", + "REQUIREMENTS_DESCRIPTION", + ) diff --git a/dashboard/compliance/ccc_aws.py b/dashboard/compliance/ccc_aws.py new file mode 100644 index 0000000000..5344dada84 --- /dev/null +++ b/dashboard/compliance/ccc_aws.py @@ -0,0 +1,36 @@ +import warnings + +from dashboard.common_methods import get_section_containers_3_levels + +warnings.filterwarnings("ignore") + + +def get_table(data): + + data["REQUIREMENTS_ID"] = ( + data["REQUIREMENTS_ID"] + " - " + data["REQUIREMENTS_DESCRIPTION"] + ) + + data["REQUIREMENTS_ID"] = data["REQUIREMENTS_ID"].apply( + lambda x: x[:150] + "..." if len(str(x)) > 150 else x + ) + + aux = data[ + [ + "REQUIREMENTS_ID", + "REQUIREMENTS_ATTRIBUTES_SECTION", + "REQUIREMENTS_ATTRIBUTES_SUBSECTION", + "CHECKID", + "STATUS", + "REGION", + "ACCOUNTID", + "RESOURCEID", + ] + ] + + return get_section_containers_3_levels( + aux, + "REQUIREMENTS_ATTRIBUTES_SECTION", + "REQUIREMENTS_ATTRIBUTES_SUBSECTION", + "REQUIREMENTS_ID", + ) diff --git a/dashboard/compliance/ccc_azure.py b/dashboard/compliance/ccc_azure.py new file mode 100644 index 0000000000..5344dada84 --- /dev/null +++ b/dashboard/compliance/ccc_azure.py @@ -0,0 +1,36 @@ +import warnings + +from dashboard.common_methods import get_section_containers_3_levels + +warnings.filterwarnings("ignore") + + +def get_table(data): + + data["REQUIREMENTS_ID"] = ( + data["REQUIREMENTS_ID"] + " - " + data["REQUIREMENTS_DESCRIPTION"] + ) + + data["REQUIREMENTS_ID"] = data["REQUIREMENTS_ID"].apply( + lambda x: x[:150] + "..." if len(str(x)) > 150 else x + ) + + aux = data[ + [ + "REQUIREMENTS_ID", + "REQUIREMENTS_ATTRIBUTES_SECTION", + "REQUIREMENTS_ATTRIBUTES_SUBSECTION", + "CHECKID", + "STATUS", + "REGION", + "ACCOUNTID", + "RESOURCEID", + ] + ] + + return get_section_containers_3_levels( + aux, + "REQUIREMENTS_ATTRIBUTES_SECTION", + "REQUIREMENTS_ATTRIBUTES_SUBSECTION", + "REQUIREMENTS_ID", + ) diff --git a/dashboard/compliance/ccc_gcp.py b/dashboard/compliance/ccc_gcp.py new file mode 100644 index 0000000000..5344dada84 --- /dev/null +++ b/dashboard/compliance/ccc_gcp.py @@ -0,0 +1,36 @@ +import warnings + +from dashboard.common_methods import get_section_containers_3_levels + +warnings.filterwarnings("ignore") + + +def get_table(data): + + data["REQUIREMENTS_ID"] = ( + data["REQUIREMENTS_ID"] + " - " + data["REQUIREMENTS_DESCRIPTION"] + ) + + data["REQUIREMENTS_ID"] = data["REQUIREMENTS_ID"].apply( + lambda x: x[:150] + "..." if len(str(x)) > 150 else x + ) + + aux = data[ + [ + "REQUIREMENTS_ID", + "REQUIREMENTS_ATTRIBUTES_SECTION", + "REQUIREMENTS_ATTRIBUTES_SUBSECTION", + "CHECKID", + "STATUS", + "REGION", + "ACCOUNTID", + "RESOURCEID", + ] + ] + + return get_section_containers_3_levels( + aux, + "REQUIREMENTS_ATTRIBUTES_SECTION", + "REQUIREMENTS_ATTRIBUTES_SUBSECTION", + "REQUIREMENTS_ID", + ) diff --git a/dashboard/compliance/cis_3_0_oci.py b/dashboard/compliance/cis_3_0_oci.py new file mode 100644 index 0000000000..286a6cd12f --- /dev/null +++ b/dashboard/compliance/cis_3_0_oci.py @@ -0,0 +1,41 @@ +import warnings + +from dashboard.common_methods import get_section_containers_cis + +warnings.filterwarnings("ignore") + + +def get_table(data): + """ + Generate CIS OCI Foundations Benchmark v3.0 compliance table. + + Args: + data: DataFrame containing compliance check results with columns: + - REQUIREMENTS_ID: CIS requirement ID (e.g., "1.1", "2.1") + - REQUIREMENTS_DESCRIPTION: Description of the requirement + - REQUIREMENTS_ATTRIBUTES_SECTION: CIS section name + - CHECKID: Prowler check identifier + - STATUS: Check status (PASS/FAIL) + - REGION: OCI region + - TENANCYID: OCI tenancy OCID + - RESOURCEID: Resource OCID or identifier + + Returns: + Section containers organized by CIS sections for dashboard display + """ + aux = data[ + [ + "REQUIREMENTS_ID", + "REQUIREMENTS_DESCRIPTION", + "REQUIREMENTS_ATTRIBUTES_SECTION", + "CHECKID", + "STATUS", + "REGION", + "TENANCYID", + "RESOURCEID", + ] + ].copy() + + return get_section_containers_cis( + aux, "REQUIREMENTS_ID", "REQUIREMENTS_ATTRIBUTES_SECTION" + ) diff --git a/dashboard/compliance/fedramp_20x_ksi_low_aws.py b/dashboard/compliance/fedramp_20x_ksi_low_aws.py new file mode 100644 index 0000000000..5ca220301f --- /dev/null +++ b/dashboard/compliance/fedramp_20x_ksi_low_aws.py @@ -0,0 +1,46 @@ +import warnings + +from dashboard.common_methods import get_section_containers_cis + +warnings.filterwarnings("ignore") + + +def get_table(data): + aux = data[ + [ + "REQUIREMENTS_ID", + "REQUIREMENTS_DESCRIPTION", + "REQUIREMENTS_ATTRIBUTES_SECTION", + "CHECKID", + "STATUS", + "REGION", + "ACCOUNTID", + "RESOURCEID", + ] + ].copy() + + # Shorten the long FedRAMP KSI descriptions for better display + ksi_short_names = { + "A secure cloud service offering will protect user data, control access, and apply zero trust principles": "Identity and Access Management", + "A secure cloud service offering will use cloud native architecture and design principles to enforce and enhance the Confidentiality, Integrity and Availability of the system": "Cloud Native Architecture", + "A secure cloud service provider will ensure that all system changes are properly documented and configuration baselines are updated accordingly": "Change Management", + "A secure cloud service provider will continuously educate their employees on cybersecurity measures, testing them regularly": "Cybersecurity Education", + "A secure cloud service offering will document, report, and analyze security incidents to ensure regulatory compliance and continuous security improvement": "Incident Reporting", + "A secure cloud service offering will monitor, log, and audit all important events, activity, and changes": "Monitoring, Logging, and Auditing", + "A secure cloud service offering will have intentional, organized, universal guidance for how every information resource, including personnel, is secured": "Policy and Inventory", + "A secure cloud service offering will define, maintain, and test incident response plan(s) and recovery capabilities to ensure minimal service disruption and data loss": "Recovery Planning", + "A secure cloud service offering will follow FedRAMP encryption policies, continuously verify information resource integrity, and restrict access to third-party information resources": "Service Configuration", + "A secure cloud service offering will understand, monitor, and manage supply chain risks from third-party information resources": "Third-Party Information Resources", + } + + # Replace long descriptions with short names - use contains for partial matching + if not aux.empty: + for long_desc, short_name in ksi_short_names.items(): + mask = aux["REQUIREMENTS_DESCRIPTION"].str.contains( + long_desc, na=False, regex=False + ) + aux.loc[mask, "REQUIREMENTS_DESCRIPTION"] = short_name + + return get_section_containers_cis( + aux, "REQUIREMENTS_ID", "REQUIREMENTS_ATTRIBUTES_SECTION" + ) diff --git a/dashboard/compliance/fedramp_20x_ksi_low_azure.py b/dashboard/compliance/fedramp_20x_ksi_low_azure.py new file mode 100644 index 0000000000..5ca220301f --- /dev/null +++ b/dashboard/compliance/fedramp_20x_ksi_low_azure.py @@ -0,0 +1,46 @@ +import warnings + +from dashboard.common_methods import get_section_containers_cis + +warnings.filterwarnings("ignore") + + +def get_table(data): + aux = data[ + [ + "REQUIREMENTS_ID", + "REQUIREMENTS_DESCRIPTION", + "REQUIREMENTS_ATTRIBUTES_SECTION", + "CHECKID", + "STATUS", + "REGION", + "ACCOUNTID", + "RESOURCEID", + ] + ].copy() + + # Shorten the long FedRAMP KSI descriptions for better display + ksi_short_names = { + "A secure cloud service offering will protect user data, control access, and apply zero trust principles": "Identity and Access Management", + "A secure cloud service offering will use cloud native architecture and design principles to enforce and enhance the Confidentiality, Integrity and Availability of the system": "Cloud Native Architecture", + "A secure cloud service provider will ensure that all system changes are properly documented and configuration baselines are updated accordingly": "Change Management", + "A secure cloud service provider will continuously educate their employees on cybersecurity measures, testing them regularly": "Cybersecurity Education", + "A secure cloud service offering will document, report, and analyze security incidents to ensure regulatory compliance and continuous security improvement": "Incident Reporting", + "A secure cloud service offering will monitor, log, and audit all important events, activity, and changes": "Monitoring, Logging, and Auditing", + "A secure cloud service offering will have intentional, organized, universal guidance for how every information resource, including personnel, is secured": "Policy and Inventory", + "A secure cloud service offering will define, maintain, and test incident response plan(s) and recovery capabilities to ensure minimal service disruption and data loss": "Recovery Planning", + "A secure cloud service offering will follow FedRAMP encryption policies, continuously verify information resource integrity, and restrict access to third-party information resources": "Service Configuration", + "A secure cloud service offering will understand, monitor, and manage supply chain risks from third-party information resources": "Third-Party Information Resources", + } + + # Replace long descriptions with short names - use contains for partial matching + if not aux.empty: + for long_desc, short_name in ksi_short_names.items(): + mask = aux["REQUIREMENTS_DESCRIPTION"].str.contains( + long_desc, na=False, regex=False + ) + aux.loc[mask, "REQUIREMENTS_DESCRIPTION"] = short_name + + return get_section_containers_cis( + aux, "REQUIREMENTS_ID", "REQUIREMENTS_ATTRIBUTES_SECTION" + ) diff --git a/dashboard/compliance/fedramp_20x_ksi_low_gcp.py b/dashboard/compliance/fedramp_20x_ksi_low_gcp.py new file mode 100644 index 0000000000..5ca220301f --- /dev/null +++ b/dashboard/compliance/fedramp_20x_ksi_low_gcp.py @@ -0,0 +1,46 @@ +import warnings + +from dashboard.common_methods import get_section_containers_cis + +warnings.filterwarnings("ignore") + + +def get_table(data): + aux = data[ + [ + "REQUIREMENTS_ID", + "REQUIREMENTS_DESCRIPTION", + "REQUIREMENTS_ATTRIBUTES_SECTION", + "CHECKID", + "STATUS", + "REGION", + "ACCOUNTID", + "RESOURCEID", + ] + ].copy() + + # Shorten the long FedRAMP KSI descriptions for better display + ksi_short_names = { + "A secure cloud service offering will protect user data, control access, and apply zero trust principles": "Identity and Access Management", + "A secure cloud service offering will use cloud native architecture and design principles to enforce and enhance the Confidentiality, Integrity and Availability of the system": "Cloud Native Architecture", + "A secure cloud service provider will ensure that all system changes are properly documented and configuration baselines are updated accordingly": "Change Management", + "A secure cloud service provider will continuously educate their employees on cybersecurity measures, testing them regularly": "Cybersecurity Education", + "A secure cloud service offering will document, report, and analyze security incidents to ensure regulatory compliance and continuous security improvement": "Incident Reporting", + "A secure cloud service offering will monitor, log, and audit all important events, activity, and changes": "Monitoring, Logging, and Auditing", + "A secure cloud service offering will have intentional, organized, universal guidance for how every information resource, including personnel, is secured": "Policy and Inventory", + "A secure cloud service offering will define, maintain, and test incident response plan(s) and recovery capabilities to ensure minimal service disruption and data loss": "Recovery Planning", + "A secure cloud service offering will follow FedRAMP encryption policies, continuously verify information resource integrity, and restrict access to third-party information resources": "Service Configuration", + "A secure cloud service offering will understand, monitor, and manage supply chain risks from third-party information resources": "Third-Party Information Resources", + } + + # Replace long descriptions with short names - use contains for partial matching + if not aux.empty: + for long_desc, short_name in ksi_short_names.items(): + mask = aux["REQUIREMENTS_DESCRIPTION"].str.contains( + long_desc, na=False, regex=False + ) + aux.loc[mask, "REQUIREMENTS_DESCRIPTION"] = short_name + + return get_section_containers_cis( + aux, "REQUIREMENTS_ID", "REQUIREMENTS_ATTRIBUTES_SECTION" + ) diff --git a/dashboard/compliance/hipaa_gcp.py b/dashboard/compliance/hipaa_gcp.py new file mode 100644 index 0000000000..b0a8eb6582 --- /dev/null +++ b/dashboard/compliance/hipaa_gcp.py @@ -0,0 +1,25 @@ +import warnings + +from dashboard.common_methods import get_section_containers_format3 + +warnings.filterwarnings("ignore") + + +def get_table(data): + + aux = data[ + [ + "REQUIREMENTS_ID", + "REQUIREMENTS_ATTRIBUTES_SECTION", + "REQUIREMENTS_DESCRIPTION", + "CHECKID", + "STATUS", + "REGION", + "ACCOUNTID", + "RESOURCEID", + ] + ].copy() + + return get_section_containers_format3( + aux, "REQUIREMENTS_ATTRIBUTES_SECTION", "REQUIREMENTS_ID" + ) diff --git a/dashboard/compliance/nist_csf_2_0_aws.py b/dashboard/compliance/nist_csf_2_0_aws.py new file mode 100644 index 0000000000..07b956b104 --- /dev/null +++ b/dashboard/compliance/nist_csf_2_0_aws.py @@ -0,0 +1,24 @@ +import warnings + +from dashboard.common_methods import get_section_containers_format3 + +warnings.filterwarnings("ignore") + + +def get_table(data): + aux = data[ + [ + "REQUIREMENTS_ID", + "REQUIREMENTS_ATTRIBUTES_SECTION", + "REQUIREMENTS_DESCRIPTION", + "CHECKID", + "STATUS", + "REGION", + "ACCOUNTID", + "RESOURCEID", + ] + ].copy() + + return get_section_containers_format3( + aux, "REQUIREMENTS_ATTRIBUTES_SECTION", "REQUIREMENTS_ID" + ) diff --git a/dashboard/pages/overview.py b/dashboard/pages/overview.py index 56fbff483e..4ce749a9e4 100644 --- a/dashboard/pages/overview.py +++ b/dashboard/pages/overview.py @@ -1654,6 +1654,39 @@ def generate_table(data, index, color_mapping_severity, color_mapping_status): [ html.Div( [ + # Description as first details item + html.Div( + [ + html.P( + html.Strong( + "Description: ", + style={ + "margin-bottom": "8px" + }, + ) + ), + html.Div( + dcc.Markdown( + str( + data.get( + "DESCRIPTION", + "", + ) + ), + dangerously_allow_html=True, + style={ + "margin-left": "0px", + "padding-left": "10px", + }, + ), + className="markdown-content", + style={ + "margin-left": "0px", + "padding-left": "10px", + }, + ), + ], + ), html.Div( [ html.P( @@ -1793,19 +1826,27 @@ def generate_table(data, index, color_mapping_severity, color_mapping_status): html.P( html.Strong( "Risk: ", - style={ - "margin-right": "5px" - }, + style={}, ) ), - html.P( - str(data.get("RISK", "")), + html.Div( + dcc.Markdown( + str( + data.get("RISK", "") + ), + dangerously_allow_html=True, + style={ + "margin-left": "0px", + "padding-left": "10px", + }, + ), + className="markdown-content", style={ - "margin-left": "5px" + "margin-left": "0px", + "padding-left": "10px", }, ), ], - style={"display": "flex"}, ), html.Div( [ @@ -1847,23 +1888,32 @@ def generate_table(data, index, color_mapping_severity, color_mapping_status): html.Strong( "Recommendation: ", style={ - "margin-right": "5px" + "margin-bottom": "8px" }, ) ), - html.P( - str( - data.get( - "REMEDIATION_RECOMMENDATION_TEXT", - "", - ) + html.Div( + dcc.Markdown( + str( + data.get( + "REMEDIATION_RECOMMENDATION_TEXT", + "", + ) + ), + dangerously_allow_html=True, + style={ + "margin-left": "0px", + "padding-left": "10px", + }, ), + className="markdown-content", style={ - "margin-left": "5px" + "margin-left": "0px", + "padding-left": "10px", }, ), ], - style={"display": "flex"}, + style={"margin-bottom": "15px"}, ), html.Div( [ diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index a67d7871d4..05ed89c397 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -14,9 +14,11 @@ services: ports: - "${DJANGO_PORT:-8080}:${DJANGO_PORT:-8080}" volumes: - - "./api/src/backend:/home/prowler/backend" - - "./api/pyproject.toml:/home/prowler/pyproject.toml" - - "outputs:/tmp/prowler_api_output" + - ./api/src/backend:/home/prowler/backend + - ./api/pyproject.toml:/home/prowler/pyproject.toml + - ./api/docker-entrypoint.sh:/home/prowler/docker-entrypoint.sh + - ./_data/api:/home/prowler/.config/prowler-api + - outputs:/tmp/prowler_api_output depends_on: postgres: condition: service_healthy @@ -64,7 +66,7 @@ services: image: valkey/valkey:7-alpine3.19 hostname: "valkey" volumes: - - ./api/_data/valkey:/data + - ./_data/valkey:/data env_file: - path: .env required: false diff --git a/docker-compose.yml b/docker-compose.yml index dbb493fb9a..2e2469e0c8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,8 @@ services: ports: - "${DJANGO_PORT:-8080}:${DJANGO_PORT:-8080}" volumes: - - "output:/tmp/prowler_api_output" + - ./_data/api:/home/prowler/.config/prowler-api + - output:/tmp/prowler_api_output depends_on: postgres: condition: service_healthy diff --git a/docs/.mintlifyignore b/docs/.mintlifyignore new file mode 100644 index 0000000000..2681ed7d5c --- /dev/null +++ b/docs/.mintlifyignore @@ -0,0 +1,4 @@ +.idea/ +.git/ +.claude/ +AGENTS.md diff --git a/docs/AGENTS.md b/docs/AGENTS.md new file mode 100644 index 0000000000..47e24d419d --- /dev/null +++ b/docs/AGENTS.md @@ -0,0 +1,533 @@ +Always that you are writting documentation try to follow this text/communication style guide: + +# Prowler's Brand Voice + +Prowler is the open cloud security platform trusted by thousands of organizations automating security monitoring and compliance with hundreds of built-in security checks, remediation solutions, and compliance frameworks. With over 10 million downloads, thousands of contributors, and a vibrant global community, Prowler is driving the open-source cloud security movement by providing transparent, customizable, and user-friendly solutions that help teams secure AWS, Azure, GCP, Kubernetes, and Microsoft 365 environments. Leveraging open-source innovation and cost savings, the Prowler platform makes cloud security 10 times more cost-effective and accessible than alternatives. + +These values must be demonstrated in all our conversations and communications. + +--- + +## Unbiased Communication + +Prowler aims to reach every person in the globe. Our communications must be as inclusive and diverse as possible every time. We are guided by the following principles: + +### Avoid Gendered Pronouns + +Reference to gendered pronouns (she/her/hers, he/his/his, they/them/theirs) must be avoided whenever possible. + +* Use second person for communications (you/your/yours). +* Use a third-person reference instead of a gendered pronoun (the customer, the user). +* In case a gendered pronoun must be forcibly used, use they/them/theirs. +* Avoid double references like she/he, s/he, etc. + +### Use Alternatives for Gendered Nouns + +Avoid nouns that include gendered components. Examples: + +* Businessman 🔪 Entrepreneur, businessperson, executive +* Salesman 🔪 Sales executive, sales representative +* Mankind 🔪 Humanity, people +* Penmanship 🔪 Calligraphy, handwriting +* Middleman 🔪 Intermediary, negotiator + +### Diversity, Equity, and Inclusion + +All communications must prioritize diversity and inclusivity. When incorporating examples, ensure representation across sex, gender, age, identity, race, culture, background, ability, and socioeconomic status. Strive for balanced and respectful depictions. + +### Cultural and Geographical Awareness + +Before referencing a region, country, culture, national status, political status, or socioeconomic realities, conduct thorough research. Maintain a respectful, informed approach and avoid unnecessary conflicts. + +### Avoiding Generalizations + +Avoid broad assumptions about gender, sex, race, sexual orientation, nationality, or culture. Generalizations can introduce bias and misrepresentation. Example to avoid: "Cybersecurity is of the utmost importance in the country, where corruption runs amok." + +### Respectful Language + +Derogatory terms must not be used. If uncertain about terminology, consult individuals from the relevant region or community to ensure accuracy and appropriateness. + +### Clear and Accessible Language + +* **Jargon:** Use technical terminology only when the audience is expected to understand it. If uncertain, opt for clear and universally accessible language. +* **Slang:** Minimize slang usage. Even when confident about the audience, prefer formal and neutral language to enhance clarity. + +### Militaristic Language + +Current tendencies in a topic as sensitive as cybersecurity avoid violent and militaristic references save for explicit reference to combat. These are some alternatives: + +* Combat, fight, eliminate 🔪 Address, protect, safeguard, ward +* Kill chain 🔪 Cyberattack chain +* Attacker 🔪 Cyberattacker, bad actor, threat actor +* Defense-in-depth approach 🔪 Multilayered approach +* First line of defense, frontline 🔪 Security, protection, defense +* External attack surface 🔪 Vulnerabilities, point of access, external exposure + +### Note on Safety and Security + +ā€œSafetyā€ and ā€œsecurityā€ are terms often misunderstood. ā€œSafetyā€ is the microscopic, personal and individual term, while ā€œsecurityā€ is the macroscopic, broader, national term. Examples: + +a. Seat belts are great for personal safety. +b. National security is of the utmost concern nowadays. + +--- + +## Naming Conventions + +### Prowler Features + +Prowler Features are considered proper nouns. They are to be referenced without articles in all pieces of writing. + +This is a list of Prowler Features: + +* **Prowler App** +* **Prowler CLI** +* **Prowler SDK** +* **Built-in Compliance Checks** +* **Multi-cloud Security Scanning** +* **Autonomous Cloud Security Analyst (AI)** +* **Threat & Misconfiguration Detection** +* **Role-Based Access Control (RBAC)** +* **Identity & Access Risk Detection** +* **Tag-Based Scanning & Filtering** +* **Audit Logs & Security Reports** +* **Agentless & Works Anywhere** +* **Automated Scans & Continuous Monitoring** +* **Chat-based Security Querying (AI)** +* **AI-Generated Detections & Remediations** +* **Prowler Studio** +* **Custom Security Policies** +* **Prowler Cloud** +* **Prowler Registry** +* **Open Source & Full APIs** + +--- + +## Verbal Constructions in Technical Writing + +Choosing verbal constructions (using verbs) over nominal (using nouns) constructions can significantly impact the clarity, conciseness and especially readability of the content. + +Nominal constructions often introduce unnecessary complexity or vagueness. For example: + +* Nominal: "The creation of the report was successful." +* Verbal: "The report was successfully created." + +Verbal constructions also tend to use fewer words, resulting in a more polished and concise style: + +* Nominal: "The implementation of the solution reduced system downtime." +* Verbal: "The solution reduced system downtime." + +Verbal constructions are to be chosen over nominal constructions whenever possible. + +--- + +### Addendum: Verbal Structures Actually State your Purpose + +* **Example 1:** Recommendation for multiple subscriptions +* **Example 2:** Recommendation for Managing Multiple Subscriptions + +Example 1 is vague and even potentially ambiguous. Verbs state your purpose and they must be used whenever possible. + +--- + +## Avoiding The Second Person Except for Imperative Instructions + +Explicit use of second-person pronouns (you) and possessives (your) should be minimized whenever possible. Those constructions are best reserved for cases when instructions are directly given in an imperative form: + +**Example of Improvement Through Avoiding Second Person Pronouns** + +**Original:** +Prowler App can be installed in different ways, depending on your environment: + +**Improved Version:** +Prowler App offers flexible installation methods tailored to various environments: + +--- + +## Title-Case Capitalization + +We use title case. + +**Example:** This Is an Example on Title Case + +Title case tends to be better for SEO because it improves readability and makes headlines more visually distinct, which can lead to higher click-through rates (CTR). + +--- + +### Other Considerations on Capitalization + +Follow these additional guidelines for capitalization: + +### Inner Capitalization + +Avoid internal capitalization of words in body text unless it is part of a proper name or brand denomination. Example: instead of E-mail and e-Book use email/e-mail and e-book. + +### Acronym Capitalization + +Do not capitalize the individual words of the spelled-out form of acronyms. Example: instead of CTI (Cyber Threat Intelligence) use CTI (cyber threat intelligence), but AWS (Amazon Web Services) is to be kept as is. + +### Avoid Capitalization for Emphasis + +Do not capitalize words in order to emphasize them. + +### Capitalization of Languages and Standards + +Check for the proper capitalization of language and standard names. + +Language examples: HTML, JSON, YAML, XML, etc., must be capitalized. + +Standard examples: standards follow title-case capitalization: Industrial Automation and Control Systems (IACS). + +### Capitalization of Laws and Regulations + +Laws and Regulations follow title-case capitalization. If referring to a non-domestic law or regulation, add the nationality and the original name. + +**Example:** Code for the Cybersecurity Law published in the Spanish Official State Bulletin (BOE, BoletĆ­n Oficial del Estado). + +Most UE Regulations have an official translation for all UE languages; please check it on EUR-Lex portal and choose the proper language: https://eur-lex.europa.eu/. + +The different languages can be chosen on the portal under Languages, formats and link to OJ. + +--- + +## Hyphenation + +Hyphenation is to be used for noun modifiers in prenominal position, i.e., placed before nouns. + +**Example:** Prowler is a world-leading company in open-source software. + +It is not to be used for predicate adjectives in postnominal position. + +**Example:** Prowler has many features built in. + +### Note on Hyphenation and SEO + +Google treats hyphens as word separators, as if they were blank spaces, i.e., the term `high quality checks` is treated as if it was the same term as `high-quality checks`. Hyphenation does not affect SEO on body text, thus the grammatically correct approach is recommended as sign of good writing. However, underscores (`_`) are treated as different words. This has implications particularly for URLs. + +Hyphens are preferred for URLs as they improve readability and indexing. + +**Example:** +* Better approach: `example.com/this-is-an-URL` +* Less ideal approach: `example.com/this_is_an_URL` + +--- + +## Bullet Points + +Bullet points offer several advantages: + +* **Improved readability:** Bullet points make information scannable and enable vertical reading, allowing users to easily spot relevant details and breaking content into more digestible pieces. +* **Highlighting of relevant information:** They emphasize the most salient points, improving focus and enabling quick summarization at a glance. +* **Improved retention:** Bullet points enhance memory retention and contribute to a clearer, more polished final product. +* **Structured presentation:** They improve user experience through the logical organization of content. +* **SEO relevance (Search Engine Optimization):** Bullet points make content easier to consume and offer the following SEO benefits: + * Reduced bounce rates + * Increased time spent on page + * Strategic keyword optimization + * Improved chances of being featured in search engine snippets + * Enhanced crawlability for search engines. + +--- + +### When to Use Bullet Points + +The use of bullet points is highly recommended when: + +* Information can be logically divided into multiple categories, each sharing characteristics, features, or other relevant classifications. +* Items are significant enough as standalone concepts to deserve their own bullet point. + +**Example of Improvement Through Bullet Points** + +**Original:** +It contains hundreds of controls covering CIS, NIST 800, NIST CSF, CISA, RBI, FedRAMS, PCI-DSS, GDPR, HIPAA, FFIEC, SOC2, GXP, AWS Well-Architected Framework Security Pillar, AWS Foundational Technical Review (FTR), ENS (Spanish National Security Scheme), and your custom security frameworks. + +**Improved with Bullet Points:** + +**Prowler CLI Features:** +Prowler CLI includes hundreds of built-in controls to ensure compliance with standards and frameworks, including: + +* **Industry standards:** CIS, NIST 800, NIST CSF, and CISA +* **Regulatory compliance and governance:** RBI, FedRAMP, and PCI-DSS +* **Frameworks for sensitive data and privacy:** GDPR, HIPAA, and FFIEC +* **Frameworks for organizational governance and quality control:** SOC2 and GXP +* **AWS-specific guidance:** AWS Foundational Technical Review (FTR) and AWS Well-Architected Framework (Security Pillar) +* **Regional compliance:** ENS (Spanish National Security Scheme) +* **Custom security frameworks:** Tailored to meet your organization’s specific needs + +--- + +### Punctuation of Bullet Points + +There are several options for punctuating bullet points. Regardless of the style chosen, it is imperative to maintain consistency throughout the text. + +* **No punctuation (minimalistic):** This strategy is suitable when no verbs are involved and is best used to highlight products or features in isolation. For example: + + Prowler App is composed of three key components: + * Prowler UI + * Prowler API + * Prowler SDK + + This example highlights each element individually and fosters retention with a noise-free approach. + +* **Periods for full sentences:** This approach works best when each bullet point forms a full sentence or includes verbs. For example: + + Prowler App is composed of three key components: + * Prowler UI, a web-based interface, built with Next.js, providing a user-friendly experience for executing Prowler scans and visualizing results. + * Prowler API, a backend service, developed with Django REST Framework, responsible for running Prowler scans and storing the generated results. + * Prowler SDK, a Python SDK designed to extend the functionality of the Prowler CLI for advanced capabilities. + + This example demonstrates a polished list using proper punctuation. + +* **Semi-colons with final period:** This approach was traditionally used for those cases when bullet points were part of a continuous sentence or logical succession. However, it is being deprecated, consistent with the declining use of semi-colons in modern writing. It is to be avoided whenever possible. For example: + + Prowler UI: + * is a web-based interface; + * is built with Next.js; + * provides a user-friendly experience for executing Prowler scans and visualizing results. + +--- + +### Advantages of Adding Headers to Bullet Points + +Adding headers to bullet points in technical writing is a powerful technique that enhances both the clarity and usability of the content. It has also advantages for SEO: + +* Increased crawlability of search engines +* Enhanced keyword integration +* Improved user engagement +* Enhanced snippetting by search engines +* Reduced bounce rates + +It is recommended to add headers to bullet points whenever possible. + +--- + +## Quotation Marks + +### Quotation Marks Usage in Technical Documentation + +Proper use of quotation marks enhances clarity and consistency in technical writing. Below are key guidelines for using double and single quotation marks, following American English conventions. + +### Double Quotation Marks + +* Use for titles of books, movies, songs, and articles. +* Enclose direct quotes: + * **Example:** The developer said, ā€œWe will try to fix this issue.ā€ +* Capitalize the first word if quoting a full sentence. +* When quoting a phrase within a sentence, do not capitalize: + * **Example:** The news portal called our product ā€œone of the most efficient online help authoring tools.ā€ +* Use scare quotes when words acquire a different or ironic meaning: + * **Example:** The update is ā€œscheduledā€ to release next week. +* To refer to a term without applying its meaning, use double quotes (or italics): + * **Example:** Avoid terms like ā€œdon’t worryā€ in pop-ups to prevent user anxiety. + +### Single Quotation Marks + +* Used inside double quotes: + * **Example:** He said, ā€œI am not sure what ā€˜single sourcing’ means.ā€ +* In British English, the order is often reversed (single quotation marks on the outside). + +--- + +### Double Quoting in Software Documentation + +Double quoting is to be used through software documentation where their use does not interfere with formatting restrictions. + +1. **Menu Items & UI Options** + * Use double quotation marks when referring to selectable items in software interfaces. + * **Example:** Click ā€œFileā€ and select ā€œSave Asā€ to export your document. +2. **Buttons & Commands** + * Use double quotes for labeled interface elements that users interact with. + * **Example:** Select ā€œSubmitā€ to finalize the form. +3. **Exact Input & User Actions** + * If users need to enter exact text, enclose it in double quotes. + * **Example:** Type ā€œadminā€ in the username field. +4. **Avoid Quoting Software Names** + * Do not use quotation marks for software product names unless required for clarity. + * **Correct:** Open Microsoft Excel. + * **Incorrect:** Open ā€œMicrosoft Excel.ā€ + +--- + +## Interaction Verbs + +The following are the correct verbs that must be used when referring to user interactions with the software. + +### Mouse & Trackpad Actions (Desktop/Laptop) + +* **Click:** Press and release the left mouse button or trackpad without moving the pointer. + * **Example:** Click the ā€œOKā€ button to confirm. 🔪 Transitive +* **Click on:** Often interchangeable with "Click," but less commonly used in technical writing for UI interactions. + * **Example:** Click on the "Settings" icon to open preferences. (Less recommendedā€”ā€œClickā€ is preferred.) +* **Double-click:** Press and release twice in quick succession, usually to open files or applications. + * **Example:** Double-click the document to open it. 🔪 Transitive +* **Right-click:** Press and release the right mouse button to open a context menu. + * **Example:** Right-click the folder and select ā€œProperties.ā€ 🔪 Transitive + +### Touchscreen Actions (Mobile & Touch) + +* **Tap:** Touch the screen lightly with a finger or stylus, equivalent to "Click" on a mouse. + * **Example:** Tap the ā€œSign inā€ button. +* **Double-tap:** Quickly touch the screen twice, often used for zooming or selecting text. + * **Example:** Double-tap an image to zoom in. +* **Press and hold:** Touch and hold the screen for a moment to access additional options. + * **Example:** Press and hold an app icon to see more actions. (Similar to ā€œRight-clickā€ in desktop environments.) + +### Additional Actions + +* **Drag:** Click or tap an item and move it while holding down the button or finger. + * **Example:** Drag the file into the folder. +* **Swipe:** Move a finger across the touchscreen horizontally or vertically. + * **Example:** Swipe left to dismiss the notification. +* **Pinch to zoom:** Use two fingers to zoom in or out. + * **Example:** Pinch the screen to zoom in on the image. +* **Scroll:** Move the mouse wheel, swipe, or use the arrow keys to navigate up/down. + * **Example:** Scroll down to see more results. + +The widely-accepted terminology for gestures is Windows’: https://support.microsoft.com/en-us/windows/touch-gestures-for-windows-a9d28305-4818-a5df-4e2b-e5590f850741 + +--- + +## Sentence Structure for Technical Writing and SEO + +When writing technical documentation, clarity, conciseness, and searchability (SEO) are key factors. Let’s compare the following two sentence structures, extracted from Prowler’s documentation: + +**Option 1:** +"Open a terminal and execute the following command to create a new custom role." + +**Option 2:** +"To create a new custom role, open a terminal and execute the following command." + +### SEO Optimization + +* Search engines prioritize clear intent at the beginning of a sentence. +* Option 2 starts with the action users are likely to search for (e.g., "Create a custom role"), which improves SEO rankings and makes the content more likely to match search queries. +* Option 1 places the primary search term toward the end, making it less effective for keyword optimization. + +### Technical Writing Best Practices + +* Technical writing emphasizes clear objectives first, followed by actions. +* Option 2 follows this best practice by stating the goal first ("To create a new custom role") and then providing instructions. +* Option 1 is still acceptable for step-by-step guides, but Option 2 is more effective for tutorials, manuals, and documentation. + +### Key Takeaways + +* Draft trying to mimic the most likely way users are to find the information (ā€œCtrl + F approachā€). +* Place keywords and key terms at the beginning of sentences so that they rank better SEO-wise. +* Rule of thumb: ā€œIn order to whatā€ precedes the ā€œwhatā€. ā€œWhatā€ must mirror the user’s most likely way of drafting or searching. + +--- + +## Section Titles and Headers in Technical Writing + +Effective headers and section titles enhance document readability and structure, making content more accessible to the reader. This chapter outlines best practices for crafting clear, consistent, and meaningful headings. + +1. **Purpose of Headers** + Headers serve several key functions: + * **Improve Navigation:** Allow users to quickly locate relevant information. + * **Enhance Readability:** Break down complex topics into manageable sections. + * **Establish Hierarchy:** Define the logical flow of content. + * **SEO:** Headers impact SEO both directly and indirectly: + * Search engines use headings to determine the hierarchy and relevance of content. + * **H1:** The primary heading (should be unique and descriptive). + * **H2-H6:** Subheadings that break down content logically. + * Best practices for SEO-friendly headers: + * Include keywords naturally in headings. + * Avoid keyword stuffing—keep it clear and readable. + * Use structured hierarchy (H1 → H2 → H3, etc.). +2. **Header Levels and Formatting** + Use a structured approach for organizing section titles. Common conventions include: + * **Title:** The primary heading of the document (e.g., H1). + * **Main Sections:** First-level headers (H2), introducing key content areas. + * **Subsections:** Second-level headers (H3) to detail specific topics within sections. + * **Subtopics:** Third-level headers (H4+) used sparingly for finer details. + + **Example:** + + ```markdown + # Document Title (H1) + ## Main Section (H2) + ### Subsection (H3) + #### Subtopic (H4) + ``` + +3. **Writing Effective Headers** + When crafting headers and section titles, follow these guidelines: + * **Be Descriptive:** Clearly indicate what the section covers. + * **Poor:** Introduction (too vague) + * **Good:** Introduction to AWS CloudShell Installation (informative) + * **Keep It Concise:** Use precise language without unnecessary words. + * **Maintain Consistency:** Apply uniform formatting and style conventions throughout. + * **Avoid Special Characters:** Limit punctuation for clarity—avoid excessive symbols, dashes, or underscores. +4. **Capitalization Rules** + Use Title Case for headers to ensure a professional look: + * **Good:** How to Clone and Install Prowler from GitHub + * **Poor:** How to clone and install Prowler from GitHub + + For technical documentation, sentence case may be used for readability in subheadings. Please note this differs from headers and it is only a recommendation, but consistency is to be kept throughout the documentation: + + * **Example:** + * How to Clone and Install Prowler from GitHub (header: Title case) + * How to install poetry dependencies (subheading: Sentence case) +5. **Using Keywords in Headers** + Headers should include relevant keywords to improve document searchability: + * **Good:** Scanning AWS Accounts in Parallel + * **Poor:** Ways to scan on AWS (vague and imprecise) +6. **Consistency Across Documents** + Ensure uniformity in section titles across related documentation: + * **Standardized Header Naming:** Use consistent wording for common sections (e.g., "Installation," "Setup," "Configuration"). + * **Numbering Sections (If Necessary):** For structured guides, include numbering where appropriate (e.g., "Step 1: Install Prowler"). + +--- + +## Avoid Assumptions Regarding Audience’s Expertise + +### Understand Your Audience’s Expertise + +Despite knowing your target audience, assumptions on target audience’s expertise or knowledge are to be avoided. + +Adjust the level of detail based on expected reader proficiency, but make sure to be as explanatory as humanly possible. + +### Define Key Terms and Acronyms on First Use + +Even if your audience is technical, some domain-specific terms may vary. +* Introduce jargon only after defining it clearly. +* If using acronyms (e.g., IAM, MFA), spell them out on first mention: + * AWS Identity and Access Management (IAM) + * Multifactor Authentication (MFA) + +### Don’t Assume Unwritten Knowledge + +Even experienced readers may not know every prerequisite. If a process relies on prior steps, briefly reference them: + +* Before configuring security groups, ensure VPC networking is set up. + +### Use Consistent Formatting + +### Provide as Many Examples as Deemed Right… and Then Some + +### Anticipate Common Knowledge Gaps + +### Avoid Excessive Notes + +Notes are often omitted by readers and they clutter text, so use them sparingly and only for additional information that is not essential or prompts any error or mistake. + +--- + +## Using Warnings and Danger Calls for High-Severity Information + +In technical documentation, warnings and danger calls highlight critical risks, guiding users in preventing security breaches or system failures. Proper usage ensures clarity and actionable guidance. + +1. **Define Severity Levels** + Before applying Note, Warning, or Danger, clearly define their significance: + * **Note:** Provides general information or best practices (low severity). + * **Warning:** Indicates potential issues if instructions are not followed (moderate severity). + * **Danger:** Highlights actions that could result in severe consequences, such as system corruption or data loss (high severity). +2. **Explain Consequences** + Each warning or danger call should explicitly describe the impact of ignoring the caution: + * **Good:** Disabling encryption may expose sensitive data to unauthorized access. + * **Poor:** Avoid disabling encryption. +3. **Provide Remediation and Troubleshooting** + Whenever possible, direct users to troubleshooting guides or mitigation steps to resolve the issue. + + **Example:** + **Danger:** Running this command will **permanently delete all data**. Refer to @Data Recovery Guide for restoration steps. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..79917aeed1 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,45 @@ +# Prowler Documentation + +This repository contains the Prowler Open Source documentation powered by [Mintlify](https://mintlify.com). + +## Documentation Structure + +- **Getting Started**: Overview, installation, and basic usage guides +- **User Guide**: Comprehensive guides for Prowler App, CLI, providers, and compliance +- **Developer Guide**: Technical documentation for developers contributing to Prowler + +## Local Development + +Install the [Mintlify CLI](https://www.npmjs.com/package/mint) to preview documentation changes locally: + +```bash +npm i -g mint +``` + +Run the following command at the root of your documentation (where `mint.json` is located): + +```bash +mint dev +``` + +View your local preview at `http://localhost:3000`. + +## Publishing Changes + +Changes pushed to the main branch are automatically deployed to production through Mintlify's GitHub integration. + +## Documentation Guidelines + +When contributing to the documentation, please follow the Prowler documentation style guide located in the `.claude` directory. + +## Troubleshooting + +- If your dev environment isn't running: Run `mint update` to ensure you have the most recent version of the CLI. +- If a page loads as a 404: Make sure you are running in a folder with a valid `mint.json` file and that the page path is correctly listed in the navigation. + +## Resources + +- [Prowler GitHub Repository](https://github.com/prowler-cloud/prowler) +- [Prowler Documentation](https://docs.prowler.com/) +- [Mintlify Documentation](https://mintlify.com/docs) +- [Mintlify Community](https://mintlify.com/community) diff --git a/docs/basic-usage/prowler-app.md b/docs/basic-usage/prowler-app.md deleted file mode 100644 index 8ed7625577..0000000000 --- a/docs/basic-usage/prowler-app.md +++ /dev/null @@ -1,61 +0,0 @@ -## Access Prowler App - -After [installation](../installation/prowler-app.md), navigate to [http://localhost:3000](http://localhost:3000) and sign up with email and password. - -Sign Up Button -Sign Up - -???+ note "User creation and default tenant behavior" - - When creating a new user, the behavior depends on whether an invitation is provided: - - - **Without an invitation**: - - - A new tenant is automatically created. - - The new user is assigned to this tenant. - - A set of **RBAC admin permissions** is generated and assigned to the user for the newly-created tenant. - - - **With an invitation**: The user is added to the specified tenant with the permissions defined in the invitation. - - This mechanism ensures that the first user in a newly created tenant has administrative permissions within that tenant. - -## Log In - -Access Prowler App by logging in with **email and password**. - -Log In - -## Add Cloud Provider - -Configure a cloud provider for scanning: - -1. Navigate to `Settings > Cloud Providers` and click `Add Account`. -2. Select the cloud provider. -3. Enter the provider's identifier (Optional: Add an alias): - - **AWS**: Account ID - - **GCP**: Project ID - - **Azure**: Subscription ID - - **Kubernetes**: Cluster ID - - **M365**: Domain ID -4. Follow the guided instructions to add and authenticate your credentials. - -## Start a Scan - -Once credentials are successfully added and validated, Prowler initiates a scan of your cloud environment. - -Click `Go to Scans` to monitor progress. - -## View Results - -Review findings during scan execution in the following sections: - -- **Overview** – Provides a high-level summary of your scans. - Overview - -- **Compliance** – Displays compliance insights based on security frameworks. - Compliance - -> For detailed usage instructions, refer to the [Prowler App Guide](../tutorials/prowler-app.md). - -???+ note - Prowler will automatically scan all configured providers every **24 hours**, ensuring your cloud environment stays continuously monitored. diff --git a/docs/contact.md b/docs/contact.mdx similarity index 93% rename from docs/contact.md rename to docs/contact.mdx index 94c8adf0bb..3f898b9049 100644 --- a/docs/contact.md +++ b/docs/contact.mdx @@ -1,4 +1,6 @@ -# Contact Us +--- +title: 'Contact Us' +--- For technical support or any type of inquiries, you are very welcome to: diff --git a/docs/developer-guide/aws-details.md b/docs/developer-guide/aws-details.mdx similarity index 86% rename from docs/developer-guide/aws-details.md rename to docs/developer-guide/aws-details.mdx index 9fa182d689..70f94f4006 100644 --- a/docs/developer-guide/aws-details.md +++ b/docs/developer-guide/aws-details.mdx @@ -1,12 +1,14 @@ -# AWS Provider +--- +title: 'AWS Provider' +--- In this page you can find all the details about [Amazon Web Services (AWS)](https://aws.amazon.com/) provider implementation in Prowler. -By default, Prowler will audit just one account and organization settings per scan. To configure it, follow the [AWS getting started guide](../tutorials/aws/getting-started-aws.md). +By default, Prowler will audit just one account and organization settings per scan. To configure it, follow the [AWS getting started guide](/user-guide/providers/aws/getting-started-aws). ## AWS Provider Classes Architecture -The AWS provider implementation follows the general [Provider structure](./provider.md). This section focuses on the AWS-specific implementation, highlighting how the generic provider concepts are realized for AWS in Prowler. For a full overview of the provider pattern, base classes, and extension guidelines, see [Provider documentation](./provider.md). In next subsection you can find a list of the main classes of the AWS provider. +The AWS provider implementation follows the general [Provider structure](/developer-guide/provider). This section focuses on the AWS-specific implementation, highlighting how the generic provider concepts are realized for AWS in Prowler. For a full overview of the provider pattern, base classes, and extension guidelines, see [Provider documentation](/developer-guide/provider). In next subsection you can find a list of the main classes of the AWS provider. ### `AwsProvider` (Main Class) @@ -33,7 +35,7 @@ The AWS provider implementation follows the general [Provider structure](./provi ### `AWSService` (Service Base Class) - **Location:** [`prowler/providers/aws/lib/service/service.py`](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/aws/lib/service/service.py) -- **Purpose:** Abstract base class that all AWS service-specific classes inherit from. This implements the generic service pattern (described in [service page](./services.md#service-base-class)) specifically for AWS. +- **Purpose:** Abstract base class that all AWS service-specific classes inherit from. This implements the generic service pattern (described in [service page](/developer-guide/services#service-base-class)) specifically for AWS. - **Key AWS Responsibilities:** - Receives an `AwsProvider` instance to access session, identity, and configuration. - Manages clients for all services by regions. @@ -52,12 +54,12 @@ The AWS provider implementation follows the general [Provider structure](./provi ## Specific Patterns in AWS Services -The generic service pattern is described in [service page](./services.md#service-structure-and-initialisation). You can find all the right now implemented services in the following locations: +The generic service pattern is described in [service page](/developer-guide/services#service-structure-and-initialisation). You can find all the right now implemented services in the following locations: - Directly in the code, in location [`prowler/providers/aws/services/`](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers/aws/services) - In the [Prowler Hub](https://hub.prowler.com/). For a more human-readable view. -The best reference to understand how to implement a new service is following the [service implementation documentation](./services.md#adding-a-new-service) and taking other services already implemented as reference. In next subsection you can find a list of common patterns that are used accross all AWS services. +The best reference to understand how to implement a new service is following the [service implementation documentation](/developer-guide/services#adding-a-new-service) and taking other services already implemented as reference. In next subsection you can find a list of common patterns that are used accross all AWS services. ### AWS Service Common Patterns @@ -74,12 +76,12 @@ The best reference to understand how to implement a new service is following the ## Specific Patterns in AWS Checks -The AWS checks pattern is described in [checks page](./checks.md). You can find all the right now implemented checks: +The AWS checks pattern is described in [checks page](/developer-guide/checks). You can find all the right now implemented checks: - Directly in the code, within each service folder, each check has its own folder named after the name of the check. (e.g. [`prowler/providers/aws/services/s3/s3_bucket_acl_prohibited/`](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers/aws/services/s3/s3_bucket_acl_prohibited)) - In the [Prowler Hub](https://hub.prowler.com/). For a more human-readable view. -The best reference to understand how to implement a new check is following the [check creation documentation](./checks.md#creating-a-check) and taking other similar checks as reference. +The best reference to understand how to implement a new check is following the [check creation documentation](/developer-guide/checks#creating-a-check) and taking other similar checks as reference. ### Check Report Class diff --git a/docs/developer-guide/azure-details.md b/docs/developer-guide/azure-details.mdx similarity index 84% rename from docs/developer-guide/azure-details.md rename to docs/developer-guide/azure-details.mdx index d1eb6b73be..d298a13bf4 100644 --- a/docs/developer-guide/azure-details.md +++ b/docs/developer-guide/azure-details.mdx @@ -1,12 +1,14 @@ -# Azure Provider +--- +title: 'Azure Provider' +--- In this page you can find all the details about [Microsoft Azure](https://azure.microsoft.com/) provider implementation in Prowler. -By default, Prowler will audit all the subscriptions that it is able to list in the Microsoft Entra tenant, and tenant Entra ID service. To configure it, follow the [Azure getting started guide](../tutorials/azure/getting-started-azure.md). +By default, Prowler will audit all the subscriptions that it is able to list in the Microsoft Entra tenant, and tenant Entra ID service. To configure it, follow the [Azure getting started guide](/user-guide/providers/azure/getting-started-azure). ## Azure Provider Classes Architecture -The Azure provider implementation follows the general [Provider structure](./provider.md). This section focuses on the Azure-specific implementation, highlighting how the generic provider concepts are realized for Azure in Prowler. For a full overview of the provider pattern, base classes, and extension guidelines, see [Provider documentation](./provider.md). In next subsection you can find a list of the main classes of the Azure provider. +The Azure provider implementation follows the general [Provider structure](/developer-guide/provider). This section focuses on the Azure-specific implementation, highlighting how the generic provider concepts are realized for Azure in Prowler. For a full overview of the provider pattern, base classes, and extension guidelines, see [Provider documentation](/developer-guide/provider). In next subsection you can find a list of the main classes of the Azure provider. ### `AzureProvider` (Main Class) @@ -32,7 +34,7 @@ The Azure provider implementation follows the general [Provider structure](./pro ### `AzureService` (Service Base Class) - **Location:** [`prowler/providers/azure/lib/service/service.py`](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/azure/lib/service/service.py) -- **Purpose:** Abstract base class that all Azure service-specific classes inherit from. This implements the generic service pattern (described in [service page](./services.md#service-base-class)) specifically for Azure. +- **Purpose:** Abstract base class that all Azure service-specific classes inherit from. This implements the generic service pattern (described in [service page](/developer-guide/services#service-base-class)) specifically for Azure. - **Key Azure Responsibilities:** - Receives an `AzureProvider` instance to access session, identity, and configuration. - Manages clients for all services by subscription. @@ -50,12 +52,12 @@ The Azure provider implementation follows the general [Provider structure](./pro ## Specific Patterns in Azure Services -The generic service pattern is described in [service page](./services.md#service-structure-and-initialisation). You can find all the currently implemented services in the following locations: +The generic service pattern is described in [service page](/developer-guide/services#service-structure-and-initialisation). You can find all the currently implemented services in the following locations: - Directly in the code, in location [`prowler/providers/azure/services/`](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers/azure/services) - In the [Prowler Hub](https://hub.prowler.com/) for a more human-readable view. -The best reference to understand how to implement a new service is following the [service implementation documentation](./services.md#adding-a-new-service) and taking other services already implemented as reference. In next subsection you can find a list of common patterns that are used accross all Azure services. +The best reference to understand how to implement a new service is following the [service implementation documentation](/developer-guide/services#adding-a-new-service) and taking other services already implemented as reference. In next subsection you can find a list of common patterns that are used accross all Azure services. ### Azure Service Common Patterns @@ -68,12 +70,12 @@ The best reference to understand how to implement a new service is following the ## Specific Patterns in Azure Checks -The Azure checks pattern is described in [checks page](./checks.md). You can find all the currently implemented checks: +The Azure checks pattern is described in [checks page](/developer-guide/checks). You can find all the currently implemented checks: - Directly in the code, within each service folder, each check has its own folder named after the name of the check. (e.g. [`prowler/providers/azure/services/storage/storage_blob_public_access_level_is_disabled/`](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers/azure/services/storage/storage_blob_public_access_level_is_disabled)) - In the [Prowler Hub](https://hub.prowler.com/) for a more human-readable view. -The best reference to understand how to implement a new check is the [Azure check implementation documentation](./checks.md#creating-a-check) and taking other similar checks as reference. +The best reference to understand how to implement a new check is the [Azure check implementation documentation](/developer-guide/checks#creating-a-check) and taking other similar checks as reference. ### Check Report Class diff --git a/docs/developer-guide/check-metadata-guidelines.mdx b/docs/developer-guide/check-metadata-guidelines.mdx new file mode 100644 index 0000000000..2b6524bcc6 --- /dev/null +++ b/docs/developer-guide/check-metadata-guidelines.mdx @@ -0,0 +1,215 @@ +--- +title: 'Check Metadata Guidelines' +--- + +## Introduction + +This guide provides comprehensive guidelines for creating check metadata in Prowler. For basic information on check metadata structure, refer to the [check metadata](/developer-guide/checks#metadata-structure-for-prowler-checks) section. + +## Check Title Guidelines + +### Writing Guidelines + +1. **Determine Resource Finding Scope (Singular vs. Plural)**: + When determining whether to use singular or plural in the check title, examine the code for certain patterns. If the code contains a loop that generates an individual report for each resource, use the singular form. If the code produces a single report that covers all resources collectively, use the plural form. For organization- or account-wide checks, select the scope that best matches the breadth of the evaluation. Additionally, review the `status_extended` field messages in the code, as they often provide clues about whether the check is scoped to individual resources or to groups of resources. + Analyze the detection code to determine if the check reports on individual resources or aggregated resources: + - **Singular**: Use when the check creates one report per resource (e.g., "EC2 instance has IMDSv2 enforced", "S3 bucket does not allow public write access"). + - **Plural**: Use when the check creates one report for all resources together (e.g., "All EC2 instances have IMDSv2 enforced", "S3 buckets do not allow public write access"). +2. **Describe the Compliant (*PASS*) State**: + Always write the title to describe the **desired, compliant state** of the resources. The title should reflect what it looks like when the audited resource is following the check's requirements. +3. **Be Specific and Factual**: + Include the exact secure configuration being verified. Avoid vague or generic terms like "properly configured". +4. **Avoid Redundant or Action Words**: + Do not include verbs like "Check", "Verify", "Ensure", or "Monitor". The title is a declarative statement of the secure condition. +5. **Length Limit**: + Keep the title under 150 characters. + +### Common Mistakes to Avoid + +- Starting with verbs like "Check", "Verify", "Ensure", "Make sure". Always start with the affected resource instead. +- Being too vague or generic (e.g., "Ensure security groups are properly configured", what does it mean? "properly configured" is not a clear description of the compliant state). +- Focusing on the non-compliant state instead of the compliant state. +- Using unclear scope and resource identification. + +## Check Type Guidelines (AWS Only) + +### AWS Security Hub Type Format + +AWS Security Hub uses a three-part type taxonomy: + +- **Namespace**: The top-level security domain. +- **Category**: The security control family or area. +- **Classifier**: The specific security concern (optional). + +A partial path may be defined (e.g., `TTPs` or `TTPs/Defense Evasion` are valid). + +### Selection Guidelines + +1. **Be Specific**: Use the most specific classifier that accurately describes the check. +2. **Standard Compliance**: Consider if the check relates to specific compliance standards. +3. **Multiple Types**: You can specify multiple types if the check addresses multiple concerns. + +## Description Guidelines + +### Writing Guidelines + +1. **Focus on the Finding**: All fields should address how the finding affects the security posture, rather than the control itself. +2. **Use Natural Language**: Write in simple, clear paragraphs with complete, grammatically correct sentences. +3. **Use Markdown Formatting**: Enhance readability with: + - Use **bold** for emphasis on key security concepts. + - Use *italic* for a secondary emphasis. Use it for clarifications, conditions, or optional notes. But don't abuse it. + - Use `code` formatting for specific configuration values, or technical details. Don't use it for service names or common technical terms. + - Use one or two line breaks (`\n` or `\n\n`) to separate distinct ideas. + - Use bullet points (`-`) for listing multiple concepts or actions. + - Use numbers for listing steps or sequential actions. +4. **Be Concise**: Maximum 400 characters (spaces count). Every word should add value. +5. **Explain What the Finding Means**: Focus on what the security control evaluates and what it means when it passes or fails, but without explicitly stating the pass or fail state. +6. **Be Technical but Clear**: Use appropriate technical terminology while remaining understandable. +7. **Avoid Risk Descriptions**: Do not describe potential risks, threats, or consequences. +8. **CheckTitle and Description can be the same**: If the check is very simple and the title is already clear, you can use the same text for the description. + +### Common Mistakes to Avoid + +- **Technical Implementation Details**: "The control loops through all instances and calls the describe_instances API...". +- **Vague Descriptions**: "This control verifies proper configuration of resources". What does it mean? "proper configuration" is not a clear description of the compliant state. +- **Risk Descriptions**: "This could lead to data breaches" or "This poses a security threat". +- **Starting with Verbs**: "Check if...", "Verify...", "Ensure...". Always start with the affected resource instead. +- **References to Pass/Fail States**: Avoid using words like "pass" or "fail". + +## Risk Guidelines + +### Writing Guidelines + +1. **Explain the Cybersecurity Impact**: Focus on how the finding affects confidentiality, integrity, or availability (CIA triad). If the CIA triad does not apply, explain the risk in terms of the organization's business objectives. +2. **Be Specific About Threats**: Clearly state what could happen if this security control is not in place. What attacks or incidents become possible? +3. **Focus on Risk Context**: Explain the specific security implications of the finding, not just generic security risks. +4. **Use Markdown Formatting**: Enhance readability with markdown formatting: + - Use **bold** for emphasis on key security concepts. + - Use *italic* for a secondary emphasis. Use it for clarifications, conditions, or optional notes. But don't abuse it. + - Use `code` formatting for specific configuration values, or technical details. Don't use it for service names or common technical terms. + - Use one or two line breaks (`\n` or `\n\n`) to separate distinct ideas. + - Use bullet points (`-`) for listing multiple concepts or actions. + - Use numbers for listing steps or sequential actions. +5. **Be Concise**: Maximum 400 characters. Make every word count. + +### Common Mistakes to Avoid + +- **Generic Risks**: "This could lead to security issues" or "Regulatory compliance violations". +- **Technical Implementation Focus**: "The API call might fail and return incorrect results...". +- **Overly Broad Statements**: "This is a serious security risk that could impact everything". +- **Vague Threats**: "This could be exploited by threat actors" without explaining how. + +## Recommendation Guidelines + +### Writing Guidelines + +1. **Provide Actionable Best Practice Guidance**: Explain what should be done to maintain security posture. Focus on preventive measures and proactive security practices. +2. **Be Principle-Based**: Reference established security principles (least privilege, defense in depth, zero trust, separation of duties) where applicable. +3. **Focus on Prevention**: Explain best practices that prevent the security issue from occurring, not just detection or remediation. +4. **Use Markdown Formatting**: Enhance readability with markdown formatting: + - Use **bold** for emphasis on key security concepts. + - Use *italic* for a secondary emphasis. Use it for clarifications, conditions, or optional notes. But don't abuse it. + - Use `code` formatting for specific configuration values, or technical details. Don't use it for service names or common technical terms. + - Use one or two line breaks (`\n` or `\n\n`) to separate distinct ideas. + - Use bullet points (`-`) for listing multiple concepts or actions. + - Use numbers for listing steps or sequential actions. +5. **Be Concise**: Maximum 400 characters. + +### Common Mistakes to Avoid + +- **Specific Remediation Steps**: "1. Go to the console\n2. Click on settings..." - Focus on principles, not click-by-click instructions. +- **Implementation Details**: "Configure the JSON policy with the following IAM actions..." - Explain what to achieve, not how. +- **Vague Guidance**: "Follow security best practices..." without explaining what those practices are. +- **Resource-Specific Recommendations**: "Enable MFA on user john.doe@example.com" - Keep it general. +- **Missing Context**: Not explaining why the best practice is important for security. + +### Good Examples + +- *"Avoid exposing sensitive resources directly to the Internet; configure access controls to limit exposure."* +- *"Apply the principle of least privilege when assigning permissions to users and services."* +- *"Regularly review and update your security configurations to align with current best practices."* + +## Remediation Code Guidelines + +### Critical Requirement + +The **fundamental principle** is to focus on the **specific change** that converts the finding from non-compliant to compliant. + +Also is important to keep all code examples as short as possible, including the essential code to fix the issue. Remove any extra configuration, optional parameters, or nice-to-have settings and add comments to explain the code when possible. + +### Common Guidelines for All Code Fields + +1. **Be Minimal**: Keep code blocks as short as possible - only include what is absolutely necessary. +2. **Focus on the Fix**: Remove any extra configuration, optional parameters, or nice-to-have settings. +3. **Be Accurate**: Ensure all commands and code are syntactically correct. +4. **Use Markdown Formatting**: Format code properly using code blocks and appropriate syntax highlighting. +5. **Follow Best Practices**: Use the most secure and recommended approaches for each platform. + +### CLI Guidelines + +- Only provide a single command that directly changes the finding from fail to pass. +- The command must be executable as-is and resolve the security issue completely. +- Use proper command syntax for the provider (AWS CLI, Azure CLI, gcloud, kubectl, etc.). +- Do not use markdown formatting or code blocks - just the raw command. +- Do not include multiple commands, comments, or explanations. +- If the issue cannot be resolved with a single command, leave this field empty. + +### Native IaC Guidelines + +- **Keep It Minimal**: Only include the specific resource/configuration that fixes the security issue. +- Format as markdown code blocks with proper syntax highlighting. +- Include only the required properties to fix the issue. +- Add comments indicating the critical line(s) that remediate the check. +- Use `example_resource` as the generic name for all resources and IDs. + +### Terraform Guidelines + +- **Keep It Minimal**: Only include the specific resource/configuration that fixes the security issue. +- Provide valid HCL (HashiCorp Configuration Language) code with an example of a compliant configuration. +- Use the latest Terraform syntax and provider versions. +- Include only the required arguments to fix the issue - skip optional parameters. +- Format as markdown code blocks with `hcl` syntax highlighting. +- Add comments indicating the critical line(s) that remediate the check. +- Use `example_resource` as the generic name for all resources and IDs. +- Skip provider requirements unless critical for the fix. + +### Other (Manual Steps) Guidelines + +- **Keep It Minimal**: Only include the exact steps needed to fix the security issue. +- Provide step-by-step instructions for manual remediation through web interfaces. +- Use numbered lists for sequential steps. +- Be specific about menu locations, button names, and settings. +- Skip optional configurations or nice-to-have settings. +- Format using markdown for better readability. + +## Categories Guidelines + +### Selection Guidelines + +1. **Be Specific**: Only select categories that directly relate to what the automated control evaluates. +2. **Primary Focus**: Consider the primary security concern the automated control addresses. +3. **Avoid Over-Categorization**: Do not select categories just because they are tangentially related. + +### Available Categories + +| Category | Definition | +|-------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| encryption | Ensures data is encrypted in transit and/or at rest, including key management practices | +| internet-exposed | Checks that limit or flag public access to services, APIs, or assets from the Internet | +| logging | Ensures appropriate logging of events, activities, and system interactions for traceability | +| secrets | Manages and protects credentials, API keys, tokens, and other sensitive information | +| resilience | Ensures systems can maintain availability and recover from disruptions, failures, or degradation. Includes redundancy, fault-tolerance, auto-scaling, backup, disaster recovery, and failover strategies | +| threat-detection | Identifies suspicious activity or behaviors using IDS, malware scanning, or anomaly detection | +| trust-boundaries | Enforces isolation or segmentation between different trust levels (e.g., VPCs, tenants, network zones) | +| vulnerabilities | Detects or remediates known software, infrastructure, or config vulnerabilities (e.g., CVEs) | +| cluster-security | Secures Kubernetes cluster components such as API server, etcd, and role-based access | +| container-security | Ensures container images and runtimes follow security best practices | +| node-security | Secures nodes running containers or services | +| gen-ai | Checks related to safe and secure use of generative AI services or models | +| ci-cd | Ensures secure configurations in CI/CD pipelines | +| identity-access | Governs user and service identities, including least privilege, MFA, and permission boundaries | +| email-security | Ensures detection and protection against phishing, spam, spoofing, etc. | +| forensics-ready | Ensures systems are instrumented to support post-incident investigations. Any digital trace or evidence (logs, volume snapshots, memory dumps, network captures, etc.) preserved immutably and accompanied by integrity guarantees, which can be used in a forensic analysis | +| software-supply-chain | Detects or prevents tampering, unauthorized packages, or third-party risks in software supply chain | +| e3 | M365-specific controls enabled by or dependent on an E3 license (e.g., baseline security policies, conditional access) | +| e5 | M365-specific controls enabled by or dependent on an E5 license (e.g., advanced threat protection, audit, DLP, and eDiscovery) | diff --git a/docs/developer-guide/checks.md b/docs/developer-guide/checks.mdx similarity index 60% rename from docs/developer-guide/checks.md rename to docs/developer-guide/checks.mdx index 6f760eb558..7a86686071 100644 --- a/docs/developer-guide/checks.md +++ b/docs/developer-guide/checks.mdx @@ -1,4 +1,6 @@ -# Prowler Checks +--- +title: 'Prowler Checks' +--- This guide explains how to create new checks in Prowler. @@ -12,7 +14,7 @@ The most common high level steps to create a new check are: 1. Prerequisites: - Verify the check does not already exist by searching [Prowler Hub](https://hub.prowler.com) or checking `prowler/providers//services///`. - - Ensure required provider and service exist. If not, follow the [Provider](./provider.md) and [Service](./services.md) documentation to create them. + - Ensure required provider and service exist. If not, follow the [Provider](/developer-guide/provider) and [Service](/developer-guide/services) documentation to create them. - Confirm the service has implemented all required methods and attributes for the check (in most cases, you will need to add or modify some methods in the service to get the data you need for the check). 2. Navigate to the service directory. The path should be as follows: `prowler/providers//services/`. 3. Create a check-specific folder. The path should follow this pattern: `prowler/providers//services//`. Adhere to the [Naming Format for Checks](#naming-format-for-checks). @@ -20,7 +22,7 @@ The most common high level steps to create a new check are: 5. Run the check locally to ensure it works as expected. For checking you can use the CLI in the next way: - To ensure the check has been detected by Prowler: `poetry run python prowler-cli.py --list-checks | grep `. - To run the check, to find possible issues: `poetry run python prowler-cli.py --log-level ERROR --verbose --check `. -6. Create comprehensive tests for the check that cover multiple scenarios including both PASS (compliant) and FAIL (non-compliant) cases. For detailed information about test structure and implementation guidelines, refer to the [Testing](./unit-testing.md) documentation. +6. Create comprehensive tests for the check that cover multiple scenarios including both PASS (compliant) and FAIL (non-compliant) cases. For detailed information about test structure and implementation guidelines, refer to the [Testing](/developer-guide/unit-testing) documentation. 7. If the check and its corresponding tests are working as expected, you can submit a PR to Prowler. ### Naming Format for Checks @@ -39,8 +41,8 @@ The name components are: Each check in Prowler follows a straightforward structure. Within the newly created folder, three files must be added to implement the check logic: - `__init__.py` (empty file) – Ensures Python treats the check folder as a package. -- `.py` (code file) – Contains the check logic, following the prescribed format. Please refer to the [prowler's check code structure](./checks.md#prowlers-check-code-structure) for more information. -- `.metadata.json` (metadata file) – Defines the check's metadata for contextual information. Please refer to the [check metadata](./checks.md#) for more information. +- `.py` (code file) – Contains the check logic, following the prescribed format. Please refer to the [prowler's check code structure](/developer-guide/checks#prowlers-check-code-structure) for more information. +- `.metadata.json` (metadata file) – Defines the check's metadata for contextual information. Please refer to the [check metadata](/developer-guide/checks#metadata-structure-for-prowler-checks) for more information. ## Prowler's Check Code Structure @@ -50,9 +52,10 @@ Below the code for a generic check is presented. It is strongly recommended to c Report fields are the most dependent on the provider, consult the `CheckReport` class for more information on what can be included in the report [here](https://github.com/prowler-cloud/prowler/blob/master/prowler/lib/check/models.py). -???+ note - Legacy providers (AWS, Azure, GCP, Kubernetes) follow the `Check_Report_` naming convention. This is not recommended for current instances. Newer providers adopt the `CheckReport` naming convention. Learn more at [Prowler Code](https://github.com/prowler-cloud/prowler/tree/master/prowler/lib/check/models.py). + +Legacy providers (AWS, Azure, GCP, Kubernetes) follow the `Check_Report_` naming convention. This is not recommended for current instances. Newer providers adopt the `CheckReport` naming convention. Learn more at [Prowler Code](https://github.com/prowler-cloud/prowler/tree/master/prowler/lib/check/models.py). + ```python title="Generic Check Class" # Required Imports # Import the base Check class and the provider-specific CheckReport class @@ -122,11 +125,11 @@ Each check **must** populate the `report.status` and `report.status_extended` fi The severity of each check is defined in the metadata file using the `Severity` field. Severity values are always lowercase and must be one of the predefined categories below. -- `critical` – Issue that must be addressed immediately. -- `high` – Issue that should be addressed as soon as possible. -- `medium` – Issue that should be addressed within a reasonable timeframe. -- `low` – Issue that can be addressed in the future. -- `informational` – Not an issue but provides valuable information. +- `critical` – Highest potential impact with broad exposure that could affect core security boundaries or business operations. +- `high` – Substantial potential impact with significant exposure that could affect important security controls or resources. +- `medium` – Moderate potential impact with limited exposure that weakens defense layers but has contained scope. +- `low` – Minimal potential impact with negligible exposure that represents minor gaps in security posture. +- `informational` – Provides valuable information but does not affect the security posture. If the check involves multiple scenarios that may alter its severity, adjustments can be made dynamically within the check's logic using the severity `report.check_metadata.Severity` attribute: @@ -213,7 +216,7 @@ Each check **must** populate the report with an unique identifier for the audite ### Configurable Checks in Prowler -See [Configurable Checks](./configurable-checks.md) for detailed information on making checks configurable using the `audit_config` object and configuration file. +See [Configurable Checks](/developer-guide/configurable-checks) for detailed information on making checks configurable using the `audit_config` object and configuration file. ## Metadata Structure for Prowler Checks @@ -226,68 +229,150 @@ Below is a generic example of a check metadata file. **Do not include comments i ```json { "Provider": "aws", - "CheckID": "example_check_id", - "CheckTitle": "Example Check Title", - "CheckType": ["Infrastructure Security"], - "ServiceName": "ec2", - "SubServiceName": "ami", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", - "Severity": "critical", + "CheckID": "service_resource_security_setting", + "CheckTitle": "Service resource has security setting enabled", + "CheckType": [], + "ServiceName": "service", + "SubServiceName": "", + "ResourceIdTemplate": "", + "Severity": "medium", "ResourceType": "Other", - "Description": "Example description of the check.", - "Risk": "Example risk if the check fails.", - "RelatedUrl": "https://example.com", + "Description": "This check verifies that the service resource has the required **security setting** enabled to protect against potential vulnerabilities.\n\nIt ensures that the resource follows security best practices and maintains proper access controls. The check evaluates whether the security configuration is properly implemented and active.", + "Risk": "Without proper security settings, the resource may be vulnerable to:\n\n- **Unauthorized access** - Malicious actors could gain entry\n- **Data breaches** - Sensitive information could be compromised\n- **Security threats** - Various attack vectors could be exploited\n\nThis could result in compliance violations and potential financial or reputational damage.", + "RelatedUrl": "", + "AdditionalURLs": ["https://example.com/security-documentation", "https://example.com/best-practices"], "Remediation": { "Code": { - "CLI": "example CLI command", - "NativeIaC": "", - "Other": "", - "Terraform": "" + "CLI": "provider-cli service enable-security-setting --resource-id resource-123", + "NativeIaC": "```yaml\nType: Provider::Service::Resource\nProperties:\n SecuritySetting: enabled\n ResourceId: resource-123\n```", + "Other": "1. Open the provider management console\n2. Navigate to the service section\n3. Select the resource\n4. Enable the security setting\n5. Save the configuration", + "Terraform": "```hcl\nresource \"provider_service_resource\" \"example\" {\n resource_id = \"resource-123\"\n security_setting = true\n}\n```" }, "Recommendation": { - "Text": "Example recommendation text.", - "Url": "https://example.com/remediation" + "Text": "Enable security settings on all service resources to ensure proper protection. Regularly review and update security configurations to align with current best practices.", + "Url": "https://hub.prowler.com/check/service_resource_security_setting" } }, - "Categories": ["example-category"], + "Categories": ["internet-exposed", "secrets"], "DependsOn": [], - "RelatedTo": [], - "Notes": "" + "RelatedTo": ["service_resource_security_setting", "service_resource_security_setting_2"], + "Notes": "This is a generic example check that should be customized for specific provider and service requirements." } ``` ### Metadata Fields and Their Purpose -- **Provider** — The Prowler provider related to the check. The name **must** be lowercase and match the provider folder name. For supported providers refer to [Prowler Hub](https://hub.prowler.com/check) or directly to [Prowler Code](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers). -- **CheckID** — The unique identifier for the check inside the provider, this field **must** match the check's folder and python file and json metadata file name. For more information about the naming refer to the [Naming Format for Checks](#naming-format-for-checks) section. -- **CheckTitle** — A concise, descriptive title for the check. -- **CheckType** — *For now this field is only standardized for the AWS provider*. - - For AWS this field must follow the [AWS Security Hub Types](https://docs.aws.amazon.com/securityhub/latest/userguide/asff-required-attributes.html#Types) format. So the common pattern to follow is `namespace/category/classifier`, refer to the attached documentation for the valid values for this fields. -- **ServiceName** — The name of the provider service being audited. This field **must** be in lowercase and match with the service folder name. For supported services refer to [Prowler Hub](https://hub.prowler.com/check) or directly to [Prowler Code](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers). -- **SubServiceName** — The subservice or resource within the service, if applicable. For more information refer to the [Naming Format for Checks](#naming-format-for-checks) section. -- **ResourceIdTemplate** — A template for the unique resource identifier. For more information refer to the [Resource Identification in Prowler](#resource-identification-in-prowler) section. -- **Severity** — The severity of the finding if the check fails. Must be one of: `critical`, `high`, `medium`, `low`, or `informational`, this field **must** be in lowercase. To get more information about the severity levels refer to the [Prowler's Check Severity Levels](#prowlers-check-severity-levels) section. -- **ResourceType** — The type of resource being audited. *For now this field is only standardized for the AWS provider*. - - For AWS use the [Security Hub resource types](https://docs.aws.amazon.com/securityhub/latest/userguide/asff-resources.html) or, if not available, the PascalCase version of the [CloudFormation type](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html) (e.g., `AwsEc2Instance`). Use "Other" if no match exists. -- **Description** — A short description of what the check does. -- **Risk** — The risk or impact if the check fails, explaining why the finding matters. -- **RelatedUrl** — A URL to official documentation or further reading about the check's purpose. If no official documentation is available, use the risk and recommendation text from trusted third-party sources. -- **Remediation** — Guidance for fixing a failed check, including: - - **Code** — Remediation commands or code snippets for CLI, Terraform, native IaC, or other tools like the Web Console. - - **Recommendation** — A textual human readable recommendation. Here it is not necessary to include actual steps, but rather a general recommendation about what to do to fix the check. -- **Categories** — One or more categories for grouping checks in execution (e.g., `internet-exposed`). For the current list of categories, refer to the [Prowler Hub](https://hub.prowler.com/check). -- **DependsOn** — Currently not used. -- **RelatedTo** — Currently not used. -- **Notes** — Any additional information not covered by other fields. +#### Provider -### Remediation Code Guidelines +The Prowler provider related to the check. The name **must** be lowercase and match the provider folder name. For supported providers refer to [Prowler Hub](https://hub.prowler.com/check) or directly to [Prowler Code](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers). -When providing remediation steps, reference the following sources: +#### CheckID -- Official provider documentation. -- [Prowler Checks Remediation Index](https://docs.prowler.com/checks/checks-index) -- [TrendMicro Cloud One Conformity](https://www.trendmicro.com/cloudoneconformity) -- [CloudMatos Remediation Repository](https://github.com/cloudmatos/matos/tree/master/remediations) +The unique identifier for the check inside the provider. This field **must** match the check's folder, Python file, and JSON metadata file name. For more information about naming, refer to the [Naming Format for Checks](#naming-format-for-checks) section. + +#### CheckTitle + +The `CheckTitle` field must be plain text, clearly and succinctly define **the best practice being evaluated and which resource(s) each finding applies to**. The title should be specific, concise (no more than 150 characters), and reference the relevant resource(s) involved. + +**Always write the `CheckTitle` to describe the *PASS* case**, the desired secure or compliant state of the resource(s). This helps ensure that findings are easy to interpret and that the title always reflects the best practice being met. + +For detailed guidelines on writing effective check titles, including how to determine singular vs. plural scope and common mistakes to avoid, see [Check Title Guidelines](/developer-guide/check-metadata-guidelines#check-title-guidelines). + +#### CheckType + + +This field is only applicable to the AWS provider. + + +It follows the [AWS Security Hub Types](https://docs.aws.amazon.com/securityhub/latest/userguide/asff-required-attributes.html#Types) format using the pattern `namespace/category/classifier`. + +For the complete AWS Security Hub selection guidelines, see [Check Type Guidelines](/developer-guide/check-metadata-guidelines#check-type-guidelines-aws-only). + +#### ServiceName + +The name of the provider service being audited. Must be lowercase and match the service folder name. For supported services refer to [Prowler Hub](https://hub.prowler.com/check) or the [Prowler Code](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers). + +#### SubServiceName + +This field is in the process of being deprecated and should be **left empty**. + +#### ResourceIdTemplate + +This field is in the process of being deprecated and should be **left empty**. + +#### Severity + +Severity level if the check fails. Must be one of: `critical`, `high`, `medium`, `low`, or `informational`, and written in lowercase. See [Prowler's Check Severity Levels](#prowlers-check-severity-levels) for details. + +#### ResourceType + +The type of resource being audited. This field helps categorize and organize findings by resource type for better analysis and reporting. For each provider: + +- **AWS**: Use [Security Hub resource types](https://docs.aws.amazon.com/securityhub/latest/userguide/asff-resources.html) or PascalCase CloudFormation types removing the `::` separator used in CloudFormation templates (e.g., in CloudFormation template the type of an EC2 instance is `AWS::EC2::Instance` but in the check it should be `AwsEc2Instance`). Use `Other` if none apply. +- **Azure**: Use types from [Azure Resource Graph](https://learn.microsoft.com/en-us/azure/governance/resource-graph/reference/supported-tables-resources), for example: `Microsoft.Storage/storageAccounts`. +- **Google Cloud**: Use [Cloud Asset Inventory asset types](https://cloud.google.com/asset-inventory/docs/asset-types), for example: `compute.googleapis.com/Instance`. +- **Kubernetes**: Use types shown under `KIND` from `kubectl api-resources`. +- **M365 / GitHub**: Leave empty due to lack of standardized types. + +#### Description + +A concise, natural language explanation that **clearly describes what the finding means**, focusing on clarity and context rather than technical implementation details. Use simple paragraphs with line breaks if needed, but avoid sections, code blocks, or complex formatting. This field is limited to maximum 400 characters. + +For detailed writing guidelines and common mistakes to avoid, see [Description Guidelines](/developer-guide/check-metadata-guidelines#description-guidelines). + +#### Risk + +A clear, natural language explanation of **why this finding poses a cybersecurity risk**. Focus on how it may impact confidentiality, integrity, or availability. If those do not apply, describe any relevant operational or financial risks. Use simple paragraphs with line breaks if needed, but avoid sections, code blocks, or complex formatting. Limit your explanation to 400 characters. + +For detailed writing guidelines and common mistakes to avoid, see [Risk Guidelines](/developer-guide/check-metadata-guidelines#risk-guidelines). + +#### RelatedUrl + +*Deprecated*. Use `AdditionalURLs` for adding your URLs references. + +#### AdditionalURLs + + +URLs must be valid and not repeated. + + +A list of official documentation URLs for further reading. These should be authoritative sources that provide additional context, best practices, or detailed information about the security control being checked. Prefer official provider documentation, security standards, or well-established security resources. Avoid third-party blogs or unofficial sources unless they are highly reputable and directly relevant. + +#### Remediation + +Provides both code examples and best practice recommendations for addressing the security issue. + +- **Code**: Contains remediation examples in different formats: + - **CLI**: Command-line interface commands to make the finding compliant in runtime. + - **NativeIaC**: Native Infrastructure as Code templates with an example of a compliant configuration. For now it applies to: + - **AWS**: CloudFormation YAML formatted code (do not use JSON format). + - **Azure**: Bicep formatted code (do not use ARM templates). + - **Terraform**: HashiCorp Configuration Language (HCL) code with an example of a compliant configuration. + - **Other**: Manual steps through web interfaces or other tools to make the finding compliant. + + For detailed guidelines on writing remediation code, see [Remediation Code Guidelines](/developer-guide/check-metadata-guidelines#remediation-code-guidelines). + +- **Recommendation** + - **Text**: Generic best practice guidance in natural language using Markdown format (maximum 400 characters). For writing guidelines, see [Recommendation Guidelines](/developer-guide/check-metadata-guidelines#recommendation-guidelines). + - **Url**: [Prowler Hub URL](https://hub.prowler.com/) of the check. This URL is always composed by `https://hub.prowler.com/check/`. + +#### Categories + +One or more functional groupings used for execution filtering (e.g., `internet-exposed`). You can define new categories just by adding to this field. + +For the complete list of available categories, see [Categories Guidelines](/developer-guide/check-metadata-guidelines#categories-guidelines). + +#### DependsOn + +List of check IDs of checks that if are compliant, this check will be a compliant too or it is not going to give any finding. + +#### RelatedTo + +List of check IDs of checks that are conceptually related, even if they do not share a technical dependency. + +#### Notes + +Any additional information not covered in the above fields. ### Python Model Reference diff --git a/docs/developer-guide/configurable-checks.md b/docs/developer-guide/configurable-checks.mdx similarity index 94% rename from docs/developer-guide/configurable-checks.md rename to docs/developer-guide/configurable-checks.mdx index aad072ddd5..76b339601d 100644 --- a/docs/developer-guide/configurable-checks.md +++ b/docs/developer-guide/configurable-checks.mdx @@ -1,4 +1,6 @@ -# Configurable Checks in Prowler +--- +title: 'Configurable Checks in Prowler' +--- Prowler empowers users to extend and adapt cloud security coverage by making checks configurable through the use of the `audit_config` object. This approach enables customization of checks to meet specific requirements through a configuration file. @@ -41,6 +43,6 @@ When adding a new configurable check to Prowler, update the following files: - **Test Fixtures:** If tests depend on this configuration, add the variable to `tests/config/fixtures/config.yaml`. - **Documentation:** Document the new variable in the list of configurable checks in `docs/tutorials/configuration_file.md`. -For a complete list of checks that already support configuration, see the [Configuration File Tutorial](../tutorials/configuration_file.md). +For a complete list of checks that already support configuration, see the [Configuration File Tutorial](/user-guide/cli/tutorials/configuration_file). This approach ensures that checks are easily configurable, making Prowler highly adaptable to different environments and requirements. diff --git a/docs/developer-guide/debugging.md b/docs/developer-guide/debugging.mdx similarity index 98% rename from docs/developer-guide/debugging.md rename to docs/developer-guide/debugging.mdx index a323ec0187..647b23c614 100644 --- a/docs/developer-guide/debugging.md +++ b/docs/developer-guide/debugging.mdx @@ -1,4 +1,6 @@ -# Debugging in Prowler +--- +title: 'Debugging in Prowler' +--- Debugging in Prowler simplifies the development process, allowing developers to efficiently inspect and resolve unexpected issues during execution. diff --git a/docs/developer-guide/documentation.md b/docs/developer-guide/documentation.md deleted file mode 100644 index 50ac0956e7..0000000000 --- a/docs/developer-guide/documentation.md +++ /dev/null @@ -1,28 +0,0 @@ -## Contributing to Documentation - -Prowler documentation is built using `mkdocs`, allowing contributors to easily add or enhance documentation. - -### Installation and Setup - -Install all necessary dependencies using: `poetry install --with docs`. - -1. Install `mkdocs` using your preferred package manager. - -2. Running the Documentation Locally -Navigate to the `prowler` repository folder. -Start the local documentation server by running: `mkdocs serve`. -Open `http://localhost:8000` in your browser to view live updates. - -3. Making Documentation Changes -Make all needed changes to docs or add new documents. Edit existing Markdown (.md) files inside `prowler/docs`. -To add new sections or files, update the `mkdocs.yaml` file located in the root directory of Prowler’s repository. - -4. Submitting Changes - -Once documentation updates are complete: - -Submit a pull request for review. - -The Prowler team will assess and merge contributions. - -Your efforts help improve Prowler documentation—thank you for contributing! diff --git a/docs/developer-guide/documentation.mdx b/docs/developer-guide/documentation.mdx new file mode 100644 index 0000000000..f1fae30d35 --- /dev/null +++ b/docs/developer-guide/documentation.mdx @@ -0,0 +1,61 @@ +--- +title: 'Contributing to Documentation' +--- + +Prowler documentation is built using [Mintlify](https://www.mintlify.com/docs), allowing contributors to easily add or enhance documentation. + +## Documentation Structure + +The Prowler documentation is organized into several sections. The main ones are: + +- **Getting Started**: Provides an overview of the Prowler platform and its different solutions, including Prowler Cloud/App, Prowler CLI, Prowler MCP Server, Prowler Hub, and Prowler Lighthouse AI. This section helps new users understand which Prowler solution best fits their needs and includes product comparisons. + +- **Guides**: Contains practical tutorials and how-to guides organized by product (Prowler Cloud/App, CLI) and provider (AWS, Azure, GCP, Kubernetes, Microsoft 365, GitHub, etc.). This section covers authentication, integrations, compliance, and advanced usage scenarios. + +- **Developer Guide**: Documentation for contributors looking to extend Prowler functionality. This includes guides on creating providers, services, checks, output formats, integrations, and compliance frameworks. Provider-specific implementation details and testing strategies are also covered here. + +- **Troubleshooting**: Common issues, error messages, and their solutions. This section helps users resolve problems encountered during installation, configuration, or execution. + + +## AI-Driven Documentation + +As mentioned in the [Introduction](/developer-guide/introduction#ai-driven-contributions), we have specialized resources to enhance AI-driven development. + +This includes the [AGENTS.md](https://github.com/prowler-cloud/prowler/blob/master/docs/AGENTS.md) file that contains the guidelines and style guide for the AI agents in the Prowler documentation. + +## Local Development + + + + ```bash + npm i -g mint + ``` + For detailed instructions, check the [Mintlify documentation](https://www.mintlify.com/docs/installation). + + + + Start the local development server to preview changes in real-time. + + ```bash + mint dev + ``` + + A local preview of your documentation will be available at http://localhost:3000 + + + + Edit existing Markdown (.mdx) files inside the `docs` directory or add new documents. + + For reference about formatting, check the [Mintlify documentation](https://www.mintlify.com/docs/create/text). + + To add new sections or files, update the [`docs/docs.json`](https://github.com/prowler-cloud/prowler/blob/master/docs/docs.json) file to include them in the navigation. + + + + Once documentation updates are complete, [submit a pull request for review](/developer-guide/introduction#sending-the-pull-request). + + The Prowler team will assess and merge contributions. + + + +Your efforts help improve Prowler documentation. Thank you for contributing! 🤘 diff --git a/docs/developer-guide/gcp-details.md b/docs/developer-guide/gcp-details.mdx similarity index 88% rename from docs/developer-guide/gcp-details.md rename to docs/developer-guide/gcp-details.mdx index dc13958a05..6011b784c9 100644 --- a/docs/developer-guide/gcp-details.md +++ b/docs/developer-guide/gcp-details.mdx @@ -1,12 +1,14 @@ -# Google Cloud Provider +--- +title: 'Google Cloud Provider' +--- This page details the [Google Cloud Platform (GCP)](https://cloud.google.com/) provider implementation in Prowler. -By default, Prowler will audit all the GCP projects that the authenticated identity can access. To configure it, follow the [GCP getting started guide](../tutorials/gcp/getting-started-gcp.md). +By default, Prowler will audit all the GCP projects that the authenticated identity can access. To configure it, follow the [GCP getting started guide](/user-guide/providers/gcp/getting-started-gcp). ## GCP Provider Classes Architecture -The GCP provider implementation follows the general [Provider structure](./provider.md). This section focuses on the GCP-specific implementation, highlighting how the generic provider concepts are realized for GCP in Prowler. For a full overview of the provider pattern, base classes, and extension guidelines, see [Provider documentation](./provider.md). +The GCP provider implementation follows the general [Provider structure](/developer-guide/provider). This section focuses on the GCP-specific implementation, highlighting how the generic provider concepts are realized for GCP in Prowler. For a full overview of the provider pattern, base classes, and extension guidelines, see [Provider documentation](/developer-guide/provider). ### Main Class @@ -32,7 +34,7 @@ The GCP provider implementation follows the general [Provider structure](./provi ### `GCPService` (Service Base Class) - **Location:** [`prowler/providers/gcp/lib/service/service.py`](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/gcp/lib/service/service.py) -- **Purpose:** Abstract base class that all GCP service-specific classes inherit from. This implements the generic service pattern (described in [service page](./services.md#service-base-class)) specifically for GCP. +- **Purpose:** Abstract base class that all GCP service-specific classes inherit from. This implements the generic service pattern (described in [service page](/developer-guide/services#service-base-class)) specifically for GCP. - **Key GCP Responsibilities:** - Receives a `GcpProvider` instance to access session, identity, and configuration. - Manages clients for all services by project. @@ -95,12 +97,12 @@ def _get_instances(self): ## Specific Patterns in GCP Services -The generic service pattern is described in [service page](./services.md#service-structure-and-initialisation). You can find all the currently implemented services in the following locations: +The generic service pattern is described in [service page](/developer-guide/services#service-structure-and-initialisation). You can find all the currently implemented services in the following locations: - Directly in the code, in location [`prowler/providers/gcp/services/`](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers/gcp/services) - In the [Prowler Hub](https://hub.prowler.com/) for a more human-readable view. -The best reference to understand how to implement a new service is following the [service implementation documentation](./services.md#adding-a-new-service) and taking other services already implemented as reference. In next subsection you can find a list of common patterns that are used accross all GCP services. +The best reference to understand how to implement a new service is following the [service implementation documentation](/developer-guide/services#adding-a-new-service) and taking other services already implemented as reference. In next subsection you can find a list of common patterns that are used accross all GCP services. ### GCP Service Common Patterns @@ -117,12 +119,12 @@ The best reference to understand how to implement a new service is following the ## Specific Patterns in GCP Checks -The GCP checks pattern is described in [checks page](./checks.md). You can find all the currently implemented checks: +The GCP checks pattern is described in [checks page](/developer-guide/checks). You can find all the currently implemented checks: - Directly in the code, within each service folder, each check has its own folder named after the name of the check. (e.g. [`prowler/providers/gcp/services/iam/iam_sa_user_managed_key_unused/`](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers/gcp/services/iam/iam_sa_user_managed_key_unused)) - In the [Prowler Hub](https://hub.prowler.com/) for a more human-readable view. -The best reference to understand how to implement a new check is following the [GCP check implementation documentation](./checks.md#creating-a-check) and taking other similar checks as reference. +The best reference to understand how to implement a new check is following the [GCP check implementation documentation](/developer-guide/checks#creating-a-check) and taking other similar checks as reference. ### Check Report Class diff --git a/docs/developer-guide/github-details.md b/docs/developer-guide/github-details.mdx similarity index 86% rename from docs/developer-guide/github-details.md rename to docs/developer-guide/github-details.mdx index 97a1cffac3..1b5546cd16 100644 --- a/docs/developer-guide/github-details.md +++ b/docs/developer-guide/github-details.mdx @@ -1,12 +1,14 @@ -# GitHub Provider +--- +title: 'GitHub Provider' +--- This page details the [GitHub](https://github.com/) provider implementation in Prowler. -By default, Prowler will audit the GitHub account - scanning all repositories, organizations, and applications that your configured credentials can access. To configure it, follow the [GitHub getting started guide](../tutorials/github/getting-started-github.md). +By default, Prowler will audit the GitHub account - scanning all repositories, organizations, and applications that your configured credentials can access. To configure it, follow the [GitHub getting started guide](/user-guide/providers/github/getting-started-github). ## GitHub Provider Classes Architecture -The GitHub provider implementation follows the general [Provider structure](./provider.md). This section focuses on the GitHub-specific implementation, highlighting how the generic provider concepts are realized for GitHub in Prowler. For a full overview of the provider pattern, base classes, and extension guidelines, see [Provider documentation](./provider.md). +The GitHub provider implementation follows the general [Provider structure](/developer-guide/provider). This section focuses on the GitHub-specific implementation, highlighting how the generic provider concepts are realized for GitHub in Prowler. For a full overview of the provider pattern, base classes, and extension guidelines, see [Provider documentation](/developer-guide/provider). ### `GithubProvider` (Main Class) @@ -48,12 +50,12 @@ The GitHub provider implementation follows the general [Provider structure](./pr ## Specific Patterns in GitHub Services -The generic service pattern is described in [service page](./services.md#service-structure-and-initialisation). You can find all the currently implemented services in the following locations: +The generic service pattern is described in [service page](/developer-guide/services#service-structure-and-initialisation). You can find all the currently implemented services in the following locations: - Directly in the code, in location [`prowler/providers/github/services/`](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers/github/services) - In the [Prowler Hub](https://hub.prowler.com/) for a more human-readable view. -The best reference to understand how to implement a new service is following the [service implementation documentation](./services.md#adding-a-new-service) and by taking other already implemented services as reference. +The best reference to understand how to implement a new service is following the [service implementation documentation](/developer-guide/services#adding-a-new-service) and by taking other already implemented services as reference. ### GitHub Service Common Patterns @@ -66,12 +68,12 @@ The best reference to understand how to implement a new service is following the ## Specific Patterns in GitHub Checks -The GitHub checks pattern is described in [checks page](./checks.md). You can find all the currently implemented checks in: +The GitHub checks pattern is described in [checks page](/developer-guide/checks). You can find all the currently implemented checks in: - Directly in the code, within each service folder, each check has its own folder named after the name of the check. (e.g. [`prowler/providers/github/services/repository/repository_secret_scanning_enabled/`](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers/github/services/repository/repository_secret_scanning_enabled)) - In the [Prowler Hub](https://hub.prowler.com/) for a more human-readable view. -The best reference to understand how to implement a new check is the [GitHub check implementation documentation](./checks.md#creating-a-check) and by taking other checks as reference. +The best reference to understand how to implement a new check is the [GitHub check implementation documentation](/developer-guide/checks#creating-a-check) and by taking other checks as reference. ### Check Report Class diff --git a/docs/developer-guide/integration-testing.md b/docs/developer-guide/integration-testing.md deleted file mode 100644 index 0d03319c5e..0000000000 --- a/docs/developer-guide/integration-testing.md +++ /dev/null @@ -1,3 +0,0 @@ -# Integration Tests - -Coming soon ... \ No newline at end of file diff --git a/docs/developer-guide/integration-testing.mdx b/docs/developer-guide/integration-testing.mdx new file mode 100644 index 0000000000..e8f0f804f8 --- /dev/null +++ b/docs/developer-guide/integration-testing.mdx @@ -0,0 +1,5 @@ +--- +title: 'Integration Tests' +--- + +Coming soon ... diff --git a/docs/developer-guide/integrations.md b/docs/developer-guide/integrations.mdx similarity index 99% rename from docs/developer-guide/integrations.md rename to docs/developer-guide/integrations.mdx index e3f6789a8e..cb4b242d8c 100644 --- a/docs/developer-guide/integrations.md +++ b/docs/developer-guide/integrations.mdx @@ -1,4 +1,6 @@ -# Creating a New Integration +--- +title: 'Creating a New Integration' +--- ## Introduction @@ -151,7 +153,7 @@ Refer to the [Prowler Developer Guide](https://docs.prowler.com/projects/prowler # More properties and methods ``` - + * Test Connection Method: * Validating Credentials or Tokens diff --git a/docs/developer-guide/introduction.md b/docs/developer-guide/introduction.md deleted file mode 100644 index abc83fb682..0000000000 --- a/docs/developer-guide/introduction.md +++ /dev/null @@ -1,176 +0,0 @@ -# Introduction to developing in Prowler - -Extending Prowler - -Prowler can be extended in various ways, with common use cases including: - -- New security checks -- New compliance frameworks -- New output formats -- New integrations -- New proposed features - -All the relevant information for these cases is included in this guide. - -## Getting the Code and Installing All Dependencies - -### Prerequisites - -Before proceeding, ensure the following: - -- Git is installed. -- Python 3.9 or higher is installed. -- `poetry` is installed to manage dependencies. - -### Forking the Prowler Repository - -To contribute to Prowler, fork the Prowler GitHub repository. This allows you to propose changes, submit new features, and fix bugs. For guidance on forking, refer to the [official GitHub documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo?tool=webui#forking-a-repository). - -### Cloning Your Forked Repository - -Once your fork is created, clone it using the following commands: - -``` -git clone https://github.com//prowler -cd prowler -``` - -### Dependency Management and Environment Isolation - -To prevent conflicts between environments, we recommend using `poetry`, a Python dependency management solution. Install it by following the [instructions](https://python-poetry.org/docs/#installation). - -### Installing Dependencies - -To install all required dependencies, including those needed for development, run: - -``` -poetry install --with dev -eval $(poetry env activate) -``` - -???+ important - Starting from Poetry v2.0.0, `poetry shell` has been deprecated in favor of `poetry env activate`. - If your poetry version is below 2.0.0 you must keep using `poetry shell` to activate your environment. - In case you have any doubts, consult the [Poetry environment activation guide](https://python-poetry.org/docs/managing-environments/#activating-the-environment). - -## Contributing to Prowler - -### Ways to Contribute - -Here are some ideas for collaborating with Prowler: - -1. **Review Current Issues**: Check out our [GitHub Issues](https://github.com/prowler-cloud/prowler/issues) page. We often tag issues as `good first issue` - these are perfect for new contributors as they are typically well-defined and manageable in scope. - -2. **Expand Prowler's Capabilities**: Prowler is constantly evolving, and you can be a part of its growth. Whether you are adding checks, supporting new services, or introducing integrations, your contributions help improve the tool for everyone. Here is how you can get involved: - - - **Adding New Checks** - Want to improve Prowler's detection capabilities for your favorite cloud provider? You can contribute by writing new checks. To get started, follow the [create a new check guide](./checks.md). - - - **Adding New Services** - One key service for your favorite cloud provider is missing? Add it to Prowler! To add a new service, check out the [create a new service guide](./services.md). Do not forget to include relevant checks to validate functionality. - - - **Adding New Providers** - If you would like to extend Prowler to work with a new cloud provider, follow the [create a new provider guide](./provider.md). This typically involves setting up new services and checks to ensure compatibility. - - - **Adding New Output Formats** - Want to tailor how results are displayed or exported? You can add custom output formats by following the [create a new output format guide](./outputs.md). - - - **Adding New Integrations** - Prowler can work with other tools and platforms through integrations. If you would like to add one, see the [create a new integration guide](./integrations.md). - - - **Proposing or Implementing Features** - Got an idea to make Prowler better? Whether it is a brand-new feature or an enhancement to an existing one, you are welcome to propose it or help implement community-requested improvements. - -3. **Improve Documentation**: Help make Prowler more accessible by enhancing our documentation, fixing typos, or adding examples/tutorials. See the tutorial of how we write our documentation [here](./documentation.md). - -4. **Bug Fixes**: If you find any issues or bugs, you can report them in the [GitHub Issues](https://github.com/prowler-cloud/prowler/issues) page and if you want you can also fix them. - -Remember, our community is here to help! If you need guidance, do not hesitate to ask questions in the issues or join our [Slack workspace](https://goto.prowler.com/slack). - -### Pre-Commit Hooks - -This repository uses Git pre-commit hooks managed by the [pre-commit](https://pre-commit.com/) tool, it is installed with `poetry install --with dev`. Next, run the following command in the root of this repository: - -```shell -pre-commit install -``` - -Successful installation should produce the following output: - -```shell -pre-commit installed at .git/hooks/pre-commit -``` - -### Code Quality and Security Checks - -Before merging pull requests, several automated checks and utilities ensure code security and updated dependencies: - -???+ note - These should have been already installed if `poetry install --with dev` was already run. - -- [`bandit`](https://pypi.org/project/bandit/) for code security review. -- [`safety`](https://pypi.org/project/safety/) and [`dependabot`](https://github.com/features/security) for dependencies. -- [`hadolint`](https://github.com/hadolint/hadolint) and [`dockle`](https://github.com/goodwithtech/dockle) for container security. -- [`Snyk`](https://docs.snyk.io/integrations/snyk-container-integrations/container-security-with-docker-hub-integration) for container security in Docker Hub. -- [`clair`](https://github.com/quay/clair) for container security in Amazon ECR. -- [`vulture`](https://pypi.org/project/vulture/), [`flake8`](https://pypi.org/project/flake8/), [`black`](https://pypi.org/project/black/), and [`pylint`](https://pypi.org/project/pylint/) for formatting and best practices. - -Additionally, ensure the latest version of [`TruffleHog`](https://github.com/trufflesecurity/trufflehog) is installed to scan for sensitive data in the code. Follow the official [installation guide](https://github.com/trufflesecurity/trufflehog?tab=readme-ov-file#floppy_disk-installation) for setup. - -### Dependency Management - -All dependencies are listed in the `pyproject.toml` file. - -For proper code documentation, refer to the following and follow the code documentation practices presented there: [Google Python Style Guide - Comments and Docstrings](https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings). - -???+ note - If you encounter issues when committing to the Prowler repository, use the `--no-verify` flag with the `git commit` command. - -### Repository Folder Structure - -Understanding the layout of the Prowler codebase will help you quickly find where to add new features, checks, or integrations. The following is a high-level overview from the root of the repository: - -``` -prowler/ -ā”œā”€ā”€ prowler/ # Main source code for Prowler SDK (CLI, providers, services, checks, compliances, config, etc.) -ā”œā”€ā”€ api/ # API server and related code -ā”œā”€ā”€ dashboard/ # Local Dashboard extracted from the CLI output -ā”œā”€ā”€ ui/ # Web UI components -ā”œā”€ā”€ util/ # Utility scripts and helpers -ā”œā”€ā”€ tests/ # Prowler SDK test suite -ā”œā”€ā”€ docs/ # Documentation, including this guide -ā”œā”€ā”€ examples/ # Example output formats for providers and scripts -ā”œā”€ā”€ permissions/ # Permission-related files and policies -ā”œā”€ā”€ contrib/ # Community-contributed scripts or modules -ā”œā”€ā”€ kubernetes/ # Kubernetes deployment files -ā”œā”€ā”€ .github/ # GitHub related files (workflows, issue templates, etc.) -ā”œā”€ā”€ pyproject.toml # Python project configuration (Poetry) -ā”œā”€ā”€ poetry.lock # Poetry lock file -ā”œā”€ā”€ README.md # Project overview and getting started -ā”œā”€ā”€ Makefile # Common development commands -ā”œā”€ā”€ Dockerfile # SDK Docker container -ā”œā”€ā”€ docker-compose.yml # Prowler App Docker compose -└── ... # Other supporting files -``` - -## Pull Request Checklist - -When creating or reviewing a pull request in https://github.com/prowler-cloud/prowler, follow [this checklist](https://github.com/prowler-cloud/prowler/blob/master/.github/pull_request_template.md#checklist). - -## Contribution Appreciation - -If you enjoy swag, we’d love to thank you for your contribution with laptop stickers or other Prowler merchandise! - -To request swag: Share your pull request details in our [Slack workspace](https://goto.prowler.com/slack). - -You can also reach out to Toni de la Fuente on [Twitter](https://twitter.com/ToniBlyx)—his DMs are open! - -# Testing a Pull Request from a Specific Branch - -To test Prowler from a specific branch (for example, to try out changes from a pull request before it is merged), you can use `pipx` to install directly from GitHub: - -```sh -pipx install "git+https://github.com/prowler-cloud/prowler.git@branch-name" -``` - -Replace `branch-name` with the name of the branch you want to test. This will install Prowler in an isolated environment, allowing you to try out the changes safely. \ No newline at end of file diff --git a/docs/developer-guide/introduction.mdx b/docs/developer-guide/introduction.mdx new file mode 100644 index 0000000000..9d1ea742b1 --- /dev/null +++ b/docs/developer-guide/introduction.mdx @@ -0,0 +1,216 @@ +--- +title: 'Introduction to developing in Prowler' +--- + +Thanks for your interest in contributing to Prowler! + +Prowler can be extended in various ways. This guide provides the different ways to contribute and how to get started. + +## Contributing to Prowler + +### Review Current Issues +Check out our [GitHub Issues](https://github.com/prowler-cloud/prowler/issues) page for ideas to contribute. + + + We tag issues as `good first issue` for new contributors. These are typically well-defined and manageable in scope. + + + We tag issues as `help wanted` for other issues that require more time to complete. + + + +### Expand Prowler's Capabilities +Prowler is constantly evolving. Contributions to checks, services, or integrations help improve the tool for everyone. Here is how to get involved: + + + + Want to improve Prowler's detection capabilities for your favorite cloud provider? You can contribute by writing new checks. + + + One key service for your favorite cloud provider is missing? Add it to Prowler! Do not forget to include relevant checks to validate functionality. + + + If you would like to extend Prowler to work with a new cloud provider, this typically involves setting up new services and checks to ensure compatibility. + + + Want to tailor how results are displayed or exported? You can add custom output formats. + + + Prowler can work with other tools and platforms through integrations. + + + Propose brand-new features or enhancements to existing ones, or help implement community-requested improvements. + + + +### Improve Documentation +Help make Prowler more accessible by enhancing our documentation, fixing typos, or adding examples/tutorials. + + + + Enhance our documentation, fix typos, or add examples/tutorials. + + + +### Bug Fixes +If you find any issues or bugs, you can report them in the [GitHub Issues](https://github.com/prowler-cloud/prowler/issues) page and if you want you can also fix them. + + + + Report or fix issues or bugs. + + + +Remember, our community is here to help! If you need guidance, do not hesitate to ask questions in the issues or join our [ Slack workspace](https://goto.prowler.com/slack). + + + +## Setting up your development environment + +### Prerequisites + +Before proceeding, ensure the following: + +- Git is installed. +- Python 3.9 or higher is installed. +- `poetry` is installed to manage dependencies. + +### Forking the Prowler Repository + +Fork the Prowler GitHub repository to contribute to Prowler. This allows proposing changes, submitting new features, and fixing bugs. For guidance on forking, refer to the [official GitHub documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo?tool=webui#forking-a-repository). + +### Cloning Your Forked Repository + +Once your fork is created, clone it using the following commands (replace `` with your GitHub username): + +``` +git clone https://github.com//prowler +cd prowler +``` + +### Dependency Management and Environment Isolation + +To prevent conflicts between environments, we recommend using `poetry`, a Python dependency management solution. Install it by following the [instructions](https://python-poetry.org/docs/#installation). + +### Installing Dependencies + +To install all required dependencies, including those needed for development, run: + +``` +poetry install --with dev +eval $(poetry env activate) +``` + + +Starting from Poetry v2.0.0, `poetry shell` has been deprecated in favor of `poetry env activate`. +If your poetry version is below 2.0.0 you must keep using `poetry shell` to activate your environment. +In case you have any doubts, consult the [Poetry environment activation guide](https://python-poetry.org/docs/managing-environments/#activating-the-environment). + + + + +### Pre-Commit Hooks + +This repository uses Git pre-commit hooks managed by the [pre-commit](https://pre-commit.com/) tool, it is installed with `poetry install --with dev`. Next, run the following command in the root of this repository: + +```shell +pre-commit install +``` + +Successful installation should produce the following output: + +```shell +pre-commit installed at .git/hooks/pre-commit +``` + +### Code Quality and Security Checks + +Before merging pull requests, several automated checks and utilities ensure code security and updated dependencies: + + +These should have been already installed if `poetry install --with dev` was already run. + + +- [`bandit`](https://pypi.org/project/bandit/) for code security review. +- [`safety`](https://pypi.org/project/safety/) and [`dependabot`](https://github.com/features/security) for dependencies. +- [`hadolint`](https://github.com/hadolint/hadolint) and [`dockle`](https://github.com/goodwithtech/dockle) for container security. +- [`Snyk`](https://docs.snyk.io/integrations/snyk-container-integrations/container-security-with-docker-hub-integration) for container security in Docker Hub. +- [`clair`](https://github.com/quay/clair) for container security in Amazon ECR. +- [`vulture`](https://pypi.org/project/vulture/), [`flake8`](https://pypi.org/project/flake8/), [`black`](https://pypi.org/project/black/), and [`pylint`](https://pypi.org/project/pylint/) for formatting and best practices. + +Additionally, ensure the latest version of [`TruffleHog`](https://github.com/trufflesecurity/trufflehog) is installed to scan for sensitive data in the code. Follow the official [installation guide](https://github.com/trufflesecurity/trufflehog?tab=readme-ov-file#floppy_disk-installation) for setup. + +### AI-Driven Contributions + +If you are using AI assistants to help with your contributions, Prowler provides specialized resources to enhance AI-driven development: + +- **Prowler MCP Server**: The [Prowler MCP Server](/getting-started/products/prowler-mcp) provides AI assistants with access to the entire Prowler ecosystem, including security checks, compliance frameworks, documentation, and more. This enables AI tools to better understand Prowler's architecture and help you create contributions that align with project standards. + +- **AGENTS.md Files**: Each component of the Prowler monorepo includes an `AGENTS.md` file that contains specific guidelines for AI agents working on that component. These files provide context about project structure, coding standards, and best practices. When working on a specific component, refer to the relevant `AGENTS.md` file (e.g., `prowler/AGENTS.md`, `ui/AGENTS.md`, `api/AGENTS.md`) to ensure your AI assistant follows the appropriate guidelines. + +These resources help ensure that AI-assisted contributions maintain consistency with Prowler's codebase and development practices. + +### Dependency Management + +All dependencies are listed in the `pyproject.toml` file. + +For proper code documentation, refer to the following and follow the code documentation practices presented there: [Google Python Style Guide - Comments and Docstrings](https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings). + + +If you encounter issues when committing to the Prowler repository, use the `--no-verify` flag with the `git commit` command. + + +### Repository Folder Structure + +The Prowler codebase layout helps quickly locate where to add new features, checks, or integrations. The following is a high-level overview from the root of the repository: + +``` +prowler/ +ā”œā”€ā”€ prowler/ # Main source code for Prowler SDK (CLI, providers, services, checks, compliances, config, etc.) +ā”œā”€ā”€ api/ # API server and related code +ā”œā”€ā”€ dashboard/ # Local Dashboard extracted from the CLI output +ā”œā”€ā”€ ui/ # Web UI components +ā”œā”€ā”€ util/ # Utility scripts and helpers +ā”œā”€ā”€ tests/ # Prowler SDK test suite +ā”œā”€ā”€ docs/ # Documentation, including this guide +ā”œā”€ā”€ examples/ # Example output formats for providers and scripts +ā”œā”€ā”€ permissions/ # Permission-related files and policies +ā”œā”€ā”€ contrib/ # Community-contributed scripts or modules +ā”œā”€ā”€ kubernetes/ # Kubernetes deployment files +ā”œā”€ā”€ .github/ # GitHub-related files (workflows, issue templates, etc.) +ā”œā”€ā”€ pyproject.toml # Python project configuration (Poetry) +ā”œā”€ā”€ poetry.lock # Poetry lock file +ā”œā”€ā”€ README.md # Project overview and getting started +ā”œā”€ā”€ Makefile # Common development commands +ā”œā”€ā”€ Dockerfile # SDK Docker container +ā”œā”€ā”€ docker-compose.yml # Prowler App Docker compose +└── ... # Other supporting files +``` + +## Sending the Pull Request + +When creating or reviewing a pull request in [Prowler](https://github.com/prowler-cloud/prowler), follow [this template](https://github.com/prowler-cloud/prowler/blob/master/.github/pull_request_template.md) and fill it with the relevant information: + +- **Context** and **Description** of the change: This will help the reviewers to understand the change and the purpose of the pull request. +- **Steps to review**: A detailed description of how to review the change. +- **Checklist**: A mandatory checklist of the things that should be reviewed before merging the pull request. + +## Contribution Appreciation + +If you enjoy swag, we'd love to thank you for your contribution with laptop stickers or other Prowler merchandise! + +To request swag: Share your pull request details in our [Slack workspace](https://goto.prowler.com/slack). + +You can also reach out to Toni de la Fuente on [Twitter](https://twitter.com/ToniBlyx)—his DMs are open! + +## Testing a Pull Request from a Specific Branch + +To test Prowler from a specific branch (for example, to try out changes from a pull request before it is merged), you can use `pipx` to install directly from GitHub: + +```sh +pipx install "git+https://github.com/prowler-cloud/prowler.git@branch-name" +``` + +Replace `branch-name` with the name of the branch you want to test. This will install Prowler in an isolated environment, allowing you to try out the changes safely. + +For more details on testing go to the [Testing section](/developer-guide/unit-testing) of this documentation. \ No newline at end of file diff --git a/docs/developer-guide/kubernetes-details.md b/docs/developer-guide/kubernetes-details.mdx similarity index 83% rename from docs/developer-guide/kubernetes-details.md rename to docs/developer-guide/kubernetes-details.mdx index be4b72f383..0ccda94f38 100644 --- a/docs/developer-guide/kubernetes-details.md +++ b/docs/developer-guide/kubernetes-details.mdx @@ -1,12 +1,14 @@ -# Kubernetes Provider +--- +title: 'Kubernetes Provider' +--- This page details the [Kubernetes](https://kubernetes.io/) provider implementation in Prowler. -By default, Prowler will audit all namespaces in the Kubernetes cluster accessible by the configured context. To configure it, see the [In-Cluster Execution](../tutorials/kubernetes/in-cluster.md) or [Non In-Cluster Execution](../tutorials/kubernetes/outside-cluster.md) guides. +By default, Prowler will audit all namespaces in the Kubernetes cluster accessible by the configured context. To configure it, see the [In-Cluster Execution](/user-guide/providers/kubernetes/getting-started-k8s#in-cluster-execution) or [Non In-Cluster Execution](/user-guide/providers/kubernetes/getting-started-k8s#non-in-cluster-execution) guides. ## Kubernetes Provider Classes Architecture -The Kubernetes provider implementation follows the general [Provider structure](./provider.md). This section focuses on the Kubernetes-specific implementation, highlighting how the generic provider concepts are realized for Kubernetes in Prowler. For a full overview of the provider pattern, base classes, and extension guidelines, see [Provider documentation](./provider.md). +The Kubernetes provider implementation follows the general [Provider structure](/developer-guide/provider). This section focuses on the Kubernetes-specific implementation, highlighting how the generic provider concepts are realized for Kubernetes in Prowler. For a full overview of the provider pattern, base classes, and extension guidelines, see [Provider documentation](/developer-guide/provider). ### `KubernetesProvider` (Main Class) @@ -31,7 +33,7 @@ The Kubernetes provider implementation follows the general [Provider structure]( ### `KubernetesService` (Service Base Class) - **Location:** [`prowler/providers/kubernetes/lib/service/service.py`](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/kubernetes/lib/service/service.py) -- **Purpose:** Abstract base class that all Kubernetes service-specific classes inherit from. This implements the generic service pattern (described in [service page](./services.md#service-base-class)) specifically for Kubernetes. +- **Purpose:** Abstract base class that all Kubernetes service-specific classes inherit from. This implements the generic service pattern (described in [service page](/developer-guide/services#service-base-class)) specifically for Kubernetes. - **Key Kubernetes Responsibilities:** - Receives a `KubernetesProvider` instance to access session, identity, and configuration. - Manages the Kubernetes API client and context. @@ -50,12 +52,12 @@ The Kubernetes provider implementation follows the general [Provider structure]( ## Specific Patterns in Kubernetes Services -The generic service pattern is described in [service page](./services.md#service-structure-and-initialisation). You can find all the currently implemented services in the following locations: +The generic service pattern is described in [service page](/developer-guide/services#service-structure-and-initialisation). You can find all the currently implemented services in the following locations: - Directly in the code, in location [`prowler/providers/kubernetes/services/`](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers/kubernetes/services) - In the [Prowler Hub](https://hub.prowler.com/) for a more human-readable view. -The best reference to understand how to implement a new service is following the [service implementation documentation](./services.md#adding-a-new-service) and taking other already implemented services as reference. +The best reference to understand how to implement a new service is following the [service implementation documentation](/developer-guide/services#adding-a-new-service) and taking other already implemented services as reference. ### Kubernetes Service Common Patterns @@ -69,12 +71,12 @@ The best reference to understand how to implement a new service is following the ## Specific Patterns in Kubernetes Checks -The Kubernetes checks pattern is described in [checks page](./checks.md). You can find all the currently implemented checks in: +The Kubernetes checks pattern is described in [checks page](/developer-guide/checks). You can find all the currently implemented checks in: - Directly in the code, within each service folder, each check has its own folder named after the name of the check. (e.g. [`prowler/providers/kubernetes/services/rbac/rbac_minimize_wildcard_use_roles/`](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers/kubernetes/services/rbac/rbac_minimize_wildcard_use_roles)) - In the [Prowler Hub](https://hub.prowler.com/) for a more human-readable view. -The best reference to understand how to implement a new check is following the [Kubernetes check implementation documentation](./checks.md#creating-a-check) and taking other checks as reference. +The best reference to understand how to implement a new check is following the [Kubernetes check implementation documentation](/developer-guide/checks#creating-a-check) and taking other checks as reference. ### Check Report Class diff --git a/docs/developer-guide/lighthouse.md b/docs/developer-guide/lighthouse.mdx similarity index 89% rename from docs/developer-guide/lighthouse.md rename to docs/developer-guide/lighthouse.mdx index e01067844f..25afd51728 100644 --- a/docs/developer-guide/lighthouse.md +++ b/docs/developer-guide/lighthouse.mdx @@ -1,4 +1,6 @@ -# Extending Prowler Lighthouse AI +--- +title: 'Extending Prowler Lighthouse AI' +--- This guide helps developers customize and extend Prowler Lighthouse AI by adding or modifying AI agents. @@ -15,9 +17,10 @@ AI agents fall into two main categories: Prowler Lighthouse AI is an autonomous agent - selecting the right tool(s) based on the users query. -???+ note - To learn more about AI agents, read [Anthropic's blog post on building effective agents](https://www.anthropic.com/engineering/building-effective-agents). + +To learn more about AI agents, read [Anthropic's blog post on building effective agents](https://www.anthropic.com/engineering/building-effective-agents). + ### LLM Dependency The autonomous nature of agents depends on the underlying LLM. Autonomous agents using identical system prompts and tools but powered by different LLM providers might approach user queries differently. Agent with one LLM might solve a problem efficiently, while with another it might take a different route or fail entirely. @@ -30,7 +33,7 @@ Prowler Lighthouse AI uses a multi-agent architecture orchestrated by the [Langg ### Architecture Components -Prowler Lighthouse architecture +Prowler Lighthouse architecture Prowler Lighthouse AI integrates with the NextJS application: @@ -67,9 +70,10 @@ Modifying the supervisor prompt allows you to: - Modify task delegation to specialized agents - Set up guardrails (query types to answer or decline) -???+ note - The supervisor agent should not have its own tools. This design keeps the system modular and maintainable. + +The supervisor agent should not have its own tools. This design keeps the system modular and maintainable. + ### How to Create New Specialized Agents The supervisor agent and all specialized agents are defined in the `route.ts` file. The supervisor agent uses [langgraph-supervisor](https://www.npmjs.com/package/@langchain/langgraph-supervisor), while other agents use the prebuilt [create-react-agent](https://langchain-ai.github.io/langgraphjs/how-tos/create-react-agent/). @@ -77,14 +81,16 @@ The supervisor agent and all specialized agents are defined in the `route.ts` fi To add new capabilities or all Lighthouse AI to interact with other APIs, create additional specialized agents: 1. First determine what the new agent would do. Create a detailed prompt defining the agent's purpose and capabilities. You can see an example from [here](https://github.com/prowler-cloud/prowler/blob/master/ui/lib/lighthouse/prompts.ts#L359-L385). -???+ note - Ensure that the new agent's capabilities don't collide with existing agents. For example, if there's already a *findings_agent* that talks to findings APIs don't create a new agent to do the same. + +Ensure that the new agent's capabilities don't collide with existing agents. For example, if there's already a *findings_agent* that talks to findings APIs don't create a new agent to do the same. + 2. Create necessary tools for the agents to access specific data or perform actions. A tool is a specialized function that extends the capabilities of LLM by allowing it to access external data or APIs. A tool is triggered by LLM based on the description of the tool and the user's query. For example, the description of `getScanTool` is "Fetches detailed information about a specific scan by its ID." If the description doesn't convey what the tool is capable of doing, LLM will not invoke the function. If the description of `getScanTool` was set to something random or not set at all, LLM will not answer queries like "Give me the critical issues from the scan ID xxxxxxxxxxxxxxx" -???+ note - Ensure that one tool is added to one agent only. Adding tools is optional. There can be agents with no tools at all. + +Ensure that one tool is added to one agent only. Adding tools is optional. There can be agents with no tools at all. + 3. Use the `createReactAgent` function to define a new agent. For example, the rolesAgent name is "roles_agent" and has access to call tools "*getRolesTool*" and "*getRoleTool*" ```js const rolesAgent = createReactAgent({ diff --git a/docs/developer-guide/llm-details.mdx b/docs/developer-guide/llm-details.mdx new file mode 100644 index 0000000000..3647552c0f --- /dev/null +++ b/docs/developer-guide/llm-details.mdx @@ -0,0 +1,104 @@ +--- +title: 'LLM Provider' +--- + +This page details the [Large Language Model (LLM)](https://en.wikipedia.org/wiki/Large_language_model) provider implementation in Prowler. + +The LLM provider enables security testing of language models using red team techniques. By default, Prowler uses the built-in LLM configuration that targets OpenAI models with comprehensive security test suites. To configure it, follow the [LLM getting started guide](/user-guide/providers/llm/getting-started-llm). + +## LLM Provider Classes Architecture + +The LLM provider implementation follows the general [Provider structure](/developer-guide/provider). This section focuses on the LLM-specific implementation, highlighting how the generic provider concepts are realized for LLM security testing in Prowler. For a full overview of the provider pattern, base classes, and extension guidelines, see [Provider documentation](/developer-guide/provider). + +### Main Class + +- **Location:** [`prowler/providers/llm/llm_provider.py`](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/llm/llm_provider.py) +- **Base Class:** Inherits from `Provider` (see [base class details](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/common/provider.py)). +- **Purpose:** Central orchestrator for LLM-specific logic, configuration management, and integration with promptfoo for red team testing. +- **Key LLM Responsibilities:** + - Initializes and manages LLM configuration using promptfoo. + - Validates configuration and sets up the LLM testing context. + - Loads and manages red team test configuration, plugins, and target models. + - Provides properties and methods for downstream LLM security testing. + - Integrates with promptfoo for comprehensive LLM security evaluation. + +### Data Models + +- **Location:** [`prowler/providers/llm/models.py`](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/llm/models.py) +- **Purpose:** Define structured data for LLM output options and configuration. +- **Key LLM Models:** + - `LLMOutputOptions`: Customizes output filename logic for LLM-specific reporting. + +### LLM Security Testing Integration + +- **Location:** [`prowler/providers/llm/llm_provider.py`](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/llm/llm_provider.py) +- **Purpose:** Integrates with promptfoo for comprehensive LLM security testing. +- **Key LLM Responsibilities:** + - Executes promptfoo red team evaluations against target LLMs. + - Processes security test results and converts them to Prowler reports. + - Manages test concurrency and progress tracking. + - Handles real-time streaming of test results. + +### Configuration Management + +The LLM provider uses promptfoo configuration files to define: + +- **Target Models**: The LLM models to test (e.g., OpenAI GPT, Anthropic Claude) +- **Red Team Plugins**: Security test suites (OWASP, MITRE, NIST, EU AI Act) +- **Test Parameters**: Concurrency, test counts, and evaluation criteria + +### Default Configuration + +Prowler includes a comprehensive default LLM configuration that: + +- Targets OpenAI models by default +- Includes multiple security test frameworks (OWASP, MITRE, NIST, EU AI Act) +- Provides extensive test coverage for LLM security vulnerabilities +- Supports custom configuration for specific testing needs + +## Specific Patterns in LLM Security Testing + +The LLM provider implements security testing through integration with promptfoo, following these patterns: + +### Red Team Testing Framework + +- **Plugin-based Architecture**: Uses promptfoo plugins for different security test categories +- **Comprehensive Coverage**: Includes OWASP LLM Top 10, MITRE ATLAS, NIST AI Risk Management, and EU AI Act compliance +- **Real-Time Evaluation**: Streams test results as they are generated +- **Progress Tracking**: Provides detailed progress information during test execution + +### Test Execution Flow + +1. **Configuration Loading**: Loads promptfoo configuration with target models and test plugins +2. **Test Generation**: Generates security test cases based on configured plugins +3. **Concurrent Execution**: Runs tests with configurable concurrency limits +4. **Result Processing**: Converts promptfoo results to Prowler security reports +5. **Progress Monitoring**: Tracks and displays test execution progress + +### Security Test Categories + +The LLM provider supports comprehensive security testing across multiple frameworks: + +- **OWASP LLM Top 10**: Covers prompt injection, data leakage, and model security +- **MITRE ATLAS**: Adversarial threat landscape for AI systems +- **NIST AI Risk Management**: AI system risk assessment and mitigation +- **EU AI Act**: European Union AI regulation compliance +- **Custom Tests**: Support for organization-specific security requirements + +## Error Handling and Validation + +The LLM provider includes comprehensive error handling for: + +- **Configuration Validation**: Ensures valid promptfoo configuration files +- **Model Access**: Handles authentication and access issues with target LLMs +- **Test Execution**: Manages test failures and timeout scenarios +- **Result Processing**: Handles malformed or incomplete test results + +## Integration with Prowler Ecosystem + +The LLM provider seamlessly integrates with Prowler's existing infrastructure: + +- **Output Formats**: Supports all Prowler output formats (JSON, CSV, HTML, etc.) +- **Compliance Frameworks**: Integrates with Prowler's compliance reporting +- **Fixer Integration**: Supports automated remediation recommendations +- **Dashboard Integration**: Compatible with Prowler App for centralized management diff --git a/docs/developer-guide/m365-details.md b/docs/developer-guide/m365-details.mdx similarity index 86% rename from docs/developer-guide/m365-details.md rename to docs/developer-guide/m365-details.mdx index 65fcd3f622..185e1e022b 100644 --- a/docs/developer-guide/m365-details.md +++ b/docs/developer-guide/m365-details.mdx @@ -1,8 +1,10 @@ -# Microsoft 365 (M365) Provider +--- +title: 'Microsoft 365 (M365) Provider' +--- This page details the [Microsoft 365 (M365)](https://www.microsoft.com/en-us/microsoft-365) provider implementation in Prowler. -By default, Prowler will audit the Microsoft Entra ID tenant and its supported services. To configure it, follow the [M365 getting started guide](../tutorials/microsoft365/getting-started-m365.md). +By default, Prowler will audit the Microsoft Entra ID tenant and its supported services. To configure it, follow the [M365 getting started guide](/user-guide/providers/microsoft365/getting-started-m365). --- @@ -15,14 +17,14 @@ By default, Prowler will audit the Microsoft Entra ID tenant and its supported s - **Required modules:** - [ExchangeOnlineManagement](https://www.powershellgallery.com/packages/ExchangeOnlineManagement/3.6.0) (≄ 3.6.0) - [MicrosoftTeams](https://www.powershellgallery.com/packages/MicrosoftTeams/6.6.0) (≄ 6.6.0) -- If you use Prowler Cloud or the official containers, PowerShell is pre-installed. For local or pip installations, you must install PowerShell and the modules yourself. See [Authentication: Supported PowerShell Versions](../tutorials/microsoft365/authentication.md#supported-powershell-versions) and [Needed PowerShell Modules](../tutorials/microsoft365/authentication.md#required-powershell-modules). -- For more details and troubleshooting, see [Use of PowerShell in M365](../tutorials/microsoft365/use-of-powershell.md). +- If you use Prowler Cloud or the official containers, PowerShell is pre-installed. For local or pip installations, you must install PowerShell and the modules yourself. See [Authentication: Supported PowerShell Versions](/user-guide/providers/microsoft365/authentication#supported-powershell-versions) and [Needed PowerShell Modules](/user-guide/providers/microsoft365/authentication#required-powershell-modules). +- For more details and troubleshooting, see [Use of PowerShell in M365](/user-guide/providers/microsoft365/use-of-powershell). --- ## M365 Provider Classes Architecture -The M365 provider implementation follows the general [Provider structure](./provider.md). This section focuses on the M365-specific implementation, highlighting how the generic provider concepts are realized for M365 in Prowler. For a full overview of the provider pattern, base classes, and extension guidelines, see [Provider documentation](./provider.md). +The M365 provider implementation follows the general [Provider structure](/developer-guide/provider). This section focuses on the M365-specific implementation, highlighting how the generic provider concepts are realized for M365 in Prowler. For a full overview of the provider pattern, base classes, and extension guidelines, see [Provider documentation](/developer-guide/provider). ### `M365Provider` (Main Class) @@ -73,12 +75,12 @@ The M365 provider implementation follows the general [Provider structure](./prov ## Specific Patterns in M365 Services -The generic service pattern is described in [service page](./services.md#service-structure-and-initialisation). You can find all the currently implemented services in the following locations: +The generic service pattern is described in [service page](/developer-guide/services#service-structure-and-initialisation). You can find all the currently implemented services in the following locations: - Directly in the code, in location [`prowler/providers/m365/services/`](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers/m365/services) - In the [Prowler Hub](https://hub.prowler.com/) for a more human-readable view. -The best reference to understand how to implement a new service is by following the [service implementation documentation](./services.md#adding-a-new-service) and by taking other already implemented services as reference. +The best reference to understand how to implement a new service is by following the [service implementation documentation](/developer-guide/services#adding-a-new-service) and by taking other already implemented services as reference. ### M365 Service Common Patterns @@ -92,12 +94,12 @@ The best reference to understand how to implement a new service is by following ## Specific Patterns in M365 Checks -The M365 checks pattern is described in [checks page](./checks.md). You can find all the currently implemented checks in: +The M365 checks pattern is described in [checks page](/developer-guide/checks). You can find all the currently implemented checks in: - Directly in the code, within each service folder, each check has its own folder named after the name of the check. (e.g. [`prowler/providers/m365/services/entra/entra_users_mfa_enabled/`](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers/m365/services/entra/entra_users_mfa_enabled)) - In the [Prowler Hub](https://hub.prowler.com/) for a more human-readable view. -The best reference to understand how to implement a new check is following the [M365 check implementation documentation](./checks.md#creating-a-check) and by taking other checks as reference. +The best reference to understand how to implement a new check is following the [M365 check implementation documentation](/developer-guide/checks#creating-a-check) and by taking other checks as reference. ### Check Report Class diff --git a/docs/developer-guide/outputs.md b/docs/developer-guide/outputs.mdx similarity index 98% rename from docs/developer-guide/outputs.md rename to docs/developer-guide/outputs.mdx index 5131f9844d..15b785b799 100644 --- a/docs/developer-guide/outputs.md +++ b/docs/developer-guide/outputs.mdx @@ -1,4 +1,6 @@ -# Create a Custom Output Format +--- +title: 'Create a Custom Output Format' +--- ## Introduction @@ -101,6 +103,7 @@ Prowler supports multiple output formats, allowing users to tailor findings pres finding_dict["DESCRIPTION"] = finding.metadata.Description finding_dict["RISK"] = finding.metadata.Risk finding_dict["RELATED_URL"] = finding.metadata.RelatedUrl + finding_dict["ADDITIONAL_URLS"] = unroll_list(finding.metadata.AdditionalURLs) finding_dict["REMEDIATION_RECOMMENDATION_TEXT"] = ( finding.metadata.Remediation.Recommendation.Text ) diff --git a/docs/developer-guide/provider.md b/docs/developer-guide/provider.md deleted file mode 100644 index 8d4708640f..0000000000 --- a/docs/developer-guide/provider.md +++ /dev/null @@ -1,170 +0,0 @@ -# Prowler Providers - -## Introduction - -Providers form the backbone of Prowler, enabling security assessments across various cloud environments. - -A provider is any platform or service that offers resources, data, or functionality that can be audited for security and compliance. This includes: - -- Cloud Infrastructure Providers (like Amazon Web Services, Microsoft Azure, and Google Cloud) -- Software as a Service (SaaS) Platforms (like Microsoft 365) -- Development Platforms (like GitHub) -- Container Orchestration Platforms (like Kubernetes) - -For providers supported by Prowler, refer to [Prowler Hub](https://hub.prowler.com/). - -???+ important - There are some custom providers added by the community, like [NHN Cloud](https://www.nhncloud.com/), that are not maintained by the Prowler team, but can be used in the Prowler CLI. They can be checked directly at the [Prowler GitHub repository](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers). - -## Adding a New Provider - -To integrate an unsupported Prowler provider and implement its security checks, create a dedicated folder for all related files (e.g., services, checks)." - -This folder must be placed within [`prowler/providers//`](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers). - -Within this folder the following folders are also to be created: - -- `lib` – Stores additional utility functions and core files required by every provider. The following files and subfolders are commonly found in every provider's `lib` folder: - - - `service/service.py` – Provides a generic service class to be inherited by all services. - - `arguments/arguments.py` – Handles provider-specific argument parsing. - - `mutelist/mutelist.py` – Manages the mutelist functionality for the provider. - -- `services` – Stores all [services](./services.md) that the provider offers and want to be audited by [Prowler checks](./checks.md). - -- `__init__.py` (empty) – Ensures Python recognizes this folder as a package. - -- `_provider.py` – Defines authentication logic, configurations, and other provider-specific data. - -- `models.py` – Contains necessary models for the new provider. - -By adhering to this structure, Prowler can effectively support services and security checks for additional providers. - -???+ important - If your new provider requires a Python library (such as an official SDK or API client) to connect to its services, make sure to add it as a dependency in the `pyproject.toml` file. This ensures that all contributors and users have the necessary packages installed when working with your provider. - -## Provider Structure in Prowler - -Prowler's provider architecture is designed to facilitate security audits through a generic service tailored to each provider. This is accomplished by passing the necessary parameters to the constructor, which initializes all required session values. - -### Base Class - -All Prowler providers inherit from the same base class located in [`prowler/providers/common/provider.py`](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/common/provider.py). It is an [abstract base class](https://docs.python.org/3/library/abc.html) that defines the interface for all provider classes. - -### Provider Class - -#### Provider Implementation Guidance - -Given the complexity and variability of providers, use existing provider implementations as templates when developing new integrations. - -- [AWS](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/aws/aws_provider.py) -- [GCP](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/gcp/gcp_provider.py) -- [Azure](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/azure/azure_provider.py) -- [Kubernetes](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/kubernetes/kubernetes_provider.py) -- [Microsoft365](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/microsoft365/microsoft365_provider.py) -- [GitHub](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/github/github_provider.py) - -### Basic Provider Implementation: Pseudocode Example - -To simplify understanding, the following pseudocode outlines the fundamental structure of a provider, including library imports necessary for authentication. - -```python title="Provider Example Class" - -# Library Imports for Authentication - -# When implementing authentication for a provider, import the required libraries. - -from prowler.config.config import load_and_validate_config_file -from prowler.lib.logger import logger -from prowler.lib.mutelist.mutelist import parse_mutelist_file -from prowler.lib.utils.utils import print_boxes -from prowler.providers.common.models import Audit_Metadata -from prowler.providers.common.provider import Provider -from prowler.providers..models import ( - # All provider models needed. - ProviderSessionModel, - ProviderIdentityModel, - ProviderOutputOptionsModel -) - -class NewProvider(Provider): - # All properties from the class, some of which are properties in the base class. - _type: str = "" - _session: - _identity: - _audit_config: dict - _output_options: ProviderOutputOptionsModel - _mutelist: dict - audit_metadata: Audit_Metadata - - def __init__(self, arguments): - """ - Initializes the NewProvider instance. - Args: - arguments (dict): A dictionary containing configuration arguments. - """ - logger.info("Setting provider ...") - - # Initializing the Provider Session - - # Steps: - - # - Retrieve Account Information - # - Extract relevant account identifiers (subscriptions, projects, or other service references) from the provided arguments. - - # Establish a Session - - # Use the method enforced by the parent class to set up the session: - self._session = self.setup_session(credentials_file) - - # Define Provider Identity - # Assign the identity class, typically provided by the Python provider library: - self._identity = () - - # Configure the Provider - # Set the provider-specific configuration. - self._audit_config = load_and_validate_config_file( - self._type, arguments.config_file - ) - - # All the enforced properties by the parent class. - @property - def identity(self): - return self._identity - - @property - def session(self): - return self._session - - @property - def type(self): - return self._type - - @property - def audit_config(self): - return self._audit_config - - @property - def output_options(self): - return self._output_options - - def setup_session(self, ): - """ - Sets up the Provider session. - - Args: - Can include all necessary arguments to set up the session - - Returns: - Credentials necessary to communicate with the provider. - """ - pass - - """ - This method is enforced by parent class and is used to print all relevant - information during the prowler execution as a header of execution. - Displaying Account Information with Color Formatting. In Prowler, Account IDs, usernames, and other identifiers are typically displayed using color formatting provided by the colorama module (Fore). - """ - def print_credentials(self): - pass -``` diff --git a/docs/developer-guide/provider.mdx b/docs/developer-guide/provider.mdx new file mode 100644 index 0000000000..85dafc6300 --- /dev/null +++ b/docs/developer-guide/provider.mdx @@ -0,0 +1,3458 @@ +--- +title: 'Prowler Providers' +--- + +## Introduction + +Providers form the backbone of Prowler, enabling security assessments across various cloud environments. + +A provider is any platform or service that offers resources, data, or functionality that can be audited for security and compliance. This includes: + +- Cloud Infrastructure Providers (like Amazon Web Services, Microsoft Azure, and Google Cloud) +- Software as a Service (SaaS) Platforms (like Microsoft 365) +- Development Platforms (like GitHub) +- Container Orchestration Platforms (like Kubernetes) +- Database-as-a-Service Platforms (like MongoDB Atlas) + +For providers supported by Prowler, refer to [Prowler Hub](https://hub.prowler.com/). + + + There are some custom providers added by the community, like [NHN Cloud](https://www.nhncloud.com/), that are not maintained by the Prowler team, but can be used in the Prowler CLI. The main purpose of this documentation is to guide you through creating a new provider and integrating it not only in the CLI, but also in the API and UI. Non official providers can be checked directly at the [Prowler GitHub repository](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers). + +--- + +## Provider Types in Prowler + +Prowler supports several types of providers, each with its own implementation pattern and use case. Understanding these differences is key to designing your provider correctly. + +### Classifying your Provider + +Before implementing a new provider, you need to determine which type it belongs to. This classification will guide your implementation approach and help you choose the right patterns and libraries. + +#### Decision Criteria + +Once you have decided the provider you want or need to add to Prowler, the next step is to study how to retrieve data from it. Based on that, the provider will fall into one of the following types: SDK, API or Tool/Wrapper (maybe in the future there will be new types but for now this are the only ones). + +**Choose SDK Provider if:** + +- The target platform/service has an **official Python SDK** available +- The target platform/service has a **non-official Python SDK** available but it's been updated and maintained +- You need to support **multiple authentication methods** (profiles, service principals, IAM roles, etc.) +- The SDK provides **built-in session management**, retry logic, and error handling +- You want to leverage **SDK-specific features** like credential chaining, role assumption, etc +- The platform is a **major cloud provider** (AWS, Azure, GCP, etc.) or has mature SDK support + +**Choose API Provider if:** + +- The target platform has a **REST API** but **no official Python SDK** +- The target platform has a **non-official Python SDK** available but it's not updated and maintained +- You need to implement **custom authentication flows** (OAuth, token-based, etc.) +- The platform is a **custom or community service** without official SDK support +- You want to use **standard HTTP libraries** like `requests` for API calls +- The platform exposes **well-documented REST endpoints** but lacks SDK tooling + +**Choose Tool/Wrapper Provider if:** + +- You're integrating a **third-party security tool** or library +- The tool provides **scanning capabilities** that need to be adapted to Prowler's interface +- You don't need **authentication or session management** (the tool handles this) +- You need to **map tool arguments** and **convert outputs** to Prowler's format + +**Special Case - Hybrid Providers:** + +- Some providers may **combine multiple approaches** (e.g., SDK + Tool wrapper, SDK + API, etc.) +- Example: M365 uses **msgraph SDK** for authentication and some checks, and **PowerShell wrapper** for other checks that the SDK doesn't support +- These require **custom implementation patterns** that blend different provider types + +#### Classification Examples + +| Provider | Type | Reasoning | +| ----------- | ------ | ----------------------------------------------------------------- | +| AWS | SDK | Official boto3 SDK, multiple auth methods, mature ecosystem | +| Azure | SDK | Official azure-identity SDK, service principals, managed identity | +| GCP | SDK | Official google-auth SDK, service accounts, ADC support | +| Kubernetes | SDK | Official kubernetes SDK, service accounts, ADC support | +| NHN Cloud | API | Custom REST API, no official SDK, community provider | +| MongoDB Atlas| API | Custom REST API, no official SDK | +| IAC | Tool | Third-party security tool that uses trivy, no auth needed, output conversion| +| M365 | Hybrid | Combines msgraph SDK for auth + PowerShell wrapper for operations | +| GitHub | Hybrid | Non-Official PyGithub SDK but it's been updated and maintained + Official graphql API requests| + +#### Questions to Ask Yourself + +**1. Does the platform have an official Python SDK?** + +- Yes → Consider SDK Provider +- No → Continue to question 2 + +**2. Does the platform have a non-official Python SDK?** + +- Yes → Then if the SDK is updated and maintained, consider SDK Provider, otherwise continue to question 3. +- No → Continue to question 3 + +**3. Is this a third-party security tool or library?** + +- Yes → Consider Tool/Wrapper Provider +- No → Continue to question 4 + +**4. Does the platform expose a REST API?** + +- Yes → Consider API Provider +- No → You may need a custom approach + +![FlowChart Decision](../img/provider-decision-tree.png) + +#### Implementation Complexity + +- **SDK Providers**: Low complexity. You have mature examples like AWS, Azure, GCP, Kubernetes, etc. that you can leverage to implement your provider. +- **API Providers**: Medium complexity. You need to implement the authentication and session management, and the API calls to the provider. You now have NHN and MongoDB Atlas as example to follow. +- **Tool/Wrapper Providers**: High complexity. You need to implement the argument/output mapping to the provider and handle problems that the tool/wrapper may have. You now have IAC and the PowerShell wrapper as example to follow. +- **Hybrid Providers**: High complexity. You need to "customize" your provider, mixing the other types of providers in order to achieve the desired result. You have M365 (msgraph SDK + PowerShell wrapper) and Github (PyGithub SDK + graphql API requests) as examples. + +### Determining Regional vs Non-Regional Architecture + +After classifying your provider type, the next critical decision is determining whether your provider operates with **regional concepts** or is **global/non-regional**. This decision fundamentally affects how your provider and services are structured and executed. + +#### Regional Providers + +Regional providers operate across multiple geographic locations and require region-specific resource discovery and iteration. + +**Examples:** + +- **AWS**: Has regions like `us-east-1`, `eu-west-1`, `ap-southeast-2` +- **Azure**: Has regions like `East US`, `West Europe`, `Australia East` +- **GCP**: Has regions like `us-central1`, `europe-west1`, `asia-southeast1` + +**Implementation Requirements:** + +- Must implement region discovery and iteration +- Services must be instantiated per region or handle multi-region data +- Checks must execute across all available/specified regions +- Resource ARNs/IDs must include region information +- Region-specific client initialization + +**Execution Pattern:** + +```python +# Regional provider execution pattern +for region in provider.get_regions(): + regional_client = service.get_regional_client(region) + regional_resources = regional_client.discover_resources() + # Process regional resources +``` + +#### Non-Regional (Global) Providers + +Non-regional providers operate globally without geographic partitioning. + +**Examples:** + +- **GitHub**: Repositories, organizations are global concepts +- **M365**: Tenants operate globally across Microsoft datacenters +- **Kubernetes**: Clusters are independent units without regional concepts + +**Implementation Requirements:** + +- Single global client/session +- No region iteration required +- Global resource discovery +- Simpler resource identification (no region in ARNs/IDs) +- Single audit execution + +**Execution Pattern:** + +```python +# Non-regional provider execution pattern +global_client = service.get_client() +global_resources = global_client.discover_resources() +# Process all resources in single iteration +``` + +#### Decision Matrix + +| Aspect | Regional Provider | Non-Regional Provider | +| ------------------------ | ------------------------ | ---------------------- | +| **Client Init** | Per-region clients | Single global client | +| **Resource Discovery** | Iterate through regions | Single discovery call | +| **Resource ARN/ID** | Include region | Global identifier/None | +| **Audit Execution** | Multi-region loops | Single execution | +| **Service Architecture** | Region-aware services | Global services | +| **Performance** | Parallelizable by region | Linear execution | + +#### Region Discovery + +Region discovery is the process of getting the list of regions that are available for the account. This is done by the provider and is stored in the `prowler/providers//lib/regions/_regions.py` file. + +```python +# File: prowler/providers/aws/aws_provider.py +def get_aws_enabled_regions(self, current_session: Session) -> set: + """get_aws_enabled_regions returns a set of enabled AWS regions""" + try: + # EC2 Client to check enabled regions + service = "ec2" + default_region = self.get_default_region(service) + ec2_client = current_session.client(service, region_name=default_region) + + enabled_regions = set() + # With AllRegions=False we only get the enabled regions for the account + for region in ec2_client.describe_regions(AllRegions=False).get("Regions", []): + enabled_regions.add(region.get("RegionName")) + + return enabled_regions + except Exception as error: + logger.error(f"{error.__class__.__name__}: {error}") + return set() +``` + +The function returns a JSON file containing the list of regions for the provider. It is used to retrieve the provider’s regions and to validate the region specified by the user. + +```json +# File: prowler/providers/aws/aws_regions_by_service.json (extract) +{ + "services": { + "ec2": { + "regions": { + "aws": [ + "af-south-1", "ap-east-1", "ap-northeast-1", "ap-northeast-2", + "ap-northeast-3", "ap-south-1", "ap-southeast-1", "ap-southeast-2", + "ca-central-1", "eu-central-1", "eu-north-1", "eu-south-1", + "eu-west-1", "eu-west-2", "eu-west-3", "me-south-1", + "sa-east-1", "us-east-1", "us-east-2", "us-west-1", "us-west-2" + ], + "aws-cn": ["cn-north-1", "cn-northwest-1"], + "aws-us-gov": ["us-gov-east-1", "us-gov-west-1"] + } + } + } +} +``` + +### Regional Service Implementation + +For detailed guidance on implementing services for regional services, including code examples, service architecture, and check execution patterns, see the [Regional Service Implementation](./services#regional-service-implementation) section in the Services documentation. + +**Key concepts covered:** + +- Threading and parallel processing across regions +- Service implementation patterns for regional providers +- Cross-region resource attribution and ARN handling +- Best practices for performance and error isolation + +## Step 1: Create the Provider Backend (CLI Integration) + +Once the type of provider and its regional architecture are determined, the next step is to start creating the code of the provider. + +### SDK Providers + +General aspects to consider when implementing a new SDK provider: + +**Definition:** + +- Use the official SDK of the provider to interact with its resources and APIs. +- Examples: AWS (boto3), Azure (azure-identity), GCP (google-auth), Kubernetes (kubernetes), M365 (msal/msgraph), GitHub (PyGithub). + +**Typical Use Cases:** + +- Cloud platforms and services with mature Python SDKs. +- Need to support multiple authentication methods (profiles, service principals, etc). +- Providers that offer comprehensive Python libraries for resource management. + +**Key Characteristics:** + +- Authentication and session management handled by the SDK. +- Arguments: Depends on the provider, but for example we can have `profile`, `region`, `tenant_id`, `client_id`, `client_secret`, etc. +- Outputs: Standardized via SDK models and responses. +- Session objects that can be reused across multiple API calls. +- Built-in retry logic and error handling. + +**Implementation Details:** + +- SDK providers typically use credential objects or session objects provided by the official SDK. +- They often support multiple authentication methods (several types of credentials, configuration files, IAM roles, etc.). +- Session management includes token refresh, connection pooling, and retry mechanisms. +- Resource discovery and enumeration is usually straightforward through SDK methods. + +--- + +### Implementation Guide for SDK Providers + +Now it's time to start creating the code needed to implement the provider. + +#### Step 1: Create the Provider Structure + +**Explanation:** +SDK providers require a specific folder structure to organize authentication, configuration, and service management. This structure follows Prowler's conventions and ensures proper integration with the CLI and API. + +**Required Structure:** + +``` +prowler/providers// +ā”œā”€ā”€ __init__.py +ā”œā”€ā”€ _provider.py +ā”œā”€ā”€ models.py +ā”œā”€ā”€ exceptions/ +│ ā”œā”€ā”€ __init__.py +│ └── exceptions.py +ā”œā”€ā”€ services/ +│ ā”œā”€ā”€ service_name1/ +│ └── service_name2/ +└── lib/ + ā”œā”€ā”€ __init__.py + ā”œā”€ā”€ arguments/ + │ ā”œā”€ā”€ __init__.py + │ └── arguments.py + ā”œā”€ā”€ mutelist/ + │ ā”œā”€ā”€ __init__.py + │ └── mutelist.py + ā”œā”€ā”€ regions/ + │ ā”œā”€ā”€ __init__.py + │ └── _regions.py + └── service/ + ā”œā”€ā”€ __init__.py + └── service.py +``` + +**Key Components:** + +- **`_provider.py`**: Main provider class with authentication and session management +- **`models.py`**: Data structures for identity, session, and provider-specific information +- **`exceptions/`**: Custom exception classes for error handling +- **`services/`**: Folder that contains all the provider services, how to make a new service is explained in another section. +- **`lib/arguments/`**: CLI argument validation and parsing +- **`lib/mutelist/`**: Resource exclusion and muting functionality +- **`lib/regions/`**: Region management and validation. If the provider is NOT regional, this folder will not be created. +- **`lib/service/`**: Base service class for provider-specific services + +#### Step 2: Implement the Provider Class + +**Explanation:** +The provider class is the core component that handles authentication, session management, and identity information. It inherits from Prowler's base Provider class and implements SDK-specific authentication flows. All providers must share, as far as possible, common patterns for session setup, identity management, and credential validation. + +Nevertheless, you may encounter changes and must adapt the implementation logic accordingly. A basic example of a common provider implementation is the following: + +**File:** `prowler/providers//_provider.py` + +```python +import os +from typing import Optional, Union +from prowler.providers.common.provider import Provider +from prowler.providers.common.models import Audit_Metadata, Connection +from prowler.config.config import load_and_validate_config_file, get_default_mute_file_path +from prowler.lib.logger import logger +from prowler.lib.utils.utils import print_boxes + +# Import your SDK and all the needed libraries for the provider. +import your_sdk_library +from your_sdk_library.auth_methods import ClientSecretCredential, ProfileCredential, DefaultCredential + +# Import the needed exceptions, mutelist and models for the provider. +from prowler.providers..exceptions.exceptions import Exceptions +from prowler.providers..mutelist.mutelist import Mutelist +from prowler.providers..models import NeededModels + +class YourProvider(Provider): + """ + YourProvider class is the main class for the Your Provider. + + This class is responsible for initializing the provider, setting up the session, + validating credentials, and managing identity information. + + Attributes: + _type (str): The provider type. + _session (YourSDKSession): The provider session. + _identity (YourProviderIdentityInfo): The provider identity information. + _audit_config (dict): The audit configuration. + _mutelist (YourProviderMutelist): The provider mutelist. + audit_metadata (Audit_Metadata): The audit metadata. + """ + + _type: str = "your_provider" + _session: your_sdk_library.Session + _identity: YourProviderIdentityInfo + _audit_config: dict + _mutelist: YourProviderMutelist + audit_metadata: Audit_Metadata + + def __init__( + self, + # Authentication parameters + client_id: str = None, + client_secret: str = None, + tenant_id: str = None, + # Configuration + config_path: str = None, + config_content: dict = None, + mutelist_path: str = None, + mutelist_content: dict = None, + # Additional provider-specific parameters + region: str = None, + profile: str = None, + ): + """ + Initializes the YourProvider instance. + + Args: + client_id: The client ID for authentication + client_secret: The client secret for authentication + tenant_id: The tenant ID for authentication + config_path: Path to the configuration file + config_content: Configuration content as dictionary + mutelist_path: Path to the mutelist file + mutelist_content: Mutelist content as dictionary + region: The region to use + profile: The profile to use + + Raises: + YourProviderSetUpSessionError: If session setup fails + YourProviderInvalidCredentialsError: If credentials are invalid + """ + logger.info("Initializing YourProvider ...") + + # Setup session using SDK + self._session = self.setup_session( + client_id, client_secret, tenant_id, region, profile + ) + + # Get identity information + self._identity = self.setup_identity(self._session) + + # Load configuration + if config_content: + self._audit_config = config_content + else: + if not config_path: + config_path = default_config_file_path + self._audit_config = load_and_validate_config_file(self._type, config_path) + + # Setup mutelist + if mutelist_content: + self._mutelist = YourProviderMutelist(mutelist_content=mutelist_content) + else: + if not mutelist_path: + mutelist_path = get_default_mute_file_path(self._type) + self._mutelist = YourProviderMutelist(mutelist_path=mutelist_path) + + Provider.set_global_provider(self) + + @staticmethod + def setup_session( + client_id: str = None, + client_secret: str = None, + tenant_id: str = None, + region: str = None, + profile: str = None, + ) -> your_sdk_library.Session: + """ + Sets up the provider session using the provided credentials. + + This method handles the authentication flow and creates a session object + that can be used to interact with the provider's services. + + Args: + client_id: The client ID for authentication + client_secret: The client secret for authentication + tenant_id: The tenant ID for authentication + region: The region to use + profile: The profile to use + + Returns: + YourSDKSession: The authenticated session object + + Raises: + YourProviderSetUpSessionError: If session setup fails + """ + try: + logger.debug("Creating session ...") + + # Determine authentication method based on provided parameters + if client_id and client_secret and tenant_id: + # Use client credentials authentication + credentials = your_sdk_library.ClientSecretCredential( + tenant_id=tenant_id, + client_id=client_id, + client_secret=client_secret + ) + auth_method = "Client Credentials" + elif profile: + # Use profile-based authentication + credentials = your_sdk_library.ProfileCredential(profile=profile) + auth_method = "Profile" + else: + # Use default authentication (environment variables, etc.) + credentials = your_sdk_library.DefaultCredential() + auth_method = "Default" + + # Create session with credentials + session = your_sdk_library.Session( + credentials=credentials, + region=region + ) + + logger.debug(f"Session created using {auth_method} authentication") + return session + + except Exception as error: + logger.critical(f"Failed to setup session: {error}") + raise YourProviderSetUpSessionError( + original_exception=error, + file=os.path.basename(__file__), + ) + + def setup_identity(self, session: your_sdk_library.Session) -> YourProviderIdentityInfo: + """ + Gets identity information from the provider session. + + This method retrieves account information, user details, and other + identity-related data from the provider. + + Args: + session: The authenticated session object + + Returns: + YourProviderIdentityInfo: The identity information + + Raises: + YourProviderSetUpIdentityError: If identity setup fails + """ + try: + # Use SDK to get account/identity information + identity_info = session.get_identity() + + return YourProviderIdentityInfo( + account_id=identity_info.account_id, + account_name=identity_info.account_name, + region=identity_info.region, + user_id=identity_info.user_id, + # Add other identity fields as needed + ) + except Exception as e: + logger.error(f"Failed to get identity information: {e}") + raise YourProviderSetUpIdentityError( + original_exception=e, + file=os.path.basename(__file__), + ) + + @property + def identity(self): + """Returns the provider identity information.""" + return self._identity + + @property + def session(self): + """Returns the provider session object.""" + return self._session + + @property + def type(self): + """Returns the provider type.""" + return self._type + + @property + def audit_config(self): + """Returns the audit configuration.""" + return self._audit_config + + @property + def mutelist(self): + """Returns the provider mutelist.""" + return self._mutelist + + def print_credentials(self): + """ + Display account information with color formatting. + + This method prints the provider credentials and account information + in a formatted way using colorama for better readability. + """ + from colorama import Fore, Style + from prowler.lib.utils.utils import print_boxes + + report_lines = [ + f" Account ID: {Fore.YELLOW}{self._identity.account_id}{Style.RESET_ALL}", + f" Account Name: {Fore.YELLOW}{self._identity.account_name}{Style.RESET_ALL}", + f" Region: {Fore.YELLOW}{self._identity.region}{Style.RESET_ALL}", + f" User ID: {Fore.YELLOW}{self._identity.user_id}{Style.RESET_ALL}", + ] + report_title = f"{Style.BRIGHT}Using the {self._type.upper()} credentials below:{Style.RESET_ALL}" + print_boxes(report_lines, report_title) + + @staticmethod + def test_connection( + client_id: str = None, + client_secret: str = None, + tenant_id: str = None, + region: str = None, + profile: str = None, + raise_on_exception: bool = True, + provider_id: str = None, + ) -> Connection: + """ + Test connection to the provider. + + This method validates the provided credentials and tests the connection + to the provider's services. + + Args: + client_id: The client ID for authentication + client_secret: The client secret for authentication + tenant_id: The tenant ID for authentication + region: The region to test + profile: The profile to use + raise_on_exception: Whether to raise exceptions or return Connection object + provider_id: The provider ID to validate against + + Returns: + Connection: Connection test result + + Raises: + YourProviderSetUpSessionError: If session setup fails + YourProviderInvalidCredentialsError: If credentials are invalid + """ + try: + # Create temporary session for testing + test_session = YourProvider.setup_session( + client_id, client_secret, tenant_id, region, profile + ) + + # Test the connection by getting identity + identity = YourProvider.setup_identity(test_session) + + # Validate provider ID if provided + if provider_id and identity.account_id != provider_id: + raise YourProviderInvalidProviderIdError( + file=os.path.basename(__file__), + ) + + return Connection( + status=True, + message=f"Successfully connected to {provider_id or 'provider'}", + error=None, + ) + except Exception as e: + if raise_on_exception: + raise e + return Connection( + status=False, + message="Failed to connect", + error=str(e), + ) + + def get_regions(self) -> set: + """ + Get available regions for the provider. + + Returns: + set: Set of available region names + """ + # Implementation depends on your provider + # Example for cloud providers that support regions + return {"region1", "region2", "region3"} + + def get_services(self) -> list: + """ + Get available services for the provider. + + Returns: + list: List of available service names + """ + # Implementation depends on your provider + return ["service1", "service2", "service3"] +``` + +#### Step 3: Create Models + +**Explanation:** +Models define the data structures used by your provider. They include identity information, session details, and provider-specific configurations. These models ensure type safety and consistent data handling across the provider. + +**File:** `prowler/providers//models.py` + +```python +# Import the needed generic libraries for the provider. +from pydantic import BaseModel +from dataclasses import dataclass +from typing import Optional, List + +# Import the needed Prowler libraries for the provider. +from prowler.providers.common.models import ProviderOutputOptions +from prowler.config.config import output_file_timestamp + +class YourProviderIdentityInfo: + """ + Identity information for the provider. + + This class holds all the identity-related information retrieved + from the provider, including account details and user information. + """ + account_id: str + account_name: str + region: str + user_id: str + # Add other identity fields as needed + +class YourProviderSession: + """ + Session object that contains the credentials and authentication details for the provider. + + This class holds the actual credentials and authentication information needed + to establish a connection with the provider's services. + """ + # Authentication credentials + access_key: str + secret_key: str + # Or for other providers: + # client_id: str + # client_secret: str + # tenant_id: str + + # Connection details + region: str +``` + +#### Step 4: Implement Arguments + +**Explanation:** +Argument validation ensures that the provider receives valid configuration parameters. This step is crucial for preventing runtime errors and providing clear error messages to users. The validation should check for required parameters and validate their format. + +**File:** `prowler/providers//lib/arguments/arguments.py` + +```python +def init_parser(self): + """Init the Provider CLI parser""" + _parser = self.subparsers.add_parser( + "", parents=[self.common_providers_parser], help=" Provider" + ) + # Authentication Modes + _auth_subparser = _parser.add_argument_group("Authentication Modes") + _auth_modes_group = _auth_subparser.add_mutually_exclusive_group() + _auth_modes_group.add_argument( + "--credentials-file", + nargs="?", + metavar="FILE_PATH", + help="Authenticate using a Service Account Application Credentials JSON file", + ) + _auth_modes_group.add_argument( + "--impersonate-service-account", + nargs="?", + metavar="SERVICE_ACCOUNT", + help="Impersonate a Service Account", + ) + _parser.add_argument( + "--your-provider-region", + help="Your Provider Region", + type=str, + ) + _parser.add_argument( + "--env-auth", + action="store_true", + help="Use User and Password environment variables authentication to log in against ", + ) + # More arguments for the provider. +``` + +#### Step 5: Implement Mutelist + +**Explanation:** +The mutelist functionality allows users to exclude specific resources or checks from the audit. This is useful for handling false positives or excluding resources that are intentionally configured differently. + +**File:** `prowler/providers//lib/mutelist/mutelist.py` + +```python +from prowler.lib.mutelist.mutelist import Mutelist +from prowler.lib.check.models import CheckReportYourProvider + +class YourProviderMutelist(Mutelist): + """ + Mutelist implementation for YourProvider. + + This class handles the muting functionality for the provider, + allowing users to exclude specific checks or resources from audits. + """ + + def is_finding_muted(self, finding: CheckReportYourProvider) -> bool: + """ + Check if a specific finding is muted. + + Args: + finding: The finding to check + """ + return self.is_muted(finding.check_id, finding.resource_id) +``` + +#### Step 6: Implement Regions + +**Explanation:** +Region management is essential for cloud providers that operate across multiple geographic locations. This component handles region validation and provides region-specific functionality. + + +Regions are optional, only if the provider has regions, for example Github does not have regions, but AWS does. + + +**File:** `prowler/providers//lib/regions/_regions.py` + +```python +from typing import List, Set + +def get_regions() -> List[str]: + """ + Get list of available regions for the provider. + + Returns: + List[str]: List of available region names + """ + return [ + "region1", + "region2", + "region3", + # ... other regions + ] + +def validate_region(region: str) -> bool: + """ + Validate if a region is supported. + + Args: + region: The region to validate + + Returns: + bool: True if the region is valid, False otherwise + """ + return region in get_regions() + +def get_default_region() -> str: + """ + Get the default region for the provider. + + Returns: + str: The default region name + """ + return "region1" + +def get_global_region() -> str: + """ + Get the global region for the provider. + + Returns: + str: The global region name + """ + return "global" +``` + +#### Step 7: Create Custom Exceptions + +**Explanation:** +Custom exceptions are needed to be able to handle the errors in a more specific way. Prowler uses a structured exception system with error codes, messages, and remediation steps. + +**File:** `prowler/providers//exceptions.py` + +```python +from prowler.exceptions.exceptions import ProwlerException + + +# Exceptions codes from 7000 to 7999 are reserved for YourProvider exceptions (Numbers as example) +class YourProviderBaseException(ProwlerException): + """Base class for YourProvider Errors.""" + + YOUR_PROVIDER_ERROR_CODES = { + (7001, "YourProviderCredentialsError"): { + "message": "Error loading credentials for YourProvider", + "remediation": "Check the credentials and ensure they are properly set up. API_KEY and API_SECRET are required.", + }, + (7002, "YourProviderAuthenticationError"): { + "message": "Authentication failed with YourProvider", + "remediation": "Check the API credentials and ensure they are valid and have proper permissions.", + }, + (7003, "YourProviderInvalidRegionError"): { + "message": "Invalid region provided for YourProvider", + "remediation": "Check the region and ensure it is a valid region for YourProvider.", + }, + (7004, "YourProviderSetUpSessionError"): { + "message": "Error setting up session", + "remediation": "Check the session setup and ensure it is properly configured.", + }, + (7005, "YourProviderInvalidProviderIdError"): { + "message": "Provider does not match with the expected account_id", + "remediation": "Check the provider and ensure it matches the expected account_id.", + }, + } + + def __init__(self, code, file=None, original_exception=None, message=None): + provider = "YourProvider" + error_info = self.YOUR_PROVIDER_ERROR_CODES.get((code, self.__class__.__name__)) + if message: + error_info["message"] = message + super().__init__( + code=code, + source=provider, + file=file, + original_exception=original_exception, + error_info=error_info, + ) + + +class YourProviderCredentialsError(YourProviderBaseException): + """Base class for YourProvider credentials errors.""" + + def __init__(self, file=None, original_exception=None, message=None): + super().__init__( + 7001, file=file, original_exception=original_exception, message=message + ) + + +class YourProviderAuthenticationError(YourProviderCredentialsError): + def __init__(self, file=None, original_exception=None, message=None): + super().__init__( + 7002, file=file, original_exception=original_exception, message=message + ) + + +class YourProviderInvalidRegionError(YourProviderBaseException): + def __init__(self, file=None, original_exception=None, message=None): + super().__init__( + 7003, file=file, original_exception=original_exception, message=message + ) + + +class YourProviderSetUpSessionError(YourProviderCredentialsError): + def __init__(self, file=None, original_exception=None, message=None): + super().__init__( + 7004, file=file, original_exception=original_exception, message=message + ) + + +class YourProviderInvalidProviderIdError(YourProviderBaseException): + def __init__(self, file=None, original_exception=None, message=None): + super().__init__( + 7005, file=file, original_exception=original_exception, message=message + ) +``` + +#### Step 8: Implement Service Base Class + +**Explanation:** +The service base class defines a common interface for all services in your provider, since they will inherit from it. It defines the client to make requests to, the audit configuration and the fixer configuration. + +**File:** `prowler/providers//lib/service/service.py` + +```python +from prowler.providers.._provider import Provider + +class YourProviderService(BaseService): + """ + Base service class for YourProvider services. + + This class provides common functionality for all services + within the provider, including session management and error handling. + """ + + def __init__(self, provider: Provider): + """ + Initialize the service. + + Args: + provider: The provider instance + """ + self.client = provider.session.get_client(self.service_name) + self.audit_config = provider.audit_config + self.fixer_config = provider.fixer_config +``` + +#### Step 9: Register in CLI + +**Explanation:** +Add your provider to the available providers in the CLI. + +**File:** `prowler/lib/cli/parser.py` + +```python +class ProwlerArgumentParser: + # Set the default parser + def __init__(self): + # CLI Arguments + self.parser = argparse.ArgumentParser( + prog="prowler", + formatter_class=RawTextHelpFormatter, + usage="prowler [-h] [--version] {aws,azure,gcp,kubernetes,m365,github,nhn,dashboard,iac,your_provider} ...", + epilog=""" +Available Cloud Providers: + {aws,azure,gcp,kubernetes,m365,github,iac,nhn,your_provider} + aws AWS Provider + azure Azure Provider + gcp GCP Provider + kubernetes Kubernetes Provider + m365 Microsoft 365 Provider + github GitHub Provider + iac IaC Provider (Preview) + nhn NHN Provider (Unofficial) + your_provider Your Provider + +Available components: + dashboard Local dashboard + +To see the different available options on a specific component, run: + prowler {provider|dashboard} -h|--help + +Detailed documentation at https://docs.prowler.com +""", +``` + +#### Step 10: Register in Main + +**Explanation:** +Main registration makes your provider discoverable by Prowler's core system. It's needed to add your provider to the output options and to the compliance evaluation. + +**File:** `prowler/__main__.py` + +```python +# In the prowler setup output options section + if provider == "aws": + output_options = AWSOutputOptions( + args, bulk_checks_metadata, global_provider.identity + ) + elif provider == "azure": + output_options = AzureOutputOptions( + args, bulk_checks_metadata, global_provider.identity + ) + elif provider == "gcp": + output_options = GCPOutputOptions( + args, bulk_checks_metadata, global_provider.identity + ) + elif provider == "kubernetes": + output_options = KubernetesOutputOptions( + args, bulk_checks_metadata, global_provider.identity + ) + elif provider == "github": + output_options = GithubOutputOptions( + args, bulk_checks_metadata, global_provider.identity + ) + elif provider == "m365": + output_options = M365OutputOptions( + args, bulk_checks_metadata, global_provider.identity + ) + elif provider == "nhn": + output_options = NHNOutputOptions( + args, bulk_checks_metadata, global_provider.identity + ) + elif provider == "iac": + output_options = IACOutputOptions( + args, bulk_checks_metadata + ) + elif provider == "your_provider": + output_options = YourProviderOutputOptions( + args, bulk_checks_metadata, global_provider.identity + ) + + + # Setup Compliance Options + elif provider == "your_provider": + for compliance_name in input_compliance_frameworks: + if compliance_name.startswith("cis_"): + # Generate CIS Finding Object (example of compliance with CIS framework) + filename = ( + f"{output_options.output_directory}/compliance/" + f"{output_options.output_filename}_{compliance_name}.csv" + ) + cis = YourProviderCIS( + findings=finding_outputs, + compliance=bulk_compliance_frameworks[compliance_name], + file_path=filename, + ) + generated_outputs["compliance"].append(cis) + cis.batch_write_data_to_file() +``` + +#### Step 11: Register in the list of providers + +**Explanation:** +This is needed to be able to use the provider in the generic checks. The provider must be registered in the `init_global_provider` method to handle CLI arguments and initialization. + +**File:** `prowler/providers/common/provider.py` + +```python +elif "your_provider" in provider_class_name.lower(): + provider_class( + username=arguments.your_provider_username, + password=arguments.your_provider_password, + tenant_id=arguments.your_provider_tenant_id, + config_path=arguments.config_file, + mutelist_path=arguments.mutelist_file, + fixer_config=fixer_config, + ) +``` + +#### Step 12: Add to Config + +**Explanation:** +Configuration registration ensures your provider is recognized by Prowler's configuration system. This enables proper handling of provider-specific settings and defaults. + +**File:** `prowler/config/config.py` + +```python +class Provider(str, Enum): + AWS = "aws" + AZURE = "azure" + GCP = "gcp" + KUBERNETES = "kubernetes" + M365 = "m365" + GITHUB = "github" + YOUR_PROVIDER = "your_provider" # Add your provider here +``` + +In some cases, you may need to create a new configuration file for your provider, for example, the AWS one that is inside `prowler/providers/aws/config.py`. + +#### Step 13: Create Compliance Files + +**Explanation:** +Compliance files define the security checks and standards that your provider supports. These JSON files map security controls to specific checks and provide remediation guidance. It's needed to create the folder with an init file to ensure the provider will work, however, adding different compliance files is optional. + +**Folder:** `prowler/compliance//` + +```json +{ + "Framework": "CIS", + "Version": "1.0", + "Provider": "your_provider", + "Description": "Description of the compliance framework", + # The requirements depends on the framework, for example, CIS has a requirements section with the checks and attributes. + "Requirements": [ + { + "Id": "1.1.1", + "Description": "Description of the requirement", + "Checks": ["your_provider_check_1", "your_provider_check_2"], + "Attributes": [] + } + ] +} +``` + +#### Step 14: Add Output Support + +**Explanation:** +Output support ensures that your provider's results are properly formatted in Prowler's various output formats (CSV, JSON, HTML, etc.). This step integrates your provider with Prowler's reporting system. + +**File:** `prowler/lib/outputs/summary_table.py` + +```python +# Add your provider case in the display_summary_table function +elif provider.type == "your_provider": + entity_type = "Your Entity Type" + audited_entities = provider.identity.your_entity_field +``` + +**File:** `prowler/lib/outputs/finding.py` + +```python +# Add your provider case in the fill_common_finding_data function +elif provider.type == "your_provider": + output_data["auth_method"] = f"Your Auth Method: {get_nested_attribute(provider, 'identity.auth_type')}" + output_data["account_uid"] = get_nested_attribute(provider, "identity.account_id") + output_data["account_name"] = get_nested_attribute(provider, "identity.account_name") + output_data["resource_name"] = check_output.resource_name + output_data["resource_uid"] = check_output.resource_id + output_data["region"] = check_output.location # or your location field +``` + +**File:** `prowler/lib/outputs/outputs.py` + +```python +# Add your provider case in the stdout_report function +if finding.check_metadata.Provider == "your_provider": + details = finding.your_location_field # e.g., finding.location, finding.namespace, etc. +``` + +#### Step 15: Generate the HTML Report + +**Explanation:** +The HTML file is needed to be able to generate the HTML report. This step involves adding support for your provider in the HTML output generation system to ensure proper display of assessment summaries and findings. + +**File:** `prowler/lib/outputs/html/html.py` + +```python +@staticmethod +def get_your_provider_assessment_summary(provider: Provider) -> str: + """ + get_your_provider_assessment_summary gets the HTML assessment summary for your provider + + Args: + provider (Provider): the provider object + + Returns: + str: the HTML assessment summary + """ + try: + return f""" +
+
+
+ Your Provider Assessment Summary +
+
    +
  • + Your Entity Type: {provider.identity.your_entity_field} +
  • +
  • + Your Location Field: {provider.identity.your_location_field} +
  • +
+
+
+
+
+
+ Your Provider Credentials +
+
    +
  • + Authentication Method: {provider.auth_method} +
  • +
  • + Identity ID: {provider.identity.identity_id} +
  • +
+
+
""" + except Exception as error: + logger.error( + f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}] -- {error}" + ) + return "" +``` + +#### Step 16: Add the Check Report Model + +**Explanation:** +Add the provider to the generic models, this is needed to be able to use the provider in the generic checks. + +**File:** `prowler/providers/check/models.py` + +```python +@dataclass +class CheckReportYourProvider(CheckReport): + """ + Check report for YourProvider. + """ + resource_name: str + resource_id: str + + def _init_(self, metadata: Dict, resource: Any) -> None: + super()._init_(metadata, resource) + self.resource_name = resource.name + self.resource_id = resource.id +``` + +#### Step 17: Add Dependencies + +**Explanation:** +Dependencies ensure that your provider's required libraries are available when Prowler is installed. This step adds the necessary SDK or API client to Prowler's dependency management. + +**File:** `pyproject.toml` + +```toml +[tool.poetry.dependencies] +python = "^3.9" +# ... other dependencies +your-sdk-library = "^1.0.0" # Add your SDK dependency +``` + +#### Step 18: Create Tests + +**Explanation:** +Testing ensures that your provider works correctly and maintains compatibility as Prowler evolves. Comprehensive tests cover authentication, session management, and provider-specific functionality. + +**Folder:** `tests/providers//` + +```python +import pytest +from prowler.providers.your_provider.your_provider import YourProvider + +class TestYourProvider: + """Test cases for YourProvider.""" + + def test_provider_initialization_with_client_credentials(self): + """Test provider initialization with client credentials.""" + provider = YourProvider( + client_id="test_client_id", + client_secret="test_client_secret", + tenant_id="test_tenant_id" + ) + assert provider.type == "your_provider" + assert provider.identity is not None + assert provider.session is not None + + def test_provider_initialization_with_profile(self): + """Test provider initialization with profile.""" + provider = YourProvider( + profile="test_profile" + ) + assert provider.type == "your_provider" + assert provider.identity is not None + + def test_connection_test(self): + """Test connection functionality.""" + result = YourProvider.test_connection( + client_id="test_client_id", + client_secret="test_client_secret", + tenant_id="test_tenant_id" + ) + # Add assertions based on expected behavior + + def test_identity_retrieval(self): + """Test identity information retrieval.""" + provider = YourProvider( + client_id="test_client_id", + client_secret="test_client_secret", + tenant_id="test_tenant_id" + ) + assert provider.identity.account_id is not None + assert provider.identity.account_name is not None + + def test_argument_validation(self): + """Test argument validation.""" + from prowler.providers.your_provider.lib.arguments.arguments import ( + validate_your_provider_arguments + ) + + # Valid arguments + validate_your_provider_arguments( + client_id="test_client_id", + client_secret="test_client_secret", + tenant_id="test_tenant_id" + ) + + # Invalid arguments + with pytest.raises(ValueError, match="at least one authentication method"): + validate_your_provider_arguments() +``` + +#### Step 19: Update Documentation + +**Explanation:** +Documentation updates ensure that users can find information about your provider in Prowler's documentation. This includes examples, configuration guides, and troubleshooting information. + +Update the provider documentation to include your new provider in the examples and implementation guidance. + +--- + +### API Providers + +**Definition:** + +- Interact directly with the provider's REST API using HTTP requests (e.g., via `requests`). +- Examples: NHN Cloud. + +**Typical Use Cases:** + +- Providers without an official Python SDK. +- Providers with a non-official Python SDK that is not updated and maintained. +- Providers that expose REST APIs and meet above requirements. + +**Key Characteristics:** + +- Manual management of authentication (tokens, username/password, etc). +- Arguments: Depends on the provider, for example, `username`, `password`, `tenant_id`, etc. +- Outputs: Dicts or custom models based on API responses. +- Custom HTTP session management with headers and authentication. +- Manual handling of pagination, rate limiting, and error responses. + +**Implementation Details:** + +- API providers require manual HTTP request management using libraries like `requests`. +- Authentication typically involves obtaining tokens via login endpoints or OAuth flows. +- Session management includes setting appropriate headers (Authorization, Content-Type, etc.). +- Resource discovery often requires multiple API calls to different endpoints. +- Error handling and retry logic must be implemented manually. + +--- + +### Implementation Guide for API Providers + +#### Step 1: Create the Provider Structure + +**Explanation:** +API providers require the same structure as the SDK providers, the main difference would be that due to the lack of an official Python SDK, some methods could be implemented differently or not implemented at all. + +**Required Structure:** + +``` +prowler/providers// +ā”œā”€ā”€ __init__.py +ā”œā”€ā”€ _provider.py +ā”œā”€ā”€ models.py +ā”œā”€ā”€ exceptions/ +│ ā”œā”€ā”€ __init__.py +│ └── exceptions.py +ā”œā”€ā”€ services/ +│ ā”œā”€ā”€ service_name1/ +│ └── service_name2/ +└── lib/ + ā”œā”€ā”€ __init__.py + ā”œā”€ā”€ arguments/ + │ ā”œā”€ā”€ __init__.py + │ └── arguments.py + ā”œā”€ā”€ mutelist/ + │ ā”œā”€ā”€ __init__.py + │ └── mutelist.py + ā”œā”€ā”€ regions/ + │ ā”œā”€ā”€ __init__.py + │ └── regions.py + └── service/ + ā”œā”€ā”€ __init__.py + └── service.py +``` + +**Key Components:** + +- **`_provider.py`**: Main provider class with HTTP session management +- **`models.py`**: Data structures for identity and API responses +- **`exceptions/`**: Custom exception classes for API errors +- **`services/`**: Folder that contains all the provider services +- **`lib/arguments/`**: CLI argument validation and parsing +- **`lib/mutelist/`**: Resource exclusion and muting functionality +- **`lib/regions/`**: Region management and validation. If the provider is NOT regional, this folder will not be created. +- **`lib/service/`**: Base service class for provider-specific services + +#### Step 2: Implement the Provider Class + +**Explanation:** +The provider class is the core component that handles HTTP session management, authentication, and identity information. It inherits from Prowler's base Provider class and implements API-specific authentication flows using direct HTTP requests. + +**File:** `prowler/providers//_provider.py` + +```python +import os +from typing import Optional +import requests +from prowler.providers.common.provider import Provider +from prowler.providers.common.models import Audit_Metadata, Connection +from prowler.config.config import load_and_validate_config_file, get_default_mute_file_path +from prowler.lib.logger import logger +from prowler.lib.utils.utils import print_boxes + +# Import the needed exceptions, mutelist and models for the provider. +from prowler.providers..exceptions.exceptions import Exceptions +from prowler.providers..lib.mutelist.mutelist import Mutelist +from prowler.providers..models import NeededModels + +class APIProvider(Provider): + """ + APIProvider class is the main class for the API Provider. + + This class is responsible for initializing the provider, setting up the HTTP session, + validating credentials, and managing identity information through direct API calls. + + Attributes: + _type (str): The provider type. + _session (requests.Session): The HTTP session for API calls. + _identity (APIIdentityInfo): The provider identity information. + _audit_config (dict): The audit configuration. + _mutelist (APIMutelist): The provider mutelist. + audit_metadata (Audit_Metadata): The audit metadata. + """ + + _type: str = "api_provider" + _session: Optional[requests.Session] + _identity: APIIdentityInfo + _audit_config: dict + _mutelist: APIMutelist + audit_metadata: Audit_Metadata + + def __init__( + self, + # Authentication parameters + username: str = None, + password: str = None, + tenant_id: str = None, + # Configuration + config_path: str = None, + config_content: dict = None, + mutelist_path: str = None, + mutelist_content: dict = None, + fixer_config: dict = None, + ): + """ + Initializes the APIProvider instance. + + Args: + username: The API username for authentication + password: The API password for authentication + tenant_id: The tenant ID for authentication + config_path: Path to the configuration file + config_content: Configuration content as dictionary + mutelist_path: Path to the mutelist file + mutelist_content: Mutelist content as dictionary + fixer_config: Fixer configuration dictionary + + Raises: + ValueError: If required authentication parameters are missing + """ + logger.info("Initializing APIProvider ...") + + # 1) Store argument values with environment variable fallback + self._username = username or os.getenv("YOUR_PROVIDER_USERNAME") + self._password = password or os.getenv("YOUR_PROVIDER_PASSWORD") + self._tenant_id = tenant_id or os.getenv("YOUR_PROVIDER_TENANT_ID") + + # Validate required parameters + if not all([self._username, self._password, self._tenant_id]): + raise ValueError("APIProvider requires username, password and tenant_id") + + # 2) Load audit_config, fixer_config, mutelist + self._fixer_config = fixer_config if fixer_config else {} + + if config_content: + self._audit_config = config_content + else: + if not config_path: + config_path = default_config_file_path + self._audit_config = load_and_validate_config_file(self._type, config_path) + + if mutelist_content: + self._mutelist = APIMutelist(mutelist_content=mutelist_content) + else: + if not mutelist_path: + mutelist_path = get_default_mute_file_path(self._type) + self._mutelist = APIMutelist(mutelist_path=mutelist_path) + + # 3) Initialize session/token + self._token = None + self._session = None + self.setup_session() + + # 4) Create identity object + self._identity = APIIdentityInfo( + tenant_id=self._tenant_id, + username=self._username, + ) + + Provider.set_global_provider(self) + + @property + def type(self) -> str: + """Returns the type of the provider.""" + return self._type + + @property + def identity(self) -> APIIdentityInfo: + """Returns the provider identity information.""" + return self._identity + + @property + def session(self) -> requests.Session: + """Returns the HTTP session for API calls.""" + return self._session + + @property + def audit_config(self) -> dict: + """Returns the audit configuration.""" + return self._audit_config + + @property + def fixer_config(self) -> dict: + """Returns the fixer configuration.""" + return self._fixer_config + + @property + def mutelist(self) -> APIMutelist: + """Returns the provider mutelist.""" + return self._mutelist + + def print_credentials(self) -> None: + """ + Display account information with color formatting. + + This method prints the provider credentials and account information + in a formatted way using colorama for better readability. + """ + from colorama import Style + + report_lines = [ + f" Username: {self._username}", + f" TenantID: {self._tenant_id}", + ] + report_title = f"{Style.BRIGHT}Using the {self._type.upper()} credentials below:{Style.RESET_ALL}" + print_boxes(report_lines, report_title) + + def setup_session(self) -> None: + """ + Implement API authentication method by calling the provider's authentication endpoint. + + This method performs the authentication flow to obtain an access token + and creates a requests.Session with the appropriate headers for API calls. + """ + # Example for a Keystone-like authentication + url = "https://api.your-provider.com/v2.0/tokens" + data = { + "auth": { + "tenantId": self._tenant_id, + "passwordCredentials": { + "username": self._username, + "password": self._password, + }, + } + } + + try: + response = requests.post(url, json=data, timeout=10) + if response.status_code == 200: + resp_json = response.json() + self._token = resp_json["access"]["token"]["id"] + + # Create session with authentication headers + sess = requests.Session() + sess.headers.update({ + "X-Auth-Token": self._token, + "Content-Type": "application/json" + }) + self._session = sess + logger.info("API token acquired successfully and session is set up.") + else: + logger.critical( + f"Failed to get token. Status: {response.status_code}, Body: {response.text}" + ) + raise ValueError("Failed to get API token") + except Exception as e: + logger.critical(f"[setup_session] Error: {e}") + raise e + + @staticmethod + def test_connection( + username: str, + password: str, + tenant_id: str, + raise_on_exception: bool = True, + ) -> Connection: + """ + Test connection to the API provider by performing: + 1) Authentication token request + 2) (Optional) a small test API call to confirm credentials are valid + + Args: + username: The API username + password: The API password + tenant_id: The tenant ID + raise_on_exception: If True, raise the caught exception; + if False, return Connection(error=exception). + + Returns: + Connection: Connection test result + """ + try: + # 1) Validate arguments + if not username or not password or not tenant_id: + error_msg = "API test_connection error: missing username/password/tenant_id" + logger.error(error_msg) + raise ValueError(error_msg) + + # 2) Request authentication token + token_url = "https://api.your-provider.com/v2.0/tokens" + data = { + "auth": { + "tenantId": tenant_id, + "passwordCredentials": { + "username": username, + "password": password, + }, + } + } + + resp = requests.post(token_url, json=data, timeout=10) + if resp.status_code != 200: + error_msg = f"Failed to get token. Status: {resp.status_code}, Body: {resp.text}" + logger.error(error_msg) + if raise_on_exception: + raise Exception(error_msg) + return Connection(error=Exception(error_msg)) + + # Success + token_json = resp.json() + api_token = token_json["access"]["token"]["id"] + logger.info("API test_connection: Successfully acquired token.") + + # 3) (Optional) Test API call to confirm credentials are valid + test_endpoint = f"https://api.your-provider.com/v2/{tenant_id}/test" + headers = { + "X-Auth-Token": api_token, + "Content-Type": "application/json", + } + + test_resp = requests.get(test_endpoint, headers=headers, timeout=10) + if test_resp.status_code == 200: + logger.info("API test_connection: Test call success. Credentials valid.") + return Connection(is_connected=True) + else: + error_msg = f"Test call failed. Status: {test_resp.status_code}, Body: {test_resp.text}" + logger.error(error_msg) + if raise_on_exception: + raise Exception(error_msg) + return Connection(error=Exception(error_msg)) + + except Exception as e: + logger.critical(f"{e.__class__.__name__}[{e.__traceback__.tb_lineno}]: {e}") + if raise_on_exception: + raise e + return Connection(error=e) + + @staticmethod + def validate_arguments(username: str, password: str, tenant_id: str) -> None: + """ + Ensures that username, password, and tenant_id are not empty. + + Args: + username: The username to validate + password: The password to validate + tenant_id: The tenant ID to validate + + Raises: + ValueError: If any required parameter is missing + """ + if not username or not password or not tenant_id: + raise ValueError("API Provider requires username, password and tenant_id.") +``` + +#### Step 3: Create Models + +**Explanation:** +Models define the data structures used by your API provider. They include identity information and API response structures. These models ensure type safety and consistent data handling across the provider. + +**File:** `prowler/providers//models.py` + +This step is common with SDK providers so you can follow the same pattern as [there](#step-3-create-models). + +#### Step 4: Implement Arguments + +**Explanation:** +Argument validation ensures that the API provider receives valid configuration parameters. This step is crucial for preventing runtime errors and providing clear error messages to users. + +**File:** `prowler/providers//lib/arguments/arguments.py` + +Arguments depends on the provider and not the type, so the pattern for this step is the same as the [SDK providers](#step-4-implement-arguments). + +#### Step 5: Implement Mutelist + +**Explanation:** +The mutelist functionality allows users to exclude specific resources or checks from the audit. This is useful for handling false positives or excluding resources that are intentionally configured differently. + +**File:** `prowler/providers//lib/mutelist/mutelist.py` + +The implementation of the mutelist is the same as the [SDK providers](#step-5-implement-mutelist). + +#### Step 6: Implement Regions + +**Explanation:** +Region management is essential for cloud providers that operate across multiple geographic locations. This component handles region validation and provides region-specific functionality. + + +Regions are optional, only if the provider has regions, for example Github does not have regions, but AWS does. + + +**File:** `prowler/providers//lib/regions/_regions.py` + +The implementation of the regions is the same as the [SDK providers](#step-6-implement-regions). + +#### Step 7: Create Custom Exceptions + +**Explanation:** +Custom exceptions provide specific error handling for API-related issues, making debugging and error reporting more effective. Prowler uses a structured exception system with error codes, messages, and remediation steps. + +**File:** `prowler/providers//exceptions/exceptions.py` + +```python +from prowler.exceptions.exceptions import ProwlerException + + +# Exceptions codes from 8000 to 8999 are reserved for API Provider exceptions (example numbers) +class APIProviderBaseException(ProwlerException): + """Base class for API Provider Errors.""" + + APIProvider_ERROR_CODES = { + (8000, "APIProviderCredentialsError"): { + "message": "API Provider credentials not found or invalid", + "remediation": "Check the API Provider API credentials and ensure they are properly set.", + }, + (8001, "APIProviderAuthenticationError"): { + "message": "API Provider authentication failed", + "remediation": "Check the API Provider API credentials and ensure they are valid.", + }, + (8002, "APIProviderSessionError"): { + "message": "API Provider session setup failed", + "remediation": "Check the session setup and ensure it is properly configured.", + }, + (8003, "APIProviderIdentityError"): { + "message": "API Provider identity setup failed", + "remediation": "Check credentials and ensure they are properly set up for API Provider.", + }, + (8004, "APIProviderAPIError"): { + "message": "API Provider API call failed", + "remediation": "Check the API request and ensure it is properly formatted.", + }, + (8005, "APIProviderRateLimitError"): { + "message": "API Provider API rate limit exceeded", + "remediation": "Reduce the number of API requests or wait before making more requests.", + }, + } + + def __init__(self, code, file=None, original_exception=None, message=None): + provider = "API Provider" + error_info = self.APIProvider_ERROR_CODES.get((code, self.__class__.__name__)) + if message: + error_info["message"] = message + super().__init__( + code=code, + source=provider, + file=file, + original_exception=original_exception, + error_info=error_info, + ) + + +class APIProviderCredentialsError(APIProviderBaseException): + """Exception for API Provider credentials errors""" + + def __init__(self, file=None, original_exception=None, message=None): + super().__init__( + code=8000, + file=file, + original_exception=original_exception, + message=message, + ) + + +class APIProviderAuthenticationError(APIProviderBaseException): + """Exception for API Provider authentication errors""" + + def __init__(self, file=None, original_exception=None, message=None): + super().__init__( + code=8001, + file=file, + original_exception=original_exception, + message=message, + ) + + +class APIProviderSessionError(APIProviderBaseException): + """Exception for API Provider session setup errors""" + + def __init__(self, file=None, original_exception=None, message=None): + super().__init__( + code=8002, + file=file, + original_exception=original_exception, + message=message, + ) + + +class APIProviderIdentityError(APIProviderBaseException): + """Exception for API Provider identity setup errors""" + + def __init__(self, file=None, original_exception=None, message=None): + super().__init__( + code=8003, + file=file, + original_exception=original_exception, + message=message, + ) + + +class APIProviderAPIError(APIProviderBaseException): + """Exception for API Provider API errors""" + + def __init__(self, file=None, original_exception=None, message=None): + super().__init__( + code=8004, + file=file, + original_exception=original_exception, + message=message, + ) + + +class APIProviderRateLimitError(APIProviderBaseException): + """Exception for API Provider rate limit errors""" + + def __init__(self, file=None, original_exception=None, message=None): + super().__init__( + code=8005, + file=file, + original_exception=original_exception, + message=message, + ) +``` + +#### Step 8: Implement Service Base Class + +**Explanation:** +The service base class defines a common interface for all services in your provider, since they will inherit from it. It defines the client to make requests to, the audit configuration and the fixer configuration. + +**File:** `prowler/providers//lib/service/service.py` + +```python +from prowler.providers.._provider import Provider + +class APIProviderService(BaseService): + """ + Base service class for API Provider services. + + This class provides common functionality for all services + within the provider, including session management and error handling. + """ + + def __init__(self, provider: Provider): + """ + Initialize the service. + + Args: + provider: The provider instance + """ + self.client = provider.session.get_client(self.service_name) + self.audit_config = provider.audit_config + self.fixer_config = provider.fixer_config + self.session = provider.session + self.base_url = provider.session.base_url + self.auth = HTTPDigestAuth( + provider.session.public_key, + provider.session.private_key, + ) + self.headers = { + "Authorization": self.auth.encode(), + "Content-Type": "application/json", + } +``` + +#### Step 9: Register in CLI + +**Explanation:** +Add your provider to the available providers in the CLI. + +**File:** `prowler/lib/cli/parser.py` + +This step is the same as the [SDK providers](#step-9-register-in-cli). + +#### Step 10: Register in Main + +**Explanation:** +Main registration makes your provider discoverable by Prowler's core system. It's needed to add your provider to the output options and to the compliance evaluation. + +**File:** `prowler/__main__.py` + +This step is the same as the [SDK providers](#step-10-register-in-main). + +#### Step 11: Register in the list of providers + +**Explanation:** +This is needed to be able to use the provider in the generic checks. The provider must be registered in the `init_global_provider` method to handle CLI arguments and initialization. + +**File:** `prowler/providers/common/provider.py` + +This step is the same as the [SDK providers](#step-11-register-in-the-list-of-providers). + +#### Step 12: Add to Config + +**Explanation:** +Configuration registration ensures your API provider is recognized by Prowler's configuration system. This enables proper handling of provider-specific settings and defaults. + +**File:** `prowler/config/config.py` + +This step is the same as the [SDK providers](#step-12-add-to-config). + +#### Step 13: Create Compliance Files + +**Explanation:** +Compliance files define the security checks and standards that your provider supports. These JSON files map security controls to specific checks and provide remediation guidance. It's needed to create the folder with an init file to ensure the provider will work, however, adding different compliance files is optional. + +**Folder:** `prowler/compliance//` + +This step is the same as the [SDK providers](#step-13-create-compliance-files). + +#### Step 14: Add Output Support + +**Explanation:** +Output support ensures that your provider's results are properly formatted in Prowler's various output formats (CSV, JSON, HTML, etc.). This step integrates your provider with Prowler's reporting system. + +**File:** `prowler/lib/outputs/summary_table.py` + +This step is the same as the [SDK providers](#step-14-add-output-support). + +#### Step 15: Generate the HTML Report + +**Explanation:** +The HTML file is needed to be able to generate the HTML report. This step involves adding support for your provider in the HTML output generation system to ensure proper display of assessment summaries and findings. + +**File:** `prowler/lib/outputs/html/html.py` + +This step is the same as the [SDK providers](#step-15-generate-the-html-report). + +#### Step 16: Add the Check Report Model + +**Explanation:** +Add the provider to the generic models, this is needed to be able to use the provider in the generic checks. + +**File:** `prowler/providers/check/models.py` + +This step is the same as the [SDK providers](#step-16-add-the-check-report-model). + +#### Step 17: Create Tests + +**Explanation:** +Testing ensures that your API provider works correctly and maintains compatibility as Prowler evolves. Comprehensive tests cover authentication, session management, and API-specific functionality. + +**Folder:** `tests/providers//` + +```python +import pytest +from prowler.providers.api_provider.api_provider import APIProvider + +class TestAPIProvider: + """Test cases for APIProvider.""" + + def test_provider_initialization(self): + """Test provider initialization with valid credentials.""" + provider = APIProvider( + username="test_user", + password="test_password", + tenant_id="test_tenant" + ) + assert provider.type == "your_api_provider" + assert provider.identity is not None + assert provider.session is not None + + def test_connection_test(self): + """Test connection functionality.""" + result = APIProvider.test_connection( + username="test_user", + password="test_password", + tenant_id="test_tenant" + ) + # Add assertions based on expected behavior + + def test_argument_validation(self): + """Test argument validation.""" + from prowler.providers.api_provider.api_provider import ( + APIProvider + ) + + # Valid arguments + APIProvider.validate_arguments( + username="test_user", + password="test_password", + tenant_id="test_tenant" + ) + + # Invalid arguments + with pytest.raises(ValueError, match="requires username, password and tenant_id"): + APIProvider.validate_arguments("", "", "") + + def test_session_setup(self): + """Test session setup.""" + provider = APIProvider( + username="test_user", + password="test_password", + tenant_id="test_tenant" + ) + assert provider.session is not None + assert "X-Auth-Token" in provider.session.headers +``` + +#### Step 18: Update Documentation + +**Explanation:** +Documentation updates ensure that users can find information about your API provider in Prowler's documentation. This includes examples, configuration guides, and troubleshooting information. + +Update the provider documentation to include your new API provider in the examples and implementation guidance. + +--- + +### Tool/Wrapper Providers + +**Definition:** + +- Integrate third-party tools as libraries or subprocesses (e.g., Trivy for IaC). +- Examples: IaC (Trivy). + +**Typical Use Cases:** + +- Providers that require integration with external security tools. +- Tools that need to be executed as subprocesses or imported as libraries. +- Providers that require specific tool configurations and argument mapping. +- Legacy systems or tools that don't have direct API access. + +**Key Characteristics:** + +- No session/identity management required (tool handles this internally). +- Arguments: specific to the tool, but for example: `scan_path`, `frameworks`, `exclude_path`, `scan_repository_url`, etc. +- Outputs: Tool-specific output formats that need to be parsed and converted. +- Tool execution and output parsing. +- Configuration file mapping and argument translation. + +**Implementation Details:** + +- Tool providers typically execute external tools as subprocesses (e.g., `pwsh` or `trivy` command). +- They require mapping between Prowler's interface and the tool's arguments. +- Output parsing and conversion to Prowler's standard format is crucial. +- Tool-specific configuration files and validation. +- Repository cloning and temporary file management for remote scans (if needed). + +**Note:** This guide provides a general framework for integrating any external tool. The specific implementation details (like repository cloning, authentication tokens, etc.) will depend on your particular tool's requirements. The core pattern is: integrate with Prowler's CLI, execute your tool via subprocess, and parse the output into Prowler's format. + +--- + +### Implementation Guide for Tool/Wrapper Providers + +#### Step 1: Create the Provider Structure + +**Explanation:** +Tool/Wrapper providers require a specific folder structure to organize tool integration, configuration, and service management. This structure follows Prowler's conventions and ensures proper integration with the CLI and API. + +**Required Structure:** + +``` +prowler/providers// +ā”œā”€ā”€ __init__.py +ā”œā”€ā”€ _provider.py +ā”œā”€ā”€ models.py +└── lib/ + ā”œā”€ā”€ __init__.py + └── arguments/ + ā”œā”€ā”€ __init__.py + └── arguments.py +``` + +**Key Components:** + +- **`_provider.py`**: Main provider class with tool integration +- **`models.py`**: Data structures for tool output and configuration +- **`lib/arguments/`**: CLI argument validation and parsing + +#### Step 2: Implement the Provider Class + +**Explanation:** +The provider class is the core component that handles tool integration, execution, and output parsing. It inherits from Prowler's base Provider class and implements tool-specific execution flows using subprocesses or library calls. + +**File:** `prowler/providers//_provider.py` + +```python +import json +import subprocess +import sys +from typing import List + +from colorama import Fore, Style + +from prowler.config.config import ( + default_config_file_path, + load_and_validate_config_file, +) +from prowler.lib.check.models import CheckReportYourTool +from prowler.lib.logger import logger +from prowler.lib.utils.utils import print_boxes +from prowler.providers.common.models import Audit_Metadata +from prowler.providers.common.provider import Provider + +class ToolProvider(Provider): + """ + ToolProvider class is the main class for the Your Tool Provider. + + This class is responsible for initializing the provider, executing the external tool, + parsing tool output, and converting results to Prowler's standard format. + + Attributes: + _type (str): The provider type. + _session: Not used for tool providers. + _identity (str): Simple identity for tool providers. + _audit_config (dict): The audit configuration. + audit_metadata (Audit_Metadata): The audit metadata. + """ + + _type: str = "your_tool_provider" + audit_metadata: Audit_Metadata + + def __init__( + self, + # Tool-specific parameters + scan_path: str = ".", + tool_specific_arg: str = "default_value", + exclude_path: list[str] = [], + # Configuration + config_path: str = None, + config_content: dict = None, + fixer_config: dict = {}, + # Authentication (if needed for your tool) + auth_token: str = None, + auth_username: str = None, + ): + """ + Initializes the ToolProvider instance. + + Args: + scan_path: Path to the folder containing files to scan + tool_specific_arg: Tool-specific argument for your external tool + exclude_path: List of paths to exclude from scan + config_path: Path to the configuration file + config_content: Configuration content as dictionary + fixer_config: Fixer configuration dictionary + auth_token: Authentication token for your tool (if needed) + auth_username: Username for your tool (if needed) + + Raises: + ValueError: If required parameters are missing + """ + logger.info("Instantiating YourTool Provider...") + + # Store tool-specific parameters + self.scan_path = scan_path + self.tool_specific_arg = tool_specific_arg + self.exclude_path = exclude_path + self.region = "global" + self.audited_account = "local-tool" + self._session = None + self._identity = "prowler" + self._auth_method = "No auth" + + # Handle tool authentication if needed + if auth_token: + self.auth_token = auth_token + self._auth_method = "Token" + logger.info("Using token for tool authentication") + elif auth_username: + self.auth_username = auth_username + self._auth_method = "Username" + logger.info("Using username for tool authentication") + logger.info("Using username for tool authentication") + else: + logger.debug("No authentication method provided; proceeding without authentication.") + + # Audit Config + if config_content: + self._audit_config = config_content + else: + if not config_path: + config_path = default_config_file_path + self._audit_config = load_and_validate_config_file(self._type, config_path) + + # Fixer Config + self._fixer_config = fixer_config + + # Mutelist (not needed for tool providers since tools have their own mutelist logic) + self._mutelist = None + + Provider.set_global_provider(self) + + @property + def auth_method(self): + """Returns the authentication method used.""" + return self._auth_method + + @property + def type(self): + """Returns the type of the provider.""" + return self._type + + @property + def identity(self): + """Returns the provider identity.""" + return self._identity + + @property + def session(self): + """Returns the session (not used for tool providers).""" + return self._session + + @property + def audit_config(self): + """Returns the audit configuration.""" + return self._audit_config + + @property + def fixer_config(self): + """Returns the fixer configuration.""" + return self._fixer_config + + def setup_session(self): + """Tool providers don't need a session since they use external tools directly""" + return None + + def _process_check(self, finding: dict, check: dict, status: str) -> CheckReportYourTool: + """ + Process a single check (failed or passed) and create a CheckReportYourTool object. + + Args: + finding: The finding object from tool output + check: The individual check data + status: The status of the check ("FAIL", "PASS", or "MUTED") + + Returns: + CheckReportYourTool: The processed check report + """ + try: + metadata_dict = { + "Provider": "your_tool_provider", + "CheckID": check.get("check_id", ""), + "CheckTitle": check.get("check_name", ""), + "CheckType": ["Your Tool Provider"], + "ServiceName": finding["check_type"], + "SubServiceName": "", + "ResourceIdTemplate": "", + "Severity": ( + check.get("severity", "low").lower() + if check.get("severity") + else "low" + ), + "ResourceType": "your_tool", + "Description": check.get("check_name", ""), + "Risk": "", + "RelatedUrl": ( + check.get("guideline", "") if check.get("guideline") else "" + ), + "Remediation": { + "Code": { + "NativeIaC": "", + "Terraform": "", + "CLI": "", + "Other": "", + }, + "Recommendation": { + "Text": "", + "Url": ( + check.get("guideline", "") if check.get("guideline") else "" + ), + }, + }, + "Categories": [], + "DependsOn": [], + "RelatedTo": [], + "Notes": "", + } + + # Convert metadata dict to JSON string + metadata = json.dumps(metadata_dict) + + report = CheckReportYourTool(metadata=metadata, finding=check) + report.status = status + report.resource_tags = check.get("entity_tags", {}) + report.status_extended = check.get("check_name", "") + if status == "MUTED": + report.muted = True + return report + except Exception as error: + logger.critical( + f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}" + ) + sys.exit(1) + + def run(self) -> List[CheckReportYourTool]: + """ + Main execution method that handles tool execution. + + Returns: + List[CheckReportYourTool]: List of check reports from the tool scan + """ + return self.run_scan(self.scan_path, self.exclude_path) + + def run_scan( + self, directory: str, exclude_path: list[str] + ) -> List[CheckReportYourTool]: + """ + Execute the external tool and parse its output. + + Args: + directory: Directory to scan + frameworks: List of frameworks to scan + exclude_path: List of paths to exclude + + Returns: + List[CheckReportYourTool]: List of check reports + """ + try: + logger.info(f"Running YourTool scan on {directory} ...") + + # Build the tool command + tool_command = [ + "your_tool_command", + # Add your tool-specific arguments here, this are just examples + "-d", + directory, + "-o", + "json", + "-f", + ",".join(frameworks), + ] + if exclude_path: + tool_command.extend(["--skip-path", ",".join(exclude_path)]) + + # Run the tool with JSON output + process = subprocess.run( + tool_command, + capture_output=True, + text=True, + ) + + # Log tool's error output if any + if process.stderr: + logger.error(process.stderr) + + try: + output = json.loads(process.stdout) + if not output: + logger.warning("No findings returned from YourTool scan") + return [] + except Exception as error: + logger.critical( + f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}" + ) + sys.exit(1) + + reports = [] + + # If only one framework has findings, the output is a dict, otherwise it's a list of dicts + if isinstance(output, dict): + output = [output] + + # Process all frameworks findings + for finding in output: + results = finding.get("results", {}) + + # Process failed checks + failed_checks = results.get("failed_checks", []) + for failed_check in failed_checks: + report = self._process_check(finding, failed_check, "FAIL") + reports.append(report) + + # Process passed checks + passed_checks = results.get("passed_checks", []) + for passed_check in passed_checks: + report = self._process_check(finding, passed_check, "PASS") + reports.append(report) + + # Process skipped checks (muted) + skipped_checks = results.get("skipped_checks", []) + for skipped_check in skipped_checks: + report = self._process_check(finding, skipped_check, "MUTED") + reports.append(report) + + return reports + + except Exception as error: + if "No such file or directory: 'your_tool_command'" in str(error): + logger.critical("Please, install your_tool using 'pip install your_tool'") + sys.exit(1) + logger.critical( + f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}" + ) + sys.exit(1) + + def print_credentials(self): + """ + Display scan information with color formatting. + + This method prints the tool scan information in a formatted way + using colorama for better readability. + """ + if self.scan_repository_url: + report_title = ( + f"{Style.BRIGHT}Scanning remote repository:{Style.RESET_ALL}" + ) + report_lines = [ + f"Repository: {Fore.YELLOW}{self.scan_repository_url}{Style.RESET_ALL}", + ] + else: + report_title = ( + f"{Style.BRIGHT}Scanning local directory:{Style.RESET_ALL}" + ) + report_lines = [ + f"Directory: {Fore.YELLOW}{self.scan_path}{Style.RESET_ALL}", + ] + + if self.exclude_path: + report_lines.append( + f"Excluded paths: {Fore.YELLOW}{', '.join(self.exclude_path)}{Style.RESET_ALL}" + ) + + report_lines.append( + f"Frameworks: {Fore.YELLOW}{', '.join(self.frameworks)}{Style.RESET_ALL}" + ) + + report_lines.append( + f"Authentication method: {Fore.YELLOW}{self.auth_method}{Style.RESET_ALL}" + ) + + print_boxes(report_lines, report_title) +``` + +#### Step 3: Create Models + +**Explanation:** +Models define the data structures used by your tool provider. They include output options and tool-specific configurations. These models ensure type safety and consistent data handling across the provider. + +**File:** `prowler/providers//models.py` + +```python +from prowler.config.config import output_file_timestamp +from prowler.providers.common.models import ProviderOutputOptions + +class YourToolOutputOptions(ProviderOutputOptions): + """ + YourToolOutputOptions overrides ProviderOutputOptions for tool-specific output logic. + For example, generating a filename that includes the tool name. + + Attributes inherited from ProviderOutputOptions: + - output_filename (str): The base filename used for generated reports. + - output_directory (str): The directory to store the output files. + - ... see ProviderOutputOptions for more details. + + Methods: + - __init__: Customizes the output filename logic for the tool provider. + """ + + def __init__(self, arguments, bulk_checks_metadata): + super().__init__(arguments, bulk_checks_metadata) + + # If --output-filename is not specified, build a default name. + if not getattr(arguments, "output_filename", None): + self.output_filename = f"prowler-output-your_tool-{output_file_timestamp}" + # If --output-filename was explicitly given, respect that + else: + self.output_filename = arguments.output_filename +``` + +#### Step 4: Implement Arguments + +**Explanation:** +Argument validation ensures that the tool provider receives valid configuration parameters. This step is crucial for preventing runtime errors and providing clear error messages to users. + +**File:** `prowler/providers//lib/arguments/arguments.py` + +```python +# Add your tool-specific choices if needed +TOOL_SPECIFIC_CHOICES = [ + "option1", + "option2", + "option3", + # Add your tool's supported options +] + +def init_parser(self): + """Init the Provider CLI parser""" + _parser = self.subparsers.add_parser( + "", parents=[self.common_providers_parser], help=" Provider" + ) + + # Scan Path + _scan_subparser = _parser.add_argument_group("Scan Path") + _scan_subparser.add_argument( + "--scan-path", + "-P", + dest="scan_path", + default=".", + help="Path to the folder containing your files to scan. Default: current directory.", + ) + + _scan_subparser.add_argument( + "--tool-specific-arg", + dest="tool_specific_arg", + default="default_value", + choices=TOOL_SPECIFIC_CHOICES, + help="Tool-specific argument for your external tool. Default: default_value", + ) + + _scan_subparser.add_argument( + "--exclude-path", + dest="exclude_path", + nargs="+", + default=[], + help="Comma-separated list of paths to exclude from the scan. Default: none", + ) + + # Authentication (if needed for your tool) + _scan_subparser.add_argument( + "--auth-token", + dest="auth_token", + nargs="?", + default=None, + help="Authentication token for your tool. If not provided, will use YOUR_TOOL_AUTH_TOKEN env var.", + ) + _scan_subparser.add_argument( + "--auth-username", + dest="auth_username", + nargs="?", + default=None, + help="Username for your tool authentication. If not provided, will use YOUR_TOOL_AUTH_USERNAME env var.", + ) + +def validate_arguments(arguments): + """ + Validate tool-specific arguments. + + Args: + arguments: The parsed arguments + + Returns: + tuple: (is_valid, error_message) + """ + scan_path = getattr(arguments, "scan_path", None) + scan_repository_url = getattr(arguments, "scan_repository_url", None) + + if scan_path and scan_repository_url: + # If scan_path is set to default ("."), allow scan_repository_url + if scan_path != ".": + return ( + False, + "--scan-path (-P) and --scan-repository-url (-R) are mutually exclusive. Please specify only one.", + ) + return (True, "") +``` + +#### Step 5: Register in CLI + +**Explanation:** +Add your provider to the available providers in the CLI. + +**File:** `prowler/lib/cli/parser.py` + +This step is the same as the [SDK providers](#step-9-register-in-cli). + +#### Step 6: Register in Main + +**Explanation:** +Main registration makes your provider discoverable by Prowler's core system. It's needed to add your provider to the output options and to the compliance evaluation. + +**File:** `prowler/__main__.py` + +This step is the same as the [SDK providers](#step-10-register-in-main). + +#### Step 7: Register in the list of providers + +**Explanation:** +This is needed to be able to use the provider in the generic checks. The provider must be registered in the `init_global_provider` method to handle CLI arguments and initialization. + +**File:** `prowler/providers/common/provider.py` + +This step is the same as the [SDK providers](#step-11-register-in-the-list-of-providers). + +#### Step 8: Add to Config + +**Explanation:** +Configuration registration ensures your tool provider is recognized by Prowler's configuration system. This enables proper handling of provider-specific settings and defaults. + +**File:** `prowler/config/config.py` + +This step is the same as the [SDK providers](#step-12-add-to-config). + +In some cases, you may need to create a new configuration file for your provider, for example, the AWS one that is inside `prowler/providers/aws/config.py`. + +#### Step 9: Create Compliance Files + +**Explanation:** +Compliance files define the security checks and standards that your provider supports. These JSON files map security controls to specific checks and provide remediation guidance. It's needed to create the folder with an init file to ensure the provider will work, however, adding different compliance files is optional. + +**Folder:** `prowler/compliance//` + +This step is the same as the [SDK providers](#step-13-create-compliance-files). + +#### Step 10: Add Output Support + +**Explanation:** +Output support ensures that your provider's results are properly formatted in Prowler's various output formats (CSV, JSON, HTML, etc.). This step integrates your provider with Prowler's reporting system. + +**File:** `prowler/lib/outputs/summary_table.py` + +This step is the same as the [SDK providers](#step-14-add-output-support). + +#### Step 11: Generate the HTML Report + +**Explanation:** +The HTML file is needed to be able to generate the HTML report. This step involves adding support for your provider in the HTML output generation system to ensure proper display of assessment summaries and findings. + +**File:** `prowler/lib/outputs/html/html.py` + +This step is the same as the [SDK providers](#step-15-generate-the-html-report). + +#### Step 12: Add the Check Report Model + +**Explanation:** +Add the provider to the generic models, this is needed to be able to use the provider in the generic checks. + +**File:** `prowler/providers/check/models.py` + +This step is the same as the [SDK providers](#step-16-add-the-check-report-model). + +#### Step 13: Create Tests + +**Explanation:** +Testing ensures that your tool provider works correctly and maintains compatibility as Prowler evolves. Comprehensive tests cover tool execution, output parsing, and provider-specific functionality. + +**Folder:** `tests/providers//` + +```python +import pytest +import tempfile +import os +from prowler.providers.your_tool_provider.your_tool_provider import ToolProvider + +class TestToolProvider: + """Test cases for ToolProvider.""" + + def test_provider_initialization(self): + """Test provider initialization with valid parameters.""" + provider = ToolProvider( + scan_path=".", + frameworks=["framework1"] + ) + assert provider.type == "your_tool_provider" + assert provider.identity == "prowler" + assert provider.scan_path == "." + + def test_tool_execution(self): + """Test tool execution and output parsing.""" + provider = ToolProvider(scan_path=".") + # Mock the subprocess call and test output parsing + # This will depend on your specific tool's output format + + def test_argument_validation(self): + """Test argument validation.""" + from prowler.providers.your_tool_provider.lib.arguments.arguments import ( + validate_arguments + ) + + # Valid arguments + class MockArgs: + scan_path = "." + tool_specific_arg = "value" + + is_valid, message = validate_arguments(MockArgs()) + assert is_valid is True + + # Add more test cases as needed for your specific tool provider + + def test_print_credentials(self): + """Test print_credentials method.""" + provider = ToolProvider( + scan_path="/test/path", + frameworks=["framework1"] + ) + # This should not raise any exceptions + provider.print_credentials() +``` + +#### Step 14: Update Documentation + +**Explanation:** +Documentation updates ensure that users can find information about your tool provider in Prowler's documentation. This includes examples, configuration guides, and troubleshooting information. + +Update the provider documentation to include your new tool provider in the examples and implementation guidance. + +--- + + +## Step 2: Integrate the Provider in the API + +This step is required only if you want your provider to be available in the API and UI. The API integration involves several components: + +### 2.1. Backend API Models + +**Location:** `api/src/backend/api/models.py` + +Add your provider to the `ProviderChoices` enum and implement UID validation: + +```python +class ProviderChoices(models.TextChoices): + AWS = "aws", "AWS" + AZURE = "azure", "Azure" + GCP = "gcp", "GCP" + KUBERNETES = "kubernetes", "Kubernetes" + M365 = "m365", "Microsoft 365" + GITHUB = "github", "GitHub" + NHN = "nhn", "NHN Cloud" + IAC = "iac", "Infrastructure as Code" + YOUR_PROVIDER = "your_provider", "Your Provider" # Add your provider here + +@staticmethod +def validate_your_provider_uid(value): + """Validate your provider UID format.""" + if not re.match(r"^your-regex-pattern$", value): + raise ModelValidationError( + detail="Your provider UID must follow the specified format.", + code="your-provider-uid", + pointer="/data/attributes/uid", + ) +``` + +**Provider Model:** +The `Provider` model already exists and supports all provider types. Ensure your provider type is included in the choices. + +### 2.2. Add the provider to the Provider Choices + +Update the `return_prowler_provider` function to include your provider. This function is crucial for the API to instantiate the correct provider class. + +**File:** `api/src/backend/api/utils.py` + +```python +from prowler.providers.your_provider.your_provider import YourProvider # Add your import + +def return_prowler_provider( + provider: Provider, +) -> [ + AwsProvider + | AzureProvider + | GcpProvider + | GithubProvider + | KubernetesProvider + | M365Provider + | YourProvider # Add your provider to the return type annotation +]: + """Return the Prowler provider class based on the given provider type.""" + match provider.provider: + case Provider.ProviderChoices.AWS.value: + prowler_provider = AwsProvider + case Provider.ProviderChoices.AZURE.value: + prowler_provider = AzureProvider + case Provider.ProviderChoices.GCP.value: + prowler_provider = GcpProvider + case Provider.ProviderChoices.KUBERNETES.value: + prowler_provider = KubernetesProvider + case Provider.ProviderChoices.M365.value: + prowler_provider = M365Provider + case Provider.ProviderChoices.GITHUB.value: + prowler_provider = GithubProvider + case Provider.ProviderChoices.YOUR_PROVIDER.value: # Add your provider here + prowler_provider = YourProvider + case _: + raise ValueError(f"Provider type {provider.provider} not supported") + return prowler_provider +``` + +**Also update the `initialize_prowler_provider` function:** + +```python +def initialize_prowler_provider( + provider: Provider, + mutelist_processor: Processor | None = None, +) -> ( + AwsProvider + | AzureProvider + | GcpProvider + | GithubProvider + | KubernetesProvider + | M365Provider + | YourProvider # Add your provider to the return type annotation +): + """Initialize a Prowler provider instance based on the given provider type.""" + prowler_provider = return_prowler_provider(provider) + prowler_provider_kwargs = get_prowler_provider_kwargs(provider, mutelist_processor) + return prowler_provider(**prowler_provider_kwargs) +``` + +**Note:** The `match` statement requires Python 3.10+. If you're using an older version, you can use traditional `if-elif` statements instead. + +### 2.3. API Serializers + +Create or update serializers for your provider. You'll need to add your provider to the validation logic: + +**File:** `api/src/backend/api/v1/serializers.py` + +```python +def validate_secret_based_on_provider(provider_type, secret): + """Validate provider-specific secrets.""" + if provider_type == Provider.ProviderChoices.AWS.value: + serializer = AWSProviderSecret(data=secret) + elif provider_type == Provider.ProviderChoices.AZURE.value: + serializer = AzureProviderSecret(data=secret) + elif provider_type == Provider.ProviderChoices.GCP.value: + serializer = GCPProviderSecret(data=secret) + elif provider_type == Provider.ProviderChoices.YOUR_PROVIDER.value: # Add your provider here + serializer = YourProviderSecret(data=secret) + # ... other providers + + if serializer.is_valid(): + return serializer.validated_data + else: + raise serializers.ValidationError(serializer.errors) + +class YourProviderSecret(serializers.Serializer): + """Serializer for your provider credentials.""" + your_auth_field = serializers.CharField(required=True) + your_optional_field = serializers.CharField(required=False) + + class Meta: + resource_name = "provider-secrets" +``` + +Also update the providers included in the serializer: + +**File:** `api/src/backend/api/v1/serializer_utils/providers.py` + +```python +@extend_schema_field( + { + "oneOf": [ + # ... existing provider schemas ... + { + "type": "object", + "title": "Your Provider Credentials", + "properties": { + "your_auth_field": { + "type": "string", + "description": "Your provider authentication field description.", + }, + "your_optional_field": { + "type": "string", + "description": "Optional field for your provider (if applicable).", + }, + "your_required_field": { + "type": "string", + "description": "Required field for your provider authentication.", + } + }, + "required": ["your_auth_field", "your_required_field"] + }, + # ... other existing schemas ... + ] + } +) +``` + +### 2.4. Database Migration + +Create a new migration to add your provider to the database. This is crucial for the API to recognize your provider type. + +**File:** `api/src/backend/api/migrations/XXXX_your_provider.py` + +```python +# Generated by Django X.X.X on YYYY-MM-DD + +from django.db import migrations + +import api.db_utils + + +class Migration(migrations.Migration): + dependencies = [ + ("api", "previous_migration_name"), # Update this to the latest migration + ] + + operations = [ + migrations.AlterField( + model_name="provider", + name="provider", + field=api.db_utils.ProviderEnumField( + choices=[ + ("aws", "AWS"), + ("azure", "Azure"), + ("gcp", "GCP"), + ("kubernetes", "Kubernetes"), + ("m365", "M365"), + ("github", "GitHub"), + ("your_provider", "Your Provider"), # Add your provider here + ], + default="aws", + ), + ), + migrations.RunSQL( + "ALTER TYPE provider ADD VALUE IF NOT EXISTS 'your_provider';", + reverse_sql=migrations.RunSQL.noop, + ), + ] +``` + +**Important Notes:** + +- **Migration Number**: Use the next sequential number (e.g., if latest is 0044, use 0045) +- **Dependencies**: Update the `dependencies` list to point to the most recent migration +- **Choices Array**: Add your provider to the `choices` array with proper display name +- **SQL Operation**: The `RunSQL` operation adds your provider to the PostgreSQL enum type +- **Reverse SQL**: Use `migrations.RunSQL.noop` since adding enum values cannot be easily reversed + +**Migration Naming Convention:** + +- Format: `XXXX_your_provider.py` (e.g., `0045_your_provider.py`) +- Use descriptive names that indicate what the migration does +- Follow the existing pattern in the migrations folder + +### 2.5. Update the V1 Yaml + +Update the OpenAPI specification (`v1.yaml`) to include your provider in all relevant endpoints and schemas. This is crucial for API documentation and client generation. + +**File:** `api/src/backend/api/specs/v1.yaml` + +#### 2.5.1. Provider Enum Values + +Add your provider to the provider enum in the Provider schema: + +```yaml +# Around line 12150 in v1.yaml +Provider: + type: object + properties: + attributes: + properties: + provider: + enum: + - aws + - azure + - gcp + - kubernetes + - m365 + - github + - your_provider # Add your provider here + type: string + description: |- + * `aws` - AWS + * `azure` - Azure + * `gcp` - GCP + * `kubernetes` - Kubernetes + * `m365` - M365 + * `github` - GitHub + * `your_provider` - Your Provider # Add your provider here +``` + +#### 2.5.2. Provider Credential Schemas + +Add your provider's credential schema to the integration configuration. This defines how your provider's credentials are structured: + +```yaml +# Around line 11100 in v1.yaml, in the integration configuration +- type: object + title: Your Provider Credentials # Add your provider here + properties: + your_auth_field: + type: string + description: Your provider authentication field description. + your_optional_field: + type: string + description: Optional field for your provider (if applicable). + your_required_field: + type: string + description: Required field for your provider authentication. + required: + - your_auth_field + - your_required_field +``` + +#### 2.5.3. Example Provider Schemas + +Here are examples of how existing providers are documented: + +**AWS Provider:** +```yaml +- type: object + title: AWS Static Credentials + properties: + aws_access_key_id: + type: string + description: The AWS access key ID. + aws_secret_access_key: + type: string + description: The AWS secret access key. + required: + - aws_access_key_id + - aws_secret_access_key + +- type: object + title: AWS Assume Role + properties: + role_arn: + type: string + description: The Amazon Resource Name (ARN) of the role to assume. + external_id: + type: string + description: An identifier to enhance security for role assumption. + required: + - role_arn + - external_id +``` + +**GitHub Provider:** +```yaml +- type: object + title: GitHub Personal Access Token + properties: + personal_access_token: + type: string + description: GitHub personal access token for authentication. + required: + - personal_access_token + +- type: object + title: GitHub OAuth App Token + properties: + oauth_app_token: + type: string + description: GitHub OAuth App token for authentication. + required: + - oauth_app_token +``` + +**M365 Provider:** +```yaml +- type: object + title: M365 Static Credentials + properties: + client_id: + type: string + description: The Azure application (client) ID for authentication in Azure AD. + client_secret: + type: string + description: The client secret associated with the application (client) ID. + tenant_id: + type: string + description: The Azure tenant ID, representing the directory where the application is registered. + user: + type: email + description: User microsoft email address. + password: + type: string + description: User password. + required: + - client_id + - client_secret + - tenant_id + - user + - password +``` + +#### 2.5.4. Important Notes + +- **Position**: Add your schema in the `oneOf` array alongside existing providers +- **Structure**: Follow the exact pattern of other providers (title, properties, required fields) +- **Descriptions**: Provide clear, helpful descriptions for each field +- **Required Fields**: Specify which fields are mandatory in the `required` array +- **Field Types**: Use appropriate JSON schema types (`string`, `integer`, `boolean`, `email`, etc.) +- **Validation**: Add any field-specific validation patterns or constraints +- **Documentation**: Ensure your provider appears in the generated API documentation + +### 2.6. Testing API Integration + +Create tests for your provider: + +**Location:** `api/src/backend/api/tests/` + +```python +class YourProviderAPITestCase(APITestCase): + def setUp(self): + self.user = User.objects.create_user(username='testuser', password='testpass') + self.client.force_authenticate(user=self.user) + + def test_create_your_provider(self): + data = { + 'provider': 'your_provider', + 'uid': 'valid-uid-123', + 'alias': 'Test Account' + } + response = self.client.post('/api/v1/providers/', data) + self.assertEqual(response.status_code, 201) + self.assertEqual(response.data['provider'], 'your_provider') + + def test_your_provider_uid_validation(self): + """Test UID validation for your provider.""" + invalid_uids = [ + 'invalid@uid', + '-invalid-start', + 'a' * 40, # Too long + ] + + for invalid_uid in invalid_uids: + data = { + 'provider': 'your_provider', + 'uid': invalid_uid, + 'alias': 'Test' + } + response = self.client.post('/api/v1/providers/', data) + self.assertEqual(response.status_code, 400) + self.assertIn('your-provider-uid', str(response.data)) + + def test_add_your_provider_credentials(self): + # Create provider first + provider = Provider.objects.create( + user=self.user, + provider='your_provider', + uid='valid-uid-123' + ) + + # Add credentials + credentials_data = { + 'secret_type': 'your_provider_credentials', + 'secret': { + 'your_auth_field': 'auth_value', + 'your_optional_field': 'optional_value' + }, + 'provider': provider.id + } + response = self.client.post('/api/v1/providers/secrets/', credentials_data) + self.assertEqual(response.status_code, 201) +``` + +#### 2.6.1. Add your mocked provider to the tests + +If needed, add your mocked provider to the tests config file so you can use it on the tests. + +**File:** `api/src/backend/conftest.py` + +```python +@pytest.fixture +def providers_fixture(tenants_fixture): + tenant, *_ = tenants_fixture + providerX = Provider.objects.create( + provider="your_provider", + uid="your_uid", + alias="your_alias", + tenant_id=tenant.id, + ) + return provider1, provider2, provider3, ... providerX +``` + +### 2.7. Compliance and Output Support + +Add your provider to the compliance export functionality: + +**File:** `api/src/backend/tasks/jobs/export.py` + +```python +COMPLIANCE_FRAMEWORKS = { + "aws": [...], + "azure": [...], + "gcp": [...], + "kubernetes": [...], + "m365": [...], + "github": [...], + "your_provider": [ # Add your provider here + (lambda name: name.startswith("cis_"), YourProviderCIS), + (lambda name: name.startswith("iso27001_"), YourProviderISO27001), + ], +} +``` + +If your provider has specific fields, add them to the finding transformation: + +**File:** `prowler/lib/outputs/finding.py` + +```python +def transform_api_finding(cls, finding, provider) -> "Finding": + # ... existing code ... + + # Your provider specific field + if provider.type == "your_provider": + finding.your_field = resource.your_field + + # ... rest of the code ... +``` + +### 2.8. API Endpoints + +Your provider will be available through these endpoints: + +- `GET /api/v1/providers/` - List all providers +- `POST /api/v1/providers/` - Create a new provider +- `GET /api/v1/providers/{id}/` - Get provider details +- `PUT /api/v1/providers/{id}/` - Update provider +- `DELETE /api/v1/providers/{id}/` - Delete provider +- `POST /api/v1/providers/secrets/` - Add provider credentials + +### 2.9. Update the provider if needed + +Depending on your provider's authentication requirements, you may need to add new authentication methods that are compatible with the API. This involves updating the provider class to support additional credential types beyond the basic ones. + +#### 2.9.1. Adding New Authentication Methods + +If your provider requires specific authentication methods, you'll need to: + +1. **Update the provider constructor** to accept new authentication parameters +2. **Extend the credential handling** to support the new authentication method +3. **Update the API serializers** to include the new credential fields +4. **Modify the OpenAPI specification** to document the new authentication schema + +#### 2.9.2. Example: GitHub Provider Authentication Methods + +The GitHub provider demonstrates how to implement multiple authentication methods: + +```python +# In prowler/providers/github/github_provider.py +def __init__( + self, + # Authentication methods + personal_access_token: str = "", + oauth_app_token: str = "", + github_app_key: str = "", + #Needed for the API integration + github_app_key_content: str = "", + github_app_id: int = 0, + # Provider configuration + config_path: str = None, + # ... other parameters +): + """ + Initialize GitHub provider. + + Args: + personal_access_token (str): GitHub personal access token. + oauth_app_token (str): GitHub OAuth App token. + github_app_key (str): GitHub App key. + github_app_key_content (str): GitHub App key content. + github_app_id (int): GitHub App ID. + config_path (str): Path to the audit configuration file. + # ... other parameters + """ + super().__init__( + personal_access_token, + oauth_app_token, + github_app_id, + github_app_key, + github_app_key_content, + ) +``` + +--- + +## Step 3: Integrate the Provider in the UI + +TBD + +--- + +## Provider Implementation Guidance + +Use existing providers as templates, this will help you to understand better the structure and the implementation will be easier: + +- [AWS (SDK)](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/aws/aws_provider.py) +- [Azure (SDK)](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/azure/azure_provider.py) +- [GCP (SDK)](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/gcp/gcp_provider.py) +- [Kubernetes (SDK)](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/kubernetes/kubernetes_provider.py) +- [M365 (SDK/Wrapper)](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/m365/m365_provider.py) +- [GitHub (SDK)](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/github/github_provider.py) +- [NHN (API)](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/nhn/nhn_provider.py) +- [IAC (Tool)](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/iac/iac_provider.py) +- [MongoDB Atlas](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/mongodbatlas/mongodbatlas_provider.py) + +--- + +## Best Practices + +- **Code Quality & Documentation** + + - **Comprehensive Docstrings**: Every class, method, and function should have detailed docstrings following Prowler's format + ```python + def method_name(self, param: str) -> str: + """ + Brief description of what the method does. + + Args: + param: Description of the parameter + + Returns: + Description of the return value + + Raises: + ExceptionType: When and why this exception occurs + """ + ``` + + - **Type Hints**: Use type hints for all function parameters and return values + ```python + from typing import Optional, List, Dict, Any + ``` + + - **Logging**: Implement proper logging using Prowler's logger + ```python + from prowler.lib.logger import logger + + logger.info("Operation completed successfully") + logger.warning("Something to be aware of") + logger.error("Something went wrong") + logger.critical("Critical error that may cause failure") + ``` + +- **Error Handling & Validation** + + - **Custom Exceptions**: Create provider-specific exceptions for better error handling + - **Input Validation**: Validate all inputs and provide clear error messages + - **Graceful Degradation**: Handle errors gracefully without crashing the entire scan + - **Raise on Exception**: Use `raise_on_exception` parameter for test methods + +- **Testing & Quality Assurance** + + - **Comprehensive Test Coverage**: Aim for >80% test coverage + - **Test Naming**: Use descriptive test names: `test_method_name_scenario` + - **Test Organization**: Group related tests in test classes + - **Mock External Dependencies**: Mock external API calls and services + - **Test Edge Cases**: Include tests for error conditions and edge cases + - **End-to-End Testing**: Test the provider on real infrastructure + +- **Performance & Security** + + - **Session Management**: Reuse sessions when possible, don't create new ones unnecessarily + - **Rate Limiting**: Implement rate limiting for API calls to avoid hitting limits + - **Resource Cleanup**: Ensure proper cleanup of temporary resources + - **Authentication Security**: Never log sensitive credentials or tokens + +- **Code Organization** + + - **Single Responsibility**: Each method should have one clear purpose + - **Consistent Naming**: Follow Prowler's naming conventions + - **Modular Design**: Break complex functionality into smaller, testable methods + - **Configuration Management**: Use configuration files for provider-specific settings + +- **Documentation & Maintenance** + + - **README Updates**: Update provider-specific documentation + - **Changelog**: Document changes and new features + - **Examples**: Provide usage examples and common scenarios + - **Troubleshooting**: Include common issues and solutions + - **Documentation**: Update the provider documentation to include your new tool provider in the examples and implementation guidance. + +- **Integration Standards** + + - **CLI Consistency**: Follow Prowler's CLI argument patterns + - **Output Format**: Ensure outputs are compatible with Prowler's reporting system + - **Compliance Mapping**: Map provider checks to relevant compliance frameworks + - **Backward Compatibility**: Maintain compatibility when possible + +- **AI-Assisted Development** + + - **Use Rules**: Use rules to ensure the code generated by AI is following the way of working in Prowler. + +## Checklist for New Providers + +### CLI Integration Only + +**Phase 1: Research & Planning** + +- [ ] Soft research completed +- [ ] Spike date scheduled +- [ ] Deeper research completed +- [ ] Action plan created + +**Phase 2: Implementation** + +- [ ] Folder and files created in `prowler/providers/` +- [ ] Provider class implemented and inherits from `Provider` +- [ ] Authentication/session logic implemented +- [ ] Arguments/flags mapped and documented +- [ ] Outputs and metadata standardized +- [ ] Registered in the CLI +- [ ] Minimal usage example provided + +**Phase 3: Delivery** + +- [ ] PoC delivered +- [ ] MVP delivered +- [ ] Version 1 completed +- [ ] QA and documentation completed +- [ ] GA release ready + +### API Integration + +- [ ] All CLI integration items completed +- [ ] Provider added to `ProviderChoices` enum in API models +- [ ] API serializers created/updated for the provider +- [ ] API views support the new provider type +- [ ] Provider credentials model supports the new provider +- [ ] API endpoints tested and working +- [ ] Provider-specific validation implemented +- [ ] API tests created and passing + +### UI Integration + +- TBD + +--- + +## Next Steps + +- [How to add a new Service](./services) +- [How to add new Checks](./checks) +- [How to contribute](./introduction#contributing-to-prowler) diff --git a/docs/developer-guide/renaming-checks.mdx b/docs/developer-guide/renaming-checks.mdx new file mode 100644 index 0000000000..7a593542f4 --- /dev/null +++ b/docs/developer-guide/renaming-checks.mdx @@ -0,0 +1,212 @@ +--- +title: 'Renaming Checks in Prowler' +--- + +To rename a check in Prowler, follow these steps when aligning with Check ID structure, fixing typos, or updating check logic that requires a new name. + +When changing a Check ID, update the following files: + +## Update Check Folder Structure + +First, rename the check folder with the new check name. + +**Path:** `prowler/providers//services//` + +**Example:** +``` +# Before +prowler/providers/aws/services/inspector2/inspector2_findings_exist/ + +# After +prowler/providers/aws/services/inspector2/inspector2_active_findings_exist/ +``` + +Next, rename the file that contains the check logic. Inside that file, also rename the class name to match the new check name. + +**Path:** `prowler/providers//services///.py` + +**Example:** +```python +# Before +class inspector2_findings_exist(Check): + def execute(self): + findings = [] + # ... check logic ... + +# After +class inspector2_active_findings_exist(Check): + def execute(self): + findings = [] + # ... check logic ... +``` + +Then, rename the file that contains the check metadata. Inside that file, add the old check name as an alias in the `CheckAliases` field and modify the `CheckID` to the new check name. + +**Path:** `prowler/providers//services///.metadata.json` + +**Example:** +```json +{ + "Provider": "aws", + "CheckID": "inspector2_active_findings_exist", + "CheckTitle": "Check if Inspector2 active findings exist", + "CheckAliases": [ + "inspector2_findings_exist" + ], + "CheckType": [], + "ServiceName": "inspector2", + "SubServiceName": "", + "ResourceIdTemplate": "arn:aws:inspector2:region:account-id/detector-id", + "Severity": "medium", + "ResourceType": "Other", + "Description": "This check determines if there are any active findings in your AWS account that have been detected by AWS Inspector2.", + "Risk": "Without using AWS Inspector, you may not be aware of all the security vulnerabilities in your AWS resources.", + "RelatedUrl": "https://docs.aws.amazon.com/inspector/latest/user/findings-understanding.html", + "Remediation": { + "Code": { + "CLI": "", + "NativeIaC": "", + "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Inspector/amazon-inspector-findings.html", + "Terraform": "" + }, + "Recommendation": { + "Text": "Review the active findings from Inspector2", + "Url": "https://docs.aws.amazon.com/inspector/latest/user/what-is-inspector.html" + } + }, + "Categories": [], + "DependsOn": [], + "RelatedTo": [], + "Notes": "" +} +``` + +## Update Test Files + +Second, rename the tests folder with the new check name. + +**Path:** `tests/providers//services//` + +**Example:** +``` +# Before +tests/providers/aws/services/inspector2/inspector2_findings_exist/ + +# After +tests/providers/aws/services/inspector2/inspector2_active_findings_exist/ +``` + +Next, rename the test file that contains all the unit tests. Inside that file, rename all appearances of the old check name to the new check name. + +**Path:** `tests/providers//services///_test.py` + +**Example:** +```python +# Before +from prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist import ( + inspector2_findings_exist, +) + +class Test_inspector2_findings_exist: + def test_inspector2_no_findings(self): + # ... test logic ... + + def test_inspector2_with_findings(self): + # ... test logic ... + +# After +from prowler.providers.aws.services.inspector2.inspector2_active_findings_exist.inspector2_active_findings_exist import ( + inspector2_active_findings_exist, +) + +class Test_inspector2_active_findings_exist: + def test_inspector2_no_findings(self): + # ... test logic ... + + def test_inspector2_with_findings(self): + # ... test logic ... +``` + +**Important:** Update all references to the old check name in the test file, including: + +- Import statements at the top of the file +- Class name in the test class +- Any function calls to the check +- Any string references to the check name +- Mock patches that reference the check + +**Complete example of all changes needed in test files:** +```python +# Before +from prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist import ( + inspector2_findings_exist, +) + +class Test_inspector2_findings_exist: + def test_inspector2_no_findings(self): + # Mock setup + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.inspector2_client", + inspector2_client, + ): + check = inspector2_findings_exist() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "PASS" + assert "No active findings found" in result[0].status_extended + +# After +from prowler.providers.aws.services.inspector2.inspector2_active_findings_exist.inspector2_active_findings_exist import ( + inspector2_active_findings_exist, +) + +class Test_inspector2_active_findings_exist: + def test_inspector2_no_findings(self): + # Mock setup + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_active_findings_exist.inspector2_active_findings_exist.inspector2_client", + inspector2_client, + ): + check = inspector2_active_findings_exist() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "PASS" + assert "No active findings found" in result[0].status_extended +``` + +## Update Compliance Mappings + +Finally, rename all appearances of the old check name to the new check name inside any compliance framework where the check is mapped. + +- `prowler/compliance//.json` + +**Example:** +```json +{ + "Framework": "CIS", + "Version": "2.0", + "Provider": "AWS", + "Description": "The CIS Amazon Web Services Foundations Benchmark provides prescriptive guidance for configuring security options for a subset of Amazon Web Services.", + "Requirements": [ + { + "Id": "4.1", + "Description": "Ensure a log metric filter and alarm exist for unauthorized API calls", + "Checks": [ + "inspector2_active_findings_exist" + ], + "Attributes": [ + { + "Section": "4 Logging and Monitoring", + "Profile": "Level 1", + "AssessmentStatus": "Automated", + "Description": "Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms." + } + ] + } + ] +} +``` + +The development compliance file may contain examples of the check being renamed. If so, modify this file as well: + +- `api/src/backend/api/fixtures/dev/7_dev_compliance.json` diff --git a/docs/developer-guide/security-compliance-framework.md b/docs/developer-guide/security-compliance-framework.mdx similarity index 97% rename from docs/developer-guide/security-compliance-framework.md rename to docs/developer-guide/security-compliance-framework.mdx index 95b7677605..bb01af8271 100644 --- a/docs/developer-guide/security-compliance-framework.md +++ b/docs/developer-guide/security-compliance-framework.mdx @@ -1,4 +1,6 @@ -# Creating a New Security Compliance Framework in Prowler +--- +title: 'Creating a New Security Compliance Framework in Prowler' +--- ## Introduction diff --git a/docs/developer-guide/services.md b/docs/developer-guide/services.md deleted file mode 100644 index 7615404cd9..0000000000 --- a/docs/developer-guide/services.md +++ /dev/null @@ -1,250 +0,0 @@ -# Prowler Services - -Here you can find how to create a new service, or to complement an existing one, for a [Prowler Provider](./provider.md). - -???+note - First ensure that the provider you want to add the service is already created. It can be checked [here](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers). If the provider is not present, please refer to the [Provider](./provider.md) documentation to create it from scratch. - -## Introduction - -In Prowler, a **service** represents a specific solution or resource offered by one of the supported [Prowler Providers](./provider.md), for example, [EC2](https://aws.amazon.com/ec2/) in AWS, or [Microsoft Exchange](https://www.microsoft.com/en-us/microsoft-365/exchange/exchange-online) in M365. Services are the building blocks that allow Prowler interact directly with the various resources exposed by each provider. - -Each service is implemented as a class that encapsulates all the logic, data models, and API interactions required to gather and store information about that service's resources. All of this data is used by the [Prowler checks](./checks.md) to generate the security findings. - -## Adding a New Service - -To create a new service, a new folder must be created inside the specific provider following this pattern: `prowler/providers//services//`. - -Within this folder the following files are also to be created: - -- `__init__.py` (empty) – Ensures Python recognizes this folder as a package. -- `_service.py` – Contains all the logic and API calls of the service. -- `_client_.py` – Contains the initialization of the freshly created service's class so that the checks can use it. - -Once the files are create, you can check that the service has been created by running the following command: `poetry run python prowler-cli.py --list-services | grep `. - -## Service Structure and Initialisation - -The Prowler's service structure is as outlined below. To initialise it, just import the service client in a check. - -### Service Base Class - -All Prowler provider service should inherit from a common base class to avoid code duplication. This base class handles initialization and storage of functions and objects needed across services. The exact implementation depends on the provider's API requirements, but the following are the most common responsibilities: - -- Initialize/store clients to interact with the provider's API. -- Store the audit and fixer configuration. -- Implement threading logic where applicable. - -For reference, the base classes for each provider can be checked here: - -- [AWS Service Base Class](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/aws/lib/service/service.py) -- [GCP Service Base Class](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/gcp/lib/service/service.py) -- [Azure Service Base Class](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/azure/lib/service/service.py) -- [Kubernetes Service Base Class](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/kubernetes/lib/service/service.py) -- [M365 Service Base Class](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/m365/lib/service/service.py) -- [GitHub Service Base Class](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/github/lib/service/service.py) - -### Service Class - -Due to the complexity and differences across provider APIs, the following example demonstrates best practices for structuring a service in Prowler. - -File `_service.py`: - -```python title="Example Service Class" -from datetime import datetime -from typing import Optional - -# To use the Pydantic's BaseModel. -from pydantic import BaseModel - -# Prowler logging library. -from prowler.lib.logger import logger - -# Provider parent class. -from prowler.providers..lib.service.service import ServiceParentClass - -# Create a class for the Service. -class (ServiceParentClass): - def __init__(self, provider: Provider): - """Initialize the Service Class - - Args: - provider: Prowler Provider object. - """ - # Call Service Parent Class __init__. - # The __class__.__name__ is used to obtain it automatically. - # From the Service Class name, but a custom one can be passed. - # String in case the provider's API service name is different. - super().__init__(__class__.__name__, provider) - - # Create an empty dictionary of items to be gathered, using the unique ID as the dictionary's key, e.g., instances. - self. = {} - - # If parallelization can be carried out by regions or locations, the function __threading_call__ to be used must be implemented in the Service Parent Class. - # If it is not implemented, you can make it in a sequential way, just calling the function. - self.__threading_call__(self.__describe___) - - # If it is needed you can create another function to retrieve more data from the items. - # Here we are using the second parameter of the __threading_call__ function to create one thread per item. - # You can also make it sequential without using the __threading_call__ function iterating over the items inside the function. - self.__threading_call__(self.__describe___, self..values()) - - # In case of use the __threading_call__ function, you have to pass the regional_client to the function, as a parameter. - def __describe___(self, regional_client): - """Get all and store in the self. dictionary - - Args: - regional_client: Regional client object. - """ - logger.info(" - Describing ...") - - # A try-except block must be created in each function. - try: - # If pagination is supported by the provider, is always better to use it, call to the provider API to retrieve the desired data. - describe__paginator = regional_client.get_paginator("describe_") - - # Paginator to get every item. - for page in describe__paginator.paginate(): - - # Another try-except within the for loop to continue iterating in case something unexpected happens. - try: - - for in page[""]: - - # Adding Retrieved Resources to the Object - - # Once the resource has been retrieved, it must be included in the previously created object to ensure proper data handling within the service. - self.[] = - ( - arn=stack[""], - name=stack[""], - tags=stack.get("Tags", []), - region=regional_client.region, - ) - - except Exception as error: - logger.error( - f"{} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - - # Logging Errors in Exception Handling - - # When handling exceptions, use the following approach to log errors appropriately based on the cloud provider being used: - except Exception as error: - # Depending on each provider we can must use different fields in the logger, e.g.: AWS: regional_client.region or self.region, GCP: project_id and location, Azure: subscription - logger.error( - f"{} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - - def __describe___(self, item: ): - """Get details for a - - Args: - item: Item object. - """ - logger.info(" - Describing to get specific details...") - # A try-except block must be created in each function. - try: - - _details = self.regional_clients[.region].describe_( - =.name - ) - - # E.g., check if item is Public. This case is important: if values are being retrieved from a dictionary, the function "dict.get()" must be used with a default value in case this value is not present. - .public = _details.get("Public", False) - except Exception as error: - # Fields for logging errors with relevant item information, e.g.: AWS: .region, GCP: .project_id, Azure: .region - logger.error( - f"{.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) -``` - -???+note - To prevent false findings, when Prowler fails to retrieve items due to Access Denied or similar errors, the affected item's value is set to `None`. - -#### Resource Models - -Resource models define structured classes used within services to store and process data extracted from API calls. They are defined in the same file as the service class, but outside of the class, usually at the bottom of the file. - -Prowler leverages Pydantic's [BaseModel](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel) to enforce data validation. - -```python title="Service Model" - -# Implementation Approach - -# Each service class should include custom model classes using Pydantic's BaseModel for the resources being audited. - -class (BaseModel): - """ holds a """ - - id: str - """[].id""" - - name: str - """[].name""" - - region: str - """[].region""" - - public: bool - """[].public""" - - # Optional attributes can be created set to None by default. - - tags: Optional[list] - """[].tags""" -``` - -#### Service Attributes - -*Optimized Data Storage with Python Dictionaries* - -Each group of resources within a service should be structured as a Python [dictionary](https://docs.python.org/3/tutorial/datastructures.html#dictionaries) to enable efficient lookups. The dictionary lookup operation has [O(1) complexity](https://en.wikipedia.org/wiki/Big_O_notation#Orders_of_common_functions), and lookups are constantly executed. - -*Assigning Unique Identifiers* - -Each dictionary key must be a unique ID to identify the resource in a univocal way. - -Example: - -```python -self.virtual_machines = {} -self.virtual_machines["vm-01234567890abcdef"] = VirtualMachine() -``` - -### Service Client - -Each Prowler service requires a service client to use the service in the checks. - -The following is the `_client.py` file, which contains the initialization of the freshly created service's class so that service checks can use it. This file is almost the same for all the services among the providers: - -```python -from prowler.providers.common.provider import Provider -from prowler.providers..services.._service import - -_client = (Provider.get_global_provider()) -``` - -## Provider Permissions in Prowler - -Before implementing a new service, verify that Prowler's existing permissions for each provider are sufficient. If additional permissions are required, refer to the relevant documentation and update accordingly. - -Provider-Specific Permissions Documentation: - -- [AWS](../tutorials/aws/authentication.md#required-permissions) -- [Azure](../tutorials/azure/authentication.md#required-permissions) -- [GCP](../tutorials/gcp/authentication.md#required-permissions) -- [M365](../tutorials/microsoft365/authentication.md#required-permissions) -- [GitHub](../tutorials/github/authentication.md) - -## Best Practices - -- When available in the provider, use threading or parallelization utilities for all methods that can be parallelized by to maximize performance and reduce scan time. -- Define a Pydantic `BaseModel` for every resource you manage, and use these models for all resource data handling. -- Log every major step (start, success, error) in resource discovery and attribute collection for traceability and debugging; include as much context as possible. -- Catch and log all exceptions, providing detailed context (region, subscription, resource, error type, line number) to aid troubleshooting. -- Use consistent naming for resource containers, unique identifiers, and model attributes to improve code readability and maintainability. -- Add docstrings to every method and comments to explain any service-specific logic, especially where provider APIs behave differently or have quirks. -- Collect and store resource tags and additional attributes to support richer checks and reporting. -- Leverage shared utility helpers for session setup, identifier parsing, and other cross-cutting concerns to avoid code duplication. This kind of code is typically stored in a `lib` folder in the service folder. -- Keep code modular, maintainable, and well-documented for ease of extension and troubleshooting. diff --git a/docs/developer-guide/services.mdx b/docs/developer-guide/services.mdx new file mode 100644 index 0000000000..ac7088dda0 --- /dev/null +++ b/docs/developer-guide/services.mdx @@ -0,0 +1,550 @@ +--- +title: 'Prowler Services' +--- + +Here you can find how to create a new service, or to complement an existing one, for a [Prowler Provider](/developer-guide/provider). + + +First ensure that the provider you want to add the service is already created. It can be checked [here](https://github.com/prowler-cloud/prowler/tree/master/prowler/providers). If the provider is not present, please refer to the [Provider](./provider.md) documentation to create it from scratch. + +## Introduction + +In Prowler, a **service** represents a specific solution or resource offered by one of the supported [Prowler Providers](/developer-guide/provider), for example, [EC2](https://aws.amazon.com/ec2/) in AWS, or [Microsoft Exchange](https://www.microsoft.com/en-us/microsoft-365/exchange/exchange-online) in M365. Services are the building blocks that allow Prowler interact directly with the various resources exposed by each provider. + +Each service is implemented as a class that encapsulates all the logic, data models, and API interactions required to gather and store information about that service's resources. All of this data is used by the [Prowler checks](/developer-guide/checks) to generate the security findings. + +## Adding a New Service + +To create a new service, a new folder must be created inside the specific provider following this pattern: `prowler/providers//services//`. + +Within this folder the following files are also to be created: + +- `__init__.py` (empty) – Ensures Python recognizes this folder as a package. +- `_service.py` – Contains all the logic and API calls of the service. +- `_client_.py` – Contains the initialization of the freshly created service's class so that the checks can use it. + +Once the files are create, you can check that the service has been created by running the following command: `poetry run python prowler-cli.py --list-services | grep `. + +## Service Structure and Initialisation + +The Prowler's service structure is as outlined below. To initialise it, just import the service client in a check. + +### Service Base Class + +All Prowler provider service should inherit from a common base class to avoid code duplication. This base class handles initialization and storage of functions and objects needed across services. The exact implementation depends on the provider's API requirements, but the following are the most common responsibilities: + +- Initialize/store clients to interact with the provider's API. +- Store the audit and fixer configuration. +- Implement threading logic where applicable. + +For reference, the base classes for each provider can be checked here: + +- [AWS Service Base Class](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/aws/lib/service/service.py) +- [GCP Service Base Class](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/gcp/lib/service/service.py) +- [Azure Service Base Class](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/azure/lib/service/service.py) +- [Kubernetes Service Base Class](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/kubernetes/lib/service/service.py) +- [M365 Service Base Class](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/m365/lib/service/service.py) +- [GitHub Service Base Class](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/github/lib/service/service.py) + +### Service Class + +Due to the complexity and differences across provider APIs, the following example demonstrates best practices for structuring a service in Prowler. + +File `_service.py`: + +```python title="Example Service Class" +from datetime import datetime +from typing import Optional + +# To use the Pydantic's BaseModel. +from pydantic import BaseModel + +# Prowler logging library. +from prowler.lib.logger import logger + +# Provider parent class. +from prowler.providers..lib.service.service import ServiceParentClass + +# Create a class for the Service. +class (ServiceParentClass): + def __init__(self, provider: Provider): + """Initialize the Service Class + + Args: + provider: Prowler Provider object. + """ + # Call Service Parent Class __init__. + # The __class__.__name__ is used to obtain it automatically. + # From the Service Class name, but a custom one can be passed. + # String in case the provider's API service name is different. + super().__init__(__class__.__name__, provider) + + # Create an empty dictionary of items to be gathered, using the unique ID as the dictionary's key, e.g., instances. + self. = {} + + # If parallelization can be carried out by regions or locations, the function __threading_call__ to be used must be implemented in the Service Parent Class. + # If it is not implemented, you can make it in a sequential way, just calling the function. + self.__threading_call__(self.__describe___) + + # If it is needed you can create another function to retrieve more data from the items. + # Here we are using the second parameter of the __threading_call__ function to create one thread per item. + # You can also make it sequential without using the __threading_call__ function iterating over the items inside the function. + self.__threading_call__(self.__describe___, self..values()) + + # In case of use the __threading_call__ function, you have to pass the regional_client to the function, as a parameter. + def __describe___(self, regional_client): + """Get all and store in the self. dictionary + + Args: + regional_client: Regional client object. + """ + logger.info(" - Describing ...") + + # A try-except block must be created in each function. + try: + # If pagination is supported by the provider, is always better to use it, call to the provider API to retrieve the desired data. + describe__paginator = regional_client.get_paginator("describe_") + + # Paginator to get every item. + for page in describe__paginator.paginate(): + + # Another try-except within the for loop to continue iterating in case something unexpected happens. + try: + + for in page[""]: + + # Adding Retrieved Resources to the Object + + # Once the resource has been retrieved, it must be included in the previously created object to ensure proper data handling within the service. + self.[] = + ( + arn=stack[""], + name=stack[""], + tags=stack.get("Tags", []), + region=regional_client.region, + ) + + except Exception as error: + logger.error( + f"{} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + + # Logging Errors in Exception Handling + + # When handling exceptions, use the following approach to log errors appropriately based on the cloud provider being used: + except Exception as error: + # Depending on each provider we can must use different fields in the logger, e.g.: AWS: regional_client.region or self.region, GCP: project_id and location, Azure: subscription + logger.error( + f"{} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + + def __describe___(self, item: ): + """Get details for a + + Args: + item: Item object. + """ + logger.info(" - Describing to get specific details...") + # A try-except block must be created in each function. + try: + + _details = self.regional_clients[.region].describe_( + =.name + ) + + # E.g., check if item is Public. This case is important: if values are being retrieved from a dictionary, the function "dict.get()" must be used with a default value in case this value is not present. + .public = _details.get("Public", False) + except Exception as error: + # Fields for logging errors with relevant item information, e.g.: AWS: .region, GCP: .project_id, Azure: .region + logger.error( + f"{.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) +``` + + +To prevent false findings, when Prowler fails to retrieve items due to Access Denied or similar errors, the affected item's value is set to `None`. + + +#### Resource Models + +Resource models define structured classes used within services to store and process data extracted from API calls. They are defined in the same file as the service class, but outside of the class, usually at the bottom of the file. + +Prowler leverages Pydantic's [BaseModel](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel) to enforce data validation. + +```python title="Service Model" + +# Implementation Approach + +# Each service class should include custom model classes using Pydantic's BaseModel for the resources being audited. + +class (BaseModel): + """ holds a """ + + id: str + """[].id""" + + name: str + """[].name""" + + region: str + """[].region""" + + public: bool + """[].public""" + + # Optional attributes can be created set to None by default. + + tags: Optional[list] + """[].tags""" +``` + +#### Service Attributes + +_Optimized Data Storage with Python Dictionaries_ + +Each group of resources within a service should be structured as a Python [dictionary](https://docs.python.org/3/tutorial/datastructures.html#dictionaries) to enable efficient lookups. The dictionary lookup operation has [O(1) complexity](https://en.wikipedia.org/wiki/Big_O_notation#Orders_of_common_functions), and lookups are constantly executed. + +_Assigning Unique Identifiers_ + +Each dictionary key must be a unique ID to identify the resource in a univocal way. + +Example: + +```python +self.virtual_machines = {} +self.virtual_machines["vm-01234567890abcdef"] = VirtualMachine() +``` + +### Service Client + +Each Prowler service requires a service client to use the service in the checks. + +The following is the `_client.py` file, which contains the initialization of the freshly created service's class so that service checks can use it. This file is almost the same for all the services among the providers: + +```python +from prowler.providers.common.provider import Provider +from prowler.providers..services.._service import + +_client = (Provider.get_global_provider()) +``` + +## Provider Permissions in Prowler + +Before implementing a new service, verify that Prowler's existing permissions for each provider are sufficient. If additional permissions are required, refer to the relevant documentation and update accordingly. + +Provider-Specific Permissions Documentation: + +- [AWS](/user-guide/providers/aws/authentication#required-permissions) +- [Azure](/user-guide/providers/azure/authentication#required-permissions) +- [GCP](/user-guide/providers/gcp/authentication#required-permissions) +- [M365](/user-guide/providers/microsoft365/authentication#required-permissions) +- [GitHub](/user-guide/providers/github/authentication) + +## Service Architecture and Cross-Service Communication + +### Core Principle: Service Isolation with Client Communication + +Each service must contain **ONLY** the information unique to that specific service. When a check requires information from multiple services, it must use the **client objects** of other services rather than directly accessing their data structures. + +This architecture ensures: + +- **Loose coupling** between services +- **Clear separation of concerns** +- **Maintainable and testable code** +- **Consistent data access patterns** + +### Cross-Service Communication Pattern + +Instead of services directly accessing each other's internal data, checks should import and use client objects: + +**āŒ INCORRECT - Direct data access:** + +```python +# DON'T DO THIS +from prowler.providers.aws.services.cloudtrail.cloudtrail_service import cloudtrail_service +from prowler.providers.aws.services.s3.s3_service import s3_service + +class cloudtrail_bucket_requires_mfa_delete(Check): + def execute(self): + # WRONG: Directly accessing service data + for trail in cloudtrail_service.trails.values(): + for bucket in s3_service.buckets.values(): + # Direct access violates separation of concerns +``` + +**āœ… CORRECT - Client-based communication:** + +```python +# DO THIS INSTEAD +from prowler.providers.aws.services.cloudtrail.cloudtrail_client import cloudtrail_client +from prowler.providers.aws.services.s3.s3_client import s3_client + +class cloudtrail_bucket_requires_mfa_delete(Check): + def execute(self): + # CORRECT: Using client objects for cross-service communication + for trail in cloudtrail_client.trails.values(): + trail_bucket = trail.s3_bucket + for bucket in s3_client.buckets.values(): + if trail_bucket == bucket.name: + # Use bucket properties through s3_client + if bucket.mfa_delete: + # Implementation logic +``` + +### Real-World Example: CloudTrail + S3 Integration + +This example demonstrates how CloudTrail checks validate S3 bucket configurations: + +```python +from prowler.lib.check.models import Check, Check_Report_AWS +from prowler.providers.aws.services.cloudtrail.cloudtrail_client import cloudtrail_client +from prowler.providers.aws.services.s3.s3_client import s3_client + +class cloudtrail_bucket_requires_mfa_delete(Check): + def execute(self): + findings = [] + if cloudtrail_client.trails is not None: + for trail in cloudtrail_client.trails.values(): + if trail.is_logging: + trail_bucket_is_in_account = False + trail_bucket = trail.s3_bucket + + # Cross-service communication: CloudTrail check uses S3 client + for bucket in s3_client.buckets.values(): + if trail_bucket == bucket.name: + trail_bucket_is_in_account = True + if bucket.mfa_delete: + report.status = "PASS" + report.status_extended = f"Trail {trail.name} bucket ({trail_bucket}) has MFA delete enabled." + + # Handle cross-account scenarios + if not trail_bucket_is_in_account: + report.status = "MANUAL" + report.status_extended = f"Trail {trail.name} bucket ({trail_bucket}) is a cross-account bucket or out of Prowler's audit scope, please check it manually." + + findings.append(report) + return findings +``` + +**Key Benefits:** + +- **CloudTrail service** only contains CloudTrail-specific data (trails, configurations) +- **S3 service** only contains S3-specific data (buckets, policies, ACLs) +- **Check logic** orchestrates between services using their public client interfaces +- **Cross-account detection** is handled gracefully when resources span accounts + +### Service Consolidation Guidelines + +**When to combine services in the same file:** + +Implement multiple services as **separate classes in the same file** when two services are **practically the same** or one is a **direct extension** of another. + +**Example: S3 and S3Control** + +S3Control is an extension of S3 that provides account-level controls and access points. Both are implemented in `s3_service.py`: + +```python +# File: prowler/providers/aws/services/s3/s3_service.py + +class S3(AWSService): + """Standard S3 service for bucket operations""" + def __init__(self, provider): + super().__init__(__class__.__name__, provider) + self.buckets = {} + self.regions_with_buckets = [] + + # S3-specific initialization + self._list_buckets(provider) + self._get_bucket_versioning() + # ... other S3-specific operations + +class S3Control(AWSService): + """S3Control service for account-level and access point operations""" + def __init__(self, provider): + super().__init__(__class__.__name__, provider) + self.account_public_access_block = None + self.access_points = {} + + # S3Control-specific initialization + self._get_public_access_block() + self._list_access_points() + # ... other S3Control-specific operations +``` + +**Separate client files:** + +```python +# File: prowler/providers/aws/services/s3/s3_client.py +from prowler.providers.aws.services.s3.s3_service import S3 +s3_client = S3(Provider.get_global_provider()) + +# File: prowler/providers/aws/services/s3/s3control_client.py +from prowler.providers.aws.services.s3.s3_service import S3Control +s3control_client = S3Control(Provider.get_global_provider()) +``` + +**When NOT to consolidate services:** + +Keep services separate when they: + +- **Operate on different resource types** (EC2 vs RDS) +- **Have different authentication mechanisms** (different API endpoints) +- **Serve different operational domains** (IAM vs CloudTrail) +- **Have different regional behaviors** (global vs regional services) + +### Cross-Service Dependencies Guidelines + +**1. Always use client imports:** + +```python +# Correct pattern +from prowler.providers.aws.services.service_a.service_a_client import service_a_client +from prowler.providers.aws.services.service_b.service_b_client import service_b_client +``` + +**2. Handle missing resources gracefully:** + +```python +# Handle cross-service scenarios +resource_found_in_account = False +for external_resource in other_service_client.resources.values(): + if target_resource_id == external_resource.id: + resource_found_in_account = True + # Process found resource + break + +if not resource_found_in_account: + # Handle cross-account or missing resource scenarios + report.status = "MANUAL" + report.status_extended = "Resource is cross-account or out of audit scope" +``` + +**3. Document cross-service dependencies:** + +```python +class check_with_dependencies(Check): + """ + Check Description + + Dependencies: + - service_a_client: For primary resource information + - service_b_client: For related resource validation + - service_c_client: For policy analysis + """ +``` + +## Regional Service Implementation + +When implementing services for regional providers (like AWS, Azure, GCP), special considerations are needed to handle resource discovery across multiple geographic locations. This section provides a complete guide using AWS as the reference example. + +### Regional vs Non-Regional Services + +**Regional Services:** Require iteration across multiple geographic locations where resources may exist (e.g., EC2 instances, VPC, RDS databases). + +**Non-Regional/Global Services:** Operate at a global or tenant level without regional concepts (e.g., IAM users, Route53 hosted zones). + +### AWS Regional Implementation Example + +AWS is the perfect example of a regional provider. Here's how Prowler handles AWS's regional architecture: + + +```python +# File: prowler/providers/aws/services/ec2/ec2_service.py +class EC2(AWSService): + def __init__(self, provider): + super().__init__(__class__.__name__, provider) + self.instances = {} + self.security_groups = {} + + # Regional resource discovery across all AWS regions + self.__threading_call__(self._describe_instances) + self.__threading_call__(self._describe_security_groups) + + def _describe_instances(self, regional_client): + """Discover EC2 instances in a specific region""" + try: + describe_instances_paginator = regional_client.get_paginator("describe_instances") + for page in describe_instances_paginator.paginate(): + for reservation in page["Reservations"]: + for instance in reservation["Instances"]: + # Each instance includes its region + self.instances[instance["InstanceId"]] = Instance( + id=instance["InstanceId"], + region=regional_client.region, + state=instance["State"]["Name"], + # ... other properties + ) + except Exception as error: + logger.error(f"Failed to describe instances in {regional_client.region}: {error}") +``` + +#### Regional Check Execution + +```python +# File: prowler/providers/aws/services/ec2/ec2_instance_public_ip/ec2_instance_public_ip.py +class ec2_instance_public_ip(Check): + def execute(self): + findings = [] + + # Automatically iterates across ALL AWS regions where instances exist + for instance in ec2_client.instances.values(): + report = Check_Report_AWS(metadata=self.metadata(), resource=instance) + report.region = instance.region # Critical: region attribution + report.resource_arn = f"arn:aws:ec2:{instance.region}:{instance.account_id}:instance/{instance.id}" + + if instance.public_ip: + report.status = "FAIL" + report.status_extended = f"Instance {instance.id} in {instance.region} has public IP {instance.public_ip}" + else: + report.status = "PASS" + report.status_extended = f"Instance {instance.id} in {instance.region} does not have a public IP" + + findings.append(report) + + return findings +``` + +#### Key AWS Regional Features + +**Region-Specific ARNs:** + +``` +arn:aws:ec2:us-east-1:123456789012:instance/i-1234567890abcdef0 +arn:aws:s3:eu-west-1:123456789012:bucket/my-bucket +arn:aws:rds:ap-southeast-2:123456789012:db:my-database +``` + +**Parallel Processing:** + +- Each region processed independently in separate threads +- Failed regions don't affect other regions +- User can filter specific regions: `-f us-east-1` + +**Global vs Regional Services:** + +- **Regional**: EC2, RDS, VPC (require region iteration) +- **Global**: IAM, Route53, CloudFront (single `us-east-1` call) + +This architecture allows Prowler to efficiently scan AWS accounts with resources spread across multiple regions while maintaining performance and error isolation. + +### Regional Service Best Practices + +1. **Use Threading for Regional Discovery**: Leverage the `__threading_call__` method to parallelize resource discovery across regions +2. **Store Region Information**: Always include region metadata in resource objects for proper attribution +3. **Handle Regional Failures Gracefully**: Ensure that failures in one region don't affect others +4. **Optimize for Performance**: Use paginated calls and efficient data structures for large-scale resource discovery +5. **Support Region Filtering**: Allow users to limit scans to specific regions for focused audits + +## Best Practices + +- When available in the provider, use threading or parallelization utilities for all methods that can be parallelized by to maximize performance and reduce scan time. +- Define a Pydantic `BaseModel` for every resource you manage, and use these models for all resource data handling. +- Log every major step (start, success, error) in resource discovery and attribute collection for traceability and debugging; include as much context as possible. +- Catch and log all exceptions, providing detailed context (region, subscription, resource, error type, line number) to aid troubleshooting. +- Use consistent naming for resource containers, unique identifiers, and model attributes to improve code readability and maintainability. +- Add docstrings to every method and comments to explain any service-specific logic, especially where provider APIs behave differently or have quirks. +- Collect and store resource tags and additional attributes to support richer checks and reporting. +- Leverage shared utility helpers for session setup, identifier parsing, and other cross-cutting concerns to avoid code duplication. This kind of code is typically stored in a `lib` folder in the service folder. +- Keep code modular, maintainable, and well-documented for ease of extension and troubleshooting. +- **Each service should contain only information unique to that specific service** - use client objects for cross-service communication. +- **Handle cross-account and missing resources gracefully** when checks span multiple services. diff --git a/docs/developer-guide/unit-testing.md b/docs/developer-guide/unit-testing.mdx similarity index 96% rename from docs/developer-guide/unit-testing.md rename to docs/developer-guide/unit-testing.mdx index ab4e4e3bf7..8713988440 100644 --- a/docs/developer-guide/unit-testing.md +++ b/docs/developer-guide/unit-testing.mdx @@ -1,4 +1,6 @@ -# Unit Tests for Prowler Checks +--- +title: 'Unit Tests for Prowler Checks' +--- Unit tests for Prowler checks vary based on the provider being evaluated. @@ -39,7 +41,7 @@ To execute the Prowler test suite, install the necessary dependencies listed in ### Prerequisites -If you have not installed Prowler yet, refer to the [developer guide introduction](./introduction.md#getting-the-code-and-installing-all-dependencies). +If you have not installed Prowler yet, refer to the [developer guide introduction](/developer-guide/introduction#getting-the-code-and-installing-all-dependencies). ### Executing Tests @@ -57,16 +59,18 @@ Other Commands for Running Tests - Running tests for a provider check: `pytest -n auto -vvv -s -x tests/providers//services//` -???+ note - Refer to the [pytest documentation](https://docs.pytest.org/en/7.1.x/getting-started.html) for more details. + +Refer to the [pytest documentation](https://docs.pytest.org/en/7.1.x/getting-started.html) for more details. + ## AWS Testing Approaches For AWS provider, different testing approaches apply based on API coverage based on several criteria. -???+ note - Prowler leverages and contributes to the[Moto](https://github.com/getmoto/moto) library for mocking AWS infrastructure in tests. + +Prowler leverages and contributes to the[Moto](https://github.com/getmoto/moto) library for mocking AWS infrastructure in tests. + - AWS API Calls Covered by [Moto](https://github.com/getmoto/moto): - Service Tests: `@mock_aws` - Checks Tests: `@mock_aws` @@ -205,12 +209,14 @@ class Test_iam_password_policy_uppercase: If the IAM service required for testing is not supported by the Moto library, use [MagicMock](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.MagicMock) to inject objects into the service client. -???+ warning - As stated above, direct service instantiation must be avoided to prevent actual AWS API calls. + +As stated above, direct service instantiation must be avoided to prevent actual AWS API calls. -???+ note - The example below demonstrates the IAM GetAccountPasswordPolicy API, which is covered by Moto, but is used for instructional purposes only. + + +The example below demonstrates the IAM GetAccountPasswordPolicy API, which is covered by Moto, but is used for instructional purposes only. + #### Mocking Service Objects Using MagicMock The following code demonstrates how to use MagicMock to create service objects. @@ -377,13 +383,15 @@ class Test_iam_password_policy_uppercase: # Refer to the previous section for the check test, as the implementation remains unchanged. ``` -???+ note - This example does not use Moto to simplify the setup. - However, if additional `moto` decorators are applied alongside the patch, Moto will automatically intercept the call to `orig(self, operation_name, kwarg)`. + +This example does not use Moto to simplify the setup. +However, if additional `moto` decorators are applied alongside the patch, Moto will automatically intercept the call to `orig(self, operation_name, kwarg)`. -???+ note - The source of the above implementation can be found here:[Patch Other Services with Moto](https://docs.getmoto.org/en/latest/docs/services/patching\_other\_services.html) + + +The source of the above implementation can be found here:[Patch Other Services with Moto](https://docs.getmoto.org/en/latest/docs/services/patching\_other\_services.html) + #### Mocking Several Services Since the provider is being mocked, multiple attributes can be configured to customize its behavior: @@ -488,7 +496,7 @@ will cause that the service will be initialised twice: Later, when importing `_client.py` at `.py`, Python uses the mocked instance since the patch was applied at the correct reference point. -In the [next section](./unit-testing.md#mocking-the-service-and-the-service-client-at-the-service-client-level) we will explore an improved approach to mock objects. +In the [next section](/developer-guide/unit-testing#mocking-the-service-and-the-service-client-at-the-service-client-level) we will explore an improved approach to mock objects. ##### Mocking the Service and the Service Client at the Service Client Level @@ -642,9 +650,10 @@ class Test_compute_project_os_login_enabled: The testing of Google Cloud Services follows the same principles as the one of Google Cloud checks. While all API calls must be mocked, attribute setup for API calls in this scenario is defined in the fixtures file, specifically within the [fixtures file](https://github.com/prowler-cloud/prowler/blob/master/tests/providers/gcp/gcp_fixtures.py) in the `mock_api_client` function. -???+ important - Every method within a service must be tested to ensure full coverage and accurate validation. + +Every method within a service must be tested to ensure full coverage and accurate validation. + The following example presents a real testing class, but includes additional comments for educational purposes, explaining key concepts and implementation details. ```python title="BigQuery Service Test" @@ -907,9 +916,12 @@ class Test_app_ensure_http_is_redirected_to_https: The testing of Azure Services follows the same principles as the one of Google Cloud checks. All API calls are still mocked, but for methods that initialize attributes via an API call, use the [patch](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch) decorator at the beginning of the class to ensure proper mocking. -???+ important "Remember" - Every method within a service must be tested to ensure full coverage and accurate validation. + +**Remember** +Every method within a service must be tested to ensure full coverage and accurate validation. + + The following example presents a real testing class, but includes additional comments for educational purposes, explaining key concepts and implementation details. ```python title="AppInsights Service Test" diff --git a/docs/docs.json b/docs/docs.json new file mode 100644 index 0000000000..7d3f795482 --- /dev/null +++ b/docs/docs.json @@ -0,0 +1,433 @@ +{ + "$schema": "https://mintlify.com/docs.json", + "theme": "mint", + "name": "Prowler Documentation", + "colors": { + "primary": "#000000", + "light": "#10B981", + "dark": "#10B981" + }, + "favicon": "/favicon.ico", + "logo": { + "dark": "/images/prowler-logo-white.png", + "light": "/images/prowler-logo-black.png" + }, + "navigation": { + "tabs": [ + { + "tab": "Getting Started", + "groups": [ + { + "group": "Welcome", + "pages": [ + "introduction" + ] + }, + { + "group": "Prowler Cloud", + "pages": [ + "getting-started/products/prowler-cloud", + "getting-started/products/prowler-cloud-pricing", + "getting-started/products/prowler-cloud-aws-marketplace", + "getting-started/goto/prowler-cloud", + "getting-started/goto/prowler-api-reference" + ] + }, + { + "group": "Prowler CLI", + "pages": [ + "getting-started/products/prowler-cli", + "getting-started/installation/prowler-cli", + "getting-started/basic-usage/prowler-cli" + ] + }, + { + "group": "Prowler App", + "pages": [ + "getting-started/products/prowler-app", + "getting-started/installation/prowler-app", + "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": [ + "getting-started/products/prowler-hub", + "getting-started/goto/prowler-hub" + ] + }, + { + "group": "Prowler vs. Others", + "pages": [ + "getting-started/comparison/index", + "getting-started/comparison/awssecurityhub", + "getting-started/comparison/gcp", + "getting-started/comparison/microsoftdefender", + "getting-started/comparison/microsoftsentinel" + ] + } + ] + }, + { + "tab": "Guides", + "groups": [ + { + "group": "Prowler Cloud/App", + "pages": [ + "user-guide/tutorials/prowler-app", + { + "group": "Authentication", + "pages": [ + "user-guide/tutorials/prowler-app-social-login", + "user-guide/tutorials/prowler-app-sso" + ] + }, + "user-guide/tutorials/prowler-app-rbac", + "user-guide/tutorials/prowler-app-api-keys", + "user-guide/tutorials/prowler-app-mute-findings", + { + "group": "Integrations", + "expanded": true, + "pages": [ + "user-guide/tutorials/prowler-app-s3-integration", + "user-guide/tutorials/prowler-app-security-hub-integration", + "user-guide/tutorials/prowler-app-jira-integration" + ] + }, + "user-guide/tutorials/prowler-app-lighthouse", + "user-guide/tutorials/prowler-cloud-public-ips", + { + "group": "Tutorials", + "pages": [ + "user-guide/tutorials/prowler-app-sso-entra", + "user-guide/tutorials/bulk-provider-provisioning", + "user-guide/tutorials/aws-organizations-bulk-provisioning" + ] + } + ] + }, + { + "group": "CLI", + "pages": [ + "user-guide/cli/tutorials/misc", + "user-guide/cli/tutorials/reporting", + "user-guide/cli/tutorials/compliance", + "user-guide/cli/tutorials/dashboard", + "user-guide/cli/tutorials/configuration_file", + "user-guide/cli/tutorials/logging", + "user-guide/cli/tutorials/mutelist", + { + "group": "Integrations", + "pages": [ + "user-guide/providers/aws/securityhub", + "user-guide/cli/tutorials/integrations", + "user-guide/providers/aws/s3" + ] + }, + "user-guide/cli/tutorials/fixer", + "user-guide/cli/tutorials/check-aliases", + "user-guide/cli/tutorials/custom-checks-metadata", + "user-guide/cli/tutorials/pentesting", + "user-guide/cli/tutorials/scan-unused-services", + "user-guide/cli/tutorials/quick-inventory", + { + "group": "Tutorials", + "pages": [ + "user-guide/cli/tutorials/parallel-execution" + ] + } + ] + }, + { + "group": "Providers", + "pages": [ + { + "group": "AWS", + "pages": [ + "user-guide/providers/aws/getting-started-aws", + "user-guide/providers/aws/authentication", + "user-guide/providers/aws/role-assumption", + "user-guide/providers/aws/organizations", + "user-guide/providers/aws/regions-and-partitions", + "user-guide/providers/aws/tag-based-scan", + "user-guide/providers/aws/resource-arn-based-scan", + "user-guide/providers/aws/boto3-configuration", + "user-guide/providers/aws/threat-detection", + "user-guide/providers/aws/cloudshell", + "user-guide/providers/aws/multiaccount" + ] + }, + { + "group": "Azure", + "pages": [ + "user-guide/providers/azure/getting-started-azure", + "user-guide/providers/azure/authentication", + "user-guide/providers/azure/use-non-default-cloud", + "user-guide/providers/azure/subscriptions", + "user-guide/providers/azure/create-prowler-service-principal" + ] + }, + { + "group": "Google Cloud", + "pages": [ + "user-guide/providers/gcp/getting-started-gcp", + "user-guide/providers/gcp/authentication", + "user-guide/providers/gcp/projects", + "user-guide/providers/gcp/organization", + "user-guide/providers/gcp/retry-configuration" + ] + }, + { + "group": "Kubernetes", + "pages": [ + "user-guide/providers/kubernetes/getting-started-k8s", + "user-guide/providers/kubernetes/misc" + ] + }, + { + "group": "Microsoft 365", + "pages": [ + "user-guide/providers/microsoft365/getting-started-m365", + "user-guide/providers/microsoft365/authentication", + "user-guide/providers/microsoft365/use-of-powershell" + ] + }, + { + "group": "GitHub", + "pages": [ + "user-guide/providers/github/getting-started-github", + "user-guide/providers/github/authentication" + ] + }, + { + "group": "IaC", + "pages": [ + "user-guide/providers/iac/getting-started-iac", + "user-guide/providers/iac/authentication" + ] + }, + { + "group": "MongoDB Atlas", + "pages": [ + "user-guide/providers/mongodbatlas/getting-started-mongodbatlas", + "user-guide/providers/mongodbatlas/authentication" + ] + }, + { + "group": "LLM", + "pages": [ + "user-guide/providers/llm/getting-started-llm" + ] + }, + { + "group": "Oracle Cloud Infrastructure", + "pages": [ + "user-guide/providers/oci/getting-started-oci", + "user-guide/providers/oci/authentication" + ] + } + ] + }, + { + "group": "Compliance", + "pages": [ + "user-guide/compliance/tutorials/threatscore" + ] + } + ] + }, + { + "tab": "Developer Guide", + "groups": [ + { + "group": "Concepts", + "pages": [ + "developer-guide/introduction", + "developer-guide/provider", + "developer-guide/services", + "developer-guide/checks", + "developer-guide/outputs", + "developer-guide/integrations", + "developer-guide/security-compliance-framework", + "developer-guide/lighthouse" + ] + }, + { + "group": "Providers", + "pages": [ + "developer-guide/aws-details", + "developer-guide/azure-details", + "developer-guide/gcp-details", + "developer-guide/kubernetes-details", + "developer-guide/m365-details", + "developer-guide/github-details", + "developer-guide/llm-details" + ] + }, + { + "group": "Miscellaneous", + "pages": [ + "developer-guide/documentation", + { + "group": "Testing", + "pages": [ + "developer-guide/unit-testing", + "developer-guide/integration-testing" + ] + }, + "developer-guide/debugging", + "developer-guide/configurable-checks", + "developer-guide/renaming-checks", + "developer-guide/check-metadata-guidelines" + ] + } + ] + }, + { + "tab": "Security", + "pages": [ + "security" + ] + }, + { + "tab": "Contact Us", + "pages": [ + "contact" + ] + }, + { + "tab": "Troubleshooting", + "pages": [ + "troubleshooting" + ] + }, + { + "tab": "About Us", + "icon": "/favicon.ico", + "href": "https://prowler.com/about#team" + }, + { + "tab": "Changelog", + "icon": "github", + "href": "https://github.com/prowler-cloud/prowler/releases" + }, + { + "tab": "Public Roadmap", + "href": "https://roadmap.prowler.com/" + } + ], + "global": { + "anchors": [ + { + "anchor": "GitHub", + "href": "https://github.com/prowler-cloud/prowler", + "icon": "github" + }, + { + "anchor": "Slack", + "href": "https://goto.prowler.com/slack", + "icon": "slack" + }, + { + "anchor": "YouTube", + "href": "https://www.youtube.com/@prowlercloud", + "icon": "youtube" + } + ] + } + }, + "navbar": { + "links": [ + { + "label": "Prowler Hub", + "href": "https://hub.prowler.com" + }, + { + "label": "Prowler Cloud", + "href": "https://cloud.prowler.com", + "style": "primary" + } + ] + }, + "analytics": { + "ga4": { + "measurementId": "G-KBKV70W5Y2" + } + }, + "feedback": { + "thumbsRating": true, + "suggestEdit": true, + "raiseIssue": true + }, + "footer": { + "socials": { + "x-twitter": "https://x.com/prowlercloud", + "github": "https://github.com/prowler-cloud/prowler", + "linkedin": "https://www.linkedin.com/company/prowler-security", + "youtube": "https://www.youtube.com/@prowlercloud", + "slack": "https://goto.prowler.com/slack", + "website": "https://prowler.com" + } + }, + "redirects": [ + { + "source": "/projects/prowler-open-source/en/latest/tutorials/prowler-app-lighthouse", + "destination": "/user-guide/tutorials/prowler-app-lighthouse" + }, + { + "source": "/projects/prowler-open-source/en/latest/developer-guide/introduction", + "destination": "/developer-guide/introduction" + }, + { + "source": "/projects/prowler-open-source/en/latest/tutorials/aws/getting-started-aws", + "destination": "/user-guide/providers/aws/getting-started-aws" + }, + { + "source": "/projects/prowler-open-source/en/latest/tutorials/azure/getting-started-azure", + "destination": "/user-guide/providers/azure/getting-started-azure" + }, + { + "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/microsoft365/getting-started-m365", + "destination": "/user-guide/providers/microsoft365/getting-started-m365" + }, + { + "source": "/projects/prowler-open-source/en/latest/tutorials/github/getting-started-github", + "destination": "/user-guide/providers/github/getting-started-github" + }, + { + "source": "/projects/prowler-open-source/en/latest/tutorials/prowler-app-sso", + "destination": "/user-guide/tutorials/prowler-app-sso" + }, + { + "source": "/projects/prowler-open-source/en/latest", + "destination": "/introduction" + }, + { + "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-app.mdx b/docs/getting-started/basic-usage/prowler-app.mdx new file mode 100644 index 0000000000..26d7d8ee2e --- /dev/null +++ b/docs/getting-started/basic-usage/prowler-app.mdx @@ -0,0 +1,70 @@ +--- +title: 'Basic Usage' +--- + +## Access Prowler App + +After [installation](/getting-started/installation/prowler-app), navigate to [http://localhost:3000](http://localhost:3000) and sign up with email and password. + +Sign Up Button +Sign Up + + +**User creation and default tenant behavior** + + +When creating a new user, the behavior depends on whether an invitation is provided: + +- **Without an invitation**: + + - A new tenant is automatically created. + - The new user is assigned to this tenant. + - A set of **RBAC admin permissions** is generated and assigned to the user for the newly-created tenant. + +- **With an invitation**: The user is added to the specified tenant with the permissions defined in the invitation. + +This mechanism ensures that the first user in a newly created tenant has administrative permissions within that tenant. + + +## Log In + +Access Prowler App by logging in with **email and password**. + +Log In + +## Add Cloud Provider + +Configure a cloud provider for scanning: + +1. Navigate to `Settings > Cloud Providers` and click `Add Account`. +2. Select the cloud provider. +3. Enter the provider's identifier (Optional: Add an alias): + - **AWS**: Account ID + - **GCP**: Project ID + - **Azure**: Subscription ID + - **Kubernetes**: Cluster ID + - **M365**: Domain ID +4. Follow the guided instructions to add and authenticate your credentials. + +## Start a Scan + +Once credentials are successfully added and validated, Prowler initiates a scan of your cloud environment. + +Click `Go to Scans` to monitor progress. + +## View Results + +Review findings during scan execution in the following sections: + +- **Overview** – Provides a high-level summary of your scans. + Overview + +- **Compliance** – Displays compliance insights based on security frameworks. + Compliance + +> For detailed usage instructions, refer to the [Prowler App Guide](/user-guide/tutorials/prowler-app). + + +Prowler will automatically scan all configured providers every **24 hours**, ensuring your cloud environment stays continuously monitored. + + diff --git a/docs/basic-usage/prowler-cli.md b/docs/getting-started/basic-usage/prowler-cli.mdx similarity index 68% rename from docs/basic-usage/prowler-cli.md rename to docs/getting-started/basic-usage/prowler-cli.mdx index 0c093968b4..95e7a77b51 100644 --- a/docs/basic-usage/prowler-cli.md +++ b/docs/getting-started/basic-usage/prowler-cli.mdx @@ -1,18 +1,24 @@ +--- +title: 'Basic Usage' +--- + ## Running Prowler -Running Prowler requires specifying the provider (e.g `aws`, `gcp`, `azure`, `m365`, `github` or `kubernetes`): +Running Prowler requires specifying the provider (e.g `aws`, `gcp`, `azure`, `kubernetes`, `m365`, `github`, `iac` or `mongodbatlas`): -???+ note - If no provider is specified, AWS is used by default for backward compatibility with Prowler v2. + +If no provider is specified, AWS is used by default for backward compatibility with Prowler v2. + ```console prowler ``` -![Prowler Execution](../img/short-display.png) +![Prowler Execution](/images/short-display.png) -???+ note - Running the `prowler` command without options will uses environment variable credentials. Refer to the Authentication section of each provider for credential configuration details. + +Running the `prowler` command without options will uses environment variable credentials. Refer to the Authentication section of each provider for credential configuration details. + ## Verbose Output If you prefer the former verbose output, use: `--verbose`. This allows seeing more info while Prowler is running, minimal output is displayed unless verbosity is enabled. @@ -26,7 +32,7 @@ prowler -M csv json-asff json-ocsf html ``` The HTML report is saved in the output directory, alongside other reports. It will look like this: -![Prowler Execution](../img/html-output.png) +![Prowler Execution](/images/html-output.png) ## Listing Available Checks and Services @@ -58,7 +64,7 @@ prowler kubernetes --excluded-services controllermanager ``` ## Additional Options -Explore more advanced time-saving execution methods in the [Miscellaneous](../tutorials/misc.md) section. +Explore more advanced time-saving execution methods in the [Miscellaneous](/user-guide/cli/tutorials/misc) section. Access the help menu and view all available options with `-h`/`--help`: @@ -74,10 +80,11 @@ Use a custom AWS profile with `-p`/`--profile` and/or specific AWS regions with prowler aws --profile custom-profile -f us-east-1 eu-south-2 ``` -???+ note - By default, `prowler` will scan all AWS regions. + +By default, `prowler` will scan all AWS regions. -See more details about AWS Authentication in the [Authentication Section](../tutorials/aws/authentication.md) section. + +See more details about AWS Authentication in the [Authentication Section](/user-guide/providers/aws/authentication) section. ## Azure @@ -97,7 +104,7 @@ prowler azure --browser-auth --tenant-id "XXXXXXXX" prowler azure --managed-identity-auth ``` -See more details about Azure Authentication in the [Authentication Section](../tutorials/azure/authentication.md) +See more details about Azure Authentication in the [Authentication Section](/user-guide/providers/azure/authentication) By default, Prowler scans all accessible subscriptions. Scan specific subscriptions using the following flag (using az cli auth as example): @@ -154,9 +161,10 @@ Prowler enables security scanning of Kubernetes clusters, supporting both **in-c ```console prowler kubernetes --kubeconfig-file path ``` - ???+ note + If no `--kubeconfig-file` is provided, Prowler will use the default KubeConfig file location (`~/.kube/config`). + - **In-Cluster Execution** To run Prowler inside the cluster, apply the provided YAML configuration to deploy a job in a new namespace: @@ -170,9 +178,10 @@ Prowler enables security scanning of Kubernetes clusters, supporting both **in-c kubectl logs prowler-XXXXX --namespace prowler-ns ``` - ???+ note + By default, Prowler scans all namespaces in the active Kubernetes context. Use the `--context`flag to specify the context to be scanned and `--namespaces` to restrict scanning to specific namespaces. + ## Microsoft 365 Microsoft 365 requires specifying the auth method: @@ -182,9 +191,6 @@ Microsoft 365 requires specifying the auth method: # To use service principal authentication for MSGraph and PowerShell modules prowler m365 --sp-env-auth -# To use both service principal (for MSGraph) and user credentials (for PowerShell modules) -prowler m365 --env-auth - # To use az cli authentication prowler m365 --az-cli-auth @@ -193,7 +199,7 @@ prowler m365 --browser-auth --tenant-id "XXXXXXXX" ``` -See more details about M365 Authentication in the [Authentication Section](../tutorials/microsoft365/authentication.md) section. +See more details about M365 Authentication in the [Authentication Section](/user-guide/providers/microsoft365/authentication) section. ## GitHub @@ -214,13 +220,14 @@ Prowler enables security scanning of your **GitHub account**, including **Reposi prowler github --github-app-id app_id --github-app-key app_key ``` - ???+ note + If no login method is explicitly provided, Prowler will automatically attempt to authenticate using environment variables in the following order of precedence: 1. `GITHUB_PERSONAL_ACCESS_TOKEN` 2. `OAUTH_APP_TOKEN` 3. `GITHUB_APP_ID` and `GITHUB_APP_KEY` + ## Infrastructure as Code (IaC) Prowler's Infrastructure as Code (IaC) provider enables you to scan local or remote infrastructure code for security and compliance issues using [Trivy](https://trivy.dev/). This provider supports a wide range of IaC frameworks, allowing you to assess your code before deployment. @@ -247,11 +254,63 @@ prowler iac --scan-path ./my-iac-directory --frameworks terraform kubernetes prowler iac --scan-path ./my-iac-directory --exclude-path ./my-iac-directory/test,./my-iac-directory/examples ``` -???+ note - - `--scan-path` and `--scan-repository-url` are mutually exclusive; only one can be specified at a time. - - For remote repository scans, authentication can be provided via CLI flags or environment variables (`GITHUB_OAUTH_APP_TOKEN`, `GITHUB_USERNAME`, `GITHUB_PERSONAL_ACCESS_TOKEN`). CLI flags take precedence. - - The IaC provider does not require cloud authentication for local scans. - - It is ideal for CI/CD pipelines and local development environments. - - For more details on supported scanners, see the [Trivy documentation](https://trivy.dev/latest/docs/scanner/vulnerability/) + +- `--scan-path` and `--scan-repository-url` are mutually exclusive; only one can be specified at a time. +- For remote repository scans, authentication can be provided via CLI flags or environment variables (`GITHUB_OAUTH_APP_TOKEN`, `GITHUB_USERNAME`, `GITHUB_PERSONAL_ACCESS_TOKEN`). CLI flags take precedence. +- The IaC provider does not require cloud authentication for local scans. +- It is ideal for CI/CD pipelines and local development environments. +- For more details on supported scanners, see the [Trivy documentation](https://trivy.dev/latest/docs/scanner/vulnerability/) -See more details about IaC scanning in the [IaC Tutorial](../tutorials/iac/getting-started-iac.md) section. + +See more details about IaC scanning in the [IaC Tutorial](/user-guide/providers/iac/getting-started-iac) section. + +## MongoDB Atlas + +Prowler allows you to scan your MongoDB Atlas cloud database deployments for security and compliance issues. + +Authentication is done using MongoDB Atlas API key pairs: + +```console +# Using command-line arguments +prowler mongodbatlas --atlas-public-key --atlas-private-key + +# Using environment variables +export ATLAS_PUBLIC_KEY= +export ATLAS_PRIVATE_KEY= +prowler mongodbatlas +``` + +You can filter scans to specific organizations or projects: + +```console +# Scan specific project +prowler mongodbatlas --atlas-project-id +``` + +See more details about MongoDB Atlas Authentication in [MongoDB Atlas Authentication](/user-guide/providers/mongodbatlas/authentication) + +## Oracle Cloud + +Prowler allows you to scan your Oracle Cloud deployments for security and compliance issues. + +You have two options to authenticate: + +1. OCI Config File Authentication: this config file can be generated using the OCI CLI with the `oci session authenticate` command or created manually using the OCI Console. For more details, see the [OCI Authentication Guide](/user-guide/providers/oci/authentication#oci-session-authentication). + + ```console + prowler oci + ``` + + You can add different profiles to the config file to scan different tenancies or regions. In order to scan a specific profile, use the `--profile` flag: + + ```console + prowler oci --profile + ``` + +2. Instance Principal Authentication: when running Prowler on an OCI Compute instance, you can use Instance Principal authentication. For more details, see the [OCI Authentication Guide](/user-guide/providers/oci/authentication#instance-principal-authentication). + + ```console + prowler oci --use-instance-principal + ``` + +See more details about Oracle Cloud Authentication in [Oracle Cloud Authentication](/user-guide/providers/oci/authentication) 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..b6d59093e7 --- /dev/null +++ b/docs/getting-started/basic-usage/prowler-mcp.mdx @@ -0,0 +1,291 @@ +--- +title: "Configuration" +--- + +Configure your MCP client to connect to Prowler MCP Server. + +## Step 1: Get Your API Key + + +**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/tutorials/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 Host/Client + +Choose the configuration based on your deployment: + +- **HTTP Mode**: Prowler Cloud MCP Server or self-hosted Prowler MCP Server. +- **STDIO Mode**: Local installation only (runs as subprocess of your MCP client). + +### HTTP Mode + + + + **Configuration:** + ```json + { + "mcpServers": { + "prowler": { + "url": "https://mcp.prowler.com/mcp", // or your self-hosted Prowler MCP Server URL + "headers": { + "Authorization": "Bearer " + } + } + } + } + ``` + + + + **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": "" + } + } + } + } + ``` + + 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). + + + + + 1. Open Claude Desktop settings + 2. Go to "Developer" tab + 3. Click in "Edit Config" button + 4. Edit the `claude_desktop_config.json` file with your favorite editor + 5. Add the following configuration: + ```json + { + "mcpServers": { + "prowler": { + "command": "npx", + "args": [ + "mcp-remote", + "https://mcp.prowler.com/mcp", + "--header", + "Authorization: Bearer ${PROWLER_APP_API_KEY}" + ], + "env": { + "PROWLER_APP_API_KEY": "" + } + } + } + } + ``` + + + + Run the following command: + ```bash + export PROWLER_APP_API_KEY="" + claude mcp add --transport http prowler https://mcp.prowler.com/mcp --header "Authorization: Bearer $PROWLER_APP_API_KEY" --scope user + ``` + + + + 1. Open Cursor settings + 2. Go to "Tools & MCP" + 3. Click in "New MCP Server" button + 4. Add to the JSON Configuration the following: + ```json + { + "mcpServers": { + "prowler": { + "url": "https://mcp.prowler.com/mcp", + "headers": { + "Authorization": "Bearer " + } + } + } + } + ``` + + + + + +### STDIO Mode + +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": "", + "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=", + "--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 +``` + +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/comparison/awssecurityhub.mdx b/docs/getting-started/comparison/awssecurityhub.mdx new file mode 100644 index 0000000000..4b5d743dbe --- /dev/null +++ b/docs/getting-started/comparison/awssecurityhub.mdx @@ -0,0 +1,94 @@ +--- +title: 'AWS Security Hub' +--- + +AWS Security Hub remains a managed service designed for centralizing security alerts and compliance status within AWS environments. It integrates with various AWS security services and provides a consolidated view of security findings. + +## Key Features and Strengths + +- **Centralized Dashboard for AWS:** Provides a single pane of glass to monitor and manage security findings from multiple AWS services like GuardDuty, Inspector, and Config. + +- **Compliance Checks:** Automatically checks for compliance against standards like CIS and PCI DSS within AWS environments. + +- **AWS Native Automation:** Offers seamless automation for incident response using AWS Lambda and CloudWatch Events, reducing the time to react to security issues. + +- **User-Friendly Interface:** Accessible via the AWS Management Console, offering a streamlined experience for managing security across AWS accounts. + +## Limitations + +- **AWS-Centric:** Limited to AWS environments, with no direct support for multi-cloud or hybrid environments. + +- **Dependency on AWS Config:** Some of its checks depend on AWS Config, which may not be enabled in all regions or accounts. + +- **Vendor Lock-In:** Tightly coupled with AWS, making it less suitable for organizations with a cloud-agnostic strategy. + +## Prowler + +Prowler is an open-source, multi-cloud security tool that offers extensive customization and flexibility, making it ideal for organizations with complex or multi-cloud environments. Here are the updated features and advantages: + +## Main Advantages of Prowler + +- **Multi-Region and Multi-Account Scanning by Default:** + - Prowler is inherently multi-region and can scan multiple AWS accounts without requiring additional configuration or enabling specific services like AWS Config. + +- **Minimal Setup Requirements:** + - All Prowler needs is a role with appropriate permissions to start scanning. There’s no need to enable specific services or configure complex setups. + +- **Versatile Execution Environment:** + - Prowler can be run from various environments, including a local workstation, container, AWS CloudShell, or even from another AWS account or cloud provider by assuming a role. This flexibility makes it easy to integrate into different operational workflows. + +- **Flexible Results Storage and Sharing:** + - Prowler results can be stored directly into an S3 bucket, allowing for quick analysis, or locally for easy sharing and discussion. This flexibility is particularly useful for collaborative security assessments. + +- **Customizable Reporting and Analysis:** + - Prowler supports exporting results in multiple formats, including JSON, CSV, OCSF format, and static HTML reports. It also supports integration with Amazon QuickSight for in-depth analysis and offers a SaaS model with resource-based pricing, making it adaptable to different organizational needs. + +- **Security Hub Integration for Cost-Effective Operations:** + - Prowler can send results directly into Security Hub in any AWS account, including only failed findings. This selective reporting can make Security Hub more cost-effective by reducing the volume of data processed. + +- **Custom Checks and Compliance Frameworks:** + - Users can write custom checks, remediations, and compliance frameworks in minutes, tailoring the tool to their specific security policies and operational needs. + +- **Extensive Compliance Support:** + - Prowler supports over 27 compliance frameworks out of the box for AWS, providing comprehensive coverage across various regulatory requirements and best practices. + +- **Kubernetes and Multi-Cloud Support:** + - Prowler extends its scanning capabilities beyond AWS, offering support for Kubernetes clusters (including EKS), as well as environments in Google Cloud Platform (GCP) and Azure. This multi-cloud capability is essential for organizations with diverse cloud footprints. + +- **All-Region Checks:** + - Prowler runs all checks in all regions, regardless of AWS Config resource type support, ensuring comprehensive coverage across your entire AWS environment. + +## Comparison Summary + +### Scope and Environment + +- **Security Hub** is ideal for AWS-centric environments needing a managed service for monitoring and automating security across AWS resources. +- **Prowler** is better suited for organizations operating in multi-cloud or hybrid environments, offering flexibility, customization, and support for multiple cloud providers including AWS, Azure, GCP, and Kubernetes. + +### Setup and Maintenance + +- **Security Hub** requires enabling and configuring AWS services by region, per account, and can become more than one person's full-time role – including Config. Security Hub operates only within the AWS ecosystem. +- **Prowler** requires minimal setup, only needing appropriate permissions, and can be executed from various environments, making it more versatile in different operational contexts. + +### Customization and Flexibility + +- **Security Hub** offers predefined compliance checks and automation within AWS but is less flexible in terms of customization. +- **Prowler** allows for highly customizable checks, remediation actions, and compliance frameworks, with the ability to adapt quickly to organizational needs and regulatory changes. + +### Cost Efficiency + +- **Security Hub** may involve additional costs for processing and storing findings. +- **Prowler** can optimize costs by selectively sending failed findings to Security Hub and storing results locally or in S3, which can be more cost-effective. + +### Multi-Cloud and Multi-Region Support + +- **Security Hub** is confined to AWS, with region-specific checks depending on AWS Config. +- **Prowler** is inherently multi-region and multi-cloud, offering consistent and comprehensive checks across different cloud environments and regions. + +## Conclusion + +For a CISO or security professional evaluating these tools, the decision between AWS Security Hub and Prowler will depend on the organization’s cloud strategy, compliance needs, and the level of flexibility required: + +- If the organization is heavily invested in AWS and prefers a managed, integrated security service that offers ease of use and automation within the AWS ecosystem, **AWS Security Hub** is the more appropriate choice. + +- If the organization operates in a multi-cloud environment or requires a highly customizable tool that can run comprehensive, multi-region scans across AWS, Azure, GCP, and Kubernetes, **Prowler** provides a more powerful and flexible solution, especially for those needing to adapt quickly to evolving security and compliance requirements. diff --git a/docs/getting-started/comparison/gcp.mdx b/docs/getting-started/comparison/gcp.mdx new file mode 100644 index 0000000000..00f61091d7 --- /dev/null +++ b/docs/getting-started/comparison/gcp.mdx @@ -0,0 +1,97 @@ +--- +title: 'GCP Cloud Security Command Center (Cloud SCC)' +--- + +Google Cloud Security Command Center (Cloud SCC) is a centralized security and risk management platform for Google Cloud Platform (GCP). It provides visibility into assets, vulnerabilities, and threats across GCP environments, helping organizations to manage and improve their security posture. + +## Key Features and Strengths + +- **Centralized Security Visibility:** Cloud SCC provides a single pane of glass to monitor the security and risk status across your GCP resources. It aggregates findings from various GCP security services, such as Security Health Analytics, Web Security Scanner, and Event Threat Detection. + +- **Asset Inventory and Classification:** Cloud SCC offers comprehensive asset discovery and classification across GCP, giving security teams a detailed inventory of their cloud resources, including their configurations and security states. + +- **Threat Detection and Monitoring:** The platform integrates with GCP’s threat detection tools, such as Google’s Event Threat Detection, which analyzes logs for suspicious activities and potential threats. + +- **Compliance Monitoring:** Cloud SCC helps monitor compliance with various regulatory standards by continuously assessing your GCP resources against best practices and security benchmarks. + +- **Automated Remediation:** Cloud SCC can trigger automated responses to security findings through integrations with Google Cloud Functions or other orchestration tools, helping to mitigate risks quickly. + +- **Native GCP Integration:** Cloud SCC is deeply integrated with the GCP ecosystem, offering seamless operation within Google Cloud environments and leveraging Google's extensive security expertise. + +## Limitations + +- **GCP-Centric:** While Cloud SCC is powerful within the GCP ecosystem, it is primarily focused on GCP and does not natively extend to multi-cloud environments without additional tools or connectors. + +- **Cost Considerations:** As a managed service within GCP, costs can scale with the amount of data ingested and the complexity of the environment, especially as additional features or higher volumes of data are utilized. + +- **Dependency on GCP Services:** Cloud SCC's capabilities depend on other GCP services being enabled, such as Security Health Analytics and Web Security Scanner, which may increase overall complexity and cost. + +## Prowler + +Prowler is an open-source, multi-cloud security tool designed to perform detailed security assessments and compliance checks across diverse cloud environments, including AWS, Azure, GCP, and Kubernetes. Here are the key advantages of Prowler when compared to GCP Cloud SCC: + +## Main Advantages of Prowler + +- **Multi-Region and Multi-Account Scanning by Default:** + - Prowler inherently supports multi-region and multi-account scanning across multiple cloud providers, including GCP, AWS, Azure, and Kubernetes. It does not require additional configuration to perform these scans, making it immediately useful for organizations operating in multiple cloud environments. + +- **Minimal Setup Requirements:** + - Prowler requires only appropriate roles and permissions to start scanning. It doesn’t necessitate enabling specific services within GCP, which can simplify the setup process and reduce dependencies. + +- **Versatile Execution Environment:** + - Prowler can be run from various environments, such as a local workstation, container, Google Cloud Shell, or even other cloud providers by assuming a role. This versatility allows for flexible deployment and integration into existing security operations. + +- **Flexible Results Storage and Sharing:** + - Prowler results can be stored in an S3 bucket for AWS, Google Cloud Storage (GCS) for GCP, or locally, allowing for quick analysis and easy sharing. This flexibility is particularly advantageous for multi-cloud security assessments and collaborative security processes. + +- **Customizable Reporting and Analysis:** + - Prowler supports exporting results in multiple formats, including JSON, CSV, OCSF format, and static HTML reports. These reports can be tailored to specific needs and easily integrated with other security tools or dashboards, providing comprehensive insights across all cloud environments. + +- **SIEM Integration and Cost Efficiency:** + - Prowler can be configured to send findings directly into SIEM systems, including those integrated with GCP or other platforms. By sending only failed findings or selected results, Prowler helps manage costs associated with data ingestion and analysis in SIEM platforms. + +- **Custom Checks and Compliance Frameworks:** + - Prowler allows for the creation of custom security checks, remediation actions, and compliance frameworks, providing flexibility that can be adapted to the unique security policies and regulatory requirements of an organization. + +- **Extensive Compliance Support:** + - Prowler supports over 27 compliance frameworks out of the box, with capabilities to extend these frameworks to GCP environments as well as other cloud platforms. This broad compliance coverage ensures that organizations can maintain adherence to various regulatory requirements. + +- **Kubernetes and Multi-Cloud Support:** + - Prowler is designed to support security assessments across cloud environments, including Kubernetes clusters and GCP. This multi-cloud capability is essential for organizations that operate across diverse cloud platforms and require consistent security posture management. + +- **All-Region Checks:** + - Prowler runs all checks in all regions by default, ensuring comprehensive coverage across an organization’s cloud resources, regardless of the region or cloud provider. + +## Comparison Summary + +### Scope and Environment + +- **GCP Cloud SCC** is ideal for organizations primarily using GCP, offering a centralized platform for managing security and compliance within the GCP ecosystem. +- **Prowler** excels in multi-cloud environments, offering flexibility and comprehensive security checks across AWS, Azure, GCP, and Kubernetes without being confined to a single cloud provider. + +### Setup and Flexibility + +- **GCP Cloud SCC** requires enabling various GCP services and may involve more complex setup, especially for multi-region or multi-account scenarios within GCP. +- **Prowler** requires minimal setup and can be deployed quickly across different cloud environments, offering a more straightforward approach to multi-cloud security management. + +### Customization and Compliance + +- **GCP Cloud SCC** provides predefined compliance checks within the GCP environment but may require additional tools or customization for broader or more specific requirements. +- **Prowler** allows for extensive customization of security checks, compliance frameworks, and reporting, providing a flexible solution that can be tailored to an organization’s specific needs across various cloud platforms. + +### Cost Efficiency + +- **GCP Cloud SCC** costs can scale with the volume of data processed and the number of enabled services, which may be significant in large or complex environments. SCC pricing is confusing to understand, and starts at $0.071 per vCPU hour for some tiers and depending on the scan service. Take a look at the pricing model [here](https://cloud.google.com/security-command-center/pricing), godspeed. +- **Prowler** helps manage costs by allowing selective reporting, such as sending only failed findings to SIEMs, and storing results in cost-effective ways, such as local storage or cloud buckets. Prowler is always $0.001 per resource per day - no per account charge. + +### Multi-Cloud and Multi-Region Support + +- **GCP Cloud SCC** is focused on GCP and may require additional tools for comprehensive multi-cloud support. +- **Prowler** is inherently multi-cloud, supporting AWS, Azure, GCP, and Kubernetes out of the box, making it an ideal choice for organizations with diverse cloud footprints. + +## Conclusion + +For a CISO evaluating these tools, the decision between GCP Cloud Security Command Center (Cloud SCC) and Prowler hinges on the organization’s cloud strategy, security management needs, and the level of flexibility and multi-cloud support required: + +- If the organization is heavily invested in GCP and needs a centralized platform that integrates seamlessly with GCP services for asset management, threat detection, and compliance monitoring, **GCP Cloud SCC** is likely the better choice. +- If the organization operates in a multi-cloud environment or requires a highly customizable tool for performing detailed security assessments across AWS, Azure, GCP, and Kubernetes, **Prowler** offers a more flexible and cost-effective solution, especially for those needing quick deployment, minimal setup, and the ability to manage security across diverse cloud environments. diff --git a/docs/getting-started/comparison/index.mdx b/docs/getting-started/comparison/index.mdx new file mode 100644 index 0000000000..9cbc494d42 --- /dev/null +++ b/docs/getting-started/comparison/index.mdx @@ -0,0 +1,10 @@ +--- +title: 'Comparison' +--- + +Click to learn more about each cloud security provider and learn how Prowler is differentiated. + +- [AWS Security Hub](/getting-started/comparison/awssecurityhub) +- [Microsoft Sentinel](/getting-started/comparison/microsoftsentinel) +- [Microsoft Defender](/getting-started/comparison/microsoftdefender) +- [Google Cloud Security Command Center](/getting-started/comparison/gcp) diff --git a/docs/getting-started/comparison/microsoftdefender.mdx b/docs/getting-started/comparison/microsoftdefender.mdx new file mode 100644 index 0000000000..76b61ba9a6 --- /dev/null +++ b/docs/getting-started/comparison/microsoftdefender.mdx @@ -0,0 +1,101 @@ +--- +title: 'Microsoft Defender for Cloud' +--- + +**Use open-source scanning to validate and extend Microsoft Defender for Cloud** + +--- + +## **Overview** + +If you're using Microsoft Defender for Cloud to monitor your Azure infrastructure, Prowler can complement it with fully transparent, customizable scans across Azure, AWS, GCP, and Kubernetes. Prowler helps you validate policies, automate compliance, and gain deeper visibility—all from the CLI, API or our Prowler UI. + +You can run Prowler alongside Defender for Cloud to: + +* Double-check security posture with open-source checks. +* Customize rules for your organization’s policies. +* Bring your own, or community contributed policies. +* Automate multi-cloud scans in CI/CD or scheduled jobs. + +--- + +## **Why use Prowler with Defender for Cloud** + +Microsoft Defender for Cloud offers centralized dashboards, alerting, and some cross-cloud coverage. Prowler provides full transparency and control over what’s being checked and how those checks work—no vendor lock-in, no surprises. + +Use them together to get: + +* More confidence in your security posture +* Checks you can inspect, modify, and version +* CLI-first, portable scanning across clouds +* Open-source tooling that integrates easily into pipelines and audits + +--- + +## **Quickstart** + +Here’s how to install Prowler and run a scan in your Azure account. + +### **1\. Install Prowler** + +``` +git clone https://github.com/prowler-cloud/prowler +cd prowler +./install.sh +``` + +### **2\. Authenticate with Azure** + +Make sure you're signed in and select your subscription: + +``` +az login +export AZURE_SUBSCRIPTION_ID=$(az account show --query id -o tsv) +``` + +### **3\. Run a scan** + +``` +./prowler -p Azure -f az-aks -f az-general +``` + +This will run checks focused on Azure Kubernetes Service (AKS) and general Azure best practices. + +### **4\. Review results** + +``` +cat output/prowler-output-*.json +open output/prowler-output-*.html +``` + +You can export findings in JSON, CSV, JUnit, HTML, or AWS Security Hub–compatible formats. + +--- + +## **Compare capabilities** + +| Feature | Microsoft Defender for Cloud | Prowler | +| ----- | ----- | ----- | +| Azure-native posture management | āœ… | āœ… | +| AWS, GCP, and Kubernetes support | āš ļø (limited) | āœ… | +| Custom policy creation | āŒ | āœ… | +| CLI-first, scriptable | āŒ | āœ… | +| Open source | āŒ | āœ… | +| Compliance mappings (CIS, NIST, etc.) | āœ… (limited control) | āœ… (customizable) | +| Exportable detections | āŒ | āœ… | + +--- + +## **Common use cases** + +**āœ… Validate policies** + Run Prowler to confirm your Azure policies are configured as expected and compliant with frameworks like CIS or NIST. + +**āœ… Automate compliance scans** + Schedule regular Prowler scans in your CI/CD pipeline or infrastructure monitoring workflows. Generate reports for auditors or internal reviews. + +**āœ… Extend detection coverage** + If Defender for Cloud doesn’t cover all the services or resources in your environment, Prowler’s checks fill in the gaps. + +**āœ… Build custom checks** + Security is never one-size-fits-all. Prowler lets you write your own checks for organization-specific policies. diff --git a/docs/getting-started/comparison/microsoftsentinel.mdx b/docs/getting-started/comparison/microsoftsentinel.mdx new file mode 100644 index 0000000000..a6ff00dbfc --- /dev/null +++ b/docs/getting-started/comparison/microsoftsentinel.mdx @@ -0,0 +1,93 @@ +--- +title: 'Microsoft Sentinel' +--- + +Microsoft Sentinel is a scalable, cloud-native security information and event management (SIEM) and security orchestration automated response (SOAR) solution. It's designed to collect, detect, investigate, and respond to threats across the enterprise, primarily within the Azure cloud environment but also extending to on-premises and other cloud environments through various connectors. + +## Key Features and Strengths + +- **SIEM and SOAR Capabilities:** Microsoft Sentinel combines SIEM and SOAR functionalities, allowing it to collect and analyze large volumes of data from various sources and automate responses to detected threats. + +- **Native Azure Integration:** As part of the Azure ecosystem, Sentinel integrates seamlessly with Azure services, providing deep visibility and analytics for Azure resources. + +- **Advanced Threat Detection:** Sentinel uses AI and machine learning to detect potential threats and anomalous activities, leveraging Microsoft's extensive threat intelligence network. + +- **Scalability and Flexibility:** Being cloud-native, Sentinel scales automatically to handle increasing data volumes and complexity without requiring extensive infrastructure management. + +- **Customizable Dashboards and Analytics:** Sentinel offers customizable dashboards and analytics, allowing security teams to tailor their views and queries to specific needs. + +- **Multi-Source Data Ingestion:** While focused on Azure, Sentinel can ingest data from multiple sources, including AWS, GCP, on-premises environments, and third-party security products. + +## Limitations + +- **Azure-Centric:** While it supports multi-cloud environments, its primary focus and strengths are within the Azure ecosystem. Integration with other cloud platforms and on-premises environments may require additional connectors and configurations. + +- **Cost Considerations:** As a SIEM tool, Sentinel can become expensive, particularly as data ingestion and analysis volumes grow. The cost model is based on data volume, which can add up quickly in large environments. + +- **Complexity in Customization:** Although Sentinel offers advanced customization, setting up and fine-tuning these customizations can require significant expertise and effort, particularly in multi-cloud environments. + +## Prowler + +Prowler is an open-source, multi-cloud security tool that offers extensive flexibility and customization, making it ideal for organizations that need to maintain a strong security posture across diverse cloud environments. Here are the key advantages of Prowler, particularly when compared to Microsoft Sentinel: + +## Main Advantages of Prowler + +- **Multi-Region and Multi-Account Scanning by Default:** + - Prowler is inherently multi-region and multi-account, requiring no additional configuration to scan across these environments. This capability is available out of the box without needing to enable specific services or create complex setups. + +- **Minimal Setup Requirements:** + - Prowler requires only a role with appropriate permissions to begin scanning. There’s no need for extensive setup, making it easier and quicker to deploy across various environments. + +- **Versatile Execution Environment:** + - Prowler can be run from a local workstation, container, AWS CloudShell, or even from other cloud providers like Azure or GCP by assuming a role. This versatility allows security teams to integrate Prowler into a wide range of operational workflows without being tied to a single cloud environment. + +- **Flexible Results Storage and Sharing:** + - Prowler results can be stored directly into an S3 bucket, allowing for quick analysis or locally for easy sharing and collaboration. This flexibility is particularly useful for multi-cloud security assessments and incident response. + +- **Customizable Reporting and Analysis:** + - Prowler supports exporting results in multiple formats, including JSON, CSV, OCSF format, and static HTML reports. Additionally, it can integrate with Amazon QuickSight for advanced analytics, and offers a SaaS model with resource-based pricing, making it adaptable to various organizational needs. + +- **SIEM Integration and Cost Efficiency:** + - While Microsoft Sentinel has a built-in SIEM functionality, Prowler can send results directly into SIEM systems, including Microsoft Sentinel. By sending only failed findings, Prowler can help optimize costs associated with data ingestion and storage in SIEM platforms. + +- **Custom Checks and Compliance Frameworks:** + - Prowler enables users to write custom checks, remediations, and compliance frameworks quickly, allowing organizations to adapt the tool to their specific security policies and regulatory requirements. + +- **Extensive Compliance Support:** + - Prowler supports over 27 compliance frameworks out of the box, providing comprehensive coverage for AWS environments, which can be extended to multi-cloud scenarios. + +- **Kubernetes and Multi-Cloud Support:** + - Prowler is designed to support security assessments beyond AWS, including Kubernetes clusters (including EKS) and environments in Azure and GCP. This capability is critical for organizations that operate across multiple cloud platforms and require consistent security posture management. + +- **All-Region Checks:** + - Prowler runs all checks in all regions by default, ensuring comprehensive coverage without the limitations that may be imposed by region-specific configurations or services. + +## Comparison Summary + +### Scope and Environment +- **Microsoft Sentinel** is an advanced SIEM/SOAR tool optimized for Azure environments, with support for multi-cloud and on-premises systems through connectors. +- **Prowler** is a flexible, multi-cloud security tool that excels in environments where organizations need to manage security across AWS, Azure, GCP, and Kubernetes with minimal setup and high customizability. + +### Setup and Flexibility +- **Microsoft Sentinel** requires more setup, especially when integrating with non-Azure environments, and its cost scales with data ingestion. +- **Prowler** requires minimal setup and can be easily deployed in any cloud or on-premises environment. Its ability to run from various environments and store results in flexible formats makes it particularly adaptable. + +### Customization and Compliance +- **Microsoft Sentinel** offers powerful but complex customization options, primarily within the Azure ecosystem. +- **Prowler** provides straightforward customization of security checks, remediation actions, and compliance frameworks, with broad support for multiple compliance standards out of the box. + +### Cost Efficiency +- **Microsoft Sentinel** can become costly as data volumes grow, particularly in large or multi-cloud environments. +- **Prowler** helps control costs by enabling selective reporting (e.g., sending only failed findings to SIEMs like Sentinel) and storing results in cost-effective ways, such as S3 or locally. + +### Multi-Cloud and Multi-Region Support +- **Microsoft Sentinel** supports multi-cloud environments but may require additional configuration and connectors. +- **Prowler** is designed for multi-cloud environments from the ground up, with inherent support for AWS, Azure, GCP, Kubernetes, and all regions, making it an ideal tool for organizations with diverse cloud footprints. + +## Conclusion + +For a CISO or security professional evaluating these tools, the decision between Microsoft Sentinel and Prowler hinges on the organization's cloud strategy, SIEM needs, and the level of customization and flexibility required: + +- If the organization is heavily invested in Azure and needs an integrated SIEM/SOAR solution with advanced threat detection, analytics, and automation capabilities, **Microsoft Sentinel** is likely the better choice. + +- If the organization operates in a multi-cloud environment or requires a highly customizable tool for performing detailed security assessments across AWS, Azure, GCP, and Kubernetes, **Prowler** offers a more flexible and cost-effective solution, especially for those needing quick deployment, minimal setup, and the ability to manage security across diverse cloud environments. diff --git a/docs/getting-started/goto/prowler-api-reference.mdx b/docs/getting-started/goto/prowler-api-reference.mdx new file mode 100644 index 0000000000..f8ca1dc3da --- /dev/null +++ b/docs/getting-started/goto/prowler-api-reference.mdx @@ -0,0 +1,4 @@ +--- +title: "Prowler API Reference" +url: "https://api.prowler.com/api/v1/docs" +--- diff --git a/docs/getting-started/goto/prowler-cloud.mdx b/docs/getting-started/goto/prowler-cloud.mdx new file mode 100644 index 0000000000..964c34ddab --- /dev/null +++ b/docs/getting-started/goto/prowler-cloud.mdx @@ -0,0 +1,4 @@ +--- +title: "Go to Cloud" +url: "https://cloud.prowler.com" +--- diff --git a/docs/getting-started/goto/prowler-hub.mdx b/docs/getting-started/goto/prowler-hub.mdx new file mode 100644 index 0000000000..b9862b582d --- /dev/null +++ b/docs/getting-started/goto/prowler-hub.mdx @@ -0,0 +1,4 @@ +--- +title: "Go to Hub" +url: "https://hub.prowler.com" +--- diff --git a/docs/getting-started/goto/prowler-mcp.mdx b/docs/getting-started/goto/prowler-mcp.mdx new file mode 100644 index 0000000000..5706ca1396 --- /dev/null +++ b/docs/getting-started/goto/prowler-mcp.mdx @@ -0,0 +1,5 @@ +--- +title: "Prowler MCP" +url: "https://github.com/prowler-cloud/prowler/tree/master/mcp_server" +tag: "new!" +--- diff --git a/docs/installation/prowler-app.md b/docs/getting-started/installation/prowler-app.mdx similarity index 58% rename from docs/installation/prowler-app.md rename to docs/getting-started/installation/prowler-app.mdx index d8b03427cf..f404180791 100644 --- a/docs/installation/prowler-app.md +++ b/docs/getting-started/installation/prowler-app.mdx @@ -1,51 +1,48 @@ +--- +title: "Installation" +--- + ### Installation Prowler App supports multiple installation methods based on your environment. -Refer to the [Prowler App Tutorial](../tutorials/prowler-app.md) for detailed usage instructions. +Refer to the [Prowler App Tutorial](/user-guide/tutorials/prowler-app) for detailed usage instructions. -=== "Docker Compose" + + Prowler configuration is based in `.env` files. Every version of Prowler can have differences on that file, so, please, use the file that corresponds with that version or repository branch or tag. + + + _Requirements_: - * `Docker Compose` installed: https://docs.docker.com/compose/install/. + - `Docker Compose` installed: https://docs.docker.com/compose/install/. _Commands_: - ``` bash - curl -LO https://raw.githubusercontent.com/prowler-cloud/prowler/refs/heads/master/docker-compose.yml - curl -LO https://raw.githubusercontent.com/prowler-cloud/prowler/refs/heads/master/.env + ```bash + VERSION=$(curl -s https://api.github.com/repos/prowler-cloud/prowler/releases/latest | jq -r .tag_name) + curl -sLO "https://raw.githubusercontent.com/prowler-cloud/prowler/refs/tags/${VERSION}/docker-compose.yml" + curl -sLO "https://raw.githubusercontent.com/prowler-cloud/prowler/refs/tags/${VERSION}/.env" docker compose up -d ``` > Containers are built for `linux/amd64`. If your workstation's architecture is different, please set `DOCKER_DEFAULT_PLATFORM=linux/amd64` in your environment or use the `--platform linux/amd64` flag in the docker command. - - > Enjoy Prowler App at http://localhost:3000 by signing up with your email and password. - - ???+ note - You can change the environment variables in the `.env` file. Note that it is not recommended to use the default values in production environments. - - ???+ note - There is a development mode available, you can use the file https://github.com/prowler-cloud/prowler/blob/master/docker-compose-dev.yml to run the app in development mode. - - ???+ warning - Google and GitHub authentication is only available in [Prowler Cloud](https://prowler.com). - -=== "GitHub" - + + _Requirements_: - * `git` installed. - * `poetry` installed: [poetry installation](https://python-poetry.org/docs/#installation). - * `npm` installed: [npm installation](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm). - * `Docker Compose` installed: https://docs.docker.com/compose/install/. - - ???+ warning - Make sure to have `api/.env` and `ui/.env.local` files with the required environment variables. You can find the required environment variables in the [`api/.env.template`](https://github.com/prowler-cloud/prowler/blob/master/api/.env.example) and [`ui/.env.template`](https://github.com/prowler-cloud/prowler/blob/master/ui/.env.template) files. + - `git` installed. + - `poetry` installed: [poetry installation](https://python-poetry.org/docs/#installation). + - `npm` installed: [npm installation](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm). + - `Docker Compose` installed: https://docs.docker.com/compose/install/. + + Make sure to have `api/.env` and `ui/.env.local` files with the required environment variables. You can find the required environment variables in the [`api/.env.template`](https://github.com/prowler-cloud/prowler/blob/master/api/.env.example) and [`ui/.env.template`](https://github.com/prowler-cloud/prowler/blob/master/ui/.env.template) files. + _Commands to run the API_: - ``` bash + ```bash git clone https://github.com/prowler-cloud/prowler \ cd prowler/api \ poetry install \ @@ -58,17 +55,16 @@ Refer to the [Prowler App Tutorial](../tutorials/prowler-app.md) for detailed us gunicorn -c config/guniconf.py config.wsgi:application ``` - ???+ important - Starting from Poetry v2.0.0, `poetry shell` has been deprecated in favor of `poetry env activate`. - - If your poetry version is below 2.0.0 you must keep using `poetry shell` to activate your environment. - In case you have any doubts, consult the Poetry environment activation guide: https://python-poetry.org/docs/managing-environments/#activating-the-environment + + Starting from Poetry v2.0.0, `poetry shell` has been deprecated in favor of `poetry env activate`. + If your poetry version is below 2.0.0 you must keep using `poetry shell` to activate your environment. In case you have any doubts, consult the Poetry environment activation guide: https://python-poetry.org/docs/managing-environments/#activating-the-environment + > Now, you can access the API documentation at http://localhost:8080/api/v1/docs. _Commands to run the API Worker_: - ``` bash + ```bash git clone https://github.com/prowler-cloud/prowler \ cd prowler/api \ poetry install \ @@ -81,7 +77,7 @@ Refer to the [Prowler App Tutorial](../tutorials/prowler-app.md) for detailed us _Commands to run the API Scheduler_: - ``` bash + ```bash git clone https://github.com/prowler-cloud/prowler \ cd prowler/api \ poetry install \ @@ -94,7 +90,7 @@ Refer to the [Prowler App Tutorial](../tutorials/prowler-app.md) for detailed us _Commands to run the UI_: - ``` bash + ```bash git clone https://github.com/prowler-cloud/prowler \ cd prowler/ui \ npm install \ @@ -104,9 +100,11 @@ Refer to the [Prowler App Tutorial](../tutorials/prowler-app.md) for detailed us > Enjoy Prowler App at http://localhost:3000 by signing up with your email and password. - ???+ warning - Google and GitHub authentication is only available in [Prowler Cloud](https://prowler.com). - + + Google and GitHub authentication is only available in [Prowler Cloud](https://prowler.com). + + + ### Update Prowler App @@ -129,9 +127,11 @@ docker compose pull --policy always The `--policy always` flag ensures that Docker pulls the latest images even if they already exist locally. + + **What Gets Preserved During Upgrade** -???+ note "What Gets Preserved During Upgrade" - Everything is preserved, nothing will be deleted after the update. + Everything is preserved, nothing will be deleted after the update. + ### Troubleshooting @@ -152,7 +152,6 @@ docker compose pull docker compose up -d ``` - ### Container versions The available versions of Prowler CLI are the following: @@ -168,6 +167,5 @@ The available versions of Prowler CLI are the following: The container images are available here: - Prowler App: - - - [DockerHub - Prowler UI](https://hub.docker.com/r/prowlercloud/prowler-ui/tags) - - [DockerHub - Prowler API](https://hub.docker.com/r/prowlercloud/prowler-api/tags) + - [DockerHub - Prowler UI](https://hub.docker.com/r/prowlercloud/prowler-ui/tags) + - [DockerHub - Prowler API](https://hub.docker.com/r/prowlercloud/prowler-api/tags) diff --git a/docs/installation/prowler-cli.md b/docs/getting-started/installation/prowler-cli.mdx similarity index 83% rename from docs/installation/prowler-cli.md rename to docs/getting-started/installation/prowler-cli.mdx index 663b6bebaf..a3c87c8ce7 100644 --- a/docs/installation/prowler-cli.md +++ b/docs/getting-started/installation/prowler-cli.mdx @@ -1,10 +1,13 @@ +--- +title: 'Installation' +--- ## Installation Prowler is available as a project in [PyPI](https://pypi.org/project/prowler/). Install it as a Python package with `Python >= 3.9, <= 3.12`: -=== "pipx" - + + [pipx](https://pipx.pypa.io/stable/) installs Python applications in isolated environments. Use `pipx` for global installation. _Requirements_: @@ -19,17 +22,11 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler/). pipx install prowler prowler -v ``` - - Upgrade Prowler to the latest version: - - ``` bash - pipx upgrade prowler - ``` - -=== "pip" - - ???+ warning - This method modifies the chosen installation environment. Consider using [pipx](https://docs.prowler.com/projects/prowler-open-source/en/latest/#__tabbed_1_1) for global installation. + + + + This method modifies the chosen installation environment. Consider using [pipx](https://docs.prowler.com/projects/prowler-open-source/en/latest/#__tabbed_1_1) for global installation. + _Requirements_: @@ -49,9 +46,8 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler/). ``` bash pip install --upgrade prowler ``` - -=== "Docker" - + + _Requirements_: * Have `docker` installed: https://docs.docker.com/get-docker/. @@ -69,9 +65,8 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler/). --env AWS_SECRET_ACCESS_KEY \ --env AWS_SESSION_TOKEN toniblyx/prowler:latest ``` - -=== "GitHub" - + + _Requirements for Developers_: * `git` @@ -86,11 +81,12 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler/). poetry install poetry run python prowler-cli.py -v ``` - ???+ note - If you want to clone Prowler from Windows, use `git config core.longpaths true` to allow long file paths. - -=== "Amazon Linux 2" + + If you want to clone Prowler from Windows, use `git config core.longpaths true` to allow long file paths. + + + _Requirements_: * `Python >= 3.9, <= 3.12` @@ -104,9 +100,8 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler/). pipx install prowler prowler -v ``` - -=== "Ubuntu" - + + _Requirements_: * `Ubuntu 23.04` or above, if you are using an older version of Ubuntu check [pipx installation](https://docs.prowler.com/projects/prowler-open-source/en/latest/#__tabbed_1_1) and ensure you have `Python >= 3.9, <= 3.12`. @@ -122,9 +117,8 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler/). pipx install prowler prowler -v ``` - -=== "Brew" - + + _Requirements_: * `Brew` installed in your Mac or Linux @@ -136,9 +130,8 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler/). brew install prowler prowler -v ``` - -=== "AWS CloudShell" - + + After the migration of AWS CloudShell from Amazon Linux 2 to Amazon Linux 2023 [[1]](https://aws.amazon.com/about-aws/whats-new/2023/12/aws-cloudshell-migrated-al2023/) [[2]](https://docs.aws.amazon.com/cloudshell/latest/userguide/cloudshell-AL2023-migration.html), there is no longer a need to manually compile Python 3.9 as it is already included in AL2023. Prowler can thus be easily installed following the generic method of installation via pip. Follow the steps below to successfully execute Prowler v4 in AWS CloudShell: _Requirements_: @@ -158,11 +151,11 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler/). prowler aws ``` - ???+ note - To download the results from AWS CloudShell, select Actions -> Download File and add the full path of each file. For the CSV file it will be something like `/tmp/output/prowler-output-123456789012-20221220191331.csv` - -=== "Azure CloudShell" - + + To download the results from AWS CloudShell, select Actions -> Download File and add the full path of each file. For the CSV file it will be something like `/tmp/output/prowler-output-123456789012-20221220191331.csv` + + + _Requirements_: * Open Azure CloudShell `bash`. @@ -176,18 +169,8 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler/). cd /tmp prowler azure --az-cli-auth ``` - - - - - - - - - - - - + + ## Container versions The available versions of Prowler CLI are the following: 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/products/img/dashboard.png b/docs/getting-started/products/img/dashboard.png similarity index 100% rename from docs/products/img/dashboard.png rename to docs/getting-started/products/img/dashboard.png diff --git a/docs/products/img/overview.png b/docs/getting-started/products/img/overview.png similarity index 100% rename from docs/products/img/overview.png rename to docs/getting-started/products/img/overview.png diff --git a/docs/products/img/prowler-app-architecture.png b/docs/getting-started/products/img/prowler-app-architecture.png similarity index 100% rename from docs/products/img/prowler-app-architecture.png rename to docs/getting-started/products/img/prowler-app-architecture.png diff --git a/docs/products/prowler-app.md b/docs/getting-started/products/prowler-app.mdx similarity index 84% rename from docs/products/prowler-app.md rename to docs/getting-started/products/prowler-app.mdx index fb2eb1686b..f21e0222cd 100644 --- a/docs/products/prowler-app.md +++ b/docs/getting-started/products/prowler-app.mdx @@ -1,9 +1,13 @@ +--- +title: 'Overview' +--- + Prowler App is a web application that simplifies running Prowler. It provides: - **User-friendly interface** for configuring and executing scans - Dashboard to **view results** and manage **security findings** -![Prowler App](img/overview.png) +![Prowler App](/images/products/overview.png) ## Components @@ -19,4 +23,4 @@ Supporting infrastructure includes: - **Celery Workers**: Asynchronous execution of Prowler scans - **Valkey**: In-memory database serving as message broker for Celery workers -![Prowler App Architecture](img/prowler-app-architecture.png) +![Prowler App Architecture](/images/products/prowler-app-architecture.png) diff --git a/docs/products/prowler-cli.md b/docs/getting-started/products/prowler-cli.mdx similarity index 90% rename from docs/products/prowler-cli.md rename to docs/getting-started/products/prowler-cli.mdx index 633827b01e..ac4f37c291 100644 --- a/docs/products/prowler-cli.md +++ b/docs/getting-started/products/prowler-cli.mdx @@ -1,16 +1,20 @@ +--- +title: 'Overview' +--- + Prowler CLI is a command-line interface for running Prowler scans from the terminal. ```console prowler ``` -![Prowler CLI Execution](../img/short-display.png) +![Prowler CLI Execution](/images/short-display.png) ## Prowler Dashboard ```console prowler dashboard ``` -![Prowler Dashboard](img/dashboard.png) +![Prowler Dashboard](/images/products/dashboard.png) Prowler includes hundreds of security controls aligned with widely recognized industry frameworks and standards, including: diff --git a/docs/getting-started/products/prowler-cloud-aws-marketplace.mdx b/docs/getting-started/products/prowler-cloud-aws-marketplace.mdx new file mode 100644 index 0000000000..5e4c7036c7 --- /dev/null +++ b/docs/getting-started/products/prowler-cloud-aws-marketplace.mdx @@ -0,0 +1,82 @@ +--- +title: "AWS Marketplace" +--- + +This section contains the instructions to subscribe to **Prowler Cloud** through the **AWS Marketplace**. + +## How to subscribe + +To get to the **Prowler Cloud** product listing in the AWS Marketplace, and click the `View purchase options` button: + +1. Use this link to be taken directly to the [Prowler Cloud Marketplace Listing](https://aws.amazon.com/marketplace/pp/prodview-6ochhig5kxpok): + + ![](/images/aws-marketplace/marketplace-listing.png) + +2. Then, scroll down to the "Purchase Details" section and click the `Subscribe` button: + + ![](/images/aws-marketplace/marketplace-subscribe.png) + +## Set up your account + +After you have subscribed to the **Prowler Cloud** product, you will need to set up your **Prowler Cloud** account: + +1. Click the `Set up your account` button: + + ![](/images/aws-marketplace/marketplace-message.png) + +2. You will be redirected to **Prowler Cloud Sign In** page. You can sign in with an exsiting account or sign up with a new account.: + + ![](/images/aws-marketplace/marketplace-sign-up.png) + +3. Once you have successfully authenticated, you should be automatically redirected to the **Prowler Cloud** [Billing](https://cloud.prowler.com/billing) page where you should now see that your account has the `AWS Marketplace Subscription` badge. + + ![](/images/aws-marketplace/marketplace-my-account.png) + +If you have any issues signing up, please contact us at support@prowler.com. + + +## Billing + +You will be charged monthly based on resources scanned and monitored depending on usage in **Prowler Cloud**. For more information on billing, please see the [Prowler Cloud Pricing FAQ](https://prowler.com/pricing/). + +**Note:** Your **Prowler Cloud** bills can be seen at [AWS Billing](https://us-east-1.console.aws.amazon.com/billing/home#/bills). + +## Subscription + +If you subscribe to Prowler Cloud through the AWS Marketplace it is not necessary to subscribe from different AWS accounts to use Prowler Cloud for those accounts. + +In Prowler Cloud you only need to subscribe from one of your AWS accounts through the AWS Marketplace and add multiple provider accounts once you are in the Prowler Cloud console. We will send usage metrics to the AWS Marketplace regardless of the number of accounts you add in our platform, so the AWS Marketplace will bill you based on those usage metrics. + +## Troubleshooting + +### SEPA Payment Method Issues + +If AWS Marketplace notifies that payment failed due to an issue with the payment method, this typically occurs when a SEPA bank account is set as the default payment method. AWS Marketplace does not support SEPA bank accounts for product subscriptions, even when the account includes valid alternative payment methods. This is because AWS Marketplace invoices are issued by AWS Inc., a US entity. SEPA accounts do not recognize these invoices as valid, causing subscription failures. + +To successfully subscribe to AWS Marketplace products with a SEPA account configuration: + +1. Switch default payment method to credit card +2. Complete subscription +3. Switch the default payment method back to the bank account + + +**Renewal Considerations** + +This issue will recur during subscription renewals. AWS service teams recommend maintaining credit card as the default payment method to prevent future disruptions. Update payment methods at https://console.aws.amazon.com/billing/home#/paymentmethods. + + + + +**AWS Marketplace Statement** + +The AWS Marketplace team acknowledges this limitation: "We apologize for these additional steps, and please know we are fully aware of this situation, and our internal teams are working on simplifying this process." + + + +### Credit and Debit Card Storage Restrictions (AISPL Customers in India) + +AWS Marketplace no longer supports payments using credit or debit cards stored on file for Amazon Internet Services Private Limited (AISPL) customers. This restriction stems from Reserve Bank of India (RBI) regulations regarding payment aggregators, which prohibit the storage of card data. As explained in [this AWS blog post](https://aws.amazon.com/blogs/awsmarketplace/restriction-on-credit-and-debit-card-purchases-for-aispl-customers-using-aws-marketplace/): + +> AWS Marketplace can no longer support payments using credit or debit cards stored on file. [The Reserve Bank of India (RBI) has issued a notice regarding regulation of payment aggregators](https://www.rbi.org.in/Scripts/NotificationUser.aspx?Id=11822&Mode=0), which restricts the storage of card data. If you are currently using credit or debit card as your default payment instrument, your ability to use AWS Marketplace products will be restricted. However, you can switch your default payment instrument to Pay By Invoice to avoid disruption or restore your original experience. + +To maintain uninterrupted access to AWS Marketplace products, change the default payment instrument from stored card data to Pay By Invoice billing. diff --git a/docs/getting-started/products/prowler-cloud-pricing.mdx b/docs/getting-started/products/prowler-cloud-pricing.mdx new file mode 100644 index 0000000000..fc7d2104df --- /dev/null +++ b/docs/getting-started/products/prowler-cloud-pricing.mdx @@ -0,0 +1,4 @@ +--- +title: "Pricing" +url: "https://prowler.com/pricing" +--- diff --git a/docs/getting-started/products/prowler-cloud.mdx b/docs/getting-started/products/prowler-cloud.mdx new file mode 100644 index 0000000000..b8b3431a89 --- /dev/null +++ b/docs/getting-started/products/prowler-cloud.mdx @@ -0,0 +1,24 @@ +--- +title: "Overview" +--- + +[Prowler Cloud](https://prowler.com) makes Cloud Security easy and enables your team to build trust in their deployed services and applications. + +Prowler Cloud Automates scanning single or multiple accounts and has all of the benefits of Prowler Open Source, plus hands-off continuous monitoring, auto-scaling workers for faster execution, integrations, personalized support options and out of the box social authentication. + +![](/images/products/overview.png) + + + +With 100% consistency across our open source policies and APIs. Prowler Cloud provides the following added benefits: + +
    +
  • Immediate sign-up and account provisioning, including a trial period with zero billing details needed at registration.
  • +
  • Simple, transparent pricing, with cloud account sizing and exact pricing being available to view in your account settings.
  • +
  • SOC2 Security processes around the deployment, management, data protection and security updates of your prowler environment.
  • +
  • Helpers for smooth onboarding of cloud environments (Eg. Automatic account ID and ExternalID for AWS assumed roles, Known Static IP for Kubernetes access).
  • +
  • Zero touch third party notifications to Slack, Jira, and more.
  • +
+ +The team who built [Prowler](https://github.com/prowler-cloud/prowler), has helped thousands of companies get Cloud Security under control, is now making it easier by taking +[Prowler](https://github.com/prowler-cloud/prowler) to the [Cloud](https://prowler.com)! diff --git a/docs/getting-started/products/prowler-hub.mdx b/docs/getting-started/products/prowler-hub.mdx new file mode 100644 index 0000000000..a8dde7549f --- /dev/null +++ b/docs/getting-started/products/prowler-hub.mdx @@ -0,0 +1,17 @@ +--- +title: "Overview" +--- + +**Prowler Hub** is our growing public library of versioned checks, cloud service artifacts, and compliance frameworks with its mappings. It’s searchable, explainable, and built to serve the community. + +**Why this matters**: Every engineer has asked, ā€œWhat does this check actually do?ā€ Prowler Hub answers that question in one place, lets you pin to a specific version, and pulls definitions into your own tools or dashboards. + +![](/images/products/prowler-hub.webp) + + + +Prowler Hub also provides a fully documented public API that you can integrate into your internal tools, dashboards, or automation workflows. + +šŸ“š Explore the API docs at: https://hub.prowler.com/api/docs + +Whether you’re customizing policies, managing compliance, or enhancing visibility, Prowler Hub is built to support your security operations. \ No newline at end of file diff --git a/docs/getting-started/products/prowler-mcp.mdx b/docs/getting-started/products/prowler-mcp.mdx new file mode 100644 index 0000000000..94a5466edb --- /dev/null +++ b/docs/getting-started/products/prowler-mcp.mdx @@ -0,0 +1,187 @@ +--- +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 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. + +## MCP Server Architecture + +The following diagram illustrates the Prowler MCP Server architecture and its integration points: + +Prowler MCP Server Schema +Prowler MCP Server Schema + +The architecture shows how AI assistants connect through the MCP protocol to access Prowler's three main components: Prowler Cloud/App for security operations, Prowler Hub for security knowledge, and Prowler Documentation for guidance and reference. + +## 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?" + +### Example: Creating a custom dashboard with Prowler extracted data + +In the next example you can see how to create a dashboard using Prowler MCP Server and Claude Desktop. + +**Used Prompt:** +``` +Generate me a security dashboard for the Prowler open source project using live data from Prowler MCP tools. + +REQUIREMENTS: +1. Fetch real-time data from Prowler Findings using MCP tools +2. Create a single self-contained HTML file and display it +3. Dashboard must be production-ready with modern design + +DATA TO FETCH: +Use these MCP tools in this order: +1. Prowler app list providers - To get all available configured provider in the account +2. Prowler app get latest findings - To get findings information, if there are so many you can use the filter_fields to get less information, or pagination to get in different batches +3. For most critical findings you can get more context and remediation with Prowler Hub to get remediations for example + +DESIGN REQUIREMENTS: +- Dark theme (gradient background: #0a0e27 to #131830) +- Card-based layout with glassmorphism effects +- Color scheme: +Ā * Primary green +Ā * Secondary purple +- Modern, professional look +- Animated "LIVE DATA" indicator (pulsing green badge) +- Hover effects on all cards (lift, glow, border color change) +- Responsive grid layout +- Mobile-responsive breakpoints at 768px +- Single HTML file with all CSS and JavaScript embedded +- No external dependencies + +SPECIFIC DETAILS TO INCLUDE: +- Show actual counts from the data (don't hardcode numbers) +- Add timestamp showing when dashboard was generated +- Link to GitHub repository:Ā https://github.com/prowler-cloud/prowler + +OUTPUT: +Generate the complete HTML file and display it +``` + +**Video:** + + + +## 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/AAD-permissions.png b/docs/images/AAD-permissions.png new file mode 100644 index 0000000000..f2f37e354d Binary files /dev/null and b/docs/images/AAD-permissions.png differ diff --git a/docs/images/add-account.png b/docs/images/add-account.png new file mode 100644 index 0000000000..35333883b5 Binary files /dev/null and b/docs/images/add-account.png differ diff --git a/docs/images/add-provider.png b/docs/images/add-provider.png new file mode 100644 index 0000000000..4e986e3f1a Binary files /dev/null and b/docs/images/add-provider.png differ diff --git a/docs/images/add-reader-role.gif b/docs/images/add-reader-role.gif new file mode 100644 index 0000000000..4868abb773 Binary files /dev/null and b/docs/images/add-reader-role.gif differ diff --git a/docs/images/add-sub-to-management-group.gif b/docs/images/add-sub-to-management-group.gif new file mode 100644 index 0000000000..d63049d58b Binary files /dev/null and b/docs/images/add-sub-to-management-group.gif differ diff --git a/docs/images/architecture.png b/docs/images/architecture.png new file mode 100644 index 0000000000..aeac3b136a Binary files /dev/null and b/docs/images/architecture.png differ diff --git a/docs/images/aws-credentials.png b/docs/images/aws-credentials.png new file mode 100644 index 0000000000..71098075db Binary files /dev/null and b/docs/images/aws-credentials.png differ diff --git a/docs/images/aws-marketplace/discover-product.png b/docs/images/aws-marketplace/discover-product.png new file mode 100644 index 0000000000..b78f0c6fc4 Binary files /dev/null and b/docs/images/aws-marketplace/discover-product.png differ diff --git a/docs/images/aws-marketplace/marketplace-billing.png b/docs/images/aws-marketplace/marketplace-billing.png new file mode 100644 index 0000000000..f54d232880 Binary files /dev/null and b/docs/images/aws-marketplace/marketplace-billing.png differ diff --git a/docs/images/aws-marketplace/marketplace-listing.png b/docs/images/aws-marketplace/marketplace-listing.png new file mode 100644 index 0000000000..aae03ee438 Binary files /dev/null and b/docs/images/aws-marketplace/marketplace-listing.png differ diff --git a/docs/images/aws-marketplace/marketplace-message.png b/docs/images/aws-marketplace/marketplace-message.png new file mode 100644 index 0000000000..7b4581273c Binary files /dev/null and b/docs/images/aws-marketplace/marketplace-message.png differ diff --git a/docs/images/aws-marketplace/marketplace-my-account.png b/docs/images/aws-marketplace/marketplace-my-account.png new file mode 100644 index 0000000000..85fc08f932 Binary files /dev/null and b/docs/images/aws-marketplace/marketplace-my-account.png differ diff --git a/docs/images/aws-marketplace/marketplace-sign-up.png b/docs/images/aws-marketplace/marketplace-sign-up.png new file mode 100644 index 0000000000..249bbb6c56 Binary files /dev/null and b/docs/images/aws-marketplace/marketplace-sign-up.png differ diff --git a/docs/images/aws-marketplace/marketplace-subscribe.png b/docs/images/aws-marketplace/marketplace-subscribe.png new file mode 100644 index 0000000000..033e7f156d Binary files /dev/null and b/docs/images/aws-marketplace/marketplace-subscribe.png differ diff --git a/docs/images/aws-marketplace/marketplace-unsubscribe-error.png b/docs/images/aws-marketplace/marketplace-unsubscribe-error.png new file mode 100644 index 0000000000..97c81abe71 Binary files /dev/null and b/docs/images/aws-marketplace/marketplace-unsubscribe-error.png differ diff --git a/docs/images/aws-marketplace/my-account.png b/docs/images/aws-marketplace/my-account.png new file mode 100644 index 0000000000..3476a7e5aa Binary files /dev/null and b/docs/images/aws-marketplace/my-account.png differ diff --git a/docs/images/aws-marketplace/subscription-in-use.png b/docs/images/aws-marketplace/subscription-in-use.png new file mode 100644 index 0000000000..7797170f6b Binary files /dev/null and b/docs/images/aws-marketplace/subscription-in-use.png differ diff --git a/docs/images/aws-marketplace/subscription-pending.png b/docs/images/aws-marketplace/subscription-pending.png new file mode 100644 index 0000000000..bb608afd68 Binary files /dev/null and b/docs/images/aws-marketplace/subscription-pending.png differ diff --git a/docs/images/aws-role.png b/docs/images/aws-role.png new file mode 100644 index 0000000000..bd63511fb6 Binary files /dev/null and b/docs/images/aws-role.png differ diff --git a/docs/images/azure-credentials.png b/docs/images/azure-credentials.png new file mode 100644 index 0000000000..2f5448d0b9 Binary files /dev/null and b/docs/images/azure-credentials.png differ diff --git a/docs/tutorials/img/add-cloud-provider.png b/docs/images/cli/add-cloud-provider.png similarity index 100% rename from docs/tutorials/img/add-cloud-provider.png rename to docs/images/cli/add-cloud-provider.png diff --git a/docs/images/cli/api-keys/create.png b/docs/images/cli/api-keys/create.png new file mode 100644 index 0000000000..54218c88f8 Binary files /dev/null and b/docs/images/cli/api-keys/create.png differ diff --git a/docs/images/cli/api-keys/created.png b/docs/images/cli/api-keys/created.png new file mode 100644 index 0000000000..a64b6faa74 Binary files /dev/null and b/docs/images/cli/api-keys/created.png differ diff --git a/docs/images/cli/api-keys/list.png b/docs/images/cli/api-keys/list.png new file mode 100644 index 0000000000..3c6020acfc Binary files /dev/null and b/docs/images/cli/api-keys/list.png differ diff --git a/docs/images/cli/api-keys/management.png b/docs/images/cli/api-keys/management.png new file mode 100644 index 0000000000..85ebab8d02 Binary files /dev/null and b/docs/images/cli/api-keys/management.png differ diff --git a/docs/images/cli/api-keys/update.png b/docs/images/cli/api-keys/update.png new file mode 100644 index 0000000000..81cc574801 Binary files /dev/null and b/docs/images/cli/api-keys/update.png differ diff --git a/docs/tutorials/img/bulk-provider-provisioning.png b/docs/images/cli/bulk-provider-provisioning.png similarity index 100% rename from docs/tutorials/img/bulk-provider-provisioning.png rename to docs/images/cli/bulk-provider-provisioning.png diff --git a/docs/tutorials/img/cloud-providers-page.png b/docs/images/cli/cloud-providers-page.png similarity index 100% rename from docs/tutorials/img/cloud-providers-page.png rename to docs/images/cli/cloud-providers-page.png diff --git a/docs/tutorials/img/compliance/compliance-cis-sample1.png b/docs/images/cli/compliance/compliance-cis-sample1.png similarity index 100% rename from docs/tutorials/img/compliance/compliance-cis-sample1.png rename to docs/images/cli/compliance/compliance-cis-sample1.png diff --git a/docs/tutorials/img/compliance/compliance.png b/docs/images/cli/compliance/compliance.png similarity index 100% rename from docs/tutorials/img/compliance/compliance.png rename to docs/images/cli/compliance/compliance.png diff --git a/docs/tutorials/img/create-slack-app.png b/docs/images/cli/create-slack-app.png similarity index 100% rename from docs/tutorials/img/create-slack-app.png rename to docs/images/cli/create-slack-app.png diff --git a/docs/tutorials/img/create-sp.gif b/docs/images/cli/create-sp.gif similarity index 100% rename from docs/tutorials/img/create-sp.gif rename to docs/images/cli/create-sp.gif diff --git a/docs/tutorials/img/dashboard/dashboard-banner.png b/docs/images/cli/dashboard/dashboard-banner.png similarity index 100% rename from docs/tutorials/img/dashboard/dashboard-banner.png rename to docs/images/cli/dashboard/dashboard-banner.png diff --git a/docs/tutorials/img/dashboard/dashboard-compliance.png b/docs/images/cli/dashboard/dashboard-compliance.png similarity index 100% rename from docs/tutorials/img/dashboard/dashboard-compliance.png rename to docs/images/cli/dashboard/dashboard-compliance.png diff --git a/docs/tutorials/img/dashboard/dashboard-files-scanned.png b/docs/images/cli/dashboard/dashboard-files-scanned.png similarity index 100% rename from docs/tutorials/img/dashboard/dashboard-files-scanned.png rename to docs/images/cli/dashboard/dashboard-files-scanned.png diff --git a/docs/tutorials/img/dashboard/dashboard-overview.png b/docs/images/cli/dashboard/dashboard-overview.png similarity index 100% rename from docs/tutorials/img/dashboard/dashboard-overview.png rename to docs/images/cli/dashboard/dashboard-overview.png diff --git a/docs/tutorials/img/dashboard/dropdown.png b/docs/images/cli/dashboard/dropdown.png similarity index 100% rename from docs/tutorials/img/dashboard/dropdown.png rename to docs/images/cli/dashboard/dropdown.png diff --git a/docs/tutorials/img/fixer.png b/docs/images/cli/fixer.png similarity index 100% rename from docs/tutorials/img/fixer.png rename to docs/images/cli/fixer.png diff --git a/docs/tutorials/img/gcp-auth-methods.png b/docs/images/cli/gcp-auth-methods.png similarity index 100% rename from docs/tutorials/img/gcp-auth-methods.png rename to docs/images/cli/gcp-auth-methods.png diff --git a/docs/tutorials/img/gcp-service-account-creds.png b/docs/images/cli/gcp-service-account-creds.png similarity index 100% rename from docs/tutorials/img/gcp-service-account-creds.png rename to docs/images/cli/gcp-service-account-creds.png diff --git a/docs/tutorials/img/github-app-credentials.png b/docs/images/cli/github-app-credentials.png similarity index 100% rename from docs/tutorials/img/github-app-credentials.png rename to docs/images/cli/github-app-credentials.png diff --git a/docs/tutorials/img/github-auth-methods.png b/docs/images/cli/github-auth-methods.png similarity index 100% rename from docs/tutorials/img/github-auth-methods.png rename to docs/images/cli/github-auth-methods.png diff --git a/docs/tutorials/img/github-oauth-credentials.png b/docs/images/cli/github-oauth-credentials.png similarity index 100% rename from docs/tutorials/img/github-oauth-credentials.png rename to docs/images/cli/github-oauth-credentials.png diff --git a/docs/tutorials/img/github-pat-credentials.png b/docs/images/cli/github-pat-credentials.png similarity index 100% rename from docs/tutorials/img/github-pat-credentials.png rename to docs/images/cli/github-pat-credentials.png diff --git a/docs/tutorials/img/install-in-slack-workspace.png b/docs/images/cli/install-in-slack-workspace.png similarity index 100% rename from docs/tutorials/img/install-in-slack-workspace.png rename to docs/images/cli/install-in-slack-workspace.png diff --git a/docs/tutorials/img/integrate-slack-app.png b/docs/images/cli/integrate-slack-app.png similarity index 100% rename from docs/tutorials/img/integrate-slack-app.png rename to docs/images/cli/integrate-slack-app.png diff --git a/docs/images/cli/jira/connection-settings.png b/docs/images/cli/jira/connection-settings.png new file mode 100644 index 0000000000..86ebe73dea Binary files /dev/null and b/docs/images/cli/jira/connection-settings.png differ diff --git a/docs/images/cli/jira/integrations-tab.png b/docs/images/cli/jira/integrations-tab.png new file mode 100644 index 0000000000..e71773fc52 Binary files /dev/null and b/docs/images/cli/jira/integrations-tab.png differ diff --git a/docs/images/cli/jira/send-to-jira-modal.png b/docs/images/cli/jira/send-to-jira-modal.png new file mode 100644 index 0000000000..2cf498926a Binary files /dev/null and b/docs/images/cli/jira/send-to-jira-modal.png differ diff --git a/docs/tutorials/img/lighthouse-architecture.png b/docs/images/cli/lighthouse-architecture.png similarity index 100% rename from docs/tutorials/img/lighthouse-architecture.png rename to docs/images/cli/lighthouse-architecture.png diff --git a/docs/tutorials/img/lighthouse-config.png b/docs/images/cli/lighthouse-config.png similarity index 100% rename from docs/tutorials/img/lighthouse-config.png rename to docs/images/cli/lighthouse-config.png diff --git a/docs/tutorials/img/lighthouse-feature1.png b/docs/images/cli/lighthouse-feature1.png similarity index 100% rename from docs/tutorials/img/lighthouse-feature1.png rename to docs/images/cli/lighthouse-feature1.png diff --git a/docs/tutorials/img/lighthouse-feature2.png b/docs/images/cli/lighthouse-feature2.png similarity index 100% rename from docs/tutorials/img/lighthouse-feature2.png rename to docs/images/cli/lighthouse-feature2.png diff --git a/docs/tutorials/img/lighthouse-feature3.png b/docs/images/cli/lighthouse-feature3.png similarity index 100% rename from docs/tutorials/img/lighthouse-feature3.png rename to docs/images/cli/lighthouse-feature3.png diff --git a/docs/tutorials/img/lighthouse-intro.png b/docs/images/cli/lighthouse-intro.png similarity index 100% rename from docs/tutorials/img/lighthouse-intro.png rename to docs/images/cli/lighthouse-intro.png diff --git a/docs/tutorials/img/mutelist-keys.png b/docs/images/cli/mutelist-keys.png similarity index 100% rename from docs/tutorials/img/mutelist-keys.png rename to docs/images/cli/mutelist-keys.png diff --git a/docs/tutorials/img/mutelist-row.png b/docs/images/cli/mutelist-row.png similarity index 100% rename from docs/tutorials/img/mutelist-row.png rename to docs/images/cli/mutelist-row.png diff --git a/docs/tutorials/img/rbac/invitation_details.png b/docs/images/cli/rbac/invitation_details.png similarity index 100% rename from docs/tutorials/img/rbac/invitation_details.png rename to docs/images/cli/rbac/invitation_details.png diff --git a/docs/tutorials/img/rbac/invitation_details_1.png b/docs/images/cli/rbac/invitation_details_1.png similarity index 100% rename from docs/tutorials/img/rbac/invitation_details_1.png rename to docs/images/cli/rbac/invitation_details_1.png diff --git a/docs/tutorials/img/rbac/invitation_edit.png b/docs/images/cli/rbac/invitation_edit.png similarity index 100% rename from docs/tutorials/img/rbac/invitation_edit.png rename to docs/images/cli/rbac/invitation_edit.png diff --git a/docs/tutorials/img/rbac/invitation_edit_1.png b/docs/images/cli/rbac/invitation_edit_1.png similarity index 100% rename from docs/tutorials/img/rbac/invitation_edit_1.png rename to docs/images/cli/rbac/invitation_edit_1.png diff --git a/docs/tutorials/img/rbac/invitation_info.png b/docs/images/cli/rbac/invitation_info.png similarity index 100% rename from docs/tutorials/img/rbac/invitation_info.png rename to docs/images/cli/rbac/invitation_info.png diff --git a/docs/tutorials/img/rbac/invitation_revoke.png b/docs/images/cli/rbac/invitation_revoke.png similarity index 100% rename from docs/tutorials/img/rbac/invitation_revoke.png rename to docs/images/cli/rbac/invitation_revoke.png diff --git a/docs/tutorials/img/rbac/invitation_sign-up.png b/docs/images/cli/rbac/invitation_sign-up.png similarity index 100% rename from docs/tutorials/img/rbac/invitation_sign-up.png rename to docs/images/cli/rbac/invitation_sign-up.png diff --git a/docs/tutorials/img/rbac/invite.png b/docs/images/cli/rbac/invite.png similarity index 100% rename from docs/tutorials/img/rbac/invite.png rename to docs/images/cli/rbac/invite.png diff --git a/docs/tutorials/img/rbac/membership.png b/docs/images/cli/rbac/membership.png similarity index 100% rename from docs/tutorials/img/rbac/membership.png rename to docs/images/cli/rbac/membership.png diff --git a/docs/tutorials/img/rbac/provider_group.png b/docs/images/cli/rbac/provider_group.png similarity index 100% rename from docs/tutorials/img/rbac/provider_group.png rename to docs/images/cli/rbac/provider_group.png diff --git a/docs/tutorials/img/rbac/provider_group_edit.png b/docs/images/cli/rbac/provider_group_edit.png similarity index 100% rename from docs/tutorials/img/rbac/provider_group_edit.png rename to docs/images/cli/rbac/provider_group_edit.png diff --git a/docs/tutorials/img/rbac/provider_group_edit_1.png b/docs/images/cli/rbac/provider_group_edit_1.png similarity index 100% rename from docs/tutorials/img/rbac/provider_group_edit_1.png rename to docs/images/cli/rbac/provider_group_edit_1.png diff --git a/docs/tutorials/img/rbac/provider_group_remove.png b/docs/images/cli/rbac/provider_group_remove.png similarity index 100% rename from docs/tutorials/img/rbac/provider_group_remove.png rename to docs/images/cli/rbac/provider_group_remove.png diff --git a/docs/tutorials/img/rbac/role_create.png b/docs/images/cli/rbac/role_create.png similarity index 100% rename from docs/tutorials/img/rbac/role_create.png rename to docs/images/cli/rbac/role_create.png diff --git a/docs/tutorials/img/rbac/role_create_1.png b/docs/images/cli/rbac/role_create_1.png similarity index 100% rename from docs/tutorials/img/rbac/role_create_1.png rename to docs/images/cli/rbac/role_create_1.png diff --git a/docs/tutorials/img/rbac/role_edit.png b/docs/images/cli/rbac/role_edit.png similarity index 100% rename from docs/tutorials/img/rbac/role_edit.png rename to docs/images/cli/rbac/role_edit.png diff --git a/docs/tutorials/img/rbac/role_edit_details.png b/docs/images/cli/rbac/role_edit_details.png similarity index 100% rename from docs/tutorials/img/rbac/role_edit_details.png rename to docs/images/cli/rbac/role_edit_details.png diff --git a/docs/tutorials/img/rbac/role_remove.png b/docs/images/cli/rbac/role_remove.png similarity index 100% rename from docs/tutorials/img/rbac/role_remove.png rename to docs/images/cli/rbac/role_remove.png diff --git a/docs/tutorials/img/rbac/user_edit.png b/docs/images/cli/rbac/user_edit.png similarity index 100% rename from docs/tutorials/img/rbac/user_edit.png rename to docs/images/cli/rbac/user_edit.png diff --git a/docs/tutorials/img/rbac/user_edit_details.png b/docs/images/cli/rbac/user_edit_details.png similarity index 100% rename from docs/tutorials/img/rbac/user_edit_details.png rename to docs/images/cli/rbac/user_edit_details.png diff --git a/docs/tutorials/img/rbac/user_remove.png b/docs/images/cli/rbac/user_remove.png similarity index 100% rename from docs/tutorials/img/rbac/user_remove.png rename to docs/images/cli/rbac/user_remove.png diff --git a/docs/tutorials/img/reporting/html-output.png b/docs/images/cli/reporting/html-output.png similarity index 100% rename from docs/tutorials/img/reporting/html-output.png rename to docs/images/cli/reporting/html-output.png diff --git a/docs/tutorials/img/s3/s3-cross-account.png b/docs/images/cli/s3/s3-cross-account.png similarity index 100% rename from docs/tutorials/img/s3/s3-cross-account.png rename to docs/images/cli/s3/s3-cross-account.png diff --git a/docs/tutorials/img/s3/s3-integration-ui-1.png b/docs/images/cli/s3/s3-integration-ui-1.png similarity index 100% rename from docs/tutorials/img/s3/s3-integration-ui-1.png rename to docs/images/cli/s3/s3-integration-ui-1.png diff --git a/docs/tutorials/img/s3/s3-integration-ui-2.png b/docs/images/cli/s3/s3-integration-ui-2.png similarity index 100% rename from docs/tutorials/img/s3/s3-integration-ui-2.png rename to docs/images/cli/s3/s3-integration-ui-2.png diff --git a/docs/tutorials/img/s3/s3-integration-ui-3.png b/docs/images/cli/s3/s3-integration-ui-3.png similarity index 100% rename from docs/tutorials/img/s3/s3-integration-ui-3.png rename to docs/images/cli/s3/s3-integration-ui-3.png diff --git a/docs/tutorials/img/s3/s3-integration-ui-4.png b/docs/images/cli/s3/s3-integration-ui-4.png similarity index 100% rename from docs/tutorials/img/s3/s3-integration-ui-4.png rename to docs/images/cli/s3/s3-integration-ui-4.png diff --git a/docs/tutorials/img/s3/s3-integration-ui-5.png b/docs/images/cli/s3/s3-integration-ui-5.png similarity index 100% rename from docs/tutorials/img/s3/s3-integration-ui-5.png rename to docs/images/cli/s3/s3-integration-ui-5.png diff --git a/docs/tutorials/img/s3/s3-integration-ui-6.png b/docs/images/cli/s3/s3-integration-ui-6.png similarity index 100% rename from docs/tutorials/img/s3/s3-integration-ui-6.png rename to docs/images/cli/s3/s3-integration-ui-6.png diff --git a/docs/tutorials/img/s3/s3-integration-ui-7.png b/docs/images/cli/s3/s3-integration-ui-7.png similarity index 100% rename from docs/tutorials/img/s3/s3-integration-ui-7.png rename to docs/images/cli/s3/s3-integration-ui-7.png diff --git a/docs/tutorials/img/s3/s3-multiple-accounts.png b/docs/images/cli/s3/s3-multiple-accounts.png similarity index 100% rename from docs/tutorials/img/s3/s3-multiple-accounts.png rename to docs/images/cli/s3/s3-multiple-accounts.png diff --git a/docs/tutorials/img/s3/s3-output-folder.png b/docs/images/cli/s3/s3-output-folder.png similarity index 100% rename from docs/tutorials/img/s3/s3-output-folder.png rename to docs/images/cli/s3/s3-output-folder.png diff --git a/docs/tutorials/img/s3/s3-same-account.png b/docs/images/cli/s3/s3-same-account.png similarity index 100% rename from docs/tutorials/img/s3/s3-same-account.png rename to docs/images/cli/s3/s3-same-account.png diff --git a/docs/tutorials/img/saml/app-catalog-browse-prowler-add.png b/docs/images/cli/saml/app-catalog-browse-prowler-add.png similarity index 100% rename from docs/tutorials/img/saml/app-catalog-browse-prowler-add.png rename to docs/images/cli/saml/app-catalog-browse-prowler-add.png diff --git a/docs/tutorials/img/saml/app-catalog-browse-prowler-configure.png b/docs/images/cli/saml/app-catalog-browse-prowler-configure.png similarity index 100% rename from docs/tutorials/img/saml/app-catalog-browse-prowler-configure.png rename to docs/images/cli/saml/app-catalog-browse-prowler-configure.png diff --git a/docs/tutorials/img/saml/app-catalog-browse-prowler.png b/docs/images/cli/saml/app-catalog-browse-prowler.png similarity index 100% rename from docs/tutorials/img/saml/app-catalog-browse-prowler.png rename to docs/images/cli/saml/app-catalog-browse-prowler.png diff --git a/docs/tutorials/img/saml/app-catalog-browse.png b/docs/images/cli/saml/app-catalog-browse.png similarity index 100% rename from docs/tutorials/img/saml/app-catalog-browse.png rename to docs/images/cli/saml/app-catalog-browse.png diff --git a/docs/tutorials/img/saml/idp_config.png b/docs/images/cli/saml/idp_config.png similarity index 100% rename from docs/tutorials/img/saml/idp_config.png rename to docs/images/cli/saml/idp_config.png diff --git a/docs/tutorials/img/saml/saml-signin-1.png b/docs/images/cli/saml/saml-signin-1.png similarity index 100% rename from docs/tutorials/img/saml/saml-signin-1.png rename to docs/images/cli/saml/saml-signin-1.png diff --git a/docs/tutorials/img/saml/saml-signin-2.png b/docs/images/cli/saml/saml-signin-2.png similarity index 100% rename from docs/tutorials/img/saml/saml-signin-2.png rename to docs/images/cli/saml/saml-signin-2.png diff --git a/docs/tutorials/img/saml/saml-sso-azure-1.png b/docs/images/cli/saml/saml-sso-azure-1.png similarity index 100% rename from docs/tutorials/img/saml/saml-sso-azure-1.png rename to docs/images/cli/saml/saml-sso-azure-1.png diff --git a/docs/tutorials/img/saml/saml-sso-azure-2.png b/docs/images/cli/saml/saml-sso-azure-2.png similarity index 100% rename from docs/tutorials/img/saml/saml-sso-azure-2.png rename to docs/images/cli/saml/saml-sso-azure-2.png diff --git a/docs/tutorials/img/saml/saml-sso-azure-3.png b/docs/images/cli/saml/saml-sso-azure-3.png similarity index 100% rename from docs/tutorials/img/saml/saml-sso-azure-3.png rename to docs/images/cli/saml/saml-sso-azure-3.png diff --git a/docs/tutorials/img/saml/saml-sso-azure-4.png b/docs/images/cli/saml/saml-sso-azure-4.png similarity index 100% rename from docs/tutorials/img/saml/saml-sso-azure-4.png rename to docs/images/cli/saml/saml-sso-azure-4.png diff --git a/docs/tutorials/img/saml/saml-sso-azure-5.png b/docs/images/cli/saml/saml-sso-azure-5.png similarity index 100% rename from docs/tutorials/img/saml/saml-sso-azure-5.png rename to docs/images/cli/saml/saml-sso-azure-5.png diff --git a/docs/tutorials/img/saml/saml-sso-azure-6.png b/docs/images/cli/saml/saml-sso-azure-6.png similarity index 100% rename from docs/tutorials/img/saml/saml-sso-azure-6.png rename to docs/images/cli/saml/saml-sso-azure-6.png diff --git a/docs/tutorials/img/saml/saml-sso-azure-7.png b/docs/images/cli/saml/saml-sso-azure-7.png similarity index 100% rename from docs/tutorials/img/saml/saml-sso-azure-7.png rename to docs/images/cli/saml/saml-sso-azure-7.png diff --git a/docs/tutorials/img/saml/saml-sso-azure-8.png b/docs/images/cli/saml/saml-sso-azure-8.png similarity index 100% rename from docs/tutorials/img/saml/saml-sso-azure-8.png rename to docs/images/cli/saml/saml-sso-azure-8.png diff --git a/docs/tutorials/img/saml/saml-sso-azure-9.png b/docs/images/cli/saml/saml-sso-azure-9.png similarity index 100% rename from docs/tutorials/img/saml/saml-sso-azure-9.png rename to docs/images/cli/saml/saml-sso-azure-9.png diff --git a/docs/tutorials/img/saml/saml-step-1.png b/docs/images/cli/saml/saml-step-1.png similarity index 100% rename from docs/tutorials/img/saml/saml-step-1.png rename to docs/images/cli/saml/saml-step-1.png diff --git a/docs/tutorials/img/saml/saml-step-2.png b/docs/images/cli/saml/saml-step-2.png similarity index 100% rename from docs/tutorials/img/saml/saml-step-2.png rename to docs/images/cli/saml/saml-step-2.png diff --git a/docs/tutorials/img/saml/saml-step-3.png b/docs/images/cli/saml/saml-step-3.png similarity index 100% rename from docs/tutorials/img/saml/saml-step-3.png rename to docs/images/cli/saml/saml-step-3.png diff --git a/docs/tutorials/img/saml/saml-step-4.png b/docs/images/cli/saml/saml-step-4.png similarity index 100% rename from docs/tutorials/img/saml/saml-step-4.png rename to docs/images/cli/saml/saml-step-4.png diff --git a/docs/tutorials/img/saml/saml-step-remove.png b/docs/images/cli/saml/saml-step-remove.png similarity index 100% rename from docs/tutorials/img/saml/saml-step-remove.png rename to docs/images/cli/saml/saml-step-remove.png diff --git a/docs/tutorials/img/saml/saml_attribute_statements.png b/docs/images/cli/saml/saml_attribute_statements.png similarity index 100% rename from docs/tutorials/img/saml/saml_attribute_statements.png rename to docs/images/cli/saml/saml_attribute_statements.png diff --git a/docs/images/cli/security-hub/create-integration.png b/docs/images/cli/security-hub/create-integration.png new file mode 100644 index 0000000000..145e68d201 Binary files /dev/null and b/docs/images/cli/security-hub/create-integration.png differ diff --git a/docs/images/cli/security-hub/integration-settings.png b/docs/images/cli/security-hub/integration-settings.png new file mode 100644 index 0000000000..3a32bf0830 Binary files /dev/null and b/docs/images/cli/security-hub/integration-settings.png differ diff --git a/docs/images/cli/security-hub/integrations-tab.png b/docs/images/cli/security-hub/integrations-tab.png new file mode 100644 index 0000000000..9d11cae33a Binary files /dev/null and b/docs/images/cli/security-hub/integrations-tab.png differ diff --git a/docs/tutorials/img/slack-app-token.png b/docs/images/cli/slack-app-token.png similarity index 100% rename from docs/tutorials/img/slack-app-token.png rename to docs/images/cli/slack-app-token.png diff --git a/docs/tutorials/img/slack-prowler-message.png b/docs/images/cli/slack-prowler-message.png similarity index 100% rename from docs/tutorials/img/slack-prowler-message.png rename to docs/images/cli/slack-prowler-message.png diff --git a/docs/tutorials/img/social-login/social_login_buttons.png b/docs/images/cli/social-login/social_login_buttons.png similarity index 100% rename from docs/tutorials/img/social-login/social_login_buttons.png rename to docs/images/cli/social-login/social_login_buttons.png diff --git a/docs/tutorials/img/social-login/social_login_buttons_disabled.png b/docs/images/cli/social-login/social_login_buttons_disabled.png similarity index 100% rename from docs/tutorials/img/social-login/social_login_buttons_disabled.png rename to docs/images/cli/social-login/social_login_buttons_disabled.png diff --git a/docs/images/compliance.png b/docs/images/compliance.png new file mode 100644 index 0000000000..b08fcc3651 Binary files /dev/null and b/docs/images/compliance.png differ diff --git a/docs/images/compliance_download.png b/docs/images/compliance_download.png new file mode 100644 index 0000000000..32aed141b3 Binary files /dev/null and b/docs/images/compliance_download.png differ diff --git a/docs/images/compliance_section.png b/docs/images/compliance_section.png new file mode 100644 index 0000000000..2b64031550 Binary files /dev/null and b/docs/images/compliance_section.png differ diff --git a/docs/images/connect-aws-credentials.png b/docs/images/connect-aws-credentials.png new file mode 100644 index 0000000000..7ea1f193c3 Binary files /dev/null and b/docs/images/connect-aws-credentials.png differ diff --git a/docs/images/connect-aws-role.png b/docs/images/connect-aws-role.png new file mode 100644 index 0000000000..78c8f6f390 Binary files /dev/null and b/docs/images/connect-aws-role.png differ diff --git a/docs/images/create-management-group.gif b/docs/images/create-management-group.gif new file mode 100644 index 0000000000..0088e78495 Binary files /dev/null and b/docs/images/create-management-group.gif differ diff --git a/docs/images/download_output.png b/docs/images/download_output.png new file mode 100644 index 0000000000..452851b84d Binary files /dev/null and b/docs/images/download_output.png differ diff --git a/docs/images/extended-display.png b/docs/images/extended-display.png new file mode 100644 index 0000000000..4e97d278ff Binary files /dev/null and b/docs/images/extended-display.png differ diff --git a/docs/images/findings.png b/docs/images/findings.png new file mode 100644 index 0000000000..e2ea9c56ce Binary files /dev/null and b/docs/images/findings.png differ diff --git a/docs/images/gcp-credentials.png b/docs/images/gcp-credentials.png new file mode 100644 index 0000000000..4f6dae3b1e Binary files /dev/null and b/docs/images/gcp-credentials.png differ diff --git a/docs/images/html-output.png b/docs/images/html-output.png new file mode 100644 index 0000000000..00a8b60812 Binary files /dev/null and b/docs/images/html-output.png differ diff --git a/docs/images/issues.png b/docs/images/issues.png new file mode 100644 index 0000000000..009bc0d447 Binary files /dev/null and b/docs/images/issues.png differ diff --git a/docs/images/kubernetes-credentials.png b/docs/images/kubernetes-credentials.png new file mode 100644 index 0000000000..b461ed218a Binary files /dev/null and b/docs/images/kubernetes-credentials.png differ diff --git a/docs/images/log-in.png b/docs/images/log-in.png new file mode 100644 index 0000000000..9e6d410abe Binary files /dev/null and b/docs/images/log-in.png differ diff --git a/docs/tutorials/microsoft365/img/m365-credentials.png b/docs/images/m365-credentials.png similarity index 100% rename from docs/tutorials/microsoft365/img/m365-credentials.png rename to docs/images/m365-credentials.png diff --git a/docs/images/mutelist-ui-1.png b/docs/images/mutelist-ui-1.png new file mode 100644 index 0000000000..8114e64fdf Binary files /dev/null and b/docs/images/mutelist-ui-1.png differ diff --git a/docs/images/mutelist-ui-2.png b/docs/images/mutelist-ui-2.png new file mode 100644 index 0000000000..847f7c1b16 Binary files /dev/null and b/docs/images/mutelist-ui-2.png differ diff --git a/docs/images/mutelist-ui-3.png b/docs/images/mutelist-ui-3.png new file mode 100644 index 0000000000..da1951c533 Binary files /dev/null and b/docs/images/mutelist-ui-3.png differ diff --git a/docs/images/mutelist-ui-4.png b/docs/images/mutelist-ui-4.png new file mode 100644 index 0000000000..82ce685e51 Binary files /dev/null and b/docs/images/mutelist-ui-4.png differ diff --git a/docs/images/mutelist-ui-5.png b/docs/images/mutelist-ui-5.png new file mode 100644 index 0000000000..128bf30731 Binary files /dev/null and b/docs/images/mutelist-ui-5.png differ diff --git a/docs/images/mutelist-ui-6.png b/docs/images/mutelist-ui-6.png new file mode 100644 index 0000000000..659eccb61e Binary files /dev/null and b/docs/images/mutelist-ui-6.png differ diff --git a/docs/images/mutelist-ui-7.png b/docs/images/mutelist-ui-7.png new file mode 100644 index 0000000000..e6352c97e9 Binary files /dev/null and b/docs/images/mutelist-ui-7.png differ diff --git a/docs/images/mutelist-ui-8.png b/docs/images/mutelist-ui-8.png new file mode 100644 index 0000000000..54e2110edb Binary files /dev/null and b/docs/images/mutelist-ui-8.png differ diff --git a/docs/images/mutelist-ui-9.png b/docs/images/mutelist-ui-9.png new file mode 100644 index 0000000000..cba2ece1a3 Binary files /dev/null and b/docs/images/mutelist-ui-9.png differ diff --git a/docs/images/nacho.png b/docs/images/nacho.png new file mode 100644 index 0000000000..549d6b6c6d Binary files /dev/null and b/docs/images/nacho.png differ diff --git a/docs/images/output_folder.png b/docs/images/output_folder.png new file mode 100644 index 0000000000..11ae4d9925 Binary files /dev/null and b/docs/images/output_folder.png differ diff --git a/docs/images/pepe.png b/docs/images/pepe.png new file mode 100644 index 0000000000..a9aed2be15 Binary files /dev/null and b/docs/images/pepe.png differ diff --git a/docs/images/products/dashboard.png b/docs/images/products/dashboard.png new file mode 100644 index 0000000000..2392debbb7 Binary files /dev/null and b/docs/images/products/dashboard.png differ diff --git a/docs/images/products/overview.png b/docs/images/products/overview.png new file mode 100644 index 0000000000..724ffc9588 Binary files /dev/null and b/docs/images/products/overview.png differ diff --git a/docs/images/products/prowler-app-architecture.png b/docs/images/products/prowler-app-architecture.png new file mode 100644 index 0000000000..889bc0da88 Binary files /dev/null and b/docs/images/products/prowler-app-architecture.png differ diff --git a/docs/images/products/prowler-hub.webp b/docs/images/products/prowler-hub.webp new file mode 100644 index 0000000000..b489ff9012 Binary files /dev/null and b/docs/images/products/prowler-hub.webp differ diff --git a/docs/images/provider-added.png b/docs/images/provider-added.png new file mode 100644 index 0000000000..cfb94d2cab Binary files /dev/null and b/docs/images/provider-added.png differ diff --git a/docs/tutorials/gcp/img/access-console.png b/docs/images/providers/access-console.png similarity index 100% rename from docs/tutorials/gcp/img/access-console.png rename to docs/images/providers/access-console.png diff --git a/docs/images/providers/access-manager.png b/docs/images/providers/access-manager.png new file mode 100644 index 0000000000..1f7bf21839 Binary files /dev/null and b/docs/images/providers/access-manager.png differ diff --git a/docs/tutorials/aws/img/add-account-id.png b/docs/images/providers/add-account-id.png similarity index 100% rename from docs/tutorials/aws/img/add-account-id.png rename to docs/images/providers/add-account-id.png diff --git a/docs/tutorials/azure/img/add-api-permission.png b/docs/images/providers/add-api-permission.png similarity index 100% rename from docs/tutorials/azure/img/add-api-permission.png rename to docs/images/providers/add-api-permission.png diff --git a/docs/tutorials/microsoft365/img/add-app-api-permission.png b/docs/images/providers/add-app-api-permission.png similarity index 100% rename from docs/tutorials/microsoft365/img/add-app-api-permission.png rename to docs/images/providers/add-app-api-permission.png diff --git a/docs/tutorials/microsoft365/img/add-assginments.png b/docs/images/providers/add-assginments.png similarity index 100% rename from docs/tutorials/microsoft365/img/add-assginments.png rename to docs/images/providers/add-assginments.png diff --git a/docs/tutorials/azure/img/add-credentials-azure-prowler-cloud.png b/docs/images/providers/add-credentials-azure-prowler-cloud.png similarity index 100% rename from docs/tutorials/azure/img/add-credentials-azure-prowler-cloud.png rename to docs/images/providers/add-credentials-azure-prowler-cloud.png diff --git a/docs/tutorials/azure/img/add-custom-role-json.png b/docs/images/providers/add-custom-role-json.png similarity index 100% rename from docs/tutorials/azure/img/add-custom-role-json.png rename to docs/images/providers/add-custom-role-json.png diff --git a/docs/tutorials/azure/img/add-custom-role.png b/docs/images/providers/add-custom-role.png similarity index 100% rename from docs/tutorials/azure/img/add-custom-role.png rename to docs/images/providers/add-custom-role.png diff --git a/docs/tutorials/microsoft365/img/add-delegated-api-permission.png b/docs/images/providers/add-delegated-api-permission.png similarity index 100% rename from docs/tutorials/microsoft365/img/add-delegated-api-permission.png rename to docs/images/providers/add-delegated-api-permission.png diff --git a/docs/tutorials/microsoft365/img/add-domain-id.png b/docs/images/providers/add-domain-id.png similarity index 100% rename from docs/tutorials/microsoft365/img/add-domain-id.png rename to docs/images/providers/add-domain-id.png diff --git a/docs/images/providers/add-github-account-id.png b/docs/images/providers/add-github-account-id.png new file mode 100644 index 0000000000..899d772c60 Binary files /dev/null and b/docs/images/providers/add-github-account-id.png differ diff --git a/docs/images/providers/add-iac-repo.png b/docs/images/providers/add-iac-repo.png new file mode 100644 index 0000000000..31981e7fd1 Binary files /dev/null and b/docs/images/providers/add-iac-repo.png differ diff --git a/docs/images/providers/add-ip.png b/docs/images/providers/add-ip.png new file mode 100644 index 0000000000..8e6fd8a021 Binary files /dev/null and b/docs/images/providers/add-ip.png differ diff --git a/docs/tutorials/gcp/img/add-project-id.png b/docs/images/providers/add-project-id.png similarity index 100% rename from docs/tutorials/gcp/img/add-project-id.png rename to docs/images/providers/add-project-id.png diff --git a/docs/tutorials/azure/img/add-reader-role.png b/docs/images/providers/add-reader-role.png similarity index 100% rename from docs/tutorials/azure/img/add-reader-role.png rename to docs/images/providers/add-reader-role.png diff --git a/docs/tutorials/azure/img/add-role-assigment.png b/docs/images/providers/add-role-assigment.png similarity index 100% rename from docs/tutorials/azure/img/add-role-assigment.png rename to docs/images/providers/add-role-assigment.png diff --git a/docs/tutorials/azure/img/add-subscription-id.png b/docs/images/providers/add-subscription-id.png similarity index 100% rename from docs/tutorials/azure/img/add-subscription-id.png rename to docs/images/providers/add-subscription-id.png diff --git a/docs/tutorials/microsoft365/img/api-permissions-page.png b/docs/images/providers/api-permissions-page.png similarity index 100% rename from docs/tutorials/microsoft365/img/api-permissions-page.png rename to docs/images/providers/api-permissions-page.png diff --git a/docs/tutorials/azure/img/api-permissions-result.png b/docs/images/providers/api-permissions-result.png similarity index 100% rename from docs/tutorials/azure/img/api-permissions-result.png rename to docs/images/providers/api-permissions-result.png diff --git a/docs/tutorials/microsoft365/img/app-overview.png b/docs/images/providers/app-overview.png similarity index 100% rename from docs/tutorials/microsoft365/img/app-overview.png rename to docs/images/providers/app-overview.png diff --git a/docs/tutorials/microsoft365/img/app-permissions.png b/docs/images/providers/app-permissions.png similarity index 100% rename from docs/tutorials/microsoft365/img/app-permissions.png rename to docs/images/providers/app-permissions.png diff --git a/docs/tutorials/microsoft365/img/app-registration-menu.png b/docs/images/providers/app-registration-menu.png similarity index 100% rename from docs/tutorials/microsoft365/img/app-registration-menu.png rename to docs/images/providers/app-registration-menu.png diff --git a/docs/tutorials/azure/img/application-permissions-inside-graph.png b/docs/images/providers/application-permissions-inside-graph.png similarity index 100% rename from docs/tutorials/azure/img/application-permissions-inside-graph.png rename to docs/images/providers/application-permissions-inside-graph.png diff --git a/docs/tutorials/microsoft365/img/assign-global-reader-role.png b/docs/images/providers/assign-global-reader-role.png similarity index 100% rename from docs/tutorials/microsoft365/img/assign-global-reader-role.png rename to docs/images/providers/assign-global-reader-role.png diff --git a/docs/tutorials/aws/img/assume-role-overview.png b/docs/images/providers/assume-role-overview.png similarity index 100% rename from docs/tutorials/aws/img/assume-role-overview.png rename to docs/images/providers/assume-role-overview.png diff --git a/docs/images/providers/auth-github-app.png b/docs/images/providers/auth-github-app.png new file mode 100644 index 0000000000..ce7555f081 Binary files /dev/null and b/docs/images/providers/auth-github-app.png differ diff --git a/docs/images/providers/auth-oauth.png b/docs/images/providers/auth-oauth.png new file mode 100644 index 0000000000..fd38330aa4 Binary files /dev/null and b/docs/images/providers/auth-oauth.png differ diff --git a/docs/images/providers/auth-pat.png b/docs/images/providers/auth-pat.png new file mode 100644 index 0000000000..573640851e Binary files /dev/null and b/docs/images/providers/auth-pat.png differ diff --git a/docs/tutorials/gcp/img/authorize-cloud-shell.png b/docs/images/providers/authorize-cloud-shell.png similarity index 100% rename from docs/tutorials/gcp/img/authorize-cloud-shell.png rename to docs/images/providers/authorize-cloud-shell.png diff --git a/docs/tutorials/aws/img/aws-account-id.png b/docs/images/providers/aws-account-id.png similarity index 100% rename from docs/tutorials/aws/img/aws-account-id.png rename to docs/images/providers/aws-account-id.png diff --git a/docs/tutorials/aws/img/aws-cloudshell.png b/docs/images/providers/aws-cloudshell.png similarity index 100% rename from docs/tutorials/aws/img/aws-cloudshell.png rename to docs/images/providers/aws-cloudshell.png 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/tutorials/microsoft365/img/certificates-and-secrets.png b/docs/images/providers/certificates-and-secrets.png similarity index 100% rename from docs/tutorials/microsoft365/img/certificates-and-secrets.png rename to docs/images/providers/certificates-and-secrets.png diff --git a/docs/tutorials/azure/img/click-add-permissions.png b/docs/images/providers/click-add-permissions.png similarity index 100% rename from docs/tutorials/azure/img/click-add-permissions.png rename to docs/images/providers/click-add-permissions.png diff --git a/docs/tutorials/azure/img/click-next-azure.png b/docs/images/providers/click-next-azure.png similarity index 100% rename from docs/tutorials/azure/img/click-next-azure.png rename to docs/images/providers/click-next-azure.png diff --git a/docs/tutorials/microsoft365/img/click-next-m365.png b/docs/images/providers/click-next-m365.png similarity index 100% rename from docs/tutorials/microsoft365/img/click-next-m365.png rename to docs/images/providers/click-next-m365.png diff --git a/docs/tutorials/aws/img/cloudformation-nav.png b/docs/images/providers/cloudformation-nav.png similarity index 100% rename from docs/tutorials/aws/img/cloudformation-nav.png rename to docs/images/providers/cloudformation-nav.png diff --git a/docs/tutorials/aws/img/cloudshell-output.png b/docs/images/providers/cloudshell-output.png similarity index 100% rename from docs/tutorials/aws/img/cloudshell-output.png rename to docs/images/providers/cloudshell-output.png diff --git a/docs/tutorials/aws/img/connect-via-credentials.png b/docs/images/providers/connect-via-credentials.png similarity index 100% rename from docs/tutorials/aws/img/connect-via-credentials.png rename to docs/images/providers/connect-via-credentials.png diff --git a/docs/tutorials/gcp/img/copy-auth-code.png b/docs/images/providers/copy-auth-code.png similarity index 100% rename from docs/tutorials/gcp/img/copy-auth-code.png rename to docs/images/providers/copy-auth-code.png diff --git a/docs/images/providers/copy-key.png b/docs/images/providers/copy-key.png new file mode 100644 index 0000000000..a4624480c5 Binary files /dev/null and b/docs/images/providers/copy-key.png differ diff --git a/docs/images/providers/create-api-key.png b/docs/images/providers/create-api-key.png new file mode 100644 index 0000000000..5d73c1236d Binary files /dev/null and b/docs/images/providers/create-api-key.png differ diff --git a/docs/tutorials/aws/img/create-stack.png b/docs/images/providers/create-stack.png similarity index 100% rename from docs/tutorials/aws/img/create-stack.png rename to docs/images/providers/create-stack.png diff --git a/docs/tutorials/microsoft365/img/custom-domain-names.png b/docs/images/providers/custom-domain-names.png similarity index 100% rename from docs/tutorials/microsoft365/img/custom-domain-names.png rename to docs/images/providers/custom-domain-names.png diff --git a/docs/tutorials/microsoft365/img/directory-permission-delegated.png b/docs/images/providers/directory-permission-delegated.png similarity index 100% rename from docs/tutorials/microsoft365/img/directory-permission-delegated.png rename to docs/images/providers/directory-permission-delegated.png diff --git a/docs/tutorials/microsoft365/img/directory-permission.png b/docs/images/providers/directory-permission.png similarity index 100% rename from docs/tutorials/microsoft365/img/directory-permission.png rename to docs/images/providers/directory-permission.png diff --git a/docs/tutorials/azure/img/domain-permission.png b/docs/images/providers/domain-permission.png similarity index 100% rename from docs/tutorials/azure/img/domain-permission.png rename to docs/images/providers/domain-permission.png diff --git a/docs/tutorials/azure/img/download-prowler-role.png b/docs/images/providers/download-prowler-role.png similarity index 100% rename from docs/tutorials/azure/img/download-prowler-role.png rename to docs/images/providers/download-prowler-role.png diff --git a/docs/tutorials/aws/img/download-role-template.png b/docs/images/providers/download-role-template.png similarity index 100% rename from docs/tutorials/aws/img/download-role-template.png rename to docs/images/providers/download-role-template.png diff --git a/docs/tutorials/aws/img/enable-2.png b/docs/images/providers/enable-2.png similarity index 100% rename from docs/tutorials/aws/img/enable-2.png rename to docs/images/providers/enable-2.png diff --git a/docs/tutorials/aws/img/enable-partner-integration-2.png b/docs/images/providers/enable-partner-integration-2.png similarity index 100% rename from docs/tutorials/aws/img/enable-partner-integration-2.png rename to docs/images/providers/enable-partner-integration-2.png diff --git a/docs/tutorials/aws/img/enable-partner-integration-3.png b/docs/images/providers/enable-partner-integration-3.png similarity index 100% rename from docs/tutorials/aws/img/enable-partner-integration-3.png rename to docs/images/providers/enable-partner-integration-3.png diff --git a/docs/tutorials/aws/img/enable-partner-integration-4.png b/docs/images/providers/enable-partner-integration-4.png similarity index 100% rename from docs/tutorials/aws/img/enable-partner-integration-4.png rename to docs/images/providers/enable-partner-integration-4.png diff --git a/docs/tutorials/aws/img/enable-partner-integration.png b/docs/images/providers/enable-partner-integration.png similarity index 100% rename from docs/tutorials/aws/img/enable-partner-integration.png rename to docs/images/providers/enable-partner-integration.png diff --git a/docs/tutorials/aws/img/enable.png b/docs/images/providers/enable.png similarity index 100% rename from docs/tutorials/aws/img/enable.png rename to docs/images/providers/enable.png diff --git a/docs/tutorials/gcp/img/enter-auth-code.png b/docs/images/providers/enter-auth-code.png similarity index 100% rename from docs/tutorials/gcp/img/enter-auth-code.png rename to docs/images/providers/enter-auth-code.png diff --git a/docs/tutorials/gcp/img/enter-credentials-prowler-cloud.png b/docs/images/providers/enter-credentials-prowler-cloud.png similarity index 100% rename from docs/tutorials/gcp/img/enter-credentials-prowler-cloud.png rename to docs/images/providers/enter-credentials-prowler-cloud.png diff --git a/docs/tutorials/microsoft365/img/exchange-permission.png b/docs/images/providers/exchange-permission.png similarity index 100% rename from docs/tutorials/microsoft365/img/exchange-permission.png rename to docs/images/providers/exchange-permission.png diff --git a/docs/tutorials/aws/img/fill-stack-data.png b/docs/images/providers/fill-stack-data.png similarity index 100% rename from docs/tutorials/aws/img/fill-stack-data.png rename to docs/images/providers/fill-stack-data.png diff --git a/docs/tutorials/microsoft365/img/final-permissions-m365.png b/docs/images/providers/final-permissions-m365.png similarity index 100% rename from docs/tutorials/microsoft365/img/final-permissions-m365.png rename to docs/images/providers/final-permissions-m365.png diff --git a/docs/tutorials/microsoft365/img/final-permissions.png b/docs/images/providers/final-permissions.png similarity index 100% rename from docs/tutorials/microsoft365/img/final-permissions.png rename to docs/images/providers/final-permissions.png diff --git a/docs/tutorials/aws/img/finding-details.png b/docs/images/providers/finding-details.png similarity index 100% rename from docs/tutorials/aws/img/finding-details.png rename to docs/images/providers/finding-details.png diff --git a/docs/tutorials/aws/img/findings.png b/docs/images/providers/findings.png similarity index 100% rename from docs/tutorials/aws/img/findings.png rename to docs/images/providers/findings.png diff --git a/docs/tutorials/aws/img/get-external-id-prowler-cloud.png b/docs/images/providers/get-external-id-prowler-cloud.png similarity index 100% rename from docs/tutorials/aws/img/get-external-id-prowler-cloud.png rename to docs/images/providers/get-external-id-prowler-cloud.png diff --git a/docs/tutorials/gcp/img/get-needed-values-auth.png b/docs/images/providers/get-needed-values-auth.png similarity index 100% rename from docs/tutorials/gcp/img/get-needed-values-auth.png rename to docs/images/providers/get-needed-values-auth.png diff --git a/docs/tutorials/aws/img/get-role-arn.png b/docs/images/providers/get-role-arn.png similarity index 100% rename from docs/tutorials/aws/img/get-role-arn.png rename to docs/images/providers/get-role-arn.png diff --git a/docs/tutorials/azure/img/get-subscription-id.png b/docs/images/providers/get-subscription-id.png similarity index 100% rename from docs/tutorials/azure/img/get-subscription-id.png rename to docs/images/providers/get-subscription-id.png diff --git a/docs/tutorials/gcp/img/get-temp-file-credentials.png b/docs/images/providers/get-temp-file-credentials.png similarity index 100% rename from docs/tutorials/gcp/img/get-temp-file-credentials.png rename to docs/images/providers/get-temp-file-credentials.png diff --git a/docs/tutorials/github/img/github-pat-permissions.png b/docs/images/providers/github-pat-permissions.png similarity index 100% rename from docs/tutorials/github/img/github-pat-permissions.png rename to docs/images/providers/github-pat-permissions.png diff --git a/docs/tutorials/microsoft365/img/global-reader-role.png b/docs/images/providers/global-reader-role.png similarity index 100% rename from docs/tutorials/microsoft365/img/global-reader-role.png rename to docs/images/providers/global-reader-role.png diff --git a/docs/tutorials/microsoft365/img/global-reader.png b/docs/images/providers/global-reader.png similarity index 100% rename from docs/tutorials/microsoft365/img/global-reader.png rename to docs/images/providers/global-reader.png diff --git a/docs/tutorials/microsoft365/img/grant-admin-consent-delegated.png b/docs/images/providers/grant-admin-consent-delegated.png similarity index 100% rename from docs/tutorials/microsoft365/img/grant-admin-consent-delegated.png rename to docs/images/providers/grant-admin-consent-delegated.png diff --git a/docs/tutorials/microsoft365/img/grant-admin-consent-for-role.png b/docs/images/providers/grant-admin-consent-for-role.png similarity index 100% rename from docs/tutorials/microsoft365/img/grant-admin-consent-for-role.png rename to docs/images/providers/grant-admin-consent-for-role.png diff --git a/docs/tutorials/microsoft365/img/grant-admin-consent.png b/docs/images/providers/grant-admin-consent.png similarity index 100% rename from docs/tutorials/microsoft365/img/grant-admin-consent.png rename to docs/images/providers/grant-admin-consent.png diff --git a/docs/tutorials/microsoft365/img/grant-external-api-permissions.png b/docs/images/providers/grant-external-api-permissions.png similarity index 100% rename from docs/tutorials/microsoft365/img/grant-external-api-permissions.png rename to docs/images/providers/grant-external-api-permissions.png diff --git a/docs/tutorials/microsoft365/img/here.png b/docs/images/providers/here.png similarity index 100% rename from docs/tutorials/microsoft365/img/here.png rename to docs/images/providers/here.png diff --git a/docs/images/providers/iac-authentication.png b/docs/images/providers/iac-authentication.png new file mode 100644 index 0000000000..c6caad4ae1 Binary files /dev/null and b/docs/images/providers/iac-authentication.png differ diff --git a/docs/images/providers/iac-verify-connection.png b/docs/images/providers/iac-verify-connection.png new file mode 100644 index 0000000000..bc918f6c24 Binary files /dev/null and b/docs/images/providers/iac-verify-connection.png differ diff --git a/docs/tutorials/azure/img/iam-azure-page.png b/docs/images/providers/iam-azure-page.png similarity index 100% rename from docs/tutorials/azure/img/iam-azure-page.png rename to docs/images/providers/iam-azure-page.png diff --git a/docs/images/providers/ip-access-list.png b/docs/images/providers/ip-access-list.png new file mode 100644 index 0000000000..43d407fd54 Binary files /dev/null and b/docs/images/providers/ip-access-list.png differ diff --git a/docs/tutorials/aws/img/launch-scan-button-prowler-cloud.png b/docs/images/providers/launch-scan-button-prowler-cloud.png similarity index 100% rename from docs/tutorials/aws/img/launch-scan-button-prowler-cloud.png rename to docs/images/providers/launch-scan-button-prowler-cloud.png diff --git a/docs/tutorials/microsoft365/img/launch-scan.png b/docs/images/providers/launch-scan.png similarity index 100% rename from docs/tutorials/microsoft365/img/launch-scan.png rename to docs/images/providers/launch-scan.png 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/m365-credentials.png b/docs/images/providers/m365-credentials.png new file mode 100644 index 0000000000..ab912f9d8e Binary files /dev/null and b/docs/images/providers/m365-credentials.png differ diff --git a/docs/tutorials/azure/img/member-select-app-prowler.png b/docs/images/providers/member-select-app-prowler.png similarity index 100% rename from docs/tutorials/azure/img/member-select-app-prowler.png rename to docs/images/providers/member-select-app-prowler.png diff --git a/docs/tutorials/microsoft365/img/microsoft-entra-id.png b/docs/images/providers/microsoft-entra-id.png similarity index 100% rename from docs/tutorials/microsoft365/img/microsoft-entra-id.png rename to docs/images/providers/microsoft-entra-id.png diff --git a/docs/tutorials/azure/img/microsoft-graph-detail.png b/docs/images/providers/microsoft-graph-detail.png similarity index 100% rename from docs/tutorials/azure/img/microsoft-graph-detail.png rename to docs/images/providers/microsoft-graph-detail.png diff --git a/docs/images/providers/modify-permission.png b/docs/images/providers/modify-permission.png new file mode 100644 index 0000000000..47d186aa1a Binary files /dev/null and b/docs/images/providers/modify-permission.png differ diff --git a/docs/tutorials/microsoft365/img/new-client-secret.png b/docs/images/providers/new-client-secret.png similarity index 100% rename from docs/tutorials/microsoft365/img/new-client-secret.png rename to docs/images/providers/new-client-secret.png diff --git a/docs/tutorials/microsoft365/img/new-registration.png b/docs/images/providers/new-registration.png similarity index 100% rename from docs/tutorials/microsoft365/img/new-registration.png rename to docs/images/providers/new-registration.png diff --git a/docs/tutorials/aws/img/next-button-prowler-cloud.png b/docs/images/providers/next-button-prowler-cloud.png similarity index 100% rename from docs/tutorials/aws/img/next-button-prowler-cloud.png rename to docs/images/providers/next-button-prowler-cloud.png diff --git a/docs/tutorials/aws/img/next-cloudformation-template.png b/docs/images/providers/next-cloudformation-template.png similarity index 100% rename from docs/tutorials/aws/img/next-cloudformation-template.png rename to docs/images/providers/next-cloudformation-template.png diff --git a/docs/tutorials/gcp/img/open-link-console.png b/docs/images/providers/open-link-console.png similarity index 100% rename from docs/tutorials/gcp/img/open-link-console.png rename to docs/images/providers/open-link-console.png diff --git a/docs/images/providers/organization-access.png b/docs/images/providers/organization-access.png new file mode 100644 index 0000000000..4a0a26e024 Binary files /dev/null and b/docs/images/providers/organization-access.png differ diff --git a/docs/tutorials/aws/img/paste-role-arn-prowler.png b/docs/images/providers/paste-role-arn-prowler.png similarity index 100% rename from docs/tutorials/aws/img/paste-role-arn-prowler.png rename to docs/images/providers/paste-role-arn-prowler.png diff --git a/docs/tutorials/azure/img/policy-permission.png b/docs/images/providers/policy-permission.png similarity index 100% rename from docs/tutorials/azure/img/policy-permission.png rename to docs/images/providers/policy-permission.png diff --git a/docs/tutorials/gcp/img/project-id-console.png b/docs/images/providers/project-id-console.png similarity index 100% rename from docs/tutorials/gcp/img/project-id-console.png rename to docs/images/providers/project-id-console.png diff --git a/docs/tutorials/azure/img/prowler-app-registration.png b/docs/images/providers/prowler-app-registration.png similarity index 100% rename from docs/tutorials/azure/img/prowler-app-registration.png rename to docs/images/providers/prowler-app-registration.png diff --git a/docs/tutorials/aws/img/prowler-cloud-credentials-next.png b/docs/images/providers/prowler-cloud-credentials-next.png similarity index 100% rename from docs/tutorials/aws/img/prowler-cloud-credentials-next.png rename to docs/images/providers/prowler-cloud-credentials-next.png diff --git a/docs/tutorials/aws/img/prowler-cloud-external-id.png b/docs/images/providers/prowler-cloud-external-id.png similarity index 100% rename from docs/tutorials/aws/img/prowler-cloud-external-id.png rename to docs/images/providers/prowler-cloud-external-id.png diff --git a/docs/tutorials/aws/img/prowler-scan-pre-info.png b/docs/images/providers/prowler-scan-pre-info.png similarity index 100% rename from docs/tutorials/aws/img/prowler-scan-pre-info.png rename to docs/images/providers/prowler-scan-pre-info.png diff --git a/docs/tutorials/aws/img/prowler-scan-role-template.png b/docs/images/providers/prowler-scan-role-template.png similarity index 100% rename from docs/tutorials/aws/img/prowler-scan-role-template.png rename to docs/images/providers/prowler-scan-role-template.png diff --git a/docs/tutorials/azure/img/review-and-assign-last-step.png b/docs/images/providers/review-and-assign-last-step.png similarity index 100% rename from docs/tutorials/azure/img/review-and-assign-last-step.png rename to docs/images/providers/review-and-assign-last-step.png diff --git a/docs/tutorials/azure/img/review-and-create.png b/docs/images/providers/review-and-create.png similarity index 100% rename from docs/tutorials/azure/img/review-and-create.png rename to docs/images/providers/review-and-create.png diff --git a/docs/tutorials/gcp/img/run-gcloud-auth.png b/docs/images/providers/run-gcloud-auth.png similarity index 100% rename from docs/tutorials/gcp/img/run-gcloud-auth.png rename to docs/images/providers/run-gcloud-auth.png diff --git a/docs/tutorials/microsoft365/img/search-default-domain.png b/docs/images/providers/search-default-domain.png similarity index 100% rename from docs/tutorials/microsoft365/img/search-default-domain.png rename to docs/images/providers/search-default-domain.png diff --git a/docs/tutorials/microsoft365/img/search-domain-names.png b/docs/images/providers/search-domain-names.png similarity index 100% rename from docs/tutorials/microsoft365/img/search-domain-names.png rename to docs/images/providers/search-domain-names.png diff --git a/docs/tutorials/microsoft365/img/search-exchange-api.png b/docs/images/providers/search-exchange-api.png similarity index 100% rename from docs/tutorials/microsoft365/img/search-exchange-api.png rename to docs/images/providers/search-exchange-api.png diff --git a/docs/tutorials/azure/img/search-microsoft-entra-id.png b/docs/images/providers/search-microsoft-entra-id.png similarity index 100% rename from docs/tutorials/azure/img/search-microsoft-entra-id.png rename to docs/images/providers/search-microsoft-entra-id.png diff --git a/docs/tutorials/microsoft365/img/search-skype-teams-tenant-admin-api.png b/docs/images/providers/search-skype-teams-tenant-admin-api.png similarity index 100% rename from docs/tutorials/microsoft365/img/search-skype-teams-tenant-admin-api.png rename to docs/images/providers/search-skype-teams-tenant-admin-api.png diff --git a/docs/tutorials/azure/img/search-subscriptions.png b/docs/images/providers/search-subscriptions.png similarity index 100% rename from docs/tutorials/azure/img/search-subscriptions.png rename to docs/images/providers/search-subscriptions.png 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/images/providers/select-auth-method.png b/docs/images/providers/select-auth-method.png new file mode 100644 index 0000000000..cab2c844ce Binary files /dev/null and b/docs/images/providers/select-auth-method.png differ diff --git a/docs/tutorials/aws/img/select-aws.png b/docs/images/providers/select-aws.png similarity index 100% rename from docs/tutorials/aws/img/select-aws.png rename to docs/images/providers/select-aws.png diff --git a/docs/tutorials/azure/img/select-azure-prowler-cloud.png b/docs/images/providers/select-azure-prowler-cloud.png similarity index 100% rename from docs/tutorials/azure/img/select-azure-prowler-cloud.png rename to docs/images/providers/select-azure-prowler-cloud.png diff --git a/docs/tutorials/azure/img/select-custom-role-prowler.png b/docs/images/providers/select-custom-role-prowler.png similarity index 100% rename from docs/tutorials/azure/img/select-custom-role-prowler.png rename to docs/images/providers/select-custom-role-prowler.png diff --git a/docs/tutorials/gcp/img/select-gcp.png b/docs/images/providers/select-gcp.png similarity index 100% rename from docs/tutorials/gcp/img/select-gcp.png rename to docs/images/providers/select-gcp.png diff --git a/docs/images/providers/select-github.png b/docs/images/providers/select-github.png new file mode 100644 index 0000000000..5208e658d0 Binary files /dev/null and b/docs/images/providers/select-github.png differ diff --git a/docs/images/providers/select-iac.png b/docs/images/providers/select-iac.png new file mode 100644 index 0000000000..1dc474cbe8 Binary files /dev/null and b/docs/images/providers/select-iac.png differ diff --git a/docs/tutorials/microsoft365/img/select-m365-prowler-cloud.png b/docs/images/providers/select-m365-prowler-cloud.png similarity index 100% rename from docs/tutorials/microsoft365/img/select-m365-prowler-cloud.png rename to docs/images/providers/select-m365-prowler-cloud.png diff --git a/docs/tutorials/azure/img/select-members-iam.png b/docs/images/providers/select-members-iam.png similarity index 100% rename from docs/tutorials/azure/img/select-members-iam.png rename to docs/images/providers/select-members-iam.png diff --git a/docs/tutorials/aws/img/stack-creation-second-step.png b/docs/images/providers/stack-creation-second-step.png similarity index 100% rename from docs/tutorials/aws/img/stack-creation-second-step.png rename to docs/images/providers/stack-creation-second-step.png diff --git a/docs/tutorials/aws/img/submit-third-page.png b/docs/images/providers/submit-third-page.png similarity index 100% rename from docs/tutorials/aws/img/submit-third-page.png rename to docs/images/providers/submit-third-page.png diff --git a/docs/tutorials/azure/img/subscription-page-azure.png b/docs/images/providers/subscription-page-azure.png similarity index 100% rename from docs/tutorials/azure/img/subscription-page-azure.png rename to docs/images/providers/subscription-page-azure.png diff --git a/docs/tutorials/gcp/img/take-account-email.png b/docs/images/providers/take-account-email.png similarity index 100% rename from docs/tutorials/gcp/img/take-account-email.png rename to docs/images/providers/take-account-email.png diff --git a/docs/tutorials/microsoft365/img/teams-permission.png b/docs/images/providers/teams-permission.png similarity index 100% rename from docs/tutorials/microsoft365/img/teams-permission.png rename to docs/images/providers/teams-permission.png diff --git a/docs/tutorials/aws/img/upload-template-file.png b/docs/images/providers/upload-template-file.png similarity index 100% rename from docs/tutorials/aws/img/upload-template-file.png rename to docs/images/providers/upload-template-file.png diff --git a/docs/tutorials/aws/img/upload-template-from-downloads.png b/docs/images/providers/upload-template-from-downloads.png similarity index 100% rename from docs/tutorials/aws/img/upload-template-from-downloads.png rename to docs/images/providers/upload-template-from-downloads.png diff --git a/docs/tutorials/microsoft365/img/user-domains.png b/docs/images/providers/user-domains.png similarity index 100% rename from docs/tutorials/microsoft365/img/user-domains.png rename to docs/images/providers/user-domains.png diff --git a/docs/tutorials/microsoft365/img/user-info-page.png b/docs/images/providers/user-info-page.png similarity index 100% rename from docs/tutorials/microsoft365/img/user-info-page.png rename to docs/images/providers/user-info-page.png diff --git a/docs/tutorials/azure/img/user-permission.png b/docs/images/providers/user-permission.png similarity index 100% rename from docs/tutorials/azure/img/user-permission.png rename to docs/images/providers/user-permission.png diff --git a/docs/tutorials/microsoft365/img/user-role-page.png b/docs/images/providers/user-role-page.png similarity index 100% rename from docs/tutorials/microsoft365/img/user-role-page.png rename to docs/images/providers/user-role-page.png diff --git a/docs/images/prowler-app/add-cloud-provider.png b/docs/images/prowler-app/add-cloud-provider.png new file mode 100644 index 0000000000..dd42e73047 Binary files /dev/null and b/docs/images/prowler-app/add-cloud-provider.png differ diff --git a/docs/images/prowler-app/bulk-provider-provisioning.png b/docs/images/prowler-app/bulk-provider-provisioning.png new file mode 100644 index 0000000000..c43c746874 Binary files /dev/null and b/docs/images/prowler-app/bulk-provider-provisioning.png differ diff --git a/docs/images/prowler-app/cloud-providers-page.png b/docs/images/prowler-app/cloud-providers-page.png new file mode 100644 index 0000000000..0581e0132f Binary files /dev/null and b/docs/images/prowler-app/cloud-providers-page.png differ diff --git a/docs/images/prowler-app/compliance/compliance-cis-sample1.png b/docs/images/prowler-app/compliance/compliance-cis-sample1.png new file mode 100644 index 0000000000..925e5c80f8 Binary files /dev/null and b/docs/images/prowler-app/compliance/compliance-cis-sample1.png differ diff --git a/docs/images/prowler-app/compliance/compliance.png b/docs/images/prowler-app/compliance/compliance.png new file mode 100644 index 0000000000..de5c27fbe3 Binary files /dev/null and b/docs/images/prowler-app/compliance/compliance.png differ diff --git a/docs/images/prowler-app/create-slack-app.png b/docs/images/prowler-app/create-slack-app.png new file mode 100644 index 0000000000..dc910634ec Binary files /dev/null and b/docs/images/prowler-app/create-slack-app.png differ diff --git a/docs/images/prowler-app/create-sp.gif b/docs/images/prowler-app/create-sp.gif new file mode 100644 index 0000000000..1ed345bb6a Binary files /dev/null and b/docs/images/prowler-app/create-sp.gif differ diff --git a/docs/images/prowler-app/dashboard/dashboard-banner.png b/docs/images/prowler-app/dashboard/dashboard-banner.png new file mode 100644 index 0000000000..3d6dc92304 Binary files /dev/null and b/docs/images/prowler-app/dashboard/dashboard-banner.png differ diff --git a/docs/images/prowler-app/dashboard/dashboard-compliance.png b/docs/images/prowler-app/dashboard/dashboard-compliance.png new file mode 100644 index 0000000000..95fb7179f9 Binary files /dev/null and b/docs/images/prowler-app/dashboard/dashboard-compliance.png differ diff --git a/docs/images/prowler-app/dashboard/dashboard-files-scanned.png b/docs/images/prowler-app/dashboard/dashboard-files-scanned.png new file mode 100644 index 0000000000..2629a8ac77 Binary files /dev/null and b/docs/images/prowler-app/dashboard/dashboard-files-scanned.png differ diff --git a/docs/images/prowler-app/dashboard/dashboard-overview.png b/docs/images/prowler-app/dashboard/dashboard-overview.png new file mode 100644 index 0000000000..a5a470cb0e Binary files /dev/null and b/docs/images/prowler-app/dashboard/dashboard-overview.png differ diff --git a/docs/images/prowler-app/dashboard/dropdown.png b/docs/images/prowler-app/dashboard/dropdown.png new file mode 100644 index 0000000000..b1df77798e Binary files /dev/null and b/docs/images/prowler-app/dashboard/dropdown.png differ diff --git a/docs/images/prowler-app/fixer.png b/docs/images/prowler-app/fixer.png new file mode 100644 index 0000000000..d794485454 Binary files /dev/null and b/docs/images/prowler-app/fixer.png differ diff --git a/docs/images/prowler-app/gcp-auth-methods.png b/docs/images/prowler-app/gcp-auth-methods.png new file mode 100644 index 0000000000..dc8681396e Binary files /dev/null and b/docs/images/prowler-app/gcp-auth-methods.png differ diff --git a/docs/images/prowler-app/gcp-service-account-creds.png b/docs/images/prowler-app/gcp-service-account-creds.png new file mode 100644 index 0000000000..af09776ab1 Binary files /dev/null and b/docs/images/prowler-app/gcp-service-account-creds.png differ diff --git a/docs/images/prowler-app/github-app-credentials.png b/docs/images/prowler-app/github-app-credentials.png new file mode 100644 index 0000000000..1a71db4fbd Binary files /dev/null and b/docs/images/prowler-app/github-app-credentials.png differ diff --git a/docs/images/prowler-app/github-auth-methods.png b/docs/images/prowler-app/github-auth-methods.png new file mode 100644 index 0000000000..17414054aa Binary files /dev/null and b/docs/images/prowler-app/github-auth-methods.png differ diff --git a/docs/images/prowler-app/github-oauth-credentials.png b/docs/images/prowler-app/github-oauth-credentials.png new file mode 100644 index 0000000000..5d84c4bf75 Binary files /dev/null and b/docs/images/prowler-app/github-oauth-credentials.png differ diff --git a/docs/images/prowler-app/github-pat-credentials.png b/docs/images/prowler-app/github-pat-credentials.png new file mode 100644 index 0000000000..044cbb7996 Binary files /dev/null and b/docs/images/prowler-app/github-pat-credentials.png differ diff --git a/docs/images/prowler-app/install-in-slack-workspace.png b/docs/images/prowler-app/install-in-slack-workspace.png new file mode 100644 index 0000000000..649c107cdd Binary files /dev/null and b/docs/images/prowler-app/install-in-slack-workspace.png differ diff --git a/docs/images/prowler-app/integrate-slack-app.png b/docs/images/prowler-app/integrate-slack-app.png new file mode 100644 index 0000000000..beea9ef56b Binary files /dev/null and b/docs/images/prowler-app/integrate-slack-app.png differ diff --git a/docs/images/prowler-app/jira/connection-settings.png b/docs/images/prowler-app/jira/connection-settings.png new file mode 100644 index 0000000000..86ebe73dea Binary files /dev/null and b/docs/images/prowler-app/jira/connection-settings.png differ diff --git a/docs/images/prowler-app/jira/integrations-tab.png b/docs/images/prowler-app/jira/integrations-tab.png new file mode 100644 index 0000000000..e71773fc52 Binary files /dev/null and b/docs/images/prowler-app/jira/integrations-tab.png differ diff --git a/docs/images/prowler-app/jira/send-to-jira-modal.png b/docs/images/prowler-app/jira/send-to-jira-modal.png new file mode 100644 index 0000000000..2cf498926a Binary files /dev/null and b/docs/images/prowler-app/jira/send-to-jira-modal.png differ diff --git a/docs/images/prowler-app/lighthouse-architecture.png b/docs/images/prowler-app/lighthouse-architecture.png new file mode 100644 index 0000000000..63202ce7c7 Binary files /dev/null and b/docs/images/prowler-app/lighthouse-architecture.png differ diff --git a/docs/images/prowler-app/lighthouse-config.png b/docs/images/prowler-app/lighthouse-config.png new file mode 100644 index 0000000000..8bae46f51b Binary files /dev/null and b/docs/images/prowler-app/lighthouse-config.png differ diff --git a/docs/images/prowler-app/lighthouse-feature1.png b/docs/images/prowler-app/lighthouse-feature1.png new file mode 100644 index 0000000000..4568f5752a Binary files /dev/null and b/docs/images/prowler-app/lighthouse-feature1.png differ diff --git a/docs/images/prowler-app/lighthouse-feature2.png b/docs/images/prowler-app/lighthouse-feature2.png new file mode 100644 index 0000000000..01e72bbaf4 Binary files /dev/null and b/docs/images/prowler-app/lighthouse-feature2.png differ diff --git a/docs/images/prowler-app/lighthouse-feature3.png b/docs/images/prowler-app/lighthouse-feature3.png new file mode 100644 index 0000000000..a40177cf18 Binary files /dev/null and b/docs/images/prowler-app/lighthouse-feature3.png differ diff --git a/docs/images/prowler-app/lighthouse-intro.png b/docs/images/prowler-app/lighthouse-intro.png new file mode 100644 index 0000000000..38d3f0819c Binary files /dev/null and b/docs/images/prowler-app/lighthouse-intro.png differ diff --git a/docs/images/prowler-app/mutelist-keys.png b/docs/images/prowler-app/mutelist-keys.png new file mode 100644 index 0000000000..0822344376 Binary files /dev/null and b/docs/images/prowler-app/mutelist-keys.png differ diff --git a/docs/images/prowler-app/mutelist-row.png b/docs/images/prowler-app/mutelist-row.png new file mode 100644 index 0000000000..0ed7d75a7d Binary files /dev/null and b/docs/images/prowler-app/mutelist-row.png differ diff --git a/docs/images/prowler-app/rbac/invitation_details.png b/docs/images/prowler-app/rbac/invitation_details.png new file mode 100644 index 0000000000..656a698308 Binary files /dev/null and b/docs/images/prowler-app/rbac/invitation_details.png differ diff --git a/docs/images/prowler-app/rbac/invitation_details_1.png b/docs/images/prowler-app/rbac/invitation_details_1.png new file mode 100644 index 0000000000..e167db74af Binary files /dev/null and b/docs/images/prowler-app/rbac/invitation_details_1.png differ diff --git a/docs/images/prowler-app/rbac/invitation_edit.png b/docs/images/prowler-app/rbac/invitation_edit.png new file mode 100644 index 0000000000..ef3d81f192 Binary files /dev/null and b/docs/images/prowler-app/rbac/invitation_edit.png differ diff --git a/docs/images/prowler-app/rbac/invitation_edit_1.png b/docs/images/prowler-app/rbac/invitation_edit_1.png new file mode 100644 index 0000000000..6d1a1d2223 Binary files /dev/null and b/docs/images/prowler-app/rbac/invitation_edit_1.png differ diff --git a/docs/images/prowler-app/rbac/invitation_info.png b/docs/images/prowler-app/rbac/invitation_info.png new file mode 100644 index 0000000000..a6ec05f976 Binary files /dev/null and b/docs/images/prowler-app/rbac/invitation_info.png differ diff --git a/docs/images/prowler-app/rbac/invitation_revoke.png b/docs/images/prowler-app/rbac/invitation_revoke.png new file mode 100644 index 0000000000..6c4e042c16 Binary files /dev/null and b/docs/images/prowler-app/rbac/invitation_revoke.png differ diff --git a/docs/images/prowler-app/rbac/invitation_sign-up.png b/docs/images/prowler-app/rbac/invitation_sign-up.png new file mode 100644 index 0000000000..f5b67a7762 Binary files /dev/null and b/docs/images/prowler-app/rbac/invitation_sign-up.png differ diff --git a/docs/images/prowler-app/rbac/invite.png b/docs/images/prowler-app/rbac/invite.png new file mode 100644 index 0000000000..dd60aba314 Binary files /dev/null and b/docs/images/prowler-app/rbac/invite.png differ diff --git a/docs/images/prowler-app/rbac/membership.png b/docs/images/prowler-app/rbac/membership.png new file mode 100644 index 0000000000..e2b96e40f5 Binary files /dev/null and b/docs/images/prowler-app/rbac/membership.png differ diff --git a/docs/images/prowler-app/rbac/provider_group.png b/docs/images/prowler-app/rbac/provider_group.png new file mode 100644 index 0000000000..878306e02f Binary files /dev/null and b/docs/images/prowler-app/rbac/provider_group.png differ diff --git a/docs/images/prowler-app/rbac/provider_group_edit.png b/docs/images/prowler-app/rbac/provider_group_edit.png new file mode 100644 index 0000000000..5de9649578 Binary files /dev/null and b/docs/images/prowler-app/rbac/provider_group_edit.png differ diff --git a/docs/images/prowler-app/rbac/provider_group_edit_1.png b/docs/images/prowler-app/rbac/provider_group_edit_1.png new file mode 100644 index 0000000000..ed4a090eed Binary files /dev/null and b/docs/images/prowler-app/rbac/provider_group_edit_1.png differ diff --git a/docs/images/prowler-app/rbac/provider_group_remove.png b/docs/images/prowler-app/rbac/provider_group_remove.png new file mode 100644 index 0000000000..580a8533cf Binary files /dev/null and b/docs/images/prowler-app/rbac/provider_group_remove.png differ diff --git a/docs/images/prowler-app/rbac/role_create.png b/docs/images/prowler-app/rbac/role_create.png new file mode 100644 index 0000000000..8dc270f209 Binary files /dev/null and b/docs/images/prowler-app/rbac/role_create.png differ diff --git a/docs/images/prowler-app/rbac/role_create_1.png b/docs/images/prowler-app/rbac/role_create_1.png new file mode 100644 index 0000000000..a96b0ac9ef Binary files /dev/null and b/docs/images/prowler-app/rbac/role_create_1.png differ diff --git a/docs/images/prowler-app/rbac/role_edit.png b/docs/images/prowler-app/rbac/role_edit.png new file mode 100644 index 0000000000..775b4b8562 Binary files /dev/null and b/docs/images/prowler-app/rbac/role_edit.png differ diff --git a/docs/images/prowler-app/rbac/role_edit_details.png b/docs/images/prowler-app/rbac/role_edit_details.png new file mode 100644 index 0000000000..6170f210b1 Binary files /dev/null and b/docs/images/prowler-app/rbac/role_edit_details.png differ diff --git a/docs/images/prowler-app/rbac/role_remove.png b/docs/images/prowler-app/rbac/role_remove.png new file mode 100644 index 0000000000..613f770bd4 Binary files /dev/null and b/docs/images/prowler-app/rbac/role_remove.png differ diff --git a/docs/images/prowler-app/rbac/user_edit.png b/docs/images/prowler-app/rbac/user_edit.png new file mode 100644 index 0000000000..421ea93156 Binary files /dev/null and b/docs/images/prowler-app/rbac/user_edit.png differ diff --git a/docs/images/prowler-app/rbac/user_edit_details.png b/docs/images/prowler-app/rbac/user_edit_details.png new file mode 100644 index 0000000000..3e4734f142 Binary files /dev/null and b/docs/images/prowler-app/rbac/user_edit_details.png differ diff --git a/docs/images/prowler-app/rbac/user_remove.png b/docs/images/prowler-app/rbac/user_remove.png new file mode 100644 index 0000000000..4c368ded66 Binary files /dev/null and b/docs/images/prowler-app/rbac/user_remove.png differ diff --git a/docs/images/prowler-app/reporting/html-output.png b/docs/images/prowler-app/reporting/html-output.png new file mode 100644 index 0000000000..00a8b60812 Binary files /dev/null and b/docs/images/prowler-app/reporting/html-output.png differ diff --git a/docs/images/prowler-app/s3/s3-cross-account.png b/docs/images/prowler-app/s3/s3-cross-account.png new file mode 100644 index 0000000000..ad34a303fc Binary files /dev/null and b/docs/images/prowler-app/s3/s3-cross-account.png differ diff --git a/docs/images/prowler-app/s3/s3-integration-ui-1.png b/docs/images/prowler-app/s3/s3-integration-ui-1.png new file mode 100644 index 0000000000..1081f20453 Binary files /dev/null and b/docs/images/prowler-app/s3/s3-integration-ui-1.png differ diff --git a/docs/images/prowler-app/s3/s3-integration-ui-2.png b/docs/images/prowler-app/s3/s3-integration-ui-2.png new file mode 100644 index 0000000000..618621ce26 Binary files /dev/null and b/docs/images/prowler-app/s3/s3-integration-ui-2.png differ diff --git a/docs/images/prowler-app/s3/s3-integration-ui-3.png b/docs/images/prowler-app/s3/s3-integration-ui-3.png new file mode 100644 index 0000000000..6fabbe2ed3 Binary files /dev/null and b/docs/images/prowler-app/s3/s3-integration-ui-3.png differ diff --git a/docs/images/prowler-app/s3/s3-integration-ui-4.png b/docs/images/prowler-app/s3/s3-integration-ui-4.png new file mode 100644 index 0000000000..1967eda8af Binary files /dev/null and b/docs/images/prowler-app/s3/s3-integration-ui-4.png differ diff --git a/docs/images/prowler-app/s3/s3-integration-ui-5.png b/docs/images/prowler-app/s3/s3-integration-ui-5.png new file mode 100644 index 0000000000..ffdea752f1 Binary files /dev/null and b/docs/images/prowler-app/s3/s3-integration-ui-5.png differ diff --git a/docs/images/prowler-app/s3/s3-integration-ui-6.png b/docs/images/prowler-app/s3/s3-integration-ui-6.png new file mode 100644 index 0000000000..330588e17b Binary files /dev/null and b/docs/images/prowler-app/s3/s3-integration-ui-6.png differ diff --git a/docs/images/prowler-app/s3/s3-integration-ui-7.png b/docs/images/prowler-app/s3/s3-integration-ui-7.png new file mode 100644 index 0000000000..3448f82a48 Binary files /dev/null and b/docs/images/prowler-app/s3/s3-integration-ui-7.png differ diff --git a/docs/images/prowler-app/s3/s3-multiple-accounts.png b/docs/images/prowler-app/s3/s3-multiple-accounts.png new file mode 100644 index 0000000000..db30e09841 Binary files /dev/null and b/docs/images/prowler-app/s3/s3-multiple-accounts.png differ diff --git a/docs/images/prowler-app/s3/s3-output-folder.png b/docs/images/prowler-app/s3/s3-output-folder.png new file mode 100644 index 0000000000..448687a8b1 Binary files /dev/null and b/docs/images/prowler-app/s3/s3-output-folder.png differ diff --git a/docs/images/prowler-app/s3/s3-same-account.png b/docs/images/prowler-app/s3/s3-same-account.png new file mode 100644 index 0000000000..39e586c762 Binary files /dev/null and b/docs/images/prowler-app/s3/s3-same-account.png differ diff --git a/docs/images/prowler-app/saml/app-catalog-browse-prowler-add.png b/docs/images/prowler-app/saml/app-catalog-browse-prowler-add.png new file mode 100644 index 0000000000..71c70bb7cd Binary files /dev/null and b/docs/images/prowler-app/saml/app-catalog-browse-prowler-add.png differ diff --git a/docs/images/prowler-app/saml/app-catalog-browse-prowler-configure.png b/docs/images/prowler-app/saml/app-catalog-browse-prowler-configure.png new file mode 100644 index 0000000000..6d5715eb92 Binary files /dev/null and b/docs/images/prowler-app/saml/app-catalog-browse-prowler-configure.png differ diff --git a/docs/images/prowler-app/saml/app-catalog-browse-prowler.png b/docs/images/prowler-app/saml/app-catalog-browse-prowler.png new file mode 100644 index 0000000000..5706997980 Binary files /dev/null and b/docs/images/prowler-app/saml/app-catalog-browse-prowler.png differ diff --git a/docs/images/prowler-app/saml/app-catalog-browse.png b/docs/images/prowler-app/saml/app-catalog-browse.png new file mode 100644 index 0000000000..d0a9b6926d Binary files /dev/null and b/docs/images/prowler-app/saml/app-catalog-browse.png differ diff --git a/docs/images/prowler-app/saml/idp_config.png b/docs/images/prowler-app/saml/idp_config.png new file mode 100644 index 0000000000..0665b34886 Binary files /dev/null and b/docs/images/prowler-app/saml/idp_config.png differ diff --git a/docs/images/prowler-app/saml/saml-signin-1.png b/docs/images/prowler-app/saml/saml-signin-1.png new file mode 100644 index 0000000000..5da2e84711 Binary files /dev/null and b/docs/images/prowler-app/saml/saml-signin-1.png differ diff --git a/docs/images/prowler-app/saml/saml-signin-2.png b/docs/images/prowler-app/saml/saml-signin-2.png new file mode 100644 index 0000000000..f0f7082fc9 Binary files /dev/null and b/docs/images/prowler-app/saml/saml-signin-2.png differ diff --git a/docs/images/prowler-app/saml/saml-sso-azure-1.png b/docs/images/prowler-app/saml/saml-sso-azure-1.png new file mode 100644 index 0000000000..c714d742e7 Binary files /dev/null and b/docs/images/prowler-app/saml/saml-sso-azure-1.png differ diff --git a/docs/images/prowler-app/saml/saml-sso-azure-2.png b/docs/images/prowler-app/saml/saml-sso-azure-2.png new file mode 100644 index 0000000000..483af4548c Binary files /dev/null and b/docs/images/prowler-app/saml/saml-sso-azure-2.png differ diff --git a/docs/images/prowler-app/saml/saml-sso-azure-3.png b/docs/images/prowler-app/saml/saml-sso-azure-3.png new file mode 100644 index 0000000000..7983694c5c Binary files /dev/null and b/docs/images/prowler-app/saml/saml-sso-azure-3.png differ diff --git a/docs/images/prowler-app/saml/saml-sso-azure-4.png b/docs/images/prowler-app/saml/saml-sso-azure-4.png new file mode 100644 index 0000000000..f6c6029343 Binary files /dev/null and b/docs/images/prowler-app/saml/saml-sso-azure-4.png differ diff --git a/docs/images/prowler-app/saml/saml-sso-azure-5.png b/docs/images/prowler-app/saml/saml-sso-azure-5.png new file mode 100644 index 0000000000..6dbeb6e65d Binary files /dev/null and b/docs/images/prowler-app/saml/saml-sso-azure-5.png differ diff --git a/docs/images/prowler-app/saml/saml-sso-azure-6.png b/docs/images/prowler-app/saml/saml-sso-azure-6.png new file mode 100644 index 0000000000..b351004a87 Binary files /dev/null and b/docs/images/prowler-app/saml/saml-sso-azure-6.png differ diff --git a/docs/images/prowler-app/saml/saml-sso-azure-7.png b/docs/images/prowler-app/saml/saml-sso-azure-7.png new file mode 100644 index 0000000000..76551bef06 Binary files /dev/null and b/docs/images/prowler-app/saml/saml-sso-azure-7.png differ diff --git a/docs/images/prowler-app/saml/saml-sso-azure-8.png b/docs/images/prowler-app/saml/saml-sso-azure-8.png new file mode 100644 index 0000000000..5dd2f1e1ef Binary files /dev/null and b/docs/images/prowler-app/saml/saml-sso-azure-8.png differ diff --git a/docs/images/prowler-app/saml/saml-sso-azure-9.png b/docs/images/prowler-app/saml/saml-sso-azure-9.png new file mode 100644 index 0000000000..130dd5e7cd Binary files /dev/null and b/docs/images/prowler-app/saml/saml-sso-azure-9.png differ diff --git a/docs/images/prowler-app/saml/saml-step-1.png b/docs/images/prowler-app/saml/saml-step-1.png new file mode 100644 index 0000000000..d505c2597c Binary files /dev/null and b/docs/images/prowler-app/saml/saml-step-1.png differ diff --git a/docs/images/prowler-app/saml/saml-step-2.png b/docs/images/prowler-app/saml/saml-step-2.png new file mode 100644 index 0000000000..ddb036c98d Binary files /dev/null and b/docs/images/prowler-app/saml/saml-step-2.png differ diff --git a/docs/images/prowler-app/saml/saml-step-3.png b/docs/images/prowler-app/saml/saml-step-3.png new file mode 100644 index 0000000000..2b8dfbd845 Binary files /dev/null and b/docs/images/prowler-app/saml/saml-step-3.png differ diff --git a/docs/images/prowler-app/saml/saml-step-4.png b/docs/images/prowler-app/saml/saml-step-4.png new file mode 100644 index 0000000000..cca0987c50 Binary files /dev/null and b/docs/images/prowler-app/saml/saml-step-4.png differ diff --git a/docs/images/prowler-app/saml/saml-step-remove.png b/docs/images/prowler-app/saml/saml-step-remove.png new file mode 100644 index 0000000000..f0868691af Binary files /dev/null and b/docs/images/prowler-app/saml/saml-step-remove.png differ diff --git a/docs/images/prowler-app/saml/saml_attribute_statements.png b/docs/images/prowler-app/saml/saml_attribute_statements.png new file mode 100644 index 0000000000..62d6366131 Binary files /dev/null and b/docs/images/prowler-app/saml/saml_attribute_statements.png differ diff --git a/docs/images/prowler-app/security-hub/create-integration.png b/docs/images/prowler-app/security-hub/create-integration.png new file mode 100644 index 0000000000..145e68d201 Binary files /dev/null and b/docs/images/prowler-app/security-hub/create-integration.png differ diff --git a/docs/images/prowler-app/security-hub/integration-settings.png b/docs/images/prowler-app/security-hub/integration-settings.png new file mode 100644 index 0000000000..3a32bf0830 Binary files /dev/null and b/docs/images/prowler-app/security-hub/integration-settings.png differ diff --git a/docs/images/prowler-app/security-hub/integrations-tab.png b/docs/images/prowler-app/security-hub/integrations-tab.png new file mode 100644 index 0000000000..9d11cae33a Binary files /dev/null and b/docs/images/prowler-app/security-hub/integrations-tab.png differ diff --git a/docs/images/prowler-app/slack-app-token.png b/docs/images/prowler-app/slack-app-token.png new file mode 100644 index 0000000000..550970503b Binary files /dev/null and b/docs/images/prowler-app/slack-app-token.png differ diff --git a/docs/images/prowler-app/slack-prowler-message.png b/docs/images/prowler-app/slack-prowler-message.png new file mode 100644 index 0000000000..1151a7be7f Binary files /dev/null and b/docs/images/prowler-app/slack-prowler-message.png differ diff --git a/docs/images/prowler-app/social-login/social_login_buttons.png b/docs/images/prowler-app/social-login/social_login_buttons.png new file mode 100644 index 0000000000..476081e0fc Binary files /dev/null and b/docs/images/prowler-app/social-login/social_login_buttons.png differ diff --git a/docs/images/prowler-app/social-login/social_login_buttons_disabled.png b/docs/images/prowler-app/social-login/social_login_buttons_disabled.png new file mode 100644 index 0000000000..7b11a7802d Binary files /dev/null and b/docs/images/prowler-app/social-login/social_login_buttons_disabled.png differ diff --git a/docs/images/prowler-cli-quick.gif b/docs/images/prowler-cli-quick.gif new file mode 100644 index 0000000000..16197a5ba7 Binary files /dev/null and b/docs/images/prowler-cli-quick.gif differ diff --git a/docs/images/prowler-logo-black.png b/docs/images/prowler-logo-black.png new file mode 100644 index 0000000000..3a6ed6490d Binary files /dev/null and b/docs/images/prowler-logo-black.png differ diff --git a/docs/images/prowler-logo-white.png b/docs/images/prowler-logo-white.png new file mode 100644 index 0000000000..b2d551f995 Binary files /dev/null and b/docs/images/prowler-logo-white.png differ diff --git a/docs/images/prowler-multi-account-environment.png b/docs/images/prowler-multi-account-environment.png new file mode 100644 index 0000000000..89adaf5f69 Binary files /dev/null and b/docs/images/prowler-multi-account-environment.png differ diff --git a/docs/images/prowler-single-account-environment.png b/docs/images/prowler-single-account-environment.png new file mode 100644 index 0000000000..585fe33a57 Binary files /dev/null and b/docs/images/prowler-single-account-environment.png differ diff --git a/docs/images/prowler_mcp_schema_dark.png b/docs/images/prowler_mcp_schema_dark.png new file mode 100644 index 0000000000..7771557601 Binary files /dev/null and b/docs/images/prowler_mcp_schema_dark.png differ diff --git a/docs/images/prowler_mcp_schema_light.png b/docs/images/prowler_mcp_schema_light.png new file mode 100644 index 0000000000..c542d84ed2 Binary files /dev/null and b/docs/images/prowler_mcp_schema_light.png differ diff --git a/docs/images/quick-inventory.jpg b/docs/images/quick-inventory.jpg new file mode 100644 index 0000000000..a7124bb7ae Binary files /dev/null and b/docs/images/quick-inventory.jpg differ diff --git a/docs/images/register-application.png b/docs/images/register-application.png new file mode 100644 index 0000000000..dd69291987 Binary files /dev/null and b/docs/images/register-application.png differ diff --git a/docs/images/scan-progress.png b/docs/images/scan-progress.png new file mode 100644 index 0000000000..3378775dcd Binary files /dev/null and b/docs/images/scan-progress.png differ diff --git a/docs/images/scan_jobs_section.png b/docs/images/scan_jobs_section.png new file mode 100644 index 0000000000..e307cf7f60 Binary files /dev/null and b/docs/images/scan_jobs_section.png differ diff --git a/docs/images/select-provider.png b/docs/images/select-provider.png new file mode 100644 index 0000000000..3151bfe5e7 Binary files /dev/null and b/docs/images/select-provider.png differ diff --git a/docs/images/sergio.png b/docs/images/sergio.png new file mode 100644 index 0000000000..d8d82846dc Binary files /dev/null and b/docs/images/sergio.png differ diff --git a/docs/images/services.png b/docs/images/services.png new file mode 100644 index 0000000000..e82a441576 Binary files /dev/null and b/docs/images/services.png differ diff --git a/docs/images/short-display.png b/docs/images/short-display.png new file mode 100644 index 0000000000..a36364acc0 Binary files /dev/null and b/docs/images/short-display.png differ diff --git a/docs/images/sign-up-button.png b/docs/images/sign-up-button.png new file mode 100644 index 0000000000..b7006e72e5 Binary files /dev/null and b/docs/images/sign-up-button.png differ diff --git a/docs/images/sign-up.png b/docs/images/sign-up.png new file mode 100644 index 0000000000..56e8901b24 Binary files /dev/null and b/docs/images/sign-up.png differ diff --git a/docs/images/sts-configuration.png b/docs/images/sts-configuration.png new file mode 100644 index 0000000000..cb78fbda74 Binary files /dev/null and b/docs/images/sts-configuration.png differ diff --git a/docs/images/test-connection-button.png b/docs/images/test-connection-button.png new file mode 100644 index 0000000000..261cb035c7 Binary files /dev/null and b/docs/images/test-connection-button.png differ diff --git a/docs/images/toni.png b/docs/images/toni.png new file mode 100644 index 0000000000..26b27d0a0f Binary files /dev/null and b/docs/images/toni.png differ diff --git a/docs/img/provider-decision-tree.png b/docs/img/provider-decision-tree.png new file mode 100644 index 0000000000..f76d375f94 Binary files /dev/null and b/docs/img/provider-decision-tree.png differ diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index eae09ba70b..0000000000 --- a/docs/index.md +++ /dev/null @@ -1,24 +0,0 @@ -# What is Prowler? - -**Prowler** is the open source cloud security platform trusted by thousands to **automate security and compliance** in any cloud environment. With hundreds of ready-to-use checks and compliance frameworks, Prowler delivers real-time, customizable monitoring and seamless integrations, making cloud security simple, scalable, and cost-effective for organizations of any size. - -The official supported providers right now are: - -- **AWS** -- **Azure** -- **Google Cloud** -- **Kubernetes** -- **M365** -- **Github** -- **IaC** - -Unofficially, Prowler supports: NHN. - -Prowler supports **auditing, incident response, continuous monitoring, hardening, forensic readiness, and remediation**. - -### Products - -- **Prowler CLI** (Command Line Interface) -- **Prowler App** (Web Application) -- [**Prowler Cloud**](https://cloud.prowler.com) – A managed service built on top of Prowler App. -- [**Prowler Hub**](https://hub.prowler.com) – A public library of versioned checks, cloud service artifacts, and compliance frameworks. diff --git a/docs/introduction.mdx b/docs/introduction.mdx new file mode 100644 index 0000000000..603bd1afbd --- /dev/null +++ b/docs/introduction.mdx @@ -0,0 +1,51 @@ +# What is Prowler? + +**Prowler** is the world’s most widely used open-source cloud security platform that **automates security and compliance** across any cloud environment. With hundreds of ready-to-use security checks, remediation guidance, and compliance frameworks, Prowler delivers AI-driven, customizable, and easy-to-use monitoring and integrations, making cloud security simple, scalable, and cost-effective for organizations of any size. + +![](/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/getting-started-k8s) | 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 | UI, API, CLI | +| [Infra as Code](/user-guide/providers/iac/getting-started-iac) | Official | UI, API, CLI | +| [MongoDB Atlas](/user-guide/providers/mongodbatlas/getting-started-mongodbatlas) | Official | CLI, API | +| [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? + + diff --git a/docs/security.md b/docs/security.mdx similarity index 99% rename from docs/security.md rename to docs/security.mdx index 9e7e4bd0ea..d8a3f63c73 100644 --- a/docs/security.md +++ b/docs/security.mdx @@ -1,4 +1,6 @@ -# Security +--- +title: 'Security' +--- ## Compliance and Trust We publish our live SOC 2 Type 2 Compliance data at [https://trust.prowler.com](https://trust.prowler.com) @@ -14,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/snippets/version-badge.mdx b/docs/snippets/version-badge.mdx new file mode 100644 index 0000000000..7541ff823a --- /dev/null +++ b/docs/snippets/version-badge.mdx @@ -0,0 +1,12 @@ +export const VersionBadge = ({ version }) => { + return ( + +

+ Added in:  + {version} +

+
+ + + ); +}; diff --git a/docs/style.css b/docs/style.css new file mode 100644 index 0000000000..3e9bedbc80 --- /dev/null +++ b/docs/style.css @@ -0,0 +1,51 @@ +/* Version Badge Styling */ +.version-badge-container { + display: inline-block; + margin: 0 0 1rem 0; + padding: 0; +} + +.version-badge { + display: inline-flex; + align-items: center; + margin: 0; + padding: 0.375rem 0.75rem; + background: linear-gradient(135deg, #1a1a1a 0%, #000000 100%); + color: #ffffff; + border-radius: 1.25rem; + font-weight: 400; + font-size: 0.875rem; + line-height: 1.25rem; + border: 1px solid rgba(0, 0, 0, 0.15); + box-shadow: none; +} + +.version-badge-label { + font-weight: 400; + opacity: 1; +} + +.version-badge-version { + background: rgba(255, 255, 255, 0.12); + padding: 0.125rem 0.5rem; + border-radius: 0.875rem; + font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace; + font-weight: 600; + font-size: 0.875rem; + color: #ffffff; + border: none; +} + + +.dark .version-badge { + background: #55B685; + color: #000000; + border: 2px solid rgba(85, 182, 133, 0.3); + box-shadow: none; + } + + .dark .version-badge-version { + background: rgba(0, 0, 0, 0.1); + color: #000000; + border: none; +} diff --git a/docs/troubleshooting.md b/docs/troubleshooting.mdx similarity index 94% rename from docs/troubleshooting.md rename to docs/troubleshooting.mdx index e5650723db..80b6590669 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.mdx @@ -1,4 +1,6 @@ -# Troubleshooting +--- +title: 'Troubleshooting' +--- - **Running `prowler` I get `[File: utils.py:15] [Module: utils] CRITICAL: path/redacted: OSError[13]`**: @@ -11,7 +13,7 @@ This error is also related with a lack of system requirements. To improve performance, Prowler stores information in memory so it may need to be run in a system with more than 1GB of memory. -See section [Logging](./tutorials/logging.md) for further information or [contact us](./contact.md). +See section [Logging](/user-guide/cli/tutorials/logging) for further information or [contact us](/contact). ## Common Issues with Docker Compose Installation diff --git a/docs/tutorials/aws/authentication.md b/docs/tutorials/aws/authentication.md deleted file mode 100644 index dbfc97eaa7..0000000000 --- a/docs/tutorials/aws/authentication.md +++ /dev/null @@ -1,49 +0,0 @@ -# AWS Authentication in Prowler - -Prowler requires AWS credentials to function properly. Authentication is available through the following methods: - -## Required Permissions -To ensure full functionality, attach the following AWS managed policies to the designated user or role: - -- `arn:aws:iam::aws:policy/SecurityAudit` -- `arn:aws:iam::aws:policy/job-function/ViewOnlyAccess` - -### Additional Permissions - -For certain checks, additional read-only permissions are required. Attach the following custom policy to your role: [prowler-additions-policy.json](https://github.com/prowler-cloud/prowler/blob/master/permissions/prowler-additions-policy.json) - - -## Configure AWS Credentials - -Use one of the following methods to authenticate: - -```console -aws configure -``` - -or - -```console -export AWS_ACCESS_KEY_ID="ASXXXXXXX" -export AWS_SECRET_ACCESS_KEY="XXXXXXXXX" -export AWS_SESSION_TOKEN="XXXXXXXXX" -``` - -These credentials must be associated with a user or role with the necessary permissions to perform security checks. - - - -## AWS Profiles - -Specify a custom AWS profile using the following command: - -```console -prowler aws -p/--profile -``` - -## Multi-Factor Authentication (MFA) - -For IAM entities requiring Multi-Factor Authentication (MFA), use the `--mfa` flag. Prowler prompts for the following values to initiate a new session: - -- **ARN of your MFA device** -- **TOTP (Time-Based One-Time Password)** diff --git a/docs/tutorials/aws/getting-started-aws.md b/docs/tutorials/aws/getting-started-aws.md deleted file mode 100644 index 88ecea3e95..0000000000 --- a/docs/tutorials/aws/getting-started-aws.md +++ /dev/null @@ -1,217 +0,0 @@ -# Getting Started with AWS on Prowler Cloud/App - - - -Set up your AWS account to enable security scanning using Prowler Cloud/App. - -## Requirements - -To configure your AWS account, you’ll need: - -1. Access to Prowler Cloud/App -2. Properly configured AWS credentials (either static or via an assumed IAM role) - ---- - -## Step 1: Get Your AWS Account ID - -1. Log in to the [AWS Console](https://console.aws.amazon.com) -2. Locate your AWS account ID in the top-right dropdown menu - -![Account ID detail](./img/aws-account-id.png) - ---- - -## Step 2: Access Prowler Cloud/App - -1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](../prowler-app.md) -2. Go to `Configuration` > `Cloud Providers` - - ![Cloud Providers Page](../img/cloud-providers-page.png) - -3. Click `Add Cloud Provider` - - ![Add a Cloud Provider](../img/add-cloud-provider.png) - -4. Select `Amazon Web Services` - - ![Select AWS Provider](./img/select-aws.png) - -5. Enter your AWS Account ID and optionally provide a friendly alias - - ![Add account ID](./img/add-account-id.png) - -6. Choose your preferred authentication method (next step) - - ![Select auth method](./img/select-auth-method.png) - ---- - -## Step 3: Set Up AWS Authentication - -Before proceeding, choose your preferred authentication mode: - -Credentials - -* Quick scan as current user āœ… -* No extra setup āœ… -* Credentials time out āŒ - -Assumed Role - -* Preferred Setup āœ… -* Permanent Credentials āœ… -* Requires access to create role āŒ - ---- - -### šŸ” Assume Role (Recommended) - -![Assume Role Overview](./img/assume-role-overview.png) - -This method grants permanent access and is the recommended setup for production environments. - -=== "CloudFormation" - - 1. Download the [Prowler Scan Role Template](https://raw.githubusercontent.com/prowler-cloud/prowler/refs/heads/master/permissions/templates/cloudformation/prowler-scan-role.yml) - - ![Prowler Scan Role Template](./img/prowler-scan-role-template.png) - - ![Download Role Template](./img/download-role-template.png) - - 2. Open the [AWS Console](https://console.aws.amazon.com), search for **CloudFormation** - - ![CloudFormation Search](./img/cloudformation-nav.png) - - 3. Go to **Stacks** and click `Create stack` > `With new resources (standard)` - - ![Create Stack](./img/create-stack.png) - - 4. In **Specify Template**, choose `Upload a template file` and select the downloaded file - - ![Upload a template file](./img/upload-template-file.png) - ![Upload file from downloads](./img/upload-template-from-downloads.png) - - 5. Click `Next`, provide a stack name and the **External ID** shown in the Prowler Cloud setup screen - - ![External ID](./img/prowler-cloud-external-id.png) - ![Stack Data](./img/fill-stack-data.png) - - !!! info - An **External ID** is required when assuming the *ProwlerScan* role to comply with AWS [confused deputy prevention](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html). - - 6. Acknowledge the IAM resource creation warning and proceed - - ![Stack Creation Second Step](./img/stack-creation-second-step.png) - - 7. Click `Submit` to deploy the stack - - ![Click on submit](./img/submit-third-page.png) - -=== "Terraform" - - To provision the scan role using Terraform: - - 1. Run the following commands: - - ```bash - terraform init - terraform plan - terraform apply - ``` - - 2. During `plan` and `apply`, you will be prompted for the **External ID**, which is available in the Prowler Cloud/App UI: - - ![Get External ID](./img/get-external-id-prowler-cloud.png) - - > šŸ’” Note: Terraform will use the AWS credentials of your default profile. - ---- - -### Finish Setup with Assume Role - -8. Once the role is created, go to the **IAM Console**, click on the `ProwlerScan` role to open its details: - - ![ProwlerScan role info](./img/prowler-scan-pre-info.png) - -9. Copy the **Role ARN** - - ![New Role Info](./img/get-role-arn.png) - -10. Paste the ARN into the corresponding field in Prowler Cloud/App - - ![Input the Role ARN](./img/paste-role-arn-prowler.png) - -11. Click `Next`, then `Launch Scan` - - ![Next button in Prowler Cloud](./img/next-button-prowler-cloud.png) - ![Launch Scan](./img/launch-scan-button-prowler-cloud.png) - ---- - -### šŸ”‘ Credentials (Static Access Keys) - -You can also configure your AWS account using static credentials (not recommended for long-term use): - -![Connect via credentials](./img/connect-via-credentials.png) - -=== "Long term credentials" - - 1. Go to the [AWS Console](https://console.aws.amazon.com), open **CloudShell** - - ![AWS CloudShell](./img/aws-cloudshell.png) - - 2. Run: - - ```bash - aws iam create-access-key - ``` - - 3. Copy the output containing: - - - `AccessKeyId` - - `SecretAccessKey` - - ![CloudShell Output](./img/cloudshell-output.png) - - > āš ļø Save these credentials securely and paste them into the Prowler Cloud/App setup screen. - -=== "Short term credentials (Recommended)" - - You can use your [AWS Access Portal](https://docs.aws.amazon.com/singlesignon/latest/userguide/howtogetcredentials.html) or the CLI: - - 1. Retrieve short-term credentials for the IAM identity using this command: - - ```bash - aws sts get-session-token --duration-seconds 900 - ``` - - ???+ note - Check the aws documentation [here](https://docs.aws.amazon.com/IAM/latest/UserGuide/sts_example_sts_GetSessionToken_section.html) - - 2. Copy the output containing: - - - `AccessKeyId` - - `SecretAccessKey` - - > Sample output: - ```json - { - "Credentials": { - "AccessKeyId": "ASIAIOSFODNN7EXAMPLE", - "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY", - "SessionToken": "AQoEXAMPLEH4aoAH0gNCAPyJxz4BlCFFxWNE1OPTgk5TthT+FvwqnKwRcOIfrRh3c/LTo6UDdyJwOOvEVPvLXCrrrUtdnniCEXAMPLE/IvU1dYUg2RVAJBanLiHb4IgRmpRV3zrkuWJOgQs8IZZaIv2BXIa2R4OlgkBN9bkUDNCJiBeb/AXlzBBko7b15fjrBs2+cTQtpZ3CYWFXG8C5zqx37wnOE49mRl/+OtkIKGO7fAE", - "Expiration": "2020-05-19T18:06:10+00:00" - } - } - ``` - - > āš ļø Save these credentials securely and paste them into the Prowler Cloud/App setup screen. - -Complete the form in Prowler Cloud/App and click `Next` - -![Filled credentials page](./img/prowler-cloud-credentials-next.png) - -Click `Launch Scan` - -![Launch Scan](./img/launch-scan-button-prowler-cloud.png) diff --git a/docs/tutorials/azure/authentication.md b/docs/tutorials/azure/authentication.md deleted file mode 100644 index 92f613fe16..0000000000 --- a/docs/tutorials/azure/authentication.md +++ /dev/null @@ -1,77 +0,0 @@ -# Azure Authentication in Prowler - -Prowler for Azure supports multiple authentication types. To use a specific method, pass the appropriate flag during execution: - -- [**Service Principal Application**](https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals?tabs=browser#service-principal-object) (**Recommended**) -- Existing **AZ CLI credentials** -- **Interactive browser authentication** -- [**Managed Identity**](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/overview) authentication - -> āš ļø **Important:** For Prowler App, only Service Principal authentication is supported. - -### Service Principal Application Authentication - -Enable Prowler authentication using a Service Principal Application by setting up the following environment variables: - -```console -export AZURE_CLIENT_ID="XXXXXXXXX" -export AZURE_TENANT_ID="XXXXXXXXX" -export AZURE_CLIENT_SECRET="XXXXXXX" -``` - -Execution with the `--sp-env-auth` flag fails if these variables are not set or exported. - -Refer to the [Create Prowler Service Principal](create-prowler-service-principal.md) guide for detailed setup instructions. - -### Azure Authentication Methods - -Prowler for Azure supports the following authentication methods: - -- **AZ CLI Authentication (`--az-cli-auth`)** – Automated authentication using stored AZ CLI credentials. -- **Managed Identity Authentication (`--managed-identity-auth`)** – Automated authentication via Azure Managed Identity. -- **Browser Authentication (`--browser-auth`)** – Requires the user to authenticate using the default browser. The `tenant-id` parameter is mandatory for this method. - -### Required Permissions - -Prowler for Azure requires two types of permission scopes: - -#### Microsoft Entra ID Permissions - -These permissions allow Prowler to retrieve metadata from the assumed identity and perform specific Entra checks. While not mandatory for execution, they enhance functionality. - -Required permissions: - -- `Directory.Read.All` -- `Policy.Read.All` -- `UserAuthenticationMethod.Read.All` (used for Entra multifactor authentication checks) - - ???+ note - Replace `Directory.Read.All` with `Domain.Read.All` for more restrictive permissions. Note that Entra checks related to DirectoryRoles and GetUsers will not run with this permission. - - -#### Subscription Scope Permissions - -These permissions are required to perform security checks against Azure resources. The following **RBAC roles** must be assigned per subscription to the entity used by Prowler: - -- `Reader` – Grants read-only access to Azure resources. -- `ProwlerRole` – A custom role with minimal permissions, defined in the [prowler-azure-custom-role](https://github.com/prowler-cloud/prowler/blob/master/permissions/prowler-azure-custom-role.json). - -???+ note - The `assignableScopes` field in the JSON custom role file must be updated to reflect the correct subscription or management group. Use one of the following formats: `/subscriptions/` or `/providers/Microsoft.Management/managementGroups/`. - -### Assigning Permissions - -To properly configure permissions, follow these guides: - -- [Microsoft Entra ID permissions](create-prowler-service-principal.md#assigning-proper-permissions) -- [Azure subscription permissions](subscriptions.md) - -???+ warning - Some permissions in `ProwlerRole` involve **write access**. If a `ReadOnly` lock is attached to certain resources, you may encounter errors, and findings for those checks will not be available. - -#### Checks Requiring `ProwlerRole` - -The following security checks require the `ProwlerRole` permissions for execution. Ensure the role is assigned to the identity assumed by Prowler before running these checks: - -- `app_function_access_keys_configured` -- `app_function_ftps_deployment_disabled` diff --git a/docs/tutorials/azure/create-prowler-service-principal.md b/docs/tutorials/azure/create-prowler-service-principal.md deleted file mode 100644 index 7ab6f58f43..0000000000 --- a/docs/tutorials/azure/create-prowler-service-principal.md +++ /dev/null @@ -1,100 +0,0 @@ -# Creating a Prowler Service Principal Application - -To enable Prowler to assume an identity for scanning with the required privileges, a Service Principal must be created. This Service Principal authenticates against Azure and retrieves necessary metadata for checks. - -### Methods for Creating a Service Principal - -Service Principal Applications can be created using either the Azure Portal or the Azure CLI. - -## Creating a Service Principal via Azure Portal / Entra Admin Center - -1. Access Microsoft Entra ID. -2. In the left menu bar, navigate to **"App registrations"**. -3. Click **"+ New registration"** in the menu bar to register a new application -4. Fill the **"Name"**, select the **"Supported account types"** and click **"Register"**. You will be redirected to the applications page. -5. In the left menu bar, select **"Certificates & secrets"**. -6. Under the **"Certificates & secrets"** view, click **"+ New client secret"**. -7. Fill the **"Description"** and **"Expires"** fields, then click **"Add"**. -8. Copy the secret value, as it will be used as `AZURE_CLIENT_SECRET` environment variable. - -![Registering an Application in Azure CLI for Prowler](../img/create-sp.gif) - -## From Azure CLI - -### Creating a Service Principal - -To create a Service Principal using the Azure CLI, follow these steps: - -1. Open a terminal and execute the following command: - - ```console - az ad sp create-for-rbac --name "ProwlerApp" - ``` - -2. The output will be similar to: - - ```json - { - "appId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", - "displayName": "ProwlerApp", - "password": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", - "tenant": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" - } - ``` - -3. Save the values of `appId`, `password` and `tenant`, as they will be used as credentials in Prowler. - -## Assigning Proper Permissions - -To allow Prowler to retrieve metadata from the assumed identity and run Entra checks, assign the following permissions: - -- `Directory.Read.All` -- `Policy.Read.All` -- `UserAuthenticationMethod.Read.All` (used only for the Entra checks related with multifactor authentication) - -Permissions can be assigned via the Azure Portal or the Azure CLI. - -???+ note - After creating and assigning the necessary Entra permissions, follow this [tutorial](../azure/subscriptions.md) to add subscription permissions to the application and start scanning your resources. - -### Assigning the Reader Role in Azure Portal - -1. Access Microsoft Entra ID. - -2. In the left menu bar, navigate to ā€œApp registrationsā€. - -3. Select the created application. - -4. In the left menu bar, select ā€œAPI permissionsā€. - -5. Click ā€œ+ Add a permissionā€ and select ā€œMicrosoft Graphā€. - -6. In the ā€œMicrosoft Graphā€ view, select ā€œApplication permissionsā€. - -7. Finally, search for "Directory", "Policy" and "UserAuthenticationMethod" select the following permissions: - - - `Domain.Read.All` - - - `Policy.Read.All` - - - `UserAuthenticationMethod.Read.All` - -8. Click ā€œAdd permissionsā€ to apply the new permissions. - -9. Finally, an admin must click ā€œGrant admin consent for \[your tenant]ā€ to apply the permissions. - -![Entra ID Permissions in Prowler](../../img/AAD-permissions.png) - -### From Azure CLI - -1. To grant permissions to a Service Principal, execute the following command in a terminal: - - ```console - az ad app permission add --id {appId} --api 00000003-0000-0000-c000-000000000000 --api-permissions 7ab1d382-f21e-4acd-a863-ba3e13f7da61=Role 246dd0d5-5bd0-4def-940b-0421030a5b68=Role 38d9df27-64da-44fd-b7c5-a6fbac20248f=Role - ``` - -2. Once the permissions are assigned, admin consent is required to finalize the changes. An administrator should run: - - ```console - az ad app permission admin-consent --id {appId} - ``` diff --git a/docs/tutorials/azure/getting-started-azure.md b/docs/tutorials/azure/getting-started-azure.md deleted file mode 100644 index 41cdabfd61..0000000000 --- a/docs/tutorials/azure/getting-started-azure.md +++ /dev/null @@ -1,174 +0,0 @@ -# Getting Started with Azure on Prowler Cloud/App - - - -Set up your Azure subscription to enable security scanning using Prowler Cloud/App. - -## Requirements - -To configure your Azure subscription, you’ll need: - -1. Get the `Subscription ID` -2. Access to Prowler Cloud/App -3. Configure authentication in Azure: - - 3.1 Create a Service Principal - - 3.2 Assign required permissions - - 3.3 Assign permissions at the subscription level - -4. Add the credentials to Prowler Cloud/App - ---- - -## Step 1: Get the Subscription ID - -1. Go to the [Azure Portal](https://portal.azure.com/#home) and search for `Subscriptions` -2. Locate and copy your Subscription ID - - ![Search Subscription](./img/search-subscriptions.png) - ![Subscriptions Page](./img/get-subscription-id.png) - ---- - -## Step 2: Access Prowler Cloud/App - -1. Go to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](../prowler-app.md) -2. Navigate to `Configuration` > `Cloud Providers` - - ![Cloud Providers Page](../img/cloud-providers-page.png) - -3. Click on `Add Cloud Provider` - - ![Add a Cloud Provider](../img/add-cloud-provider.png) - -4. Select `Microsoft Azure` - - ![Select Microsoft Azure](./img/select-azure-prowler-cloud.png) - -5. Add the Subscription ID and an optional alias, then click `Next` - - ![Add Subscription ID](./img/add-subscription-id.png) - ---- - -## Step 3: Configure the Azure Subscription - -### Create the Service Principal - -A Service Principal is required to grant Prowler the necessary privileges. - -1. Access **Microsoft Entra ID** - - ![Search Microsoft Entra ID](./img/search-microsoft-entra-id.png) - -2. Navigate to `Manage` > `App registrations` - - ![App Registration nav](./img/app-registration-menu.png) - -3. Click `+ New registration`, complete the form, and click `Register` - - ![New Registration](./img/new-registration.png) - -4. Go to `Certificates & secrets` > `+ New client secret` - - ![Certificate & Secrets nav](./img/certificates-and-secrets.png) - ![New Client Secret](./img/new-client-secret.png) - -5. Fill in the required fields and click `Add`, then copy the generated value - -| Value | Description | -|-------|-------------| -| Client ID | Application ID | -| Client Secret | AZURE_CLIENT_SECRET | -| Tenant ID | Azure Active Directory tenant ID | - ---- - -### Assign Required API Permissions - -Assign the following Microsoft Graph permissions: - -- Directory.Read.All - -- Policy.Read.All - -- UserAuthenticationMethod.Read.All (optional, for MFA checks) - -???+ note - You can replace `Directory.Read.All` with `Domain.Read.All` that is a more restrictive permission but you won't be able to run the Entra checks related with DirectoryRoles and GetUsers. - -1. Go to your App Registration > `API permissions` - - ![API Permission Page](./img/api-permissions-page.png) - -2. Click `+ Add a permission` > `Microsoft Graph` > `Application permissions` - - ![Add API Permission](./img/add-api-permission.png) - ![Microsoft Graph Detail](./img/microsoft-graph-detail.png) - -3. Search and select: - - - `Directory.Read.All` - - `Policy.Read.All` - - `UserAuthenticationMethod.Read.All` - - ![Permission Screenshots](./img/domain-permission.png) - -4. Click `Add permissions`, then grant admin consent - - ![Grant Admin Consent](./img/grant-admin-consent.png) - ---- - -### Assign Permissions at the Subscription Level - -1. Download the [Prowler Azure Custom Role](https://github.com/prowler-cloud/prowler/blob/master/permissions/prowler-azure-custom-role.json) - - ![Azure Custom Role](./img/download-prowler-role.png) - -2. Modify `assignableScopes` to match your Subscription ID (e.g. `/subscriptions/xxxx-xxxx-xxxx-xxxx`) - -3. Go to your Azure Subscription > `Access control (IAM)` - - ![IAM Page](./img/iam-azure-page.png) - -4. Click `+ Add` > `Add custom role`, choose "Start from JSON" and upload the modified file - - ![Add custom role via JSON](./img/add-custom-role-json.png) - -5. Click `Review + Create` to finish - - ![Select review and create](./img/review-and-create.png) - -6. Return to `Access control (IAM)` > `+ Add` > `Add role assignment` - - - Assign the `Reader` role to the Application created in the previous step - - Then repeat the same process assigning the custom `ProwlerRole` - - ![Role Assignment](./img/add-role-assigment.png) - ---- - -## Step 4: Add Credentials to Prowler Cloud/App - -1. Go to your App Registration overview and copy the `Client ID` and `Tenant ID` - - ![App Overview](./img/app-overview.png) - -2. Go to Prowler Cloud/App and paste: - - - `Client ID` - - `Tenant ID` - - `AZURE_CLIENT_SECRET` from earlier - - ![Prowler Cloud Azure Credentials](./img/add-credentials-azure-prowler-cloud.png) - -3. Click `Next` - - ![Next Detail](./img/click-next-azure.png) - -4. Click `Launch Scan` - - ![Launch Scan Azure](./img/launch-scan.png) diff --git a/docs/tutorials/azure/subscriptions.md b/docs/tutorials/azure/subscriptions.md deleted file mode 100644 index 50eac293e5..0000000000 --- a/docs/tutorials/azure/subscriptions.md +++ /dev/null @@ -1,159 +0,0 @@ -# Azure Subscription Scope - -Prowler performs security scans within the subscription scope in Azure. To execute checks, it requires appropriate permissions to access the subscription and retrieve necessary metadata. - -By default, Prowler operates multi-subscription, scanning all subscriptions it has permission to list. If permissions are granted for only a single subscription, Prowler will limit scans to that subscription. - -## Configuring Specific Subscription Scans in Prowler - -Additionally, Prowler supports restricting scans to specific subscriptions by passing a set of subscription IDs as an input argument. To configure this limitation, use the appropriate command options: - -```console -prowler azure --az-cli-auth --subscription-ids ... -``` - -Prowler allows you to specify one or more subscriptions for scanning (up to N), enabling flexible audit configurations. - -???+ warning - The multi-subscription feature is available only in the CLI. In Prowler App, each scan is limited to a single subscription. - -## Assigning Permissions for Subscription Scans - -To perform scans, ensure that the identity assumed by Prowler has the appropriate permissions. - -By default, Prowler scans all accessible subscriptions. If you need to audit specific subscriptions, you must assign the necessary role `Reader` for each one. For streamlined and less repetitive role assignments in multi-subscription environments, refer to the [following section](#recommendation-for-managing-multiple-subscriptions). - -### Assigning the Reader Role in Azure Portal - -1. To grant Prowler access to scan a specific Azure subscription, follow these steps in Azure Portal: -Navigate to the subscription you want to audit with Prowler. - -2. In the left menu, select ā€œAccess control (IAM)ā€. - -3. Click ā€œ+ Addā€ and select ā€œAdd role assignmentā€. - -4. In the search bar, enter `Reader`, select it and click ā€œNextā€. - -5. In the ā€œMembersā€ tab, click ā€œ+ Select membersā€, then add the accounts to assign this role. - -6. Click ā€œReview + assignā€ to finalize and apply the role assignment. - -![Adding the Reader Role to a Subscription](../../img/add-reader-role.gif) - -### From Azure CLI - -1. Open a terminal and execute the following command to assign the `Reader` role to the identity that is going to be assumed by Prowler: - - ```console - az role assignment create --role "Reader" --assignee --scope /subscriptions/ - ``` - -2. If the command is executed successfully, the output is going to be similar to the following: - - ```json - { - "condition": null, - "conditionVersion": null, - "createdBy": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", - "createdOn": "YYYY-MM-DDTHH:MM:SS.SSSSSS+00:00", - "delegatedManagedIdentityResourceId": null, - "description": null, - "id": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/providers/Microsoft.Authorization/roleAssignments/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", - "name": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", - "principalId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", - "principalName": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", - "principalType": "ServicePrincipal", - "roleDefinitionId": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/providers/Microsoft.Authorization/roleDefinitions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", - "roleDefinitionName": "Reader", - "scope": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", - "type": "Microsoft.Authorization/roleAssignments", - "updatedBy": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", - "updatedOn": "YYYY-MM-DDTHH:MM:SS.SSSSSS+00:00" - } - ``` - -### Prowler Custom Role - -Some read-only permissions required for specific security checks are not included in the built-in Reader role. To support these checks, Prowler utilizes a custom role, defined in [prowler-azure-custom-role](https://github.com/prowler-cloud/prowler/blob/master/permissions/prowler-azure-custom-role.json). Once created, this role can be assigned following the same process as the `Reader` role. - -The checks requiring this `ProwlerRole` can be found in this [section](../../tutorials/azure/authentication.md#checks-requiring-prowlerrole). - -#### Create ProwlerRole via Azure Portal - -1. Download the [prowler-azure-custom-role](https://github.com/prowler-cloud/prowler/blob/master/permissions/prowler-azure-custom-role.json) file and modify the `assignableScopes` field to match the target subscription. Example format: `/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX`. - -2. Access your Azure subscription. - -3. Select ā€œAccess control (IAM)ā€. - -4. Click ā€œ+ Addā€ and select ā€œAdd custom roleā€. - -5. Under ā€œBaseline permissionsā€, select ā€œStart from JSONā€ and upload the modified role file. - -6. Click ā€œReview + createā€ to finalize the role creation. - -#### Create ProwlerRole via Azure CLI - -1. To create a new custom role, open a terminal and execute the following command: - - ```console - az role definition create --role-definition '{ 640ms  lun 16 dic 17:04:17 2024 - "Name": "ProwlerRole", - "IsCustom": true, - "Description": "Role used for checks that require read-only access to Azure resources and are not covered by the Reader role.", - "AssignableScopes": [ - "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" // USE YOUR SUBSCRIPTION ID - ], - "Actions": [ - "Microsoft.Web/sites/host/listkeys/action", - "Microsoft.Web/sites/config/list/Action" - ] - }' - ``` - -2. If the command is executed successfully, the output is going to be similar to the following: - - ```json - { - "assignableScopes": [ - "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" - ], - "createdBy": null, - "createdOn": "YYYY-MM-DDTHH:MM:SS.SSSSSS+00:00", - "description": "Role used for checks that require read-only access to Azure resources and are not covered by the Reader role.", - "id": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/providers/Microsoft.Authorization/roleDefinitions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", - "name": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", - "permissions": [ - { - "actions": [ - "Microsoft.Web/sites/host/listkeys/action", - "Microsoft.Web/sites/config/list/Action" - ], - "condition": null, - "conditionVersion": null, - "dataActions": [], - "notActions": [], - "notDataActions": [] - } - ], - "roleName": "ProwlerRole", - "roleType": "CustomRole", - "type": "Microsoft.Authorization/roleDefinitions", - "updatedBy": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", - "updatedOn": "YYYY-MM-DDTHH:MM:SS.SSSSSS+00:00" - } - ``` - -## Recommendation for Managing Multiple Subscriptions - -Scanning multiple subscriptions requires creating and assigning roles for each, which can be a time-consuming process. To streamline subscription management and auditing, use management groups in Azure. This approach allows Prowler to efficiently organize and audit multiple subscriptions collectively. - -1. **Create a Management Group**: Follow the [official guide](https://learn.microsoft.com/en-us/azure/governance/management-groups/create-management-group-portal) to create a new management group. - - ![Create management group](../../img/create-management-group.gif) - -2. **Assign Roles**: Assign necessary roles to the management group, similar to the [role assignment process](#assigning-permissions-for-subscription-scans). - - Role assignment should be done at the management group level instead of per subscription. - -3. **Add Subscriptions**: Add all subscriptions you want to audit to the newly created management group. ![Add Subscription to Management Group](../../img/add-sub-to-management-group.gif) diff --git a/docs/tutorials/compliance.md b/docs/tutorials/compliance.md deleted file mode 100644 index 9d0f4a593a..0000000000 --- a/docs/tutorials/compliance.md +++ /dev/null @@ -1,158 +0,0 @@ -# Compliance - -Prowler allows you to execute checks based on requirements defined in compliance frameworks. By default, it will execute and give you an overview of the status of each compliance framework: - - - -You can find CSVs containing detailed compliance results in the compliance folder within Prowler's output folder. - -## Execute Prowler based on Compliance Frameworks - -Prowler can analyze your environment based on a specific compliance framework and get more details, to do it, you can use option `--compliance`: - -```sh -prowler --compliance -``` - -Standard results will be shown and additionally the framework information as the sample below for CIS AWS 2.0. For details a CSV file has been generated as well. - - - -???+ note - **If Prowler can't find a resource related with a check from a compliance requirement, this requirement won't appear on the output** - -##Ā List Available Compliance Frameworks - -In order to see which compliance frameworks are covered by Prowler, you can use option `--list-compliance`: - -```sh -prowler --list-compliance -``` - -### AWS (36 frameworks) - -- `aws_account_security_onboarding_aws` -- `aws_audit_manager_control_tower_guardrails_aws` -- `aws_foundational_security_best_practices_aws` -- `aws_foundational_technical_review_aws` -- `aws_well_architected_framework_reliability_pillar_aws` -- `aws_well_architected_framework_security_pillar_aws` -- `cis_1.4_aws` -- `cis_1.5_aws` -- `cis_2.0_aws` -- `cis_3.0_aws` -- `cis_4.0_aws` -- `cis_5.0_aws` -- `cisa_aws` -- `ens_rd2022_aws` -- `fedramp_low_revision_4_aws` -- `fedramp_moderate_revision_4_aws` -- `ffiec_aws` -- `gdpr_aws` -- `gxp_21_cfr_part_11_aws` -- `gxp_eu_annex_11_aws` -- `hipaa_aws` -- `iso27001_2013_aws` -- `iso27001_2022_aws` -- `kisa_isms_p_2023_aws` -- `kisa_isms_p_2023_korean_aws` -- `mitre_attack_aws` -- `nis2_aws` -- `nist_800_171_revision_2_aws` -- `nist_800_53_revision_4_aws` -- `nist_800_53_revision_5_aws` -- `nist_csf_1.1_aws` -- `pci_3.2.1_aws` -- `pci_4.0_aws` -- `prowler_threatscore_aws` -- `rbi_cyber_security_framework_aws` -- `soc2_aws` - -### Azure (10 frameworks) - -- `cis_2.0_azure` -- `cis_2.1_azure` -- `cis_3.0_azure` -- `ens_rd2022_azure` -- `iso27001_2022_azure` -- `mitre_attack_azure` -- `nis2_azure` -- `pci_4.0_azure` -- `prowler_threatscore_azure` -- `soc2_azure` - -### GCP (10 frameworks) - -- `cis_2.0_gcp` -- `cis_3.0_gcp` -- `cis_4.0_gcp` -- `ens_rd2022_gcp` -- `iso27001_2022_gcp` -- `mitre_attack_gcp` -- `nis2_gcp` -- `pci_4.0_gcp` -- `prowler_threatscore_gcp` -- `soc2_gcp` - -### Kubernetes (5 frameworks) - -- `cis_1.10_kubernetes` -- `cis_1.11_kubernetes` -- `cis_1.8_kubernetes` -- `iso27001_2022_kubernetes` -- `pci_4.0_kubernetes` - -### M365 (3 frameworks) - -- `cis_4.0_m365` -- `iso27001_2022_m365` -- `prowler_threatscore_m365` - -### GitHub (1 framework) - -- `cis_1.0_github` - -##Ā List Requirements of Compliance Frameworks -For each compliance framework, you can use the `--list-compliance-requirements` option to list its requirements: - -```sh -prowler --list-compliance-requirements -``` - -Example for the first requirements of CIS 1.5 for AWS: - -``` -Listing CIS 1.5 AWS Compliance Requirements: - -Requirement Id: 1.1 - - Description: Maintain current contact details - - Checks: - account_maintain_current_contact_details - -Requirement Id: 1.2 - - Description: Ensure security contact information is registered - - Checks: - account_security_contact_information_is_registered - -Requirement Id: 1.3 - - Description: Ensure security questions are registered in the AWS account - - Checks: - account_security_questions_are_registered_in_the_aws_account - -Requirement Id: 1.4 - - Description: Ensure no 'root' user account access key exists - - Checks: - iam_no_root_access_key - -Requirement Id: 1.5 - - Description: Ensure MFA is enabled for the 'root' user account - - Checks: - iam_root_mfa_enabled - -[redacted] - -``` - -## Create and contribute adding other Security Frameworks - -This information is part of the Developer Guide and can be found [here](../developer-guide/security-compliance-framework.md). diff --git a/docs/tutorials/gcp/authentication.md b/docs/tutorials/gcp/authentication.md deleted file mode 100644 index 5b8ec7b92a..0000000000 --- a/docs/tutorials/gcp/authentication.md +++ /dev/null @@ -1,83 +0,0 @@ -# GCP Authentication in Prowler - -## Required Permissions - -Prowler for Google Cloud requires the following permissions: - -### IAM Roles -- **Reader (`roles/reader`)** – Must be granted at the **project, folder, or organization** level to allow scanning of target projects. - -### Project-Level Settings - -At least one project must have the following configurations: - -- **Identity and Access Management (IAM) API (`iam.googleapis.com`)** – Must be enabled via: - - - The [Google Cloud API UI](https://console.cloud.google.com/apis/api/iam.googleapis.com/metrics), or - - The `gcloud` CLI: - ```sh - gcloud services enable iam.googleapis.com --project - ``` - -- **Service Usage Consumer (`roles/serviceusage.serviceUsageConsumer`)** IAM Role – Required for resource scanning. - -- **Quota Project Setting** – Define a quota project using either: - - - The `gcloud` CLI: - ```sh - gcloud auth application-default set-quota-project - ``` - - Setting an environment variable: - ```sh - export GOOGLE_CLOUD_QUOTA_PROJECT= - ``` - -???+ note - `prowler` will scan the GCP project associated with the credentials. - -## Credentials lookup order - -Prowler follows the same credential search process as [Google authentication libraries](https://cloud.google.com/docs/authentication/application-default-credentials#search_order), checking credentials in this order: - -1. [`GOOGLE_APPLICATION_CREDENTIALS` environment variable](https://cloud.google.com/docs/authentication/application-default-credentials#GAC) -2. [`CLOUDSDK_AUTH_ACCESS_TOKEN` + optional `GOOGLE_CLOUD_PROJECT`](https://cloud.google.com/sdk/gcloud/reference/auth/print-access-token) -3. [User credentials set up by using the Google Cloud CLI](https://cloud.google.com/docs/authentication/application-default-credentials#personal) -4. [Attached service account (e.g., Cloud Run, GCE, Cloud Functions)](https://cloud.google.com/docs/authentication/application-default-credentials#attached-sa) - -???+ note - The credentials must belong to a user or service account with the necessary permissions. - To ensure full access, assign the roles/reader IAM role to the identity being used. - -???+ note - Prowler will use the enabled Google Cloud APIs to get the information needed to perform the checks. - - - - -## Using an Access Token - -For existing access tokens (e.g., generated with `gcloud auth print-access-token`), run Prowler with: - -```bash -export CLOUDSDK_AUTH_ACCESS_TOKEN=$(gcloud auth print-access-token) -prowler gcp --project-ids -``` - -???+ note - When using this method, also set the default project explicitly: - ```bash - export GOOGLE_CLOUD_PROJECT= - ``` - - - - -## Impersonating a GCP Service Account - -To impersonate a GCP service account, use the `--impersonate-service-account` argument followed by the service account email: - -```console -prowler gcp --impersonate-service-account -``` - -This command leverages the default credentials to impersonate the specified service account. diff --git a/docs/tutorials/gcp/getting-started-gcp.md b/docs/tutorials/gcp/getting-started-gcp.md deleted file mode 100644 index ea34f293e8..0000000000 --- a/docs/tutorials/gcp/getting-started-gcp.md +++ /dev/null @@ -1,105 +0,0 @@ -# Getting Started with GCP on Prowler Cloud/App - -Set up your GCP project to enable security scanning using Prowler Cloud/App. - -## Requirements - -To configure your GCP project, you’ll need: - -1. Get the `Project ID` -2. Access to Prowler Cloud/App -3. Configure authentication in GCP: - - 3.1 Retrieve credentials from Google Cloud - -4. Add the credentials to Prowler Cloud/App - ---- - -## Step 1: Get the Project ID - -1. Go to the [GCP Console](https://console.cloud.google.com/) -2. Locate your Project ID on the welcome screen - -![Get the Project ID](./img/project-id-console.png) - ---- - -## Step 2: Access Prowler Cloud/App - -1. Go to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](../prowler-app.md) -2. Navigate to `Configuration` > `Cloud Providers` - - ![Cloud Providers Page](../img/cloud-providers-page.png) - -3. Click `Add Cloud Provider` - - ![Add a Cloud Provider](../img/add-cloud-provider.png) - -4. Select `Google Cloud Platform` - - ![Select GCP](./img/select-gcp.png) - -5. Add the Project ID and optionally provide a provider alias, then click `Next` - - ![Add Project ID](./img/add-project-id.png) - ---- - -## Step 3: Configure Authentication in GCP - -### Retrieve Credentials from Google Cloud - -1. In the [GCP Console](https://console.cloud.google.com/), click on `Activate Cloud Shell` - - ![Activate Cloud Shell](./img/access-console.png) - -2. Click `Authorize Cloud Shell` - - ![Authorize Cloud Shell](./img/authorize-cloud-shell.png) - -3. Run the following command: - - ```bash - gcloud auth application-default login - ``` - - - Type `Y` when prompted - - ![Run Gcloud Auth](./img/run-gcloud-auth.png) - -4. Open the authentication URL provided in a browser and select your Google account - - ![Choose the account](./img/take-account-email.png) - -5. Follow the steps to obtain the authentication code - - ![Copy auth code](./img/copy-auth-code.png) - -6. Paste the authentication code back in Cloud Shell - - ![Enter Auth Code](./img/enter-auth-code.png) - -7. Use `cat ` to view the temporary credentials file - - ![Get the FileName](./img/get-temp-file-credentials.png) - -8. Extract the following values for Prowler Cloud/App: - - - `client_id` - - `client_secret` - - `refresh_token` - - ![Get the values](./img/get-needed-values-auth.png) - ---- - -## Step 4: Add Credentials to Prowler Cloud/App - -1. Go back to Prowler Cloud/App and enter the required credentials, then click `Next` - - ![Enter the Credentials](./img/enter-credentials-prowler-cloud.png) - -2. Click `Launch Scan` to begin scanning your GCP environment - - ![Launch Scan GCP](./img/launch-scan.png) diff --git a/docs/tutorials/gcp/organization.md b/docs/tutorials/gcp/organization.md deleted file mode 100644 index 96c7406711..0000000000 --- a/docs/tutorials/gcp/organization.md +++ /dev/null @@ -1,23 +0,0 @@ -# Scanning a Specific GCP Organization - -By default, Prowler scans all Google Cloud projects accessible to the authenticated user. - -To limit the scan to projects within a specific Google Cloud organization, use the `--organization-id` option with the GCP organization’s ID: - -```console -prowler gcp --organization-id organization-id -``` - -???+ warning - Ensure the credentials used have one of the following roles at the organization level: - Cloud Asset Viewer (`roles/cloudasset.viewer`), or Cloud Asset Owner (`roles/cloudasset.owner`). - -???+ note - With this option, Prowler retrieves all projects under the specified Google Cloud organization, including those organized within folders and nested subfolders. This ensures full visibility across the entire organization’s hierarchy. - -???+ note - To obtain the Google Cloud organization ID, use: - - ```console - gcloud organizations list - ``` diff --git a/docs/tutorials/github/authentication.md b/docs/tutorials/github/authentication.md deleted file mode 100644 index adb26be402..0000000000 --- a/docs/tutorials/github/authentication.md +++ /dev/null @@ -1,47 +0,0 @@ -# Github Authentication in Prowler - -Prowler supports multiple methods to [authenticate with GitHub](https://docs.github.com/en/rest/authentication/authenticating-to-the-rest-api). These include: - -- **Personal Access Token (PAT)** -- **OAuth App Token** -- **GitHub App Credentials** - -This flexibility enables scanning and analysis of GitHub accounts, including repositories, organizations, and applications, using the method that best suits the use case. - -## Supported Login Methods - -Here are the available login methods and their respective flags: - -### Personal Access Token (PAT) - -Use this method by providing your personal access token directly. - -```console -prowler github --personal-access-token pat -``` - -### OAuth App Token - -Authenticate using an OAuth app token. - -```console -prowler github --oauth-app-token oauth_token -``` - -### GitHub App Credentials -Use GitHub App credentials by specifying the App ID and the private key path. - -```console -prowler github --github-app-id app_id --github-app-key-path app_key_path -``` - -### Automatic Login Method Detection - -If no login method is explicitly provided, Prowler will automatically attempt to authenticate using environment variables in the following order of precedence: - -1. `GITHUB_PERSONAL_ACCESS_TOKEN` -2. `GITHUB_OAUTH_APP_TOKEN` -3. `GITHUB_APP_ID` and `GITHUB_APP_KEY` (where the key is the content of the private key file) - -???+ note - Ensure the corresponding environment variables are set up before running Prowler for automatic detection when not specifying the login method. diff --git a/docs/tutorials/iac/getting-started-iac.md b/docs/tutorials/iac/getting-started-iac.md deleted file mode 100644 index 4dac4eea56..0000000000 --- a/docs/tutorials/iac/getting-started-iac.md +++ /dev/null @@ -1,88 +0,0 @@ -# Getting Started with the IaC Provider - -Prowler's Infrastructure as Code (IaC) provider enables you to scan local or remote infrastructure code for security and compliance issues using [Trivy](https://trivy.dev/). This provider supports a wide range of IaC frameworks, allowing you to assess your code before deployment. - -## Supported Scanners - -The IaC provider leverages Trivy to support multiple scanners, including: - -- Vulnerability -- Misconfiguration -- Secret -- License - -## How It Works - -- The IaC provider scans your local directory (or a specified path) for supported IaC files, or scan a remote repository. -- No cloud credentials or authentication are required for local scans. -- For remote repository scans, authentication can be provided via [git URL](https://git-scm.com/docs/git-clone#_git_urls), CLI flags or environment variables. -- Mutelist logic is handled by Trivy, not Prowler. -- Results are output in the same formats as other Prowler providers (CSV, JSON, HTML, etc.). - -## Usage - -To run Prowler with the IaC provider, use the `iac` argument. You can specify the directory or repository to scan, frameworks to include, and paths to exclude. - -### Scan a Local Directory (default) - -```sh -prowler iac --scan-path ./my-iac-directory -``` - -### Scan a Remote GitHub Repository - -```sh -prowler iac --scan-repository-url https://github.com/user/repo.git -``` - -#### Authentication for Remote Private Repositories - -You can provide authentication for private repositories using one of the following methods: - -- **GitHub Username and Personal Access Token (PAT):** - ```sh - prowler iac --scan-repository-url https://github.com/user/repo.git \ - --github-username --personal-access-token - ``` -- **GitHub OAuth App Token:** - ```sh - prowler iac --scan-repository-url https://github.com/user/repo.git \ - --oauth-app-token - ``` -- If not provided via CLI, the following environment variables will be used (in order of precedence): - - `GITHUB_OAUTH_APP_TOKEN` - - `GITHUB_USERNAME` and `GITHUB_PERSONAL_ACCESS_TOKEN` -- If neither CLI flags nor environment variables are set, the scan will attempt to clone without authentication or using the provided in the [git URL](https://git-scm.com/docs/git-clone#_git_urls). - -#### Mutually Exclusive Flags -- `--scan-path` and `--scan-repository-url` are mutually exclusive. Only one can be specified at a time. - -### Specify Scanners - -Scan only vulnerability and misconfiguration scanners: - -```sh -prowler iac --scan-path ./my-iac-directory --scanners vuln misconfig -``` - -### Exclude Paths - -```sh -prowler iac --scan-path ./my-iac-directory --exclude-path ./my-iac-directory/test,./my-iac-directory/examples -``` - -## Output - -You can use the standard Prowler output options, for example: - -```sh -prowler iac --scan-path ./iac --output-formats csv json html -``` - -## Notes - -- The IaC provider does not require cloud authentication for local scans. -- For remote repository scans, authentication is optional but required for private repos. -- CLI flags override environment variables for authentication. -- It is ideal for CI/CD pipelines and local development environments. -- For more details on supported scanners, see the [Trivy documentation](https://trivy.dev/latest/docs/scanner/vulnerability/). diff --git a/docs/tutorials/kubernetes/in-cluster.md b/docs/tutorials/kubernetes/in-cluster.md deleted file mode 100644 index ac645c0010..0000000000 --- a/docs/tutorials/kubernetes/in-cluster.md +++ /dev/null @@ -1,38 +0,0 @@ -# In-Cluster Execution - -For in-cluster execution, use the supplied yaml files inside `/kubernetes`: - -* [prowler-sa.yaml](https://github.com/prowler-cloud/prowler/blob/master/kubernetes/prowler-sa.yaml) -* [job.yaml](https://github.com/prowler-cloud/prowler/blob/master/kubernetes/job.yaml) -* [prowler-role.yaml](https://github.com/prowler-cloud/prowler/blob/master/kubernetes/prowler-role.yaml) -* [prowler-rolebinding.yaml](https://github.com/prowler-cloud/prowler/blob/master/kubernetes/prowler-rolebinding.yaml) - -They can be used to run Prowler as a job within a new Prowler namespace: - -```console -kubectl apply -f kubernetes/prowler-sa.yaml -kubectl apply -f kubernetes/job.yaml -kubectl apply -f kubernetes/prowler-role.yaml -kubectl apply -f kubernetes/prowler-rolebinding.yaml -kubectl get pods --namespace prowler-ns --> prowler-XXXXX -kubectl logs prowler-XXXXX --namespace prowler-ns -``` - -???+ note - By default, `prowler` will scan all namespaces in your active Kubernetes context. Use the [`--namespace`](https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/kubernetes/namespace/) flag to specify the namespace(s) to be scanned. - -???+ tip "Identifying the cluster in reports" - When running in in-cluster mode, the Kubernetes API does not expose the actual cluster name by default. - - To uniquely identify the cluster in logs and reports, you can: - - - Use the `--cluster-name` flag to manually set the cluster name: - ```bash - prowler -p kubernetes --cluster-name production-cluster - ``` - - Or set the `CLUSTER_NAME` environment variable: - ```yaml - env: - - name: CLUSTER_NAME - value: production-cluster - ``` diff --git a/docs/tutorials/kubernetes/outside-cluster.md b/docs/tutorials/kubernetes/outside-cluster.md deleted file mode 100644 index 5a8f15ac92..0000000000 --- a/docs/tutorials/kubernetes/outside-cluster.md +++ /dev/null @@ -1,16 +0,0 @@ -# Non In-Cluster Execution - -For execution outside the cluster environment, specify the location of the [kubeconfig](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) file using the following argument: - -```console -prowler kubernetes --kubeconfig-file /path/to/kubeconfig -``` - -???+ note - If no `--kubeconfig-file` is provided, Prowler will use the default KubeConfig file location (`~/.kube/config`). - -???+ note - `prowler` will scan the active Kubernetes context by default. Use the [`--context`](https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/kubernetes/context/) flag to specify the context to be scanned. - -???+ note - By default, `prowler` will scan all namespaces in your active Kubernetes context. Use the [`--namespace`](https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/kubernetes/namespace/) flag to specify the namespace(s) to be scanned. diff --git a/docs/tutorials/microsoft365/authentication.md b/docs/tutorials/microsoft365/authentication.md deleted file mode 100644 index c8f78c1c78..0000000000 --- a/docs/tutorials/microsoft365/authentication.md +++ /dev/null @@ -1,361 +0,0 @@ -# Microsoft 365 Authentication for Prowler - -Prowler for Microsoft 365 (M365) supports the following authentication methods: - -- [**Service Principal Application**](https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals?tabs=browser#service-principal-object) (**Recommended**) -- **Service Principal Application with Microsoft User Credentials** -- **Stored AZ CLI credentials** -- **Interactive browser authentication** - -???+ warning - Prowler App supports the **Service Principal** authentication method and the **Service Principal with User Credentials** authentication method, but this last one will be deprecated in September once Microsoft will enforce MFA in all tenants not allowing User authentication without interactive method. - -### Service Principal Authentication (Recommended) - -**Authentication flag:** `--sp-env-auth` - -Enable Prowler authentication as the **Service Principal Application** by configuring the following environment variables: - -```console -export AZURE_CLIENT_ID="XXXXXXXXX" -export AZURE_CLIENT_SECRET="XXXXXXXXX" -export AZURE_TENANT_ID="XXXXXXXXX" -``` - -If these variables are not set or exported, execution using `--sp-env-auth` will fail. - -Refer to the [Create Prowler Service Principal](getting-started-m365.md#create-the-service-principal-app) guide for setup instructions. - -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. - -???+ note - In order to scan all the checks from M365 required permissions to the service principal application must be added. Refer to the [External API Permissions Assignment](getting-started-m365.md#grant-powershell-modules-permissions) section for more information. - -### Service Principal and User Credentials Authentication - -Authentication flag: `--env-auth` - -???+ warning - This method is not recommended anymore, we recommend just use the **Service Principal Application** authentication method instead. - -This method builds upon the Service Principal authentication by adding User Credentials. Configure the following environment variables: `M365_USER` and `M365_PASSWORD`. - -```console -export AZURE_CLIENT_ID="XXXXXXXXX" -export AZURE_CLIENT_SECRET="XXXXXXXXX" -export AZURE_TENANT_ID="XXXXXXXXX" -export M365_USER="your_email@example.com" -export M365_PASSWORD="examplepassword" -``` - -These two new environment variables are **required** in this authentication method to execute the PowerShell modules needed to retrieve information from M365 services. Prowler uses Service Principal authentication to access Microsoft Graph and user credentials to authenticate to Microsoft PowerShell modules. - -- `M365_USER` should be your Microsoft account email using the **assigned domain in the tenant**. This means it must look like `example@YourCompany.onmicrosoft.com` or `example@YourCompany.com`, but it must be the exact domain assigned to that user in the tenant. - - ???+ warning - Newly created users must sign in with the account first, as Microsoft prompts for password change. Without completing this step, user authentication fails because Microsoft marks the initial password as expired. - - ???+ warning - The user must not be MFA capable. Microsoft does not allow MFA capable users to authenticate programmatically. See [Microsoft documentation](https://learn.microsoft.com/en-us/entra/identity-platform/scenario-desktop-acquire-token-username-password?tabs=dotnet) for more information. - - ???+ warning - Using a tenant domain other than the one assigned — even if it belongs to the same tenant — will cause Prowler to fail, as Microsoft authentication will not succeed. - - Ensure the correct domain is used for the authenticating user. - - ![User Domains](img/user-domains.png) - -- `M365_PASSWORD` must be the user password. - - ???+ note - Previously an encrypted password was required, but now the user password is accepted directly. Prowler handles the password encryption. - - - -### Interactive Browser Authentication - -**Authentication flag:** `--browser-auth` - -This authentication method requires authentication against Azure using the default browser to start the scan. The `--tenant-id` flag is also required. - -These credentials only enable checks that rely on Microsoft Graph. The entire provider cannot be run with this method. To perform a full M365 security scan, use the **recommended authentication method**. - -Since this is a **delegated permission** authentication method, necessary permissions should be assigned to the user rather than the application. - -### 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 (`--sp-env-auth`) - Recommended - -When using service principal authentication, add the following **Application Permissions**: - -**Microsoft Graph API 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. -- `User.Read` (IMPORTANT: this must be set as **delegated**): Required for the sign-in. - -**External API Permissions:** - -- `Exchange.ManageAsApp` from external API `Office 365 Exchange Online`: Required for Exchange PowerShell module app authentication. You also need to assign the `Global Reader` role to the app. -- `application_access` from external API `Skype and Teams Tenant Admin API`: Required for Teams PowerShell module app authentication. - -???+ note - `Directory.Read.All` can be replaced with `Domain.Read.All` that is a more restrictive permission but you won't be able to run the Entra checks related with DirectoryRoles and GetUsers. - - > If you do this you will need to add also the `Organization.Read.All` permission to the service principal application in order to authenticate. - -???+ note - This is the **recommended authentication method** because it allows you to run the full M365 provider including PowerShell checks, providing complete coverage of all available security checks, same as the Service Principal Authentication + User Credentials Authentication but this last one will be deprecated in September once Microsoft will enforce MFA in all tenants not allowing User authentication without interactive method. - - -#### Service Principal + User Credentials Authentication (`--env-auth`) - -When using service principal with user credentials authentication, you need **both** sets of permissions: - -**1. Service Principal Application Permissions**: -- You **will need** all the Microsoft Graph API permissions listed above. -- You **won't need** the External API permissions listed above. - -**2. User-Level Permissions**: These are set at the `M365_USER` level, so the user used to run Prowler must have one of the following roles: - -- `Global Reader` (recommended): this allows you to read all roles needed. -- `Exchange Administrator` and `Teams Administrator`: user needs both roles but with this [roles](https://learn.microsoft.com/en-us/exchange/permissions-exo/permissions-exo#microsoft-365-permissions-in-exchange-online) you can access to the same information as a Global Reader (since only read access is needed, Global Reader is recommended). - - -#### Browser Authentication (`--browser-auth`) - -When using browser authentication, permissions are delegated to the user, so the user must have the appropriate permissions rather than the application. - -???+ warning - With browser authentication, you will only be able to run checks that work through MS Graph API. PowerShell module checks will not be executed. - -### Assigning Permissions and Roles - -For guidance on assigning the necessary permissions and roles, follow these instructions: -- [Grant API Permissions](getting-started-m365.md#grant-required-graph-api-permissions) -- [Assign Required Roles](getting-started-m365.md#if-using-user-authentication) - -### Supported PowerShell Versions - -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? - -- **PowerShell 5.1** (default on some Windows systems) does not support required cmdlets. -- Older [cross-platform PowerShell versions](https://learn.microsoft.com/en-us/powershell/scripting/install/powershell-support-lifecycle?view=powershell-7.5) are **unsupported**, leading to potential errors. - -???+ note - Installing PowerShell is only necessary if you install Prowler via **pip or other sources**. **SDK and API containers include PowerShell by default.** - -### Installing PowerShell - -Installing PowerShell is different depending on your OS. - -- [Windows](https://learn.microsoft.com/es-es/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.5#install-powershell-using-winget-recommended): you will need to update PowerShell to +7.4 to be able to run prowler, if not some checks will not show findings and the provider could not work as expected. This version of PowerShell is [supported](https://learn.microsoft.com/es-es/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.4#supported-versions-of-windows) on Windows 10, Windows 11, Windows Server 2016 and higher versions. - -```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 you have it is just running the command above, Pwsh is only supported in macOS 15 (Sequoia) x64 and Arm64, macOS 14 (Sonoma) x64 and Arm64, macOS 13 (Ventura) x64 and Arm64 - -```console -brew install powershell/tap/powershell -``` - -Once it's installed run `pwsh` on your terminal to verify it's working. - -- Linux: installing PowerShell on Linux depends on the distro you are using: - - - [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. The recommended way to install it is downloading the package available on PMC. You just need to follow the following steps: - - ```console - ################################### - # Prerequisites - - # Update the list of packages - sudo apt-get update - - # Install pre-requisite packages. - sudo apt-get install -y wget apt-transport-https software-properties-common - - # Get the version of Ubuntu - source /etc/os-release - - # Download the Microsoft repository keys - wget -q https://packages.microsoft.com/config/ubuntu/$VERSION_ID/packages-microsoft-prod.deb - - # Register the Microsoft repository keys - sudo dpkg -i packages-microsoft-prod.deb - - # Delete the Microsoft repository keys file - rm packages-microsoft-prod.deb - - # Update the list of packages after we added packages.microsoft.com - sudo apt-get update - - ################################### - # Install PowerShell - sudo apt-get install -y powershell - - # 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). You just need to follow the following steps: - - ```console - # Install the requirements - sudo apk add --no-cache \ - ca-certificates \ - less \ - ncurses-terminfo-base \ - krb5-libs \ - libgcc \ - libintl \ - libssl3 \ - libstdc++ \ - tzdata \ - userspace-rcu \ - zlib \ - icu-libs \ - curl - - apk -X https://dl-cdn.alpinelinux.org/alpine/edge/main add --no-cache \ - lttng-ust \ - openssh-client \ - - # Download the powershell '.tar.gz' archive - curl -L https://github.com/PowerShell/PowerShell/releases/download/v7.5.0/powershell-7.5.0-linux-musl-x64.tar.gz -o /tmp/powershell.tar.gz - - # Create the target folder where powershell will be placed - sudo mkdir -p /opt/microsoft/powershell/7 - - # Expand powershell to the target folder - sudo tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7 - - # Set execute permissions - sudo chmod +x /opt/microsoft/powershell/7/pwsh - - # Create the symbolic link that points to pwsh - sudo ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh - - # 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. You just need to follow the following steps: - - ```console - ################################### - # Prerequisites - - # Update the list of packages - sudo apt-get update - - # Install pre-requisite packages. - sudo apt-get install -y wget - - # Get the version of Debian - source /etc/os-release - - # Download the Microsoft repository GPG keys - wget -q https://packages.microsoft.com/config/debian/$VERSION_ID/packages-microsoft-prod.deb - - # Register the Microsoft repository GPG keys - sudo dpkg -i packages-microsoft-prod.deb - - # Delete the Microsoft repository GPG keys file - rm packages-microsoft-prod.deb - - # Update the list of packages after we added packages.microsoft.com - sudo apt-get update - - ################################### - # Install PowerShell - sudo apt-get install -y powershell - - # 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. You just need to follow the following steps: - - ```console - ################################### - # Prerequisites - - # Get version of RHEL - source /etc/os-release - if [ ${VERSION_ID%.*} -lt 8 ] - then majorver=7 - elif [ ${VERSION_ID%.*} -lt 9 ] - then majorver=8 - else majorver=9 - fi - - # Download the Microsoft RedHat repository package - curl -sSL -O https://packages.microsoft.com/config/rhel/$majorver/packages-microsoft-prod.rpm - - # Register the Microsoft RedHat repository - sudo rpm -i packages-microsoft-prod.rpm - - # Delete the downloaded package after installing - rm packages-microsoft-prod.rpm - - # Update package index files - sudo dnf update - # 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: - - ```console - docker pull mcr.microsoft.com/dotnet/sdk:9.0 - ``` - - To start an interactive shell of Pwsh you just need to run: - - ```console - docker run -it mcr.microsoft.com/dotnet/sdk:9.0 pwsh - ``` - -### Required PowerShell Modules - -Prowler relies on several PowerShell cmdlets to retrieve necessary data. -These cmdlets come from different modules that must be installed. - -#### Automatic Installation - -The required modules are automatically installed when running Prowler with the `--init-modules` flag. - -Example command: - -```console -python3 prowler-cli.py m365 --verbose --log-level ERROR --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. - -???+ note - Prowler installs the modules using `-Scope CurrentUser`. - If you encounter any issues with services not working after the automatic installation, try installing the modules manually using `-Scope AllUsers` (administrator permissions are required for this). - The command needed to install a module manually is: - ```powershell - Install-Module -Name "ModuleName" -Scope AllUsers -Force - ``` - -#### Modules Version - -- [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/tutorials/microsoft365/getting-started-m365.md b/docs/tutorials/microsoft365/getting-started-m365.md deleted file mode 100644 index 988f58a1b5..0000000000 --- a/docs/tutorials/microsoft365/getting-started-m365.md +++ /dev/null @@ -1,272 +0,0 @@ -# Getting Started with M365 on Prowler Cloud/App - -Set up your M365 account to enable security scanning using Prowler Cloud/App. - -## Requirements - -To configure your M365 account, you'll need: - -1. Obtain a domain from the Entra ID portal. - -2. Access Prowler Cloud/App and add a new cloud provider `Microsoft 365`. - -3. Configure your M365 account: - - 3.1 Create the Service Principal app. - - 3.2 Grant the required API permissions. - - 3.3 Assign the required roles to your user. - -4. Add the credentials to Prowler Cloud/App. - -## Step 1: Obtain your Domain - -Go to the Entra ID portal, then you can search for `Domain` or go to Identity > Settings > Domain Names. - -![Search Domain Names](./img/search-domain-names.png) - -
- -![Custom Domain Names](./img/custom-domain-names.png) - -Once you are there just select the domain you want to use as unique identifier for your M365 account in Prowler Cloud/App. - ---- - -## Step 2: Access Prowler Cloud/App - -1. Go to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](../prowler-app.md) -2. Navigate to `Configuration` > `Cloud Providers` - - ![Cloud Providers Page](../img/cloud-providers-page.png) - -3. Click on `Add Cloud Provider` - - ![Add a Cloud Provider](../img/add-cloud-provider.png) - -4. Select `Microsoft 365` - - ![Select Microsoft 365](./img/select-m365-prowler-cloud.png) - -5. Add the Domain ID and an optional alias, then click `Next` - - ![Add Domain ID](./img/add-domain-id.png) - ---- - -## Step 3: Configure your M365 account - - -### Create the Service Principal app - -A Service Principal is required to grant Prowler the necessary privileges. - -1. Access **Microsoft Entra ID** - - ![Overview of Microsoft Entra ID](./img/microsoft-entra-id.png) - -2. Navigate to `Applications` > `App registrations` - - ![App Registration nav](./img/app-registration-menu.png) - -3. Click `+ New registration`, complete the form, and click `Register` - - ![New Registration](./img/new-registration.png) - -4. Go to `Certificates & secrets` > `Client secrets` > `+ New client secret` - - ![Certificate & Secrets nav](./img/certificates-and-secrets.png) - -5. Fill in the required fields and click `Add`, then copy the generated `value` (that value will be `AZURE_CLIENT_SECRET`) - - ![New Client Secret](./img/new-client-secret.png) - -With this done you will have all the needed keys, summarized in the following table - -| Value | Description | -|-------|-------------| -| Client ID | Application (client) ID | -| Client Secret | AZURE_CLIENT_SECRET | -| Tenant ID | Directory (tenant) ID | - ---- - -### Grant required Graph API permissions - -Assign the following Microsoft Graph 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. -- `User.Read` (IMPORTANT: this is set as **delegated**): Required for the sign-in only if using user authentication. - -???+ note - You can replace `Directory.Read.All` with `Domain.Read.All` is a more restrictive permission but you won't be able to run the Entra checks related with DirectoryRoles and GetUsers. - - > If you do this you will need to add also the `Organization.Read.All` permission to the service principal application in order to authenticate. - -Follow these steps to assign the permissions: - -1. Go to your App Registration > Select your Prowler App created before > click on `API permissions` - - ![API Permission Page](./img/api-permissions-page.png) - -2. Click `+ Add a permission` > `Microsoft Graph` > `Application permissions` - - ![Add API Permission](./img/add-app-api-permission.png) - -3. Search and select every permission below and once all are selected click on `Add permissions`: - - `AuditLog.Read.All`: Required for Entra service. - - `Directory.Read.All` - - `Policy.Read.All` - - `SharePointTenantSettings.Read.All` - - - ![Permission Screenshots](./img/directory-permission.png) - - ![Application Permissions](./img/app-permissions.png) - ---- - - -### Grant PowerShell modules permissions - -The permissions you need to grant depends on whether you are using user credentials or service principal to authenticate to the M365 modules. - -???+ warning "Warning" - Make sure you add the correct set of permissions for the authentication method you are using. - - -#### If using application(service principal) authentication (Recommended) - -To grant the permissions for the PowerShell modules via application authentication, you need to add the necessary APIs to your app registration. All of this assignments are done through Entra ID. - -???+ warning "Warning" - You need to have a license that allows you to use the APIs. - -1. Add Exchange API: - - - Search and select`Office 365 Exchange Online` API in **APIs my organization uses**. - - ![Office 365 Exchange Online API](./img/search-exchange-api.png) - - - Select `Exchange.ManageAsApp` permission and click on `Add permissions`. - - ![Exchange.ManageAsApp Permission](./img/exchange-permission.png) - - You also need to assign the `Global Reader` role to the app. For that go to `Roles and administrators` and in the `Administrative roles` section click `here` to go to the directory level assignment: - - ![Roles and administrators](./img/here.png) - - Once in the directory level assignment, search for `Global Reader` and click on it to open the assginments page of that role. - - ![Global Reader Role](./img/global-reader-role.png) - - Click on `Add assignments`, search for your app and click on `Assign`. - - You have to select it as `Active` and click on `Assign` to assign the role to the app. - - ![Assign Global Reader Role](./img/assign-global-reader-role.png) - - For more information about the need of adding this role, see [Microsoft documentation](https://learn.microsoft.com/en-us/powershell/exchange/app-only-auth-powershell-v2?view=exchange-ps#step-5-assign-microsoft-entra-roles-to-the-application). You can select any other role of the specified. - -2. Add Teams API: - - - Search and select `Skype and Teams Tenant Admin API` API in **APIs my organization uses**. - - ![Skype and Teams Tenant Admin API](./img/search-skype-teams-tenant-admin-api.png) - - - Select `application_access` permission and click on `Add permissions`. - - ![application_access Permission](./img/teams-permission.png) - -3. Click on `Grant admin consent for ` to grant admin consent. - - ![Grant Admin Consent](./img/grant-external-api-permissions.png) - - The final result of permission assignment should be this: - - ![Final Permission Assignment](./img/final-permissions.png) - ---- - -#### If using user authentication - -This method is not recommended because it requires a user with MFA enabled and Microsoft will not allow MFA capable users to authenticate programmatically after 1st September 2025. See [Microsoft documentation](https://learn.microsoft.com/en-us/entra/identity/authentication/concept-mandatory-multifactor-authentication?tabs=dotnet) for more information. - -???+ warning - Remember that if the user is newly created, you need to sign in with that account first, as Microsoft will prompt you to change the password. If you don’t complete this step, user authentication will fail because Microsoft marks the initial password as expired. - - -1. Search and select: - - - `User.Read` - - ![Permission Screenshots](./img/directory-permission-delegated.png) - -2. Click `Add permissions`, then **grant admin consent** - - ![Grant Admin Consent](./img/grant-admin-consent.png) - - The final result of permission assignment should be this: - - ![Final Permission Assignment](./img/final-permissions-m365.png) - -3. Assign **required roles** to your **user** - - Assign one of the following roles to your User: - - - `Global Reader` (recommended): this allows you to read all roles needed. - - `Exchange Administrator` and `Teams Administrator`: user needs both roles but with this [roles](https://learn.microsoft.com/en-us/exchange/permissions-exo/permissions-exo#microsoft-365-permissions-in-exchange-online) you can access to the same information as a Global Reader (here you only read so that's why we recomend that role). - - Follow these steps to assign the role: - - 1. Go to Users > All Users > Click on the email for the user you will use - - ![User Overview](./img/user-info-page.png) - - 2. Click `Assigned Roles` - - ![User Roles](./img/user-role-page.png) - - 3. Click on `Add assignments`, then search and select: - - - `Global Reader` This is the recommended, if you want to use the others just search for them - - ![Global Reader Screenshots](./img/global-reader.png) - - 4. Click on next, then assign the role as `Active`, and click on `Assign` to grant admin consent - - ![Grant Admin Consent for Role](./img/grant-admin-consent-for-role.png) - ---- - -## Step 4: Add credentials to Prowler Cloud/App - -1. Go to your App Registration overview and copy the `Client ID` and `Tenant ID` - - ![App Overview](./img/app-overview.png) - - -2. Go to Prowler Cloud/App and paste: - - - `Client ID` - - `Tenant ID` - - `AZURE_CLIENT_SECRET` from earlier - - If you are using user authentication, also add: - - - `M365_USER` the user using the correct assigned domain, more info [here](../../tutorials/microsoft365/authentication.md#service-principal-and-user-credentials-authentication) - - `M365_PASSWORD` the password of the user - - ![Prowler Cloud M365 Credentials](./img/m365-credentials.png) - -3. Click `Next` - - ![Next Detail](./img/click-next-m365.png) - -4. Click `Launch Scan` - - ![Launch Scan M365](./img/launch-scan.png) diff --git a/docs/tutorials/prowler-app.md b/docs/tutorials/prowler-app.md deleted file mode 100644 index 8eca5cbf73..0000000000 --- a/docs/tutorials/prowler-app.md +++ /dev/null @@ -1,327 +0,0 @@ -# Prowler App - -**Prowler App** is a user-friendly interface for Prowler CLI, providing a visual dashboard to monitor your cloud security posture. This tutorial will guide you through setting up and using Prowler App. - -## Accessing Prowler App and API Documentation - -After [installing](../installation/prowler-app.md) **Prowler App**, access it at [http://localhost:3000](http://localhost:3000). To view the auto-generated **Prowler API** documentation, navigate to [http://localhost:8080/api/v1/docs](http://localhost:8080/api/v1/docs). This documentation provides details on available endpoints, parameters, and responses. - -???+ note - If you are a [Prowler Cloud](https://cloud.prowler.com/sign-in) user, you can access API docs at [https://api.prowler.com/api/v1/docs](https://api.prowler.com/api/v1/docs) - -## **Step 1: Sign Up** - -### **Sign Up with Email** - -To get started, sign up using your email and password: - -Sign Up Button -Sign Up - -### **Sign Up with Social Login** - -If Social Login is enabled, you can sign up using your preferred provider (e.g., Google, GitHub). - -???+ note "How Social Login Works" - If your email is already registered, you will be logged in, and your social account will be linked. - If your email is not registered, a new account will be created using your social account email. - -???+ note "Enable Social Login" - See [how to configure Social Login for Prowler](prowler-app-social-login.md) to enable this feature in your own deployments. - -## **Step 2: Log In** - -Once registered, log in with your email and password to access Prowler App. - -Log In - -Upon logging in, the Overview page will display. At this stage, no data is present: add a provider to begin scanning your cloud environment. - -## **Step 3: Add a Provider** - -To perform security scans, link a cloud provider account. Prowler supports the following providers: - -- **AWS** - -- **Azure** - -- **Google Cloud Platform (GCP)** - -- **Kubernetes** - -- **M365** - -Steps to add a provider: - -1. Navigate to `Settings > Cloud Providers`. -2. Click `Add Account` to set up a new provider and provide your credentials. - -Add Provider - -## **Step 4: Configure the Provider** - -Select the cloud provider you want to scan. - -Select a Provider - -Once chosen, enter the Provider UID for authentication: - -- **AWS**: Enter your AWS Account ID. -- **GCP**: Enter your GCP Project ID. -- **Azure**: Enter your Azure Subscription ID. -- **Kubernetes**: Enter your Kubernetes Cluster context of your kubeconfig file. -- **M365**: Enter your M365 Domain ID. - -Optionally, provide a **Provider Alias** for easier identification. Follow the instructions provided to add your credentials: - -###Ā **Step 4.1: AWS Credentials** - -For AWS, enter your `AWS Account ID` and choose one of the following methods to connect: - -#### **Step 4.1.1: IAM Access Keys** - -1. Select `Connect via Credentials`. - - AWS Credentials - -2. Enter your `Access Key ID`, `Secret Access Key` and optionally a `Session Token`: - - AWS Credentials - -#### **Step 4.1.2: IAM Role** - -1. Select `Connect assuming IAM Role`. - - AWS Role - -2. Enter the `Role ARN` and any optional field like the AWS Access Keys to assume the role, the `External ID`, the `Role Session Name` or the `Session Duration`: - - AWS Role - -???+ note - Check if your AWS Security Token Service (STS) has the EU (Ireland) endpoint active. If not, we will not be able to connect to your AWS account. - - If that is the case your STS configuration may look like this: - - AWS Role - - To solve this issue, please activate the EU (Ireland) STS endpoint. - -###Ā **Step 4.2: Azure Credentials**: - -For Azure, Prowler App uses a service principal application to authenticate. For more information about the process of creating and adding permissions to a service principal refer to this [section](../tutorials/azure/authentication.md). When you finish creating and adding the [Entra](./azure/create-prowler-service-principal.md#assigning-proper-permissions) and [Subscription](./azure/subscriptions.md) scope permissions to the service principal, enter the `Tenant ID`, `Client ID` and `Client Secret` of the service principal application. - -Azure Credentials - ---- -###Ā **Step 4.3: GCP Credentials** - -For Google Cloud, first enter your `GCP Project ID` and then select the authentication method you want to use: - -- **Service Account Authentication** (**Recommended**) -- **Application Default Credentials** - -**Service Account Authentication** is the recommended authentication method for automated systems and machine-to-machine interactions, like Prowler. For detailed information about this, refer to the [Google Cloud documentation](https://cloud.google.com/iam/docs/service-account-overview). - -GCP Authentication Methods - -#### **Step 4.3.1: Service Account Authentication** - -First of all, in the same project that you selected in the previous step, you need to create a service account and then generate a key in JSON format for it. For more information about this, you can follow the next Google Cloud documentation tutorials: - -- [Create a service account](https://cloud.google.com/iam/docs/creating-managing-service-accounts) -- [Generate a key for a service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) - -GCP Service Account Credentials - -#### **Step 4.3.2: Application Default Credentials** - -1. Run the following command in your terminal to authenticate with GCP: - - ```bash - gcloud auth application-default login - ``` - -2. Once authenticated, get the `Client ID`, `Client Secret` and `Refresh Token` from `~/.config/gcloud/application_default_credentials`. - -3. Paste the `Client ID`, `Client Secret` and `Refresh Token` into Prowler App. - -GCP Credentials - -###Ā **Step 4.4: Kubernetes Credentials**: - -For Kubernetes, Prowler App uses a `kubeconfig` file to authenticate, paste the contents of your `kubeconfig` file into the `Kubeconfig content` field. - -By default, the `kubeconfig` file is located at `~/.kube/config`. - -Kubernetes Credentials - -If you are adding an **EKS**, **GKE**, **AKS** or external cluster, follow these additional steps to ensure proper authentication: - -**Make sure your cluster allow traffic from the Prowler Cloud IP address `52.48.254.174/32`** - -1. Apply the necessary Kubernetes resources to your EKS, GKE, AKS or external cluster (you can find the files in the [`kubernetes` directory of the Prowler repository](https://github.com/prowler-cloud/prowler/tree/master/kubernetes)): - - ```console - kubectl apply -f kubernetes/prowler-sa.yaml - kubectl apply -f kubernetes/prowler-role.yaml - kubectl apply -f kubernetes/prowler-rolebinding.yaml - ``` - -2. Generate a long-lived token for authentication: - - ```console - kubectl create token prowler-sa -n prowler-ns --duration=0 - ``` - - - **Security Note:** The `--duration=0` option generates a non-expiring token, which may pose a security risk if not managed properly. Users should decide on an appropriate expiration time based on their security policies. If a limited-time token is preferred, set `--duration=