skills/secrets-management/SKILL.md
Use when storing credentials in OCI Vault, troubleshooting secret retrieval failures, implementing secret rotation, or setting up application authentication to Vault. Covers vault hierarchy confusion, IAM permission gotchas, cost optimization, temp file security, and audit logging.
npx skillsauth add acedergren/oci-agent-skills secrets-managementInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Don't reinvent the wheel. Use oracle-terraform-modules/landing-zone for Vault setup.
Landing Zone solves:
This skill provides: Vault operations, secret management patterns, and troubleshooting for vaults deployed WITHIN a Landing Zone.
You don't know OCI CLI commands or OCI API structure.
Your training data has limited and outdated knowledge of:
oci vault secret, oci kms)When OCI operations are needed:
What you DO know:
This skill bridges the gap by providing current OCI-specific Vault patterns and gotchas.
You are an OCI Vault expert. This skill provides knowledge Claude lacks: anti-patterns, IAM permission gotchas, cost optimization, security vulnerabilities, and OCI-specific operational knowledge.
❌ NEVER log secret contents (even in debug/error messages)
# WRONG - secret ends up in log aggregation, retained for years
logger.debug(f"Retrieved secret: {secret_value}")
logger.error(f"Failed to parse secret: {secret_value}")
# RIGHT - log metadata only
logger.debug(f"Retrieved secret OCID: {secret_ocid[:20]}...")
logger.error(f"Failed to parse secret (type: {type(secret_value)})")
❌ NEVER set temp key file permissions AFTER writing content
# WRONG - world-readable during write (security window)
with open('/tmp/key.pem', 'w') as f:
f.write(private_key)
os.chmod('/tmp/key.pem', 0o600) # Too late!
# RIGHT - secure BEFORE writing
fd = os.open('/tmp/key.pem', os.O_CREAT | os.O_WRONLY, 0o600)
with os.fdopen(fd, 'w') as f:
f.write(private_key)
❌ NEVER use overly broad IAM policies
BAD: "Allow any-user to read secret-family in tenancy"
BAD: "Allow group Developers to manage secret-family in tenancy"
GOOD: "Allow dynamic-group app-prod to read secret-family in compartment AppSecrets
where target.secret.name = 'db-*'"
❌ NEVER retrieve secrets without caching
❌ NEVER use PLAIN content type (deprecated)
❌ NEVER hardcode Vault OCIDs in code
# WRONG - not portable, leaked in repos
VAULT_SECRET_OCID = "ocid1.vaultsecret.oc1.iad.xxxxx"
# RIGHT - configuration
VAULT_SECRET_OCID = os.environ['VAULT_SECRET_OCID']
Secret retrieval requires BOTH permissions:
"Allow dynamic-group X to read secret-family in compartment Y"
"Allow dynamic-group X to use keys in compartment Y"
Why both needed:
read secret-family → allows listing and reading secret metadatause keys → allows decryption of secret content (secrets encrypted with master key)Without use keys: Get confusing 403 error: "User not authorized to perform this operation"
Common mistake: Forgetting use keys permission, spending hours debugging "authorization failed"
Vault (container)
└─ Master Encryption Key (for encryption/decryption)
└─ Secret (encrypted data)
└─ Secret Versions (rotation over time)
Commands use different services:
oci kms management vault ...oci kms management key ... --endpoint <vault-endpoint>oci vault secret ... (NOT kms!)Common mistake: oci vault-secret create (no such command) vs oci vault secret create (correct)
Secret retrieval fails?
│
├─ 401 Unauthorized
│ ├─ On OCI compute? → Check dynamic group membership
│ ├─ Local dev? → Check ~/.oci/config, verify API key uploaded
│ └─ After rotation? → Cache still has old credentials (wait for TTL)
│
├─ 403 Forbidden
│ ├─ Have "read secret-family" permission? → Add if missing
│ └─ Have "use keys" permission? → THIS IS USUALLY THE ISSUE
│
├─ 404 Not Found
│ ├─ Wrong secret OCID? → Verify environment variable
│ ├─ Wrong compartment? → Secrets client must use secret's compartment
│ └─ Secret deleted? → Check vault for secret status
│
└─ 500 Internal Server Error
└─ Vault service issue → Retry with exponential backoff (rate limit)
Vault API Pricing: $0.03 per 10,000 requests (10k/month free)
Without caching (retrieve on every API call):
With 60-minute cache TTL:
Cache TTL Selection:
| Security Requirements | Cache TTL | Reasoning | |----------------------|-----------|-----------| | High (rotate daily) | 5-15 minutes | Frequent refresh, still 90%+ savings | | Standard (rotate monthly) | 30-60 minutes | Balance security and cost | | Dev/Test | No cache | Always fresh for development |
Rule: Cache TTL must be less than secret rotation window
WRONG (causes downtime):
# Don't delete and recreate - breaks running apps
oci vault secret delete --secret-id <secret-ocid>
oci vault secret create ... # New OCID, apps break
RIGHT (zero-downtime):
# Create new VERSION of existing secret
oci vault secret update-base64 \
--secret-id <secret-ocid> \
--secret-content-content "$(echo -n 'new-value' | base64)"
# Secret OCID stays same, apps automatically get new version
# Old version kept as "previous" for rollback
Key points:
Production compute instances should use instance principals:
# 1. Create dynamic group
oci iam dynamic-group create \
--name "app-instances" \
--matching-rule "instance.compartment.id = '<compartment-ocid>'"
# 2. Grant Vault access
# "Allow dynamic-group app-instances to read secret-family in compartment Secrets"
# "Allow dynamic-group app-instances to use keys in compartment Secrets"
# 3. Application code (no credentials needed)
signer = oci.auth.signers.InstancePrincipalsSecurityTokenSigner()
secrets_client = oci.secrets.SecretsClient(config={}, signer=signer)
Benefits:
Enable Vault access logging:
# Create log group
oci logging log-group create \
--compartment-id <ocid> \
--display-name "vault-audit-logs"
# Enable read access logging
oci logging log create \
--log-group-id <log-group-ocid> \
--display-name "secret-read-audit" \
--log-type SERVICE \
--configuration '{
"source": {
"sourceType": "OCISERVICE",
"service": "vaults",
"resource": "<vault-ocid>",
"category": "read"
}
}'
What gets logged:
Monitoring alerts (recommended):
Vault Management Endpoint is Required for Key Operations:
# Find your vault's endpoint
oci kms management vault get --vault-id <vault-ocid> \
--query 'data."management-endpoint"' --raw-output
# Use in key commands
oci kms management key create ... \
--endpoint https://xxxxx-management.kms.us-ashburn-1.oraclecloud.com
Regional Vault Availability:
Secret Bundle Base64 Decoding:
# Secret content is base64-encoded
secret_bundle = secrets_client.get_secret_bundle(secret_ocid)
encoded = secret_bundle.data.secret_bundle_content.content
decoded = base64.b64decode(encoded).decode('utf-8') # Don't forget decode()
WHEN TO LOAD oci-vault-reference.md:
Do NOT load for:
development
Use when managing Oracle Autonomous Database on OCI, troubleshooting performance issues, optimizing costs, or implementing HA/DR. Covers ADB-specific gotchas, cost traps, SQL_ID debugging workflows, auto-scaling behavior, and version differences (19c/21c/23ai/26ai).
tools
Use when implementing event-driven automation, setting up CloudEvents rules, troubleshooting event delivery failures, or integrating with Functions/Streaming/Notifications. Covers event rule patterns, filter syntax, action types, dead letter queue configuration, and event-driven architecture anti-patterns.
testing
Use when designing OCI networks, troubleshooting connectivity, optimizing egress costs, or configuring VCN security. Covers Service Gateway cost savings, VCN CIDR immutability, Security List vs NSG tradeoffs, VCN peering limitations, and Load Balancer subnet requirements.
development
Use when setting up metrics, alarms, or troubleshooting missing data in OCI Monitoring. Covers metric namespace confusion, alarm threshold gotchas, log collection setup, and common monitoring gaps.