7 min de leitura

Publicação de pacotes por agentes de IA sem excesso de tokens de lançamento

Publicar pacotes com agentes de IA exige controles separados para downloads, lançamentos, tags e exclusões. Teste todo o caminho de lançamento com um pacote descartável.

Publicação de pacotes por agentes de IA sem excesso de tokens de lançamento

Um agente de programação com IA deve conseguir instalar dependências sem ter autoridade para publicar, retirar a publicação, excluir ou alterar tags de pacotes. Essas operações parecem próximas na linha de comando, mas têm consequências completamente diferentes. Tratar tudo como uma única permissão transforma uma tarefa rotineira de desenvolvimento em autoridade de lançamento.

Já vi credenciais de publicação se espalharem porque uma equipe queria que um agente executasse um único comando inofensivo de instalação. O token acabou em uma variável de ambiente do shell, em um arquivo de configuração ou na saída de um comando, onde qualquer ferramenta daquela execução poderia reutilizá-lo. A falha posterior raramente começa com um comprometimento dramático. Ela começa com um agente executando npm publish no registro errado, movendo latest antes que alguém examine o tarball ou tentando retirar uma publicação porque interpretou de forma literal demais uma solicitação de limpeza de teste.

Ler um registro não concede autoridade de lançamento

A instalação e a publicação de pacotes usam a mesma família de endpoints de registro, mas respondem a perguntas de confiança diferentes. Um download pergunta: «Este processo pode obter um artefato?» Uma publicação pergunta: «Este processo pode criar um lançamento público ou visível para a organização com este nome?» Uma exclusão ou retirada de publicação pergunta: «Este processo pode alterar o histórico e a disponibilidade de um lançamento que outras compilações talvez já consumam?»

Não transforme essas perguntas em uma única credencial só porque o cliente do registro faz as operações parecerem semelhantes. Um gerenciador de pacotes pode ler a configuração do mesmo arquivo .npmrc para npm ci, npm publish, npm dist-tag add e npm unpublish. Essa estrutura de arquivo é uma conveniência do cliente, não um modelo de permissões.

Para um agente, separe as ações do registro em pelo menos estes grupos:

  • Leitura: consulta de metadados, download do tarball, verificação de integridade e instalação de dependências.
  • Publicação: criação de uma nova versão imutável com um nome de pacote aprovado.
  • Roteamento: alterações em canais mutáveis, como latest, tags de pré-lançamento ou configurações de acesso do registro.
  • Destrutivas: retirada da publicação, exclusão do pacote quando o registro permitir e remoção de uma tag de lançamento.

A diferença entre publicar e rotear importa mais do que muitos scripts de lançamento admitem. Uma versão de pacote pode estar correta, enquanto atribuí-la a latest faz com que novos consumidores a recebam. Por outro lado, uma versão de pré-lançamento publicada com uma tag dedicada pode ter baixo risco se os usuários precisarem optar por essa tag. Os bytes do pacote e o caminho que os consumidores percorrem até eles são controles separados.

A exclusão merece sua própria categoria, mesmo quando o registro a restringe. As regras variam, e algumas operações chamadas de «excluir» apenas ocultam um artefato ou o marcam como indisponível. Isso não torna a ação inofensiva. Ela pode quebrar instalações reproduzíveis, investigações de incidentes e equipes que fixaram a versão removida. Um agente nunca deve presumir que uma limpeza é segura apenas porque a versão foi publicada alguns minutos antes.

Tokens amplos de publicação falham de maneiras comuns

Um token de registro no ambiente de um agente é uma concessão de autorização em um formato de arquivo conveniente. Ele não é uma instrução com escopo limitado. Se o agente consegue ler o ambiente ou um arquivo de configuração, uma injeção de prompt em uma dependência, um modelo de issue, um log de compilação ou um texto de terminal copiado pode alcançar a credencial.

A recomendação comum é usar o token com o menor escopo oferecido pelo registro. É um bom conselho, mas incompleto. Um token restrito à publicação ainda pode publicar uma versão indesejada, em um pacote não pretendido ao qual a conta tenha acesso ou em um endpoint de registro selecionado por uma configuração alterada. O escopo reduz o raio de impacto. Ele não estabelece a intenção de cada lançamento.

Já precisei corrigir mais de uma vez uma falha com este formato:

  1. Uma equipe dá a um agente um token do registro para que ele execute verificações de lançamento.
  2. A configuração do projeto aponta para o registro de produção porque é isso que as máquinas dos desenvolvedores usam.
  3. O agente precisa validar o conteúdo do pacote e executa npm pack, o que é inofensivo.
  4. Uma instrução seguinte diz para «testar a publicação», e o agente executa npm publish em vez de publicar em um destino isolado.
  5. O comando funciona porque o token e o nome do pacote são válidos. A equipe só percebe depois que a automação ou os usuários veem a nova versão.

Nada nessa sequência exige um invasor. O projeto deu a um sistema de planejamento uma credencial e confiou que ele preservaria um limite que o ambiente operacional não impunha.

Mantenha a credencial fora do processo do agente. Permita que um gateway de ações a armazene e execute uma solicitação HTTP ou um comando específico depois de verificar o destino solicitado e obter a aprovação humana necessária. O Sallyport segue esse padrão: o agente recebe o resultado de uma ação autorizada, nunca o token do registro.

Esse projeto ainda exige boas definições de ação. Um gateway que aprova «qualquer solicitação para registry.example» apenas colocou o problema do token amplo atrás de um botão. A solicitação precisa mostrar detalhes suficientes para que o aprovador diferencie um download de tarball de uma publicação de versão, e uma publicação de pacote de uma retirada de publicação.

Torne a solicitação de lançamento inspecionável antes da execução

Uma pessoa não pode aprovar uma instrução vaga como «publique o pacote». A tela de aprovação deve mostrar o identificador do pacote, a versão exata, o host do registro, a operação e a alteração de tag, caso exista. Se o agente não consegue fornecer esses campos, ainda não preparou uma solicitação de lançamento.

Para um registro compatível com npm, separe o trabalho em uma fase de inspeção do artefato e uma fase de alteração do registro. A inspeção pode ocorrer sem autoridade de publicação:

npm ci
npm test
npm pack --json

npm pack --json retorna informações estruturadas sobre o tarball que seria criado. As partes úteis têm um formato parecido com este:

[
  {
    "id": "@acme/[email protected]",
    "name": "@acme/widget",
    "version": "1.4.0",
    "filename": "acme-widget-1.4.0.tgz",
    "files": [
      {"path": "README.md", "size": 2400},
      {"path": "dist/index.js", "size": 18420},
      {"path": "package.json", "size": 910}
    ]
  }
]

Inspecione a lista de arquivos, não apenas o código de saída do comando. Procuro diretórios de código-fonte que deveriam ter permanecido privados, dados de teste com credenciais, um diretório de saída compilada ausente e metadados do pacote que apontem para o entry point errado. É no npm pack que esses erros custam pouco.

Depois, consulte o estado do registro separadamente. A documentação da CLI do npm descreve npm view como uma forma de consultar metadados de pacotes no registro. Use-o para fazer perguntas concretas, em vez de aceitar uma grande quantidade de dados sem filtro:

npm view @acme/widget version dist-tags --json
npm view @acme/[email protected] dist --json

O primeiro comando mostra qual versão existe e para onde as tags apontam. O segundo é útil após a publicação, porque dist contém o endereço do tarball e os dados de integridade registrados pelo registro. Um fluxo de lançamento deve preservar essa saída no registro da versão, sem segredos, porque ela captura o que o registro aceitou, e não apenas o que o diretório local pretendia enviar.

Monte uma solicitação de aprovação a partir desses fatos. Uma boa solicitação diz: publique @acme/[email protected] em registry.example, sem mover nenhuma tag. Uma solicitação ruim diz: execute npm publish. A primeira permite que o revisor perceba um erro de namespace. A segunda exige que ele reconstrua a intenção a partir de um comando em que talvez não confie.

Um pacote descartável comprova o caminho do registro

Um pacote descartável é a forma mais segura de testar o caminho que transforma um tarball preparado em uma versão recuperável no registro. Ele não prova que o pacote de produção está pronto. Prova que a autenticação, a seleção do registro, o mecanismo de publicação e a instalação limpa funcionam juntos sob controles parecidos com os do lançamento real.

Use um nome de pacote em um namespace que você controle e deixe claro que o pacote é temporário. Não imite o nome de um pacote popular e não use um nome que possa se tornar acidentalmente um produto real no futuro. Coloque nele um módulo pequeno e inerte. A função do pacote é ser publicado e instalado, não demonstrar o comportamento de uma aplicação.

Este package.json mínimo mantém o teste fácil de entender:

{
  "name": "@acme-release-test/relay-check-2025-04",
  "version": "0.0.1",
  "description": "Temporary registry release-path check",
  "main": "index.js",
  "files": ["index.js", "README.md"],
  "publishConfig": {
    "access": "restricted"
  }
}

Escolha configurações de acesso que correspondam ao tipo real do seu pacote. Não copie restricted sem pensar se o pacote real é público, e não torne um teste descartável público apenas para deixá-lo mais parecido com a realidade. O objetivo é exercitar o mesmo limite de autorização e de público pretendido. Se você precisa testar uma publicação pública, use um nome público explicitamente temporário e verifique as regras de retenção e retirada do registro antes de começar.

Execute o teste em um diretório novo para que metadados em cache e um workspace existente não produzam um resultado artificialmente positivo:

mkdir release-path-check
cd release-path-check
npm init -y
npm install @acme-release-test/[email protected]
node -e "console.log(require('@acme-release-test/relay-check-2025-04'))"

Uma instalação npm install bem-sucedida responde a uma pergunta melhor do que uma resposta de publicação bem-sucedida: um consumidor limpo consegue localizar e obter a versão nomeada? Se o pacote usa exports, declarações de tipo, um executável de linha de comando ou um script postinstall, teste também o entry point público relevante nesse diretório novo. O fato de o registro ter armazenado o pacote não significa que o consumidor consiga usá-lo.

Não exclua o pacote de teste apenas para deixar a conta organizada. Mantenha um registro de auditoria de acordo com as regras normais do registro ou use a descontinuação quando for apropriado. Um teste de lançamento deve ensinar ao agente e à equipe como é um registro real após a publicação. Apagá-lo ensina aos dois que o histórico de publicação é descartável.

O conteúdo do pacote e a aceitação pelo registro são testes separados

Evite autoridade de publicação em segundo plano
A autorização por sessão cobre uma execução conhecida do agente, enquanto a chave do registro ainda pode exigir aprovação a cada uso.

As equipes costumam chamar npm pack de teste de lançamento. Ele é um teste do conteúdo do pacote. Depois, chamam uma publicação npm publish bem-sucedida de teste de lançamento. Ela é um teste de aceitação pelo registro. Um não substitui o outro, e tratar qualquer um deles como suficiente cria lacunas previsíveis.

O teste do conteúdo pergunta se o tarball contém os arquivos e metadados pretendidos. Ele encontra acidentes com .npmignore, um array files amplo demais, um artefato compilado ausente e uma divergência de versão entre o código-fonte e o manifesto. Grande parte desse trabalho pode ser feita sem acesso à rede.

O teste de aceitação pelo registro pergunta se o registro reconhece a credencial e o namespace, aceita a versão, armazena o tarball, registra as informações de integridade e o disponibiliza para um consumidor. Ele encontra um host de registro incorreto, uma autorização ausente da organização, um erro de configuração de publicação e um caminho de autorização diferente do desenvolvimento local.

O teste do consumidor faz uma terceira pergunta: um projeto limpo consegue instalar a versão exata e executá-la da forma como os usuários farão? É nesse ponto que aparecem dependências peer ausentes, entradas exports incorretas e dependências acidentais de arquivos do workspace.

Mantenha os testes nessa ordem. Publicar primeiro porque «sempre podemos retirar a publicação» é falta de disciplina. Retirar a publicação não é um botão de reversão. Alguns usuários, espelhos, caches e registros de compilação podem manter o pacote, enquanto outros consumidores perdem a capacidade de localizá-lo. Uma versão equivocada pode ser recuperável do ponto de vista operacional, mas ainda cria trabalho e confusão que a inspeção local do tarball teria evitado.

A aprovação deve acompanhar a consequência da chamada

A aprovação por sessão é útil para uma execução que faz muitas consultas esperadas. Pedir que alguém aprove cada consulta de metadados faz essa pessoa clicar sem ler. Isso é fadiga de aprovação e reduz a atenção dada ao prompt realmente importante.

Mas a publicação e a exclusão devem interromper esse fluxo. Cada uma altera o estado externo de uma forma que um download rotineiro de dependência não altera. Exija uma confirmação específica para uma nova versão de pacote, outra para uma alteração de dist-tag e outra para cada ação destrutiva. Se o agente propõe duas publicações, mostre duas solicitações. A aprovação em lote esconde a versão exata que o revisor precisa examinar.

O prompt de cada chamada deve conter informação suficiente para que a ação seja rejeitada pelo motivo correto:

  • O host do registro e o escopo ou proprietário do pacote.
  • A operação: publicar, mover uma tag, descontinuar, retirar a publicação ou excluir.
  • A versão exata envolvida e a transição de tag solicitada.
  • O processo do agente que fez a solicitação, para que o revisor possa rejeitar um chamador inesperado.
  • Um motivo curto extraído do plano de lançamento, não da saída livre de uma ferramenta.

Não faça uma pessoa interpretar um cabeçalho de autorização ou comparar hashes opacos no momento da decisão. Esses são detalhes de auditoria. A decisão em tempo real deve mostrar a consequência da ação em linguagem simples, enquanto o sistema preserva a solicitação subjacente para análise posterior.

O controle de chave por chamada do Sallyport se encaixa bem no limite de publicação: a credencial do registro pode exigir aprovação sempre que for usada, enquanto o agente continua realizando o trabalho comum sob uma decisão de sessão separada. Isso não substitui a revisão do conteúdo do pacote. Impede que uma credencial de lançamento se torne autoridade permanente depois de um único clique anterior.

Trate as tags como uma alteração no roteamento dos consumidores

Rastreie a execução do agente
Sessões e chamadas individuais são registradas em diários separados, mantendo rastreável toda a atividade de publicação.

Uma dist-tag pode tornar insegura uma versão correta para os seus usuários. Em registros compatíveis com npm, uma instalação sem versão explícita normalmente segue a tag latest. Mover essa tag altera o que novas instalações recebem, embora o tarball já publicado permaneça igual.

Mantenha a publicação e a movimentação de tags como solicitações separadas. Publique primeiro uma versão candidata e depois recupere-a pela versão exata em um projeto de teste limpo. Só depois dessa verificação alguém deve decidir se latest será movida. Isso cria uma pausa útil: os bytes ficam visíveis sob uma versão imutável, e a decisão de roteamento ainda não aconteceu.

Os comandos deixam a diferença clara:

npm publish --tag candidate
npm view @acme/widget dist-tags --json
npm dist-tag add @acme/[email protected] latest

O primeiro comando cria uma versão e atribui a ela uma rota de candidata. O último altera a rota seguida por muitos usuários. Um script de lançamento que esconde os dois dentro de uma única função auxiliar elimina o ponto mais útil para o julgamento humano.

Não deixe um agente corrigir um erro de tag por tentativa. Se latest apontar para a versão errada, o agente deve informar o mapa atual de tags, a versão pretendida e a correção proposta. Um revisor deve confirmá-la. Este é um daqueles casos em que o custo de um clique extra é pequeno diante do custo de enviar um pacote errado para cada nova instalação.

Mantenha registros de auditoria úteis depois do incidente

Saiba qual processo fez a solicitação
A primeira aprovação para um novo processo de agente mostra sua autoridade de assinatura de código.

O histórico de comandos, sozinho, não informa quem autorizou uma alteração no registro, qual execução do agente a iniciou ou se alguém editou o log depois. As operações de lançamento precisam de um registro que conecte a solicitação, a aprovação, o resultado da execução e os metadados devolvidos pelo registro.

Registre o nome do pacote, a versão, o host do registro, o tipo de operação, o status final e uma referência à inspeção do artefato produzida antes da ação. Não registre tokens, cabeçalhos de autorização ou arquivos de configuração brutos que possam conter credenciais. Um bom registro de auditoria permite que um mantenedor responda a uma pergunta prática meses depois: publicamos esta versão, movemos uma tag ou apenas tentamos fazer isso?

A evidência contra adulteração importa porque os logs de lançamento muitas vezes só se tornam provas depois que algo dá errado. O Sallyport mantém eventos de sessão e chamadas individuais em diários separados, projetados a partir de um log de auditoria criptografado e encadeado por hash, e sp audit verify consegue verificar essa cadeia offline sem uma chave do cofre. Isso é mais forte do que confiar em um arquivo de texto mutável no repositório.

Os logs não tornam segura uma ação perigosa. Eles permitem reconstruir o caminho quando um prompt de aprovação foi mal interpretado, o destino do registro estava errado ou o processo de lançamento fez algo inesperado. Combine o log com uma forma imediata de revogar uma sessão de agente em execução. Quando uma publicação começa a se comportar de maneira estranha, interromper a próxima chamada vale mais do que escrever um post-mortem perfeito depois.

Inclua o teste descartável no contrato de lançamento

O teste de publicação descartável deve ser uma verificação planejada do caminho de lançamento, não uma improvisação depois que uma publicação de produção falha. Defina quando ele será executado: quando houver mudança na integração com o registro, no tratamento de credenciais ou na configuração do gerenciador de pacotes, ou antes de conceder acesso de publicação a um novo fluxo de agente.

Mantenha sua autoridade mais limitada que a autoridade de produção sempre que possível, mas não torne o teste tão artificial que ele deixe de encontrar o modo real de falha. Teste a mesma classe de registro, o mesmo intermediário de solicitações, o mesmo padrão de armazenamento de credenciais e a mesma verificação de instalação limpa. Se a publicação de produção exige aprovação humana, o teste também deve exigir. Caso contrário, você testou outro sistema.

A primeira ação útil é remover as credenciais de gravação do registro das variáveis de ambiente visíveis ao agente e, em seguida, executar um pacote descartável pelo caminho controlado exato em que pretende confiar. Leia a lista de arquivos do pacote antes da aprovação. Inspecione a versão exata depois da publicação. Deixe a exclusão como uma ação aprovada separadamente, porque uma conta de teste organizada nunca vale um buraco acidental no limite de lançamento.

FAQ

Por que os agentes de IA devem ter permissões diferentes para baixar e publicar pacotes?

Não. Baixar um pacote público expõe uma escolha de dependência, enquanto publicar cria uma versão que usuários posteriores podem instalar. Excluir, retirar a publicação ou alterar dist-tags pode afetar quem já depende daquele nome, por isso essas ações precisam de limites de aprovação separados.

O que é um pacote descartável para testes de publicação?

Use um nome de pacote descartável em uma conta ou escopo que você controle, publique uma primeira versão inofensiva, instale-a em um diretório novo e marque-a como obsoleta se o registro oferecer essa opção. Não use um nome parecido com um produto real ou com o namespace de outro mantenedor.

Um agente de IA deve poder retirar um pacote do registro?

Para um pacote que usuários possam instalar, trate a exclusão como uma ação destrutiva separada. Uma nova publicação pode ser aprovada a cada versão, mas retirar a publicação e excluir devem pedir nova aprovação todas as vezes, mesmo que a mesma sessão do agente ainda esteja ativa.

As dist-tags são tão arriscadas quanto publicar uma nova versão?

Uma tag é um dado de roteamento mutável, não um substituto para uma versão imutável. Permita que o agente consulte tags livremente, quando apropriado, mas exija aprovação explícita antes de mover latest, criar uma tag de lançamento ou remover uma tag.

Posso testar uma publicação npm sem mexer no meu pacote de produção?

Sim, desde que o pacote de teste use o mesmo registro, o mesmo caminho de autenticação, as mesmas configurações do repositório e o mesmo comando de instalação da publicação real. Um teste com um tarball local verifica o empacotamento, mas não prova que a autorização no registro ou a recuperação após a publicação funcionam.

O que um teste de publicação em um registro descartável realmente comprova?

Ele prova apenas que o registro aceitou o artefato e que um consumidor limpo consegue localizar a versão pretendida. Não prova que o pacote funciona corretamente, que não contém uma alteração maliciosa em uma dependência ou que uma mudança posterior de tag será segura.

É seguro colocar um token de registro de pacotes no ambiente de um agente de IA?

Não dê ao agente um token amplo do registro no ambiente dele. Mantenha a credencial fora do processo do agente, vincule-a a uma ação explícita de publicação e exija uma decisão humana para o limite de lançamento.

Uma única aprovação deve cobrir ações de publicação e exclusão?

Em geral, não. Uma solicitação para publicar um pacote nomeado merece uma aprovação direta, e uma solicitação para excluir ou retirar a publicação merece outra. Reutilizar a aprovação para consultas rotineiras faz sentido. Reutilizá-la para gravações irreversíveis no registro é como um fluxo conveniente se transforma em incidente.

O que devo verificar antes de um agente publicar um pacote?

Verifique a lista de arquivos empacotados, a versão exata, o destino do registro, o nome do pacote e o estado atual das tags antes da publicação. Depois, instale a versão exata em um projeto temporário limpo e confira o que o registro realmente forneceu.

O que deve acontecer quando a publicação de um pacote por um agente de IA falha?

O agente deve parar no comando que falhou e retornar a resposta do registro, o nome pretendido do pacote, a versão e o comando que tentou executar. Uma pessoa deve decidir se o problema é uma versão incorreta, uma permissão ausente, um registro inesperado ou uma solicitação que não deve prosseguir.

Sallyport

O Sallyport executa chamadas de API e comandos SSH pelo seu agente de IA. As chaves ficam em um cofre local no seu Mac; você aprova cada execução e toda ação vai para um registro selado.

© 2026 Sallyport · Código aberto sob Apache-2.0 · Oleg Sotnikov