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

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        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.
      </Accordion>

      <Accordion title="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:
           ```bash theme={null}
           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:
             ```text theme={null}
             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:

        ```bash theme={null}
        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):

        ```bash theme={null}
        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:

        ```bash theme={null}
        #!/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:

        ```bash theme={null}
        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:

        ```bash theme={null}
        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:

        ```bash theme={null}
        #!/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.
      </Accordion>

      <Accordion title="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:
           ```bash theme={null}
           pip install oci
           ```

        2. Configure OCI CLI/auth (SDK uses same config):
           ```bash theme={null}
           oci setup config
           ```
           This creates `~/.oci/config` with:
           * `tenancy`
           * `user`
           * `fingerprint`
           * `key_file`
           * `region`

        3. Ensure your user or instance principal has permissions:
           ```text theme={null}
           Allow group <group-name> to manage keys in tenancy
           Allow group <group-name> to read vaults in tenancy
           ```

        ***

        ## 2. Enabling Automatic Rotation Every 90 Days (Recommended)

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

        ```python theme={null}
        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

        ```python theme={null}
        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

        ```python theme={null}
        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

        ```python theme={null}
        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:

        ```python theme={null}
        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.
      </Accordion>

      <Accordion title="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.

        ```hcl theme={null}
        # 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.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
