# Senha em variável de ambiente: troque pelo AWS Secrets Manager

> Por que a senha do RDS em variável de ambiente é um risco e como ler a credencial do AWS Secrets Manager com IAM role, shell script e Node.js.

- Autor: Henrylle Maia, consultor AWS
- Publicado em: 2026-10-14
- Assuntos: Segurança, Banco de dados
- URL: https://pages.formacaoaws.com.br/blog/senha-em-variavel-de-ambiente-secrets-manager/
- Aula de origem: "Você ainda coloca senha em variáveis de ambiente (mesmo criptografada)? Pare e veja esse vídeo" (https://www.youtube.com/watch?v=nthC53OTpf0)

Senha do Amazon RDS guardada em variável de ambiente é difícil de trocar quando está espalhada em várias aplicações e, se vazar, abre caminho até o seu banco. Aqui ela passa a morar no AWS Secrets Manager: a aplicação busca usuário e senha na hora de conectar, liberada por uma permissão IAM, e mostro o caminho com shell script e com Node.js.

## Por que a senha não deveria ficar na variável de ambiente

Pense num cenário comum: uma aplicação na EC2, uma parte dela em Lambda, e as duas conectando num banco no RDS. A senha está numa variável de ambiente chamada `DBPWD`, a mesma desde que o RDS foi lançado.

Agora responda:

- **Se precisar mudar essa senha**, você tem só essas duas pontas para alterar? E se ela estiver espalhada em várias aplicações, com diversas variáveis de ambiente, como troca de forma unificada?
- **Se tiver um requisito de trocar a senha de tempos em tempos**, como faz isso hoje?
- **Se essa informação vazar**, há quanto tempo você não troca a senha do RDS?

A resposta costuma ser "configurei o security group certinho: só essa EC2 e essa Lambda acessam o banco". Mas e se existir outra máquina com acesso liberado por aquele security group e você não souber?

Se as variáveis de ambiente vazaram e alguém entra por essa máquina, ele chega no banco. Pode danificar o banco, destruir recursos ou roubar os seus dados. Senha ou API key em variável de ambiente é algo muito sensível.

## O que o Secrets Manager resolve

O Secrets Manager é gerenciado pela AWS e integrado com os principais serviços. Com o RDS, a integração é direta: ao lançar o banco, você diz que quer o usuário e a senha gerenciados pelo Secrets Manager. A senha gerada vai para um segredo, dá para configurar a rotação automática, e o próprio serviço altera a senha no RDS. A aplicação recupera a credencial na hora, então ela não precisa mais morar em variável de ambiente.

O custo citado na aula era de 40 centavos de dólar por segredo por mês, com 30 dias para teste. É o valor de fevereiro de 2024: confira na página de preços oficial da AWS antes de estimar.

**Fluxo:** Amazon EC2 (aplicação sem senha guardada) → IAM role (permissão para ler o segredo) → AWS Secrets Manager (usuário e senha em JSON) → Amazon RDS (conexão com a senha recuperada)

## Passo 1: lançar o RDS com a senha no Secrets Manager

Para comparar os dois mundos, lancei dois bancos PostgreSQL 16.1, os dois em instância t3.micro do Free Tier com 20 GB:

- **db-sem-secrets:** deixei o RDS gerar a senha, do jeito tradicional.
- **db-com-secrets:** marquei a opção de gerenciar as credenciais do usuário master no AWS Secrets Manager e mantive a chave de criptografia padrão.

Os dois usam o mesmo security group, o `bia-db`, que só tem regra de entrada vinda do security group `bia-dev`, o da máquina de teste. O `bia-dev` não precisa de nenhuma regra de entrada.

Com os bancos criados, o segredo já estava no Secrets Manager, criado pelo RDS. Em "Secret value" aparecem o username e o password, guardados em formato JSON. E na tela de conexão do db-com-secrets, o RDS não expõe mais a senha: mostra só que ela é gerenciada no Secrets Manager.

![Detalhes de conexão do db-com-secrets: o usuário master é postgres e, no lugar da senha, aparece "Manage master credentials in AWS Secrets Manager" (endpoint tarjado)](https://pages.formacaoaws.com.br/blog/assets/posts/senha-em-variavel-de-ambiente-secrets-manager/rds-senha-no-secrets-manager.webp)

## Passo 2: subir a máquina de teste

Para testar a conexão, subi uma EC2 chamada `bia-dev`: Amazon Linux 2023, t3.micro, sem key pair. O acesso é por SSM, um modelo de conexão bem mais seguro do que SSH. Para isso a instância usa uma IAM role com a política `AmazonSSMManagedInstanceCore`. No user data, colei o script do projeto BIA que já entrega a máquina com Git, Docker e Node.

Entrei nela pelo CloudShell, que usa as mesmas permissões da minha conta, com o comando de start session do SSM que está num script de apoio do projeto BIA, trocando só o ID da instância.

A instância não tem nenhuma regra de entrada. Ela só tinha IP público porque eu não estava usando NAT Gateway e precisava de saída para a internet.

Dentro dela, clonei o projeto de exemplo, que tem um teste de conexão em shell e outro em Node.js, cada um com a versão sem e com Secrets Manager. Para os testes em shell, a máquina precisa do cliente do PostgreSQL: no Amazon Linux, instalei o PostgreSQL 15.

## Passo 3: ler o segredo no shell script

No banco sem secrets, o script de teste recebe host, banco, usuário e a senha copiada do console. Conectou na hora.

Na versão com Secrets Manager, o script muda numa parte só. Ele busca o segredo pelo nome, lê o `SecretString` e usa o `jq` para tirar dele o username e o password:

```bash
secret_string=$(aws secretsmanager get-secret-value --secret-id MEU_SEGREDO --version-stage AWSCURRENT --query SecretString --output text)
username=$(echo $secret_string | jq -r '.username')
password=$(echo $secret_string | jq -r '.password')
```

A primeira linha recupera o segredo em texto; as duas seguintes separam usuário e senha. Troque `MEU_SEGREDO` pelo nome do segredo que o RDS criou. `AWSCURRENT` é a versão mais recente, e nem precisaria vir escrita, porque já é o padrão. Host, porta e nome do banco continuam no script; usuário e senha saem dessas variáveis.

![No teste em shell, DB_USER e DB_PASSWORD recebem o username e o password tirados do segredo com jq; host, porta 5432 e banco postgres ficam no script](https://pages.formacaoaws.com.br/blog/assets/posts/senha-em-variavel-de-ambiente-secrets-manager/script-shell-secretstring.webp)

## Passo 4: dar à role permissão para ler o segredo

Rodei o script, e falhou: `AccessDeniedException` na chamada `GetSecretValue`. A máquina ainda estava sem permissão.

> **Importante:** com o segredo no Secrets Manager, quem acessa precisa de permissão IAM para recuperar o segredo. Mesmo conhecendo o nome do segredo, sem essa permissão a máquina não consegue ler.

Como a instância já trabalha com role, a role do SSM, adicionei a ela mais uma política, a de leitura e escrita no Secrets Manager (`SecretsManagerReadWrite`). Rodei de novo e conectou. Mandei imprimir o password recuperado, e era exatamente a senha do banco.

![Primeira execução com AccessDeniedException, a role ainda sem permissão; depois de anexar a política, o mesmo script conecta e lista 3 schemas (ID da instância tarjado)](https://pages.formacaoaws.com.br/blog/assets/posts/senha-em-variavel-de-ambiente-secrets-manager/acesso-negado-e-conexao.webp)

Repare no que mudou: a aplicação não trabalha mais com a senha. Hoje, provavelmente, o seu projeto lê variáveis de ambiente e a senha cai direto no código. Além de ficar exposta na variável, ela compromete a segurança por todos aqueles cenários do começo.

## Passo 5: ler o segredo em Node.js

Se a sua aplicação é em JavaScript, a adaptação também é simples. O exemplo usa a biblioteca `pg` para conectar no PostgreSQL. Na versão sem secrets, você define usuário, host, banco e senha na configuração, conecta e roda uma consulta para provar que funcionou.

Na versão com Secrets Manager, o código passa a usar o AWS SDK:

1. Define a região e o nome do segredo.
2. Instancia o cliente do Secrets Manager e recupera o segredo.
3. Faz o merge da configuração que você definiu (host e banco) com o que veio do segredo (username e password).
4. Passa essa configuração para o cliente do banco e conecta.

![O new Client recebe user e password do mergedConfig, que traz o segredo, e host e database do dbConfig local](https://pages.formacaoaws.com.br/blog/assets/posts/senha-em-variavel-de-ambiente-secrets-manager/node-merge-credenciais.webp)

Rodei o script e a conexão funcionou, com o username e o password vindos do segredo, sem nenhuma senha escrita no código ou no ambiente. O exemplo é em Node, mas a lógica vale para qualquer tecnologia: buscar o segredo com o SDK, juntar com a configuração de conexão e conectar.

## Passo 6: apagar o que cobra

Para não ter custo depois da prática, apague os dois bancos (sem snapshot final) e encerre a instância `bia-dev`.

## Checklist

- Abra as variáveis de ambiente dos seus projetos e veja se tem senha de banco ou API key guardada lá.
- Ao lançar o RDS, marque a opção de gerenciar as credenciais do master no AWS Secrets Manager.
- Confira no Secrets Manager que o segredo foi criado, com username e password em JSON.
- Dê à role da instância (ou da sua aplicação) permissão IAM para ler o segredo. Sem ela, o nome do segredo não serve para nada.
- Troque a leitura da variável de ambiente pela busca do segredo: `SecretString` com `jq` no shell, AWS SDK no Node.js.
- Avalie a rotação automática da senha, que o Secrets Manager faz integrado ao RDS.
- Confira o preço do Secrets Manager na página oficial antes de estimar o custo.

Com o segredo no Secrets Manager, a senha deixa de ficar espalhada em variável de ambiente e o acesso passa a depender de permissão IAM. Comece a fazer essa troca a partir de hoje.
