Pular para o conteúdo

Segurança

O Archgate executa regras TypeScript a partir de arquivos .rules.ts no seu repositório. Esta página explica o modelo de confiança, o que as regras podem e não podem fazer, e como rodar verificações com segurança.

Arquivos .rules.ts são código executável. Quando você roda archgate check, o CLI importa dinamicamente cada arquivo .rules.ts complementar e executa suas funções check. Isso equivale a rodar bun .archgate/adrs/*.rules.ts — o código tem as mesmas capacidades que qualquer outro script na sua máquina.

Isso significa:

  • Rode archgate check apenas em repositórios nos quais você confia.
  • Revise arquivos .rules.ts com o mesmo rigor que qualquer outro código-fonte do projeto.
  • Em projetos open-source, trate mudanças em .rules.ts em pull requests como sensíveis do ponto de vista de segurança.

As regras recebem um objeto RuleContext com operações de arquivo isoladas. Todos os métodos do RuleContext (readFile, readJSON, grep, grepFiles, glob) são restritos ao diretório raiz do projeto — travessia de caminho via ../, caminhos absolutos e links simbólicos são bloqueados e lançam um erro.

Além das restrições de caminho do RuleContext acima, o Archgate executa um scanner de segurança por análise estática em cada arquivo .rules.ts antes de executá-lo. Nenhum dos dois é um sandbox de runtime — uma regra ainda roda in-process com seus privilégios; o scanner é um portão estático, e as restrições se aplicam apenas à API RuleContext que uma regra bem-comportada usa. Como um arquivo de regra roda in-process com os mesmos privilégios de quem executa archgate check, qualquer módulo que ele consiga alcançar é código arbitrário — por isso o scanner usa uma allowlist, não uma denylist: uma regra só pode importar um pequeno conjunto de módulos seguros, e tudo o mais é rejeitado.

Os únicos módulos que um arquivo de regra pode importar são node:path, node:url, node:util e node:crypto — módulos utilitários sem capacidades de sistema de arquivos, rede ou processos. Eles devem usar o prefixo node:; as formas sem prefixo (path) podem ser sombreadas por um pacote no projeto alvo e são bloqueadas. Todo outro import é rejeitado, em qualquer forma — estático (import ... from), dinâmico (await import(...), seja o especificador um literal ou uma variável), reexportado (export ... from), ou alcançado via require() / import.meta.require().

O scanner também bloqueia as outras formas de alcançar código ou capacidades fora desse conjunto:

PadrãoBloqueado
Importar qualquer módulo além dos quatro permitidos acimaSim
require(), import.meta.require()Sim
Bun.spawn(), Bun.spawnSync(), Bun.write(), Bun.file(), Bun.$Sim
fetch()Sim
eval(), new Function()Sim
process.binding(), process.dlopen() (em qualquer alias de process)Sim
Acesso computado a propriedades (Bun[variável], globalThis[variável])Sim
Atribuição a globalThis ou process.envSim
Caracteres Unicode bidirecionais ou invisíveis (“Trojan Source”)Sim

Se qualquer um desses padrões for encontrado, o arquivo de regra não é importado nem executado e archgate check termina com erro.

Como o scanner trabalha a partir da árvore de sintaxe já parseada, ele enxerga através de escapes: await import("\x6e...") resolve para o mesmo nome de módulo que a allowlist verifica, então truques com strings não escapam por ele. A única coisa que uma árvore de sintaxe não consegue enxergar é um caractere que faz o código-fonte renderizado diferir do código que efetivamente executa — por isso o scanner também rejeita caracteres Unicode bidirecionais e invisíveis de imediato.

Regras importadas também são escaneadas. Quando você importa regras de terceiros com archgate adr import, cada .rules.ts é escaneado — com uma verificação mais rígida do que para regras próprias — antes de ser gravado em disco, de modo que um pacote importado não consiga contrabandear código que seu próximo archgate check executaria.

Regras bem-comportadas usam apenas os métodos do RuleContext (ctx.readFile, ctx.grep, ctx.glob, ctx.ast, etc.) e ctx.report para saída. Quando uma regra precisa de ferramental de linguagem — parsear Python, ou comparar um arquivo com sua revisão base no git — ctx.ast() é a porta sancionada; uma regra nunca precisa, e não consegue, abrir um subprocesso próprio.

  • Escrever arquivos — a API do RuleContext é somente leitura. Regras reportam violações mas não podem modificar o codebase.
  • Escapar do timeout de 30 segundos — cada regra é encerrada após 30 segundos de tempo de execução.
  • Afetar outras regras — regras de ADRs diferentes rodam em paralelo mas não compartilham estado mutável através da API de contexto.
  • Alcançar algo fora da allowlist por uma rota reconhecida — uma regra só pode importar node:path, node:url, node:util e node:crypto. Imports de qualquer outro módulo, APIs do Bun (Bun.spawn, Bun.file), acesso à rede (fetch), acesso a subprocessos ou código nativo (require, process.binding) e geração de código (eval, new Function) são rejeitados antes da execução em suas formas diretas e reconhecidas. Isto é uma varredura estática, não uma prisão: uma capacidade montada em tempo de execução é um resíduo que ela não consegue capturar, e por isso arquivos de regra não confiáveis ainda merecem revisão (veja abaixo).

Rodar archgate check em CI é seguro quando você controla o conteúdo do repositório. Cuidado extra é necessário para pull requests de contribuidores externos.

Para pushes em main ou outras branches protegidas, archgate check executa código que já foi revisado e mesclado. Isso é seguro:

on:
push:
branches: [main]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: archgate/check-action@v1

Quando um pull request vem de um fork, os arquivos .rules.ts no PR podem conter código arbitrário. Esse é o mesmo risco de rodar qualquer script de CI não confiável.

Opção 1: Exigir aprovação antes de rodar. Use regras de proteção de ambiente do GitHub ou pull_request_target com aprovação manual para condicionar o CI à revisão:

on:
pull_request_target:
jobs:
check:
runs-on: ubuntu-latest
environment: pr-check # Requer aprovação manual
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- uses: archgate/check-action@v1

Opção 2: Rodar verificações apenas em arquivos confiáveis. Use um workflow separado que faz checkout dos arquivos .rules.ts da branch base e os executa contra os arquivos-fonte do PR. Isso garante que apenas regras revisadas sejam executadas.

Opção 3: Pular verificações em PRs de forks. Se suas regras são principalmente para governança interna, pule verificações automatizadas em PRs de forks e rode-as manualmente após revisão:

on:
pull_request:
jobs:
check:
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: archgate/check-action@v1

Rode archgate check em runners com permissões mínimas. O job precisa apenas de acesso de leitura ao repositório — não são necessários secrets, chaves de deploy ou permissões de escrita:

jobs:
check:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: archgate/check-action@v1

Ao clonar ou fazer fork de um repositório que usa Archgate, o scanner de segurança aplica automaticamente a allowlist de imports em arquivos .rules.ts. É uma forte primeira linha de defesa — não um sandbox completo — então você ainda deve revisar os arquivos de regras antes de rodar archgate check pela primeira vez:

  • O scanner bloqueia as rotas diretas para capacidades perigosas, mas é análise estática, não uma jaula: qualquer coisa construída em tempo de execução — um nome de propriedade (obj[name] com um name computado) ou uma string de código — é opaca para uma varredura de código-fonte, então revise arquivos de regra em que você não confia antes de executá-los
  • Código de nível superior que executa no import (antes da função check ser chamada) ainda é executado se passar pelo scanner
  • Regras bem-comportadas usam apenas os métodos do RuleContext (ctx.readFile, ctx.grep, ctx.glob, ctx.ast, etc.) e ctx.report para saída

O comando archgate login armazena seu token de autenticação no gerenciador de credenciais do sistema operacional (macOS Keychain, Windows Credential Manager ou libsecret no Linux) via git credential approve. Nenhuma credencial é gravada em disco como arquivo de texto. O token é usado para instalação de plugins e nunca é enviado a terceiros além do serviço de plugins do Archgate.

  • Não exponha o token em logs de CI. Comandos de instalação de plugins passam credenciais via URLs autenticadas para o git, que podem aparecer em listagens de processos. Evite rodar archgate plugin install com logging verbose em ambientes de CI compartilhados.
  • Para revogar acesso, rode archgate login logout.

Quando você roda archgate upgrade, o CLI baixa o binário de release do GitHub Releases e verifica o checksum SHA256 antes da extração. Se o checksum não corresponder, a atualização é abortada. Isso protege contra downloads adulterados por interceptação de rede ou mirrors comprometidos.

Se você descobrir um problema de segurança no Archgate, por favor reporte de forma responsável abrindo uma issue no GitHub ou entrando em contato com os mantenedores diretamente. Não inclua código de exploit em issues públicas.