Secrets Management - C-Suite
Visão Geral
Este documento descreve o sistema de gerenciamento de secrets centralizado para o ecossistema C-Suite. O objetivo é remover credenciais hardcoded do código e usar sistemas seguros de gerenciamento de secrets.
Módulo de Secrets Management
Localização
O módulo principal está em: common_secrets.py (raiz do projeto)
Características
- Múltiplos backends: AWS Secrets Manager, HashiCorp Vault, Docker Swarm secrets, arquivos, env vars
- Backend composto: Tenta múltiplos backends em ordem
- Fallback seguro: Sempre tem fallback para env vars
- Cache: Cache de secrets para reduzir chamadas
- Helpers específicos: Funções para secrets comuns (DB, API keys, JWT)
Backends Suportados
1. Variáveis de Ambiente (Padrão)
# Configuração via .env
DB_PASSWORD=senha_secreta
API_KEY=chave_api
JWT_SECRET_KEY=chave_jwt
Uso:
from common_secrets import get_secret
password = get_secret("DB_PASSWORD")
2. Docker Swarm Secrets
# Secrets são montados em /run/secrets/
# Criar secret:
echo "senha_secreta" | docker secret create db_password -
# Usar em stack:
services:
app:
secrets:
- db_password
Uso:
from common_secrets import get_secret
# Automaticamente detecta /run/secrets/
password = get_secret("db_password")
3. AWS Secrets Manager
# Configurar
export AWS_SECRETS_MANAGER_ENABLED=true
export AWS_REGION=us-east-1
# Criar secret no AWS:
aws secretsmanager create-secret \
--name csuite/db_password \
--secret-string "senha_secreta"
Uso:
from common_secrets import get_secret
password = get_secret("csuite/db_password")
4. HashiCorp Vault
# Configurar
export VAULT_ENABLED=true
export VAULT_ADDR=http://vault:8200
export VAULT_TOKEN=token_aqui
Uso:
from common_secrets import get_secret
# Formato: secret/path:key ou secret/path
password = get_secret("secret/csuite:db_password")
5. Arquivos Locais
# Criar arquivo com secret
echo "senha_secreta" > /path/to/secrets/db_password
chmod 600 /path/to/secrets/db_password
# Configurar
export SECRETS_DIR=/path/to/secrets
Uso Básico
1. Obter Secret Genérico
from common_secrets import get_secret
# Obtém secret (tenta múltiplos backends)
api_key = get_secret("API_KEY")
db_password = get_secret("DB_PASSWORD", default="fallback_password")
2. Obter Senha de Banco de Dados
from common_secrets import get_db_password
# Tenta múltiplas fontes automaticamente:
# 1. Secret (Docker Swarm, AWS, Vault)
# 2. Variável de ambiente DB_PASSWORD
# 3. Arquivo DB_PASSWORD_FILE
password = get_db_password()
3. Obter API Key
from common_secrets import get_api_key
# Gera chave automaticamente: OPENAI_API_KEY
openai_key = get_api_key("openai")
# Ou especifica chave customizada
aws_key = get_api_key("aws", "AWS_ACCESS_KEY_ID")
4. Obter JWT Secret
from common_secrets import get_jwt_secret
# Obtém JWT secret de forma segura
jwt_secret = get_jwt_secret()
5. Obter Múltiplos Secrets
from common_secrets import get_secrets
# Obtém todos os secrets com prefixo
db_secrets = get_secrets("DB_")
# Retorna: {"DB_PASSWORD": "...", "DB_USER": "...", "DB_HOST": "..."}
Configuração
Variáveis de Ambiente
# Backend a usar (composite, aws, vault, file, env)
SECRETS_BACKEND=composite
# AWS Secrets Manager
AWS_SECRETS_MANAGER_ENABLED=false
AWS_REGION=us-east-1
# HashiCorp Vault
VAULT_ENABLED=false
VAULT_ADDR=http://localhost:8200
VAULT_TOKEN=
# Docker Swarm / Arquivos
SECRETS_DIR=/run/secrets # Padrão para Docker Swarm
Backend Composto (Padrão)
O backend composto tenta múltiplos backends em ordem:
- Docker Swarm secrets (
/run/secrets) - se existir - Variáveis de ambiente - sempre disponível como fallback
Migração de Código Existente
Antes (Hardcoded)
# ❌ NÃO FAZER ISSO!
DB_PASSWORD = "senha_hardcoded"
API_KEY = "chave_hardcoded"
Depois (Secrets Management)
from common_secrets import get_db_password, get_api_key
# ✅ SEGURO
DB_PASSWORD = get_db_password()
API_KEY = get_api_key("service_name")
Exemplo Completo
# Antes
import os
DB_PASSWORD = os.getenv("DB_PASSWORD", "mfCl1bXKTxezO5lK") # ❌ Hardcoded!
# Depois
from common_secrets import get_db_password
DB_PASSWORD = get_db_password() # ✅ Seguro
Integração com Apps
core_config.py
from common_secrets import get_db_password, get_secret
class CSuiteConfig:
@classmethod
def from_env(cls):
return cls(
db_password=get_db_password("CSUITE_DB_PASSWORD"),
jwt_secret=get_secret("JWT_SECRET_KEY"),
openai_api_key=get_secret("OPENAI_API_KEY")
)
csuite-executive
from common_secrets import get_db_password, get_api_key
class Settings:
CSUITE_DB_PASSWORD = get_db_password("CSUITE_DB_PASSWORD")
OPENAI_API_KEY = get_api_key("openai")
LLM_OPENAI_API_KEY = get_api_key("openai", "LLM_OPENAI_API_KEY")
4c Decision API
from common_secrets import get_secret
# Substituir hardcoded values
LLM_OPENAI_API_KEY = get_secret("LLM_OPENAI_API_KEY")
Docker Swarm Secrets
Criar Secrets
# Criar secret
echo "senha_secreta" | docker secret create db_password -
# Criar secret de arquivo
docker secret create db_password_file /path/to/password.txt
Usar em docker-stack.yml
version: '3.8'
services:
app:
image: csuite-app:latest
secrets:
- db_password
- jwt_secret
environment:
- DB_PASSWORD_FILE=/run/secrets/db_password
- JWT_SECRET_FILE=/run/secrets/jwt_secret
secrets:
db_password:
external: true
jwt_secret:
external: true
Acessar no Código
from common_secrets import get_secret
# Automaticamente detecta /run/secrets/
password = get_secret("db_password")
AWS Secrets Manager
Setup
# Instalar boto3
pip install boto3
# Configurar credenciais AWS
aws configure
# Criar secret
aws secretsmanager create-secret \
--name csuite/database \
--secret-string '{"password":"senha","user":"core","host":"localhost"}'
Usar
from common_secrets import get_secret
# Obtém secret completo (JSON)
db_config = get_secret("csuite/database")
# Retorna: {"password":"senha","user":"core","host":"localhost"}
# Ou obtém campo específico se backend suporta
password = get_secret("csuite/database:password")
HashiCorp Vault
Setup
# Instalar hvac
pip install hvac
# Configurar
export VAULT_ADDR=http://vault:8200
export VAULT_TOKEN=token_aqui
Usar
from common_secrets import get_secret
# Formato: secret/path:key
password = get_secret("secret/csuite:db_password")
# Ou apenas path (retorna primeiro valor)
password = get_secret("secret/csuite/database")
Boas Práticas
- Nunca hardcode secrets: Sempre use
common_secrets - Use Docker Swarm em produção: Secrets montados em
/run/secrets - Use AWS Secrets Manager: Para ambientes AWS
- Use Vault: Para ambientes on-premise ou híbridos
- Rotacione secrets: Mude secrets regularmente
- Não logue secrets: Use data masking antes de logar
- Valide secrets: Verifique se secrets estão configurados na inicialização
Segurança
Checklist
- ✅ Nenhum secret hardcoded no código
- ✅ Secrets não commitados no Git
- ✅
.envno.gitignore - ✅ Secrets rotacionados regularmente
- ✅ Acesso a secrets auditado
- ✅ Secrets não logados
Remover Secrets Hardcoded
# Buscar secrets hardcoded
grep -r "password.*=" --include="*.py" .
grep -r "PASSWORD.*=" --include="*.py" .
grep -r "secret.*=" --include="*.py" .
grep -r "api_key.*=" --include="*.py" .
# Substituir por common_secrets
Troubleshooting
Secret não encontrado
- Verifique variável de ambiente
- Verifique se arquivo existe (
/run/secrets/) - Verifique credenciais AWS/Vault
- Verifique logs para erros
Backend não funciona
- Verifique dependências (boto3, hvac)
- Verifique credenciais/configuração
- Verifique conectividade (AWS, Vault)
- Use fallback para env vars
Próximos Passos
- ✅ Módulo de secrets management criado
- ⏳ Migrar código existente para usar
common_secrets - ⏳ Remover todos os secrets hardcoded
- ⏳ Configurar Docker Swarm secrets em produção
- ⏳ Configurar AWS Secrets Manager (se aplicável)
- ⏳ Documentar secrets necessários por app