OCI Vault is Oracle Cloud Infrastructure's managed service for encryption keys and, historically, secrets. It holds master encryption keys inside hardware security modules (HSMs), performs cryptographic operations with them on request, and lets other OCI services such as Object Storage and Block Volume encrypt your data with keys you control instead of Oracle-managed ones. It also stores application secrets such as database passwords and API tokens, encrypted with those keys.

The provider-neutral design ideas, such as envelope encryption, key hierarchies and why a key service becomes an availability dependency, are covered in cloud KMS architecture and cloud secrets architecture. This article is about OCI specifically: the choices you make when you create a vault and a key that cannot be changed later, how to call it from code, how IAM gates it, and what goes wrong in operation. Figures come from Oracle's documentation; check the current limits page for your tenancy before you depend on a number.

Advertisement

The object model

Four kinds of object matter, and they nest.

  • Vault. A container for keys and secrets in one compartment and one region. A vault has its own endpoints: a management endpoint for creating and rotating keys, and a cryptographic endpoint for encrypt, decrypt and data key generation. The two are separate URLs, so code that calls the wrong one fails with confusing errors.
  • Master encryption key. A named key with an OCID. It stays the same across rotations; each rotation adds a key version, and only the newest version encrypts.
  • Data encryption key (DEK). A key generated by Vault from a symmetric master key and returned to you, in plaintext and wrapped, for encrypting bulk data yourself.
  • Secret. A named value stored in a vault and encrypted by one of its master keys. Each change creates a secret version.

Keys live in the compartment you choose, which is how you scope access: a policy on the compartment decides who can use them. If you have not designed your compartments yet, read OCI IAM first, because the key and secret layout should follow it.

OCI Vault: keys never leave the HSM, data keys and secrets do the travellingVault (one region)Management endpointkeys, versionsCrypto endpointencrypt, decryptHSM partition (FIPS 140-2 L3)master encryption keysSecretsversions encrypted by a keyYour applicationinstance principalIAM policydynamic groupObject StorageBlock Volume, DBsAudit + Eventsevery call, rotationgenerate DEKget secret bundlewrap / unwrap DEKlogsIntegrated services store only the wrapped data key. Revoke IAM or disable the key, and the data becomes unreadable.
Applications call the crypto endpoint for data keys and the secrets API for secret bundles. Integrated services wrap their data keys with your master key. IAM decides every call, and Audit records it.

Choosing a vault type

When you create a vault, you choose its type, and you cannot change it afterwards.

Virtual private vaultDefault vault
HSMIsolated partition on the HSMShared partitions with other vaults
PricingHigher fixed price; 1,000 key versions includedPay per key version
BackupVault can be backed upNot supported
Automatic key rotationSupportedNot available

The practical rule: use a default vault for most workloads, where the shared HSM partition meets your requirements and you rotate keys manually or with your own automation. Use a virtual private vault when a regulator or customer contract requires an isolated HSM partition, when you need vault backups, or when you want built-in automatic rotation. Because asymmetric key versions count twice toward limits (they have public and private halves), a heavy RSA signing estate uses up the included versions faster than you might expect.

Advertisement

Choosing a protection mode and algorithm

Each key also has a protection mode, fixed at creation:

  • HSM. Key material is created and used inside the HSM and cannot be exported. Use this by default and always for keys protecting other keys or regulated data. The HSMs are validated to FIPS 140-2 Security Level 3.
  • Software. Key material is stored on a server, encrypted at rest by a root key in the HSM, and can be exported to the client so cryptographic operations happen there. It is cheaper and more flexible, and a weaker guarantee, because the key can exist outside the HSM.
  • External. The key stays in a third-party key manager outside OCI ("hold your own key"), and Vault calls it for operations. Use it when policy forbids key material in the cloud provider; accept that the external system now sits on your data path for availability and latency.

Algorithms: AES keys are for symmetric encryption and decryption, and are what integrated services and data keys use. RSA keys support encryption and decryption as well as signing and verification. ECDSA keys are for signing and verification only, not encryption. Each vault also comes with a 4096-bit RSA wrapping key, which you use to wrap your own key material when importing it (bring your own key); you cannot create, rotate or delete it.

Envelope encryption with the Python SDK

Never send bulk data to Vault. Ask it for a data key, encrypt locally, and store the wrapped key next to the data. Decrypting means sending only the wrapped key back to Vault. The code below uses the OCI Python SDK with an instance principal, so no API key lives on the host.

import base64, os, oci
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

signer = oci.auth.signers.InstancePrincipalsSecurityTokenSigner()
CRYPTO_ENDPOINT = os.environ["VAULT_CRYPTO_ENDPOINT"]   # the vault's crypto endpoint, not management
KEY_ID = os.environ["MASTER_KEY_OCID"]

kms = oci.key_management.KmsCryptoClient(config={}, signer=signer,
                                         service_endpoint=CRYPTO_ENDPOINT)

def encrypt_blob(plaintext: bytes) -> dict:
    resp = kms.generate_data_encryption_key(
        oci.key_management.models.GenerateKeyDetails(
            key_id=KEY_ID,
            include_plaintext_key=True,
            key_shape=oci.key_management.models.KeyShape(algorithm="AES", length=32)))
    dek = base64.b64decode(resp.data.plaintext)
    nonce = os.urandom(12)
    ct = AESGCM(dek).encrypt(nonce, plaintext, None)
    del dek                                      # keep the plaintext key short-lived
    return {"wrapped_key": resp.data.ciphertext, "nonce": nonce, "ct": ct}

def decrypt_blob(env: dict) -> bytes:
    resp = kms.decrypt(oci.key_management.models.DecryptDataDetails(
        key_id=KEY_ID, ciphertext=env["wrapped_key"]))
    dek = base64.b64decode(resp.data.plaintext)
    return AESGCM(dek).decrypt(env["nonce"], env["ct"], None)

The wrapped key records which key version produced it, which is why rotation does not break decryption: old versions remain usable for decrypt even though new encryptions use the newest version. Cache plaintext data keys briefly in memory if you encrypt many small objects, rather than calling Vault per object; the cryptographic endpoint has request limits, and a per-object call pattern is the usual cause of throttling.

Integrated services: customer-managed keys

Object Storage buckets, block volumes, file systems and databases can use a Vault key instead of an Oracle-managed key. You select the key on the resource, and the service generates and wraps its own data keys with it. The service needs permission to use the key, granted to the service itself, for example:

Allow service objectstorage-us-ashburn-1 to use keys in compartment security-keys
Allow service blockstorage to use keys in compartment security-keys

The service and the vault must be in the same region. This is also where the most surprising outages come from: if someone disables the key, schedules it for deletion, or removes the service policy, the service can no longer unwrap its data keys and the data becomes unreadable until access is restored. That is exactly the control you wanted, and it means key changes need the same review as data deletions. See OCI Object Storage for the bucket side of this setup.

Secrets: storing and reading

A secret is a value up to 25 KB, stored as base64 and encrypted with a master key you choose. Secret versions are not stored in the HSM; only keys are. Oracle has moved the secrets functionality, including secret rules, into a separate Secret Management service in its documentation, but secrets are still created in a vault and read through the same Secrets API.

Each version has a rotation state. CURRENT is what readers normally get, PENDING is staged for a coordinated switch, and PREVIOUS is the one before current, which is useful for rollback. Read by stage rather than by version number, so a rotation does not need a deployment:

secrets = oci.secrets.SecretsClient(config={}, signer=signer)
bundle = secrets.get_secret_bundle(secret_id=os.environ["DB_PASSWORD_SECRET_OCID"],
                                   stage="CURRENT")
db_password = base64.b64decode(bundle.data.secret_bundle_content.content).decode()

# CLI equivalent
# oci secrets secret-bundle get --secret-id <secret_ocid> --stage CURRENT

Secret rules enforce hygiene. A reuse rule prevents a new version from repeating previous content. An expiry rule sets a version expiry interval of 1 to 90 days, or an absolute expiry 1 to 365 days ahead, and can block reads of expired content. Turn on the expiry rule only once rotation is automated, or the first missed rotation becomes an outage.

IAM: who can do what

Access is governed by ordinary OCI IAM policies, and the resource types are deliberately fine-grained. Separate the people who manage keys from the workloads that use them.

Allow group KeyAdmins to manage vaults in compartment security-keys
Allow group KeyAdmins to manage keys in compartment security-keys
Allow dynamic-group app-servers to use keys in compartment security-keys
Allow dynamic-group app-servers to read secret-bundles in compartment app-secrets
Allow group SecretWriters to manage secret-family in compartment app-secrets

The application can generate and unwrap data keys and read secret contents, and nothing else; it cannot rotate, disable or delete keys. Keep vaults in a dedicated compartment owned by a security team, so a broad administrator policy on an application compartment does not reach them. Every call is recorded by OCI Audit, which is the detective control: alert on key disable, schedule deletion and policy changes in the key compartment.

Rotation and deletion

Rotating a master key creates a new version under the same OCID. New encryptions use it, and old versions stay available for decryption, so nothing needs re-encrypting immediately. Virtual private vaults can rotate automatically on an interval between 60 and 365 days, and OCI Events emits a notification after each rotation that you can route to automation. On default vaults, rotate with a scheduled job calling the management API.

Deletion is deliberately slow. Scheduling a key for deletion starts a waiting period of 7 to 30 days, 30 by default, during which you can cancel. Once a key is deleted, data encrypted under it is unrecoverable. Before scheduling deletion, disable the key for a period and watch Audit and application errors for anything still using it; a disabled key can be re-enabled, a deleted one cannot.

Availability and regions

Vault is regional. Keys are kept in copies across the availability domains of a region, or across fault domains in single-domain regions, and secrets across two availability or fault domains. There is no automatic cross-region copy of a vault; for disaster recovery, configure replication yourself and plan for keys in the recovery region before you need them. Applications in a VCN can reach Vault through a service gateway without traversing the internet. Treat the cryptographic endpoint as a dependency of every request path that decrypts, and size data-key caching and retries accordingly.

Worked example: a payments service

A payments API on OCI Compute stores card tokens in Object Storage and a database password in Vault. Setup: a default vault in a security-keys compartment; an HSM-protected AES-256 key for the bucket; a second AES key for application envelope encryption; a secret holding the database password with a reuse rule and a 60-day expiry interval; a dynamic group for the API instances with use keys and read secret-bundles; and a service policy letting Object Storage use the bucket key.

A rotation job runs every 30 days: it creates a new database password, writes it as a pending secret version, updates the database user, promotes the version to current, and lets instances pick it up on their next refresh, using previous as the fallback during the switch. Master keys are rotated quarterly by a scheduled job. Audit alerts page the security team on any key disable or deletion schedule.

Failure modes

  • Wrong endpoint. Crypto calls sent to the management endpoint, or the reverse, fail in ways that look like permission errors.
  • Missing service policy. A bucket or volume set to use a customer key without the service being allowed to use it fails at creation or, worse, after a policy cleanup.
  • Accidental key disable. Every resource wrapped by that key becomes unreadable; protect the key compartment with narrow admin rights and alerts.
  • Per-object crypto calls. High-volume code calling Vault for every object hits request limits; reuse data keys for a bounded time.
  • Expiry without rotation. An expiry rule blocks reads of a secret nobody rotated.
  • Assuming cross-region. A DR region with no keys cannot decrypt replicated data.
  • Software keys for regulated data. Exportable key material does not meet requirements that call for HSM-only keys.

What to do next

  1. Decide vault type per environment: default unless you need isolation, vault backup or automatic rotation.
  2. Create a dedicated security compartment and HSM-protected AES keys for each data domain.
  3. Switch buckets, volumes and databases holding sensitive data to customer-managed keys, with the matching service policies.
  4. Move application secrets into Vault, read them by stage with instance or resource principals, and add reuse and expiry rules once rotation is automated.
  5. Write least-privilege policies that separate key admins, secret writers and workloads.
  6. Automate key rotation and alert on key disable, deletion scheduling and policy changes through Audit and Events.
  7. Plan DR keys in a second region and test that restored data decrypts there.
Key takeaway: OCI Vault keeps master keys in FIPS 140-2 Level 3 HSMs and lets you, rather than Oracle, decide who can decrypt your data. Choose the vault type and key protection mode carefully, because neither can be changed later. Use envelope encryption with data keys from the crypto endpoint, let integrated services wrap their keys with yours, read secrets by stage, and separate key administrators from workloads in IAM. Then automate rotation, guard key disable and deletion with alerts, and plan keys for your DR region before you need them.