npm v12 GA: 이제 npm install은 코드를 실행하기 전에 허락을 묻는다

개발

오랫동안 npm install은 “파일을 내려받는다”는 말보다 훨씬 많은 일을 했다. 의존성의 preinstall, install, postinstall을 자동 실행했고, binding.gyp만 있어도 암묵적으로 node-gyp rebuild를 호출했으며, Git 저장소와 원격 tarball도 별도 승인 없이 해석했다. npm v12가 GA로 전환되면서 이 관행이 뒤집혔다. 이제 설치는 다운로드 명령이 아니라, 어떤 외부 코드에 실행 권한을 줄지 선언하는 정책 단계가 된다.

npm v12에서 registry와 lockfile 입력이 allowScripts, allow-git, allow-remote 정책 게이트를 거쳐 CI 빌드로 들어가고 OIDC 또는 staged publishing으로 배포되는 공급망 다이어그램
npm v12는 설치와 배포 양쪽에 명시적 신뢰 경계를 세운다. 의존성 코드는 승인된 경우에만 실행되고, 배포는 장기 토큰 대신 OIDC 또는 2FA 승인 단계로 이동한다.

무슨 일이 있었나

GitHub는 2026년 7월 8일 npm v12가 GA가 되었고 latest 태그를 받았다고 발표했다. v12에서는 allowScripts 기본값이 꺼지며 의존성 lifecycle script와 암묵적 node-gyp 빌드가 승인 없이는 실행되지 않는다. --allow-git--allow-remote의 기본값도 none으로 바뀌어 Git 의존성과 HTTPS tarball 같은 원격 URL 의존성을 명시적으로 허용해야 한다.

이 변화는 이미 npm 11.16.0 이상에서 경고로 관찰할 수 있었다. 공식 준비 절차는 npm approve-scripts --allow-scripts-pending로 아직 검토하지 않은 패키지를 확인하고, 신뢰한 패키지만 npm approve-scripts로 승인한 뒤 생성된 allowScripts 정책을 package.json에 커밋하는 것이다. 실행을 원치 않는 패키지는 npm deny-scripts로 명시적 거부를 기록할 수 있다.

설치만 바뀌는 것도 아니다. GitHub는 2FA 우회가 설정된 granular access token이 민감한 계정·패키지·조직 관리 작업에서 2FA를 건너뛰지 못하게 하는 변경을 2026년 8월 초에 적용할 것으로 예상한다고 밝혔다. 같은 토큰의 직접 배포 권한도 2027년 1월 전후에 줄이고, OIDC trusted publishing 또는 사람이 2FA로 승인하는 staged publishing으로 옮길 것을 권고한다. 이 일정은 확정 날짜가 아니라 공식 발표의 예상 시점으로 봐야 한다.

왜 실무 개발자에게 중요한가

핵심은 보안 옵션 하나가 아니라 신뢰 모델의 변화다. npm v11까지의 기본값은 “패키지를 선택했으니 설치 중 코드 실행도 신뢰한다”에 가까웠다. v12는 다운로드, 소스 해석, 코드 실행을 분리한다. lockfile에 버전을 고정해도 install script가 로컬 파일, 환경변수, 네트워크, 자격 증명에 접근할 수 있다는 사실은 달라지지 않기 때문이다.

이제 package.jsonallowScripts는 단순 설정이 아니라 공급망 정책 파일이다. 누가 sharpesbuild의 빌드를 허용했는지, 승인 범위가 패키지 이름 전체인지 특정 버전인지, 새 transitive dependency가 script를 추가했을 때 누가 검토하는지가 코드 리뷰 대상이 된다. 개발자 노트북, CI runner, 컨테이너 빌드가 같은 정책을 사용해야 재현성이 생긴다.

특히 AI 코딩 에이전트가 의존성을 추가하는 팀에서는 영향이 더 크다. 에이전트는 설치 오류를 만났을 때 allow-scripts=true 같은 전역 우회를 제안할 수 있다. 하지만 빠른 복구를 이유로 전역 허용을 커밋하면 v12의 보호 경계를 사실상 제거한다. 자동화가 만든 의존성 변경도 사람의 capability review를 통과해야 한다.

어디서 먼저 깨질 수 있나

첫 번째는 네이티브 모듈이다. binding.gyp가 있는 패키지는 명시적인 install script가 없어도 npm이 node-gyp rebuild를 실행해 왔기 때문에 v12에서는 승인 대상이다. 이미지 처리, 암호화, 데이터베이스 드라이버, 브라우저 자동화처럼 네이티브 binary나 postinstall 다운로드를 쓰는 패키지는 CI에서 먼저 확인해야 한다.

두 번째는 Git과 원격 URL 의존성이다. github:user/repo, git+https://..., HTTPS tarball을 직접 또는 transitive하게 사용하는 프로젝트는 v12의 기본 정책에서 해석되지 않는다. 릴리즈 전 커밋을 Git dependency로 고정하거나 사내 artifact URL을 직접 참조하는 모노레포는 registry 패키지로 전환할지, 예외를 허용할지 결정해야 한다.

세 번째는 workspace다. npm 공식 approve-scripts 문서는 현재 이 명령이 workspace를 인식하지 않는다고 명시한다. 루트에서 한 번 승인하면 모든 workspace에 자동 적용된다고 가정하지 말고, 실제 package.json 위치와 CI 작업 디렉터리를 기준으로 정책이 읽히는지 검증해야 한다.

네 번째는 캐시다. 이전 빌드에서 생성된 native binary나 다운로드 artifact가 캐시에 남아 있으면 정책 누락이 잠시 가려질 수 있다. 깨끗한 runner와 빈 npm cache에서 npm ci를 수행해야 새 기본값으로도 재현 가능한지 알 수 있다.

커뮤니티 신호: 환영과 마이그레이션 비용이 동시에 보인다

개발자 커뮤니티의 반응은 크게 두 갈래다. 한쪽은 install script의 임의 코드 실행을 기본 허용했던 관행이 너무 오래 지속됐고, 명시적 승인으로 바뀌는 방향 자체는 늦었지만 필요하다고 본다. 다른 쪽은 native addon, Git dependency, workspace가 많은 프로젝트에서 승인 목록을 유지하는 비용과 오류 메시지의 명확성을 걱정한다.

이 반응은 기능 범위를 증명하는 자료가 아니라 운영 우선순위를 알려주는 신호다. 팀이 준비해야 할 것은 “v12를 설치해 본다”가 아니라, 누가 새 script를 검토하고 어떤 증거로 승인하며 CI가 정책 이탈을 어떻게 감지할지 정하는 것이다. 실제 동작과 명령은 GitHub changelog와 npm 문서를 기준으로 확인해야 한다.

실무 마이그레이션 체크리스트

1. 현재 CI와 로컬 환경을 npm 11.16.0 이상으로 맞추고, 평소와 같은 npm ci 또는 npm install에서 v12 관련 경고를 수집한다.

2. npm approve-scripts --allow-scripts-pending 결과를 저장하고 각 패키지의 script, 소스 저장소, 배포 방식, 필요한 네트워크·파일 권한을 검토한다.

3. 승인 범위는 가능하면 설치된 버전에 pin한다. 이름 전체 승인은 미래 버전에도 실행 권한을 주므로, 자동 dependency update와 결합될 때 검토 경계를 넓힌다.

4. 실행이 불필요하거나 설명되지 않는 패키지는 npm deny-scripts로 거부한다. 전체 허용 플래그는 일시적인 장애 분석 외에는 기본 해결책으로 쓰지 않는다.

5. package-lock.json에서 Git, remote URL, file, directory source를 분류한다. Git과 remote가 필요한 경우 소유자·이유·만료 시점을 문서화하고 registry 배포로 옮길 수 있는지 검토한다.

6. macOS, Linux, Windows와 지원 Node.js 버전을 포함한 깨끗한 CI matrix에서 테스트한다. native binary 캐시를 비운 cold install도 최소 한 번 포함한다.

7. Renovate나 Dependabot PR이 allowScripts 변경을 포함하면 일반 버전 업데이트와 분리해 더 엄격한 리뷰를 요구한다.

8. npm 패키지를 배포한다면 장기 publish token을 OIDC trusted publishing으로 교체하고, 위험도가 높은 패키지는 npm stage publish와 사람의 2FA 승인을 추가한다.

배포 파이프라인도 같은 원칙으로 바뀐다

npm의 trusted publishing은 CI/CD와 npm 사이에 OIDC 신뢰 관계를 만들고, 배포할 때마다 짧고 workflow에 묶인 자격 증명을 사용한다. 장기 write token을 저장·회전·마스킹하는 부담을 줄이는 것이 핵심이다. npm 문서 기준으로 trusted publishing은 배포 작업에 적용되며 private dependency 설치 인증까지 대신하지는 않는다.

staged publishing은 npm stage publish로 tarball을 staging area에 올린 뒤, maintainer가 CLI 또는 npmjs.com에서 2FA로 승인해야 실제 registry에 공개되는 흐름이다. 신규 패키지는 stage할 수 없고, 기존 패키지와 지원 버전 조건도 확인해야 한다. 모든 팀에 필요한 것은 아니지만, 널리 쓰이는 패키지나 release 권한이 집중된 조직에는 효과적인 사람 승인 경계가 된다.

설치와 배포를 함께 보면 npm v12의 방향이 선명하다. 소비자는 의존성 코드 실행을 명시적으로 허용하고, 생산자는 장기 토큰 대신 workflow identity와 사람 승인을 사용한다. 공급망의 양 끝을 “암묵적 신뢰”에서 “검토 가능한 권한”으로 바꾸는 것이다.

리스크와 반론

첫 번째 반론은 생산성이다. 설치가 멈추거나 native module이 빌드되지 않으면 팀은 전역 허용으로 되돌리고 싶어진다. 그러나 초기 마이그레이션 비용과 영구적인 보안 경계를 분리해야 한다. 파일럿 브랜치와 CI matrix로 승인 목록을 먼저 만든 뒤 v12를 기본 도구로 올리는 편이 안전하다.

두 번째 리스크는 승인 목록의 형식화다. 패키지 이름을 한 번 승인한 뒤 영원히 신뢰하면 정책은 체크박스가 된다. pin된 승인, dependency update 시 재검토, 불필요 항목 pruning, CODEOWNERS를 함께 운영해야 한다.

세 번째는 생태계 차이다. npm의 정책이 pnpm이나 Yarn의 설정과 자동으로 호환되는 것은 아니다. 같은 monorepo에서 여러 package manager를 허용하면 각 도구의 script/build approval 모델을 별도로 점검해야 한다.

마지막으로 v12가 모든 공급망 공격을 막는 것은 아니다. 악성 코드는 runtime dependency 안에도 있을 수 있고, 승인된 install script도 침해될 수 있다. lockfile, provenance, dependency review, 최소 권한 CI, secret isolation, egress 통제와 함께 써야 한다.

npm v12 전환 체크포인트

현재 CI와 로컬 환경을 npm 11.16.0 이상으로 맞추고, 평소와 같은 npm ci 또는 npm install에서 v12 관련 경고를 수집한다.

npm approve-scripts --allow-scripts-pending 결과를 저장하고 각 패키지의 script, 소스 저장소, 배포 방식, 필요한 네트워크·파일 권한을 검토한다.

승인 범위는 가능하면 설치된 버전에 pin한다. 이름 전체 승인은 미래 버전에도 실행 권한을 주므로, 자동 dependency update와 결합될 때 검토 경계를 넓힌다.

실행이 불필요하거나 설명되지 않는 패키지는 npm deny-scripts로 거부한다. 전체 허용 플래그는 일시적인 장애 분석 외에는 기본 해결책으로 쓰지 않는다.

package-lock.json에서 Git, remote URL, file, directory source를 분류한다. Git과 remote가 필요한 경우 소유자·이유·만료 시점을 문서화하고 registry 배포로 옮길 수 있는지 검토한다.

macOS, Linux, Windows와 지원 Node.js 버전을 포함한 깨끗한 CI matrix에서 테스트한다. native binary 캐시를 비운 cold install도 최소 한 번 포함한다.

Renovate나 Dependabot PR이 allowScripts 변경을 포함하면 일반 버전 업데이트와 분리해 더 엄격한 리뷰를 요구한다.

npm 패키지를 배포한다면 장기 publish token을 OIDC trusted publishing으로 교체하고, 위험도가 높은 패키지는 npm stage publish와 사람의 2FA 승인을 추가한다.

정리

npm v12의 실무적 의미는 설치 실패 몇 건이 아니다. npm install을 실행 권한 부여 단계로 보고, allowScripts 변경을 코드 리뷰하며, Git·remote dependency 예외를 만료 가능한 정책으로 만들고, 패키지 배포는 OIDC와 staged approval로 옮기는 것이 핵심이다. 먼저 npm 11.16.0 이상의 경고 모드에서 현재 의존성의 실제 실행 표면을 목록화한 뒤, 깨끗한 CI에서 정책을 검증하자.

출처