> ## 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 Compute Block Volumes Should Be Encrypted With Customer-Managed Keys

### More Info:

Block volumes should be encrypted with customer-managed keys (CMK). Volumes using only Oracle-managed encryption do not provide customer control over key lifecycle and access auditing.

### Risk Level

High

### Address

Compliance, Security

### Compliance Standards

* APRA CPS 234 (Australia)
* AWS Startup Security Baseline
* 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)
* GDPR
* HIPAA
* ISO 27001
* ISO/IEC 27017
* ISO/IEC 27018
* ISO/IEC 27701
* KSA PDPL
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIS2 Directive
* NIST CSF
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* PCI
* Reserve Bank of India (RBI) Cyber Security Framework
* 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">
        To use customer‑managed keys (CMKs) for OCI Compute block volumes via the Console, you need to:

        1. Create a customer‑managed key in OCI Vault
        2. Apply that key to new and existing block/boot volumes used by Compute

        ***

        ### 1. Create a customer‑managed key

        1. In the OCI Console, open the navigation menu → **Identity & Security** → **Vault**.
        2. Choose the correct **compartment**.
        3. Click **Create vault** (if you don’t already have one):
           * Name: e.g. `block-vol-vault`
           * Type: typically **Default** (or as per your org’s standards)
           * Compartment: choose the same or a shared security compartment
           * Click **Create vault**.
        4. Once the vault is active, click the vault name.
        5. Go to the **Keys** tab → **Create key**:
           * Name: e.g. `block-volume-cmk`
           * Protection mode: **HSM** (or **Software** as per policy)
           * Key shape: e.g. **AES** 256‑bit
           * Click **Create key**.

        You now have a CMK that can be used for block volumes.

        ***

        ### 2. Set default customer‑managed key for Block Volumes (recommended)

        This ensures newly created block volumes in that compartment use your CMK by default.

        1. Navigation menu → **Storage** → **Block Storage**.
        2. In the left pane, click **Block Volume Settings** (or **Block Storage Settings**, name may vary by region/tenancy).
        3. Select the **compartment** where your Compute instances/volumes live.
        4. Under **Encryption**, set:
           * **Default encryption key type**: **Customer-managed key (Vault)**.
           * Select your **Vault** and **Key** (`block-volume-cmk`).
        5. Click **Save changes**.

        All *new* block volumes created in this compartment will now be encrypted with this CMK.

        ***

        ### 3. Apply CMK to **existing block volumes**

        For each existing block volume:

        1. Navigation menu → **Storage** → **Block Storage** → **Block Volumes**.
        2. Ensure you’re in the correct **compartment**.
        3. Click the block volume you want to fix.
        4. On the volume details page, look for **Encryption** / **KMS key** section.
        5. Click **Change encryption key** or **Assign KMS key** (wording can vary):
           * Choose **Customer-managed key**.
           * Select the **Vault** and the **Key** you created.
        6. Confirm the change.

        If the UI doesn’t show a direct “change key” option in your tenancy/region, use this fallback:

        1. From the volume details page, click **Create backup**.
        2. After backup completes, click **Restore backup**:
           * In the restore dialog, pick the **customer‑managed key** under encryption.
           * Restore as a new block volume.
        3. Detach the old volume from your instance and attach the new, CMK‑encrypted volume.

        Repeat for all block volumes reported by your monitoring tool.

        ***

        ### 4. Apply CMK to **boot volumes** (Compute instances)

        For existing instances:

        1. Navigation menu → **Compute** → **Instances**.
        2. Select the instance, go to the **Boot volume** section → click the boot volume name.
        3. On the boot volume details page:
           * If available, click **Change encryption key** / **Assign KMS key** and select your CMK.
           * If not available, use backup/restore:
             1. Click **Create backup** on the boot volume.
             2. After backup completes, click **Restore backup**:
                * Choose the **customer‑managed key**.
                * Restore to a new boot volume.
             3. Stop the instance, detach old boot volume, attach new CMK‑encrypted boot volume as the boot volume, and start the instance.

        ***

        ### 5. Validate in your monitoring / compliance tool

        1. After changing keys, wait for your OCI Compute Monitoring / security posture tool to rescan.
        2. Confirm that **all block and boot volumes** now show:
           * Encryption: **Enabled**
           * Key type: **Customer-managed (Vault)** with your CMK.

        These steps remediate the misconfiguration using only the OCI Console.
      </Accordion>

      <Accordion title="Using CLI">
        To meet the control “OCI Compute Block Volumes Should Be Encrypted With Customer-Managed Keys” you must:

        1. Have a Vault and Customer-Managed Key (CMK) in OCI Vault.
        2. Re-create non-compliant block volumes using that CMK (you cannot change the key of an existing volume in-place).
        3. Ensure any new volumes use the CMK.

        Below are step‑by‑step remediation steps using OCI CLI.

        ***

        ## 1. Prerequisites

        Make sure:

        * OCI CLI is installed and configured with appropriate permissions.
        * You know:
          * The **compartment OCID** where volumes and vaults reside.
          * The **availability domain** of your compute instance/volumes.
          * The **volume OCIDs** that are not using CMK.
          * The **subnet/shape** etc. if you need to create a new instance or reattach volumes.

        ***

        ## 2. Create / Identify a Vault and CMK

        ### 2.1 Create a Vault (if you don’t already have one)

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

        # Get the vault OCID from the output
        # Or list existing vaults:
        oci kms management vault list --compartment-id <compartment_ocid>
        ```

        From the vault JSON, note:

        * `id` (vault OCID)
        * `management-endpoint`

        ### 2.2 Create a Master Encryption Key

        ```bash theme={null}
        # Example: create a 256-bit AES key
        oci kms management key create \
          --compartment-id <compartment_ocid> \
          --display-name "block-volume-cmk" \
          --protection-mode HSM \
          --management-endpoint <vault_management_endpoint>
        ```

        From the output, note:

        * `id` → this is your `--kms-key-id`.

        You can also list existing keys:

        ```bash theme={null}
        oci kms management key list \
          --compartment-id <compartment_ocid> \
          --management-endpoint <vault_management_endpoint>
        ```

        ***

        ## 3. Recreate Each Non-Compliant Block Volume Using the CMK

        You **cannot** change encryption key on an existing volume directly. The standard pattern is:

        1. Create a **backup** of the existing volume.
        2. Create a **new volume** from that backup, specifying `--kms-key-id`.
        3. Detach the old volume from the instance.
        4. Attach the new CMK-encrypted volume.
        5. (Optionally) delete the old volume after verification.

        Below steps per volume:

        ### 3.1 Identify the Volume

        ```bash theme={null}
        oci bv volume get --volume-id <source_volume_ocid>
        ```

        Note:

        * `availabilityDomain`
        * `sizeInGBs`
        * `compartmentId`

        ### 3.2 Create a Backup of the Existing Volume

        ```bash theme={null}
        oci bv backup create \
          --volume-id <source_volume_ocid> \
          --type FULL \
          --display-name "backup-for-cmk-migration-<source_volume_ocid>"
        ```

        From the output, capture the backup OCID:

        ```bash theme={null}
        backup_ocid=<backup_ocid_from_output>
        ```

        Wait until backup is finished:

        ```bash theme={null}
        oci bv backup wait-for-state \
          --backup-id $backup_ocid \
          --state AVAILABLE
        ```

        ### 3.3 Create a New Volume from the Backup with CMK

        ```bash theme={null}
        oci bv volume create \
          --availability-domain "<availability_domain>" \
          --compartment-id <compartment_ocid> \
          --source-volume-backup-id $backup_ocid \
          --kms-key-id <cmk_key_ocid> \
          --display-name "cmk-encrypted-volume-from-<source_volume_ocid>"
        ```

        From the output, capture:

        ```bash theme={null}
        new_volume_ocid=<new_volume_ocid_from_output>
        ```

        Wait until the new volume is `AVAILABLE`:

        ```bash theme={null}
        oci bv volume wait-for-state \
          --volume-id $new_volume_ocid \
          --state AVAILABLE
        ```

        ***

        ## 4. Swap the Volume on the Compute Instance

        ### 4.1 Detach the Old Volume

        List current volume attachments (to find attachment OCID):

        ```bash theme={null}
        oci compute volume-attachment list \
          --compartment-id <compartment_ocid> \
          --instance-id <instance_ocid>
        ```

        Then detach:

        ```bash theme={null}
        oci compute volume-attachment delete \
          --volume-attachment-id <old_volume_attachment_ocid> \
          --force
        ```

        You may want to:

        * Stop the instance or unmount the filesystem in the OS before detaching (OS-level step, not via CLI), to avoid corruption.

        ### 4.2 Attach the New CMK-Encrypted Volume

        ```bash theme={null}
        oci compute volume-attachment attach-paravirtualized-volume \
          --instance-id <instance_ocid> \
          --volume-id $new_volume_ocid \
          --display-name "cmk-encrypted-attachment" \
          --device /dev/oracleoci/oraclevdb
        ```

        Adjust device path and attachment type (`attach-iscsi-volume` vs `attach-paravirtualized-volume`) as appropriate for your environment.

        Inside the OS, mount the new volume and verify data.

        ### 4.3 (Optional) Delete the Old Volume and Backup

        After verifying:

        ```bash theme={null}
        oci bv volume delete \
          --volume-id <source_volume_ocid> \
          --force

        oci bv backup delete \
          --backup-id $backup_ocid \
          --force
        ```

        ***

        ## 5. Ensure All New Volumes Use the CMK

        When creating new block volumes (manually or via automation), always specify your CMK:

        ```bash theme={null}
        oci bv volume create \
          --availability-domain "<availability_domain>" \
          --compartment-id <compartment_ocid> \
          --size-in-gbs 50 \
          --kms-key-id <cmk_key_ocid> \
          --display-name "new-cmk-encrypted-volume"
        ```

        If you use Terraform/Resource Manager, CI/CD, or scripts, add `kms-key-id` in those definitions as well.

        ***

        If you share:

        * Example volume OCID(s), and
        * The compartment / AD details (redacted as needed),

        I can give you CLI commands tailored exactly to those resources.
      </Accordion>

      <Accordion title="Using Python">
        In OCI you **cannot switch** an existing block volume from Oracle-managed encryption to a customer-managed key (CMK). Remediation is:

        1. Create/identify a customer-managed key in OCI Vault.
        2. For existing volumes:
           * Take a backup.
           * Create a new volume from that backup using the CMK.
           * Attach the new volume, sync data if needed, then detach/delete the old one.
        3. For new volumes: always create them with the CMK.

        Below is how to do this with Python using the OCI SDK.

        ***

        ## 1. Prerequisites

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

        `~/.oci/config` must be set (or use instance principal).

        Python imports:

        ```python theme={null}
        import oci
        from oci.core import BlockstorageClient
        from oci.core.models import CreateVolumeDetails
        ```

        ***

        ## 2. Identify a Customer-Managed Key

        You need the **OCID of the KMS key** (not vault) in the same region as your volumes. Example:

        ```python theme={null}
        kms_key_id = "ocid1.key.oc1.iad.<your_key_ocid_here>"
        compartment_id = "ocid1.compartment.oc1..xxxx"
        availability_domain = "kIdk:US-ASHBURN-AD-1"  # example
        ```

        ***

        ## 3. Find Non‑Compliant Block Volumes

        ```python theme={null}
        config = oci.config.from_file()  # or oci.config.from_file(profile_name="...")

        blockstorage = BlockstorageClient(config)

        def list_volumes_without_cmk(compartment_id):
            result = []
            list_volumes_response = oci.pagination.list_call_get_all_results(
                blockstorage.list_volumes,
                compartment_id=compartment_id
            )
            for vol in list_volumes_response.data:
                # If kms_key_id is None -> Oracle-managed key
                if getattr(vol, "kms_key_id", None) is None:
                    result.append(vol)
            return result

        non_compliant_vols = list_volumes_without_cmk(compartment_id)
        for v in non_compliant_vols:
            print(v.id, v.display_name, "AD:", v.availability_domain)
        ```

        ***

        ## 4. Remediate an Existing Volume (Backup → New Volume with CMK)

        You must:

        1. Create a backup of the existing volume.
        2. Create a new volume from that backup with `kms_key_id` set.
        3. Re-attach and migrate if necessary.
        4. Delete the old volume when safe.

        ```python theme={null}
        from oci.core.models import CreateVolumeBackupDetails

        def migrate_volume_to_cmk(volume, kms_key_id):
            # 1. Create volume backup
            print(f"Creating backup for volume {volume.display_name} ({volume.id})")
            backup_details = CreateVolumeBackupDetails(
                volume_id=volume.id,
                display_name=f"{volume.display_name}-cmk-migration-backup"
            )
            backup_resp = blockstorage.create_volume_backup(backup_details)
            backup = oci.wait_until(
                blockstorage,
                blockstorage.get_volume_backup(backup_resp.data.id),
                'lifecycle_state',
                'AVAILABLE'
            ).data

            # 2. Create new volume from backup with CMK
            print(f"Creating new CMK-encrypted volume from backup {backup.id}")
            create_vol_details = CreateVolumeDetails(
                compartment_id=volume.compartment_id,
                availability_domain=volume.availability_domain,
                display_name=f"{volume.display_name}-cmk",
                source_details={
                    "type": "volumeBackup",
                    "id": backup.id
                },
                kms_key_id=kms_key_id
            )
            new_vol_resp = blockstorage.create_volume(create_vol_details)
            new_vol = oci.wait_until(
                blockstorage,
                blockstorage.get_volume(new_vol_resp.data.id),
                'lifecycle_state',
                'AVAILABLE'
            ).data

            print(f"New CMK volume: {new_vol.id}")
            return new_vol, backup
        ```

        You then need to:

        * Stop the instance (if boot volume) or unmount filesystem (for data volume).
        * Detach the old volume and attach the new one.
        * For a boot volume of a compute instance, you typically create a custom image then launch a new instance. That flow is more involved; for data volumes this attach/detach is sufficient.

        ***

        ## 5. Remediate All Non‑Compliant Volumes

        ```python theme={null}
        for vol in non_compliant_vols:
            new_vol, backup = migrate_volume_to_cmk(vol, kms_key_id)
            # TODO: manually (or via API) update attachments:
            # - detach old vol from instances
            # - attach new_vol
            # After validation, you can delete the old volume and optionally the backup.
        ```

        ***

        ## 6. Ensure New Volumes Use CMK by Default

        For any Python code that creates volumes, always provide `kms_key_id`:

        ```python theme={null}
        def create_cmk_volume(compartment_id, availability_domain, kms_key_id, size_gbs=50):
            create_vol_details = CreateVolumeDetails(
                compartment_id=compartment_id,
                availability_domain=availability_domain,
                display_name="cmk-volume",
                size_in_gbs=size_gbs,
                kms_key_id=kms_key_id
            )
            resp = blockstorage.create_volume(create_vol_details)
            vol = oci.wait_until(
                blockstorage,
                blockstorage.get_volume(resp.data.id),
                'lifecycle_state',
                'AVAILABLE'
            ).data
            return vol
        ```

        ***

        If your “OCI Compute Monitoring” is a separate Python-based compliance scanner, integrate:

        1. The discovery function (`list_volumes_without_cmk`).
        2. Reporting (e.g., print/JSON list of non-compliant volumes).
        3. Optional auto-remediation using `migrate_volume_to_cmk`, with safeguards (e.g., only for data volumes, maintenance window checks).
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # Customer-managed KMS key (CMK) for block volume encryption
        resource "oci_kms_key" "BLOCK_VOLUME_CMK" {
          # Replace with your KMS vault OCID
          management_endpoint = oci_kms_vault.BLOCK_VOLUME_VAULT.management_endpoint

          display_name = "BLOCK_VOLUME_CMK"
          key_shape {
            algorithm = "AES"
            length    = 32
          }
        }

        # KMS vault used for the CMK
        resource "oci_kms_vault" "BLOCK_VOLUME_VAULT" {
          compartment_id = "OCID_OF_COMPARTMENT_FOR_VAULT" # substitute with your compartment OCID
          display_name   = "BLOCK_VOLUME_VAULT"
          vault_type     = "DEFAULT"
        }

        # Block volume encrypted with customer-managed key
        resource "oci_core_volume" "BLOCK_VOLUME" {
          availability_domain = "AVAILABILITY_DOMAIN_NAME"   # e.g., "kIdk:US-ASHBURN-AD-1"
          compartment_id      = "OCID_OF_COMPARTMENT_FOR_VOLUME" # substitute with your compartment OCID
          display_name        = "MY_BLOCK_VOLUME"
          size_in_gbs         = 50

          # This is the critical setting: use a customer-managed KMS key (CMK)
          kms_key_id = oci_kms_key.BLOCK_VOLUME_CMK.id
        }

        # Example: boot volume of a compute instance encrypted with CMK
        resource "oci_core_instance" "COMPUTE_INSTANCE" {
          availability_domain = "AVAILABILITY_DOMAIN_NAME"         # same as above
          compartment_id      = "OCID_OF_COMPARTMENT_FOR_INSTANCE" # substitute
          shape               = "VM.Standard3.Flex"

          source_details {
            source_type = "image"
            source_id   = "OCID_OF_IMAGE" # substitute with your image OCID

            # Encrypt the boot volume with the same CMK
            kms_key_id = oci_kms_key.BLOCK_VOLUME_CMK.id
          }

          create_vnic_details {
            subnet_id = "OCID_OF_SUBNET" # substitute
          }

          # other required arguments (e.g., shape_config) as needed...
        }
        ```

        Updating `kms_key_id` on an existing `oci_core_volume` or `oci_core_instance.source_details` is an in-place change in Terraform (no forced replacement), though encryption rekeying is irreversible once applied.

        Verification: `terraform plan` should show an in-place update adding or changing `kms_key_id` for the affected block volumes (and/or boot volumes), with no `destroy`/`create` of the volumes unless you are creating new ones.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
