When a customer's config file holds a plaintext database password, move it into OCI Vault. The application then fetches it at start-up with its instance identity, so no keys sit on disk.
1. Create the vault, key and secret
oci kms management vault create --compartment-id $C --display-name prod-vault --vault-type DEFAULT
# use the vault's management endpoint for key operations
oci kms management key create --compartment-id $C --display-name app-secrets-key \
--key-shape '{"algorithm":"AES","length":32}' --endpoint <management-endpoint>
oci vault secret create-base64 --compartment-id $C --vault-id $VAULT --key-id $KEY \
--secret-name orders-db-password \
--secret-content-content "$(printf '%s' 'S3cure-Pass!' | base64)"
2. Let the application read it
Create a dynamic group for the app's instances:
ALL {instance.compartment.id = 'ocid1.compartment.oc1..apps'}
Then a policy that grants read access to only that secret:
Allow dynamic-group OrdersApp to read secret-bundles in compartment Apps where target.secret.name = 'orders-db-password'
3. Fetch it at runtime
oci secrets secret-bundle get --secret-id $SECRET --auth instance_principal \
--query 'data."secret-bundle-content".content' --raw-output | base64 -d
import base64, oci
signer = oci.auth.signers.InstancePrincipalsSecurityTokenSigner()
client = oci.secrets.SecretsClient(config={}, signer=signer)
bundle = client.get_secret_bundle(secret_id="ocid1.vaultsecret.oc1..xxxx").data
password = base64.b64decode(bundle.secret_bundle_content.content).decode()
On OKE, use workload identity instead of instance principals so each pod gets only its own permissions.
4. Rotate without redeploying
oci vault secret update-base64 --secret-id $SECRET \
--secret-content-content "$(printf '%s' 'N3w-Pass!' | base64)"
A new version becomes current. Applications that fetch the secret at start-up (or cache it briefly) pick it up on their next restart or cache refresh. Change the database password and the secret together in one runbook step.
Common errors
| Error | Cause |
|---|---|
NotAuthorizedOrNotFound | The dynamic group rule doesn't match the instance, or the policy is in the wrong compartment |
Authorization failed or requested resource not found on the key | The secret's key is disabled or deleted. Secrets need their key. |
| Empty or garbled value | The content wasn't base64-decoded, or was double-encoded when created |
Warning
Never put secret values on the command line in shared shells or in CI logs. Use
--secret-content-contentfrom a file or environment variable, and clear your shell history afterwards.