npm разрешил создавать новые пакеты через staged publishing — и это важнее, чем кажется

Теперь CI может создать npm-пакет без ручной первой публикации. Но staged publishing не делает выпуск полностью автоматическим: первую версию должен одобрить сопровождающий, а безопасность по-прежнему зависит от прав и настроек публикации.

Интерфейс npm с первой версией нового пакета в очереди staged publishing и действием для её продвижения
Интерфейс npm с первой версией нового пакета в очереди staged publishing и действием для её продвижения
Изображение из исходного материала

Главное изменение в npm staged publishing — автоматизированный процесс теперь может не только отправлять новую версию уже существующего пакета на отложенную проверку, но и создавать сам пакет. Первая публикация при этом не становится доступной для установки автоматически: сопровождающий должен продвинуть её из staged-очереди. Это полезный компромисс между удобством CI и контролем над моментом, когда новая зависимость появляется в реестре.

GitHub сообщает, что новая возможность работает для публичных пакетов — как с областью имён, так и без неё — и для приватных пакетов с областью имён. Создать пакет можно через локальную сессию или детализированный токен доступа, в том числе токен, предназначенный только для staged-публикации. После создания доступны настройки пакета и конфигурация trusted publishing. Здесь важно не смешивать три разных действия: создать запись о пакете, отправить его первую версию на проверку и сделать версию доступной потребителям.

Первая публикация больше не обязана быть ручной

У многих автоматизированных процессов релиза есть неприметный ручной шов: CI умеет публиковать очередную версию, но для этого пакет сначала должен уже существовать в реестре. Его создают отдельной ручной командой или действием, а затем настраивают обычный цикл выпусков. Такой старт неудобен и может оказаться особенно хрупким, если проект ожидает полностью воспроизводимый выпуск из репозитория.

Теперь, согласно описанию GitHub Changelog, командой `npm stage publish` можно создать новый пакет прямо из автоматизированного рабочего процесса — без ручной первой публикации. Но слово «создать» здесь не означает «немедленно выпустить для всех». Первая версия помещается в очередь staged-публикаций и должна быть продвинута сопровождающим, прежде чем её можно будет установить.

Это разграничение — основа нововведения. CI подготавливает артефакт и инициирует публикационный процесс. Человек сохраняет право решить, когда конкретная версия станет доступна. Для команды, которая хочет убрать ручное создание пакета, но не готова делегировать роботу публичный выпуск, это значимая граница ответственности.

Что именно меняется в цепочке релиза

В качестве полезной точки сравнения можно взять `semantic-release`. Этот проект автоматизирует последовательность действий после успешной сборки: анализирует сообщения коммитов, определяет следующий номер версии, формирует заметки и публикует пакет. В описании проекта отдельно подчёркивается работа в CI после изменений в релизной ветке, то есть релиз становится следствием заданных правил, а не отдельного ручного решения о номере версии.

Новая возможность npm закрывает другой участок того же пути — начальную точку жизненного цикла пакета. Если раньше для такого сценария требовалось заранее создать пакет, теперь его можно впервые завести из рабочего процесса, который готовит публикацию. Это не означает, что `npm stage publish` заменяет `semantic-release`: один инструмент отвечает за автоматизацию версии и выпуска, другой — за staged-публикацию в npm. Их роли могут сочетаться, но детали интеграции зависят от конкретного рабочего процесса.

Практически новый путь выглядит так: CI собирает пакет, передаёт его в npm через staged-команду, сопровождающий проверяет запись и продвигает версию. После этого команда может управлять настройками пакета и настраивать trusted publishing. Подтверждение первой версии — не косметический шаг интерфейса, а точка, в которой автоматический конвейер встречается с человеческим контролем.

Почему это не просто ещё одна команда публикации

Обычная публикация и staged publishing отличаются прежде всего последствиями ошибки. Если публикация сразу делает версию доступной для установки, неверная конфигурация или ошибочный артефакт могут быстро попасть к потребителям. Отложенная публикация вставляет перед доступностью версии этап подтверждения. Новая возможность распространяет этот механизм на создание пакета, а не только на выпуск очередной версии уже существующего проекта.

Однако наличие этапа подтверждения само по себе не гарантирует проверку содержимого. Оно лишь создаёт возможность остановиться до того, как версия станет доступной. Сопровождающий может проверить, что пакет создан под ожидаемым именем, настройки выглядят корректно и артефакт соответствует релизу. Если команда просто механически нажимает «продвинуть», контроль останется формальным.

Здесь полезно разделить две модели доверия. Staged-очередь регулирует переход версии к доступности в реестре. Аутентификация определяет, кто или какой рабочий процесс вообще вправе инициировать публикацию. Уменьшение числа ручных шагов не отменяет необходимость ограничить полномочия CI и защитить его секреты.

Токен для staged-публикации — не универсальное средство защиты

GitHub указывает, что новую возможность можно использовать с локальной сессией или детализированным токеном, включая токен, предназначенный только для staged-публикаций. Специализированный токен позволяет не выдавать автоматизированному процессу больше полномочий, чем требуется для постановки версии в очередь. Но его конкретные ограничения следует оценивать по действующим настройкам npm: из самого объявления нельзя вывести все свойства токена или гарантировать, что он полностью исключает злоупотребление.

Отдельный вариант — trusted publishing. Документация npm описывает его как аутентификацию CI/CD через OIDC, при которой пакет доверяет определённому рабочему процессу, а не полагается на долгоживущий токен публикации. По описанию документации, доверенная публикация поддерживает короткоживущие удостоверения и требует npm CLI версии 11.5.1 или новее и Node.js версии 22.14.0 или новее. Это условия для trusted publishing, а не обязательно минимальные требования самой команды `npm stage publish`.

Такой способ аутентификации сокращает риск, связанный с утечкой и ротацией постоянного токена, но не превращает CI в безопасную среду автоматически. Если злоумышленник способен изменить разрешённый рабочий процесс или его зависимости, краткоживущее удостоверение тоже может быть использовано в рамках тех полномочий, которые выданы этому процессу. Принцип остаётся прежним: ограничивать права, защищать ветки и проверять, какой именно workflow получил доверие.

Почему осторожность оправданна

Опасения вокруг автоматической публикации npm не теоретические. В предоставленных материалах Microsoft описывает кампанию с вредоносными пакетами, имитировавшими внутренние корпоративные зависимости и использовавшими dependency confusion. По данным Microsoft, пакеты запускали код через lifecycle hooks и собирали сведения о системе и окружении разработчика, включая данные о CI/CD. Этот пример показывает, что риск связан не только с тем, кто выпускает пакет, но и с тем, что именно потребители устанавливают.

В материалах Datadog о компрометации axios приводится другой сценарий: по их анализу, вредоносные версии появились после компрометации аккаунта сопровождающего, а одна из них была опубликована не через настроенный GitHub Actions trusted publishing, а напрямую из пользовательской сессии. Это не доказательство того, что staged publishing предотвратил бы такую атаку. Скорее, это иллюстрация того, почему команды внимательно относятся к переходу от автоматизированной аутентификации к публикации из пользовательской сессии и к любому внезапному изменению привычного пути выпуска.

Staged publishing добавляет контроль над доступностью версии, но не устраняет риск компрометации учётных данных, подмены исходного кода или вредоносного содержимого. Его стоит рассматривать как один из барьеров, а не как замену проверке артефактов, защите CI и управлению доступом.

Небольшая проверка: где именно остаётся ручной шаг

Чтобы понять, что новая функция автоматизирует, достаточно разложить процесс на четыре контрольных вопроса — без запуска публикации и без попытки воспроизводить поведение npm локально.

Первый: можно ли создать пакет из CI? По объявлению GitHub — да, для перечисленных типов публичных и приватных пакетов.

Второй: становится ли первая версия доступной сразу? Нет: она поступает в staged-очередь и требует продвижения сопровождающим.

Третий: можно ли отделить право отправить версию на staging от более широких полномочий? GitHub указывает, что доступен stage-only token. Это полезный вариант для автоматизированного процесса, но его необходимо проверить в конкретной конфигурации npm и не трактовать как гарантию защиты от всех сценариев злоупотребления.

Четвёртый: устраняет ли staged-публикация необходимость настроить безопасную аутентификацию? Нет. Документация npm рассматривает trusted publishing как отдельный механизм, позволяющий CI аутентифицироваться через OIDC. Он помогает не хранить долгоживущий токен, но всё равно требует настроить доверие к конкретному workflow.

Ограничение этой проверки очевидно: это разбор описанного поведения и документации, а не независимый тест доступности функции во всех аккаунтах и конфигурациях. Перед внедрением команде стоит проверить текущую документацию npm, версию CLI и фактические права токена на тестовом пакете.

Кому это пригодится — и что проверить перед включением

Изменение особенно полезно командам, которые создают пакет как часть релизного процесса и хотят убрать ручной шаг до первого выпуска. Оно также пригодится проектам с политикой, по которой CI может готовить релиз, а человек отдельно подтверждает его публикацию. Для уже существующего пакета главная новость не в автоматизации создания, а в том, что staged-процесс охватывает и первую версию.

Перед подключением функции имеет смысл ответить на несколько вопросов: какой workflow имеет право отправлять публикацию; каким способом он аутентифицируется; ограничен ли токен необходимыми правами; кто и по каким критериям продвигает первую версию; проверяет ли команда содержимое пакета до продвижения. Если ответы сводятся к «CI всё сделает» и «кто-нибудь нажмёт кнопку», новая возможность сократит число ручных действий, но не обязательно повысит надёжность релиза.

Вывод зависит и от политики проекта. Для небольшого пакета с проверенным процессом сборки staged-очередь может быть удобным последним контрольным пунктом. Для организации, где опубликованные версии проходят обязательный аудит, сама очередь не заменяет утверждённые проверки и журналы изменений. А для команд, которым принципиально нужен выпуск без ручного подтверждения, новая функция не снимает главный вопрос: требуется ли человеку одобрять первую версию по внутренним правилам.

Показателем успеха будет не просто то, что новый пакет создаётся из CI. Важно, чтобы команда могла проследить, кто инициировал staged-публикацию, на основании какого исходного состояния была собрана версия и кто разрешил сделать её доступной. GitHub объявил о возможности управлять настройками пакета и настраивать trusted publishing после создания, но конкретная процедура проверки и одобрения остаётся задачей сопровождающих.

Именно так стоит понимать изменение: npm убирает ручное препятствие на входе в автоматизированный релизный процесс, но оставляет человеку контроль над первой доступной версией. Это не полная автономия публикации и не самостоятельная мера защиты от атак на цепочку поставок. Это новая точка в настройке баланса между скоростью CI, минимальными правами и человеческой ответственностью.

Источники