secrets 훅은 환경 변수에서 읽지 않고 소스 코드에 박혀 있는 자격 증명을 잡아냅니다. 값의 내용이 아니라 출처(리터럴인지, 환경 변수 조회인지)를 기준으로 판단하므로, 서비스 제공자별 접두사를 빠짐없이 모은 목록이 필요 없고 오탐도 거의 없습니다. secrets 전문 지식을 뒷받침하는 결정론적 엔진입니다.
제공자 형식 시그니처, 연결 문자열에 든 자격 증명, 시크릿을 뜻하는 이름의 식별자에 할당된 리터럴은 언어와 무관합니다. 같은 문자열은 어떤 파일에서든 똑같이 읽히기 때문입니다. 반면 문법에 의존하는 두 휴리스틱, 즉 하드코딩된 기본값이 있는 환경 변수 조회와 로그 싱크로 흘러가는 시크릿은 언어를 인식합니다. 그래서 JavaScript의 console.log 호출을 Rust 파일에서 찾는 일이 없고, Python의 os.getenv("X", "default") 호출은 Python 고유의 형태로 따로 인식합니다.
실행하기
npx lagune read secrets # scans the whole project
npx lagune read secrets --dir src # scans a directory
npx lagune read secrets --file config.ts # scans a single file
스캔 결과는 최대 두 개의 섹션으로 출력됩니다. Hardcoded secrets found 섹션은 발견 사항 목록(시크릿을 뜻하는 이름의 환경 변수에 하드코딩된 기본값, 연결 문자열에 포함된 자격 증명, 엄선한 제공자 형식과 일치하는 값)이므로 훅은 0이 아닌 종료 코드를 반환합니다. Secret handling to review manually 섹션은 단서 목록입니다. 시크릿을 뜻하는 이름의 식별자에 할당된 일반 리터럴(출처는 판단할 수 있어도 값이 실제 시크릿인지는 판단할 수 없는 경우)과, 로그나 응답 싱크로 흘러가는 시크릿 이름의 값이 여기에 해당합니다. 아무것도 발견되지 않으면 no hardcoded secrets found 메시지를 출력합니다.
CLI 옵션
| 옵션 | 값 | 설명 |
|---|---|---|
--dir | 디렉터리 | 스캔 범위를 디렉터리로 한정. 반복 지정 가능, --file 옵션과 함께 사용 가능 |
--file | 파일 | 스캔 범위를 단일 파일로 한정. 반복 지정 가능, --dir 옵션과 함께 사용 가능 |
옵션을 지정하지 않으면 프로젝트 전체를 스캔합니다.
언어별 지원 범위
환경 변수 기본값 발견 사항과 로그 싱크 단서는 언어별로 정해진 형태를 읽으므로, 아래 언어에만 적용되고 그 밖의 언어에서는 아무것도 보고하지 않습니다. 나머지 세 신호는 모든 파일에서 동작합니다.
| 신호 | 언어 |
|---|---|
| 환경 변수 기본값 | JavaScript/TypeScript, Python, Ruby, PHP, Kotlin, Java, Go (cmp.Or), Rust, C# |
| 로그 / 응답 싱크 | JavaScript/TypeScript, Python, Ruby, PHP, Java, Kotlin, Go, Rust, C, C++, C# |
아니요. 시크릿이 커밋되었다고 경고하려고 그 형식을 탐지하는 것은 표준적인 방어 도구가 하는 일로, gitleaks, trufflehog, GitHub push-protection이 수행하는 것과 같은 작업입니다. 이 훅에는 실제로 쓰이는 시크릿이 아니라 탐지 시그니처(공개된 토큰 형식)만 들어 있으며, 시크릿을 외부로 유출하지 않고 점검하고 설명할 뿐입니다.
자주 묻는 질문
값의 내용이 아니라 출처를 기준으로 판단합니다. 신뢰도가 높은 형식(제공자 토큰, 환경 변수 기본값, 연결 문자열)은 발견 사항으로 분류되어 0이 아닌 종료 코드를 반환합니다. 시크릿을 뜻하는 이름의 식별자에 할당된 일반 리터럴은 검토할 단서로 분류해 직접 확인하도록 하며, 같은 식별자를 process.env에서 읽으면 아예 잡아내지 않습니다.
