Segredo no Docker não pertence ao ENV — monte o arquivo só onde ele é usado

|Autor: Equipe editorial da QUASA|7 min de leitura
Segredo no Docker não pertence ao ENV — monte o arquivo só onde ele é usado

No Docker Compose, guarde a senha ou o token em um arquivo fora da imagem, declare-o em secrets no nível superior do compose.yaml e conceda acesso apenas ao serviço consumidor. O Compose monta o conteúdo em /run/secrets dentro desse contêiner, como descreve a documentação de secrets do Docker Compose.

A aplicação deve ler o arquivo montado, em vez de receber o valor da credencial por uma variável de ambiente. Uma variável que contém somente o caminho do arquivo pode servir quando a imagem aceita essa convenção. Para concluir a migração, ainda é preciso retirar a credencial antiga da configuração e do build, recriar o consumidor quando houver rotação e verificar os lugares onde o valor poderia ter ficado registrado.

Descubra onde cada credencial já aparece

Comece por um inventário: anote cada senha ou token, o sistema que o emite, os serviços que o utilizam e quem pode revogá-lo. Procure valores no Dockerfile, em ENV e ARG, no compose.yaml, em arquivos .env, scripts de inicialização, configurações da aplicação e arquivos copiados para a imagem. Inclua também repositórios, registros de implantação e logs aos quais a credencial possa ter chegado.

A orientação da OWASP para gestão de segredos desaconselha fixar credenciais em ENV ou ARG: esses valores podem aparecer na definição do contêiner, em logs ou em dumps do sistema. Se uma senha já entrou em um commit ou em uma imagem publicada, removê-la do arquivo atual não a invalida. Trate a credencial como potencialmente exposta, identifique seus consumidores e programe sua substituição no sistema que a emitiu.

Separe as credenciais usadas pela aplicação em execução daquelas necessárias apenas para baixar dependências privadas durante o build. Essa distinção evita tentar resolver os dois casos com uma única variável: o serviço precisa de um secret montado ao iniciar; a etapa de construção precisa de acesso temporário, limitado à instrução que usa o valor.

Declare o secret e conceda acesso por serviço

Considere um exemplo hipotético com os serviços app e worker. Apenas app se conecta ao banco de dados. Crie ./secrets/db_password.txt no host com a credencial destinada a essa conexão; restrinja a leitura do arquivo às pessoas e processos que operam a implantação. Exclua o diretório do controle de versão e do contexto de build. São cuidados distintos: ignorar o arquivo no Git não impede, por si só, que um COPY o inclua na imagem.

No compose.yaml, a configuração mínima tem estas partes:

  • Em secrets, no nível superior, declare db_password e defina file: ./secrets/db_password.txt.
  • Em services.app, acrescente secrets: [db_password]. Dentro de app, o caminho padrão será /run/secrets/db_password.
  • Em services.worker, não conceda db_password. A declaração no nível superior, sozinha, não monta o arquivo nesse serviço.

Revise a concessão sempre que separar uma aplicação em novos serviços. Se app e worker precisarem consultar o mesmo sistema, avalie primeiro se podem usar credenciais diferentes, cada uma com as permissões necessárias à sua função. A montagem por serviço limita a distribuição do arquivo entre contêineres; ela não define as permissões que a senha concede no banco ou na API.

Faça a aplicação consumir o caminho, não o valor

Configure app para abrir /run/secrets/db_password na inicialização ou quando precisar autenticar. Algumas imagens reconhecem uma variável terminada em _FILE; nesse caso, DB_PASSWORD_FILE=/run/secrets/db_password informa o caminho, enquanto o conteúdo permanece no arquivo. Essa convenção depende da imagem. Em uma aplicação própria, implemente a leitura do arquivo e trate falhas de acesso sem imprimir a credencial.

Depois, remova DB_PASSWORD e qualquer outra entrada que ainda contenha a senha. Evite um script que leia o arquivo e exporte seu conteúdo como variável de ambiente: ele volta a expor o valor aos processos que recebem aquele ambiente. Verifique também argumentos de linha de comando, mensagens de erro e modo de depuração, pois uma montagem correta não impede que a própria aplicação registre o segredo.

O caminho /run/secrets pressupõe contêineres Linux. Dentro do serviço autorizado, processos com permissão de leitura ainda podem acessar o arquivo; mantenha o escopo do serviço e as permissões da credencial tão restritos quanto o funcionamento permitir. Proteja também o arquivo de origem no host, que continua fazendo parte da implantação local.

Retire segredos usados durante o build

Secret temporário usado em uma etapa RUN do Dockerfile sem permanecer na imagem final.

Uma senha necessária para instalar dependências privadas não deve entrar no Dockerfile por ARG, ENV ou COPY. A instrução do Docker para build secrets recomenda fornecer a credencial ao build e consumi-la temporariamente em RUN com --mount=type=secret. Esse acesso atende à construção da imagem; o secret concedido em services.app atende ao contêiner em execução. Um não concede automaticamente o outro.

Remova instruções antigas que criavam arquivos com senhas na imagem e use .dockerignore para impedir que o diretório local de secrets entre no contexto do build. Reconstrua a imagem após a mudança. Apagar um arquivo em uma instrução posterior não elimina necessariamente o conteúdo de uma camada anterior; por isso, examine também imagens antigas que foram armazenadas ou publicadas e revogue as credenciais que elas possam conter.

Troque a credencial e recrie o consumidor

Serviço do Docker Compose recriado com um novo arquivo de segredo antes da revogação da credencial antiga.

Planeje a rotação com o banco ou provedor da API. Crie uma nova credencial com o menor alcance necessário, grave-a em um novo arquivo protegido no host e atualize o campo file do secret no compose.yaml para apontar a esse arquivo. Recrie app para que a implantação passe a usar a nova origem; no exemplo, docker compose up -d --no-deps --force-recreate app força a recriação do consumidor sem iniciar suas dependências. Prepare a janela de troca de acordo com a disponibilidade exigida pelo serviço.

Quando o sistema emissor permitir credenciais simultâneas, autentique uma operação real com a nova antes de revogar a antiga. Se ele aceitar apenas uma senha ativa, coordene a alteração no servidor com a recriação do serviço e tenha um procedimento de recuperação. Substituir o arquivo ou reiniciar o contêiner não revoga um token: a invalidação precisa ocorrer no banco ou provedor que o aceita.

O Compose local entrega o arquivo aos serviços declarados, mas o ciclo de vida da credencial continua exigindo emissão, controle de acesso, auditoria e revogação. Em ambientes que precisam de rotação automática ou distribuição entre várias implantações, um gerenciador de segredos pode cuidar dessa origem; ainda será necessário definir como cada consumidor obtém o valor atualizado.

Confira a imagem, os serviços e os registros

Faça a verificação sem mostrar a senha na saída dos comandos. Examine a configuração e o histórico da imagem reconstruída em busca de variáveis e instruções antigas; se houve COPY ou criação de arquivos sensíveis durante o build, verifique também o conteúdo das camadas. Não encontrar o valor em docker image inspect ou docker image history, isoladamente, não demonstra que ele nunca entrou na imagem.

Em app, confirme que /run/secrets/db_password existe, pode ser lido pelo processo correto e permite uma autenticação real. Em worker, confirme a ausência dessa montagem. Inspecione as variáveis configuradas no contêiner e procure a credencial antiga nos logs e artefatos da implantação, usando verificações que retornem apenas presença ou ausência, sem repetir o valor encontrado.

Por último, confirme no sistema emissor que a credencial anterior foi revogada e já não autentica. Essa checagem encerra uma parte que a montagem não resolve: impedir que uma senha previamente exposta continue válida depois que a aplicação passou a usar o arquivo novo.

Leia também:

Compartilhar:

Assine nossa newsletter

Receba as últimas notícias sobre Web3, IA e cripto diretamente no seu e-mail.

0