
Imagens confiáveis: secrets de build, digest e redução de privilégios
Objetivos desta aula
- Fornecer segredos temporários ao build sem incorporá-los à imagem
- Diferenciar tag móvel de referência por digest
- Aplicar restrições de execução de forma incremental
- Testar permissões e diretórios graváveis
- Definir um processo de atualização das bases
Confiança é um processo, não uma propriedade de imagens pequenas. Uma imagem de poucos megabytes pode conter código malicioso; confira origem da base, dependências e permissões. O identificador sha256 permite associar a execução ao conteúdo aprovado.
Tags são referências mutáveis: node:22-alpine pode apontar para uma base diferente amanhã. Registrar o digest evita mudanças silenciosas, mas também congela vulnerabilidades; a equipe precisa abrir atualizações regulares e executar testes novamente.
Segredos de build têm vida curta. Se uma dependência privada exige token, passe um arquivo por --secret e consuma-o em RUN --mount=type=secret. Diferentemente de ARG e ENV, o arquivo montado não é incluído automaticamente nas layers.
A montagem não impede vazamento deliberado: um comando ainda pode copiar o segredo para outro caminho ou imprimi-lo. Revise scripts de instalação e logs; o exemplo usa um .npmrc temporário, sem executar cat e sem copiá-lo ao estágio final.
Privilégios de execução são outra camada. Um processo com USER node continua sujeito às permissões de arquivos e às configurações do runtime. Combine usuário não-root com --cap-drop ALL e no-new-privileges quando o comportamento da aplicação permitir.
Filesystem somente leitura exige planejamento. A aplicação pode precisar escrever temporários em /tmp; forneça um tmpfs limitado em vez de liberar toda a raiz. Logs devem ir para saída padrão e dados persistentes para um volume ou serviço explícito.
Teste negativo também ensina: confirme que a API responde e que escrever em /app falha. Não remova proteções ao primeiro erro de permissão; localize a escrita, entenda sua necessidade e conceda acesso apenas ao caminho apropriado.
Atualização fecha o ciclo. Faça rebuild periódico com bases corrigidas, execute testes e scan, registre o novo digest e promova esse artefato. Um digest aprovado é rastreável; ele não representa uma promessa de segurança eterna.
Na prática
Dockerfile: dependências privadas com secret de BuildKit
dockerfile
# syntax=docker/dockerfile:1
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
# O arquivo existe apenas durante este RUN; não imprima seu conteúdo.
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc,required=true \
npm ci --omit=dev --ignore-scripts
FROM node:22-alpine AS runtime
WORKDIR /app
ENV NODE_ENV=production
COPY --from=deps --chown=node:node /app/node_modules ./node_modules
COPY --chown=node:node package.json ./
COPY --chown=node:node src ./src
USER node
# Pré-requisito: API JavaScript pronta, ouvindo em 0.0.0.0:3000.
CMD ["node", "src/server.js"]Construir e executar com restrições explícitas
bash
# Pré-requisito: .npmrc fora do repositório, com acesso mínimo ao registry.
# .dockerignore deve excluir .npmrc, .env*, .git e node_modules.
docker build --secret id=npmrc,src="$HOME/.npmrc" -t cloudshop-api:hardening .
# Temporários são voláteis; ajuste o limite à necessidade real da API.
docker run -d --name cloudshop-hardening \
--read-only --tmpfs /tmp:rw,noexec,nosuid,size=64m \
--cap-drop ALL --security-opt no-new-privileges \
--memory 256m --cpus 0.5 -p 127.0.0.1:3000:3000 \
cloudshop-api:hardening
# Verifique identidade e comportamento; a segunda execução deve falhar.
docker exec cloudshop-hardening id
docker exec cloudshop-hardening touch /app/nao-deveria-existirPor que isso importa
A combinação reduz vazamento de tokens durante o build e limita o impacto de uma execução remota de código no runtime.
Erro comum
Acreditar que secret mount impede qualquer vazamento ou que fixar digest dispensa atualizações.
Dica de produção
Teste o hardening em staging e mantenha uma rotina automatizada de atualização de base com revisão e validação.
Alerta de segurança
Scripts de instalação executam código de terceiros; --ignore-scripts reduz esse vetor, mas dependências com compilação nativa podem exigir um processo revisado específico.
Pergunta de entrevista
Como instalar uma dependência privada durante o build sem deixar seu token na imagem final?
Glossário
- secret mount
- Arquivo temporário disponibilizado pelo BuildKit para uma instrução de build.
- digest
- Hash do conteúdo usado para identificar de forma imutável uma imagem.
- capability
- Privilégio granular do kernel que pode ser retirado de um processo.
- tmpfs
- Filesystem temporário em memória, sem persistência após a remoção do container.
- hardening
- Redução de permissões e superfícies de ataque de um ambiente.
Conexão com o CloudShop
Construir a API do CloudShop sem incorporar tokens e comprovar sua execução com filesystem somente leitura.
Quiz da aula
1. Qual recurso fornece um token temporário durante o build?
2. Fixar a base por digest elimina qual necessidade?
3. A API precisa escrever arquivos temporários; qual ajuste é mais restrito?
Minhas anotações
Salvo automaticamente neste navegador.
