> ## 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 KMS Keys Should Not Be Pending Deletion

### More Info:

KMS keys should not be in a pending deletion or deleted state. Deleted keys cannot decrypt previously encrypted data, potentially causing permanent data loss.

### Risk Level

Medium

### 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
* HIPAA
* ISO/IEC 27017
* ISO/IEC 27018
* ISO/IEC 27701
* KSA PDPL
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIS2 Directive
* NIST
* 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">
        To remediate “OCI Encryption KMS Keys Should Not Be Pending Deletion” using the OCI Console:

        1. **Sign in and go to Key Management**
           * Open the OCI Console.
           * From the top-left menu, go to: **Identity & Security → Vault**.
           * Select the **compartment** where your vault is located.

        2. **Open the affected Vault**
           * Click the **Vault** that contains the KMS key in “Pending deletion” state.
           * In the vault details page, go to the **Keys** tab.

        3. **Locate keys in Pending Deletion**
           * In the keys list, look at the **Lifecycle state** column.
           * Identify keys with state **“Pending deletion”**.

        4. **Cancel key deletion**

           * Click the name of the affected key.
           * On the key details page, click **More Actions** (or the action menu) and choose **Cancel Deletion** (or **Cancel key deletion**).
           * Confirm the cancellation in the dialog.

           The key’s lifecycle state should change back to **Enabled** (or **Active**) after cancellation.

        5. **Verify encryption/monitoring configurations**
           * Go to the OCI services using KMS (Block Volumes, Object Storage, Databases, Logging/Monitoring resources, etc.).
           * For critical resources, confirm:
             * They reference the restored key (if they were already using it), **or**
             * They use a different active key if you truly intend to decommission this one later.

        6. **(Optional) Plan proper key rotation/deletion**
           * If a key still needs to be retired:
             * Create a **new key** in the same vault.
             * Update all dependent resources to use the **new key**.
             * Only after confirming no dependencies, schedule the old key for deletion again.

        This clears the “Pending Deletion” state for KMS keys required for OCI Encryption Monitoring and prevents service disruption.
      </Accordion>

      <Accordion title="Using CLI">
        Below are the concrete remediation steps using the OCI CLI to handle KMS keys that are in `PENDING_DELETION` and should not be.

        ***

        ## 1. Prerequisites

        1. Make sure OCI CLI is installed and configured:
           ```bash theme={null}
           oci --version
           oci iam compartment list
           ```
        2. Ensure you have:
           * Permissions on the **Vault** and **Keys** (policy allowing `MANAGE keys` / `MANAGE vaults` as appropriate).
           * The **compartment OCID** where the vault/keys live.

        ***

        ## 2. Identify KMS Keys in PENDING\_DELETION

        First, list all keys in a given compartment and filter on `PENDING_DELETION`.

        If you know the vault OCID:

        ```bash theme={null}
        COMPARTMENT_OCID="<your_compartment_ocid>"
        VAULT_ID="<your_vault_ocid>"

        oci kms management key list \
          --compartment-id "$COMPARTMENT_OCID" \
          --vault-id "$VAULT_ID" \
          --all \
          --query "data[?\"lifecycle-state\"=='PENDING_DELETION'].[\"id\",\"display-name\",\"time-of-deletion\"]" \
          --output table
        ```

        If you have multiple vaults and want to check all of them in a compartment:

        ```bash theme={null}
        COMPARTMENT_OCID="<your_compartment_ocid>"

        # List all vaults
        oci kms management vault list \
          --compartment-id "$COMPARTMENT_OCID" \
          --all \
          --query "data[].id" \
          --output text | while read VAULT_ID; do
            echo "=== Vault: $VAULT_ID ==="
            oci kms management key list \
              --compartment-id "$COMPARTMENT_OCID" \
              --vault-id "$VAULT_ID" \
              --all \
              --query "data[?\"lifecycle-state\"=='PENDING_DELETION'].[\"id\",\"display-name\",\"time-of-deletion\"]" \
              --output table
        done
        ```

        Note the **Key OCIDs** you want to rescue.

        ***

        ## 3. Cancel Deletion for Keys That Should Not Be Deleted

        For each key in `PENDING_DELETION` that you want to keep:

        ```bash theme={null}
        KEY_ID="<key_ocid>"
        VAULT_ID="<vault_ocid>"

        oci kms management key cancel-deletion \
          --key-id "$KEY_ID" \
          --endpoint "$(oci kms management vault get --vault-id $VAULT_ID --query 'data."management-endpoint"' --raw-output)"
        ```

        Explanation of `--endpoint`:

        * KMS operations require the **vault management endpoint**, not the generic region endpoint.
        * The above command dynamically fetches it from the vault.

        You can confirm:

        ```bash theme={null}
        oci kms management key get \
          --key-id "$KEY_ID" \
          --endpoint "$(oci kms management vault get --vault-id $VAULT_ID --query 'data."management-endpoint"' --raw-output)" \
          --query "data.[\"id\",\"display-name\",\"lifecycle-state\"]" \
          --output table
        ```

        Lifecycle state should move from `PENDING_DELETION` to `ENABLED` or `DISABLED` depending on previous state.

        ***

        ## 4. Bulk Remediation (Optional)

        To automatically cancel deletion for *all* keys in `PENDING_DELETION` in a compartment:

        ```bash theme={null}
        COMPARTMENT_OCID="<your_compartment_ocid>"

        oci kms management vault list \
          --compartment-id "$COMPARTMENT_OCID" \
          --all \
          --query "data[].id" \
          --output text | while read VAULT_ID; do
            MGMT_ENDPOINT=$(oci kms management vault get --vault-id "$VAULT_ID" --query 'data."management-endpoint"' --raw-output)

            oci kms management key list \
              --compartment-id "$COMPARTMENT_OCID" \
              --vault-id "$VAULT_ID" \
              --all \
              --query "data[?\"lifecycle-state\"=='PENDING_DELETION'].id" \
              --output text | while read KEY_ID; do
                echo "Canceling deletion for key $KEY_ID in vault $VAULT_ID"
                oci kms management key cancel-deletion \
                  --key-id "$KEY_ID" \
                  --endpoint "$MGMT_ENDPOINT"
              done
        done
        ```

        Use this only if you are sure every `PENDING_DELETION` key should be rescued.

        ***

        ## 5. (Optional) Monitoring via CLI Script

        To periodically check and alert on keys in `PENDING_DELETION` using a simple CLI script (for cron or an automation server):

        ```bash theme={null}
        #!/bin/bash
        set -e

        COMPARTMENT_OCID="<your_compartment_ocid>"

        OUTPUT=$(oci kms management vault list \
          --compartment-id "$COMPARTMENT_OCID" \
          --all \
          --query "data[].id" \
          --output text | while read VAULT_ID; do
            oci kms management key list \
              --compartment-id "$COMPARTMENT_OCID" \
              --vault-id "$VAULT_ID" \
              --all \
              --query "data[?\"lifecycle-state\"=='PENDING_DELETION'].[\"id\",\"display-name\",\"time-of-deletion\",\"vault-id\"]" \
              --output json
        done)

        echo "$OUTPUT"
        # Hook: send to email, OCI Notifications, or log aggregator
        ```

        You can then:

        * Run via cron and alert if `OUTPUT` is non-empty.
        * Or parse `OUTPUT` and integrate with your monitoring system.

        ***

        If you share whether you want automatic cancellation vs just detection/alerting, I can refine the exact CLI/cron or shell script pattern.
      </Accordion>

      <Accordion title="Using Python">
        Below is how to (1) detect KMS keys in `PENDING_DELETION` state and (2) optionally cancel their deletion, using Python and the OCI SDK.

        ***

        ## 1. Prerequisites

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

        2. Configure OCI CLI config (if not already):
           ```bash theme={null}
           oci setup config
           ```
           This creates `~/.oci/config` with:
           * tenancy
           * user
           * fingerprint
           * key\_file
           * region

        3. Ensure the user has permissions like:
           ```text theme={null}
           allow group <group-name> to read keys in compartment <compartment-ocid>
           allow group <group-name> to manage keys in compartment <compartment-ocid>
           ```
           (You only need `manage` if you want to cancel deletion.)

        ***

        ## 2. Python: List Keys Pending Deletion (Monitoring)

        This script lists all KMS keys in `PENDING_DELETION` in a given compartment and vault. You can wire it to cron / a scheduler or a monitoring system.

        ```python theme={null}
        import oci

        # ---- CONFIG ----
        CONFIG_FILE = "~/.oci/config"
        CONFIG_PROFILE = "DEFAULT"
        COMPARTMENT_OCID = "<your_compartment_ocid>"
        VAULT_OCID = "<your_vault_ocid>"  # OCID of the vault that holds the keys

        def list_pending_deletion_keys():
            # Load config
            config = oci.config.from_file(CONFIG_FILE, CONFIG_PROFILE)

            # KMS management client
            kms_management_client = oci.key_management.KmsManagementClient(
                config=config,
                service_endpoint=None  # We’ll set endpoint from vault metadata below
            )

            # Need vault's management endpoint
            kms_vault_client = oci.key_management.KmsVaultClient(config)
            vault = kms_vault_client.get_vault(VAULT_OCID).data
            management_endpoint = vault.management_endpoint

            # Re-create KmsManagementClient with the vault’s management endpoint
            kms_management_client.base_client.set_region(None)
            kms_management_client.base_client.endpoint = management_endpoint

            # List keys in this vault
            pending_keys = []

            list_keys_response = kms_management_client.list_keys(
                compartment_id=COMPARTMENT_OCID,
                limit=1000   # adjust as needed
            )

            for key in list_keys_response.data:
                if key.lifecycle_state == "PENDING_DELETION":
                    pending_keys.append(key)

            return pending_keys

        if __name__ == "__main__":
            keys = list_pending_deletion_keys()
            if not keys:
                print("No KMS keys in PENDING_DELETION.")
            else:
                print("KMS keys in PENDING_DELETION:")
                for k in keys:
                    print(f"- Key OCID: {k.id}, Name: {k.display_name}, TimeOfDeletion: {k.time_of_deletion}")
        ```

        Use this for monitoring:

        * Feed output to a log/alerting system (e.g., send email/Slack if list not empty).
        * Run periodically (cron, OCI Functions, etc.).

        ***

        ## 3. Python: Cancel Deletion for Keys (Remediation)

        If you want to automatically remediate by cancelling deletion for all such keys:

        ```python theme={null}
        import oci

        CONFIG_FILE = "~/.oci/config"
        CONFIG_PROFILE = "DEFAULT"
        COMPARTMENT_OCID = "<your_compartment_ocid>"
        VAULT_OCID = "<your_vault_ocid>"

        def get_kms_management_client(config, vault_ocid):
            kms_vault_client = oci.key_management.KmsVaultClient(config)
            vault = kms_vault_client.get_vault(vault_ocid).data
            management_endpoint = vault.management_endpoint

            kms_mgmt_client = oci.key_management.KmsManagementClient(config=config)
            kms_mgmt_client.base_client.endpoint = management_endpoint
            return kms_mgmt_client

        def cancel_pending_key_deletions():
            config = oci.config.from_file(CONFIG_FILE, CONFIG_PROFILE)
            kms_management_client = get_kms_management_client(config, VAULT_OCID)

            # List keys
            list_keys_response = kms_management_client.list_keys(
                compartment_id=COMPARTMENT_OCID,
                limit=1000
            )

            for key in list_keys_response.data:
                if key.lifecycle_state == "PENDING_DELETION":
                    print(f"Cancelling deletion for key: {key.display_name} ({key.id})")
                    kms_management_client.cancel_key_deletion(key_id=key.id)

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

        ***

        ## 4. Recommended Workflow

        1. **Monitoring script**: Run periodically to detect keys in `PENDING_DELETION`.
        2. **Alert first**: Prefer to notify a security/ops team rather than auto-restore, for change control.
        3. **Optional auto-remediation**: Use the `cancel_key_deletion` script in a controlled environment, with logging and approvals if required.

        If you share your vault/compartment structure, I can adapt the code to loop through all vaults and compartments automatically.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # There is currently no Terraform argument on oci_kms_key (or a separate
        # Terraform resource/action) that can cancel a “pending deletion” state.
        # Terraform can create new keys and destroy them, but it cannot call
        # the “CancelKeyDeletion” API operation on an existing pending‑deletion key.

        # You must remediate this particular finding outside Terraform:
        # 1. In the OCI Console:
        #    - Go to: Security → Key Management → (Vault) → Master Encryption Keys.
        #    - Locate the key in “Pending deletion”.
        #    - Use the “Cancel deletion” action.
        #
        # 2. Or via OCI CLI:
        #    oci kms management cancel-key-deletion \
        #      --key-id OCID_OF_THE_KEY \
        #      --endpoint https://management-kms.[REGION].oraclecloud.com

        # After cancellation, ensure your Terraform config manages only ENABLED/DISABLED keys,
        # e.g. by defining them as normal oci_kms_key resources:

        resource "oci_kms_key" "EXAMPLE_KMS_KEY" {
          # Replace with your values
          compartment_id = "OCID_OF_COMPARTMENT"
          management_endpoint = "https://management-kms.REGION.oraclecloud.com"
          display_name   = "EXAMPLE_KEY_NAME"
          key_shape {
            algorithm = "AES"
            length    = 32
          }
          protection_mode = "HSM" # or "SOFTWARE"
        }

        # This does NOT cancel deletion on an already pending-deletion key;
        # it only shows how a healthy key should be managed going forward.
        ```

        `terraform plan` will only show normal create/update/destroy operations for `oci_kms_key` resources that Terraform already manages; it will not (and cannot) show cancellation of a pending key deletion, since that operation is not exposed via the Terraform provider.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
