lifecarelog
백엔드

pnpm minimumReleaseAge, 글로벌 설정이 안 먹힌 이유와 워크스페이스 이동

pnpm minimumReleaseAge를 글로벌 config에 넣었다가 효과가 없어 pnpm-workspace.yaml로 옮긴 과정과, 백엔드 빌드에서 그게 맞는 자리인 이유를 정리했어요.

5분 읽기

npm 패키지가 탈취돼 악성 버전이 올라오는 사고는 대개 며칠 안에 잡혀요. 그래서 pnpm에는 "게시된 지 N분이 안 된 버전은 설치하지 않는다"는 minimumReleaseAge 설정이 있어요. 단위가 분이라 7일이면 10,080분, 하루면 1,440분이에요.

글로벌에 넣었는데 아무 일도 없었어요

처음엔 머신 전체에 한 번만 걸면 끝일 줄 알고 글로벌 config에 값을 넣었어요. pnpm config get으로 읽어 보면 값이 그대로 나오니 됐다고 믿었죠.

그런데 직접 테스트해 보면 달랐어요. 몇 시간 전에 새 버전이 올라온 패키지를 pnpm add 해 보니 최신 버전이 그대로 들어왔어요. 설정값은 보이는데 설치 결과는 안 바뀌는, 전형적인 가짜 초록불이었어요.

원인을 끝까지 파는 대신 질문을 바꿨어요. 이 설정이 글로벌에 있어야 할 이유가 있나?

백엔드 빌드 관점에선 애초에 잘못된 자리

플랜엘(plan-l) 법령 검색 API 서버는 Docker 이미지로 빌드돼요. 빌드 컨테이너 안에는 제 홈 디렉터리가 없어요. 글로벌 config가 로컬에서 완벽히 동작했더라도 CI와 배포 빌드에는 애초에 적용될 수 없다는 뜻이에요. 의존성 게이트는 레포에 커밋되는 파일 1개에 있어야 로컬·CI·배포가 같은 규칙으로 돌아가요.

글로벌 config(머신 1대·CI 미적용) vs pnpm-workspace.yaml(레포 커밋·모든 빌드 동일)

그래서 워크스페이스 파일로 옮겼어요. 줄 1개면 끝나요.

# pnpm-workspace.yaml
minimumReleaseAge: 10080 # 7 days, unit is minutes

적용해 봤더니 이번엔 같은 패키지가 7일 이전에 게시된 버전으로 잡혔어요. lockfile diff에도 그 버전이 남으니 리뷰에서 바로 보여요. 급하게 최신 버전이 필요한 패키지는 minimumReleaseAgeExclude에 이름만 적으면 예외로 뺄 수 있어요.

검증은 설정값 조회가 아니라 설치 결과로

이번에 배운 건 단순해요. config get은 대시보드고, 실제 표면은 설치 결과예요. 저는 3단계로 확인해요.

registry 최신 버전 확인pnpm add로 실제 설치lockfile에서 잡힌 버전 대조
  1. pnpm view 패키지 version으로 registry 최신 버전을 봐요.
  2. pnpm add 패키지를 돌려 보니 어떤 버전이 들어왔는지 확인해요.
  3. lockfile에 기록된 버전이 최신보다 오래된 것인지 대조해요.

두 번째와 세 번째가 다르게 나오면 설정이 안 먹는 거예요. 값이 읽힌다는 사실은 아무것도 보장하지 않았어요.

같이 걸어 두면 좋은 것

프로덕션 빌드 단계에선 pnpm install --ignore-scripts로 설치 스크립트 실행을 막고, pnpm audit --prod를 CI에 붙였어요. 설치 시점 7일 대기는 새로 올라온 악성 버전을 거르지만, 이미 설치된 패키지의 관리자가 바뀌는 경우는 못 잡아요. 그래서 정기 재스캔이 따로 필요해요.

라이프케어로그 백엔드처럼 1인이 여러 서비스를 굴리면 설정을 머신에 두고 싶은 유혹이 커요. 하지만 빌드가 일어나는 곳은 제 노트북이 아니에요. 규칙은 코드와 같은 자리에 두는 게 결국 제일 게으른 방법이었어요.

#pnpm#공급망보안#백엔드#CI

라이프케어로그 서비스가 궁금하신가요?

AI 기반 건강·일정·재활 관리 앱을 직접 써보세요.

서비스 살펴보기

관련 글

댓글

아직 댓글이 없어요. 첫 댓글을 남겨주세요.