을 두면, npm은 .gitignore를 읽지 않습니다. .gitignore에 .env를 작성했더라도, .npmignore에 test/만 적은 상태로 npm pack --dry-run을 실행하면, .env, .env.local, 키 파일이 패키지에 포함되었습니다 (작성자 환경에서 확인). -
루트의 package.json의 files에 디렉토리를 통째로 쓰면, 그 안의 .env.production이나 *.pem도 들어갔습니다. .gitignore는 files에서 지정한 내용을 제외하지 않았습니다 (작성자 환경에서 확인). -
공개 전에가 가장 확실합니다. npm pack --dry-run으로 포함될 파일 목록을 보는 것이 좋습니다.
files는 src처럼 필요한 것만 적고, .npmignore를 사용할 경우 .env*와 키 형식도 작성해야 합니다.
이 글은 'AI 에이전트와 비밀 정보' 검증 시리즈입니다. 새로운 검증 내용은 X (@supportapp3_lab)에서도 공지하고 있습니다.
AI에게 만들게 한 CLI나 라이브러리를 npm으로 공개할 때, .npmignore를 '테스트용 파일을 제외하기 위해' 추가하는 경우가 있습니다. 이때 .gitignore로 지키고 있던 .env까지 빠져나가지 않는지 확인해 보았습니다. AI 에이전트가 실제로 이 방식을 사용하는지는 확인하지 않았습니다.
- Debian 13 / Node.js 20.19.2 / npm 11.21.0
npm pack --dry-run과 npm publish --dry-run만 사용했습니다. 레지스트리 공개는 하지 않았습니다 (publish --dry-run도 로그인 없이 실행하여 전송하지 않았습니다). -
.env와 키 파일의 내용은 더미 문자열입니다.
시도한 프로젝트 형태는 다음과 같습니다.
package.json {"name": ..., "version": "1.0.0", "main": "src/index.js"}
src/index.js
.env API_KEY=dummy...
...
.npmignore가 없을 때는 npm은 .gitignore의 내용을 사용합니다 (npm 공식: '.gitignore가 있고 .npmignore가 없을 때는, .gitignore의 내용이 사용됩니다').
npm notice 58B package.json
npm notice 17B src/index.js
.env도 키 파일도 포함되지 않았습니다. git 리포지토리가 아닌 디렉토리에서도 같은 결과였습니다.
같은 프로젝트에, test/ 한 줄만 적은 .npmignore를 추가했습니다.
npm notice 29B .env
npm notice 14B .env.local
npm notice 18B config/.env.production
...
.gitignore의 제외가 통하지 않게 되었고, .env도 키 파일도 포함되었습니다. npm publish --dry-run에서도 같은 목록이 나왔습니다.
npm 공식의 '항상 제외되는 파일'에는 .git, .npmrc, node_modules 등이 나열되어 있지만, .env는 포함되지 않습니다.
.npmignore를 만들었다면, .gitignore와 동일한 제외 내용을 그곳에도 작성해야 합니다.```
.npmignore
test/
.env
...
이렇게 쓰니, `.env`와 키는 포함되지 않았습니다.
`package.json`의 `files`는 '포함할 내용' 목록입니다 (npm 공식). `
npm notice 18B config/.env.production
npm notice 7B config/secret.pem
npm notice 82B package.json
...
루트의 `.gitignore`에는 `.env.*`와 `*.pem`을 작성했지만, `config/` 안에서는 제외되지 않았습니다. npm 공식 문서에는 '루트의 `.npmignore`는 `files`를 덮어쓰지 않지만, 서브 디렉토리의 `.npmignore`는 덮어쓴다'고 나와 있습니다. 실제로 `config/.npmignore`에 `.env*`와 `*.pem`을 작성하니 두 파일 모두 포함되지 않았습니다.
npm pack --dry-run
이렇게 하면 전송 없이 공개될 파일 목록이 나옵니다. 다음 세 가지를 확인해야 합니다.
-
`.env`로 시작하는 파일이 없는지 -
`*.pem`
・`*.key`
・`id_rsa`와 같은 키 파일이 없는지 -
`files`로 통째로 지정한 디렉토리에 설정이나 비밀 정보가 섞여 있지 않은지
만약 공개했다면, 패키지를 삭제하기 전에 포함되었던 키를 재발급하는 것이 좋습니다(권장. 이미 공개된 시점에서 확보되었을 가능성이 있기 때문).
-
`.npmignore`를 두면 `.gitignore`는 사용되지 않습니다 (npm 공식/실제 환경). `.env`는 npm의 기본 제외 목록에 포함되어 있지 않습니다 (npm 공식). -
`files`에 디렉토리를 쓰면, 내부의 `.env.production`이나 키 파일도 포함되었습니다 (실제 환경). 서브 디렉토리의 `.npmignore`로 제외할 수 있었습니다 (실제 환경/npm 공식).
- 공개 전에는 `npm pack --dry-run`으로 목록을 확인합니다.
AI 에이전트가 `.env`를 읽을 수 있는지 여부는 ai-secret-check(`npx github:supportapp3-lab/ai-secret-check scan`, 값은 표시하지 않고 통신도 하지 않음)로 점검할 수 있습니다. npm 패키지 내부 내용은 아직 점검 대상이 아닙니다.
관련 기사:
- AI에게 커밋을 맡기기 전에: .env와 키를 pre-commit으로 막기
- 과거에 커밋한 .env는 git 히스토리에서 읽을 수 있음: 찾는 방법과 git-filter-repo로 지우는 방법
- Codex CLI가 .env를 읽지 않도록 설정: 공식 예시의 "**/*.env"만으로는 .env.local 및 깊은 계층이 읽혔습니다
참고 (공식):
※ 사양은 2026-10-21 시점의 npm 공식 문서에 기반합니다. 검증은 npm 11.21.0으로, Linux 임시 환경에서만 수행했습니다.
업데이트 정보나 간단한 Tips는 X(@supportapp3_lab)를 통해 발신하고 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31