diff --git a/.github/workflows/ui-e2e-tests.yml b/.github/workflows/ui-e2e-tests.yml index 592a32bc06..4cde993a6e 100644 --- a/.github/workflows/ui-e2e-tests.yml +++ b/.github/workflows/ui-e2e-tests.yml @@ -1,4 +1,4 @@ -name: UI - E2E Tests +name: UI - E2E Cloud Tests on: pull_request: @@ -6,125 +6,185 @@ on: - master - "v5.*" paths: - - '.github/workflows/ui-e2e-tests.yml' - - 'ui/**' + - ".github/workflows/ui-e2e-tests.yml" + - "ui/**" + push: + branches: + - master + - "v5.*" + paths: + - ".github/workflows/ui-e2e-cloud-tests.yml" + - "ui/**" + workflow_run: + workflows: + - "API - Build, Push and Deploy" + - "UI - Build, Push and Deploy" + types: [completed] + branches: [master, v5.*] + workflow_dispatch: + inputs: + environment: + description: "Environment to test" + required: true + default: "dev" + type: choice + options: + - dev + - stg + - pro + +permissions: + id-token: write + contents: read + actions: read jobs: - e2e-tests: - if: github.repository == 'prowler-cloud/prowler' + if: github.repository == 'prowler-cloud/prowler-cloud' runs-on: ubuntu-latest env: - AUTH_SECRET: 'fallback-ci-secret-for-testing' - 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_KUBERNETES_CONTEXT: 'kind-kind' - E2E_KUBERNETES_KUBECONFIG_PATH: /home/runner/.kube/config - E2E_GCP_BASE64_SERVICE_ACCOUNT_KEY: ${{ secrets.E2E_GCP_BASE64_SERVICE_ACCOUNT_KEY }} - E2E_GCP_PROJECT_ID: ${{ secrets.E2E_GCP_PROJECT_ID }} - E2E_GITHUB_APP_ID: ${{ secrets.E2E_GITHUB_APP_ID }} - E2E_GITHUB_BASE64_APP_PRIVATE_KEY: ${{ secrets.E2E_GITHUB_BASE64_APP_PRIVATE_KEY }} - E2E_GITHUB_USERNAME: ${{ secrets.E2E_GITHUB_USERNAME }} - E2E_GITHUB_PERSONAL_ACCESS_TOKEN: ${{ secrets.E2E_GITHUB_PERSONAL_ACCESS_TOKEN }} - E2E_GITHUB_ORGANIZATION: ${{ secrets.E2E_GITHUB_ORGANIZATION }} - E2E_GITHUB_ORGANIZATION_ACCESS_TOKEN: ${{ secrets.E2E_GITHUB_ORGANIZATION_ACCESS_TOKEN }} - E2E_ORGANIZATION_ID: ${{ secrets.E2E_ORGANIZATION_ID }} - E2E_OCI_TENANCY_ID: ${{ secrets.E2E_OCI_TENANCY_ID }} - E2E_OCI_USER_ID: ${{ secrets.E2E_OCI_USER_ID }} - E2E_OCI_FINGERPRINT: ${{ secrets.E2E_OCI_FINGERPRINT }} - E2E_OCI_KEY_CONTENT: ${{ secrets.E2E_OCI_KEY_CONTENT }} - E2E_OCI_REGION: ${{ secrets.E2E_OCI_REGION }} - E2E_NEW_USER_PASSWORD: ${{ secrets.E2E_NEW_USER_PASSWORD }} - + NEXTAUTH_URL: "http://localhost:3000" + AUTH_SECRET: "fallback-ci-secret-for-testing" + AUTH_TRUST_HOST: "true" steps: + - name: Determine environment + id: env + run: | + if [[ "${{ github.event_name }}" == "pull_request" || "${{ github.event_name }}" == "push" ]]; then + echo "environment=dev" >> $GITHUB_OUTPUT + elif [[ "${{ github.event_name }}" == "workflow_run" && "${{ github.event.workflow_run.conclusion }}" == "success" && "${{ github.event.workflow_run.event }}" == "release" ]]; then + echo "environment=stg" >> $GITHUB_OUTPUT + elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + echo "environment=${{ github.event.inputs.environment }}" >> $GITHUB_OUTPUT + else + echo "Unknown trigger, skipping..." + exit 1 + fi + - name: Set environment variables + id: vars + run: | + case "${{ steps.env.outputs.environment }}" in + "dev") + echo "api_url=https://api.dev.prowler.com/api/v1" >> $GITHUB_OUTPUT + echo "e2e_user_secret=DEV_E2E_USER" >> $GITHUB_OUTPUT + echo "e2e_password_secret=DEV_E2E_PASSWORD" >> $GITHUB_OUTPUT + echo "environment_name=DEV" >> $GITHUB_OUTPUT + ;; + "stg") + echo "api_url=https://api.stg.prowler.com/api/v1" >> $GITHUB_OUTPUT + echo "e2e_user_secret=STG_E2E_USER" >> $GITHUB_OUTPUT + echo "e2e_password_secret=STG_E2E_PASSWORD" >> $GITHUB_OUTPUT + echo "environment_name=STG" >> $GITHUB_OUTPUT + ;; + "pro") + echo "api_url=https://api.prowler.com/api/v1" >> $GITHUB_OUTPUT + echo "e2e_user_secret=PRO_E2E_USER" >> $GITHUB_OUTPUT + echo "e2e_password_secret=PRO_E2E_PASSWORD" >> $GITHUB_OUTPUT + echo "environment_name=PRO" >> $GITHUB_OUTPUT + ;; + esac - name: Checkout repository uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - name: Create k8s Kind Cluster - uses: helm/kind-action@v1 + - name: Environment info + env: + ENV_NAME: ${{ steps.vars.outputs.environment_name }} + API_URL: ${{ steps.vars.outputs.api_url }} + run: | + echo "Environment: $ENV_NAME" + echo "API URL: $API_URL" + echo "Workflow: ${{ github.workflow }}" + echo "Event: ${{ github.event_name }}" + echo "Started at: $(date)" + - name: Verify both STG deployments completed + if: steps.env.outputs.environment == 'stg' + env: + GH_TOKEN: ${{ github.token }} + run: | + echo "Verifying that both API and UI deployments completed successfully..." + + # Get the latest runs for both workflows triggered by the same release + API_RUN=$(gh run list --workflow="API - Build, Push and Deploy" --event=release --limit=1 --json status,conclusion,createdAt --jq '.[0]') + API_STATUS=$(echo "$API_RUN" | jq -r '.status') + API_CONCLUSION=$(echo "$API_RUN" | jq -r '.conclusion') + + UI_RUN=$(gh run list --workflow="UI - Build, Push and Deploy" --event=release --limit=1 --json status,conclusion,createdAt --jq '.[0]') + UI_STATUS=$(echo "$UI_RUN" | jq -r '.status') + UI_CONCLUSION=$(echo "$UI_RUN" | jq -r '.conclusion') + + echo "API workflow - Status: $API_STATUS, Conclusion: $API_CONCLUSION" + echo "UI workflow - Status: $UI_STATUS, Conclusion: $UI_CONCLUSION" + + # Verify both workflows completed successfully + if [[ "$API_STATUS" != "completed" || "$API_CONCLUSION" != "success" ]]; then + echo "API deployment not ready (Status: $API_STATUS, Conclusion: $API_CONCLUSION)" + exit 1 + fi + + if [[ "$UI_STATUS" != "completed" || "$UI_CONCLUSION" != "success" ]]; then + echo "UI deployment not ready (Status: $UI_STATUS, Conclusion: $UI_CONCLUSION)" + exit 1 + fi + + echo "Both API and UI deployments completed successfully for STG" + - name: Verify both PRO deployments completed + if: steps.env.outputs.environment == 'pro' + env: + GH_TOKEN: ${{ github.token }} + run: | + echo "Verifying that both API and UI deployments completed successfully..." + + # Get the latest manual runs for both workflows + API_RUN=$(gh run list --workflow="API - Build, Push and Deploy" --event=workflow_dispatch --limit=1 --json status,conclusion,createdAt --jq '.[0]') + API_STATUS=$(echo "$API_RUN" | jq -r '.status') + API_CONCLUSION=$(echo "$API_RUN" | jq -r '.conclusion') + + UI_RUN=$(gh run list --workflow="UI - Build, Push and Deploy" --event=workflow_dispatch --limit=1 --json status,conclusion,createdAt --jq '.[0]') + UI_STATUS=$(echo "$UI_RUN" | jq -r '.status') + UI_CONCLUSION=$(echo "$UI_RUN" | jq -r '.conclusion') + + echo "API workflow - Status: $API_STATUS, Conclusion: $API_CONCLUSION" + echo "UI workflow - Status: $UI_STATUS, Conclusion: $UI_CONCLUSION" + + # Verify both workflows completed successfully + if [[ "$API_STATUS" != "completed" || "$API_CONCLUSION" != "success" ]]; then + echo "API deployment not ready (Status: $API_STATUS, Conclusion: $API_CONCLUSION)" + exit 1 + fi + + if [[ "$UI_STATUS" != "completed" || "$UI_CONCLUSION" != "success" ]]; then + echo "UI deployment not ready (Status: $UI_STATUS, Conclusion: $UI_CONCLUSION)" + exit 1 + fi + + echo "Both API and UI deployments completed successfully for PRO" + - name: Setup Tailscale + if: steps.env.outputs.environment != 'pro' + uses: tailscale/github-action@84a3f23bb4d843bcf4da6cf824ec1be473daf4de # v3.2.3 with: - cluster_name: kind - - name: Modify kubeconfig + oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }} + oauth-secret: ${{ secrets.TS_OAUTH_SECRET }} + tags: tag:github-actions + - name: Verify API is accessible + env: + API_URL: ${{ steps.vars.outputs.api_url }} + ENV_NAME: ${{ steps.vars.outputs.environment_name }} run: | - # Modify the kubeconfig to use the kind cluster server to https://kind-control-plane:6443 - # from worker service into docker-compose.yml - kubectl config set-cluster kind-kind --server=https://kind-control-plane:6443 - kubectl config view - - name: Add network kind to docker compose - run: | - # Add the network kind to the docker compose to interconnect to kind cluster - yq -i '.networks.kind.external = true' docker-compose.yml - # Add network kind to worker service and default network too - yq -i '.services.worker.networks = ["kind","default"]' docker-compose.yml - - name: Fix API data directory permissions - run: docker run --rm -v $(pwd)/_data/api:/data alpine chown -R 1000:1000 /data - - name: Add AWS credentials for testing AWS SDK Default Adding Provider - run: | - echo "Adding AWS credentials for testing AWS SDK Default Adding Provider..." - echo "AWS_ACCESS_KEY_ID=${{ secrets.E2E_AWS_PROVIDER_ACCESS_KEY }}" >> .env - echo "AWS_SECRET_ACCESS_KEY=${{ secrets.E2E_AWS_PROVIDER_SECRET_KEY }}" >> .env - - name: Start API services - run: | - # Override docker-compose image tag to use latest instead of stable - # This overrides any PROWLER_API_VERSION set in .env file - export PROWLER_API_VERSION=latest - echo "Using PROWLER_API_VERSION=${PROWLER_API_VERSION}" - docker compose up -d api worker worker-beat - - name: Wait for API to be ready - run: | - echo "Waiting for prowler-api..." - timeout=150 # 5 minutes max - elapsed=0 - while [ $elapsed -lt $timeout ]; do - if curl -s ${NEXT_PUBLIC_API_BASE_URL}/docs >/dev/null 2>&1; then - echo "Prowler API is ready!" - exit 0 - fi - echo "Waiting for prowler-api... (${elapsed}s elapsed)" - sleep 5 - elapsed=$((elapsed + 5)) - done - echo "Timeout waiting for prowler-api to start" - exit 1 - - name: Load database fixtures for E2E tests - run: | - docker compose exec -T api sh -c ' - echo "Loading all fixtures from api/fixtures/dev/..." - for fixture in api/fixtures/dev/*.json; do - if [ -f "$fixture" ]; then - echo "Loading $fixture" - poetry run python manage.py loaddata "$fixture" --database admin - fi - done - echo "All database fixtures loaded successfully!" - ' + echo "Checking $ENV_NAME API at $API_URL/docs..." + curl -f --connect-timeout 30 --max-time 60 ${API_URL}/docs + echo "$ENV_NAME API is accessible" - name: Setup Node.js environment - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 with: - node-version: '20.x' - - name: Setup pnpm - uses: pnpm/action-setup@v4 + node-version: "20.x" + - name: Install pnpm + uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 with: - version: 10 + version: 9 run_install: false - name: Get pnpm store directory shell: bash - run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - name: Setup pnpm cache uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: @@ -137,6 +197,10 @@ jobs: run: pnpm install --frozen-lockfile - name: Build UI application working-directory: ./ui + env: + NEXT_PUBLIC_API_BASE_URL: ${{ steps.vars.outputs.api_url }} + NEXT_PUBLIC_IS_CLOUD_ENV: "true" + CLOUD_API_BASE_URL: ${{ steps.vars.outputs.api_url }} run: pnpm run build - name: Cache Playwright browsers uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 @@ -152,17 +216,50 @@ jobs: run: pnpm run test:e2e:install - name: Run E2E tests working-directory: ./ui - run: pnpm run test:e2e + env: + NEXT_PUBLIC_API_BASE_URL: ${{ steps.vars.outputs.api_url }} + NEXT_PUBLIC_IS_CLOUD_ENV: "true" + CLOUD_API_BASE_URL: ${{ steps.vars.outputs.api_url }} + E2E_USER: ${{ secrets[steps.vars.outputs.e2e_user_secret] }} + E2E_PASSWORD: ${{ secrets[steps.vars.outputs.e2e_password_secret] }} + 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_KUBERNETES_CONTEXT: "kind-kind" + E2E_KUBERNETES_KUBECONFIG_PATH: /home/runner/.kube/config + E2E_GCP_BASE64_SERVICE_ACCOUNT_KEY: ${{ secrets.E2E_GCP_BASE64_SERVICE_ACCOUNT_KEY }} + E2E_GCP_PROJECT_ID: ${{ secrets.E2E_GCP_PROJECT_ID }} + E2E_GITHUB_APP_ID: ${{ secrets.E2E_GITHUB_APP_ID }} + E2E_GITHUB_BASE64_APP_PRIVATE_KEY: ${{ secrets.E2E_GITHUB_BASE64_APP_PRIVATE_KEY }} + E2E_GITHUB_USERNAME: ${{ secrets.E2E_GITHUB_USERNAME }} + E2E_GITHUB_PERSONAL_ACCESS_TOKEN: ${{ secrets.E2E_GITHUB_PERSONAL_ACCESS_TOKEN }} + E2E_GITHUB_ORGANIZATION: ${{ secrets.E2E_GITHUB_ORGANIZATION }} + E2E_GITHUB_ORGANIZATION_ACCESS_TOKEN: ${{ secrets.E2E_GITHUB_ORGANIZATION_ACCESS_TOKEN }} + E2E_ORGANIZATION_ID: ${{ secrets.E2E_ORGANIZATION_ID }} + E2E_OCI_TENANCY_ID: ${{ secrets.E2E_OCI_TENANCY_ID }} + E2E_OCI_USER_ID: ${{ secrets.E2E_OCI_USER_ID }} + E2E_OCI_FINGERPRINT: ${{ secrets.E2E_OCI_FINGERPRINT }} + E2E_OCI_KEY_CONTENT: ${{ secrets.E2E_OCI_KEY_CONTENT }} + E2E_OCI_REGION: ${{ secrets.E2E_OCI_REGION }} + E2E_NEW_USER_PASSWORD: ${{ secrets.E2E_NEW_USER_PASSWORD }} + + run: pnpm run test:e2e-cloud - name: Upload test reports uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - if: failure() + if: always() with: - name: playwright-report + name: playwright-report-${{ steps.env.outputs.environment }}-${{ github.run_number }} path: ui/playwright-report/ retention-days: 30 - - name: Cleanup services - if: always() - run: | - echo "Shutting down services..." - docker compose down -v || true - echo "Cleanup completed" diff --git a/docs/user-guide/providers/oci/getting-started-oci.mdx b/docs/user-guide/providers/oci/getting-started-oci.mdx index 16fb135e79..80c008480d 100644 --- a/docs/user-guide/providers/oci/getting-started-oci.mdx +++ b/docs/user-guide/providers/oci/getting-started-oci.mdx @@ -58,7 +58,7 @@ Before you begin, ensure you have: ### Authentication -Prowler supports multiple authentication methods for OCI. For detailed authentication setup, see the [OCI Authentication Guide](./authentication.mdx). +Prowler supports multiple authentication methods for OCI. For detailed authentication setup, see the [OCI Authentication Guide](./authentication). **Note:** OCI Session Authentication and Config File Authentication both use the same `~/.oci/config` file. The difference is how the config file is generated - automatically via browser (session auth) or manually with API keys. @@ -107,7 +107,7 @@ The easiest and most secure method is using OCI session authentication, which au #### Alternative: Manual API Key Setup -If you prefer to manually generate API keys instead of using browser-based session authentication, see the detailed instructions in the [Authentication Guide](./authentication.mdx#config-file-authentication-manual-api-key-setup). +If you prefer to manually generate API keys instead of using browser-based session authentication, see the detailed instructions in the [Authentication Guide](./authentication#config-file-authentication-manual-api-key-setup). **Note:** Both methods use the same `~/.oci/config` file - the difference is that manual setup uses static API keys while session authentication uses temporary session tokens. diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md index 391c574797..081475128a 100644 --- a/prowler/CHANGELOG.md +++ b/prowler/CHANGELOG.md @@ -12,6 +12,10 @@ All notable changes to the **Prowler SDK** are documented in this file. - `compute_instance_automatic_restart_enabled` check for GCP provider [(#9271)](https://github.com/prowler-cloud/prowler/pull/9271) - `compute_instance_deletion_protection_enabled` check for GCP provider [(#9358)](https://github.com/prowler-cloud/prowler/pull/9358) - Add needed changes to AlibabaCloud provider from the API [(#9485)](https://github.com/prowler-cloud/prowler/pull/9485) +- Update SOC2 - Azure with Processing Integrity requirements [(#9463)](https://github.com/prowler-cloud/prowler/pull/9463) +- Update SOC2 - GCP with Processing Integrity requirements [(#9464)](https://github.com/prowler-cloud/prowler/pull/9464) +- Update SOC2 - AWS with Processing Integrity requirements [(#9462)](https://github.com/prowler-cloud/prowler/pull/9462) +- RBI Cyber Security Framework compliance for Azure provider [(#8822)](https://github.com/prowler-cloud/prowler/pull/8822) ### Changed - Update AWS Macie service metadata to new format [(#9265)](https://github.com/prowler-cloud/prowler/pull/9265) @@ -22,11 +26,15 @@ All notable changes to the **Prowler SDK** are documented in this file. - Update AWS Macie service metadata to new format [(#9265)](https://github.com/prowler-cloud/prowler/pull/9265) - Update AWS Lightsail service metadata to new format [(#9264)](https://github.com/prowler-cloud/prowler/pull/9264) +### Fixed +- GCP `cloudstorage_uses_vpc_service_controls` check to handle VPC Service Controls blocked API access [(#9478)](https://github.com/prowler-cloud/prowler/pull/9478) + --- ## [v5.14.3] (Prowler UNRELEASED) ### Fixed +- Fix duplicate requirement IDs in ISO 27001:2013 AWS compliance framework by adding unique letter suffixes - Removed incorrect threat-detection category from checks metadata [(#9489)](https://github.com/prowler-cloud/prowler/pull/9489) --- diff --git a/prowler/compliance/aws/iso27001_2013_aws.json b/prowler/compliance/aws/iso27001_2013_aws.json index 1cdf75a6da..a817ec22bd 100644 --- a/prowler/compliance/aws/iso27001_2013_aws.json +++ b/prowler/compliance/aws/iso27001_2013_aws.json @@ -6,13 +6,13 @@ "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.", "Requirements": [ { - "Id": "A.10.1", + "Id": "A.10.1.A", "Description": "Setup Encryption at rest for RDS instances", "Name": "Cryptographic Controls", "Attributes": [ { "Category": "A.10 Cryptography", - "Objetive_ID": "A.10.1", + "Objetive_ID": "A.10.1.A", "Objetive_Name": "Cryptographic Controls", "Check_Summary": "Setup Encryption at rest for RDS instances" } @@ -22,13 +22,13 @@ ] }, { - "Id": "A.10.1", + "Id": "A.10.1.B", "Description": "Detect use of insecure ciphers on ELBs", "Name": "Cryptographic Controls", "Attributes": [ { "Category": "A.10 Cryptography", - "Objetive_ID": "A.10.1", + "Objetive_ID": "A.10.1.B", "Objetive_Name": "Cryptographic Controls", "Check_Summary": "Detect use of insecure ciphers on ELBs" } @@ -39,13 +39,13 @@ ] }, { - "Id": "A.10.1", + "Id": "A.10.1.C", "Description": "Detect Customer Master Keys (CMKs) scheduled for deletion", "Name": "Cryptographic Controls", "Attributes": [ { "Category": "A.10 Cryptography", - "Objetive_ID": "A.10.1", + "Objetive_ID": "A.10.1.C", "Objetive_Name": "Cryptographic Controls", "Check_Summary": "Detect Customer Master Keys (CMKs) scheduled for deletion" } @@ -55,13 +55,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.A", "Description": "Ensure a log metric filter and alarm exist for VPC changes", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.A", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure a log metric filter and alarm exist for VPC changes" } @@ -71,13 +71,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.B", "Description": "Ensure a log metric filter and alarm exist for route table changes", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.B", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure a log metric filter and alarm exist for route table changes" } @@ -87,13 +87,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.C", "Description": "Ensure a log metric filter and alarm exist for changes to network gateways", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.C", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure a log metric filter and alarm exist for changes to network gateways" } @@ -103,13 +103,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.D", "Description": "Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL)", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.D", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL)" } @@ -119,13 +119,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.E", "Description": "Ensure a log metric filter and alarm exist for security group changes", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.E", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure a log metric filter and alarm exist for security group changes" } @@ -135,13 +135,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.F", "Description": "Ensure a log metric filter and alarm exist for AWS Config configuration changes", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.F", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure a log metric filter and alarm exist for AWS Config configuration changes" } @@ -151,13 +151,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.G", "Description": "Ensure a log metric filter and alarm exist for S3 bucket policy changes", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.G", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure a log metric filter and alarm exist for S3 bucket policy changes" } @@ -167,13 +167,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.H", "Description": "Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.H", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs" } @@ -183,13 +183,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.I", "Description": "Ensure a log metric filter and alarm exist for AWS Management Console authentication failures", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.I", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure a log metric filter and alarm exist for AWS Management Console authentication failures" } @@ -199,13 +199,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.J", "Description": "Ensure a log metric filter and alarm exist for CloudTrail configuration changes", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.J", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure a log metric filter and alarm exist for CloudTrail configuration changes" } @@ -215,13 +215,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.K", "Description": "Ensure a log metric filter and alarm exist for IAM policy changes", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.K", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure a log metric filter and alarm exist for IAM policy changes" } @@ -231,13 +231,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.L", "Description": "Ensure a log metric filter and alarm exist for usage of root account", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.L", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure a log metric filter and alarm exist for usage of root account" } @@ -247,13 +247,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.M", "Description": "Ensure a log metric filter and alarm exist for Management Console sign-in without MFA", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.M", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure a log metric filter and alarm exist for Management Console sign-in without MFA" } @@ -263,13 +263,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.N", "Description": "Ensure a log metric filter and alarm exist for unauthorized API calls", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.N", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure a log metric filter and alarm exist for unauthorized API calls" } @@ -279,13 +279,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.O", "Description": "Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.O", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket" } @@ -295,13 +295,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.P", "Description": "Ensure AWS Config is enabled in all regions", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.P", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure AWS Config is enabled in all regions" } @@ -311,13 +311,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.Q", "Description": "Ensure CloudTrail trails are integrated with CloudWatch Logs", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.Q", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure CloudTrail trails are integrated with CloudWatch Logs" } @@ -327,13 +327,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.R", "Description": "Ensure VPC flow logging is enabled in all VPCs", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.R", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure VPC flow logging is enabled in all VPCs" } @@ -343,13 +343,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.S", "Description": "Ensure the S3 bucket CloudTrail logs to is not publicly accessible", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.S", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure the S3 bucket CloudTrail logs to is not publicly accessible" } @@ -359,13 +359,13 @@ ] }, { - "Id": "A.12.4", + "Id": "A.12.4.T", "Description": "Ensure CloudTrail is enabled in all regions", "Name": "Logging and Monitoring", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.4", + "Objetive_ID": "A.12.4.T", "Objetive_Name": "Logging and Monitoring", "Check_Summary": "Ensure CloudTrail is enabled in all regions" } @@ -375,13 +375,13 @@ ] }, { - "Id": "A.12.6", + "Id": "A.12.6.A", "Description": "Ensure the default security group of every VPC restricts all traffic", "Name": "Technical Vulnerability Management", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.6", + "Objetive_ID": "A.12.6.A", "Objetive_Name": "Technical Vulnerability Management", "Check_Summary": "Ensure the default security group of every VPC restricts all traffic" } @@ -391,13 +391,13 @@ ] }, { - "Id": "A.12.6", + "Id": "A.12.6.B", "Description": "Ensure no security groups allow ingress from 0.0.0.0/0 to port 3389", "Name": "Technical Vulnerability Management", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.6", + "Objetive_ID": "A.12.6.B", "Objetive_Name": "Technical Vulnerability Management", "Check_Summary": "Ensure no security groups allow ingress from 0.0.0.0/0 to port 3389" } @@ -407,13 +407,13 @@ ] }, { - "Id": "A.12.6", + "Id": "A.12.6.C", "Description": "Ensure no security groups allow ingress from 0.0.0.0/0 to port 22", "Name": "Technical Vulnerability Management", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.6", + "Objetive_ID": "A.12.6.C", "Objetive_Name": "Technical Vulnerability Management", "Check_Summary": "Ensure no security groups allow ingress from 0.0.0.0/0 to port 22" } @@ -423,13 +423,13 @@ ] }, { - "Id": "A.12.6", + "Id": "A.12.6.D", "Description": "Check for publicly shared AMIs", "Name": "Technical Vulnerability Management", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.6", + "Objetive_ID": "A.12.6.D", "Objetive_Name": "Technical Vulnerability Management", "Check_Summary": "Check for publicly shared AMIs" } @@ -439,13 +439,13 @@ ] }, { - "Id": "A.12.6", + "Id": "A.12.6.E", "Description": "Ensure EBS snapshots are not publicly accessible", "Name": "Technical Vulnerability Management", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.6", + "Objetive_ID": "A.12.6.E", "Objetive_Name": "Technical Vulnerability Management", "Check_Summary": "Ensure EBS snapshots are not publicly accessible" } @@ -455,13 +455,13 @@ ] }, { - "Id": "A.12.6", + "Id": "A.12.6.F", "Description": "Ensure SNS topics do not allow global send or subscribe", "Name": "Technical Vulnerability Management", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.6", + "Objetive_ID": "A.12.6.F", "Objetive_Name": "Technical Vulnerability Management", "Check_Summary": "Ensure SNS topics do not allow global send or subscribe" } @@ -471,13 +471,13 @@ ] }, { - "Id": "A.12.6", + "Id": "A.12.6.G", "Description": "Ensure Redshift clusters do not have a public endpoint", "Name": "Technical Vulnerability Management", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.6", + "Objetive_ID": "A.12.6.G", "Objetive_Name": "Technical Vulnerability Management", "Check_Summary": "Ensure Redshift clusters do not have a public endpoint" } @@ -487,13 +487,13 @@ ] }, { - "Id": "A.12.6", + "Id": "A.12.6.H", "Description": "Ensure RDS snapshots are not publicly accessible", "Name": "Technical Vulnerability Management", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.6", + "Objetive_ID": "A.12.6.H", "Objetive_Name": "Technical Vulnerability Management", "Check_Summary": "Ensure RDS snapshots are not publicly accessible" } @@ -503,13 +503,13 @@ ] }, { - "Id": "A.12.6", + "Id": "A.12.6.I", "Description": "Ensure RDS instances are not accessible to the world.", "Name": "Technical Vulnerability Management", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.6", + "Objetive_ID": "A.12.6.I", "Objetive_Name": "Technical Vulnerability Management", "Check_Summary": "Ensure RDS instances are not accessible to the world." } @@ -519,13 +519,13 @@ ] }, { - "Id": "A.12.6", + "Id": "A.12.6.J", "Description": "Ensure the S3 bucket CloudTrail logs to is not publicly accessible", "Name": "Technical Vulnerability Management", "Attributes": [ { "Category": "A.12 Operations Security", - "Objetive_ID": "A.12.6", + "Objetive_ID": "A.12.6.J", "Objetive_Name": "Technical Vulnerability Management", "Check_Summary": "Ensure the S3 bucket CloudTrail logs to is not publicly accessible" } @@ -535,13 +535,13 @@ ] }, { - "Id": "A.13.1", + "Id": "A.13.1.A", "Description": "Ensure the default security group of every VPC restricts all traffic", "Name": "Network Security Management", "Attributes": [ { "Category": "A.13 Communications Security", - "Objetive_ID": "A.13.1", + "Objetive_ID": "A.13.1.A", "Objetive_Name": "Network Security Management", "Check_Summary": "Ensure the default security group of every VPC restricts all traffic" } @@ -551,13 +551,13 @@ ] }, { - "Id": "A.13.1", + "Id": "A.13.1.B", "Description": "Ensure no security groups allow ingress from 0.0.0.0/0 to port 3389", "Name": "Network Security Management", "Attributes": [ { "Category": "A.13 Communications Security", - "Objetive_ID": "A.13.1", + "Objetive_ID": "A.13.1.B", "Objetive_Name": "Network Security Management", "Check_Summary": "Ensure no security groups allow ingress from 0.0.0.0/0 to port 3389" } @@ -567,13 +567,13 @@ ] }, { - "Id": "A.13.1", + "Id": "A.13.1.C", "Description": "Ensure no security groups allow ingress from 0.0.0.0/0 to port 22", "Name": "Network Security Management", "Attributes": [ { "Category": "A.13 Communications Security", - "Objetive_ID": "A.13.1", + "Objetive_ID": "A.13.1.C", "Objetive_Name": "Network Security Management", "Check_Summary": "Ensure no security groups allow ingress from 0.0.0.0/0 to port 22" } @@ -583,13 +583,13 @@ ] }, { - "Id": "A.13.1", + "Id": "A.13.1.D", "Description": "Ensure EBS snapshots are not publicly accessible", "Name": "Network Security Management", "Attributes": [ { "Category": "A.13 Communications Security", - "Objetive_ID": "A.13.1", + "Objetive_ID": "A.13.1.D", "Objetive_Name": "Network Security Management", "Check_Summary": "Ensure EBS snapshots are not publicly accessible" } @@ -599,13 +599,13 @@ ] }, { - "Id": "A.13.1", + "Id": "A.13.1.E", "Description": "Ensure SNS topics do not allow global send or subscribe", "Name": "Network Security Management", "Attributes": [ { "Category": "A.13 Communications Security", - "Objetive_ID": "A.13.1", + "Objetive_ID": "A.13.1.E", "Objetive_Name": "Network Security Management", "Check_Summary": "Ensure SNS topics do not allow global send or subscribe" } @@ -615,13 +615,13 @@ ] }, { - "Id": "A.13.1", + "Id": "A.13.1.F", "Description": "Ensure Redshift clusters do not have a public endpoint", "Name": "Network Security Management", "Attributes": [ { "Category": "A.13 Communications Security", - "Objetive_ID": "A.13.1", + "Objetive_ID": "A.13.1.F", "Objetive_Name": "Network Security Management", "Check_Summary": "Ensure Redshift clusters do not have a public endpoint" } @@ -631,13 +631,13 @@ ] }, { - "Id": "A.13.1", + "Id": "A.13.1.G", "Description": "Ensure RDS snapshots are not publicly accessible", "Name": "Network Security Management", "Attributes": [ { "Category": "A.13 Communications Security", - "Objetive_ID": "A.13.1", + "Objetive_ID": "A.13.1.G", "Objetive_Name": "Network Security Management", "Check_Summary": "Ensure RDS snapshots are not publicly accessible" } @@ -647,13 +647,13 @@ ] }, { - "Id": "A.13.1", + "Id": "A.13.1.H", "Description": "Ensure RDS instances are not accessible to the world.", "Name": "Network Security Management", "Attributes": [ { "Category": "A.13 Communications Security", - "Objetive_ID": "A.13.1", + "Objetive_ID": "A.13.1.H", "Objetive_Name": "Network Security Management", "Check_Summary": "Ensure RDS instances are not accessible to the world." } @@ -663,13 +663,13 @@ ] }, { - "Id": "A.9.2", + "Id": "A.9.2.A", "Description": "Ensure IAM password policy expires passwords within 90 days or less", "Name": "User Access Management", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.2", + "Objetive_ID": "A.9.2.A", "Objetive_Name": "User Access Management", "Check_Summary": "Ensure IAM password policy expires passwords within 90 days or less" } @@ -679,13 +679,13 @@ ] }, { - "Id": "A.9.2", + "Id": "A.9.2.B", "Description": "Ensure IAM password policy prevents password reuse", "Name": "User Access Management", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.2", + "Objetive_ID": "A.9.2.B", "Objetive_Name": "User Access Management", "Check_Summary": "Ensure IAM password policy prevents password reuse" } @@ -695,13 +695,13 @@ ] }, { - "Id": "A.9.2", + "Id": "A.9.2.C", "Description": "Ensure IAM password policy requires minimum length of 14 or greater", "Name": "User Access Management", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.2", + "Objetive_ID": "A.9.2.C", "Objetive_Name": "User Access Management", "Check_Summary": "Ensure IAM password policy requires minimum length of 14 or greater" } @@ -711,13 +711,13 @@ ] }, { - "Id": "A.9.2", + "Id": "A.9.2.D", "Description": "Ensure IAM password policy require at least one number", "Name": "User Access Management", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.2", + "Objetive_ID": "A.9.2.D", "Objetive_Name": "User Access Management", "Check_Summary": "Ensure IAM password policy require at least one number" } @@ -727,13 +727,13 @@ ] }, { - "Id": "A.9.2", + "Id": "A.9.2.E", "Description": "Ensure IAM password policy require at least one symbol", "Name": "User Access Management", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.2", + "Objetive_ID": "A.9.2.E", "Objetive_Name": "User Access Management", "Check_Summary": "Ensure IAM password policy require at least one symbol" } @@ -743,13 +743,13 @@ ] }, { - "Id": "A.9.2", + "Id": "A.9.2.F", "Description": "Ensure IAM password policy require at least one lowercase letter", "Name": "User Access Management", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.2", + "Objetive_ID": "A.9.2.F", "Objetive_Name": "User Access Management", "Check_Summary": "Ensure IAM password policy require at least one lowercase letter" } @@ -759,13 +759,13 @@ ] }, { - "Id": "A.9.2", + "Id": "A.9.2.G", "Description": "Ensure IAM password policy requires at least one uppercase letter", "Name": "User Access Management", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.2", + "Objetive_ID": "A.9.2.G", "Objetive_Name": "User Access Management", "Check_Summary": "Ensure IAM password policy requires at least one uppercase letter" } @@ -775,13 +775,13 @@ ] }, { - "Id": "A.9.2", + "Id": "A.9.2.H", "Description": "Avoid the use of the 'root' account", "Name": "User Access Management", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.2", + "Objetive_ID": "A.9.2.H", "Objetive_Name": "User Access Management", "Check_Summary": "Avoid the use of the 'root' account" } @@ -791,13 +791,13 @@ ] }, { - "Id": "A.9.2", + "Id": "A.9.2.I", "Description": "Ensure IAM policies are attached only to groups or roles", "Name": "User Access Management", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.2", + "Objetive_ID": "A.9.2.I", "Objetive_Name": "User Access Management", "Check_Summary": "Ensure IAM policies are attached only to groups or roles" } @@ -807,13 +807,13 @@ ] }, { - "Id": "A.9.2", + "Id": "A.9.2.J", "Description": "Ensure multi-factor authentication (MFA) is enabled for all IAM users that have console access", "Name": "User Access Management", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.2", + "Objetive_ID": "A.9.2.J", "Objetive_Name": "User Access Management", "Check_Summary": "Ensure multi-factor authentication (MFA) is enabled for all IAM users that have console access" } @@ -823,13 +823,13 @@ ] }, { - "Id": "A.9.2", + "Id": "A.9.2.K", "Description": "Ensure MFA is enabled for the 'root' account", "Name": "User Access Management", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.2", + "Objetive_ID": "A.9.2.K", "Objetive_Name": "User Access Management", "Check_Summary": "Ensure MFA is enabled for the 'root' account" } @@ -839,13 +839,13 @@ ] }, { - "Id": "A.9.2", + "Id": "A.9.2.L", "Description": "Ensure access keys are rotated every 90 days or less", "Name": "User Access Management", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.2", + "Objetive_ID": "A.9.2.L", "Objetive_Name": "User Access Management", "Check_Summary": "Ensure access keys are rotated every 90 days or less" } @@ -855,13 +855,13 @@ ] }, { - "Id": "A.9.2", + "Id": "A.9.2.M", "Description": "Ensure credentials unused for 90 days or greater are disabled", "Name": "User Access Management", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.2", + "Objetive_ID": "A.9.2.M", "Objetive_Name": "User Access Management", "Check_Summary": "Ensure credentials unused for 90 days or greater are disabled" } @@ -872,13 +872,13 @@ ] }, { - "Id": "A.9.2", + "Id": "A.9.2.N", "Description": "Ensure no root account access key exists", "Name": "User Access Management", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.2", + "Objetive_ID": "A.9.2.N", "Objetive_Name": "User Access Management", "Check_Summary": "Ensure no root account access key exists" } @@ -888,13 +888,13 @@ ] }, { - "Id": "A.9.3", + "Id": "A.9.3.A", "Description": "Ensure IAM password policy expires passwords within 90 days or less", "Name": "User Responsibilities", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.3", + "Objetive_ID": "A.9.3.A", "Objetive_Name": "User Responsibilities", "Check_Summary": "Ensure IAM password policy expires passwords within 90 days or less" } @@ -904,13 +904,13 @@ ] }, { - "Id": "A.9.3", + "Id": "A.9.3.B", "Description": "Ensure IAM password policy prevents password reuse", "Name": "User Responsibilities", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.3", + "Objetive_ID": "A.9.3.B", "Objetive_Name": "User Responsibilities", "Check_Summary": "Ensure IAM password policy prevents password reuse" } @@ -920,13 +920,13 @@ ] }, { - "Id": "A.9.3", + "Id": "A.9.3.C", "Description": "Ensure IAM password policy requires minimum length of 14 or greater", "Name": "User Responsibilities", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.3", + "Objetive_ID": "A.9.3.C", "Objetive_Name": "User Responsibilities", "Check_Summary": "Ensure IAM password policy requires minimum length of 14 or greater" } @@ -936,13 +936,13 @@ ] }, { - "Id": "A.9.3", + "Id": "A.9.3.D", "Description": "Ensure IAM password policy require at least one number", "Name": "User Responsibilities", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.3", + "Objetive_ID": "A.9.3.D", "Objetive_Name": "User Responsibilities", "Check_Summary": "Ensure IAM password policy require at least one number" } @@ -952,13 +952,13 @@ ] }, { - "Id": "A.9.3", + "Id": "A.9.3.E", "Description": "Ensure IAM password policy require at least one symbol", "Name": "User Responsibilities", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.3", + "Objetive_ID": "A.9.3.E", "Objetive_Name": "User Responsibilities", "Check_Summary": "Ensure IAM password policy require at least one symbol" } @@ -968,13 +968,13 @@ ] }, { - "Id": "A.9.3", + "Id": "A.9.3.F", "Description": "Ensure IAM password policy require at least one lowercase letter", "Name": "User Responsibilities", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.3", + "Objetive_ID": "A.9.3.F", "Objetive_Name": "User Responsibilities", "Check_Summary": "Ensure IAM password policy require at least one lowercase letter" } @@ -984,13 +984,13 @@ ] }, { - "Id": "A.9.3", + "Id": "A.9.3.G", "Description": "Ensure IAM password policy requires at least one uppercase letter", "Name": "User Responsibilities", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.3", + "Objetive_ID": "A.9.3.G", "Objetive_Name": "User Responsibilities", "Check_Summary": "Ensure IAM password policy requires at least one uppercase letter" } @@ -1000,13 +1000,13 @@ ] }, { - "Id": "A.9.3", + "Id": "A.9.3.H", "Description": "Ensure multi-factor authentication (MFA) is enabled for all IAM users that have console access", "Name": "User Responsibilities", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.3", + "Objetive_ID": "A.9.3.H", "Objetive_Name": "User Responsibilities", "Check_Summary": "Ensure multi-factor authentication (MFA) is enabled for all IAM users that have console access" } @@ -1016,13 +1016,13 @@ ] }, { - "Id": "A.9.3", + "Id": "A.9.3.I", "Description": "Ensure access keys are rotated every 90 days or less", "Name": "User Responsibilities", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.3", + "Objetive_ID": "A.9.3.I", "Objetive_Name": "User Responsibilities", "Check_Summary": "Ensure access keys are rotated every 90 days or less" } @@ -1032,13 +1032,13 @@ ] }, { - "Id": "A.9.3", + "Id": "A.9.3.J", "Description": "Ensure credentials unused for 90 days or greater are disabled", "Name": "User Responsibilities", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.3", + "Objetive_ID": "A.9.3.J", "Objetive_Name": "User Responsibilities", "Check_Summary": "Ensure credentials unused for 90 days or greater are disabled" } @@ -1049,13 +1049,13 @@ ] }, { - "Id": "A.9.4", + "Id": "A.9.4.A", "Description": "Ensure IAM password policy expires passwords within 90 days or less", "Name": "System and Application Access Control", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.4", + "Objetive_ID": "A.9.4.A", "Objetive_Name": "System and Application Access Control", "Check_Summary": "Ensure IAM password policy expires passwords within 90 days or less" } @@ -1065,13 +1065,13 @@ ] }, { - "Id": "A.9.4", + "Id": "A.9.4.B", "Description": "Ensure IAM password policy prevents password reuse", "Name": "System and Application Access Control", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.4", + "Objetive_ID": "A.9.4.B", "Objetive_Name": "System and Application Access Control", "Check_Summary": "Ensure IAM password policy prevents password reuse" } @@ -1081,13 +1081,13 @@ ] }, { - "Id": "A.9.4", + "Id": "A.9.4.C", "Description": "Ensure IAM password policy requires minimum length of 14 or greater", "Name": "System and Application Access Control", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.4", + "Objetive_ID": "A.9.4.C", "Objetive_Name": "System and Application Access Control", "Check_Summary": "Ensure IAM password policy requires minimum length of 14 or greater" } @@ -1097,13 +1097,13 @@ ] }, { - "Id": "A.9.4", + "Id": "A.9.4.D", "Description": "Ensure IAM password policy require at least one number", "Name": "System and Application Access Control", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.4", + "Objetive_ID": "A.9.4.D", "Objetive_Name": "System and Application Access Control", "Check_Summary": "Ensure IAM password policy require at least one number" } @@ -1113,13 +1113,13 @@ ] }, { - "Id": "A.9.4", + "Id": "A.9.4.E", "Description": "Ensure IAM password policy require at least one symbol", "Name": "System and Application Access Control", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.4", + "Objetive_ID": "A.9.4.E", "Objetive_Name": "System and Application Access Control", "Check_Summary": "Ensure IAM password policy require at least one symbol" } @@ -1129,13 +1129,13 @@ ] }, { - "Id": "A.9.4", + "Id": "A.9.4.F", "Description": "Ensure IAM password policy require at least one lowercase letter", "Name": "System and Application Access Control", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.4", + "Objetive_ID": "A.9.4.F", "Objetive_Name": "System and Application Access Control", "Check_Summary": "Ensure IAM password policy require at least one lowercase letter" } @@ -1145,13 +1145,13 @@ ] }, { - "Id": "A.9.4", + "Id": "A.9.4.G", "Description": "Ensure IAM password policy requires at least one uppercase letter", "Name": "System and Application Access Control", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.4", + "Objetive_ID": "A.9.4.G", "Objetive_Name": "System and Application Access Control", "Check_Summary": "Ensure IAM password policy requires at least one uppercase letter" } @@ -1161,13 +1161,13 @@ ] }, { - "Id": "A.9.4", + "Id": "A.9.4.H", "Description": "Avoid the use of the 'root' account", "Name": "System and Application Access Control", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.4", + "Objetive_ID": "A.9.4.H", "Objetive_Name": "System and Application Access Control", "Check_Summary": "Avoid the use of the 'root' account" } @@ -1177,13 +1177,13 @@ ] }, { - "Id": "A.9.4", + "Id": "A.9.4.I", "Description": "Ensure IAM policies are attached only to groups or roles", "Name": "System and Application Access Control", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.4", + "Objetive_ID": "A.9.4.I", "Objetive_Name": "System and Application Access Control", "Check_Summary": "Ensure IAM policies are attached only to groups or roles" } @@ -1193,13 +1193,13 @@ ] }, { - "Id": "A.9.4", + "Id": "A.9.4.J", "Description": "Ensure multi-factor authentication (MFA) is enabled for all IAM users that have console access", "Name": "System and Application Access Control", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.4", + "Objetive_ID": "A.9.4.J", "Objetive_Name": "System and Application Access Control", "Check_Summary": "Ensure multi-factor authentication (MFA) is enabled for all IAM users that have console access" } @@ -1209,13 +1209,13 @@ ] }, { - "Id": "A.9.4", + "Id": "A.9.4.K", "Description": "Ensure MFA is enabled for the 'root' account", "Name": "System and Application Access Control", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.4", + "Objetive_ID": "A.9.4.K", "Objetive_Name": "System and Application Access Control", "Check_Summary": "Ensure MFA is enabled for the 'root' account" } @@ -1225,13 +1225,13 @@ ] }, { - "Id": "A.9.4", + "Id": "A.9.4.L", "Description": "Ensure access keys are rotated every 90 days or less", "Name": "System and Application Access Control", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.4", + "Objetive_ID": "A.9.4.L", "Objetive_Name": "System and Application Access Control", "Check_Summary": "Ensure access keys are rotated every 90 days or less" } @@ -1241,13 +1241,13 @@ ] }, { - "Id": "A.9.4", + "Id": "A.9.4.M", "Description": "Ensure credentials unused for 90 days or greater are disabled", "Name": "System and Application Access Control", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.4", + "Objetive_ID": "A.9.4.M", "Objetive_Name": "System and Application Access Control", "Check_Summary": "Ensure credentials unused for 90 days or greater are disabled" } @@ -1258,13 +1258,13 @@ ] }, { - "Id": "A.9.4", + "Id": "A.9.4.N", "Description": "Ensure no root account access key exists", "Name": "System and Application Access Control", "Attributes": [ { "Category": "A.9 Access Control", - "Objetive_ID": "A.9.4", + "Objetive_ID": "A.9.4.N", "Objetive_Name": "System and Application Access Control", "Check_Summary": "Ensure no root account access key exists" } diff --git a/prowler/compliance/aws/soc2_aws.json b/prowler/compliance/aws/soc2_aws.json index 91c659e65c..44d4038528 100644 --- a/prowler/compliance/aws/soc2_aws.json +++ b/prowler/compliance/aws/soc2_aws.json @@ -547,6 +547,106 @@ "cloudwatch_log_group_retention_policy_specific_days_enabled", "kinesis_stream_data_retention_period" ] + }, + { + "Id": "pi_1_2", + "Name": "PI1.2 System inputs are measured and recorded completely, accurately, and timely to meet the entity's processing integrity commitments and system requirements", + "Description": "The entity implements policies and procedures over system inputs, including controls over completeness and accuracy, to result in products, services, and reporting to meet the entity's objectives. This includes defining accuracy targets, monitoring input quality, and creating detailed records of each input event.", + "Attributes": [ + { + "ItemId": "pi_1_2", + "Section": "PI1.0 - Processing Integrity", + "Service": "aws", + "Type": "automated" + } + ], + "Checks": [ + "apigateway_restapi_logging_enabled", + "apigatewayv2_api_access_logging_enabled", + "elbv2_logging_enabled", + "elb_logging_enabled", + "wafv2_webacl_logging_enabled", + "waf_global_webacl_logging_enabled", + "cloudtrail_s3_dataevents_write_enabled", + "cloudfront_distributions_logging_enabled" + ] + }, + { + "Id": "pi_1_3", + "Name": "PI1.3 Data is processed completely, accurately, and timely as authorized to meet the entity's processing integrity commitments and system requirements", + "Description": "The entity implements controls to ensure data is processed completely, accurately, and timely. This includes defining processing specifications, identifying processing activities, detecting and correcting errors throughout processing, recording processing activities with accurate logs, and ensuring completeness and timeliness of processing.", + "Attributes": [ + { + "ItemId": "pi_1_3", + "Section": "PI1.0 - Processing Integrity", + "Service": "aws", + "Type": "automated" + } + ], + "Checks": [ + "cloudtrail_multi_region_enabled", + "cloudtrail_log_file_validation_enabled", + "cloudtrail_cloudwatch_logging_enabled", + "cloudwatch_log_metric_filter_unauthorized_api_calls", + "cloudwatch_log_metric_filter_authentication_failures", + "cloudwatch_log_metric_filter_policy_changes", + "cloudwatch_log_metric_filter_root_usage", + "config_recorder_all_regions_enabled", + "rds_instance_integration_cloudwatch_logs", + "rds_cluster_integration_cloudwatch_logs", + "glue_etl_jobs_logging_enabled", + "stepfunctions_statemachine_logging_enabled" + ] + }, + { + "Id": "pi_1_4", + "Name": "PI1.4 System outputs are complete, accurate, distributed only to intended parties, and retained to meet the entity's processing integrity commitments and system requirements", + "Description": "The entity implements controls to ensure system outputs are delivered to authorized recipients in the correct format and protected against unauthorized access, modification, theft, destruction, or corruption. This includes output encryption, access controls, and audit trails for output delivery.", + "Attributes": [ + { + "ItemId": "pi_1_4", + "Section": "PI1.0 - Processing Integrity", + "Service": "aws", + "Type": "automated" + } + ], + "Checks": [ + "s3_bucket_default_encryption", + "s3_bucket_kms_encryption", + "cloudwatch_log_group_kms_encryption_enabled", + "sns_topics_kms_encryption_at_rest_enabled", + "kinesis_stream_encrypted_at_rest", + "cloudfront_distributions_field_level_encryption_enabled", + "cloudwatch_log_group_not_publicly_accessible", + "cloudwatch_cross_account_sharing_disabled", + "glue_etl_jobs_cloudwatch_logs_encryption_enabled", + "glue_etl_jobs_amazon_s3_encryption_enabled" + ] + }, + { + "Id": "pi_1_5", + "Name": "PI1.5 Stored data is maintained complete, accurate, and protected from unauthorized modification to meet the entity's processing integrity commitments and system requirements", + "Description": "The entity implements controls to protect stored inputs, items in processing, and outputs from theft, destruction, corruption, or deterioration. This includes data encryption at rest, key management, backup and recovery procedures, access controls, and data integrity validation.", + "Attributes": [ + { + "ItemId": "pi_1_5", + "Section": "PI1.0 - Processing Integrity", + "Service": "aws", + "Type": "automated" + } + ], + "Checks": [ + "s3_bucket_object_versioning", + "s3_bucket_object_lock", + "rds_instance_storage_encrypted", + "rds_cluster_storage_encrypted", + "dynamodb_tables_kms_cmk_encryption_enabled", + "ec2_ebs_volume_encryption", + "backup_plans_exist", + "backup_recovery_point_encrypted", + "backup_vaults_encrypted", + "kms_cmk_rotation_enabled" + ] } ] } diff --git a/prowler/compliance/azure/rbi_cyber_security_framework_azure.json b/prowler/compliance/azure/rbi_cyber_security_framework_azure.json new file mode 100644 index 0000000000..a58d49949d --- /dev/null +++ b/prowler/compliance/azure/rbi_cyber_security_framework_azure.json @@ -0,0 +1,248 @@ +{ + "Framework": "RBI-Cyber-Security-Framework", + "Name": "Reserve Bank of India (RBI) Cyber Security Framework", + "Version": "", + "Provider": "Azure", + "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.", + "Requirements": [ + { + "Id": "annex_i_1_1", + "Name": "Annex I (1.1)", + "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).", + "Attributes": [ + { + "ItemId": "annex_i_1_1", + "Service": "vm" + } + ], + "Checks": [ + "vm_ensure_using_approved_images", + "vm_ensure_using_managed_disks", + "vm_trusted_launch_enabled", + "aks_cluster_rbac_enabled", + "aks_clusters_created_with_private_nodes", + "appinsights_ensure_is_configured", + "containerregistry_admin_user_disabled" + ] + }, + { + "Id": "annex_i_1_3", + "Name": "Annex I (1.3)", + "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.", + "Attributes": [ + { + "ItemId": "annex_i_1_3", + "Service": "azure" + } + ], + "Checks": [ + "keyvault_key_rotation_enabled", + "keyvault_access_only_through_private_endpoints", + "keyvault_private_endpoints", + "keyvault_rbac_enabled", + "app_function_not_publicly_accessible", + "app_ensure_http_is_redirected_to_https", + "app_minimum_tls_version_12", + "storage_blob_public_access_level_is_disabled", + "storage_secure_transfer_required_is_enabled", + "storage_ensure_encryption_with_customer_managed_keys", + "storage_ensure_minimum_tls_version_12", + "storage_default_network_access_rule_is_denied", + "storage_ensure_private_endpoints_in_storage_accounts", + "network_ssh_internet_access_restricted", + "sqlserver_unrestricted_inbound_access", + "sqlserver_tde_encryption_enabled", + "sqlserver_tde_encrypted_with_cmk", + "cosmosdb_account_use_private_endpoints", + "cosmosdb_account_firewall_use_selected_networks", + "mysql_flexible_server_ssl_connection_enabled", + "mysql_flexible_server_minimum_tls_version_12", + "postgresql_flexible_server_enforce_ssl_enabled", + "aks_clusters_public_access_disabled", + "containerregistry_not_publicly_accessible", + "containerregistry_uses_private_link", + "aisearch_service_not_publicly_accessible" + ] + }, + { + "Id": "annex_i_5_1", + "Name": "Annex I (5.1)", + "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.", + "Attributes": [ + { + "ItemId": "annex_i_5_1", + "Service": "network" + } + ], + "Checks": [ + "network_rdp_internet_access_restricted", + "network_http_internet_access_restricted", + "network_udp_internet_access_restricted", + "network_ssh_internet_access_restricted", + "network_flow_log_captured_sent", + "network_flow_log_more_than_90_days", + "network_watcher_enabled", + "network_bastion_host_exists", + "aks_network_policy_enabled", + "storage_default_network_access_rule_is_denied" + ] + }, + { + "Id": "annex_i_6", + "Name": "Annex I (6)", + "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.", + "Attributes": [ + { + "ItemId": "annex_i_6", + "Service": "defender" + } + ], + "Checks": [ + "defender_ensure_system_updates_are_applied", + "defender_assessments_vm_endpoint_protection_installed", + "defender_ensure_defender_for_server_is_on", + "defender_ensure_defender_for_app_services_is_on", + "defender_ensure_defender_for_sql_servers_is_on", + "defender_ensure_defender_for_azure_sql_databases_is_on", + "defender_ensure_defender_for_storage_is_on", + "defender_ensure_defender_for_containers_is_on", + "defender_ensure_defender_for_keyvault_is_on", + "defender_ensure_defender_for_arm_is_on", + "defender_ensure_defender_for_dns_is_on", + "defender_ensure_defender_for_databases_is_on", + "defender_ensure_defender_for_cosmosdb_is_on", + "defender_container_images_scan_enabled", + "defender_container_images_resolved_vulnerabilities", + "defender_auto_provisioning_vulnerabilty_assessments_machines_on", + "vm_backup_enabled", + "app_ensure_java_version_is_latest", + "app_ensure_php_version_is_latest", + "app_ensure_python_version_is_latest" + ] + }, + { + "Id": "annex_i_7_1", + "Name": "Annex I (7.1)", + "Description": "Disallow administrative rights on end-user workstations/PCs/laptops and provide access rights on a 'need to know' and 'need to do' basis.", + "Attributes": [ + { + "ItemId": "annex_i_7_1", + "Service": "iam" + } + ], + "Checks": [ + "iam_role_user_access_admin_restricted", + "iam_subscription_roles_owner_custom_not_created", + "iam_custom_role_has_permissions_to_administer_resource_locks", + "entra_global_admin_in_less_than_five_users", + "entra_policy_ensure_default_user_cannot_create_apps", + "entra_policy_ensure_default_user_cannot_create_tenants", + "entra_policy_default_users_cannot_create_security_groups", + "entra_policy_guest_invite_only_for_admin_roles", + "entra_policy_guest_users_access_restrictions", + "app_function_identity_without_admin_privileges" + ] + }, + { + "Id": "annex_i_7_2", + "Name": "Annex I (7.2)", + "Description": "Passwords should be set as complex and lengthy and users should not use same passwords for all the applications/systems/devices.", + "Attributes": [ + { + "ItemId": "annex_i_7_2", + "Service": "entra" + } + ], + "Checks": [ + "entra_non_privileged_user_has_mfa", + "entra_privileged_user_has_mfa", + "entra_policy_user_consent_for_verified_apps", + "entra_policy_restricts_user_consent_for_apps", + "entra_user_with_vm_access_has_mfa", + "entra_security_defaults_enabled", + "entra_conditional_access_policy_require_mfa_for_management_api", + "entra_trusted_named_locations_exists", + "sqlserver_azuread_administrator_enabled", + "postgresql_flexible_server_entra_id_authentication_enabled", + "cosmosdb_account_use_aad_and_rbac" + ] + }, + { + "Id": "annex_i_7_3", + "Name": "Annex I (7.3)", + "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.", + "Attributes": [ + { + "ItemId": "annex_i_7_3", + "Service": "network" + } + ], + "Checks": [ + "network_rdp_internet_access_restricted", + "vm_jit_access_enabled", + "network_bastion_host_exists", + "vm_linux_enforce_ssh_authentication" + ] + }, + { + "Id": "annex_i_7_4", + "Name": "Annex I (7.4)", + "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.)", + "Attributes": [ + { + "ItemId": "annex_i_7_4", + "Service": "monitor" + } + ], + "Checks": [ + "monitor_alert_create_update_nsg", + "monitor_alert_delete_nsg", + "monitor_diagnostic_setting_with_appropriate_categories", + "monitor_diagnostic_settings_exists", + "monitor_alert_create_policy_assignment", + "monitor_alert_delete_policy_assignment", + "monitor_alert_create_update_security_solution", + "monitor_alert_delete_security_solution", + "monitor_alert_create_update_sqlserver_fr", + "monitor_alert_delete_sqlserver_fr", + "monitor_alert_create_update_public_ip_address_rule", + "monitor_alert_delete_public_ip_address_rule", + "monitor_alert_service_health_exists", + "monitor_storage_account_with_activity_logs_cmk_encrypted", + "monitor_storage_account_with_activity_logs_is_private", + "keyvault_logging_enabled", + "sqlserver_auditing_enabled", + "sqlserver_auditing_retention_90_days", + "app_http_logs_enabled", + "app_function_application_insights_enabled", + "defender_additional_email_configured_with_a_security_contact", + "defender_ensure_notify_alerts_severity_is_high", + "defender_ensure_notify_emails_to_owners", + "defender_ensure_mcas_is_enabled", + "defender_ensure_wdatp_is_enabled" + ] + }, + { + "Id": "annex_i_12", + "Name": "Annex I (12)", + "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).", + "Attributes": [ + { + "ItemId": "annex_i_12", + "Service": "azure" + } + ], + "Checks": [ + "vm_backup_enabled", + "vm_sufficient_daily_backup_retention_period", + "storage_ensure_file_shares_soft_delete_is_enabled", + "storage_blob_versioning_is_enabled", + "storage_ensure_soft_delete_is_enabled", + "storage_geo_redundant_enabled", + "keyvault_recoverable", + "sqlserver_vulnerability_assessment_enabled", + "sqlserver_va_periodic_recurring_scans_enabled" + ] + } + ] +} diff --git a/prowler/compliance/azure/soc2_azure.json b/prowler/compliance/azure/soc2_azure.json index bca12bb87c..438807895d 100644 --- a/prowler/compliance/azure/soc2_azure.json +++ b/prowler/compliance/azure/soc2_azure.json @@ -619,6 +619,92 @@ "sqlserver_auditing_retention_90_days", "storage_ensure_soft_delete_is_enabled" ] + }, + { + "Id": "pi_1_2", + "Name": "PI1.2 System inputs are measured and recorded completely, accurately, and timely to meet the entity's processing integrity commitments and system requirements", + "Description": "The entity implements policies and procedures over system inputs, including controls over completeness and accuracy, to result in products, services, and reporting to meet the entity's objectives. This includes defining accuracy targets, monitoring input quality, and creating detailed records of each input event.", + "Attributes": [ + { + "ItemId": "pi_1_2", + "Section": "PI1.0 - Processing Integrity", + "Service": "azure", + "Type": "automated" + } + ], + "Checks": [ + "app_http_logs_enabled", + "network_flow_log_captured_sent", + "keyvault_logging_enabled", + "monitor_diagnostic_settings_exists", + "sqlserver_auditing_enabled" + ] + }, + { + "Id": "pi_1_3", + "Name": "PI1.3 Data is processed completely, accurately, and timely as authorized to meet the entity's processing integrity commitments and system requirements", + "Description": "The entity implements controls to ensure data is processed completely, accurately, and timely. This includes defining processing specifications, identifying processing activities, detecting and correcting errors throughout processing, recording processing activities with accurate logs, and ensuring completeness and timeliness of processing.", + "Attributes": [ + { + "ItemId": "pi_1_3", + "Section": "PI1.0 - Processing Integrity", + "Service": "azure", + "Type": "automated" + } + ], + "Checks": [ + "monitor_diagnostic_setting_with_appropriate_categories", + "monitor_diagnostic_settings_exists", + "defender_auto_provisioning_log_analytics_agent_vms_on", + "mysql_flexible_server_audit_log_enabled", + "postgresql_flexible_server_log_checkpoints_on", + "postgresql_flexible_server_log_connections_on", + "postgresql_flexible_server_log_disconnections_on", + "network_flow_log_more_than_90_days" + ] + }, + { + "Id": "pi_1_4", + "Name": "PI1.4 System outputs are complete, accurate, distributed only to intended parties, and retained to meet the entity's processing integrity commitments and system requirements", + "Description": "The entity implements controls to ensure system outputs are delivered to authorized recipients in the correct format and protected against unauthorized access, modification, theft, destruction, or corruption. This includes output encryption, access controls, and audit trails for output delivery.", + "Attributes": [ + { + "ItemId": "pi_1_4", + "Section": "PI1.0 - Processing Integrity", + "Service": "azure", + "Type": "automated" + } + ], + "Checks": [ + "storage_ensure_encryption_with_customer_managed_keys", + "storage_infrastructure_encryption_is_enabled", + "monitor_storage_account_with_activity_logs_cmk_encrypted", + "monitor_storage_account_with_activity_logs_is_private", + "sqlserver_tde_encryption_enabled", + "sqlserver_tde_encrypted_with_cmk" + ] + }, + { + "Id": "pi_1_5", + "Name": "PI1.5 Stored data is maintained complete, accurate, and protected from unauthorized modification to meet the entity's processing integrity commitments and system requirements", + "Description": "The entity implements controls to protect stored inputs, items in processing, and outputs from theft, destruction, corruption, or deterioration. This includes data encryption at rest, key management, backup and recovery procedures, access controls, and data integrity validation.", + "Attributes": [ + { + "ItemId": "pi_1_5", + "Section": "PI1.0 - Processing Integrity", + "Service": "azure", + "Type": "automated" + } + ], + "Checks": [ + "storage_ensure_encryption_with_customer_managed_keys", + "storage_infrastructure_encryption_is_enabled", + "storage_ensure_soft_delete_is_enabled", + "vm_ensure_attached_disks_encrypted_with_cmk", + "vm_ensure_unattached_disks_encrypted_with_cmk", + "keyvault_key_rotation_enabled", + "keyvault_recoverable" + ] } ] -} +} \ No newline at end of file diff --git a/prowler/compliance/gcp/soc2_gcp.json b/prowler/compliance/gcp/soc2_gcp.json index d9355f26ef..03437ed347 100644 --- a/prowler/compliance/gcp/soc2_gcp.json +++ b/prowler/compliance/gcp/soc2_gcp.json @@ -492,6 +492,87 @@ "Checks": [ "cloudstorage_bucket_log_retention_policy_lock" ] + }, + { + "Id": "pi_1_2", + "Name": "PI1.2 System inputs are measured and recorded completely, accurately, and timely to meet the entity's processing integrity commitments and system requirements", + "Description": "The entity implements policies and procedures over system inputs, including controls over completeness and accuracy, to result in products, services, and reporting to meet the entity's objectives. This includes defining accuracy targets, monitoring input quality, and creating detailed records of each input event.", + "Attributes": [ + { + "ItemId": "pi_1_2", + "Section": "PI1.0 - Processing Integrity", + "Service": "gcp", + "Type": "automated" + } + ], + "Checks": [ + "compute_loadbalancer_logging_enabled", + "compute_subnet_flow_logs_enabled", + "logging_sink_created", + "iam_audit_logs_enabled" + ] + }, + { + "Id": "pi_1_3", + "Name": "PI1.3 Data is processed completely, accurately, and timely as authorized to meet the entity's processing integrity commitments and system requirements", + "Description": "The entity implements controls to ensure data is processed completely, accurately, and timely. This includes defining processing specifications, identifying processing activities, detecting and correcting errors throughout processing, recording processing activities with accurate logs, and ensuring completeness and timeliness of processing.", + "Attributes": [ + { + "ItemId": "pi_1_3", + "Section": "PI1.0 - Processing Integrity", + "Service": "gcp", + "Type": "automated" + } + ], + "Checks": [ + "logging_log_metric_filter_and_alert_for_audit_configuration_changes_enabled", + "logging_log_metric_filter_and_alert_for_project_ownership_changes_enabled", + "logging_log_metric_filter_and_alert_for_sql_instance_configuration_changes_enabled", + "cloudsql_instance_postgres_log_connections_flag", + "cloudsql_instance_postgres_log_disconnections_flag", + "cloudsql_instance_postgres_log_statement_flag", + "iam_audit_logs_enabled" + ] + }, + { + "Id": "pi_1_4", + "Name": "PI1.4 System outputs are complete, accurate, distributed only to intended parties, and retained to meet the entity's processing integrity commitments and system requirements", + "Description": "The entity implements controls to ensure system outputs are delivered to authorized recipients in the correct format and protected against unauthorized access, modification, theft, destruction, or corruption. This includes output encryption, access controls, and audit trails for output delivery.", + "Attributes": [ + { + "ItemId": "pi_1_4", + "Section": "PI1.0 - Processing Integrity", + "Service": "gcp", + "Type": "automated" + } + ], + "Checks": [ + "cloudstorage_bucket_uniform_bucket_level_access", + "bigquery_dataset_cmk_encryption", + "bigquery_table_cmk_encryption", + "compute_instance_confidential_computing_enabled", + "pubsub_topic_encryption_with_cmk" + ] + }, + { + "Id": "pi_1_5", + "Name": "PI1.5 Stored data is maintained complete, accurate, and protected from unauthorized modification to meet the entity's processing integrity commitments and system requirements", + "Description": "The entity implements controls to protect stored inputs, items in processing, and outputs from theft, destruction, corruption, or deterioration. This includes data encryption at rest, key management, backup and recovery procedures, access controls, and data integrity validation.", + "Attributes": [ + { + "ItemId": "pi_1_5", + "Section": "PI1.0 - Processing Integrity", + "Service": "gcp", + "Type": "automated" + } + ], + "Checks": [ + "cloudstorage_bucket_log_retention_policy_lock", + "cloudsql_instance_automated_backups", + "compute_instance_encryption_with_csek_enabled", + "kms_key_rotation_enabled", + "dataproc_encrypted_with_cmks_disabled" + ] } ] -} +} \ No newline at end of file diff --git a/prowler/providers/gcp/services/cloudstorage/cloudstorage_service.py b/prowler/providers/gcp/services/cloudstorage/cloudstorage_service.py index cdfdd5c18c..1a67f7dd7e 100644 --- a/prowler/providers/gcp/services/cloudstorage/cloudstorage_service.py +++ b/prowler/providers/gcp/services/cloudstorage/cloudstorage_service.py @@ -1,5 +1,6 @@ from typing import Optional +from googleapiclient.errors import HttpError from pydantic.v1 import BaseModel from prowler.lib.logger import logger @@ -12,6 +13,7 @@ class CloudStorage(GCPService): def __init__(self, provider: GcpProvider): super().__init__("storage", provider) self.buckets = [] + self.vpc_service_controls_protected_projects = set() self._get_buckets() def _get_buckets(self): @@ -93,6 +95,17 @@ class CloudStorage(GCPService): request = self.client.buckets().list_next( previous_request=request, previous_response=response ) + except HttpError as http_error: + # Check if the error is due to VPC Service Controls blocking the API + if "vpcServiceControlsUniqueIdentifier" in str(http_error): + self.vpc_service_controls_protected_projects.add(project_id) + logger.warning( + f"Project {project_id} is protected by VPC Service Controls for Cloud Storage API." + ) + else: + logger.error( + f"{http_error.__class__.__name__}[{http_error.__traceback__.tb_lineno}]: {http_error}" + ) except Exception as error: logger.error( f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" diff --git a/prowler/providers/gcp/services/cloudstorage/cloudstorage_uses_vpc_service_controls/cloudstorage_uses_vpc_service_controls.py b/prowler/providers/gcp/services/cloudstorage/cloudstorage_uses_vpc_service_controls/cloudstorage_uses_vpc_service_controls.py index ea0330f296..43ad20093a 100644 --- a/prowler/providers/gcp/services/cloudstorage/cloudstorage_uses_vpc_service_controls/cloudstorage_uses_vpc_service_controls.py +++ b/prowler/providers/gcp/services/cloudstorage/cloudstorage_uses_vpc_service_controls/cloudstorage_uses_vpc_service_controls.py @@ -5,14 +5,22 @@ from prowler.providers.gcp.services.accesscontextmanager.accesscontextmanager_cl from prowler.providers.gcp.services.cloudresourcemanager.cloudresourcemanager_client import ( cloudresourcemanager_client, ) +from prowler.providers.gcp.services.cloudstorage.cloudstorage_client import ( + cloudstorage_client, +) class cloudstorage_uses_vpc_service_controls(Check): """ Ensure Cloud Storage is protected by VPC Service Controls at project level. - Reports PASS if a project is in a VPC Service Controls perimeter - with storage.googleapis.com as a restricted service, otherwise FAIL. + Reports PASS if: + - A project is in a VPC Service Controls perimeter with storage.googleapis.com + as a restricted service, OR + - The Cloud Storage API access is blocked by VPC Service Controls + (verified by vpcServiceControlsUniqueIdentifier in the error response) + + Otherwise reports FAIL. """ def execute(self) -> list[Check_Report_GCP]: @@ -47,6 +55,12 @@ class cloudstorage_uses_vpc_service_controls(Check): if project_resource_id in protected_projects: report.status = "PASS" report.status_extended = f"Project {project.id} has VPC Service Controls enabled for Cloud Storage in perimeter {protected_projects[project_resource_id]}." + elif ( + project.id + in cloudstorage_client.vpc_service_controls_protected_projects + ): + report.status = "PASS" + report.status_extended = f"Project {project.id} has VPC Service Controls enabled for Cloud Storage in undetermined perimeter (verified by API access restriction)." findings.append(report) diff --git a/tests/providers/gcp/services/cloudstorage/cloudstorage_service_test.py b/tests/providers/gcp/services/cloudstorage/cloudstorage_service_test.py index 0d98e00f6e..0008265049 100644 --- a/tests/providers/gcp/services/cloudstorage/cloudstorage_service_test.py +++ b/tests/providers/gcp/services/cloudstorage/cloudstorage_service_test.py @@ -1,4 +1,6 @@ -from unittest.mock import patch +from unittest.mock import MagicMock, patch + +from googleapiclient.errors import HttpError from prowler.providers.gcp.services.cloudstorage.cloudstorage_service import ( CloudStorage, @@ -56,3 +58,36 @@ class TestCloudStorageService: assert not cloudstorage_client.buckets[1].public assert cloudstorage_client.buckets[1].retention_policy is None assert cloudstorage_client.buckets[1].project_id == GCP_PROJECT_ID + + def test_vpc_service_controls_blocked(self): + with ( + patch( + "prowler.providers.gcp.lib.service.service.GCPService.__is_api_active__", + new=mock_is_api_active, + ), + patch( + "prowler.providers.gcp.lib.service.service.GCPService.__generate_client__", + ) as mock_client, + ): + mock_resp = MagicMock() + mock_resp.status = 403 + mock_resp.reason = "Forbidden" + + vpc_error = HttpError( + resp=mock_resp, + content=b'{"error": {"message": "Request is prohibited by organization\'s policy. vpcServiceControlsUniqueIdentifier: 12345"}}', + ) + + mock_buckets = MagicMock() + mock_buckets.list.return_value.execute.side_effect = vpc_error + mock_client.return_value.buckets.return_value = mock_buckets + + cloudstorage_client = CloudStorage( + set_mocked_gcp_provider(project_ids=[GCP_PROJECT_ID]) + ) + + assert ( + GCP_PROJECT_ID + in cloudstorage_client.vpc_service_controls_protected_projects + ) + assert len(cloudstorage_client.buckets) == 0 diff --git a/tests/providers/gcp/services/cloudstorage/cloudstorage_uses_vpc_service_controls/cloudstorage_uses_vpc_service_controls_test.py b/tests/providers/gcp/services/cloudstorage/cloudstorage_uses_vpc_service_controls/cloudstorage_uses_vpc_service_controls_test.py index e51dc35166..89d7e30673 100644 --- a/tests/providers/gcp/services/cloudstorage/cloudstorage_uses_vpc_service_controls/cloudstorage_uses_vpc_service_controls_test.py +++ b/tests/providers/gcp/services/cloudstorage/cloudstorage_uses_vpc_service_controls/cloudstorage_uses_vpc_service_controls_test.py @@ -315,3 +315,70 @@ class TestCloudStorageUsesVPCServiceControls: result = check.execute() assert len(result) == 0 + + def test_project_protected_by_vpc_sc_api_blocked(self): + cloudresourcemanager_client = mock.MagicMock() + accesscontextmanager_client = mock.MagicMock() + cloudstorage_client = mock.MagicMock() + + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=set_mocked_gcp_provider(), + ), + mock.patch( + "prowler.providers.gcp.services.cloudstorage.cloudstorage_uses_vpc_service_controls.cloudstorage_uses_vpc_service_controls.cloudresourcemanager_client", + new=cloudresourcemanager_client, + ), + mock.patch( + "prowler.providers.gcp.services.cloudstorage.cloudstorage_uses_vpc_service_controls.cloudstorage_uses_vpc_service_controls.accesscontextmanager_client", + new=accesscontextmanager_client, + ), + mock.patch( + "prowler.providers.gcp.services.cloudstorage.cloudstorage_uses_vpc_service_controls.cloudstorage_uses_vpc_service_controls.cloudstorage_client", + new=cloudstorage_client, + ), + ): + from prowler.providers.gcp.services.cloudresourcemanager.cloudresourcemanager_service import ( + Project, + ) + from prowler.providers.gcp.services.cloudstorage.cloudstorage_uses_vpc_service_controls.cloudstorage_uses_vpc_service_controls import ( + cloudstorage_uses_vpc_service_controls, + ) + + project1 = Project( + id=GCP_PROJECT_ID, number="123456789012", audit_logging=True + ) + + cloudresourcemanager_client.project_ids = [GCP_PROJECT_ID] + cloudresourcemanager_client.cloud_resource_manager_projects = [project1] + cloudresourcemanager_client.projects = { + GCP_PROJECT_ID: GCPProject( + id=GCP_PROJECT_ID, + number="123456789012", + name="test-project", + labels={}, + lifecycle_state="ACTIVE", + ) + } + cloudresourcemanager_client.region = GCP_US_CENTER1_LOCATION + + # No service perimeters configured, but API access is blocked by VPC SC + accesscontextmanager_client.service_perimeters = [] + cloudstorage_client.vpc_service_controls_protected_projects = { + GCP_PROJECT_ID + } + + check = cloudstorage_uses_vpc_service_controls() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Project {GCP_PROJECT_ID} has VPC Service Controls enabled for Cloud Storage in undetermined perimeter (verified by API access restriction)." + ) + assert result[0].resource_id == GCP_PROJECT_ID + assert result[0].resource_name == "test-project" + assert result[0].location == GCP_US_CENTER1_LOCATION + assert result[0].project_id == GCP_PROJECT_ID