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
Remediation
Using Console
To remediate “OCI Encryption KMS Keys Should Not Be Pending Deletion” using the OCI Console:
-
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.
-
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.
-
Locate keys in Pending Deletion
- In the keys list, look at the Lifecycle state column.
- Identify keys with state “Pending deletion”.
-
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.
-
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.
-
(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.
- If a key still needs to be retired:
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
- Make sure OCI CLI is installed and configured:
oci --versionoci iam compartment list
- Ensure you have:
- Permissions on the Vault and Keys (policy allowing
MANAGE keys/MANAGE vaultsas appropriate). - The compartment OCID where the vault/keys live.
- Permissions on the Vault and Keys (policy allowing
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
OUTPUTis non-empty. - Or parse
OUTPUTand 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
-
Install OCI Python SDK:
pip install oci -
Configure OCI CLI config (if not already):
oci setup configThis creates
~/.oci/configwith:- tenancy
- user
- fingerprint
- key_file
- region
-
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
manageif 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()
4. Recommended Workflow
- Monitoring script: Run periodically to detect keys in
PENDING_DELETION. - Alert first: Prefer to notify a security/ops team rather than auto-restore, for change control.
- Optional auto-remediation: Use the
cancel_key_deletionscript 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.