Skip to main content

OCI Storage Buckets Should Be Encrypted With

More Info:

Buckets must be encrypted using a dedicated KMS key. Relying on default encryption limits auditing visibility and prevents security teams from enforcing granular key rotation or revocation policies

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 Critical Security Controls v8
  • CMMC 2.0
  • CSA Cloud Controls Matrix v4
  • DPDPA
  • Digital Operational Resilience Act (EU)
  • Essential 8
  • 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
  • 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 step‑by‑step OCI Console instructions to remediate the finding “OCI Storage Buckets Should Be Encrypted With Customer‑Managed Keys” by moving an Object Storage bucket from Oracle‑managed keys to customer‑managed keys (CMK).


1. Prepare a Customer-Managed Key (if you don’t have one)

  1. Sign in to the OCI Console.
  2. From the left menu, go to Identity & Security → Vault.
  3. Make sure you are in the correct Compartment and Region.
  4. If you don’t already have a vault:
    1. Click Create vault.
    2. Enter a Name, choose Type (generally Default), select the Compartment, and click Create vault.
    3. Wait for the vault status to become Active.
  5. Inside the vault, create a key:
    1. Open the vault you just created.
    2. Click Master Encryption Keys (or Keys).
    3. Click Create key.
    4. Enter a Name and optional Description.
    5. Choose Key Shape (e.g., AES, 256‑bit).
    6. Click Create key and wait until it is Enabled/Active.

Note the OCID or simply remember the Key name and Vault name; you’ll need to select this key when updating the bucket.


2. Update the Bucket to Use the Customer-Managed Key

  1. In the Console, go to Storage → Buckets.
  2. Select the correct Compartment in the left pane.
  3. Click on the bucket name that has the misconfiguration (currently using Oracle-managed encryption).
  4. On the bucket details page, click Edit (or Edit bucket).
  5. Find the Encryption section:
    • By default, it is usually set to Encrypt using Oracle-managed keys.
  6. Change the encryption setting to:
    • Encrypt using customer-managed keys.
  7. A Vault and Key selector will appear:
    1. Choose the Vault that contains your CMK.
    2. Choose the Key (customer-managed key) you created in step 1.
  8. Click Save changes (or Update).

The bucket will now use your customer-managed key for encryption of new objects and re-encryption of data as per OCI behavior.


3. (Optional) Verify via Security/Monitoring

If you’re using OCI Cloud Guard / Security Zones / other monitoring:

  1. Open Cloud Guard (or your monitoring tool).
  2. Run or wait for the next Detector evaluation against Object Storage.
  3. Confirm that the finding for that bucket is now Resolved or no longer appears.

4. Repeat for All Affected Buckets

Repeat section 2 for every Object Storage bucket flagged by your monitoring as not using customer‑managed keys.

Using CLI

To enforce “OCI Object Storage buckets must be encrypted with customer-managed keys” using the OCI CLI, you need to:

  1. Have a Vault and a Master Encryption Key.
  2. Update each bucket to use that key via --kms-key-id.

Below are step‑by‑step CLI instructions.


1. Prerequisites

  • OCI CLI installed and configured (oci setup config already done).
  • Permissions:
    • To manage keys and vaults.
    • To manage buckets in the compartments you care about.

Assume:

  • Tenancy OCID: <TENANCY_OCID>
  • Compartment OCID for buckets: <COMPARTMENT_OCID>
  • Region: <REGION>

Set:

export OCI_REGION="<REGION>"

2. Create (or identify) a Vault and Key

2.1. List existing vaults (if you already have one, you can skip creation)

oci kms management vault list \
--compartment-id <COMPARTMENT_OCID> \
--all

Note id of the vault you want to use, or create a new one.

2.2. Create a new vault (if needed)

oci kms management vault create \
--compartment-id <COMPARTMENT_OCID> \
--display-name "cmk-vault-monitoring" \
--vault-type DEFAULT

Capture the id from the output as VAULT_ID:

export VAULT_ID="<VAULT_OCID>"

2.3. Wait until vault is ACTIVE (if newly created)

oci kms management vault get --vault-id "$VAULT_ID" \
--query 'data."lifecycle-state"' --raw-output

Repeat until it shows ACTIVE.


3. Create a Master Encryption Key

3.1. Get the vault’s management endpoint

export MANAGEMENT_ENDPOINT=$( \
oci kms management vault get --vault-id "$VAULT_ID" \
--query 'data."management-endpoint"' --raw-output \
)

3.2. Create a key

oci kms management key create \
--compartment-id <COMPARTMENT_OCID> \
--endpoint "$MANAGEMENT_ENDPOINT" \
--display-name "cmk-obj-storage-monitoring" \
--protection-mode HSM \
--key-shape '{"algorithm": "AES", "length": 256}'

Capture the id of the key:

export KMS_KEY_ID="<KEY_OCID>"

4. Find Buckets That Are Not Using Customer-Managed Keys

List buckets in the compartment:

oci os bucket list \
--compartment-id <COMPARTMENT_OCID> \
--all

For each bucket, check if kms-key-id is set:

oci os bucket get \
--name "<BUCKET_NAME>" \
--query 'data."kms-key-id"' \
--raw-output

If this returns null or empty, the bucket is using Oracle-managed keys and is non‑compliant.


5. Update Buckets to Use the Customer-Managed Key

For each non‑compliant bucket:

oci os bucket update \
--name "<BUCKET_NAME>" \
--kms-key-id "$KMS_KEY_ID"

To script across all buckets in a compartment:

for BUCKET in $(oci os bucket list \
--compartment-id <COMPARTMENT_OCID> \
--query 'data[].name' \
--raw-output); do

CURRENT_KMS=$(oci os bucket get \
--name "$BUCKET" \
--query 'data."kms-key-id"' \
--raw-output)

if [ "$CURRENT_KMS" = "null" ] || [ -z "$CURRENT_KMS" ]; then
echo "Updating bucket: $BUCKET"
oci os bucket update \
--name "$BUCKET" \
--kms-key-id "$KMS_KEY_ID"
else
echo "Skipping bucket (already CMK-encrypted): $BUCKET"
fi
done

6. Verify Compliance

Re-check each bucket:

oci os bucket get \
--name "<BUCKET_NAME>" \
--query 'data."kms-key-id"' \
--raw-output

You should see the KMS_KEY_ID for all monitored buckets, confirming that they are now encrypted with your customer-managed key.

Using Python

Below is a concise, end‑to‑end approach to monitor OCI Object Storage buckets for encryption with customer-managed keys (CMKs) and remediate them using Python and the OCI SDK.


1. Prerequisites

  1. Install OCI Python SDK

    pip install oci
  2. Configure OCI credentials (API key)
    Run:

    oci setup config

    This creates ~/.oci/config with a profile (e.g., DEFAULT).

  3. Have a Vault and Key (CMK) created in OCI KMS

    • Create a Vault and Key in the OCI console (or via CLI).
    • Note the Key OCID: ocid1.key.oc1....
  4. Decide the scope

    • compartment_id where your buckets live.
    • namespace of Object Storage (usually 1 per tenancy/region).

2. Monitoring: Detect Buckets Not Using CMK

The logic:

  • List all buckets in a compartment.
  • Get each bucket’s details.
  • Check kms_key_id; if empty, it’s not using a CMK.
import oci

CONFIG_PROFILE = "DEFAULT"
COMPARTMENT_OCID = "<your_compartment_ocid>"

def get_object_storage_client():
config = oci.config.from_file("~/.oci/config", CONFIG_PROFILE)
return oci.object_storage.ObjectStorageClient(config), config

def list_unencrypted_buckets():
os_client, config = get_object_storage_client()

# Get namespace
namespace = os_client.get_namespace().data

# List buckets
buckets = oci.pagination.list_call_get_all_results(
os_client.list_buckets,
namespace_name=namespace,
compartment_id=COMPARTMENT_OCID
).data

non_cmk_buckets = []

for b in buckets:
bucket = os_client.get_bucket(namespace, b.name).data
# If kms_key_id is None or empty, it's not using a CMK
if not getattr(bucket, 'kms_key_id', None):
non_cmk_buckets.append(bucket.name)

return non_cmk_buckets

if __name__ == "__main__":
non_cmk = list_unencrypted_buckets()
print("Buckets NOT using CMK:")
for name in non_cmk:
print(f" - {name}")

3. Remediation: Attach Customer-Managed Key to Buckets

You can reconfigure bucket encryption by updating the bucket with your KMS Key OCID.

Important:

  • OCI does server-side encryption by default with Oracle-managed keys.
  • When you set kms_key_id, new objects use the CMK; existing objects are gradually re-encrypted in the background by OCI.
import oci

CONFIG_PROFILE = "DEFAULT"
COMPARTMENT_OCID = "<your_compartment_ocid>"
CMK_OCID = "<your_kms_key_ocid>" # Customer-managed key OCID

def get_object_storage_client():
config = oci.config.from_file("~/.oci/config", CONFIG_PROFILE)
return oci.object_storage.ObjectStorageClient(config), config

def remediate_buckets_with_cmk(cmk_ocid):
os_client, config = get_object_storage_client()
namespace = os_client.get_namespace().data

buckets = oci.pagination.list_call_get_all_results(
os_client.list_buckets,
namespace_name=namespace,
compartment_id=COMPARTMENT_OCID
).data

for b in buckets:
bucket = os_client.get_bucket(namespace, b.name).data

if getattr(bucket, 'kms_key_id', None):
# Already using a CMK (or some key) – skip or adjust logic as needed
continue

print(f"Updating bucket '{bucket.name}' to use CMK: {cmk_ocid}")

update_details = oci.object_storage.models.UpdateBucketDetails(
kms_key_id=cmk_ocid
)

os_client.update_bucket(
namespace_name=namespace,
bucket_name=bucket.name,
update_bucket_details=update_details
)

print("Remediation complete.")

if __name__ == "__main__":
remediate_buckets_with_cmk(CMK_OCID)

4. Combining Monitoring + Remediation (Optional)

To explicitly show what’s changed:

def remediate_only_non_cmk_buckets(cmk_ocid):
os_client, config = get_object_storage_client()
namespace = os_client.get_namespace().data

buckets = oci.pagination.list_call_get_all_results(
os_client.list_buckets,
namespace_name=namespace,
compartment_id=COMPARTMENT_OCID
).data

for b in buckets:
bucket = os_client.get_bucket(namespace, b.name).data
if not getattr(bucket, 'kms_key_id', None):
print(f"[REMEDIATE] {bucket.name}")
update_details = oci.object_storage.models.UpdateBucketDetails(
kms_key_id=cmk_ocid
)
os_client.update_bucket(namespace, bucket.name, update_details)
else:
print(f"[OK] {bucket.name} already has kms_key_id set")

if __name__ == "__main__":
remediate_only_non_cmk_buckets(CMK_OCID)

5. Integrating into Continuous Monitoring

  • Run the monitoring/remediation script:
    • On a schedule (OCI Functions + Events, or cron from a bastion/CI runner).
    • In read-only mode (monitor only) for reporting.
    • In remediation mode (update_bucket) in controlled environments.

This achieves:

  • Detection of buckets not using customer-managed keys.
  • Automatic remediation by attaching your CMK using Python.
Using Terraform
# Customer-managed KMS key (dedicated for this bucket)
resource "oci_kms_key" "bucket_cmk" {
# Replace with your compartment OCID
compartment_id = "OCID_OF_KEY_COMPARTMENT"

# Replace with your KMS vault OCID
management_endpoint = "VAULT_MANAGEMENT_ENDPOINT"

display_name = "BUCKET_CMK_NAME"

key_shape {
algorithm = "AES"
length = 32
}

protection_mode = "HSM" # or "SOFTWARE" per your standard
}

# OCI Object Storage bucket using the customer-managed key
resource "oci_objectstorage_bucket" "secure_bucket" {
compartment_id = "OCID_OF_BUCKET_COMPARTMENT"
namespace = "OBJECT_STORAGE_NAMESPACE"
name = "BUCKET_NAME"

# Point bucket encryption at the CMK
kms_key_id = oci_kms_key.bucket_cmk.id

storage_tier = "Standard" # or "Archive" as needed
}

Changing kms_key_id on an existing oci_objectstorage_bucket is an in-place update in the OCI provider and should not force bucket replacement, but review the plan carefully in your environment.

To verify, terraform plan should show:

  • A new oci_kms_key.bucket_cmk created (if not existing already).
  • An in-place update on oci_objectstorage_bucket.secure_bucket setting kms_key_id to the CMK ID.