Você já resolveu a autenticação da sua VM com o Instance Principals, sem credencial em disco, sem .env, sem chave privada exposta. Ainda não? Então leia o artigo anterior com tutorial completo. Certo, tudo pronto!
Será?
Então você precisa chamar uma API externa, ou conectar num banco fora do OCI, talvez disparar um webhook do Slack. Pois é, de repente o .env precisa voltar. E não tem como usar a mesma solução da autenticação da VM: essas credenciais não têm Instance Principal, são chaves de terceiros, mas mesmo assim, elas precisam ficar em algum lugar. A pergunta é: onde?
O OCI Vault é a nossa resposta. Ele complementa a configuração sem credenciais da sua VM: o lugar certo para qualquer credencial que não deve aparecer no código, nem em algum arquivo perdido na sua aplicação.
O que você pode guardar no Vault?
Qualquer string que dá acesso a algum sistema pode ser recuperada pelo Vault:
- Chaves de API externa:
sk-abc123xyz789... - Senhas de banco de dados:
P@ssw0rd_Prod2026 - Tokens de webhook:
xoxb-fake-slack-token-... - Connection strings:
postgresql://user:senha@host/db - Chaves privadas em base64:
LS0tLS1CRUdJTi...
Todas recuperáveis pelas próprias aplicações ou um script simples em Python, por exemplo. Por outro lado, se qualquer um desses segredos aparecer num repositório, num log, ou numa variável de ambiente exposta por engano, o dano é imediato e possivelmente irreversível. E para piorar, muitas vezes a parte mais difícil é identificar quando e onde aconteceu.
Pré-requisitos
- Conta na OCI (Free Tier resolve).
- OCI CLI configurado - Cloud Shell já vem pronto e é o que vou usar.
1. Criando o Vault
Agora vamos criar nosso cofre. Lembrando que todo o procedimento está sendo feito diretamente do Cloud Shell.
oci kms management vault create \ --compartment-id $COMPARTMENT_ID \ --display-name "ace-vault" \ --vault-type DEFAULT \ --region sa-vinhedo-1
Salve o id retornado e aguarde ficar ativo:
VAULT_ID=<id retornado> oci kms management vault get \ --vault-id $VAULT_ID \ --region sa-vinhedo-1 \ --query "data.\"lifecycle-state\"" --raw-output # Aguarde: ACTIVE

2. Criando a master key
Todo secret precisa de uma chave de criptografia. O Vault usa HSM (Hardware Security Module) por padrão. A chave fica armazenada no hardware e nunca sai de lá, nem mesmo para gerenciamento.
MGMT_ENDPOINT=$(oci kms management vault get \
--vault-id $VAULT_ID \
--region sa-vinhedo-1 \
--query "data.\"management-endpoint\"" --raw-output)
oci kms management key create \
--compartment-id $COMPARTMENT_ID \
--display-name "ace-master-key" \
--key-shape '{"algorithm":"AES","length":32}' \
--endpoint $MGMT_ENDPOINT \
--region sa-vinhedo-1
Salve o id da key e aguarde o status mudar para Enabled:
KEY_ID=<id retornado>
3. Criando os secrets
Com Vault e key prontos, cada secret (senha ou chave armazenada) é criado com um único comando. O valor é codificado em base64 durante o armazenamento, mas é decodificado automaticamente durante a recuperação na hora de usar.
Chave de API externa
oci vault secret create-base64 \ --compartment-id $COMPARTMENT_ID \ --secret-name "minha-api-key" \ --vault-id $VAULT_ID \ --key-id $KEY_ID \ --secret-content-content $(echo -n "sk-abc123xyz789-chave-fake-para-demo" | base64) \ --region sa-vinhedo-1

Senha de banco de dados
oci vault secret create-base64 \ --compartment-id $COMPARTMENT_ID \ --secret-name "db-password" \ --vault-id $VAULT_ID \ --key-id $KEY_ID \ --secret-content-content $(echo -n "P@ssw0rd_Prod2026_SuperSecreta" | base64) \ --region sa-vinhedo-1
Detalhe do bash: o terminal interpreta ! como atalho de histórico de comandos. Por isso, evite esse caractere se for transmitir senhas pelo comando via echo no shell. Use _ ou - como separadores.

Token de webhook
oci vault secret create-base64 \ --compartment-id $COMPARTMENT_ID \ --secret-name "slack-webhook-token" \ --vault-id $VAULT_ID \ --key-id $KEY_ID \ --secret-content-content $(echo -n "xoxb-fake-slack-token-123456789" | base64) \ --region sa-vinhedo-1

Confirme que os três secrets foram salvos corretamente e estão ativos:
oci vault secret list \
--compartment-id $COMPARTMENT_ID \
--region sa-vinhedo-1 \
--query "data[*].{nome:\"secret-name\", status:\"lifecycle-state\"}" \
--output table

Para recuperar seus secrets via Python ou em qualquer outra aplicação, você vai precisar dos OCIDs de cada um deles. Você pode listá-los no próprio Cloud Shell:
oci vault secret list \
--compartment-id $COMPARTMENT_ID \
--region sa-vinhedo-1 \
--query "data[*].{nome:\"secret-name\", id:id}" \
--output table

4. Buscando os secrets em Python
Agora que não temos mais nenhuma credencial no código ou em algum arquivo .env, precisamos recuperá-las. Para isso, uma das maneiras mais simples é um script via Python, que solicita os segredos ao Vault, recebe em formato base64, decodifica para seu formato original e imprime na tela.
import oci
import base64
config = oci.config.from_file()
secrets_client = oci.secrets.SecretsClient(config)
secrets = {
"minha-api-key": "<ocid do secret>",
"db-password": "<ocid do secret>",
"slack-webhook-token": "<ocid do secret>"
}
for name, secret_id in secrets.items():
bundle = secrets_client.get_secret_bundle(secret_id=secret_id)
valor = base64.b64decode(
bundle.data.secret_bundle_content.content
).decode("utf-8")
print(f"{name}: {valor}")

Na verdade, em uma situação de uso real, você dificilmente vai imprimir o valor na tela. Provavelmente já vai recuperar a senha diretamente onde vai usá-la:
bundle = secrets_client.get_secret_bundle(secret_id=DB_SECRET_ID)
password = base64.b64decode(
bundle.data.secret_bundle_content.content
).decode("utf-8")
conn = psycopg2.connect(
host="seu-banco.example.com",
database="producao",
user="app_user",
password=password
)
Você também pode buscar via CLI, o que é bem útil para fazer testes antes de integrar ao código:
oci secrets secret-bundle get \ --secret-id $SECRET_ID \ --region sa-vinhedo-1 \ --query "data.\"secret-bundle-content\".content" \ --raw-output | base64 --decode
"Mas o OCID não é só outro hardcode?"
No fim das contas, parece que não mudamos muita coisa do que costumávamos fazer, não é? Na verdade, não é bem assim. A diferença está no que acontece quando o código vaza.
Uma senha no seu código hospedado em um repositório significa ter acesso direto ao banco. Sem notificação nenhuma, sem rastreamento, sem saber quem entrou ou por quanto tempo ficou. O OCID no repositório não entrega nada disso. Para buscar o secret, a aplicação precisa de uma identidade IAM com policy autorizada. Sem essa identidade, o OCID não tem acesso a nada.
Além disso, o Vault resolve três problemas que senha em código nunca resolve:
Rotação sem redesploy: Você pode atualizar sua senha diretamente no Vault e a aplicação já terá o novo valor na próxima requisição. Sem precisar alterar nenhuma linha de código nem reiniciar nada.
Auditoria: Cada acesso ao secret fica registrado no OCI Audit, ou seja, você sabe quem buscou, quando, e com qual identidade. Com .env ou senha no código você não tem nenhuma dessas informações.
Revogação imediata: Se o ambiente for comprometido, você desabilita aquele secret específico no Vault e todas as aplicações param de receber a credencial. Não vai precisar rotacionar banco, nem revogar chaves em dez lugares diferentes.
Combinando com Instance Principals
Esse é o cenário completo que elimina qualquer credencial estática do fluxo: a VM autentica no OCI via Instance Principal, sem ~/.oci/config e sem chave privada gravada em disco e busca as senhas que precisa diretamente no Vault em runtime. Pronto, você está conectado ao banco. Tudo isso sem expor nenhuma string sensível, seja num arquivo .env perdido ou no próprio código em si descansando num repositório qualquer.
Autenticação por Instance Principals foi o tema do artigo anterior desta série sobre tratamento de credenciais. Depois de ler e implementar as sugestões dos dois artigos, o ciclo se fecha: a VM não precisa de credencial para autenticar no OCI e o código não precisa de credencial para acessar o banco. Depois disso, mesmo que algo vaze, não vai servir para muita coisa.
Pode parecer muito complicado, mas o investimento de tempo é justificável. Configurar o Vault leva uma hora. Descobrir que uma credencial estava exposta há semanas vai te dar uma dor de cabeça que vai durar muito mais que isso.