Gerenciamento de segredos
Como guardar senhas, tokens e chaves fora do spec do job, com criptografia em repouso e rotação versionada.
Senha de banco, chave de API, token OAuth, credencial de provedor. Tudo isso é segredo e nada disso pode estar no spec do job.
Por dois motivos. Primeiro, specs costumam ser versionados em algum repositório. Qualquer pessoa com acesso de leitura ao repositório passa a ter acesso ao segredo. Segundo, specs trafegam em logs, em terminais compartilhados, em screenshots de revisão. Cada um desses pontos é um vazamento esperando para acontecer.
O HeroCtl traz um cofre de segredos integrado. Você não monta nada por fora.
Criando um segredo
Pela CLI, três formas:
# valor literal direto na linha de comando
heroctl secret create db_password --from-literal="s3nh4-l0nga-e-aleatoria"
# de um arquivo
heroctl secret create tls_key --from-file=./privkey.pem
# stdin (não fica no histórico do shell)
echo -n "valor-secreto" | heroctl secret create api_token --from-stdin
Pelo painel web, há um formulário equivalente.
Listando e inspecionando
# lista todos os segredos visíveis pelo seu token
heroctl secret list
# mostra metadados (versão, autor, data de criação) — nunca o valor
heroctl secret describe db_password
# mostra o valor (exige permissão explícita)
heroctl secret get db_password
heroctl secret get é a operação mais sensível do sistema. Ela aparece no log de auditoria com nome de quem leu, quando, e de qual IP.
Atenção: Em produção, restrinja
secret:readao mínimo de papéis. Para a maioria dos times, ninguém precisa ler valores manualmente — o cluster injeta direto no job.
Criptografia em repouso
Cada segredo é criptografado com AES-256 antes de ser persistido. A chave de criptografia do cluster fica protegida e nunca é armazenada junto com os dados criptografados.
Operacionalmente isso significa que um backup do estado do cluster, sem a chave, é inútil para um atacante. Você pode subir um snapshot em disco rígido externo sem se preocupar.
A chave em si é gerada na inicialização do cluster e fica em arquivo protegido por permissão de filesystem (0600, owner root) em cada nó servidor. Para rotacionar:
heroctl cluster rekey
Esse comando re-criptografa todos os segredos com uma chave nova e invalida a antiga. Faça em janela de manutenção — a operação pode demorar minutos em clusters com milhares de segredos.
Injetando no job
A injeção é feita no momento em que a alocação inicia. O valor descriptografado existe apenas na memória do processo, nunca em disco.
job: api-pagamentos
env:
DATABASE_URL: ${secret.database_url}
STRIPE_KEY: ${secret.stripe_secret}
REDIS_PASSWORD: ${secret.redis_password}
O processo dentro do contêiner enxerga as variáveis como qualquer outra. Nenhuma alteração no código da aplicação.
Para injetar como arquivo (útil para chaves TLS, certificados, JSON de service account):
job: webhook-handler
files:
- path: /etc/app/credentials.json
content: ${secret.gcp_service_account}
mode: "0400"
O arquivo é criado em tmpfs (não toca disco), com a permissão indicada, antes do processo principal subir.
Versionamento e rotação
Toda atualização de um segredo cria uma versão nova. A versão antiga fica disponível por uma janela de tempo configurável (default 7 dias) para casos de rollback.
# atualiza, mantendo histórico
heroctl secret update db_password --from-literal="senha-nova"
# lista versões
heroctl secret history db_password
# faz rollback para versão anterior
heroctl secret rollback db_password --to-version 3
Por padrão, jobs em execução continuam usando a versão que estava ativa quando subiram. Para forçar releitura, redeploye o job:
heroctl job redeploy api-pagamentos
Para um job que precisa sempre da versão mais recente sem redeploy, declare:
env:
DATABASE_URL: ${secret.database_url:latest}
Nesse modo, o cluster reinicia a alocação automaticamente quando o segredo muda.
Permissões por papel (Business+)
No plano Business, você ganha controle granular sobre quem pode fazer o quê com qual segredo. O modelo trabalha com escopos hierárquicos:
policy "deploy-prod-secrets":
secret:
path: "prod/*"
capabilities: ["read", "list"]
secret:
path: "prod/admin/*"
capabilities: [] # nem listar
Atribua a política a um token ou a um papel e pronto. Ver o documento de RBAC para o modelo completo.
Auditoria (Business+)
Todo acesso é registrado:
heroctl audit secret --name db_password --since 30d
Saída tabular com timestamp, usuário, ação (read, update, delete), origem (IP), e resultado. Exporte para análise externa:
heroctl audit secret --since 30d --format json > audit.jsonl
Configure alertas para padrões anômalos: leitura fora de horário comercial, mesmo segredo lido por usuários diferentes em janela curta, falhas de permissão repetidas.
Backup criptografado
Backups dos segredos saem cifrados, prontos para mandar para storage S3-compatível:
# config do cluster
backup:
secrets:
enabled: true
schedule: "0 3 * * *" # 3h da manhã todo dia
destination:
type: s3
bucket: heroctl-backups
region: us-east-1
prefix: secrets/
credentials: ${secret.backup_s3_creds}
retention_days: 90
O snapshot é cifrado com a chave do cluster antes de ser enviado. O bucket pode estar acessível para outros propósitos sem risco — quem tiver acesso de leitura não consegue descriptografar nada.
Para restaurar em um cluster novo, você precisa do snapshot e da chave do cluster original. Guarde a chave separada do storage de backup.
Cofres externos
Para times com requisitos de conformidade que exigem uso de cofre corporativo já existente, há integração opcional:
secret_backend:
type: aws_kms
region: us-east-1
key_id: alias/heroctl-prod
Suportado de fábrica: AWS KMS, GCP KMS, HashiCorp Vault. Nesse modo, o HeroCtl delega operações de criptografia ao cofre externo. Os segredos continuam acessíveis pela mesma sintaxe ${secret.nome}.
Use isso se você já tem o cofre operando e auditado. Para a maioria dos times, o backend nativo é suficiente e mais simples.
Boas práticas
Em ordem de importância:
- Sem hardcode em spec. Nem em commit, nem temporariamente, nem "só para teste". O hábito vaza.
- Separação dev / staging / prod. Use prefixos no nome (
dev/db_password,prod/db_password) ou clusters separados. Nunca compartilhe credencial de produção com ambiente de desenvolvimento. - Rotação periódica. Mínimo a cada 90 dias para credenciais de banco e provedores. Mais frequente para tokens de API que vazam fácil.
- Least privilege na leitura. Quase ninguém precisa de
secret:read. A injeção automática no job não exige que a pessoa que fez deploy tenha acesso ao valor. - Revisão de auditoria mensal. Olhe quem leu o quê. Anomalias aparecem se você procura.
- Não loga segredo. Configure a aplicação para mascarar variáveis sensíveis em logs. O cluster cifra em repouso, mas se sua aplicação imprime
print(os.environ)no startup, acabou.
Próximos passos
- Configurar RBAC e tokens para limitar quem acessa o quê.
- Revisar métricas e logs para detectar uso anômalo.