본문으로 건너뛰기
테마
폰트
크기
A A

패키지 공급망 보안 — 최소 공개 기간 설정

AI 에이전트가 자동으로 npm install·uv add·pnpm add를 실행하는 시대에는 방금 발행된 패키지를 곧바로 받아오는 것이 위험합니다. 한 줄 설정으로 최소 N일 지난 버전만 설치하도록 만들 수 있습니다. Hacker News PSA — 원문

이 페이지의 목적: npm·pnpm·bun·uv 네 가지 주요 패키지 매니저에서 minimum release age를 설정하고, lifecycle 스크립트 실행을 막아 공급망 공격(supply chain attack)에 노출되는 시간을 줄이는 방법을 정리합니다. 에이전트 작업 흐름에 어떻게 끼워 넣을지도 함께 다룹니다.

1. 왜 최소 공개 기간이 필요한가? #

현대 공급망 공격은 보통 다음 흐름을 따릅니다.

  1. 공격자가 잘 알려진 패키지의 유지자 계정을 탈취하거나 비슷한 이름으로 typosquatting 패키지를 발행
  2. 새 버전(또는 신규 패키지)이 npm·PyPI 등 레지스트리에 게시됨
  3. 몇 시간~며칠 안에 누군가 npm install·pip install을 실행 → 악성 코드 실행
  4. 일반적으로 1~7일 안에 보안 스캐너·커뮤니티가 발견하고 게시 취소·CVE 발급

최소 공개 기간을 7일로 설정하면 위 흐름의 3·4 단계 사이에 안전 지대가 생깁니다. 갓 게시된 악성 버전은 자동으로 설치 거부되고, 보안 스캐너가 1주일 동안 검토할 시간을 벌어줍니다.

한 줄 비유
식당에서 "오늘 새로 들어온 식재료는 일주일간 시식 후 메뉴에 올린다"는 정책과 같습니다. 가장 신선해 보이는 재료가 가장 위험할 수 있다는 점을 받아들이는 절충안입니다.
AI 에이전트와 결합되면 더 위험합니다. 에이전트는 사용자 검토 없이 빠르게 npm install some-new-package를 자동 실행할 수 있어, 사람보다 훨씬 짧은 응답 시간 안에 악성 패키지를 끌어옵니다. 본 가이드의 설정은 Permissions·Harness Engineering 보안 레이어와 함께 적용하는 것을 권장합니다.

2. 패키지 매니저별 설정 방법 #

네 도구가 같은 개념을 다른 키 이름·다른 시간 단위로 노출합니다. 모두 7일 기준으로 통일한 예시입니다.

2.1 npm

~/.npmrc
min-release-age=7   # 단위: 일(days)
ignore-scripts=true # lifecycle 스크립트도 함께 차단 (3절 참고)

워크스페이스 단위로 적용하려면 프로젝트_루트/.npmrc에 동일 내용을 둡니다. 두 위치가 모두 존재하면 워크스페이스 설정이 우선합니다.

2.2 pnpm

~/Library/Preferences/pnpm/rc (macOS) — 또는 OS별 pnpm 설정 위치
minimum-release-age=10080  # 단위: 분(minutes) → 7일 = 10080분

설정 파일 경로는 OS·pnpm 버전에 따라 다릅니다. 다음 명령으로 확인할 수 있습니다.

pnpm 설정 위치 확인
pnpm config get globalconfig

2.3 bun

~/.bunfig.toml
[install]
minimumReleaseAge = 604800  # 단위: 초(seconds) → 7일 = 604,800초

워크스페이스 단위 적용은 프로젝트 루트의 bunfig.toml에 같은 키를 둡니다.

2.4 uv

~/.config/uv/uv.toml
exclude-newer = "7 days"  # 자연어 표현 그대로 사용 가능

uv는 ISO 날짜("2026-05-03")도 지원합니다. 특정 시점 이후 발행 버전을 모두 막고 싶다면 유용합니다.

2.5 단위 차이 한눈에 보기

패키지 매니저별 최소 공개 기간 설정 비교
도구 설정 키 단위 7일 값 설정 파일
npm min-release-age 일(days) 7 .npmrc
pnpm minimum-release-age 분(minutes) 10080 pnpm rc
bun install.minimumReleaseAge 초(seconds) 604800 .bunfig.toml
uv exclude-newer 자연어 / ISO 날짜 "7 days" uv.toml
7일이 표준은 아닙니다. Hacker News 토론에서도 7일을 권장값으로 제시했을 뿐, 3~14일 범위에서 팀 정책에 맞춰 조정합니다. 짧을수록 신선한 패치를 빨리 받지만 노출이 늘고, 길수록 안전하지만 새 기능 도입이 늦어집니다.

2.6 프롬프트로 설정 요청하기

위 표를 모두 외울 필요는 없습니다. 사용 중인 패키지 매니저를 알려주고 에이전트에게 직접 작성을 부탁하세요. 그대로 복사·붙여넣기해 쓸 수 있는 예시입니다.

💬 프롬프트 예시 — 최소 공개 기간 설정 요청
  • 이 워크스페이스에 최소 공개 기간 7일 정책을 적용해 줘. 사용 중인 패키지 매니저(npm·pnpm·bun·uv)를 자동으로 감지해서 해당 도구의 설정 파일에만 키를 추가하고, 이미 설정이 있다면 값만 비교해 알려줘. 변경 전후의 diff를 한 줄씩 보여줘.
  • ~/.npmrc, ~/.bunfig.toml, ~/.config/uv/uv.toml, pnpm rc 네 파일에 각각 최소 공개 기간 7일을 한 번에 적용해 줘. 단위가 다르니 npm=일, pnpm=분, bun=초로 환산해서 정확한 값을 넣고, 파일이 없으면 만들어 줘. 작업 끝나면 각 파일을 cat으로 출력해 결과를 보여줘.
  • npm은 lifecycle 스크립트도 함께 차단하고 싶어. ~/.npmrc에 ignore-scripts=true도 추가해 줘. 단, esbuild·sharp 등 native binary가 필요한 패키지 빌드는 안내 메시지에 정리해 줘.
  • 지금 설정을 7일 → 14일로 늘리고 싶어. 네 도구(npm·pnpm·bun·uv) 모두 한 번에 바꿔 줘. 값만 바꾸고 다른 키는 건드리지 마.
  • 최소 공개 기간 설정을 임시로 끄고 한 번만 새 버전을 설치하고 싶어. 영구 변경은 하지 말고, 그 명령에만 적용되는 명령행 옵션 형태로 알려줘. (해당 패키지 매니저에서 지원하지 않으면 그 사실을 알려줘.)

💡 사용 중인 도구를 명시하면 더 정확합니다 (예: "이 프로젝트는 pnpm 사용"). 시스템 전역(~/.npmrc)과 워크스페이스(.npmrc)를 함께 다룰 때는 어느 쪽을 우선할지 함께 말해주세요.

3. lifecycle 스크립트 차단 #

최소 공개 기간은 "갓 발행된 악성 코드"를 막지만, 이미 설치 시점에 코드가 실행되는 npm lifecycle 스크립트는 별도 위험입니다. preinstall·install·postinstallnpm install 한 번으로 임의 코드를 실행시키는 가장 흔한 공격 경로입니다.

패키지 매니저별 기본 lifecycle 스크립트 정책
도구기본 동작차단 설정
npm 모든 lifecycle 스크립트 자동 실행 ignore-scripts=true in .npmrc
pnpm 대부분 차단 (allow 목록 필요) 기본값 사용 권장. 필요한 패키지만 pnpm.allowedScripts에 추가
bun 기본 차단 (신뢰 목록 기반) 기본값 사용 권장
uv Python 생태계 — npm lifecycle 개념 없음

npm 사용자는 ignore-scripts=true를 반드시 설정해야 합니다. 일부 도구(esbuild, sharp 등)는 postinstall이 정상 워크플로지만, 그 경우 npm install --ignore-scripts 이후 필요한 도구만 수동으로 npm rebuild <패키지> 하는 패턴이 안전합니다.

실제 사례: 2024년 axios 등 잘 알려진 패키지의 새 버전이 유지자 계정 탈취로 잠시 악성 코드를 포함해 게시된 적이 있습니다. lifecycle 스크립트가 활성화된 환경은 npm install 한 번만으로 토큰·SSH 키·환경변수가 외부로 유출됐습니다.

4. AI 에이전트가 이 제약을 알게 하기 #

설정만 해 두면 에이전트가 새 패키지를 설치 시도할 때 명령이 실패합니다. 에이전트가 실패 원인을 모르면 같은 명령을 반복하거나 우회를 시도할 수 있어, Rules에 안내 문구를 한 줄 추가하는 것이 효과적입니다.

.agent/rules/package-security.md (Antigravity)
# description: npm/pnpm/bun/uv로 패키지를 설치하는 모든 작업에 적용
# globs: **/package.json, **/pyproject.toml, **/uv.toml, **/.npmrc

## 패키지 설치 보안 규칙

이 워크스페이스는 **최소 공개 기간 7일** 정책을 사용한다.

- 새 패키지·새 버전 설치 시도가 "minimum release age" 또는
  "package is too new" 같은 오류로 실패할 수 있다.
- 그 경우 절대로 `--ignore-min-age` 같은 우회 옵션을 추가하지 말 것.
- 대신 사용자에게 다음을 보고한다.
  1. 어떤 패키지·어떤 버전이 막혔는지
  2. 안전한 대안 버전(7일 이상 지난 가장 최신 버전)이 있는지
  3. 그 패키지가 정말 필요한지

`ignore-scripts=true` 정책 때문에 일부 네이티브 패키지(`esbuild`,
`sharp` 등)는 설치 후 `npm rebuild <name>`이 필요할 수 있다. 이 경우만
사용자 확인을 받고 명시적으로 `npm rebuild`를 실행한다.

같은 내용을 CLAUDE.md·GEMINI.md 전역 규칙으로 두면 모든 워크스페이스에서 일관되게 동작합니다.

💬 프롬프트 예시 — Rule 파일 생성 요청
  • 이 워크스페이스의 .agent/rules/ 디렉터리에 package-security.md를 만들어 줘. 다음 내용을 포함: (1) 패키지 매니저 작업 시작 전 최소 공개 기간 정책을 안내, (2) "minimum release age" 오류 발생 시 우회 옵션 사용 금지, (3) 사용자에게 막힌 패키지·버전·안전한 대안 버전을 한 줄씩 보고. globs는 package.json, pyproject.toml, .npmrc로 한정해 줘.
  • 현재 ~/.gemini/GEMINI.md(또는 ~/.claude/CLAUDE.md)에 패키지 설치 보안 규칙 단락을 추가해 줘. 이미 비슷한 단락이 있으면 중복 추가하지 말고 누락된 규칙만 보강해 줘. 변경 전후 diff를 보여줘.
  • 방금 추가한 규칙이 실제로 동작하는지 검증하고 싶어. 일부러 새로 게시된 가짜 패키지를 설치하는 명령을 시뮬레이션하고, 에이전트가 어떤 메시지를 사용자에게 돌려주는지 시나리오로 작성해 줘.

💡 Rule 본문이 길어지면 에이전트가 일부만 읽는 경우가 생깁니다. "우회 금지"·"보고 형식" 같은 핵심 두 줄을 가장 앞에 두는 것이 효과적입니다.

5. 자주 묻는 질문 & 실패 처리 #

Q. 정말 새 버전이 필요하다면?
한 번만 우회하려면 명령에 환경변수나 옵션으로 임시 해제합니다. 예: npm install --foreground-scripts=false --min-release-age=0 <패키지>. 하지만 가능하면 전역 설정을 잠시 끄지 말고, 신뢰할 만한 다른 경로(공식 깃허브 릴리스, 미러 등)를 우선 검토하세요.
Q. CI/CD에서도 같은 설정을 써야 할까?
예, 특히 CI는 정기적으로 npm install을 다시 실행하므로 같은 정책이 필수입니다. GitHub Actions의 경우 .npmrc·uv.toml을 저장소에 커밋하거나, 워크플로에서 환경변수(NPM_CONFIG_MIN_RELEASE_AGE=7)로 주입합니다.
Q. lock 파일이 있는 프로젝트는 안전한가?
이미 합의된 버전만 설치하므로 어느 정도 안전합니다. 그러나 npm install <새 패키지>·npm update 같은 명령은 lock에 없는 새 항목을 추가하므로 위험. 최소 공개 기간 설정은 lock 파일 사용 여부와 무관하게 켜두는 것이 좋습니다.
Q. Python(pip) 사용자는?
pip에는 공식 min-release-age 옵션이 없습니다. uv로 전환하거나, pip-audit·safety 같은 보안 스캐너를 별도 단계로 추가하세요. uv는 pip 명령(uv pip install ...) 대체로 거의 그대로 쓸 수 있습니다.

오늘코드 Antigravity 튜토리얼 — Google Antigravity 공식 문서 기반 한국어 학습 가이드

이 튜토리얼은 비공식 학습 자료입니다. 공식 문서: antigravity.google/docs

오늘코드