7 min de lectura

Publicar paquetes con agentes de IA sin llenar todo de tokens de publicación

La publicación de paquetes por agentes de IA necesita controles separados para descargas, versiones, etiquetas y eliminación. Prueba toda la ruta de publicación con un paquete desechable.

Publicar paquetes con agentes de IA sin llenar todo de tokens de publicación

Un agente de programación con IA debería poder instalar dependencias sin tener autoridad para publicar, retirar, eliminar ni cambiar las etiquetas de los paquetes. Esas operaciones parecen contiguas en la línea de comandos, pero sus consecuencias son completamente distintas. Tratarlo todo como un solo permiso convierte el trabajo habitual de desarrollo en autoridad de publicación.

He visto cómo las credenciales de publicación se extendían porque un equipo quería que un agente ejecutara un comando de instalación inofensivo. El token terminaba en el entorno del shell, en un archivo de configuración o en la salida de un comando, donde cualquier herramienta de esa ejecución podía reutilizarlo. El fallo posterior rara vez comienza con un ataque espectacular. Empieza cuando un agente usa npm publish contra el registro equivocado, mueve latest antes de que alguien haya revisado el tarball o intenta retirar un paquete porque interpreta demasiado literalmente una solicitud de limpieza de pruebas.

Leer un registro no concede autoridad de publicación

La instalación y la publicación de paquetes usan la misma familia de endpoints del registro, pero responden a preguntas de confianza diferentes. Una descarga pregunta: «¿Puede este proceso obtener un artefacto?». Una publicación pregunta: «¿Puede este proceso crear una versión pública o visible para la organización con este nombre?». Una eliminación o retirada pregunta: «¿Puede este proceso alterar el historial y la disponibilidad de una versión que otros procesos de compilación quizá ya consuman?»

No juntes esas preguntas en una sola credencial porque el cliente del registro haga que parezcan similares. Un gestor de paquetes puede leer la configuración del mismo archivo .npmrc para npm ci, npm publish, npm dist-tag add y npm unpublish. Esa disposición del archivo es una comodidad del cliente, no un diseño de permisos.

Para un agente, separa como mínimo estas categorías de acciones del registro:

  • Lectura: consulta de metadatos, descarga del tarball, verificación de integridad e instalación de dependencias.
  • Publicación: creación de una nueva versión inmutable con un nombre de paquete aprobado.
  • Enrutamiento: cambios en canales mutables como latest, las etiquetas de versiones preliminares o la configuración de acceso del registro.
  • Destructivas: retirada, eliminación del paquete cuando el registro lo permita y eliminación de una etiqueta de publicación.

La diferencia entre publicar y enrutar importa más de lo que admiten muchos scripts de publicación. Un paquete versionado puede estar bien, pero asignarle latest hace que los nuevos consumidores lo reciban. En cambio, una versión preliminar publicada con una etiqueta específica puede tener poco riesgo si los usuarios deben elegir esa etiqueta de forma explícita. Los bytes del paquete y el camino que siguen los consumidores hasta ellos son controles independientes.

La eliminación merece su propia categoría aunque el registro la limite. Las reglas varían y algunas operaciones llamadas «eliminar» solo ocultan un artefacto o lo marcan como no disponible. Eso no vuelve inofensiva la acción. Puede romper instalaciones reproducibles, investigaciones de incidentes y equipos que fijaron la versión retirada. Un agente nunca debe deducir que la limpieza es segura solo porque la versión se publicó hace unos minutos.

Los tokens de publicación amplios fallan de formas habituales

Un token del registro en el entorno de un agente es una concesión de autorización con un formato de archivo cómodo. No es una instrucción con alcance limitado. Si el agente puede leer el entorno o un archivo de configuración, una inyección de instrucciones en una dependencia, una plantilla de issue, un registro de compilación o un texto copiado de la terminal tiene un camino hasta la credencial.

La recomendación habitual es usar el alcance más reducido que ofrezca el registro. Es un buen consejo, pero está incompleto. Un token limitado a publicar todavía puede publicar una versión no deseada, en un paquete equivocado al que tenga acceso su cuenta o en un endpoint seleccionado mediante una configuración alterada. El alcance reduce el impacto potencial. No establece la intención de cada publicación.

Un fallo que he tenido que solucionar más de una vez sigue este patrón:

  1. Un equipo da a un agente un token del registro para que pueda ejecutar comprobaciones de publicación.
  2. La configuración del proyecto apunta al registro de producción porque esa es la configuración de los equipos de los desarrolladores.
  3. El agente necesita validar el contenido del paquete y ejecuta npm pack, lo cual es inofensivo.
  4. Una instrucción posterior dice «probar la publicación» y el agente ejecuta npm publish en lugar de publicar en un destino aislado.
  5. El comando funciona porque el token y el nombre del paquete son válidos. El equipo solo se da cuenta cuando la automatización o los usuarios ven la nueva versión.

En esa cadena no hace falta ningún atacante. El diseño entregó una credencial a un sistema de planificación y confió en que respetaría un límite que el entorno operativo no imponía.

Mantén la credencial fuera del proceso del agente. Deja que una pasarela de acciones independiente la guarde y ejecute una solicitud HTTP o un comando específico después de comprobar el destino solicitado y obtener la aprobación humana necesaria. Sallyport sigue ese patrón: el agente recibe el resultado de una acción autorizada, nunca el token del registro.

Ese diseño también exige buenas definiciones de acciones. Una pasarela que aprueba «cualquier solicitud al registro registry.example» solo ha trasladado el problema del token amplio detrás de un botón. La solicitud debe mostrar suficiente información para que la persona que aprueba pueda distinguir una descarga de un tarball de una publicación de versión, y una publicación de paquete de una retirada.

Haz que la solicitud de publicación se pueda inspeccionar antes de ejecutarla

Una persona no puede aprobar una instrucción vaga como «publica el paquete». La pantalla de aprobación debería mostrar el identificador del paquete, la versión exacta, el host del registro, la operación y cualquier cambio de etiqueta. Si el agente no puede proporcionar esos campos, todavía no ha preparado una solicitud de publicación.

En un registro compatible con npm, separa el trabajo en una fase de inspección del artefacto y otra de modificación del registro. La fase de inspección puede ejecutarse sin autoridad de publicación:

npm ci
npm test
npm pack --json

npm pack --json devuelve información estructurada sobre el tarball que crearía. Los datos útiles tienen una forma parecida a esta:

[
  {
    "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}
    ]
  }
]

Inspecciona la lista de archivos, no solo el código de salida del comando. Yo busco directorios de código fuente que debían permanecer privados, archivos de prueba con credenciales, un directorio de salida compilado que falte y metadatos del paquete con un punto de entrada incorrecto. Con npm pack esos errores todavía son baratos.

Después, recopila por separado el estado del registro. La documentación de la CLI de npm describe npm view como una forma de inspeccionar metadatos de paquetes en el registro. Úsalo para hacer preguntas concretas, en lugar de aceptar un volcado amplio de datos:

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

El primer comando indica qué versión existe y a dónde apuntan las etiquetas. El segundo resulta útil después de publicar, porque dist contiene la dirección del tarball y los datos de integridad registrados por el registro. Un flujo de publicación debería conservar esta salida en su registro de publicación, sin secretos, porque recoge lo que el registro aceptó y no solo lo que el directorio local pretendía enviar.

Construye la solicitud de aprobación a partir de estos datos. Una buena solicitud dice: publica @acme/[email protected] en registry.example, sin mover ninguna etiqueta. Una mala solicitud dice: ejecuta npm publish. La primera permite detectar un error de espacio de nombres. La segunda obliga a la persona que revisa a reconstruir la intención a partir de un comando en el que quizá no confíe.

Un paquete desechable demuestra la ruta del registro

Un paquete desechable es la forma más segura de probar el recorrido que convierte un tarball preparado en una versión recuperable del registro. No demuestra que tu paquete de producción esté listo. Demuestra que la autenticación, la selección del registro, la mecánica de publicación y la instalación limpia funcionan juntas bajo controles parecidos a los de la publicación real.

Usa un nombre de paquete dentro de un espacio de nombres que controles y haz que sea claramente temporal. No imites el nombre de un paquete popular ni uses un nombre que pueda convertirse accidentalmente en un producto real. Incluye un módulo pequeño e inerte. Su función es publicarse e instalarse, no demostrar el comportamiento de una aplicación.

Este package.json mínimo mantiene la prueba clara:

{
  "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"
  }
}

Elige una configuración de acceso que coincida con el tipo real de tu paquete. No copies restricted sin más si tu paquete real es público, y no hagas público un paquete de prueba desechable solo porque parezca más realista. El objetivo es probar el mismo límite de autorización y de audiencia prevista. Si necesitas probar la publicación pública, usa un nombre público explícitamente temporal y verifica las reglas de conservación y retirada del registro antes de empezar.

Ejecuta la prueba en un directorio nuevo para que los metadatos en caché y un espacio de trabajo existente no hagan que el resultado parezca mejor de lo que es:

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'))"

Un npm install correcto responde a una pregunta más útil que una respuesta de publicación correcta: ¿puede un consumidor limpio resolver y recuperar la versión indicada? Si tu paquete usa exports, declaraciones de tipos, un binario de línea de comandos o un script postinstall, prueba también el punto de entrada público correspondiente en este directorio nuevo. Que el registro haya almacenado el paquete no significa que el consumidor pueda usarlo.

No elimines el paquete de prueba solo para dejar la cuenta ordenada. Conserva un rastro de auditoría según las reglas habituales del registro o usa la obsolescencia cuando corresponda. Una prueba de publicación debería enseñar al agente y al equipo cómo es un registro real posterior a la publicación. Borrarlo les enseña que el historial de publicaciones se puede desechar.

El contenido del paquete y la aceptación del registro son pruebas distintas

Identifica qué proceso lo solicitó
La primera aprobación para un proceso de agente nuevo muestra su autoridad de firma de código.

Los equipos suelen llamar a npm pack una prueba de publicación. Es una prueba del contenido del paquete. Después llaman prueba de publicación a una respuesta correcta de npm publish. Es una prueba de aceptación del registro. Ninguna sustituye a la otra, y tratar cualquiera de ellas como una comprobación completa crea carencias previsibles.

La prueba del contenido del paquete pregunta si el tarball contiene los archivos y metadatos previstos. Detecta accidentes con .npmignore, un array files demasiado amplio, un artefacto compilado ausente y una diferencia de versión entre el código fuente y el manifiesto. Gran parte de este trabajo puede hacerse sin acceso a la red.

La prueba de aceptación del registro pregunta si el registro reconoce la credencial y el espacio de nombres, acepta la versión, almacena el tarball, registra los datos de integridad y lo pone a disposición de un consumidor. Detecta un host de registro incorrecto, la falta de permisos de una organización, un error de configuración de publicación y una ruta de autorización distinta de la del desarrollo local.

La prueba del consumidor plantea una tercera pregunta: ¿puede un proyecto limpio instalar la versión exacta e invocarla de la forma en que lo harán los usuarios? Aquí aparecen las dependencias peer ausentes, las entradas exports incorrectas y la dependencia accidental de archivos del espacio de trabajo.

Mantén ese orden. Publicar primero porque «siempre podemos retirarlo» es una mala práctica. Retirar un paquete no es un botón de deshacer. Algunos usuarios, espejos, cachés y registros de compilación pueden conservarlo, mientras que otros consumidores pierden la capacidad de resolverlo. Una versión equivocada puede recuperarse desde el punto de vista operativo, pero aun así crea trabajo y confusión que una inspección local del tarball habría evitado.

La aprobación debe seguir las consecuencias de la llamada

La aprobación por sesión resulta útil para una ejecución que hace muchas lecturas esperadas. Pedir a alguien que apruebe cada consulta de metadatos le enseña a hacer clic sin leer. Eso provoca fatiga de aprobación y hace menos probable que preste atención a la solicitud importante.

Pero la publicación y la eliminación deben interrumpir ese flujo. Cada una cambia el estado externo de una forma que una descarga rutinaria de dependencias no cambia. Exige una confirmación distinta para una versión nueva, otra para un cambio de etiqueta dist y otra para cada acción destructiva. Si el agente propone publicar dos paquetes, muestra dos solicitudes. Una aprobación conjunta oculta la versión exacta que la persona debe revisar.

La solicitud por llamada debe incluir información suficiente para rechazar una acción por el motivo correcto:

  • El host del registro y el ámbito o propietario del paquete.
  • La operación: publicar, mover una etiqueta, marcar como obsoleto, retirar o eliminar.
  • La versión exacta implicada y la transición de etiquetas solicitada.
  • El proceso del agente que lo solicitó, para que la persona pueda rechazar un origen inesperado.
  • Un motivo breve tomado del plan de publicación, no de una salida de herramienta escrita libremente.

No obligues a una persona a interpretar una cabecera de autorización ni a comparar hashes opacos en ese momento. Son detalles de auditoría. La decisión inmediata debe mostrar la consecuencia de la acción en lenguaje claro, mientras el sistema conserva la solicitud subyacente para revisarla después.

El control de claves por llamada de Sallyport encaja bien con el límite de publicación: la credencial del registro puede exigir aprobación cada vez que se usa, mientras el agente realiza el trabajo habitual bajo una decisión de sesión independiente. Eso no sustituye la revisión del contenido del paquete. Impide que una credencial de publicación se convierta en autoridad permanente después de un clic anterior.

Trata las etiquetas como un cambio de enrutamiento para los consumidores

Enruta las publicaciones mediante Sallyport
Los agentes se conectan mediante sp mcp y Sallyport realiza la llamada HTTP al registro sin exponer la credencial.

Una etiqueta dist puede hacer que una versión correcta resulte insegura para tus usuarios. En registros compatibles con npm, una instalación sin una versión explícita suele seguir la etiqueta latest. Mover esa etiqueta cambia lo que reciben las nuevas instalaciones, aunque el tarball ya publicado no cambie.

Mantén la publicación y el movimiento de etiquetas como solicitudes separadas. Publica primero una versión candidata y después recupérala por su versión exacta en un proyecto de prueba limpio. Solo después de esa comprobación debería alguien decidir si mueve latest. Esto crea una pausa útil: los bytes están visibles bajo una versión inmutable y la decisión de enrutamiento todavía no se ha tomado.

Los comandos muestran claramente la diferencia:

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

El primer comando crea una versión y le asigna una ruta de candidata. El último cambia la ruta que siguen muchos usuarios. Un script de publicación que oculta ambas operaciones dentro de una sola función auxiliar elimina el momento más útil para el criterio humano.

No permitas que un agente corrija una etiqueta equivocada haciendo suposiciones. Si latest apunta a la versión incorrecta, el agente debe informar del mapa actual de etiquetas, la versión prevista y la corrección propuesta. Una persona debe confirmarla. En este caso, el coste de un clic adicional es mínimo comparado con el de enviar un paquete incorrecto a cada nueva instalación.

Mantén útiles los registros de auditoría después del incidente

Detén una ejecución de publicación incorrecta
Revoca al instante una sesión del agente cuando un flujo de publicación empieza a realizar llamadas inesperadas al registro.

El historial de comandos por sí solo no responde quién autorizó una modificación del registro, qué ejecución del agente la emitió ni si alguien editó el registro después. Las operaciones de publicación necesitan un registro que una la solicitud, la aprobación, el resultado de la ejecución y los metadatos devueltos por el registro.

Registra el nombre del paquete, la versión, el host del registro, el tipo de operación, el estado final y una referencia a la inspección del artefacto producida antes de la acción. No registres tokens, cabeceras de autorización ni archivos de configuración sin procesar que puedan contener credenciales. Un buen registro de auditoría permite responder meses después a una pregunta práctica: ¿publicamos esta versión, movimos una etiqueta o solo lo intentamos?

La evidencia contra manipulaciones importa porque los registros de publicación a menudo solo se convierten en pruebas cuando algo sale mal. Sallyport conserva los eventos de sesión y las llamadas individuales en diarios separados, proyectados desde un registro de auditoría cifrado y encadenado mediante hashes, y sp audit verify puede verificar esa cadena sin conexión y sin una clave de la bóveda. Es más sólido que confiar en un archivo de texto mutable del repositorio.

Los registros no vuelven segura una acción peligrosa. Permiten reconstruir el recorrido cuando una solicitud de aprobación se entendió mal, el destino del registro era incorrecto o el proceso de publicación hizo algo que nadie esperaba. Combina el registro con una forma inmediata de revocar la sesión de un agente en ejecución. Cuando una publicación empieza a comportarse de forma extraña, detener la siguiente llamada vale más que redactar después un informe perfecto.

Incluye la prueba desechable en el contrato de publicación

La prueba de publicación desechable debería ser una comprobación planificada de la ruta de publicación, no una improvisación después de que falle una publicación de producción. Define cuándo se ejecuta: cuando cambia una integración con el registro, cuando cambia el manejo de credenciales, cuando adoptas una nueva configuración del gestor de paquetes o antes de conceder acceso de publicación a un nuevo flujo de trabajo del agente.

Mantén su autoridad más limitada que la de producción cuando sea posible, pero no la hagas tan artificial que no detecte el fallo real. Prueba la misma clase de registro, el mismo intermediario de solicitudes, el mismo patrón de almacenamiento de credenciales y la misma verificación de instalación limpia. Si la publicación de producción requiere aprobación humana, la prueba también debe requerirla. De lo contrario, habrás probado un sistema diferente.

La primera acción útil es retirar las credenciales de escritura del registro de las variables de entorno visibles para el agente y después pasar un paquete desechable por la ruta controlada exacta en la que pretendes confiar. Lee la lista de archivos del paquete antes de aprobar. Inspecciona la versión exacta después de publicar. Deja la eliminación como una acción aprobada por separado, porque una cuenta de prueba ordenada nunca merece abrir accidentalmente un agujero en el límite de publicación.

FAQ

¿Por qué las descargas y las publicaciones de paquetes deberían usar permisos distintos para los agentes de IA?

No. Descargar un paquete público expone una elección de dependencia, mientras que publicar crea una versión que otros usuarios pueden instalar. Eliminar, retirar o cambiar las etiquetas dist puede afectar a quienes ya dependen de ese nombre, así que cada acción necesita un límite de aprobación separado.

¿Qué es un paquete desechable para probar publicaciones?

Usa un nombre de paquete desechable bajo una cuenta o un ámbito que controles, publica una primera versión inofensiva, instálala desde un directorio nuevo y márcala como obsoleta si el registro admite esa acción. No uses un nombre parecido al de un producto real ni al espacio de nombres de otro mantenedor.

¿Debería permitirse que un agente de IA retire un paquete?

Para un paquete que los usuarios puedan instalar, trata la eliminación como una acción destructiva independiente. Una publicación nueva puede aprobarse en cada versión, pero retirar o eliminar un paquete debe volver a pedir aprobación cada vez, aunque la misma sesión del agente siga activa.

¿Las etiquetas dist son tan arriesgadas como publicar una versión nueva?

Una etiqueta es información de enrutamiento mutable, no un sustituto de una versión inmutable. Puedes permitir que un agente inspeccione las etiquetas si corresponde, pero exige aprobación explícita antes de mover latest, crear una etiqueta de publicación o eliminar una etiqueta.

¿Puedo probar una publicación de npm sin tocar mi paquete de producción?

Sí, siempre que el paquete de prueba use el mismo registro, la misma ruta de autenticación, la misma configuración del repositorio y el mismo comando de instalación que la publicación real. Una prueba de un tarball local comprueba el empaquetado, pero no demuestra que funcionen la autorización del registro ni la recuperación posterior a la publicación.

¿Qué demuestra realmente una prueba de publicación en un registro desechable?

Solo demuestra que el registro aceptó el artefacto y que un consumidor limpio puede resolver la versión indicada. No demuestra que el paquete funcione correctamente, que no contenga cambios maliciosos en sus dependencias ni que un cambio posterior de etiqueta sea seguro.

¿Es seguro poner un token del registro de paquetes en el entorno de un agente de IA?

No des al agente un token amplio del registro en su entorno. Mantén la credencial fuera del proceso del agente, vincúlala a una acción de publicación explícita y exige una decisión humana para el límite de publicación.

¿Debería una sola aprobación cubrir las acciones de publicación y eliminación?

Por lo general, no. Una solicitud para publicar un paquete específico merece una aprobación directa y una solicitud para eliminarlo o retirarlo merece otra. Reutilizar la aprobación para lecturas rutinarias tiene sentido; reutilizarla para escrituras irreversibles en el registro es la forma en que un flujo cómodo se convierte en un incidente.

¿Qué debo verificar antes de que un agente publique un paquete?

Comprueba la lista de archivos empaquetados, la versión exacta, el destino del registro, el nombre del paquete y el estado actual de las etiquetas antes de publicar. Después, instala la versión exacta en un proyecto temporal limpio e inspecciona lo que el registro realmente sirvió.

¿Qué debería ocurrir si falla la publicación de un paquete por parte de un agente de IA?

El agente debe detenerse en el comando que falló y devolver la respuesta del registro, el nombre previsto del paquete, la versión y el comando que intentó ejecutar. Una persona debe decidir si el problema es una versión incorrecta, un permiso ausente, un registro inesperado o una solicitud que no debe continuar.

Sallyport

Sallyport ejecuta llamadas de API y comandos SSH por tu agente de IA. Las claves se quedan en una bóveda local de tu Mac; tú apruebas cada ejecución y cada acción queda en un registro sellado.

© 2026 Sallyport · Código abierto bajo Apache-2.0 · Oleg Sotnikov