Desenvolvimento e IA Aplicada · Tutorial

Como configurar deploy automático com segurança

Automatizar a publicação tira o erro humano do processo, mas cria um novo alvo: o pipeline tem acesso à produção. Veja como montar um deploy automático que só publica o que passou nos testes e guarda bem as chaves.

Editor responsável:
Daniel Ferreira

Publicado em · 7 min de leitura

Também disponível em: English

Em três pontos

  • O deploy automático só é seguro se uma verificação obrigatória vier antes: build e testes que falham de verdade interrompem a publicação.
  • Credenciais ficam fora do repositório, com o menor acesso possível; quando o provedor permite, troque chaves fixas por tokens de curta duração via OIDC.
  • Proteja o caminho até a produção: permissões mínimas, ambiente com aprovação, ações fixadas por commit e um rollback ensaiado.

Publicar à mão tem um problema conhecido: cada vez é um pouco diferente. Alguém esquece de rodar os testes, copia a pasta errada ou envia para o servidor de outro projeto. O deploy automático, em que um processo publica o site sem intervenção manual a cada mudança aprovada, resolve isso.

Mas ele cria outro risco. O pipeline, a sequência automatizada de etapas que vai do código à produção, passa a guardar as chaves do servidor. Quem controla o pipeline controla o site. A OWASP, fundação dedicada à segurança de software, mantém uma lista específica dos dez principais riscos de CI/CD, que inclui controle de fluxo insuficiente, higiene de credenciais insuficiente e execução de pipeline envenenado.

Este tutorial usa o GitHub Actions como exemplo, porque a documentação de segurança dele é detalhada. Os princípios valem para outras ferramentas. No final, há o caso do próprio Token & Tech.

Passo 1: defina a trava antes da publicação

A primeira regra de um deploy automático é que ele só publica o que passou numa verificação. A ordem é sempre a mesma: build, testes, e só então publicação. Se qualquer etapa falhar, o processo para.

Isso exige testes que falham de verdade, com código de saída diferente de zero. Um teste que só imprime avisos não trava nada. Para sites, a verificação mínima inclui links internos e metadados de SEO, assuntos de Como testar links internos e rotas automaticamente e Como automatizar auditorias técnicas de SEO.

No GitHub Actions, separe a verificação e a publicação em dois jobs (tarefas), com o segundo dependente do primeiro. Assim, a publicação nem começa se a verificação falhar.

Passo 2: tire as credenciais do repositório

Nenhuma senha, token ou chave de servidor deve estar no código. A referência de segurança do GitHub é direta: dados sensíveis nunca devem ficar em texto puro nos arquivos de workflow.

Use o cofre de segredos da plataforma. No GitHub, segredos são referenciados como variáveis de ambiente do passo que precisa deles. A documentação de uso de segredos recomenda evitar passar segredos como argumento de linha de comando, que pode ficar visível para outros processos ou em logs de auditoria. Prefira variável de ambiente ou entrada padrão.

Outras recomendações da mesma documentação:

  • Crie um segredo para cada valor. Não guarde um bloco JSON ou YAML inteiro num único segredo, porque a ocultação nos logs depende de correspondência exata.
  • Dê a cada credencial só o acesso necessário e troque-as periodicamente.
  • Workflows disparados por pull requests vindos de forks (cópias do repositório feitas por terceiros) não recebem os segredos, com exceção do GITHUB_TOKEN.

Para evitar que uma chave chegue ao repositório por engano, o GitHub tem a proteção de push do secret scanning: ela bloqueia o envio de commits que contêm credenciais reconhecidas antes que cheguem ao repositório (documentação). Em repositórios privados, o recurso depende do GitHub Secret Protection. Um .gitignore que exclui arquivos .env e de configuração local é a primeira barreira, e é gratuita.

Passo 3: prefira credenciais de curta duração

Um segredo guardado no cofre ainda é uma chave fixa. Se vazar, vale até alguém revogá-la.

Quando o destino é um provedor de nuvem compatível, o GitHub Actions permite usar OIDC (OpenID Connect), um protocolo de identidade. Em vez de guardar a chave da nuvem, você configura no provedor uma relação de confiança com o GitHub. A cada execução, o workflow pede um token que, segundo a documentação, vale para um único job e expira automaticamente. O provedor confere de qual repositório e de qual ambiente o pedido veio antes de liberar o acesso.

Para isso, o job precisa da permissão id-token: write (configuração nos provedores). Nem toda hospedagem aceita OIDC. Quando não aceitar, use uma credencial dedicada ao deploy, restrita a uma pasta ou a um repositório, e nunca a senha da conta principal.

Passo 4: reduza as permissões do workflow

Cada execução do GitHub Actions recebe um token automático, o GITHUB_TOKEN. A recomendação da referência de segurança é deixar a permissão padrão como somente leitura e ampliar apenas no job que precisa.

Na sintaxe de workflow, quando você declara qualquer permissão, todas as não declaradas passam a none. Um exemplo de estrutura, apenas ilustrativo:

# exemplo: .github/workflows/deploy.yml
name: deploy
on:
  push:
    branches: [main]

permissions:
  contents: read

concurrency:
  group: production
  cancel-in-progress: false

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@<SHA-completo-do-commit>
      - run: npm ci
      - run: npm run build
      - run: npm run check

  deploy:
    needs: verify
    runs-on: ubuntu-latest
    environment: production
    permissions:
      contents: read
      id-token: write   # só se o destino aceitar OIDC
    steps:
      - run: echo "publicar aqui, com a credencial do ambiente"

O exemplo omite como o resultado do build passa de um job para outro; em um projeto real, você reconstrói no job de deploy ou usa artefatos.

Três detalhes desse arquivo:

  • concurrency evita dois deploys simultâneos. Com um grupo definido, a documentação informa que só uma execução fica pendente por grupo; uma nova pendente cancela a anterior. A opção cancel-in-progress: true cancela também a que está rodando. Para deploy, a redação prefere false, para não interromper uma publicação no meio.
  • Ações fixadas por SHA. Ações de terceiros referenciadas por tag, como @v4, podem ter a tag movida. Segundo o GitHub, fixar a ação no SHA completo do commit é “atualmente a única forma” de usá-la como versão imutável.
  • Entrada não confiável. Títulos de pull request, nomes de branch e mensagens de commit são escritos por quem abre a mudança. Inseridos direto num comando run:, podem injetar código. A documentação recomenda passá-los por variável de ambiente intermediária.

Passo 5: proteja o ambiente de produção

No GitHub, um ambiente (environment) é um destino de deploy com regras próprias, como production ou staging. O job o declara com a chave environment e espera as regras serem cumpridas antes de rodar (documentação de deploy). A documentação de ambientes descreve as proteções:

  • Revisores obrigatórios: até seis pessoas ou equipes; basta uma aprovar. Há a opção de impedir que quem disparou a execução aprove a si mesmo.
  • Branches permitidos: só os branches ou tags escolhidos podem publicar nesse ambiente.
  • Temporizador: um intervalo antes de o job prosseguir.
  • Segredos do ambiente: só ficam disponíveis para o job depois que as regras forem cumpridas.

Por padrão, administradores podem passar por cima dessas regras; a opção pode ser desligada. Há um limite de plano: no GitHub Free, ambientes só podem ser configurados em repositórios públicos. Repositórios privados exigem GitHub Pro ou Team. Em equipes pequenas, a combinação de branch protegido com segredo restrito ao ambiente já fecha boa parte do caminho.

Dois cuidados com gatilhos, também da referência de segurança: evite runners auto-hospedados (máquinas próprias que executam os jobs) em repositórios públicos, e não use pull_request_target para rodar código de pull request não confiável, porque esse gatilho tem acesso de escrita e aos segredos.

Passo 6: verifique depois e tenha um rollback

O deploy terminar sem erro não prova que o site está no ar. Inclua uma checagem pós-publicação: algumas requisições ao endereço real conferindo status HTTP, redirecionamentos e uma página recente.

E decida antes como voltar atrás. Um rollback é a restauração da versão anterior. Se cada publicação é um commit num histórico, voltar é reverter o commit e publicar de novo. O procedimento deve estar escrito e ensaiado; descobrir como desfazer durante uma falha é o pior momento para isso.

Caso documentado: a publicação do Token & Tech

O site que você está lendo usa uma versão simples desses princípios, sem GitHub Actions: um script de publicação executado localmente, scripts/publish.sh, descrito no DEPLOY.md do projeto.

  • Trava antes da publicação. O script roda o build e o verificador npm run check. Se a checagem falhar, ele refaz o build uma vez, porque artigos podem ser publicados durante o build, e para de vez se falhar de novo.
  • Branch separado para o deploy. O código-fonte fica num branch; o site gerado vai para outro, dedicado à publicação, que contém só os arquivos finais. A hospedagem puxa esse branch automaticamente. O código-fonte nunca é publicado.
  • Conferência do destino. Antes de enviar, o script verifica se a pasta de trabalho aponta para o repositório remoto esperado e interrompe se não apontar. Isso evita publicar no projeto errado.
  • Sem credenciais no repositório. O documento de deploy não contém senhas, o .gitignore exclui .env e arquivos de configuração do servidor, e o verificador falha se algum desses arquivos aparecer na pasta publicada.
  • Verificação remota e rollback. O procedimento lista conferências no site real depois de publicar, como redirecionamentos, páginas principais, sitemap e página de erro 404. O rollback é reverter o último commit do branch de deploy, o que faz a hospedagem republicar a versão anterior.

Uma limitação: como o script roda na máquina de quem publica, não há aprovação obrigatória nem registro centralizado de execuções, que um ambiente protegido num serviço de CI ofereceria.

O que levar deste texto

  • Build e testes que falham de verdade vêm antes de qualquer publicação.
  • Credenciais ficam no cofre, nunca no código; quando possível, use tokens de curta duração via OIDC.
  • Permissão mínima por padrão, ações fixadas por SHA e entrada externa tratada como não confiável.
  • Proteja a produção com ambiente e branch restritos, confira o site depois de publicar e mantenha um rollback ensaiado.

Divulgação: O site do Token & Tech usa as técnicas descritas aqui.

Fontes

  1. Concurrency, GitHub Docs. Acesso em 8 de outubro de 2026
  2. Deploying with GitHub Actions, GitHub Docs. Acesso em 8 de outubro de 2026
  3. Managing environments for deployment, GitHub Docs. Acesso em 8 de outubro de 2026
  4. Configuring OpenID Connect in cloud providers, GitHub Docs. Acesso em 8 de outubro de 2026
  5. OpenID Connect, GitHub Docs. Acesso em 8 de outubro de 2026
  6. About push protection, GitHub Docs. Acesso em 8 de outubro de 2026
  7. Using secrets in GitHub Actions, GitHub Docs. Acesso em 8 de outubro de 2026
  8. Secure use reference (GitHub Actions), GitHub Docs. Acesso em 8 de outubro de 2026
  9. Workflow syntax for GitHub Actions, GitHub Docs. Acesso em 8 de outubro de 2026
  10. OWASP Top 10 CI/CD Security Risks, OWASP Foundation. Acesso em 8 de outubro de 2026

Leia também

Desenvolvimento e IA Aplicada · Explicador

Content Collections do Astro: conteúdo em escala

Quando um site passa de algumas páginas para centenas de textos, o problema deixa de ser escrever e passa a ser manter tudo consistente. Veja como o Astro resolve isso com coleções tipadas.

Desenvolvimento e IA Aplicada · Explicador

Astro: por que usar em sites com milhares de páginas

Quando um site tem milhares de páginas de conteúdo, cada decisão de arquitetura se multiplica. Veja, pela documentação oficial e por dados de campo datados, o que o Astro faz bem nesse cenário e onde estão os limites.

Desenvolvimento e IA Aplicada · Análise

Astro ou Next.js: arquitetura e desempenho comparados

Astro e Next.js geram HTML no servidor, mas partem de premissas diferentes: um nasceu para sites de conteúdo, o outro para aplicações React. Veja, com documentação oficial e dados de campo datados, o que isso muda na prática.