> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# S3 Logs Should Have Encryption Enabled CodeBuild Project

### More Info:

This rule ensures that encryption is enabled for logs stored in Amazon S3 for an AWS CodeBuild project. Enabling encryption helps protect sensitive build logs from unauthorized access or tampering. It ensures that logs are encrypted while stored, providing an additional layer of security.

### Risk Level

Medium

### Address

Security

### Compliance Standards

* APRA CPS 234 (Australia)
* AWS Startup Security Baseline
* BSI C5 (Germany)
* Brazil LGPD
* CCPA / CPRA (California)
* CIS Critical Security Controls v8
* CMMC 2.0
* CSA Cloud Controls Matrix v4
* Cloudanix Best Practice
* DPDPA
* Digital Operational Resilience Act (EU)
* ISO/IEC 27017
* ISO/IEC 27018
* ISO/IEC 27701
* KSA PDPL
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* Reserve Bank of India (RBI) Cyber Security Framework
* SWIFT Customer Security Controls Framework
* Sarbanes-Oxley IT General Controls
* Securities and Exchange Board of India (SEBI) - Cloud Security Adoption Framework
* UK NCSC Cyber Assessment Framework

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        To remediate “S3 Logs Should Have Encryption Enabled” for an AWS CodeBuild project via the AWS Console, you need to:

        1. Ensure the S3 bucket used for CodeBuild logs has default encryption enabled
        2. Ensure the CodeBuild project logging configuration uses that bucket (and, optionally, a KMS key)

        ***

        ### 1. Identify the S3 bucket used for CodeBuild logs

        1. Go to **AWS Console** → **CodeBuild**.
        2. In the left menu, click **Build projects**.
        3. Click on your **CodeBuild project**.
        4. Go to the **Build details** page → click **Edit**.
        5. Scroll down to the **Logs** section.
        6. Under **S3 logs**, note:
           * Whether S3 logging is **Enabled**.
           * The **S3 bucket name** and **path prefix** (this is the bucket you will configure).

        If S3 logs are **Disabled**, turn them **On** and specify the desired S3 bucket. Then continue.

        ***

        ### 2. Enable encryption on the S3 bucket

        1. Go to **S3** in the AWS Console.
        2. Click on the **bucket** identified in step 1.
        3. Go to the **Properties** tab.
        4. Scroll to **Default encryption** and click **Edit**.
        5. Turn **Enable** on.
        6. Choose one:
           * **Server-side encryption with Amazon S3-managed keys (SSE-S3)**
             * Simple and usually sufficient: select **AES-256** (SSE-S3).
           * **Server-side encryption with AWS KMS keys (SSE-KMS)**
             * Choose **AWS managed key** or a **customer managed KMS key**.
        7. Click **Save changes**.

        This ensures all new objects (including CodeBuild logs) written to this bucket are encrypted.

        ***

        ### 3. (Optional) Ensure CodeBuild log config is consistent with KMS usage

        If you chose **SSE-KMS**:

        1. Stay in the S3 bucket’s **Permissions** tab.
        2. Make sure the KMS key policy allows **CodeBuild** and any **IAM roles** used by CodeBuild to use the key (`kms:Encrypt`, `kms:Decrypt`, `kms:GenerateDataKey`, `kms:DescribeKey` as needed).
        3. If you used a **customer managed key**, go to **AWS KMS** → **Customer managed keys** → select the key:
           * Under **Key policy**, ensure the **CodeBuild service role** is allowed to use the key.

        ***

        ### 4. Confirm/adjust CodeBuild project logging settings

        1. Go back to **CodeBuild** → **Build projects** → select your project.
        2. Click **Edit**.
        3. In the **Logs** section:
           * Under **S3 logs**, ensure **Enabled** is selected.
           * Verify the **S3 bucket** is the encrypted one you configured.
           * Optionally set **S3 log prefix** for organization.
        4. Click **Update artifacts** / **Update** / **Save** at the bottom (exact text may vary).

        ***

        ### 5. Validate

        1. Trigger a new **build** for that project.
        2. Go to the **S3 bucket** → **Objects**.
        3. Open a recent log object → under **Properties**, confirm:
           * **Server-side encryption** is shown (either `SSE-S3` or `SSE-KMS` with the selected key).

        Your CodeBuild S3 logs are now encrypted, satisfying the “S3 Logs Should Have Encryption Enabled” requirement.
      </Accordion>

      <Accordion title="Using CLI">
        To fix “S3 Logs Should Have Encryption Enabled” for an AWS CodeBuild project via AWS CLI, you must update the project’s `logsConfig.s3Logs` to have `encryptionDisabled=false` (or omit it) and ensure the S3 bucket is encrypted.

        Below are minimal step‑by‑step CLI instructions.

        ***

        ### 1. Identify the CodeBuild project and inspect its log config

        ```bash theme={null}
        aws codebuild batch-get-projects \
          --names MyCodeBuildProject \
          --query 'projects[0].logsConfig.s3Logs'
        ```

        Check if you see `encryptionDisabled: true`.

        ***

        ### 2. (Optional but recommended) Enable default encryption on the S3 bucket

        If your log bucket isn’t already encrypted, turn on default SSE-S3 or SSE-KMS.

        **SSE-S3 (S3-managed keys):**

        ```bash theme={null}
        aws s3api put-bucket-encryption \
          --bucket my-codebuild-logs-bucket \
          --server-side-encryption-configuration '{
            "Rules": [
              {
                "ApplyServerSideEncryptionByDefault": {
                  "SSEAlgorithm": "AES256"
                }
              }
            ]
          }'
        ```

        **SSE-KMS (customer-managed KMS key):**

        ```bash theme={null}
        aws s3api put-bucket-encryption \
          --bucket my-codebuild-logs-bucket \
          --server-side-encryption-configuration '{
            "Rules": [
              {
                "ApplyServerSideEncryptionByDefault": {
                  "SSEAlgorithm": "aws:kms",
                  "KMSMasterKeyID": "arn:aws:kms:us-east-1:111122223333:key/your-kms-key-id"
                }
              }
            ]
          }'
        ```

        ***

        ### 3. Get the full current project definition

        You must provide the full project configuration to `update-project`, not just the logs.

        ```bash theme={null}
        aws codebuild batch-get-projects \
          --names MyCodeBuildProject \
          --query 'projects[0]' \
          --output json > project.json
        ```

        ***

        ### 4. Edit `project.json` to fix `logsConfig.s3Logs`

        In `project.json`, find `logsConfig.s3Logs` and set:

        ```json theme={null}
        "logsConfig": {
          "cloudWatchLogs": {
            "status": "DISABLED"
          },
          "s3Logs": {
            "status": "ENABLED",
            "location": "my-codebuild-logs-bucket/my-logs-prefix",
            "encryptionDisabled": false
          }
        }
        ```

        Notes:

        * `status` must be `"ENABLED"`.
        * `location` is `bucket-name[/optional/prefix]`.
        * `encryptionDisabled: false` (or remove the field) ensures encryption is enabled. CodeBuild will use SSE-S3 for objects it writes; the bucket policy/encryption settings will enforce SSE-S3 or SSE-KMS as configured.

        Do not change other fields unless needed.

        ***

        ### 5. Update the project using the modified JSON

        ```bash theme={null}
        aws codebuild update-project \
          --cli-input-json file://project.json
        ```

        ***

        ### 6. Verify the change

        ```bash theme={null}
        aws codebuild batch-get-projects \
          --names MyCodeBuildProject \
          --query 'projects[0].logsConfig.s3Logs'
        ```

        You should now see `"status": "ENABLED"` and either no `encryptionDisabled` field or `encryptionDisabled: false`. The S3 bucket should also show encryption configuration via:

        ```bash theme={null}
        aws s3api get-bucket-encryption \
          --bucket my-codebuild-logs-bucket
        ```
      </Accordion>

      <Accordion title="Using Python">
        To fix this for an AWS CodeBuild project using Python/boto3 you need to do **two things**:

        1. Ensure the **S3 bucket used for CodeBuild logs has encryption enabled**
        2. Ensure the **CodeBuild project is configured to use encrypted S3 logs** (i.e., `encryptionDisabled=False`)

        Below are step‑by‑step instructions and an example Python remediation script.

        ***

        ## 1. Identify the CodeBuild project and its S3 log settings

        First, find the project and its current S3 log configuration.

        ```python theme={null}
        import boto3

        codebuild = boto3.client('codebuild')

        project_name = "YOUR_CODEBUILD_PROJECT_NAME"

        response = codebuild.batch_get_projects(names=[project_name])
        project = response['projects'][0]

        print(project.get('logsConfig', {}))
        ```

        Look for:

        ```json theme={null}
        "logsConfig": {
          "s3Logs": {
            "status": "ENABLED",
            "location": "your-logs-bucket/path",
            "encryptionDisabled": false,
            "bucketOwnerAccess": "FULL"
          },
          "cloudWatchLogs": { ... }
        }
        ```

        You need:

        * `"status": "ENABLED"`
        * `"encryptionDisabled": false` (or omitted; default is encrypted if bucket has default SSE)
        * The `location` bucket to have default SSE.

        ***

        ## 2. Enable default encryption on the S3 bucket used for logs

        If the S3 bucket doesn’t have default encryption, enable it (SSE-S3 or SSE-KMS).

        ```python theme={null}
        import boto3
        from urllib.parse import urlparse

        s3 = boto3.client('s3')

        # Extract bucket name from the "location" field, e.g. "my-logs-bucket/logs/path"
        location = project.get('logsConfig', {}).get('s3Logs', {}).get('location')
        bucket_name = location.split('/', 1)[0] if location else "YOUR_LOGS_BUCKET"

        # Option A: SSE-S3 (AES256) - simplest
        s3.put_bucket_encryption(
            Bucket=bucket_name,
            ServerSideEncryptionConfiguration={
                'Rules': [{
                    'ApplyServerSideEncryptionByDefault': {
                        'SSEAlgorithm': 'AES256'
                    }
                }]
            }
        )

        # Option B (optional): SSE-KMS (if you want a specific KMS key)
        # kms_key_arn = "arn:aws:kms:REGION:ACCOUNT:key/KEY_ID"
        # s3.put_bucket_encryption(
        #     Bucket=bucket_name,
        #     ServerSideEncryptionConfiguration={
        #         'Rules': [{
        #             'ApplyServerSideEncryptionByDefault': {
        #                 'SSEAlgorithm': 'aws:kms',
        #                 'KMSMasterKeyID': kms_key_arn
        #             }
        #         }]
        #     }
        # )
        ```

        This ensures that **all new objects**, including CodeBuild logs, are encrypted by default.

        ***

        ## 3. Ensure CodeBuild S3 logs are enabled and not marked as unencrypted

        You now need to update the CodeBuild project so that:

        * S3 logs are **ENABLED**
        * `encryptionDisabled` is **False** or omitted

        The `update_project` API requires you to send a mostly complete project definition. The simplest way is:

        1. Get existing project definition
        2. Modify it
        3. Call `update_project`

        ```python theme={null}
        import copy
        import boto3

        codebuild = boto3.client('codebuild')
        project_name = "YOUR_CODEBUILD_PROJECT_NAME"

        # 1. Get the existing project
        resp = codebuild.batch_get_projects(names=[project_name])
        project = resp['projects'][0]

        # 2. Build the update payload from the existing project
        update_args = {
            'name': project['name'],
            'description': project.get('description'),
            'source': project['source'],
            'artifacts': project['artifacts'],
            'environment': project['environment'],
            'serviceRole': project['serviceRole'],
            'timeoutInMinutes': project.get('timeoutInMinutes'),
            'queuedTimeoutInMinutes': project.get('queuedTimeoutInMinutes'),
            'encryptionKey': project.get('encryptionKey'),
            'tags': project.get('tags'),
            'vpcConfig': project.get('vpcConfig'),
            'badgeEnabled': project.get('badgeEnabled'),
            'logsConfig': project.get('logsConfig', {}),
            'fileSystemLocations': project.get('fileSystemLocations'),
            'buildBatchConfig': project.get('buildBatchConfig'),
            'concurrentBuildLimit': project.get('concurrentBuildLimit'),
            'cache': project.get('cache'),
            'secondarySources': project.get('secondarySources'),
            'secondaryArtifacts': project.get('secondaryArtifacts'),
            'sourceVersion': project.get('sourceVersion'),
        }

        # Clean out any None values (CodeBuild API doesn’t like explicit None)
        update_args = {k: v for k, v in update_args.items() if v is not None}

        # 3. Adjust S3 logs config
        logs_config = update_args.get('logsConfig', {})

        # Make sure s3Logs is defined
        s3_logs = logs_config.get('s3Logs', {})
        s3_logs['status'] = 'ENABLED'
        # Use same bucket; if you want a path, include "/logs/" etc.
        s3_logs['location'] = bucket_name  
        s3_logs['encryptionDisabled'] = False  # explicitly enforce encryption

        logs_config['s3Logs'] = s3_logs
        update_args['logsConfig'] = logs_config

        # 4. Update the project
        codebuild.update_project(**update_args)
        print("Updated CodeBuild project to use encrypted S3 logs.")
        ```

        ***

        ## 4. (Optional) Simple remediation script that just sets S3 log encryption

        If you only want a focused script that:

        * Takes a project name and bucket
        * Ensures bucket encryption
        * Enables S3 logs with encryption

        ```python theme={null}
        import boto3

        def remediate_codebuild_s3_logs(project_name, bucket_name, region=None):
            session = boto3.Session(region_name=region)
            codebuild = session.client('codebuild')
            s3 = session.client('s3')

            # 1) Enable default encryption on bucket
            s3.put_bucket_encryption(
                Bucket=bucket_name,
                ServerSideEncryptionConfiguration={
                    'Rules': [{
                        'ApplyServerSideEncryptionByDefault': {
                            'SSEAlgorithm': 'AES256'
                        }
                    }]
                }
            )

            # 2) Get existing project
            resp = codebuild.batch_get_projects(names=[project_name])
            if not resp['projects']:
                raise ValueError(f"Project {project_name} not found")
            project = resp['projects'][0]

            # 3) Build update payload
            update_args = {
                'name': project['name'],
                'source': project['source'],
                'artifacts': project['artifacts'],
                'environment': project['environment'],
                'serviceRole': project['serviceRole'],
            }

            # Include optional fields if present
            optional_fields = [
                'description','timeoutInMinutes','queuedTimeoutInMinutes','encryptionKey',
                'tags','vpcConfig','badgeEnabled','logsConfig','fileSystemLocations',
                'buildBatchConfig','concurrentBuildLimit','cache',
                'secondarySources','secondaryArtifacts','sourceVersion'
            ]
            for f in optional_fields:
                if f in project:
                    update_args[f] = project[f]

            # Ensure S3 logs are enabled and encrypted
            logs_config = update_args.get('logsConfig', {})
            s3_logs = logs_config.get('s3Logs', {})
            s3_logs['status'] = 'ENABLED'
            s3_logs['location'] = bucket_name
            s3_logs['encryptionDisabled'] = False
            logs_config['s3Logs'] = s3_logs
            update_args['logsConfig'] = logs_config

            codebuild.update_project(**update_args)
            print(f"Remediated S3 logs for project {project_name} with encrypted bucket {bucket_name}")

        # Example usage
        # remediate_codebuild_s3_logs("my-codebuild-project", "my-logs-bucket", region="us-east-1")
        ```

        This aligns with the “S3 logs should have encryption enabled” control: logs are stored in an S3 bucket with default SSE, and the CodeBuild project is configured not to disable encryption.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        resource "aws_codebuild_project" "THIS_PROJECT" {
          name          = "CODEBUILD_PROJECT_NAME" # replace with your project name
          service_role  = "CODEBUILD_SERVICE_ROLE_ARN"
          artifacts {
            type = "NO_ARTIFACTS"
          }
          environment {
            compute_type                = "BUILD_GENERAL1_SMALL"
            image                       = "aws/codebuild/standard:7.0"
            type                        = "LINUX_CONTAINER"
            privileged_mode             = false
          }
          source {
            type            = "GITHUB"
            location        = "GITHUB_REPO_URL"
            git_clone_depth = 1
          }

          # Ensure S3 logs have encryption enabled
          logs_config {
            s3_logs {
              status              = "ENABLED"
              location            = "S3_BUCKET_NAME/OPTIONAL_PREFIX" # e.g. "my-logs-bucket/codebuild"
              encryption_disabled = false
            }

            # If you also use CloudWatch logs, keep them here so they are not removed
            cloudwatch_logs {
              status      = "ENABLED"
              group_name  = "CLOUDWATCH_LOG_GROUP_NAME"
              stream_name = "CLOUDWATCH_LOG_STREAM_NAME"
            }
          }
        }
        ```

        This change does not replace the CodeBuild project; it updates the logs configuration in place, but note that `logs_config` is managed as a whole, so any existing CloudWatch/S3 log settings must be represented in this block or Terraform will remove them.

        To verify, `terraform plan` should show an in-place update (`~`) to `aws_codebuild_project.THIS_PROJECT.logs_config.s3_logs.encryption_disabled` changing from `true` (or `null`) to `false` (and any other log settings you added/updated).
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://docs.aws.amazon.com/config/latest/developerguide/codebuild-project-s3-logs-encrypted.html](https://docs.aws.amazon.com/config/latest/developerguide/codebuild-project-s3-logs-encrypted.html)
