Por que usar o Secrets Manager em vez de hardcoding de credenciais?
A pergunta aparece toda semana em revisões de código: 'o repositório é privado, então qual é o problema de deixar a senha do banco no application.properties?' O problema é que repositório privado não é modelo de segurança — é uma suposição que falha no primeiro acidente de permissão, no primeiro desenvolvedor que sai da empresa, ou no primeiro vazamento de token do GitHub. O AWS Secrets Manager existe exatamente para eliminar essa suposição do design da aplicação.
TL;DR — Hardcoding vs. Secrets Manager
| Critério | Hardcoding / Variável de Ambiente | AWS Secrets Manager |
|---|---|---|
| Rotação de senha | Manual, requer redeploy | Automática via Lambda rotation function |
| Auditoria de acesso | Nenhuma | CloudTrail registra cada GetSecretValue |
| Superfície de exposição | Código-fonte, logs, variáveis de processo | Apenas em memória, no momento do uso |
| Controle de acesso | Quem tem acesso ao repo tem a senha | IAM policy por role, por recurso |
| Vazamento em histórico git | Permanente mesmo após remoção | Sem credencial no repositório |
| Custo operacional | Zero direto, alto em incidentes | Pricing por segredo/mês — verificar documentação oficial |
Como o Secrets Manager funciona — antes de agir, entenda o mecanismo
O Secrets Manager armazena segredos como pares chave-valor em JSON, criptografados com uma chave KMS. Quando a aplicação chama GetSecretValue, o serviço descriptografa o valor em memória e retorna via HTTPS. A credencial nunca trafega em texto plano na rede AWS.
A rotação automática funciona por meio de uma Lambda function que o próprio Secrets Manager invoca em um agendamento configurável. Essa função executa quatro etapas distintas — createSecret, setSecret, testSecret, finishSecret — e o serviço orquestra essas etapas. Para bancos de dados RDS, AWS fornece funções de rotação prontas. Para outros sistemas, você implementa a função seguindo o contrato documentado.
- Aplicação chama GetSecretValue — a chamada é autenticada via IAM role da instância/task, sem credencial estática.
- Secrets Manager descriptografa via KMS — a chave KMS nunca sai do serviço; apenas o valor descriptografado é retornado.
- Rotação agendada dispara a Lambda — o Secrets Manager invoca a função com o token de rotação e aguarda cada etapa.
- Nova versão do segredo é promovida — a versão anterior recebe o label
AWSPREVIOUS; a nova recebeAWSCURRENT. Aplicações que buscamAWSCURRENTrecebem a nova credencial automaticamente.
Por que 'repositório privado' não é argumento de segurança
Esse é o ponto onde a maioria dos times se engana. A premissa 'o repo é privado' colapsa em pelo menos cinco cenários reais:
- Histórico git é permanente. Um
git logougit showexpõe commits antigos mesmo depois de remover o arquivo. Ferramentas comotruffleHoge o próprio GitHub secret scanning varrem o histórico completo. - Acesso ao repo ≠ acesso controlado ao banco. Qualquer desenvolvedor com clone local tem a senha de produção. Não há granularidade.
- Logs de aplicação frequentemente imprimem variáveis de ambiente. Frameworks de diagnóstico, dumps de contexto em exceções, e configurações de debug fazem isso silenciosamente.
- Tokens de CI/CD têm escopo amplo. Um pipeline comprometido que tem acesso ao repositório tem acesso à credencial.
- Rotação é operacionalmente impossível sem downtime. Trocar a senha exige atualizar o código ou a variável de ambiente e fazer redeploy — o que significa que a rotação raramente acontece na prática.
Repositório privado é controle de acesso ao código. Não é controle de acesso à credencial. São camadas diferentes com superfícies de ataque diferentes.
Criando e acessando um segredo — passo a passo operacional
Passo 1 — Criar o segredo no Secrets Manager
Antes de qualquer coisa, o segredo precisa existir. O comando abaixo cria um segredo com as credenciais do banco em formato JSON, que é o formato esperado pelas funções de rotação nativas do RDS.
aws secretsmanager create-secret \
--name prod/myapp/db-credentials \
--description 'Credenciais do banco de dados de producao' \
--secret-string '{"username":"appuser","password":"SenhaInicialForte123!"}' \
--region us-east-1
O nome do segredo funciona como um path lógico. Usar prefixos como prod/, staging/ facilita o controle de acesso via IAM condition keys — você pode restringir roles de produção apenas a segredos com o prefixo prod/.
Passo 2 — Configurar a IAM policy para a aplicação
A aplicação precisa de permissão explícita para ler o segredo. O princípio do menor privilégio aqui significa: acesso apenas ao segredo específico, apenas para leitura, apenas para a role que executa a aplicação. Nenhuma permissão de escrita ou listagem é necessária para o caso de uso de leitura.
🔽 Clique para expandir — IAM Policy para leitura do segredo
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "LerSegredoBancoDados",
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret"
],
"Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/myapp/db-credentials-*"
},
{
"Sid": "DescriptografarViaKMS",
"Effect": "Allow",
"Action": [
"kms:Decrypt"
],
"Resource": "arn:aws:kms:us-east-1:123456789012:key/SUA-CHAVE-KMS-ID"
}
]
}
O sufixo -* no ARN do segredo é necessário porque o Secrets Manager acrescenta um sufixo aleatório de 6 caracteres ao nome do segredo no ARN real. Sem esse wildcard, a policy bloqueia o acesso mesmo com o nome correto.
Passo 3 — Verificar o segredo criado e sua versão atual
Confirme que o segredo existe e que a versão AWSCURRENT está disponível antes de configurar a rotação. Esse passo evita depurar a rotação quando o problema é simplesmente que o segredo não foi criado corretamente.
aws secretsmanager describe-secret \
--secret-id prod/myapp/db-credentials \
--region us-east-1
aws secretsmanager get-secret-value \
--secret-id prod/myapp/db-credentials \
--version-stage AWSCURRENT \
--region us-east-1
Passo 4 — Configurar rotação automática para RDS
Para instâncias RDS, o Secrets Manager oferece funções de rotação gerenciadas pela AWS. Você referencia o ARN da função Lambda de rotação correspondente ao seu engine de banco de dados — os ARNs dessas funções estão documentados na página oficial do Secrets Manager para rotação de RDS. O comando abaixo habilita rotação a cada 30 dias:
aws secretsmanager rotate-secret \
--secret-id prod/myapp/db-credentials \
--rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:SecretsManagerRDSMySQLRotationSingleUser \
--rotation-rules AutomaticallyAfterDays=30 \
--region us-east-1
O parâmetro --rotation-lambda-arn deve apontar para a função de rotação correta para o seu engine. Consulte a documentação oficial para obter o ARN exato da função gerenciada pela AWS para o seu caso — os ARNs variam por região e por tipo de banco de dados.
- createSecret — a função cria uma nova versão do segredo com label
AWSPENDING, gerando uma nova senha. - setSecret — a função aplica a nova senha no banco de dados RDS.
- testSecret — a função testa a conexão com a nova credencial para confirmar que funciona.
- finishSecret — o Secrets Manager promove
AWSPENDINGparaAWSCURRENTe rebaixa a versão anterior paraAWSPREVIOUS.
Passo 5 — Verificar o histórico de rotação e auditoria via CloudTrail
Após a rotação, confirme que a nova versão foi promovida. O CloudTrail registra cada chamada GetSecretValue com o ARN do principal que fez a chamada — isso é o que torna o Secrets Manager auditável de forma que variáveis de ambiente nunca serão.
aws secretsmanager list-secret-version-ids \
--secret-id prod/myapp/db-credentials \
--region us-east-1
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=GetSecretValue \
--region us-east-1
O erro que todo time comete na primeira rotação — experiência de campo
O sintoma: a rotação executa com sucesso (o console mostra 'Last rotated' com timestamp recente), mas a aplicação começa a retornar erros de autenticação no banco de dados minutos depois.
O diagnóstico errado: time assume que a rotação falhou e reverte manualmente a senha no RDS, quebrando o segredo no Secrets Manager.
A causa real: a aplicação estava fazendo cache da conexão com o banco e não estava relendo o segredo após a rotação. O pool de conexões mantinha as conexões abertas com a senha antiga. Quando o RDS invalidou a senha antiga, as conexões existentes começaram a falhar — mas a aplicação não tentava buscar o novo segredo porque não havia lógica de retry com releitura do Secrets Manager.
O fix correto tem duas partes: implementar lógica de retry na aplicação que, ao receber erro de autenticação, chama GetSecretValue novamente antes de desistir; e configurar o pool de conexões para validar conexões antes de reutilizá-las. A rotação do Secrets Manager funciona corretamente — o problema estava na camada de aplicação que assumia que a credencial era estática.
Rotação automática de senha só funciona de ponta a ponta se a aplicação foi projetada para tratar credenciais como temporárias — não como constantes.
Integração com aplicações — padrão recomendado em Java e Python
A aplicação nunca deve armazenar o valor do segredo em uma variável de longa duração. O padrão correto é buscar o segredo no momento da inicialização da conexão e implementar retry com releitura em caso de falha de autenticação.
🔽 Clique para expandir — Exemplo Python com boto3
import boto3
import json
from botocore.exceptions import ClientError
def get_db_credentials(secret_name: str, region_name: str) -> dict:
client = boto3.client('secretsmanager', region_name=region_name)
try:
response = client.get_secret_value(SecretId=secret_name)
except ClientError as e:
raise e
secret = json.loads(response['SecretString'])
return secret
# Uso:
credentials = get_db_credentials('prod/myapp/db-credentials', 'us-east-1')
username = credentials['username']
password = credentials['password']
Em produção, adicione lógica de retry: se a conexão com o banco falhar com erro de autenticação, chame get_db_credentials novamente antes de propagar o erro. Isso garante que a aplicação se recupera automaticamente após uma rotação sem necessidade de redeploy.
Secrets Manager vs. Parameter Store — quando usar cada um
Essa dúvida aparece sempre. A distinção prática: use o Secrets Manager quando a rotação automática é necessária ou quando o dado é uma credencial de acesso a sistema externo. Use o SSM Parameter Store (com SecureString) para configurações sensíveis que não rotacionam — como feature flags criptografadas, ARNs de recursos, ou configurações de ambiente.
O Secrets Manager tem custo por segredo armazenado e por chamada de API acima do free tier. Para configurações que são lidas milhares de vezes por segundo e não precisam de rotação, o Parameter Store é mais econômico. Sempre verifique a tabela de preços atual na documentação oficial antes de decidir a arquitetura.
Por que adotar o Secrets Manager é a decisão certa para produção
Hardcoding de credenciais não é um atalho técnico — é uma dívida de segurança com juros compostos. Cada desenvolvedor que entra no time recebe acesso implícito a credenciais de produção. Cada pipeline de CI/CD que clona o repositório carrega a credencial. Cada dump de variáveis de ambiente em um log de erro expõe o segredo.
O Secrets Manager resolve o problema na camada correta: a credencial existe apenas no serviço gerenciado, é acessada apenas por roles com permissão explícita, cada acesso é auditado, e a rotação acontece sem intervenção humana. O custo operacional de configurar corretamente na primeira vez é menor do que o custo de responder a um incidente de vazamento de credencial.
Para times que estão migrando de hardcoding para Secrets Manager, o caminho mais seguro é: criar o segredo, atualizar a aplicação para ler via SDK, validar em staging, e só então remover a credencial do código — nunca na ordem inversa.
Próximos passos e recursos
- Consulte a documentação oficial do AWS Secrets Manager para detalhes sobre funções de rotação por engine de banco de dados.
- Revise o guia de rotação automática para entender o contrato da Lambda function de rotação.
- Configure alertas no CloudWatch para a métrica de falhas de rotação — o Secrets Manager publica eventos no EventBridge quando uma rotação falha.
- Avalie o uso de VPC Endpoints para o Secrets Manager se suas aplicações rodam em subnets privadas sem NAT Gateway — isso elimina o tráfego de saída para a internet pública.
Glossário de termos-chave
| Termo | Definição operacional |
|---|---|
| Secret version | Cada valor armazenado no Secrets Manager recebe uma versão com labels como AWSCURRENT e AWSPREVIOUS. A rotação cria uma nova versão sem deletar a anterior imediatamente. |
| Rotation function | Lambda function que implementa o protocolo de rotação de quatro etapas do Secrets Manager. Para RDS, AWS fornece funções prontas; para outros sistemas, você implementa seguindo o contrato documentado. |
| KMS CMK | Customer Managed Key — chave KMS usada para criptografar o segredo. Se não especificada, o Secrets Manager usa a chave gerenciada pela AWS para o serviço. |
| AWSCURRENT / AWSPREVIOUS | Labels de versão do segredo. Aplicações que buscam sem especificar versão recebem AWSCURRENT. AWSPREVIOUS permite rollback manual se necessário. |
| Resource-based policy | Policy anexada diretamente ao segredo (não à role) que controla quais principals podem acessá-lo. Útil para acesso cross-account. |
Comentários
Postar um comentário