Skip to main content

OCI Encryption KMS Keys Should Be Rotated Every 90 Days

More Info:

KMS keys should be rotated at least every 90 days. Frequent rotation limits the amount of data encrypted under a single key version, reducing exposure from a key compromise.

Risk Level

High

Address

Compliance, Security

Compliance Standards

  • APRA CPS 234 (Australia)
  • AWS Well Architected Framework
  • BSI C5 (Germany)
  • Brazil LGPD
  • CCPA / CPRA (California)
  • CIS AWS
  • CIS Critical Security Controls v8
  • CMMC 2.0
  • CSA Cloud Controls Matrix v4
  • Cloudanix Best Practice
  • DPDPA
  • Digital Operational Resilience Act (EU)
  • GDPR
  • HIPAA
  • HITRUST CSF
  • ISO/IEC 27017
  • ISO/IEC 27018
  • ISO/IEC 27701
  • KSA PDPL
  • MAS Technology Risk Management (Singapore)
  • MITRE ATT&CK (Cloud)
  • NIS2 Directive
  • NIST
  • NIST CSF
  • NIST SP 800-171
  • NYDFS 23 NYCRR 500
  • PCI
  • Reserve Bank of India (RBI) Cyber Security Framework
  • Reserve Bank of India (RBI) Master Direction – Information Technology 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

Remediation

Using Console

Below are the steps to ensure OCI KMS keys are rotated every 90 days using the OCI Console (Vault service).


1. Navigate to the Vault and Keys

  1. Sign in to the OCI Console.
  2. In the left menu, go to:
    Identity & Security → Vault.
  3. Select the Compartment where your vault resides.
  4. Click on the Vault that contains the KMS keys you want to rotate.

2. Enable / Configure Automatic Rotation to 90 Days

  1. Inside the selected vault, go to the Keys tab.
  2. Click on the Key you want to configure.
  3. On the key details page, click Edit (or Edit Key / Edit Key Rotation, depending on UI version).
  4. Find the Automatic Key Rotation (or Rotation Interval) section.
  5. Set:
    • Enable Automatic Rotation: ON
    • Rotation Interval (days): enter 90
  6. Click Save Changes (or Update).

Repeat this for every customer-managed key that must comply with the 90-day rotation requirement.


3. (Optional) Perform Immediate Manual Rotation

If a key is already older than 90 days and needs immediate rotation:

  1. On the same Key Details page, click Create New Key Version (or Rotate Key Now).
  2. Confirm rotation.
    OCI creates a new key version and automatically starts using it for new encrypt operations.

4. Verify Configuration for Monitoring / Compliance

  1. Go back to Identity & Security → Vault → [Your Vault] → Keys.
  2. For each key:
    • Confirm Automatic rotation is Enabled.
    • Confirm Interval is set to 90 days.
  3. If you use OCI Security Zones, Cloud Guard, or a 3rd-party CSPM:
    • Trigger or wait for the next re-scan so that it picks up the new rotation setting and clears the “KMS Keys Should Be Rotated Every 90 Days” finding.

This configuration will satisfy the “OCI Encryption KMS Keys Should Be Rotated Every 90 Days” requirement using only the OCI Console.

Using CLI

In OCI, “rotating” a KMS key means creating a new key version. Apps keep using the same key OCID; OCI automatically uses the latest active version.

Below is how to (1) monitor key age and (2) rotate keys older than 90 days using the OCI CLI.


1. Prerequisites

  1. Install and configure OCI CLI:
    oci setup config
  2. Have the following:
    • Compartment OCID: ocid1.compartment.oc1...
    • Vault OCID: ocid1.vault.oc1... (optional filter)
    • IAM policy that lets your user/group manage keys:
      Allow group <your-group> to manage keys in compartment <your-compartment-name>
      Allow group <your-group> to use vaults in compartment <your-compartment-name>

Set some environment variables to simplify commands:

export COMPARTMENT_OCID="ocid1.compartment.oc1..xxxx"
export VAULT_OCID="ocid1.vault.oc1..xxxx" # optional; remove filter if not needed

2. List Keys and Find Those Older Than 90 Days

Get all keys in the compartment (optionally filter by vault):

oci kms management key list \
--compartment-id "$COMPARTMENT_OCID" \
--vault-id "$VAULT_OCID" \
--all \
--output table

To get keys whose latest version is older than 90 days, use jq and some shell:

#!/usr/bin/env bash
set -euo pipefail

COMPARTMENT_OCID="ocid1.compartment.oc1..xxxx"
VAULT_OCID="ocid1.vault.oc1..xxxx" # or leave empty and drop the option
DAYS=90

# Seconds threshold
THRESHOLD_SECONDS=$((DAYS * 24 * 60 * 60))
NOW_EPOCH=$(date -u +%s)

# List all keys
keys_json=$(oci kms management key list \
--compartment-id "$COMPARTMENT_OCID" \
--vault-id "$VAULT_OCID" \
--all \
--raw-output)

echo "$keys_json" | jq -r '.data[].id' | while read -r KEY_OCID; do
# Get latest key version
latest_version_json=$(oci kms management key-version list \
--key-id "$KEY_OCID" \
--sort-by TIME_CREATED \
--sort-order DESC \
--limit 1)

CREATED_TIME=$(echo "$latest_version_json" | jq -r '.data[0]."time-created"')
CREATED_EPOCH=$(date -u -d "$CREATED_TIME" +%s)
AGE_SECONDS=$((NOW_EPOCH - CREATED_EPOCH))

if [ "$AGE_SECONDS" -gt "$THRESHOLD_SECONDS" ]; then
echo "Key $KEY_OCID has latest version older than $DAYS days (created: $CREATED_TIME)"
fi
done

This prints keys that should be rotated.


3. Rotate a Key (Create New Version) via CLI

To rotate a single key:

export KEY_OCID="ocid1.key.oc1..xxxx"

oci kms management key-version create \
--key-id "$KEY_OCID"
  • This creates a new key version.
  • OCI automatically uses the newest version for future crypto operations.
  • You typically do not need to change the key OCID in applications.

Verify versions:

oci kms management key-version list \
--key-id "$KEY_OCID" \
--all \
--output table

4. Script: Automatically Rotate Keys Older Than 90 Days

You can combine monitoring and rotation:

#!/usr/bin/env bash
set -euo pipefail

COMPARTMENT_OCID="ocid1.compartment.oc1..xxxx"
VAULT_OCID="ocid1.vault.oc1..xxxx" # or omit --vault-id usage if not needed
DAYS=90

THRESHOLD_SECONDS=$((DAYS * 24 * 60 * 60))
NOW_EPOCH=$(date -u +%s)

keys_json=$(oci kms management key list \
--compartment-id "$COMPARTMENT_OCID" \
--vault-id "$VAULT_OCID" \
--all \
--raw-output)

echo "$keys_json" | jq -r '.data[].id' | while read -r KEY_OCID; do
latest_version_json=$(oci kms management key-version list \
--key-id "$KEY_OCID" \
--sort-by TIME_CREATED \
--sort-order DESC \
--limit 1)

CREATED_TIME=$(echo "$latest_version_json" | jq -r '.data[0]."time-created"')
CREATED_EPOCH=$(date -u -d "$CREATED_TIME" +%s)
AGE_SECONDS=$((NOW_EPOCH - CREATED_EPOCH))

if [ "$AGE_SECONDS" -gt "$THRESHOLD_SECONDS" ]; then
echo "Rotating key $KEY_OCID (latest version created: $CREATED_TIME)..."
oci kms management key-version create \
--key-id "$KEY_OCID"
else
echo "Key $KEY_OCID is within $DAYS days; no rotation needed."
fi
done

Run this script via a scheduled mechanism (cron, OCI Functions, or external scheduler) every day or week to enforce the “rotate every 90 days” requirement.


If you tell me your exact vault and compartment structure, I can tailor the CLI filters or the script to match your environment more precisely.

Using Python

Here’s how to enforce “KMS keys rotated every 90 days” in OCI using Python, by:

  1. Enabling automatic rotation (preferred), or
  2. Implementing your own monitoring + rotation script.

1. Prerequisites

  1. Install the OCI Python SDK:

    pip install oci
  2. Configure OCI CLI/auth (SDK uses same config):

    oci setup config

    This creates ~/.oci/config with:

    • tenancy
    • user
    • fingerprint
    • key_file
    • region
  3. Ensure your user or instance principal has permissions:

    Allow group <group-name> to manage keys in tenancy
    Allow group <group-name> to read vaults in tenancy

If the policy is “every 90 days”, you can set automatic rotation on each key.

import oci

# Use config file; or use instance principals if running in OCI.
config = oci.config.from_file("~/.oci/config", "DEFAULT")

kms_management_client = oci.key_management.KmsManagementClient(config)

# If using a virtual/local service, you must set the endpoint for the vault’s management endpoint:
# kms_management_client.base_client.set_region("eu-frankfurt-1") # for example
# OR:
# kms_management_client.base_client.endpoint = "<vault_management_endpoint>"

def enable_auto_rotation_for_key(key_id: str, rotation_days: int = 90):
"""
Enable automatic key rotation for a given KMS key.
key_id: OCID of the key.
rotation_days: number of days between rotations.
"""

update_key_details = oci.key_management.models.UpdateKeyDetails(
# Not changing name/description, only auto rotation
auto_key_rotation_details=oci.key_management.models.AutoKeyRotationDetails(
is_enabled=True,
rotation_interval_in_days=rotation_days
)
)

response = kms_management_client.update_key(
key_id=key_id,
update_key_details=update_key_details
)
return response.data

# Example usage:
key_ocid = "ocid1.key.oc1...." # replace with your key OCID
updated_key = enable_auto_rotation_for_key(key_ocid, rotation_days=90)
print("Auto rotation enabled for key:", updated_key.id)

You can loop over all keys in a vault/tenancy and set this.

List all keys in a specific vault and enable rotation

import oci

config = oci.config.from_file("~/.oci/config", "DEFAULT")
kms_vault_client = oci.key_management.KmsVaultClient(config)

# If needed, set region
# kms_vault_client.base_client.set_region("eu-frankfurt-1")

kms_management_client = oci.key_management.KmsManagementClient(config)

def list_keys_in_vault(compartment_id: str, vault_id: str):
"""
List all keys in a vault for a given compartment.
"""
keys = []
list_keys_response = kms_management_client.list_keys(
compartment_id=compartment_id,
limit=1000
)
keys.extend(list_keys_response.data)

# Handle pagination
while list_keys_response.has_next_page:
list_keys_response = kms_management_client.list_keys(
compartment_id=compartment_id,
limit=1000,
page=list_keys_response.next_page
)
keys.extend(list_keys_response.data)

# Filter keys by vault (if needed)
return [k for k in keys if k.vault_id == vault_id]

def enable_auto_rotation_all_keys_in_vault(compartment_id: str, vault_id: str, rotation_days: int = 90):
keys = list_keys_in_vault(compartment_id, vault_id)
for key in keys:
print(f"Enabling auto rotation on key: {key.display_name} ({key.id})")
update_key_details = oci.key_management.models.UpdateKeyDetails(
auto_key_rotation_details=oci.key_management.models.AutoKeyRotationDetails(
is_enabled=True,
rotation_interval_in_days=rotation_days
)
)
kms_management_client.update_key(
key_id=key.id,
update_key_details=update_key_details
)

# Example usage:
compartment_ocid = "ocid1.compartment.oc1...."
vault_ocid = "ocid1.vault.oc1...."
enable_auto_rotation_all_keys_in_vault(compartment_ocid, vault_ocid, rotation_days=90)

3. Monitoring + Manual Rotation (If Auto-Rotation Not Used/Supported)

You can implement a monitoring script that:

  1. Lists keys.
  2. Gets the creation time or last key version creation time.
  3. If older than 90 days, calls create_key_version to rotate.

Helper: get age of latest key version

import datetime
from dateutil import tz # pip install python-dateutil
import oci

config = oci.config.from_file("~/.oci/config", "DEFAULT")
kms_management_client = oci.key_management.KmsManagementClient(config)

def get_latest_key_version_age_days(key_id: str) -> int:
"""
Returns age in days of the latest key version.
"""
versions = kms_management_client.list_key_versions(key_id=key_id).data
if not versions:
return 0

latest_version = max(versions, key=lambda v: v.time_created)
now = datetime.datetime.now(tz.UTC)
age = (now - latest_version.time_created).days
return age

Rotate if older than 90 days

def rotate_key_if_older_than(key_id: str, max_age_days: int = 90):
age_days = get_latest_key_version_age_days(key_id)
if age_days >= max_age_days:
print(f"Rotating key {key_id}. Age: {age_days} days")
kms_management_client.create_key_version(key_id=key_id)
return True
else:
print(f"No rotation needed for {key_id}. Age: {age_days} days")
return False

# Example:
key_ocid = "ocid1.key.oc1..."
rotate_key_if_older_than(key_ocid, max_age_days=90)

You can run this script daily via a scheduled job (e.g., OCI Functions + Service Connector / Events, or a cron job in a VM).


4. Basic “Monitoring” Output / Alerting

To align with “Encryption Monitoring”, you may simply:

  • Log which keys are:
    • Not using auto-rotation, or
    • Older than 90 days.
  • Export results to:
    • OCI Logging
    • Email via OCI Notifications
    • Any SIEM

Example: print report of non-compliant keys:

def find_non_compliant_keys(compartment_id: str, vault_id: str, max_age_days: int = 90):
non_compliant = []
keys = list_keys_in_vault(compartment_id, vault_id)

for key in keys:
# Check auto rotation
if key.auto_key_rotation_details and key.auto_key_rotation_details.is_enabled:
if key.auto_key_rotation_details.rotation_interval_in_days <= max_age_days:
continue # compliant

# Otherwise check last key version age
age_days = get_latest_key_version_age_days(key.id)
if age_days > max_age_days:
non_compliant.append((key, age_days))

return non_compliant

# Usage:
non_compliant = find_non_compliant_keys(compartment_ocid, vault_ocid, max_age_days=90)
for key, age in non_compliant:
print(f"NON-COMPLIANT: {key.display_name} ({key.id}) - age {age} days")

Then you can wire this into:

  • OCI Notifications (publish message)
  • Email/slack via separate process.

If you tell me how you’re currently running “OCI Encryption Monitoring” (function, VM, CI job, etc.), I can adapt this into a single ready-to-run script for that environment.

Using Terraform

Terraform for the oci_kms_key resource does not expose any argument to configure automatic rotation or a rotation interval, so this finding cannot be remediated purely via Terraform; configure key rotation in the OCI Console (Vault → Keys → select key → Enable/Configure Auto Rotation) or via scheduled OCI CLI/SDK automation instead.

# NOTE: OCI KMS key rotation interval (e.g., every 90 days) is not configurable
# via the oci_kms_key Terraform resource as of the current provider version.
# Use the OCI Console or an external scheduler + CLI/SDK to rotate keys.

resource "oci_kms_key" "EXAMPLE_KEY" {
# Replace with your values
compartment_id = "OCID_OF_COMPARTMENT"
management_endpoint = "https://KMS_ENDPOINT"
display_name = "EXAMPLE_KEY_NAME"

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

Verification in Terraform: terraform plan will not show any field related to rotation interval or automatic rotation for oci_kms_key; rotation must be verified in the OCI Console under the key’s rotation settings.