Voltar às atualizações
New releaseSep 4, 2026

safe-chain v1.5.16

Proteja contra código malicioso instalado via npm, yarn, pnpm, npx, pnpx, pip, uv e poetry com Aikido Safe Chain. Grátis para usar, sem necessidade de tokens.

Compartilhar

Aikido Safe Chain

Aikido Safe Chain

NPM Version NPM Downloads

  • ✅ Bloqueie malware em laptops de desenvolvedores e em CI/CD
  • ✅ Suporta npm e PyPI mais gerenciadores de pacotes em breve
  • ✅ Bloqueia pacotes com menos de 48 horas sem quebrar sua build
  • ✅ Sem token, gratuito, nenhum dado de build é compartilhado

Precisa de proteção além do npm e PyPI?

O Aikido Device Protection é construído sobre o Safe Chain, estendendo a segurança de pacotes e extensões por mais ecossistemas: npm, PyPI, VS Code, Open VSX - (Cursor, Windsurf, Kiro, Vs Codium, ...), Maven, NuGet, extensões do Chrome, Go, Skills.sh AI skills, Ruby, Rust, e mais.

Obtenha gerenciamento centralizado de políticas, fluxos de solicitação e aprovação, e visibilidade em cada estação de trabalho de desenvolvedor na sua organização. Desenvolvido com o mesmo feed do Aikido Intel. Faça o deploy manualmente ou gerencie-o através da sua ferramenta de MDM (Jamf, Fleet ou Iru).


O Aikido Safe Chain suporta os seguintes gerenciadores de pacotes:

  • 📦 npm
  • 📦 npx
  • 📦 yarn
  • 📦 pnpm
  • 📦 pnpx
  • 📦 rush
  • 📦 rushx
  • 📦 bun
  • 📦 bunx
  • 📦 pip
  • 📦 pip3
  • 📦 uv
  • 📦 poetry
  • 📦 uvx
  • 📦 pipx
  • 📦 pdm

Uso

Aikido Safe Chain demo

Instalação

Instalar o Aikido Safe Chain é fácil com o script de instalação.

Unix/Linux/macOS```shell

curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.20/install-safe-chain.sh -o /tmp/install-safe-chain.sh
&& echo "0ad25efe15d1fa56105157a454d647223e78eb0c53d1f85e3d10afcd722e7bfd /tmp/install-safe-chain.sh" | sha256sum -c -
&& sh /tmp/install-safe-chain.sh
&& rm /tmp/install-safe-chain.sh

### Windows (PowerShell)```powershell
$installer = Join-Path $env:TEMP "install-safe-chain.ps1"
Invoke-WebRequest "https://github.com/AikidoSec/safe-chain/releases/download/1.5.20/install-safe-chain.ps1" -OutFile $installer -UseBasicParsing
$expectedHash = "468C342C5AABB71200B0BD19950984EDD5C4B39811B653B13A5AD15E0FBA4DFA"
if ((Get-FileHash $installer -Algorithm SHA256).Hash -ne $expectedHash) {
    Remove-Item $installer -ErrorAction SilentlyContinue
    throw "Checksum verification failed for install-safe-chain.ps1"
}
& $installer
Remove-Item $installer

Os comandos de instalação acima sempre fazem referência a uma versão específica. Para instalar uma versão diferente, substitua a versão pelo número da versão desejada. Todas as versões disponíveis estão na página de releases.

Integridade do download

Os scripts de instalação são servidos a partir de um URL de release versionado (releases/download/1.5.20/...). As releases do GitHub são imutáveis — uma vez que um artefato é publicado num URL versionado, não pode ser modificado ou substituído, pelo que o ficheiro que descarrega tem a garantia de ser exatamente o que foi lançado.

Verificar a instalação

  1. ❗Reinicie o seu terminal para começar a usar o Aikido Safe Chain.

    • Este passo é crucial, pois garante que os aliases de shell para npm, npx, yarn, pnpm, pnpx, rush, rushx, bun, bunx, pip, pip3, poetry, uv, uvx, pipx e pdm são carregados corretamente. Se não reiniciar o terminal, os aliases não estarão disponíveis.
  2. Verifique a instalação executando o comando de verificação: ```shell npm safe-chain-verify pnpm safe-chain-verify pip safe-chain-verify uv safe-chain-verify

    Any other supported package manager: {packagemanager} safe-chain-verify

  • A saída deve exibir "OK: Safe-chain works!" confirmando que o Aikido Safe Chain está devidamente instalado e em execução.
  1. (Opcional) Testar o bloqueio de malware tentando instalar um pacote de teste:

    Para JavaScript/Node.js: ```shell npm install safe-chain-test

Para Python: ```shell pip3 install safe-chain-pi-test

- A saída deve mostrar que o Aikido Safe Chain está bloqueando a instalação desses pacotes de teste, pois eles são sinalizados como malware.

Ao executar os comandos `npm`, `npx`, `yarn`, `pnpm`, `pnpx`, `rush`, `rushx`, `bun`, `bunx`, `pip`, `pip3`, `uv`, `uvx`, `poetry`, `pipx` e `pdm`, o Aikido Safe Chain verificará automaticamente se há malware nos pacotes que você está tentando instalar. Ele também intercepta invocações de módulos Python para pip quando disponível (por exemplo, `python -m pip install ...`, `python3 -m pip download ...`). Se algum malware for detectado, ele solicitará que você saia do comando.

Você pode verificar a versão instalada executando:```shell
safe-chain --version

Como funciona

Bloqueio de Malware

O Aikido Safe Chain funciona executando um servidor proxy leve que intercepta downloads de pacotes do registro npm e do PyPI. Quando você executa os comandos npm, npx, yarn, pnpm, pnpx, rush, rushx, bun, bunx, pip, pip3, uv, uvx, poetry, pipx ou pdm, todos os downloads de pacotes são roteados através deste proxy local, que verifica os pacotes em tempo real contra o Aikido Intel - Open Sources Threat Intelligence. Se malware for detectado em qualquer pacote (incluindo dependências profundas), o proxy bloqueia o download antes que o código malicioso chegue à sua máquina.

Idade mínima do pacote

O Safe Chain aplica verificações de idade mínima de pacote aos ecossistemas suportados.

A aplicação atual difere por ecossistema:

  • gerenciadores de pacotes baseados em npm:
    • durante a resolução normal de pacotes, o Safe Chain suprime versões mais recentes que a idade mínima configurada dos metadados do pacote retornados pelo registro
    • para solicitações diretas de download de pacotes que contornam esse fluxo de metadados, o Safe Chain pode bloquear a própria solicitação usando uma lista em cache de pacotes recém-lançados
  • gerenciadores de pacotes Python:
    • durante a resolução de pacotes, o Safe Chain suprime arquivos e versões muito recentes das respostas de metadados do PyPI
    • para solicitações diretas de download de pacotes que contornam esse fluxo de metadados, o Safe Chain pode bloquear a própria solicitação usando uma lista em cache de pacotes recém-lançados

Por padrão, a idade mínima do pacote é de 48 horas. Isso fornece uma camada adicional de segurança durante o período crítico em que pacotes recém-publicados são mais vulneráveis a conter ameaças não detectadas. Você pode configurar esse limite ou contornar completamente essa proteção - consulte a seção Minimum Package Age Configuration abaixo.

Integração com o Shell

O Aikido Safe Chain integra-se com o seu shell para proporcionar uma experiência perfeita ao usar npm, npx, yarn, pnpm, pnpx, rush, rushx, bun, bunx e gerenciadores de pacotes Python (pip, uv, uvx, poetry, pipx, pdm). Ele configura aliases para esses comandos de modo que sejam envolvidos pelos comandos do Aikido Safe Chain, que gerenciam o servidor proxy antes de executar os comandos originais. Atualmente suportamos:

  • ✅ Bash
  • ✅ Zsh
  • ✅ Fish
  • ✅ PowerShell
  • ✅ PowerShell Core

Mais informações sobre a integração com o shell podem ser encontradas na documentação de integração com o shell.

Desinstalação

Para desinstalar o Aikido Safe Chain, use nosso desinstalador de uma linha:

Unix/Linux/macOS```shell

curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.20/uninstall-safe-chain.sh | sh

### Windows (PowerShell)```powershell
iex (iwr "https://github.com/AikidoSec/safe-chain/releases/download/1.5.20/uninstall-safe-chain.ps1" -UseBasicParsing)

❗Reinicie o seu terminal após a desinstalação para garantir que todos os aliases sejam removidos.

Configuração

Registo

Pode controlar a saída do Aikido Safe Chain utilizando a flag --safe-chain-logging ou a variável de ambiente SAFE_CHAIN_LOGGING.

Opções de Configuração

Pode definir o nível de registo através de múltiplas fontes (por ordem de prioridade):

  1. Argumento CLI (prioridade mais alta):

    • --safe-chain-logging=silent - Suprime toda a saída do Aikido Safe Chain exceto quando malware é bloqueado. A saída do gestor de pacotes é escrita para stdout normalmente, e o Safe Chain apenas escreve uma mensagem curta se tiver bloqueado malware e provocar a saída do processo.

      npm install express --safe-chain-logging=silent
      
    • --safe-chain-logging=verbose - Ativa a saída de diagnóstico detalhada do Aikido Safe Chain. Útil para resolver problemas ou compreender o que o Safe Chain está a fazer nos bastidores.

      npm install express --safe-chain-logging=verbose
      
  2. Variável de Ambiente: ```shell export SAFE_CHAIN_LOGGING=verbose npm install express

Valores válidos: silent, normal, verbose

Isto é útil para definir um nível de registo predefinido para todos os comandos do gestor de pacotes na sua sessão de terminal ou ambiente CI/CD.

Registo em Ficheiro

Pode espelhar a saída do Aikido Safe Chain para um ficheiro de registo utilizando a flag --safe-chain-log-file ou a variável de ambiente SAFE_CHAIN_LOG_FILE. O registo em ficheiro está desativado por predefinição e é ativado quando um caminho é definido. O formato do ficheiro (--safe-chain-log-file-format) e a verbosidade (--safe-chain-log-file-verbosity) são controlados independentemente da saída do terminal.

Opções de Configuração

Definidas através de qualquer uma destas (por ordem de prioridade):

  1. Argumento CLI (maior prioridade): ```shell npm install express
    --safe-chain-log-file=~/safe-chain.log
    --safe-chain-log-file-format=plain
    --safe-chain-log-file-verbosity=normal
  2. Variável de Ambiente: ```shell export SAFE_CHAIN_LOG_FILE=~/safe-chain.log export SAFE_CHAIN_LOG_FILE_FORMAT=plain export SAFE_CHAIN_LOG_FILE_VERBOSITY=normal
  3. Arquivo de Configuração (~/.safe-chain/config.json): ```json { "logFile": "~/safe-chain.log", "logFileFormat": "plain", "logFileVerbosity": "normal" }

logFileFormat — json (padrão) ou plain.

logFileVerbosity — silent, normal ou verbose (padrão). Independente de --safe-chain-logging.

Idade Mínima do Pacote

Você pode configurar por quanto tempo os pacotes devem existir antes que o Safe Chain permita sua instalação. Por padrão, os pacotes devem ter pelo menos 48 horas de existência antes de poderem ser instalados.

Para gerenciadores de pacotes baseados em npm, esta verificação atualmente possui dois modos de aplicação:

  • O Safe Chain suprime versões muito recentes dos metadados do pacote durante a resolução normal de dependências.
  • O Safe Chain bloqueia solicitações diretas de download de pacotes quando correspondem à lista em cache de pacotes recém-lançados.

Para gerenciadores de pacotes Python, esta verificação atualmente possui dois modos de aplicação:

  • O Safe Chain suprime arquivos e versões muito recentes dos metadados do PyPI durante a resolução de dependências.
  • O Safe Chain bloqueia solicitações diretas de download de pacotes quando correspondem à lista em cache de pacotes recém-lançados.

Opções de Configuração

Você pode definir a idade mínima do pacote por meio de várias fontes (em ordem de prioridade):

  1. Argumento CLI (maior prioridade): ```shell npm install express --safe-chain-minimum-package-age-hours=48
  2. Variável de Ambiente: ```shell export SAFE_CHAIN_MINIMUM_PACKAGE_AGE_HOURS=48 npm install express
  3. Arquivo de Configuração (~/.safe-chain/config.json): ```json { "minimumPackageAgeHours": 48 }

Excluindo Pacotes

Exclua pacotes confiáveis da filtragem de idade mínima via variável de ambiente ou arquivo de configuração (ambos são mesclados). Use @scope/* para confiar em todos os pacotes de uma organização:```shell export SAFE_CHAIN_MINIMUM_PACKAGE_AGE_EXCLUSIONS="@aikidosec/*"

## 4.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.```json
{
  "npm": {
    "minimumPackageAgeExclusions": ["@aikidosec/*"]
  },
  "pip": {
    "minimumPackageAgeExclusions": ["requests"]
  }
}

Registros Personalizados

Configure o Safe Chain para escanear pacotes de registros personalizados ou privados.

Ecossistemas suportados:

  • Node.js
  • Python

Opções de Configuração

Você pode definir registros personalizados por meio de variável de ambiente ou arquivo de configuração. Ambas as fontes são mescladas.

  1. Variável de Ambiente (separados por vírgula): ```shell export SAFE_CHAIN_NPM_CUSTOM_REGISTRIES="npm.company.com,registry.internal.net" export SAFE_CHAIN_PIP_CUSTOM_REGISTRIES="pip.company.com,registry.internal.net"
  2. Arquivo de Configuração (~/.safe-chain/config.json): ```json { "npm": { "customRegistries": ["npm.company.com", "registry.internal.net"] }, "pip": { "customRegistries": ["pip.company.com", "registry.internal.net"] } }

Arquivo de Configuração do PYPI

Se você depende de um arquivo pip.conf para a configuração do pip, você deve apontar o pip para ele explicitamente através da variável de ambiente PIP_CONFIG_FILE para que o Safe Chain possa mesclá-lo.

O Safe Chain executa o pip atrás de seu proxy MITM e grava um arquivo de configuração temporário do pip para injetar seu certificado e configurações de proxy. Quando PIP_CONFIG_FILE está definido, o Safe Chain mescla suas configurações em uma cópia do seu arquivo (seu arquivo original nunca é modificado) para que seu index-url, credenciais e outras opções sejam preservados. Quando PIP_CONFIG_FILE não está definido, a configuração de nível de usuário do pip (por exemplo, ~/.config/pip/pip.conf) pode ser sobrescrita pelo arquivo temporário do Safe Chain e suas configurações não serão aplicadas.

URL Base da Lista de Malware

Configure o Safe Chain para buscar bancos de dados de malware e listas de novos pacotes a partir de uma URL de espelho personalizada. Isso permite que você hospede sua própria cópia do banco de dados de malware da Aikido.

Opções de Configuração

Você pode definir a URL base da lista de malware através de múltiplas fontes (em ordem de prioridade):

  1. Argumento CLI (maior prioridade): ```shell npm install express --safe-chain-malware-list-base-url=https://your-mirror.com
  2. Variável de Ambiente: ```shell export SAFE_CHAIN_MALWARE_LIST_BASE_URL=https://your-mirror.com npm install express
  3. Arquivo de Configuração (~/.safe-chain/config.json): ```json { "malwareListBaseUrl": "https://your-mirror.com" }

A URL base deve apontar para um servidor que espelhe a estrutura de https://malware-list.aikido.dev/, incluindo os seguintes caminhos:

  • /malware_predictions.json (banco de dados de malware do ecossistema JavaScript)
  • /malware_pypi.json (banco de dados de malware do ecossistema Python)
  • /releases/npm.json (lista de novos pacotes JavaScript)
  • /releases/pypi.json (lista de novos pacotes Python)

Arquivo de Configuração do Projeto

Além do arquivo de configuração no diretório home (~/.safe-chain/config.json), o Safe Chain suporta um arquivo de configuração de projeto para que as configurações possam ser versionadas em um repositório e compartilhadas entre uma equipe, em vez de serem configuradas por máquina.

Adicione uma seção safe-chain: ao arquivo .aikido na raiz do seu repositório (o mesmo arquivo usado por outras ferramentas Aikido; o Safe Chain lê apenas sua própria seção safe-chain: e ignora o restante). Quando encontrada, suas configurações são mescladas sobre o arquivo de configuração do diretório home: os valores definidos na configuração do projeto têm prioridade, e arrays (como customRegistries) são combinados de ambos os arquivos em vez de um substituir o outro.

Apenas as seguintes configurações podem ser definidas a partir de um arquivo de configuração de projeto:```yaml safe-chain: minimumPackageAgeHours: 48 npm: customRegistries: - npm.company.com minimumPackageAgeExclusions: - "@aikidosec/*" pip: customRegistries: - pip.company.com minimumPackageAgeExclusions: - requests

Opções como `scanTimeout`, `malwareListBaseUrl` e as opções `logFile*` não podem ser definidas a partir de um arquivo de configuração de projeto - elas só podem vir da configuração do seu diretório home, de argumentos da CLI ou de variáveis de ambiente.

## Diretório de Instalação Personalizado

Por padrão, o Safe Chain se instala em `~/.safe-chain`. Você pode alterar isso passando um diretório de instalação explícito para o instalador. Isso é útil para instalações em todo o sistema (por exemplo, dentro de uma imagem Docker) ou quando você precisa evitar conflitos com outras ferramentas.

Quando definido, todos os dados do Safe Chain (binário, shims, scripts, configuração) são colocados sob o diretório personalizado em vez de `~/.safe-chain`.

### Unix/Linux/macOS```shell
curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.20/install-safe-chain.sh -o /tmp/install-safe-chain.sh \
  && echo "0ad25efe15d1fa56105157a454d647223e78eb0c53d1f85e3d10afcd722e7bfd  /tmp/install-safe-chain.sh" | sha256sum -c - \
  && sh /tmp/install-safe-chain.sh --install-dir /usr/local/.safe-chain \
  && rm /tmp/install-safe-chain.sh

Windows```powershell

$installer = Join-Path $env:TEMP "install-safe-chain.ps1" Invoke-WebRequest "https://github.com/AikidoSec/safe-chain/releases/download/1.5.20/install-safe-chain.ps1" -OutFile $installer -UseBasicParsing $expectedHash = "468C342C5AABB71200B0BD19950984EDD5C4B39811B653B13A5AD15E0FBA4DFA" if ((Get-FileHash $installer -Algorithm SHA256).Hash -ne $expectedHash) { Remove-Item $installer -ErrorAction SilentlyContinue throw "Checksum verification failed for install-safe-chain.ps1" } & $installer -InstallDir 'C:\ProgramData\safe-chain' Remove-Item $installer

# Uso em CI/CD

Você pode proteger seus pipelines de CI/CD contra pacotes maliciosos integrando o Aikido Safe Chain ao seu processo de build. Isso garante que quaisquer pacotes instalados durante seus builds automatizados sejam verificados quanto a malware antes da instalação.

## Instalação para CI/CD

Use a flag `--ci` para configurar automaticamente o Aikido Safe Chain para ambientes de CI/CD. Isso configura shims executáveis no PATH em vez de aliases de shell.

### Unix/Linux/macOS (GitHub Actions, Azure Pipelines, etc.)```shell
curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.20/install-safe-chain.sh -o /tmp/install-safe-chain.sh \
  && echo "0ad25efe15d1fa56105157a454d647223e78eb0c53d1f85e3d10afcd722e7bfd  /tmp/install-safe-chain.sh" | sha256sum -c - \
  && sh /tmp/install-safe-chain.sh --ci \
  && rm /tmp/install-safe-chain.sh

Windows (Azure Pipelines, etc.)```powershell

$installer = Join-Path $env:TEMP "install-safe-chain.ps1" Invoke-WebRequest "https://github.com/AikidoSec/safe-chain/releases/download/1.5.20/install-safe-chain.ps1" -OutFile $installer -UseBasicParsing $expectedHash = "468C342C5AABB71200B0BD19950984EDD5C4B39811B653B13A5AD15E0FBA4DFA" if ((Get-FileHash $installer -Algorithm SHA256).Hash -ne $expectedHash) { Remove-Item $installer -ErrorAction SilentlyContinue throw "Checksum verification failed for install-safe-chain.ps1" } & $installer -ci Remove-Item $installer

## Plataformas Suportadas

- ✅ **GitHub Actions**
- ✅ **Azure Pipelines**
- ✅ **CircleCI**
- ✅ **Jenkins**
- ✅ **Bitbucket Pipelines**
- ✅ **GitLab Pipelines**

## Exemplo de GitHub Actions```yaml
- name: Setup Node.js
  uses: actions/setup-node@v4
  with:
    node-version: "22"
    cache: "npm"

- name: Install safe-chain
  run: |
    curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.20/install-safe-chain.sh -o /tmp/install-safe-chain.sh
    echo "0ad25efe15d1fa56105157a454d647223e78eb0c53d1f85e3d10afcd722e7bfd  /tmp/install-safe-chain.sh" | sha256sum -c -
    sh /tmp/install-safe-chain.sh --ci
    rm /tmp/install-safe-chain.sh

- name: Install dependencies
  run: npm ci

Exemplo do Azure DevOps```yaml

  • task: NodeTool@0 inputs: versionSpec: "22.x" displayName: "Install Node.js"

  • script: | curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.20/install-safe-chain.sh -o /tmp/install-safe-chain.sh echo "0ad25efe15d1fa56105157a454d647223e78eb0c53d1f85e3d10afcd722e7bfd /tmp/install-safe-chain.sh" | sha256sum -c - sh /tmp/install-safe-chain.sh --ci rm /tmp/install-safe-chain.sh displayName: "Install safe-chain"

  • script: npm ci displayName: "Install dependencies"

## Exemplo de CircleCI```yaml
version: 2.1
jobs:
  build:
    docker:
      - image: cimg/node:lts
    steps:
      - checkout
      - run: |
          curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.20/install-safe-chain.sh -o /tmp/install-safe-chain.sh
          echo "0ad25efe15d1fa56105157a454d647223e78eb0c53d1f85e3d10afcd722e7bfd  /tmp/install-safe-chain.sh" | sha256sum -c -
          sh /tmp/install-safe-chain.sh --ci
          rm /tmp/install-safe-chain.sh
      - run: npm ci
workflows:
  build_and_test:
    jobs:
      - build

Exemplo de Jenkins

Nota: Isto pressupõe que o Node.js e o npm estão instalados no agente Jenkins.```groovy pipeline { agent any

environment { // Jenkins does not automatically persist PATH updates from setup-ci, // so add the shims + binary directory explicitly for all stages. // If you installed into a custom directory, replace ~/.safe-chain with that path here. PATH = "${env.HOME}/.safe-chain/shims:${env.HOME}/.safe-chain/bin:${env.PATH}" }

stages { stage('Install safe-chain') { steps { sh ''' set -euo pipefail

      # Install Safe Chain for CI
      curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.20/install-safe-chain.sh -o /tmp/install-safe-chain.sh
      echo "0ad25efe15d1fa56105157a454d647223e78eb0c53d1f85e3d10afcd722e7bfd  /tmp/install-safe-chain.sh" | sha256sum -c -
      sh /tmp/install-safe-chain.sh --ci
      rm /tmp/install-safe-chain.sh
    '''
  }
}

stage('Install project dependencies etc...') {
  steps {
    sh '''
      set -euo pipefail
      npm ci
    '''
  }
}

} }

## Exemplo de Pipelines do Bitbucket```yaml
image: node:22

steps:
  - step:
      name: Install
      script:
        - |
          curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.20/install-safe-chain.sh -o /tmp/install-safe-chain.sh
          echo "0ad25efe15d1fa56105157a454d647223e78eb0c53d1f85e3d10afcd722e7bfd  /tmp/install-safe-chain.sh" | sha256sum -c -
          sh /tmp/install-safe-chain.sh --ci
          rm /tmp/install-safe-chain.sh
        - export PATH=~/.safe-chain/shims:~/.safe-chain/bin:$PATH
        - npm ci

Após a configuração, todos os comandos subsequentes do gerenciador de pacotes no seu pipeline de CI serão automaticamente protegidos pela detecção de malware do Aikido Safe Chain.

Exemplo de Pipelines do GitLab

Para adicionar o safe-chain em pipelines do GitLab, você precisa instalá-lo na imagem que executa o pipeline. Isso pode ser feito por:

  1. Definir um dockerfile para executar seu build ```dockerfile FROM node:lts

    Install safe-chain

    RUN curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.20/install-safe-chain.sh -o /tmp/install-safe-chain.sh
    && echo "0ad25efe15d1fa56105157a454d647223e78eb0c53d1f85e3d10afcd722e7bfd /tmp/install-safe-chain.sh" | sha256sum -c -
    && sh /tmp/install-safe-chain.sh --ci
    && rm /tmp/install-safe-chain.sh

    Add safe-chain to PATH (update paths if you used a custom install dir)

    ENV PATH="/root/.safe-chain/shims:/root/.safe-chain/bin:${PATH}"

  2. Construa a imagem Docker no seu pipeline de CI ```yaml build-image: stage: build-image image: docker:latest services: - docker:dind script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker build -t $CI_REGISTRY_IMAGE:latest . - docker push $CI_REGISTRY_IMAGE:latest

  3. Use a imagem em seu pipeline: ```yaml npm-ci: stage: install image: $CI_REGISTRY_IMAGE:latest script: - npm ci

O pipeline completo para este exemplo é assim:```yaml stages:

  • build-image
  • install

build-image: stage: build-image image: docker:latest services: - docker:dind script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker build -t $CI_REGISTRY_IMAGE:latest . - docker push $CI_REGISTRY_IMAGE:latest

npm-ci: stage: install image: $CI_REGISTRY_IMAGE:latest script: - npm ci

# Solução de problemas

Está com problemas? Consulte o [Guia de Solução de Problemas](https://github.com/aikidosec/safe-chain/blob/main/docs/troubleshooting.md) para obter ajuda com problemas comuns.

# Relatar Problemas

Se você encontrar problemas:

1. Visite [GitHub Issues](https://github.com/AikidoSec/safe-chain/issues)
2. Inclua:
   * Sistema operacional e versão
   * Tipo e versão do shell
   * Saída de `safe-chain --version`
   * Saída dos comandos de verificação
   * Logs detalhados do comando com falha (adicione o argumento `--safe-chain-logging=verbose`)

Categorias