stamatios
← Voltar ao feed
Segredos não pertencem a arquivos de configuração
Dev & Engenharia

Segredos não pertencem a arquivos de configuração

resumo de ~3 min

O problema

Aplicações não deveriam exigir senhas, API keys ou tokens em seus arquivos de configuração. Configuração descreve comportamento e pertence ao git, code review e máquinas de desenvolvedores. Segredos concedem autoridade e precisam de acesso restrito e rotação independente. Colocar ambos no mesmo arquivo acopla ciclos de vida e públicos diferentes.

Evidência no NixOS

Uma auditoria de todos os 445 módulos do NixOS que lidam com segredos reais (no commit 141f212 do nixpkgs) revelou a distribuição de onde o valor secreto acaba:

Destino Módulos Percentual
Mesclado em arquivo de config em runtime 110 25%
Inlined em config no /nix/store 42 9%
Variável de ambiente 161 36%
Arquivo dedicado aberto pela app 58 13%
Credenciais systemd 53 12%
Argumento de linha de comando 19 4%

O número relevante é 110: um quarto dos módulos recupera o segredo com segurança e depois o copia para dentro da configuração porque é a única interface que a aplicação aceita. Usam envsubst, replace-secret, jq, yq, sed ou código custom para montar um arquivo restrito no startup. O resultado pode ser seguro, mas cada módulo passa a possuir glue de segurança específico da aplicação.

O mesmo padrão aparece em outras plataformas como entrypoint scripts, templates Helm, init containers ou etapas de interpolação em CI.

O princípio

Aplicações devem aceitar segredos por um canal dedicado em runtime: password_file, token_file, credenciais systemd, variável de ambiente com escopo estreito ou um provider externo. A separação garante que o deployer não precise fabricar uma segunda versão da configuração contendo segredos.

O caso do Cachix

O Cachix historicamente armazenava auth token e signing keys em ~/.config/cachix/cachix.dhall, junto com nomes de cache e outra configuração. Não era possível compartilhar a configuração de cache sem também compartilhar credenciais.

O devenv 2.2 separa o token via SecretSpec: o projeto declara CACHIX_AUTH_TOKEN, o devenv resolve do provider configurado e o valor é passado ao Cachix sem entrar na configuração. Um PR aberto (Cachix #737) traz a mesma separação para o cliente via SDK Haskell do SecretSpec, resolvendo CACHIX_AUTH_TOKEN e CACHIX_SIGNING_KEY do provider escolhido pelo usuário.

SecretSpec

O SecretSpec resolve isso com um arquivo secretspec.toml que declara o que a aplicação precisa, sem armazenar valores. Providers decidem onde os valores vivem: keyring do sistema para desenvolvimento local, variáveis de ambiente para CI, 1Password/Vault/cloud secret manager para produção - sem mudar a declaração.

SDKs existem para Rust, Python, Go, Ruby, Node.js/TypeScript, Haskell, PHP e C#, compartilhando o mesmo resolver para comportamento consistente entre linguagens.

Recomendação

Se você mantém uma aplicação, pare de adicionar senhas e tokens em schemas de configuração comuns. Aceite referência a arquivo, credencial, variável de ambiente ou provider. Para NixOS, a issue #65 do SecretSpec rastreia uma integração oficial que eliminaria o glue de substituição por módulo.