Every application needs credentials: database passwords, API keys, TLS private keys, third-party service tokens. The wrong place to store them is source code, environment variables in CI/CD pipelines, or configuration files committed to Git. OCI Vault Secrets provides a managed secrets store where applications retrieve credentials at runtime using IAM Resource Principal authentication, rotation is automated through Functions, and every access is logged in the audit trail.
Step 1: Vault and Secrets
resource "oci_kms_vault" "production_vault" {
compartment_id = var.compartment_id
display_name = "production-vault"
vault_type = "DEFAULT"
defined_tags = { "Operations.Environment" = "production", "Operations.ManagedBy" = "terraform" }
}
resource "oci_kms_key" "vault_master_key" {
compartment_id = var.compartment_id
management_endpoint = oci_kms_vault.production_vault.management_endpoint
display_name = "vault-master-encryption-key"
key_shape {
algorithm = "AES"
length = 32
}
}
resource "oci_vault_secret" "db_password" {
compartment_id = var.compartment_id
vault_id = oci_kms_vault.production_vault.id
key_id = oci_kms_key.vault_master_key.id
secret_name = "orders-db-password"
description = "Oracle Database password for orders application user"
secret_content {
content_type = "BASE64"
content = base64encode(var.db_password_initial_value)
name = "initial"
stage = "CURRENT"
}
secret_rules {
rule_type = "SECRET_EXPIRY_RULE"
secret_version_expiry_interval = "P90D"
is_secret_content_retrieval_blocked_on_expiry = true
time_of_absolute_expiry = null
}
defined_tags = { "Operations.Environment" = "production" }
}
resource "oci_vault_secret" "api_key" {
compartment_id = var.compartment_id
vault_id = oci_kms_vault.production_vault.id
key_id = oci_kms_key.vault_master_key.id
secret_name = "payment-gateway-api-key"
secret_content {
content_type = "BASE64"
content = base64encode(var.payment_api_key)
name = "v1"
stage = "CURRENT"
}
secret_rules {
rule_type = "SECRET_EXPIRY_RULE"
secret_version_expiry_interval = "P365D"
is_secret_content_retrieval_blocked_on_expiry = false
}
}
output "vault_id" { value = oci_kms_vault.production_vault.id }
output "db_secret_id" { value = oci_vault_secret.db_password.id }
output "api_key_secret_id" { value = oci_vault_secret.api_key.id }
Step 2: IAM Policy for Application Access
resource "oci_identity_dynamic_group" "orders_app_instances" {
compartment_id = var.tenancy_ocid
name = "orders-application-instances"
description = "Compute instances running the orders application"
matching_rule = "All {instance.compartment.id = 'COMPARTMENT_OCID', tag.Operations.Application.value = 'orders'}"
}
resource "oci_identity_policy" "orders_vault_policy" {
compartment_id = var.compartment_id
name = "orders-app-vault-access"
statements = [
"Allow dynamic-group orders-application-instances to read secret-bundle in compartment id COMPARTMENT_OCID where target.secret.name = 'orders-db-password'",
"Allow dynamic-group orders-application-instances to read secret-bundle in compartment id COMPARTMENT_OCID where target.secret.name = 'payment-gateway-api-key'"
]
}
Step 3: Expiry Alarm
resource "oci_monitoring_alarm" "secret_expiry_warning" {
compartment_id = var.compartment_id
display_name = "vault-secret-expiry-warning"
is_enabled = true
metric_compartment_id = var.compartment_id
namespace = "oci_vault"
query = "SecretExpiryDays[1d]{vaultId = 'VAULT_OCID'}.min() < 30"
severity = "WARNING"
pending_duration = "PT24H"
destinations = [var.ops_notification_topic_id]
body = "One or more Vault secrets expire in less than 30 days. Rotate the secret before expiry to avoid application authentication failures."
}
Operational Notes
Applications retrieve secrets at runtime using the OCI SDK with Resource Principal authentication. No credentials are needed to call the Vault API when the application runs on a compute instance in the matching dynamic group. The SDK authenticates using the instance’s IMDS-issued token, which the IAM policy grants access to read specific secrets. The secret value is retrieved at startup and cached in memory for the lifetime of the process.
Secret rotation with OCI Vault creates a new secret version rather than overwriting the current value. The application must call the Vault API to get the latest version on each restart or on a periodic refresh timer. If your application caches the secret value on startup only, rotation requires a rolling restart of all instances to pick up the new value. Implement a background refresh that re-fetches the secret every hour to avoid requiring restarts for rotation.
Regards,
Osama
#OCI #OracleCloud #Vault #SecretsManagement #Terraform #IaC #TechBlog #Oracle #DevSecOps #PlatformEngineering #CloudSecurity #OracleCloudInfrastructure #ResourcePrincipal #KMS #Encryption #SecretRotation #ZeroTrust #CredentialManagement #IAM #ApplicationSecurity
Leave a Reply