npm 신뢰 게시 설정: GitHub Actions OIDC로 토큰 없이 배포하고 48시간 검증 기한 넘기지 않기

NPM_TOKEN 시크릿을 걷어내는 순서, 워크플로 예시, 금지 트리거, 재사용 워크플로 함정, 만료 시 복구 방법

npm 신뢰 게시 설정 썸네일

핵심 요약

  1. 새 신뢰 게시 설정은 48시간 안에 한 번 게시에 성공해야 검증되며, 워크플로를 먼저 병합해 두고 npm 설정을 만든다.
  2. npm CLI 11.5.1+, Node.js 22.14.0+, id-token: write 권한, GitHub 호스팅 러너가 필요하다.
  3. issue_comment·pull_request_target 트리거는 release·push·workflow_dispatch로 옮긴다.
  4. 재사용 워크플로는 호출하는 쪽 파일 이름을 등록하고, 양쪽 모두 id-token: write를 준다.
  5. 전환 후 Publishing access에서 토큰 게시를 막고 NPM_TOKEN 시크릿을 폐기한다.

npm 패키지를 GitHub Actions로 배포하면서 저장소 시크릿에 NPM_TOKEN을 넣어 두고 있는 메인테이너를 위한 글이다. 신뢰 게시(trusted publishing)는 장기 토큰 대신 워크플로 실행마다 발급되는 OIDC 토큰으로 게시하는 방식이다. 2026년 10월 2일부터 새로 만든 신뢰 게시 설정은 48시간 안에 한 번 게시에 성공하지 않으면 만료되도록 바뀌었다(GitHub Changelog). 이 글을 따라가면 npmjs.com 설정, 워크플로 작성, 첫 게시로 검증 마치기, 토큰 게시 차단까지 한 번에 끝낼 수 있다.

NPM_TOKEN 방식과 무엇이 달라지나

항목NPM_TOKEN 시크릿신뢰 게시(OIDC)
저장하는 비밀값장기 토큰을 저장소 시크릿에 보관없음. 실행마다 단기 토큰 발급
유출 시 영향토큰을 폐기할 때까지 어디서든 게시 가능지정한 저장소·워크플로 파일에서만 게시 가능
provenance--provenance 플래그 필요공개 저장소면 자동 생성
지원 러너제한 없음GitHub 호스팅 러너만(셀프 호스팅 미지원)
처음 설정 후 기한없음48시간 안에 첫 게시 성공 필요

npm 신뢰 게시 문서에 따르면 지원 CI는 GitHub Actions(GitHub 호스팅 러너), GitLab.com 공유 러너, CircleCI 클라우드이며, 패키지 하나에 신뢰 게시자를 최대 10개까지 등록할 수 있다. 비공개 저장소에서 게시하면 패키지 공개 여부와 관계없이 provenance가 생성되지 않는다.

준비: 버전과 package.json 확인

신뢰 게시는 npm CLI 11.5.1 이상, Node.js 22.14.0 이상이 필요하다. 워크플로에서 쓰는 Node 버전이 이보다 낮으면 인증 단계에서 실패한다. 또 package.json의 repository.url이 실제 GitHub 저장소와 정확히 일치해야 한다.

node -v          # v22.14.0 이상
npm -v           # 11.5.1 이상
npm pkg get repository.url
# "git+https://github.com/<owner>/<repo>.git" 형태로 실제 저장소와 일치해야 함

48시간 기한 안에 끝내는 설정 순서

새 규칙에서 중요한 것은 순서다. npmjs.com에서 설정을 먼저 만들면 그때부터 48시간이 흐르므로, 워크플로를 먼저 완성해 기본 브랜치에 병합해 두고 npm 설정을 만든 직후 게시를 실행한다.

  1. 워크플로 파일을 먼저 병합한다 — 아래 예시처럼 .github/workflows/publish.yml을 만들어 기본 브랜치에 넣는다. 아직 npm 쪽 설정이 없으므로 이 시점에 실행하면 실패하는 것이 정상이다.
  2. npmjs.com에서 신뢰 게시자를 추가한다 — 패키지 Settings → Trusted Publisher → Select your publisher에서 GitHub Actions를 고르고, 조직 또는 사용자, 저장소 이름, 워크플로 파일 이름(publish.yml, 경로 없이 확장자 포함)을 입력한다. 배포 보호용 GitHub environment를 쓴다면 environment 이름도 넣는다.
  3. 바로 게시를 실행한다 — 버전을 올린 릴리스를 만들거나 workflow_dispatch로 실행한다. 게시에 한 번 성공하면 설정이 검증 상태가 되고 만료 대상에서 빠진다.
  4. 토큰 게시를 막는다 — 패키지 Settings → Publishing access에서 "Require two-factor authentication and disallow tokens"를 선택한다. 신뢰 게시는 계속 동작하고 기존 토큰으로는 게시할 수 없게 된다.
  5. 저장소 시크릿에서 NPM_TOKEN을 지운다 — npmjs.com의 Access Tokens에서도 해당 토큰을 폐기한다.
# .github/workflows/publish.yml
name: publish
on:
  release:
    types: [published]
  workflow_dispatch:

permissions:
  id-token: write   # OIDC 토큰 발급에 필요
  contents: read

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: '24'
          registry-url: 'https://registry.npmjs.org'
          package-manager-cache: false
      - run: npm ci
      - run: npm test
      - run: npm publish

NODE_AUTH_TOKEN 환경 변수를 남겨 두면 어떤 인증이 쓰였는지 헷갈리므로 신뢰 게시로 옮길 때 함께 지운다. 문서 예시는 package-manager-cache: false로 게시 작업에서 패키지 매니저 캐시를 끄고 있다.

게시 트리거로 쓰면 안 되는 이벤트

Changelog는 게시 워크플로가 issue_comment나 pull_request_target에서 실행되고 있다면 push, release, workflow_dispatch 같은 허용된 이벤트로 옮기라고 안내한다. 두 이벤트는 외부 기여자의 댓글이나 포크 PR로 시작될 수 있고, pull_request_target은 기본 브랜치 권한으로 실행된다. 게시 권한이 있는 OIDC 토큰을 외부 입력으로 시작되는 실행에 맡기면 공급망 공격 경로가 되므로 제한이 걸린 것으로 읽는 것이 합리적이다.

이벤트게시 트리거로비고
release권장릴리스 생성이 곧 게시 승인 역할
workflow_dispatch가능수동 실행. 첫 검증 게시에 쓰기 좋음
push(태그)가능tags: ['v*']처럼 범위를 좁힌다
issue_comment, pull_request_target옮겨야 함Changelog에서 이동을 안내

릴리스 직전 자동 검사를 PR 단계에 두는 구성은 GitHub Actions와 AI 코드 리뷰 봇 연동에서 다룬 워크플로 구조를 그대로 쓸 수 있다.

재사용 워크플로를 쓸 때의 함정

여러 패키지가 공통 게시 로직을 workflow_call로 불러 쓰는 경우, npm 문서에 따르면 검증은 npm publish가 들어 있는 재사용 워크플로가 아니라 그것을 호출한 워크플로의 파일 이름을 기준으로 이뤄진다. 따라서 npmjs.com에는 호출하는 쪽 파일 이름을 적어야 하고, id-token: write 권한은 호출하는 워크플로와 호출되는 워크플로 양쪽에 모두 있어야 한다.

# .github/workflows/release.yml  ← npmjs.com에는 이 파일 이름을 등록
permissions:
  id-token: write
  contents: read
jobs:
  call-publish:
    uses: ./.github/workflows/_publish-common.yml

# .github/workflows/_publish-common.yml
on: workflow_call
permissions:
  id-token: write
  contents: read

만료·실패했을 때 확인 순서

Changelog에 정리된 만료 규칙은 다음과 같다. 만료된 설정은 설정 화면에 그대로 보이지만 게시를 승인하지 않고, 패키지당 개수 제한에는 포함되지 않는다. 같은 패키지의 다른 유효한 설정에는 영향이 없다. 기존 설정을 단순히 편집해도 48시간 카운트는 다시 시작되지 않으므로, 만료됐다면 설정을 지우고 새로 만들어 새 48시간을 받는다. 패키지 소유 조직이나 저장소를 옮긴 경우에도 새 신뢰 관계를 만들고 다시 검증해야 한다.

증상확인할 것
ENEEDAUTH / Unable to authenticate등록한 워크플로 파일 이름(확장자 포함), GitHub 호스팅 러너 사용 여부, id-token: write 권한
저장소 불일치로 거부package.json의 repository.url이 실제 저장소와 정확히 같은지
설정은 보이는데 게시가 안 됨생성 후 48시간이 지나 만료됐는지. 만료면 삭제 후 재생성
provenance가 안 붙음저장소가 비공개인지(비공개 저장소는 생성되지 않음)

새 패키지라면 staged publishing으로 시작하기

신뢰 게시는 이미 존재하는 패키지의 설정 화면에서 등록하므로, 예전에는 첫 버전을 사람이 토큰으로 직접 게시해야 했다. 같은 날 발표된 변경으로 npm stage publish가 새 패키지 생성도 지원하게 됐다(GitHub Changelog). 첫 버전은 대기열에 들어가고 메인테이너가 승격(promote)해야 설치할 수 있게 된다. 이후 생성된 패키지 설정에서 신뢰 게시를 등록하면 된다. 공개 scoped·unscoped 패키지와 비공개 scoped 패키지가 대상이며, 자동화에는 stage 전용 토큰을 쓸 수 있다. 세부 절차는 staged publishing 문서를 기준으로 확인한다.

신뢰 게시로 옮긴 뒤에도 개발자 PC에 남아 있는 ~/.npmrc 토큰은 그대로다. AI 코딩 도구가 이런 파일을 읽지 못하게 막는 설정은 시크릿·.env가 AI 코딩 도구 컨텍스트에 들어가지 않게 막는 설정에서 다뤘다.

초보자가 자주 실수하는 포인트

  • npm 설정을 먼저 만들고 워크플로 작업을 미루다 48시간이 지나 만료되는 경우
  • 워크플로 파일 이름을 경로까지 포함해 입력하거나 확장자를 빼서 ENEEDAUTH가 나는 경우
  • 만료된 설정을 편집만 하고 다시 시도하는 경우(카운트가 재시작되지 않음)
  • 신뢰 게시로 옮긴 뒤에도 NPM_TOKEN 시크릿과 토큰 게시 허용을 그대로 두는 경우

체크리스트

  • 게시 작업의 Node.js가 22.14.0 이상, npm이 11.5.1 이상인가
  • package.json의 repository.url이 실제 저장소와 일치하는가
  • 게시 워크플로가 기본 브랜치에 병합된 상태에서 npm 설정을 만들었는가
  • 설정 직후 게시를 실행해 검증 상태가 되었는가
  • Publishing access에서 토큰 게시를 막고 NPM_TOKEN을 폐기했는가

자주 묻는 질문

pnpm이나 yarn으로 게시해도 신뢰 게시가 되나요?

npm 문서는 npm CLI 기준으로 요구 버전과 절차를 안내합니다. 다른 패키지 매니저는 OIDC 신뢰 게시 지원 여부와 버전이 도구마다 다르므로 각 도구의 게시 문서에서 확인하고, 확실하지 않으면 게시 단계만 npm publish로 실행하는 방법이 있습니다.

하나의 패키지를 여러 저장소에서 게시할 수 있나요?

패키지당 신뢰 게시자를 최대 10개까지 등록할 수 있으므로 저장소·워크플로별로 각각 등록하면 됩니다. 각 설정은 따로 48시간 안에 검증해야 합니다.

참고 자료 · 검증 기준

위 자료와 내용을 대조한 날짜: . 도구·서비스 정책은 이후 바뀔 수 있으므로 적용 전 공식 문서를 다시 확인하세요.

이 글은 실제 실무 환경 테스트 및 검증된 기술 자료를 바탕으로 작성되었으며, 환경 변화에 따라 지속적으로 갱신됩니다.