AWS Admin

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

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

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 .env 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.

Arquitetura básica

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.

Implementação Prática: Armazenando e Recuperando Segredos

Criando um segredo com Boto3

import boto3
import json

# Cliente do Secrets Manager
client = boto3.client('secretsmanager', region_name='us-east-1')

# Criar um novo segredo
secret_data = {
    'username': 'admin_user',
    'password': 'SuperSecurePassword123!',
    'host': 'db.example.com'
}

response = client.create_secret(
    Name='prod/database/credentials',
    Description='Credenciais do banco de dados PostgreSQL',
    SecretString=json.dumps(secret_data),
    KmsKeyId='arn:aws:kms:us-east-1:123456789:key/12345678-1234-1234-1234-123456789012'
)

print(f"Segredo criado: {response['ARN']}")

Recuperando o segredo na aplicação

import boto3
import json
from functools import lru_cache

class SecretsManager:
    def __init__(self):
        self.client = boto3.client('secretsmanager', region_name='us-east-1')
        self._cache = {}

    @lru_cache(maxsize=10)
    def get_secret(self, secret_name):
        """Recupera e cacheia o segredo por 1 hora em produção"""
        try:
            response = self.client.get_secret_value(SecretId=secret_name)

            if 'SecretString' in response:
                return json.loads(response['SecretString'])
            else:
                return response['SecretBinary']

        except self.client.exceptions.ResourceNotFoundException:
            raise ValueError(f"Segredo '{secret_name}' não encontrado")
        except Exception as e:
            raise RuntimeError(f"Erro ao recuperar segredo: {str(e)}")

# Uso na aplicação
secrets_manager = SecretsManager()
db_creds = secrets_manager.get_secret('prod/database/credentials')

# Conectar ao banco de dados com as credenciais
db_connection = psycopg2.connect(
    host=db_creds['host'],
    user=db_creds['username'],
    password=db_creds['password'],
    database='production'
)

Rotação automática de senhas

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:

import boto3
import pymysql
import json

secrets_client = boto3.client('secretsmanager')

def lambda_handler(event, context):
    secret_id = event['SecretId']
    token = event['ClientRequestToken']
    step = event['Step']

    # Recuperar o segredo atual
    secret_response = secrets_client.get_secret_value(SecretId=secret_id)
    current_secret = json.loads(secret_response['SecretString'])

    if step == 'createSecret':
        # Gerar nova senha
        new_password = secrets_client.get_random_password(
            PasswordLength=32,
            ExcludeCharacters='/@"\'\\;'
        )['RandomPassword']

        # Armazenar nova versão pendente
        secrets_client.put_secret_value(
            SecretId=secret_id,
            ClientRequestToken=token,
            SecretString=json.dumps({
                **current_secret,
                'password': new_password
            }),
            VersionStages=['AWSPENDING']
        )

    elif step == 'setSecret':
        # Aplicar nova senha no banco de dados
        connection = pymysql.connect(
            host=current_secret['host'],
            user=current_secret['username'],
            password=current_secret['password'],
            database='mysql'
        )
        cursor = connection.cursor()
        new_creds = json.loads(
            secrets_client.get_secret_value(
                SecretId=secret_id,
                VersionId=token,
                VersionStage='AWSPENDING'
            )['SecretString']
        )
        cursor.execute(
            f"ALTER USER '{new_creds['username']}'@'%' IDENTIFIED BY '{new_creds['password']}'"
        )
        connection.commit()
        cursor.close()
        connection.close()

    elif step == 'finishSecret':
        # Marcar versão como AWSCURRENT
        secrets_client.update_secret_version_stage(
            SecretId=secret_id,
            VersionStage='AWSCURRENT',
            MoveToVersionId=token,
            RemoveFromVersionId=secret_response['VersionId']
        )

    return {'statusCode': 200}

KMS: Controle Fino de Criptografia

Políticas de chave para acesso mínimo

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:

{
  "Sid": "AllowEC2ToDecryptDatabaseSecrets",
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::123456789012:role/EC2-ApplicationRole"
  },
  "Action": [
    "kms:Decrypt",
    "kms:DescribeKey"
  ],
  "Resource": "*",
  "Condition": {
    "StringEquals": {
      "kms:ViaService": "secretsmanager.us-east-1.amazonaws.com"
    }
  }
}

Auditoria com CloudTrail

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

import boto3

cloudwatch = boto3.client('cloudwatch')

cloudwatch.put_metric_alarm(
    AlarmName='UnusualKMSDecryptions',
    MetricName='UserErrorCount',
    Namespace='AWS/KMS',
    Statistic='Sum',
    Period=300,
    EvaluationPeriods=1,
    Threshold=10,
    ComparisonOperator='GreaterThanThreshold',
    AlarmActions=['arn:aws:sns:us-east-1:123456789012:SecurityAlerts']
)

Conclusão

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

Referências


Artigos relacionados