npm, 스테이징 전용 토큰으로 더 안전한 자동화 지원
핵심 내용
npm 그래뉼러 액세스 토큰을 만들 때 "Read and write (stage only)" 권한을 선택할 수 있게 됐다. 이 토큰으로는 npm publish로 레지스트리에 직접 배포하는 것은 불가능하지만(2FA 바이패스 설정이 있어도 마찬가지), npm stage publish 명령으로 버전을 검토 대기 상태로 스테이징하거나 dist-tag를 옮기고 버전을 폐기(deprecate)하는 등 다른 쓰기 작업은 그대로 할 수 있다.
사용 흐름은 이렇다: 그래뉼러 액세스 토큰 생성 시 "Read and write (stage only)"를 선택하고, 자동화 워크플로에서 npm publish 대신 npm stage publish를 쓰도록 바꾸고, 패키지 유지보수자가 2FA로 최종 검토·승인해 실제 배포를 완료한다. 이 기능을 쓰려면 npm CLI 11.15.0 이상, Node.js 22.14.0 이상, npm 계정 2FA 활성화, 해당 패키지 배포 권한이 필요하다. GitHub는 이 기능이 2027년 1월로 예정된 "2FA 바이패스 토큰" 제거에 대비한 마이그레이션 경로라고 설명했다.
사용 방법
적용 순서는 이렇다.
- 토큰 생성 시 권한 옵션에서 "Read and write (stage only)"를 선택한다.
- CI 워크플로의 배포 명령을
npm publish에서npm stage publish로 바꾼다. - 패키지 유지보수자가 로컬에서 2FA로 로그인해 스테이징된 버전을 검토·승인한다.
예를 들어 GitHub Actions에서 태그 푸시 시 자동 배포하던 워크플로가 있다면 이렇게 바꿀 수 있다.
# .github/workflows/release.yml
name: Release
on:
push:
tags: ["v*"]
jobs:
stage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "22"
- run: npm ci
# 기존: npm publish (토큰이 있으면 바로 레지스트리에 배포됨)
# stage-only 토큰 사용 시: 배포 대기 상태로만 올라감
- run: npm stage publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_STAGE_ONLY_TOKEN }}
이렇게 해두면 CI는 스테이징까지만 자동으로 하고, 실제 배포는 이 명령이 끝난 뒤 패키지 유지보수자가 로컬에서 2FA로 로그인해 스테이징된 버전을 검토하고 승인해야 완료된다 (npm publish --otp=<2FA 코드> 형태). CI 토큰이 유출되더라도 이 승인 단계 없이는 실제 배포로 이어지지 않는다는 점이 핵심이다.
이 정도면 꽤 실용적인 안전장치다
오픈소스 공급망 공격은 이제 통계로도 확인되는 흐름이다. ReversingLabs 조사에 따르면 2024년에서 2025년 사이 오픈소스 악성 패키지가 73% 늘었고, 그중 99% 이상이 npm 레지스트리에서 발생했다. 배포 토큰 하나가 새어나가는 게 곧바로 대규모 공급망 사고로 이어질 수 있다는 뜻이다.
2FA 바이패스 토큰으로 자동 배포를 걸어둔 팀이라면 2027년 1월 제거 전에 미리 옮겨두는 게 맞다. 개인적으로 마음에 드는 부분은 토큰 권한 자체를 줄이면서도 자동화는 그대로 유지할 수 있다는 점이다 — CI는 스테이징까지만 하고 실제 배포 버튼은 사람이 누르는 구조를 강제로 만들 수 있으니, 토큰이 새어나가도 곧바로 배포로 이어지진 않는다.