> ## 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 Encryption Storage Buckets Should Use Customer-Managed KMS Keys

### More Info:

Object Storage buckets should be encrypted with customer-managed KMS keys rather than Oracle-managed defaults. Customer-managed keys provide full control over encryption lifecycle and audit trails

### Risk Level

Medium

### Address

Compliance, Security

### Compliance Standards

* APRA CPS 234 (Australia)
* 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)
* NIS2 Directive
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* SWIFT Customer Security Controls Framework
* Sarbanes-Oxley IT General Controls
* UK NCSC Cyber Assessment Framework

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        Below are the step‑by‑step remediation steps using the OCI Console so that an Object Storage bucket uses a customer‑managed KMS key instead of the Oracle‑managed default key.

        ***

        ### 1. Confirm / Create a Vault

        1. In the OCI Console, open the navigation menu.
        2. Go to **Identity & Security** → **Vault**.
        3. Make sure you are in the **correct compartment**.
        4. If you don’t have a vault yet:
           * Click **Create vault**.
           * Enter **Name**, select **Compartment**.
           * Choose **Vault type** (Default or Virtual Private).
           * Click **Create vault** and wait until its lifecycle state is **Active**.

        ***

        ### 2. Create / Identify a Customer-Managed Key

        1. Open the vault you plan to use.
        2. Go to the **Master Encryption Keys** (or **Keys**) tab.
        3. To create a new key:
           * Click **Create key**.
           * Select **Key shape** (e.g., AES, 256‑bit).
           * Set **Protection mode** to **HSM** or **Software** as required.
           * Provide a **Name** and optional description.
           * Click **Create key** and wait for it to become **Enabled**.

        Keep note of the **key** and **vault** (they must be in a region that supports the bucket’s region).

        ***

        ### 3. Update the Bucket to Use the Customer-Managed KMS Key

        1. In the OCI Console, go to **Storage** → **Buckets**.
        2. Choose the **Compartment** where your “OCI Encryption Monitoring” bucket (or target bucket) resides.
        3. Click the **bucket name** you want to remediate.
        4. On the bucket details page, click **Edit** (top-right).
        5. In the **Encryption** section:
           * Change from **Encrypt using Oracle-managed keys** to **Encrypt using Customer-managed keys**.
           * Select the **Vault** created earlier.
           * Select the **Master Encryption Key** you created/identified.
        6. Click **Save changes** (or **Update**).

        OCI will now use your customer-managed KMS key for that bucket’s encryption going forward.

        ***

        ### 4. (Optional) Verify Configuration

        1. Return to the **bucket details** page.
        2. Under **Encryption**, confirm it shows:
           * **Customer-managed keys**.
           * The correct **Vault** and **Key**.

        This completes remediation for the finding “OCI Encryption Storage Buckets Should Use Customer-Managed KMS Keys” using the OCI Console.
      </Accordion>

      <Accordion title="Using CLI">
        Below are the exact steps to remediate “OCI Encryption Storage Buckets Should Use Customer-Managed KMS Keys” using the OCI CLI.

        Assumptions:

        * You already have the OCI CLI configured (`oci setup config` done).
        * You know your compartment OCID and region (or are using defaults in `~/.oci/config`).

        ***

        ## 1. Create (or identify) a Customer-Managed KMS Key

        ### 1.1. Create a Vault (if you don’t have one)

        ```bash theme={null}
        COMPARTMENT_OCID="<your_compartment_ocid>"
        VAULT_NAME="my-vault"

        oci kms management vault create \
          --compartment-id "$COMPARTMENT_OCID" \
          --display-name "$VAULT_NAME" \
          --vault-type DEFAULT
        ```

        Get the vault OCID and management endpoint:

        ```bash theme={null}
        oci kms management vault list \
          --compartment-id "$COMPARTMENT_OCID" \
          --display-name "$VAULT_NAME" \
          --all
        ```

        From the output, note:

        * `id` → VAULT\_OCID
        * `management-endpoint` → KMS\_ENDPOINT

        ```bash theme={null}
        VAULT_OCID="<vault_ocid_from_previous_command>"
        KMS_ENDPOINT="<management_endpoint_from_previous_command>"
        ```

        ### 1.2. Create a Master Encryption Key

        ```bash theme={null}
        KEY_NAME="os-bucket-key"

        oci kms management key create \
          --endpoint "$KMS_ENDPOINT" \
          --compartment-id "$COMPARTMENT_OCID" \
          --display-name "$KEY_NAME" \
          --key-shape '{"algorithm":"AES","length":32}'
        ```

        Get the key OCID:

        ```bash theme={null}
        oci kms management key list \
          --endpoint "$KMS_ENDPOINT" \
          --compartment-id "$COMPARTMENT_OCID" \
          --display-name "$KEY_NAME" \
          --all
        ```

        Note the `id` as:

        ```bash theme={null}
        KEY_OCID="<key_ocid_from_previous_command>"
        ```

        If you already have a CMK created, just identify its `KEY_OCID` and skip the creation steps.

        ***

        ## 2. Identify Buckets Not Using Customer-Managed Keys

        Get the Object Storage namespace:

        ```bash theme={null}
        NAMESPACE=$(oci os ns get --query 'data' --raw-output)
        ```

        List all buckets in a compartment with their current KMS key:

        ```bash theme={null}
        oci os bucket list \
          --compartment-id "$COMPARTMENT_OCID" \
          --fields "kmsKeyId" \
          --all
        ```

        In the output:

        * Buckets with `"kmsKeyId": null` are using Oracle-managed keys.
        * Buckets with `"kmsKeyId": "<ocid1.key...>"` are already using a CMK.

        ***

        ## 3. Update a Single Bucket to Use the Customer-Managed KMS Key

        ```bash theme={null}
        BUCKET_NAME="<your_bucket_name>"

        oci os bucket update \
          --namespace-name "$NAMESPACE" \
          --name "$BUCKET_NAME" \
          --kms-key-id "$KEY_OCID"
        ```

        Verify:

        ```bash theme={null}
        oci os bucket get \
          --namespace-name "$NAMESPACE" \
          --name "$BUCKET_NAME" \
          --fields "kmsKeyId"
        ```

        You should see `"kmsKeyId": "<your_key_ocid>"`.

        ***

        ## 4. Bulk Remediation: Update All Non-Compliant Buckets in a Compartment

        This example updates every bucket in the compartment that does **not** yet have `kmsKeyId` set.

        ```bash theme={null}
        NAMESPACE=$(oci os ns get --query 'data' --raw-output)
        COMPARTMENT_OCID="<your_compartment_ocid>"
        KEY_OCID="<your_key_ocid>"

        # List non-compliant buckets (kmsKeyId == null)
        NON_COMPLIANT_BUCKETS=$(oci os bucket list \
          --compartment-id "$COMPARTMENT_OCID" \
          --fields "kmsKeyId" \
          --all \
          --query "data[?kmsKeyId==null].name" \
          --raw-output)

        for BUCKET in $NON_COMPLIANT_BUCKETS; do
          echo "Updating bucket: $BUCKET to use KMS key: $KEY_OCID"
          oci os bucket update \
            --namespace-name "$NAMESPACE" \
            --name "$BUCKET" \
            --kms-key-id "$KEY_OCID"
        done
        ```

        ***

        ## 5. (Optional) Script for Monitoring / Reporting via CLI

        To only **monitor** (no changes), you can run:

        ```bash theme={null}
        oci os bucket list \
          --compartment-id "$COMPARTMENT_OCID" \
          --fields "kmsKeyId" \
          --all \
          --query "data[?kmsKeyId==null].{name:name, namespace:namespace}" \
          --output table
        ```

        This will show all buckets in the compartment that are still using Oracle-managed encryption, which you can feed into your monitoring or alerting.
      </Accordion>

      <Accordion title="Using Python">
        Below is a concise, practical way to remediate this finding using Python and the OCI SDK: detect buckets not using a customer-managed KMS key and update them to use one.

        ***

        ## 1. Prerequisites

        1. **OCI Python SDK installed**

        ```bash theme={null}
        pip install oci
        ```

        2. **Configured OCI credentials** (one of):

        * `~/.oci/config` with a profile, e.g. `[DEFAULT]`
        * Or use instance principal / resource principal (for functions) – code below shows both patterns.

        3. **Existing Vault and KMS Key**

        You must already have:

        * `vault_id` (OCID of the KMS vault)
        * `kms_key_id` (OCID of the key inside that vault you want to use for bucket encryption)

        4. **IAM Policies**

        The principal running this script must be allowed to:

        ```text theme={null}
        Allow group <your-group> to manage buckets in compartment <compartment-name>
        Allow group <your-group> to use keys in compartment <vault-compartment-name> where target.key.id = '<kms-key-ocid>'
        ```

        (Adjust for dynamic groups if using instance/resource principals.)

        ***

        ## 2. Script Outline

        **What it does:**

        1. Lists all compartments (or uses a specific one).
        2. Lists all Object Storage buckets per compartment.
        3. Identifies buckets where:
           * `kms_key_id` is `None` (Oracle-managed encryption) OR
           * `kms_key_id` is not the desired KMS key.
        4. Updates each such bucket to use the customer-managed KMS key.

        ***

        ## 3. Python Remediation Script

        ```python theme={null}
        import oci

        # ----------------- CONFIGURATION -----------------
        # Either use config file:
        USE_INSTANCE_PRINCIPAL = False
        CONFIG_PROFILE = "DEFAULT"

        TENANCY_OCID = "<your-tenancy-ocid>"
        # If you only want to remediate a single compartment, set COMPARTMENT_OCID
        # otherwise leave it None to scan all compartments in the tenancy.
        COMPARTMENT_OCID = None

        # Target customer-managed KMS key:
        TARGET_KMS_KEY_ID = "<your-kms-key-ocid>"   # ocid1.key.oc1...
        # Region for Object Storage:
        REGION = "us-ashburn-1"
        # -------------------------------------------------


        def get_signer_and_config():
            if USE_INSTANCE_PRINCIPAL:
                signer = oci.auth.signers.InstancePrincipalsSecurityTokenSigner()
                config = {"region": REGION, "tenancy": TENANCY_OCID}
            else:
                config = oci.config.from_file("~/.oci/config", CONFIG_PROFILE)
                config["region"] = REGION
                signer = None
            return config, signer


        def list_compartments(identity_client, tenancy_id):
            """List all active compartments in the tenancy."""
            compartments = []
            response = oci.pagination.list_call_get_all_results(
                identity_client.list_compartments,
                tenancy_id,
                compartment_id_in_subtree=True
            )
            for c in response.data:
                if c.lifecycle_state == "ACTIVE":
                    compartments.append(c)
            return compartments


        def remediate_buckets_in_compartment(object_storage_client, compartment_id, namespace, target_kms_key_id):
            # List buckets in this compartment
            buckets = oci.pagination.list_call_get_all_results(
                object_storage_client.list_buckets,
                namespace,
                compartment_id=compartment_id
            ).data

            for bucket in buckets:
                bucket_name = bucket.name
                current_kms_key_id = bucket.kms_key_id

                # Skip if already using the desired key
                if current_kms_key_id == target_kms_key_id:
                    continue

                print(f"Updating bucket '{bucket_name}' (compartment: {compartment_id}) "
                      f"from kms_key_id={current_kms_key_id} to {target_kms_key_id}")

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

                object_storage_client.update_bucket(
                    namespace_name=namespace,
                    bucket_name=bucket_name,
                    update_bucket_details=update_details
                )


        def main():
            config, signer = get_signer_and_config()

            identity_client = oci.identity.IdentityClient(config, signer=signer)
            object_storage_client = oci.object_storage.ObjectStorageClient(config, signer=signer)

            # Get namespace (Object Storage is per-tenant per-region)
            namespace = object_storage_client.get_namespace().data

            if COMPARTMENT_OCID:
                # Only remediate one compartment
                remediate_buckets_in_compartment(
                    object_storage_client,
                    COMPARTMENT_OCID,
                    namespace,
                    TARGET_KMS_KEY_ID
                )
            else:
                # Remediate all compartments in the tenancy
                compartments = list_compartments(identity_client, TENANCY_OCID)
                for comp in compartments:
                    print(f"Scanning compartment: {comp.name} ({comp.id})")
                    remediate_buckets_in_compartment(
                        object_storage_client,
                        comp.id,
                        namespace,
                        TARGET_KMS_KEY_ID
                    )


        if __name__ == "__main__":
            main()
        ```

        ***

        ## 4. How This Ties to “Encryption Monitoring”

        If you are using **Cloud Guard / Security Zones / Cloud Advisor** with a control such as “OCI Encryption Storage Buckets Should Use Customer-Managed KMS Keys,” rerun the detector after this script:

        * All buckets will have `kms_key_id` set to your customer-managed key.
        * The encryption control should move from “Problem” to “Resolved” state once the service re-evaluates.

        ***

        If you share whether you want to target only specific compartments, tags, or exclude some buckets, I can adjust the script accordingly.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # Customer-managed KMS vault
        resource "oci_kms_vault" "cmk_vault" {
          compartment_id = "OCID_OF_BUCKET_COMPARTMENT"  # replace with the compartment OCID
          display_name   = "CUSTOMER_MANAGED_VAULT_NAME" # replace with desired vault name
          vault_type     = "DEFAULT"
        }

        # Customer-managed KMS key
        resource "oci_kms_key" "cmk_key" {
          compartment_id = "OCID_OF_BUCKET_COMPARTMENT"  # replace with the compartment OCID
          display_name   = "CUSTOMER_MANAGED_KEY_NAME"   # replace with desired key name
          management_endpoint = oci_kms_vault.cmk_vault.management_endpoint

          key_shape {
            algorithm = "AES"
            length    = 256
          }
        }

        # Object Storage bucket using the customer-managed KMS key
        resource "oci_objectstorage_bucket" "encrypted_bucket" {
          compartment_id = "OCID_OF_BUCKET_COMPARTMENT"   # replace with the compartment OCID
          name           = "BUCKET_NAME"                  # replace with the bucket name
          namespace      = "OBJECTSTORAGE_NAMESPACE"      # replace with your Object Storage namespace

          # This is the setting that remediates the finding
          kms_key_id = oci_kms_key.cmk_key.id
        }
        ```

        Changing `kms_key_id` on an existing `oci_objectstorage_bucket` updates the bucket in place; it does not force replacement, so no outage is expected.

        To verify, `terraform plan` should show an in-place `~ update` on `oci_objectstorage_bucket.encrypted_bucket` with `kms_key_id` changing from `null` (or the old key OCID) to the OCID of `oci_kms_key.cmk_key`.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
