Cloud & Infraestrutura

Dominando Secrets Manager e KMS: Gerenciamento de Segredos e Criptografia em Projetos Reais

7 min de leitura

Dominando Secrets Manager e KMS: Gerenciamento de Segredos e Criptografia em Projetos Reais

Introdução ao Secrets Manager e KMS na AWS Gerenciar segredos em aplicações modernas é uma tarefa crítica que frequentemente é negligenciada. Credenciais de banco de dados, chaves de API e tokens de autenticação comprometem toda a segurança da sua aplicação se vazados. O AWS Secrets Manager resolve esse problema fornecendo armazenamento centralizado e rotação automática de segredos, enquanto o KMS (Key Management Service) oferece criptografia de ponta a ponta. Neste artigo, aprenderemos como integrar essas duas ferramentas em projetos reais, eliminando a prática perigosa de armazenar credenciais em código ou arquivos de configuração. Fundamentos: Secrets Manager vs Variáveis de Ambiente Por que não usar variáveis de ambiente simples? A maioria dos desenvolvedores inicia armazenando credenciais em arquivos ou variáveis de ambiente. Isso funciona localmente, mas é um risco em produção: logs podem expor valores, repositórios Git podem conter histórico, e não há rotação automática. O Secrets Manager resolve isso oferecendo um vault seguro com auditoria integrada, rotação automática de senhas

<h2>Introdução ao Secrets Manager e KMS na AWS</h2>

<p>Gerenciar segredos em aplicações modernas é uma tarefa crítica que frequentemente é negligenciada. Credenciais de banco de dados, chaves de API e tokens de autenticação comprometem toda a segurança da sua aplicação se vazados. O AWS Secrets Manager resolve esse problema fornecendo armazenamento centralizado e rotação automática de segredos, enquanto o KMS (Key Management Service) oferece criptografia de ponta a ponta. Neste artigo, aprenderemos como integrar essas duas ferramentas em projetos reais, eliminando a prática perigosa de armazenar credenciais em código ou arquivos de configuração.</p>

<h2>Fundamentos: Secrets Manager vs Variáveis de Ambiente</h2>

<h3>Por que não usar variáveis de ambiente simples?</h3>

<p>A maioria dos desenvolvedores inicia armazenando credenciais em arquivos <code>.env</code> ou variáveis de ambiente. Isso funciona localmente, mas é um risco em produção: logs podem expor valores, repositórios Git podem conter histórico, e não há rotação automática. O Secrets Manager resolve isso oferecendo um vault seguro com auditoria integrada, rotação automática de senhas e integração nativa com serviços AWS.</p>

<h3>Arquitetura básica</h3>

<p>O KMS criptografa cada segredo armazenado no Secrets Manager usando chaves gerenciadas. Você define políticas de acesso granulares: apenas sua aplicação pode descriptografar o segredo específico que precisa. Essa separação entre o que está armazenado (Secrets Manager) e como é protegido (KMS) fornece defesa em profundidade.</p>

<h2>Implementação Prática: Armazenando e Recuperando Segredos</h2>

<h3>Criando um segredo com Boto3</h3>

<pre><code class="language-python">import boto3

import json

Cliente do Secrets Manager

client = boto3.client(&#039;secretsmanager&#039;, region_name=&#039;us-east-1&#039;)

Criar um novo segredo

secret_data = {

&#039;username&#039;: &#039;admin_user&#039;,

&#039;password&#039;: &#039;SuperSecurePassword123!&#039;,

&#039;host&#039;: &#039;db.example.com&#039;

}

response = client.create_secret(

Name=&#039;prod/database/credentials&#039;,

Description=&#039;Credenciais do banco de dados PostgreSQL&#039;,

SecretString=json.dumps(secret_data),

KmsKeyId=&#039;arn:aws:kms:us-east-1:123456789:key/12345678-1234-1234-1234-123456789012&#039;

)

print(f&quot;Segredo criado: {response[&#039;ARN&#039;]}&quot;)</code></pre>

<h3>Recuperando o segredo na aplicação</h3>

<pre><code class="language-python">import boto3

import json

from functools import lru_cache

class SecretsManager:

def __init__(self):

self.client = boto3.client(&#039;secretsmanager&#039;, region_name=&#039;us-east-1&#039;)

self._cache = {}

@lru_cache(maxsize=10)

def get_secret(self, secret_name):

&quot;&quot;&quot;Recupera e cacheia o segredo por 1 hora em produção&quot;&quot;&quot;

try:

response = self.client.get_secret_value(SecretId=secret_name)

if &#039;SecretString&#039; in response:

return json.loads(response[&#039;SecretString&#039;])

else:

return response[&#039;SecretBinary&#039;]

except self.client.exceptions.ResourceNotFoundException:

raise ValueError(f&quot;Segredo &#039;{secret_name}&#039; não encontrado&quot;)

except Exception as e:

raise RuntimeError(f&quot;Erro ao recuperar segredo: {str(e)}&quot;)

Uso na aplicação

secrets_manager = SecretsManager()

db_creds = secrets_manager.get_secret(&#039;prod/database/credentials&#039;)

Conectar ao banco de dados com as credenciais

db_connection = psycopg2.connect(

host=db_creds[&#039;host&#039;],

user=db_creds[&#039;username&#039;],

password=db_creds[&#039;password&#039;],

database=&#039;production&#039;

)</code></pre>

<h3>Rotação automática de senhas</h3>

<p>O Secrets Manager pode rotacionar automaticamente senhas do RDS sem intervenção manual. Configure uma função Lambda que altera a senha no banco de dados:</p>

<pre><code class="language-python">import boto3

import pymysql

import json

secrets_client = boto3.client(&#039;secretsmanager&#039;)

def lambda_handler(event, context):

secret_id = event[&#039;SecretId&#039;]

token = event[&#039;ClientRequestToken&#039;]

step = event[&#039;Step&#039;]

Recuperar o segredo atual

secret_response = secrets_client.get_secret_value(SecretId=secret_id)

current_secret = json.loads(secret_response[&#039;SecretString&#039;])

if step == &#039;createSecret&#039;:

Gerar nova senha

new_password = secrets_client.get_random_password(

PasswordLength=32,

ExcludeCharacters=&#039;/@&quot;\&#039;\\;&#039;

)[&#039;RandomPassword&#039;]

Armazenar nova versão pendente

secrets_client.put_secret_value(

SecretId=secret_id,

ClientRequestToken=token,

SecretString=json.dumps({

**current_secret,

&#039;password&#039;: new_password

}),

VersionStages=[&#039;AWSPENDING&#039;]

)

elif step == &#039;setSecret&#039;:

Aplicar nova senha no banco de dados

connection = pymysql.connect(

host=current_secret[&#039;host&#039;],

user=current_secret[&#039;username&#039;],

password=current_secret[&#039;password&#039;],

database=&#039;mysql&#039;

)

cursor = connection.cursor()

new_creds = json.loads(

secrets_client.get_secret_value(

SecretId=secret_id,

VersionId=token,

VersionStage=&#039;AWSPENDING&#039;

)[&#039;SecretString&#039;]

)

cursor.execute(

f&quot;ALTER USER &#039;{new_creds[&#039;username&#039;]}&#039;@&#039;%&#039; IDENTIFIED BY &#039;{new_creds[&#039;password&#039;]}&#039;&quot;

)

connection.commit()

cursor.close()

connection.close()

elif step == &#039;finishSecret&#039;:

Marcar versão como AWSCURRENT

secrets_client.update_secret_version_stage(

SecretId=secret_id,

VersionStage=&#039;AWSCURRENT&#039;,

MoveToVersionId=token,

RemoveFromVersionId=secret_response[&#039;VersionId&#039;]

)

return {&#039;statusCode&#039;: 200}</code></pre>

<h2>KMS: Controle Fino de Criptografia</h2>

<h3>Políticas de chave para acesso mínimo</h3>

<p>O KMS oferece criptografia gerenciada, mas o poder real está nas políticas. Uma aplicação EC2 só deve conseguir usar a chave KMS necessária, não todas:</p>

<pre><code class="language-json">{

&quot;Sid&quot;: &quot;AllowEC2ToDecryptDatabaseSecrets&quot;,

&quot;Effect&quot;: &quot;Allow&quot;,

&quot;Principal&quot;: {

&quot;AWS&quot;: &quot;arn:aws:iam::123456789012:role/EC2-ApplicationRole&quot;

},

&quot;Action&quot;: [

&quot;kms:Decrypt&quot;,

&quot;kms:DescribeKey&quot;

],

&quot;Resource&quot;: &quot;*&quot;,

&quot;Condition&quot;: {

&quot;StringEquals&quot;: {

&quot;kms:ViaService&quot;: &quot;secretsmanager.us-east-1.amazonaws.com&quot;

}

}

}</code></pre>

<h3>Auditoria com CloudTrail</h3>

<p>Todo acesso ao KMS é registrado no CloudTrail. Configure alertas para descriptografias anormais usando CloudWatch:</p>

<pre><code class="language-python">import boto3

cloudwatch = boto3.client(&#039;cloudwatch&#039;)

cloudwatch.put_metric_alarm(

AlarmName=&#039;UnusualKMSDecryptions&#039;,

MetricName=&#039;UserErrorCount&#039;,

Namespace=&#039;AWS/KMS&#039;,

Statistic=&#039;Sum&#039;,

Period=300,

EvaluationPeriods=1,

Threshold=10,

ComparisonOperator=&#039;GreaterThanThreshold&#039;,

AlarmActions=[&#039;arn:aws:sns:us-east-1:123456789012:SecurityAlerts&#039;]

)</code></pre>

<h2>Conclusão</h2>

<p>Aprendemos que <strong>Secrets Manager centraliza o armazenamento de credenciais com rotação automática</strong>, eliminando segredos em código. <strong>KMS fornece criptografia com controle granular</strong>, garantindo que apenas as aplicações certas acessem os segredos corretos. Por fim, <strong>auditoria através do CloudTrail transforma segurança reativa em proativa</strong>, detectando acessos anormais antes que se tornem incidentes. Implementar essa arquitetura desde o início economiza resgates de segurança no futuro.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://docs.aws.amazon.com/secretsmanager/" target="_blank" rel="noopener noreferrer">AWS Secrets Manager Documentation</a></li>

<li><a href="https://docs.aws.amazon.com/kms/latest/developerguide/best-practices.html" target="_blank" rel="noopener noreferrer">AWS KMS Best Practices</a></li>

<li><a href="https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html" target="_blank" rel="noopener noreferrer">Boto3 SecretsManager API Reference</a></li>

<li><a href="https://docs.aws.amazon.com/security/" target="_blank" rel="noopener noreferrer">AWS Security Best Practices Guide</a></li>

<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html" target="_blank" rel="noopener noreferrer">OWASP Secrets Management Cheat Sheet</a></li>

</ul>

Comentários

Mais em Cloud & Infraestrutura

Boas Práticas de CloudFormation em Profundidade: Templates, Stacks e StackSets para Times Ágeis
Boas Práticas de CloudFormation em Profundidade: Templates, Stacks e StackSets para Times Ágeis

Fundamentos de CloudFormation para Automação de Infraestrutura CloudFormation...

EKS em Profundidade: Managed Node Groups, Fargate e Add-ons: Do Básico ao Avançado
EKS em Profundidade: Managed Node Groups, Fargate e Add-ons: Do Básico ao Avançado

Fundamentos do EKS: Arquitetura e Componentes Amazon EKS (Elastic Kubernetes...

O que Todo Dev Deve Saber sobre Alta Disponibilidade e Disaster Recovery na AWS: RTO, RPO e Estratégias
O que Todo Dev Deve Saber sobre Alta Disponibilidade e Disaster Recovery na AWS: RTO, RPO e Estratégias

Entendendo RTO e RPO: Os Pilares da Resiliência Recovery Time Objective (RTO)...