npm запустил поэтапную публикацию — самое важное изменение процесса публикации пакетов со времён trustless publishing. Это руководство охватывает всё: от настройки до интеграции с CI/CD и миграции существующих процессов.
22 мая 2026 года npm запустил поэтапную публикацию (staged publishing) —
новый рабочий процесс, который добавляет контрольный этап между упаковкой релиза и
его публикацией в открытом реестре. Вместо npm publish, после которого
пакет становится общедоступным мгновенно, вы запускаете npm stage publish,
чтобы отправить пакет в промежуточную область (staging). Оттуда
назначенные проверяющие могут просмотреть, утвердить или отклонить пакет до того,
как он попадёт к пользователям.
Это не просто улучшение качества жизни — это фундаментальный сдвиг в
безопасности цепочки поставок npm. Поэтапная публикация закрывает
критическую брешь: момент между «я запустил команду» и «мир может установить мой код».
С ней скомпрометированный CI-пайплайн или случайный npm publish
с отладочным кодом могут быть перехвачены до того, как повлияют на пользователей.
Поддерживается в npm 11.15.0+ и pnpm 11.3+.
Поэтапная публикация работает вместе с существующим trusted publishing (аутентификация
на основе OIDC) и новыми флагами --allow-* для контроля времени установки,
создавая стратегию глубокой защиты для всего жизненного цикла пакета.
Экосистема JavaScript страдает от атак на цепочку поставок годами.
Атака Mini Shai-Hulud
в начале этого года показала, как один скомпрометированный токен может привести к
распространению вредоносных пакетов миллионам пользователей за считанные минуты.
После публикации отозвать пакет сложно — npm unpublish имеет строгие
временные ограничения (24 часа для большинства пакетов), и даже после удаления те,
кто уже установил вредоносную версию, остаются уязвимы.
Поэтапная публикация решает проблему времени до обнаружения, создавая обязательное окно проверки. Даже беглый просмотр может выявить:
postinstall)
Типичный сценарий GitHub Actions: слияние в main запускает задачу
публикации. Если злоумышленник получает доступ к секретам репозитория (или PR
содержит изменение workflow, которое извлекает токены), он может опубликовать
вредоносный пакет автоматически. С поэтапной публикацией CI-пайплайн может только
отправить в staging — отдельный шаг утверждения (человек или автоматика)
требуется перед публикацией.
Процесс состоит из трёх фаз:
Запустите npm stage publish вместо npm publish. Это упаковывает модуль и отправляет его в промежуточную область в реестре npm. Пакет не виден публично — только вы и назначенные проверяющие могут его видеть.
# Традиционный (мгновенная публикация)
npm publish
# Поэтапный (отправка на проверку)
npm stage publish
Можно добавить описание релиза:
npm stage publish -m "v2.1.0: Исправлен таймаут аутентификации, добавлены заголовки rate limit"
Отложенные пакеты можно просмотреть перед утверждением:
# Просмотр манифеста и файлов отложенного пакета
npm stage view [email protected]
# Список всех отложенных пакетов (со статусом)
npm stage ls
# Список пакетов от конкретного пользователя
npm stage ls --by "github-actions[bot]"
Команда npm stage view показывает манифест пакета, список файлов с хешами, скрипты жизненного цикла и подтверждения происхождения (provenance). Это даёт проверяющим полную видимость того, что будет опубликовано.
После проверки назначенный утверждающий публикует пакет в реестре или отклоняет его:
# Утвердить и опубликовать
npm stage approve [email protected]
# Отклонить и удалить из staging
npm stage reject [email protected] --reason "Нет записи в changelog"
Утверждения могут быть ограничены конкретной npm-командой или пользователем. Организации могут требовать несколько утверждающих перед публикацией.
Включите поэтапную публикацию для пакета, добавив секцию publishConfig:
{
"name": "@myorg/awesome-package",
"version": "2.1.0",
"publishConfig": {
"staged": true,
"access": "public"
}
}
Для расширенной настройки можно указать требования к проверяющим:
{
"publishConfig": {
"staged": {
"enabled": true,
"requiredApprovers": 2,
"approvalTimeout": 48,
"notify": ["slack:#npm-releases", "email:[email protected]"],
"autoApprove": {
"ciOnly": false,
"trustedBranches": ["main", "release/*"]
}
}
}
}
Параметры конфигурации:
enabled — (boolean) Включить поэтапную публикациюrequiredApprovers — (number) Минимум утверждающих для публикации (по умолчанию: 1)approvalTimeout — (number) Часов до автоотмены (по умолчанию: 72)notify — (string array) Каналы уведомлений при отправке нового пакета в stagingautoApprove.ciOnly — (boolean) Автоутверждать только из CI-средыautoApprove.trustedBranches — (string array) Ветки git для автоутвержденияУстановите настройки для всей организации:
# ~/.npmrc или .npmrc в корне репозитория
stage-publish=true
stage-required-approvers=2
stage-approval-timeout=48
stage-notify=slack:#npm-releases
Для организаций, использующих npm Teams, поэтапную публикацию можно настроить на уровне организации через веб-интерфейс npm: Packages → Staged Publishing Settings.
Поэтапная публикация работает с trusted publishing (OIDC, без токенов). В GitHub Actions OIDC-токен автоматически используется для отправки и утверждения:
# Токен не нужен — OIDC управляет аутентификацией
npm stage publish --provenance
Для токеновой аутентификации токен должен иметь область publish:stage. Токены с областью publish могут отправлять в staging, но не утверждать — для публикации требуется отдельный токен с областью approve.
Полный GitHub Actions workflow для отправки пакета в staging при каждом пуше в main:
# .github/workflows/stage-publish.yml
name: Stage Publish
on:
push:
branches: [main]
paths:
- 'package.json'
- 'src/**'
jobs:
stage:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Для OIDC (trusted publishing)
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm test
- name: Stage publish
run: |
npm stage publish \
--provenance \
-m "Автоматический stage: $(git log -1 --pretty=%B)"
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Для максимальной безопасности объедините GitHub Environments с поэтапной публикацией:
# .github/workflows/promote-stage.yml
name: Promote Staged Package
on:
workflow_dispatch:
inputs:
package:
description: 'Имя пакета для публикации'
required: true
version:
description: 'Версия для публикации'
required: true
jobs:
promote:
runs-on: ubuntu-latest
environment: npm-publish # Требует утверждения в UI GitHub
permissions:
id-token: write
steps:
- uses: actions/setup-node@v4
with:
node-version: '22'
registry-url: 'https://registry.npmjs.org'
- name: Просмотр отложенного пакета
run: npm stage view ${{ inputs.package }}@${{ inputs.version }}
- name: Утверждение и публикация
run: npm stage approve ${{ inputs.package }}@${{ inputs.version }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_APPROVE_TOKEN }}
| Характеристика | Прямая публикация | Trusted Publishing | Staged Publishing |
|---|---|---|---|
| Аутентификация | Токен (NPM_TOKEN) | OIDC (без токена) | OIDC или токен |
| Проверка перед публикацией | Нет | Нет | Обязательна |
| Время до публикации | Мгновенно | Мгновенно | После утверждения |
| CI/CD поддержка | Да | Да (без секретов) | Да (stage + approve) |
| Риск цепочки поставок | Высокий | Средний | Низкий |
| Отмена до публикации | Невозможно | Невозможно | Легко (reject) |
| Несколько утверждающих | Не поддерживается | Не поддерживается | Встроено |
| Provenance Attestation | Поддерживается | Поддерживается | Поддерживается |
| Требуемая версия npm | >= 6.x | >= 9.x | >= 11.15.0 |
| Требуемая версия pnpm | >= 6.x | >= 8.x | >= 11.3 |
Флаги --allow-* — представленные вместе с поэтапной публикацией — дают
потребителям тонкий контроль над тем, что опубликованные пакеты могут делать при
установке. Вместе они создают полную модель безопасности:
npm stage publish — защищает издателей от случайных/вредоносных релизов--allow-scripts / --allow-postinstall — защищает потребителей от вредоносных скриптов--allow-deprecated — контролирует установку устаревших пакетовРекомендуемая настройка для организаций: поэтапная публикация на стороне издателя (предотвращение попадания плохих пакетов в реестр) + --allow-* контроль на стороне потребителя (ограничение действий пакетов при установке).
npm install -g npm@latest
# Или для pnpm
pnpm add -g pnpm@latest
npm --version # Должно быть 11.15.0+
pnpm --version # Должно быть 11.3+
Добавьте в package.json:
"publishConfig": {
"staged": true
}
Сгенерируйте новый токен с областью publish:stage. Если используете trusted publishing (рекомендуется), убедитесь, что CI настроен на OIDC.
Замените npm publish на npm stage publish в CI-воркфлоу. Добавьте отдельный workflow для утверждения.
Добавьте членов команды как утверждающих через веб-интерфейс npm.
Запустите тестовый stage с патч-версией. Отправьте, проверьте, утвердите. Затем проверьте, что опубликованный пакет устанавливается корректно.
Для пакетов с миллионами загрузок установите requiredApprovers на 2 или больше. Ни один скомпрометированный аккаунт не сможет опубликовать вредоносный код.
Trusted publishing устраняет риск кражи токенов. Staged publishing добавляет проверку. Вместе они устраняют два главных вектора атак.
Запускайте автоматический аудит каждого отложенного пакета до проверки человеком. Проверяйте неожиданные файлы, новые скрипты, изменения зависимостей.
Настройте approvalTimeout под ваш ритм релизов. Для ежедневных — 24 часа, для еженедельных — 72 часа.
Для безопасной веб-разработки — обращайтесь
npm stage publish, а затем проходят проверку и утверждение перед публикацией в реестре. Это добавляет контрольный этап для предотвращения случайных или вредоносных публикаций.npm stage publish вместо npm publish. Затем npm stage approve для публикации или npm stage reject для отмены. Просмотр: npm stage view, список: npm stage ls.npm --version или pnpm --version.npm publish продолжает работать. Staged publishing опционален, но рекомендуется для организаций с CI/CD-пайплайнами."publishConfig": { "staged": true } в package.json. Для расширенной настройки укажите requiredApprovers, approvalTimeout и notify.--allow-* флагами и подтверждением происхождения формирует стратегию глубокой защиты.npm staged publishing — важный шаг вперёд для экосистемы JavaScript. Он закрывает один из наиболее критических пробелов в безопасности пакетов — отсутствие контрольного этапа перед публикацией — давая командам гибкость в настройке строгости этого этапа.
Будь вы мейнтейнером небольшого open-source утилиты или управляете реестром приватных пакетов для предприятия, поэтапная публикация естественно интегрируется в существующие инструменты и CI-пайплайны.
Моя рекомендация: включите staged publishing сегодня. Миграция
занимает меньше часа, а выгода для безопасности немедленная. Начните с
requiredApprovers: 1 для мягкого введения, затем ужесточайте
настройки по мере привыкания команды к процессу.
Если вам нужна помощь с миграцией CI/CD-пайплайнов или настройкой безопасного рабочего процесса публикации, я могу помочь. Как full-stack разработчик с глубоким опытом в экосистеме JavaScript, я помог командам внедрить безопасные пайплайны публикации с нуля. Свяжитесь со мной для обсуждения вашего проекта.
Миграция на staged publishing, настройка CI/CD для npm-пакетов или аудит безопасности цепочки поставок — я помогу. Бесплатная консультация.