Skip to main content

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

Remediation

Using Console

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.

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:
    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:

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:

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:

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:

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:

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):

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

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:

    pip install oci
  2. Configure OCI CLI config (if not already):

    oci setup config

    This creates ~/.oci/config with:

    • tenancy
    • user
    • fingerprint
    • key_file
    • region
  3. Ensure the user has permissions like:

    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.

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:

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()

  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.

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