> ## 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.

# OCI Storage Buckets Should Be Encrypted With Customer-Managed Keys

### More Info:

Buckets must be encrypted using a dedicated KMS key. Relying on default encryption limits auditing visibility and prevents security teams from enforcing granular key rotation or revocation policies

### Risk Level

High

### Address

Compliance, Security

### Compliance Standards

* APRA CPS 234 (Australia)
* AWS Well Architected Framework
* BSI C5 (Germany)
* Brazil LGPD
* CCPA / CPRA (California)
* CIS Critical Security Controls v8
* CMMC 2.0
* CSA Cloud Controls Matrix v4
* DPDPA
* Digital Operational Resilience Act (EU)
* Essential 8
* HITRUST CSF
* ISO/IEC 27017
* ISO/IEC 27018
* ISO/IEC 27701
* KSA PDPL
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIS2 Directive
* NIST
* NIST CSF
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* PCI
* SOC2
* 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">
        Below are step‑by‑step OCI Console instructions to remediate the finding “OCI Storage Buckets Should Be Encrypted With Customer‑Managed Keys” by moving an Object Storage bucket from Oracle‑managed keys to customer‑managed keys (CMK).

        ***

        ## 1. Prepare a Customer-Managed Key (if you don’t have one)

        1. Sign in to the **OCI Console**.
        2. From the left menu, go to **Identity & Security → Vault**.
        3. Make sure you are in the correct **Compartment** and **Region**.
        4. If you don’t already have a vault:
           1. Click **Create vault**.
           2. Enter a **Name**, choose **Type** (generally *Default*), select the **Compartment**, and click **Create vault**.
           3. Wait for the vault status to become **Active**.
        5. Inside the vault, create a key:
           1. Open the vault you just created.
           2. Click **Master Encryption Keys** (or **Keys**).
           3. Click **Create key**.
           4. Enter a **Name** and optional **Description**.
           5. Choose **Key Shape** (e.g., AES, 256‑bit).
           6. Click **Create key** and wait until it is **Enabled/Active**.

        Note the **OCID** or simply remember the **Key name** and **Vault name**; you’ll need to select this key when updating the bucket.

        ***

        ## 2. Update the Bucket to Use the Customer-Managed Key

        1. In the Console, go to **Storage → Buckets**.
        2. Select the correct **Compartment** in the left pane.
        3. Click on the **bucket name** that has the misconfiguration (currently using Oracle-managed encryption).
        4. On the bucket details page, click **Edit** (or **Edit bucket**).
        5. Find the **Encryption** section:
           * By default, it is usually set to **Encrypt using Oracle-managed keys**.
        6. Change the encryption setting to:
           * **Encrypt using customer-managed keys**.
        7. A **Vault** and **Key** selector will appear:
           1. Choose the **Vault** that contains your CMK.
           2. Choose the **Key** (customer-managed key) you created in step 1.
        8. Click **Save changes** (or **Update**).

        The bucket will now use your customer-managed key for encryption of new objects and re-encryption of data as per OCI behavior.

        ***

        ## 3. (Optional) Verify via Security/Monitoring

        If you’re using OCI Cloud Guard / Security Zones / other monitoring:

        1. Open **Cloud Guard** (or your monitoring tool).
        2. Run or wait for the next **Detector** evaluation against Object Storage.
        3. Confirm that the finding for that bucket is now **Resolved** or no longer appears.

        ***

        ## 4. Repeat for All Affected Buckets

        Repeat section **2** for every Object Storage bucket flagged by your monitoring as not using customer‑managed keys.
      </Accordion>

      <Accordion title="Using CLI">
        To enforce “OCI Object Storage buckets must be encrypted with customer-managed keys” using the OCI CLI, you need to:

        1. Have a Vault and a Master Encryption Key.
        2. Update each bucket to use that key via `--kms-key-id`.

        Below are step‑by‑step CLI instructions.

        ***

        ## 1. Prerequisites

        * OCI CLI installed and configured (`oci setup config` already done).
        * Permissions:
          * To manage keys and vaults.
          * To manage buckets in the compartments you care about.

        Assume:

        * Tenancy OCID: `<TENANCY_OCID>`
        * Compartment OCID for buckets: `<COMPARTMENT_OCID>`
        * Region: `<REGION>`

        Set:

        ```bash theme={null}
        export OCI_REGION="<REGION>"
        ```

        ***

        ## 2. Create (or identify) a Vault and Key

        ### 2.1. List existing vaults (if you already have one, you can skip creation)

        ```bash theme={null}
        oci kms management vault list \
          --compartment-id <COMPARTMENT_OCID> \
          --all
        ```

        Note `id` of the vault you want to use, or create a new one.

        ### 2.2. Create a new vault (if needed)

        ```bash theme={null}
        oci kms management vault create \
          --compartment-id <COMPARTMENT_OCID> \
          --display-name "cmk-vault-monitoring" \
          --vault-type DEFAULT
        ```

        Capture the `id` from the output as `VAULT_ID`:

        ```bash theme={null}
        export VAULT_ID="<VAULT_OCID>"
        ```

        ### 2.3. Wait until vault is ACTIVE (if newly created)

        ```bash theme={null}
        oci kms management vault get --vault-id "$VAULT_ID" \
          --query 'data."lifecycle-state"' --raw-output
        ```

        Repeat until it shows `ACTIVE`.

        ***

        ## 3. Create a Master Encryption Key

        ### 3.1. Get the vault’s management endpoint

        ```bash theme={null}
        export MANAGEMENT_ENDPOINT=$( \
          oci kms management vault get --vault-id "$VAULT_ID" \
          --query 'data."management-endpoint"' --raw-output \
        )
        ```

        ### 3.2. Create a key

        ```bash theme={null}
        oci kms management key create \
          --compartment-id <COMPARTMENT_OCID> \
          --endpoint "$MANAGEMENT_ENDPOINT" \
          --display-name "cmk-obj-storage-monitoring" \
          --protection-mode HSM \
          --key-shape '{"algorithm": "AES", "length": 256}'
        ```

        Capture the `id` of the key:

        ```bash theme={null}
        export KMS_KEY_ID="<KEY_OCID>"
        ```

        ***

        ## 4. Find Buckets That Are Not Using Customer-Managed Keys

        List buckets in the compartment:

        ```bash theme={null}
        oci os bucket list \
          --compartment-id <COMPARTMENT_OCID> \
          --all
        ```

        For each bucket, check if `kms-key-id` is set:

        ```bash theme={null}
        oci os bucket get \
          --name "<BUCKET_NAME>" \
          --query 'data."kms-key-id"' \
          --raw-output
        ```

        If this returns `null` or empty, the bucket is using Oracle-managed keys and is non‑compliant.

        ***

        ## 5. Update Buckets to Use the Customer-Managed Key

        For each non‑compliant bucket:

        ```bash theme={null}
        oci os bucket update \
          --name "<BUCKET_NAME>" \
          --kms-key-id "$KMS_KEY_ID"
        ```

        To script across all buckets in a compartment:

        ```bash theme={null}
        for BUCKET in $(oci os bucket list \
          --compartment-id <COMPARTMENT_OCID> \
          --query 'data[].name' \
          --raw-output); do

          CURRENT_KMS=$(oci os bucket get \
            --name "$BUCKET" \
            --query 'data."kms-key-id"' \
            --raw-output)

          if [ "$CURRENT_KMS" = "null" ] || [ -z "$CURRENT_KMS" ]; then
            echo "Updating bucket: $BUCKET"
            oci os bucket update \
              --name "$BUCKET" \
              --kms-key-id "$KMS_KEY_ID"
          else
            echo "Skipping bucket (already CMK-encrypted): $BUCKET"
          fi
        done
        ```

        ***

        ## 6. Verify Compliance

        Re-check each bucket:

        ```bash theme={null}
        oci os bucket get \
          --name "<BUCKET_NAME>" \
          --query 'data."kms-key-id"' \
          --raw-output
        ```

        You should see the `KMS_KEY_ID` for all monitored buckets, confirming that they are now encrypted with your customer-managed key.
      </Accordion>

      <Accordion title="Using Python">
        Below is a concise, end‑to‑end approach to **monitor** OCI Object Storage buckets for encryption with customer-managed keys (CMKs) and **remediate** them using Python and the OCI SDK.

        ***

        ## 1. Prerequisites

        1. **Install OCI Python SDK**
           ```bash theme={null}
           pip install oci
           ```

        2. **Configure OCI credentials** (API key)\
           Run:
           ```bash theme={null}
           oci setup config
           ```
           This creates `~/.oci/config` with a profile (e.g., `DEFAULT`).

        3. **Have a Vault and Key (CMK) created in OCI KMS**
           * Create a **Vault** and **Key** in the OCI console (or via CLI).
           * Note the **Key OCID**: `ocid1.key.oc1....`

        4. **Decide the scope**
           * `compartment_id` where your buckets live.
           * `namespace` of Object Storage (usually 1 per tenancy/region).

        ***

        ## 2. Monitoring: Detect Buckets Not Using CMK

        The logic:

        * List all buckets in a compartment.
        * Get each bucket’s details.
        * Check `kms_key_id`; if empty, it’s not using a CMK.

        ```python theme={null}
        import oci

        CONFIG_PROFILE = "DEFAULT"
        COMPARTMENT_OCID = "<your_compartment_ocid>"

        def get_object_storage_client():
            config = oci.config.from_file("~/.oci/config", CONFIG_PROFILE)
            return oci.object_storage.ObjectStorageClient(config), config

        def list_unencrypted_buckets():
            os_client, config = get_object_storage_client()

            # Get namespace
            namespace = os_client.get_namespace().data

            # List buckets
            buckets = oci.pagination.list_call_get_all_results(
                os_client.list_buckets,
                namespace_name=namespace,
                compartment_id=COMPARTMENT_OCID
            ).data

            non_cmk_buckets = []

            for b in buckets:
                bucket = os_client.get_bucket(namespace, b.name).data
                # If kms_key_id is None or empty, it's not using a CMK
                if not getattr(bucket, 'kms_key_id', None):
                    non_cmk_buckets.append(bucket.name)

            return non_cmk_buckets

        if __name__ == "__main__":
            non_cmk = list_unencrypted_buckets()
            print("Buckets NOT using CMK:")
            for name in non_cmk:
                print(f" - {name}")
        ```

        ***

        ## 3. Remediation: Attach Customer-Managed Key to Buckets

        You can reconfigure bucket encryption by updating the bucket with your **KMS Key OCID**.

        **Important:**

        * OCI does server-side encryption by default with Oracle-managed keys.
        * When you set `kms_key_id`, new objects use the CMK; existing objects are gradually re-encrypted in the background by OCI.

        ```python theme={null}
        import oci

        CONFIG_PROFILE = "DEFAULT"
        COMPARTMENT_OCID = "<your_compartment_ocid>"
        CMK_OCID = "<your_kms_key_ocid>"  # Customer-managed key OCID

        def get_object_storage_client():
            config = oci.config.from_file("~/.oci/config", CONFIG_PROFILE)
            return oci.object_storage.ObjectStorageClient(config), config

        def remediate_buckets_with_cmk(cmk_ocid):
            os_client, config = get_object_storage_client()
            namespace = os_client.get_namespace().data

            buckets = oci.pagination.list_call_get_all_results(
                os_client.list_buckets,
                namespace_name=namespace,
                compartment_id=COMPARTMENT_OCID
            ).data

            for b in buckets:
                bucket = os_client.get_bucket(namespace, b.name).data

                if getattr(bucket, 'kms_key_id', None):
                    # Already using a CMK (or some key) – skip or adjust logic as needed
                    continue

                print(f"Updating bucket '{bucket.name}' to use CMK: {cmk_ocid}")

                update_details = oci.object_storage.models.UpdateBucketDetails(
                    kms_key_id=cmk_ocid
                )

                os_client.update_bucket(
                    namespace_name=namespace,
                    bucket_name=bucket.name,
                    update_bucket_details=update_details
                )

            print("Remediation complete.")

        if __name__ == "__main__":
            remediate_buckets_with_cmk(CMK_OCID)
        ```

        ***

        ## 4. Combining Monitoring + Remediation (Optional)

        To explicitly show what’s changed:

        ```python theme={null}
        def remediate_only_non_cmk_buckets(cmk_ocid):
            os_client, config = get_object_storage_client()
            namespace = os_client.get_namespace().data

            buckets = oci.pagination.list_call_get_all_results(
                os_client.list_buckets,
                namespace_name=namespace,
                compartment_id=COMPARTMENT_OCID
            ).data

            for b in buckets:
                bucket = os_client.get_bucket(namespace, b.name).data
                if not getattr(bucket, 'kms_key_id', None):
                    print(f"[REMEDIATE] {bucket.name}")
                    update_details = oci.object_storage.models.UpdateBucketDetails(
                        kms_key_id=cmk_ocid
                    )
                    os_client.update_bucket(namespace, bucket.name, update_details)
                else:
                    print(f"[OK] {bucket.name} already has kms_key_id set")

        if __name__ == "__main__":
            remediate_only_non_cmk_buckets(CMK_OCID)
        ```

        ***

        ## 5. Integrating into Continuous Monitoring

        * Run the monitoring/remediation script:
          * On a schedule (OCI Functions + Events, or cron from a bastion/CI runner).
          * In **read-only mode** (monitor only) for reporting.
          * In **remediation mode** (update\_bucket) in controlled environments.

        This achieves:

        * Detection of buckets not using customer-managed keys.
        * Automatic remediation by attaching your CMK using Python.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # Customer-managed KMS key (dedicated for this bucket)
        resource "oci_kms_key" "bucket_cmk" {
          # Replace with your compartment OCID
          compartment_id = "OCID_OF_KEY_COMPARTMENT"

          # Replace with your KMS vault OCID
          management_endpoint = "VAULT_MANAGEMENT_ENDPOINT"

          display_name = "BUCKET_CMK_NAME"

          key_shape {
            algorithm = "AES"
            length    = 32
          }

          protection_mode = "HSM" # or "SOFTWARE" per your standard
        }

        # OCI Object Storage bucket using the customer-managed key
        resource "oci_objectstorage_bucket" "secure_bucket" {
          compartment_id = "OCID_OF_BUCKET_COMPARTMENT"
          namespace      = "OBJECT_STORAGE_NAMESPACE"
          name           = "BUCKET_NAME"

          # Point bucket encryption at the CMK
          kms_key_id = oci_kms_key.bucket_cmk.id

          storage_tier = "Standard" # or "Archive" as needed
        }
        ```

        Changing `kms_key_id` on an existing `oci_objectstorage_bucket` is an in-place update in the OCI provider and should not force bucket replacement, but review the plan carefully in your environment.

        To verify, `terraform plan` should show:

        * A new `oci_kms_key.bucket_cmk` created (if not existing already).
        * An in-place `update` on `oci_objectstorage_bucket.secure_bucket` setting `kms_key_id` to the CMK ID.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
