フック

secrets フック:ハードコードされたシークレットを検出する

コマンドラインから、ハードコードされた認証情報をコードベース全体でスキャンできます。

secrets フックは、環境から読み込むのではなく、ソースコードに埋め込まれている認証情報を指摘します。判断の基準は値の中身ではなく出どころ(リテラルか、環境からの読み込みか)なので、プロバイダーごとのプレフィックスを網羅した一覧は必要なく、誤検知もほとんど出ません。secrets 専門知識 を支える決定論的なエンジンです。

プロバイダー固有の形式のシグネチャ、接続文字列に含まれる認証情報、シークレットを示す名前の識別子に代入されたリテラルは、言語に依存しません:同じ文字列はどのファイルでも同じように読み取れます。一方、構文に依存する 2 つのヒューリスティック(ハードコードされたデフォルト値を持つ環境変数の読み込みと、ログのシンクに流れ込むシークレット)は言語を識別して動作します。そのため、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

スキャンは最大 2 つのセクションを出力します。Hardcoded secrets found は検出事項の一覧(シークレットを示す名前の環境変数に対するハードコードされたデフォルト値、接続文字列に埋め込まれた認証情報、厳選されたプロバイダー形式に一致する値)で、フックは 0 以外の終了コードで終了します。Secret handling to review manually は手がかりの一覧で、シークレットを示す名前の識別子に代入されたただのリテラル(出どころは判定できても、その値が本物のシークレットかどうかは判定できない)と、ログやレスポンスのシンクに流れ込む、シークレットを示す名前の値が並びます。何も見つからなければ no hardcoded secrets found と出力します。

CLI オプション​

オプション値説明
--dirディレクトリスキャン対象をディレクトリに絞る。繰り返し指定でき、--file と併用できる。
--fileファイルスキャン対象を 1 つのファイルに絞る。繰り返し指定でき、--dir と併用できる。

オプションを指定しなければ、プロジェクト全体をスキャンします。

言語ごとの対応範囲​

環境変数のフォールバックに関する検出事項とログのシンクに関する手がかりは、言語ごとの書き方を読み取るため、下の言語だけが対象で、それ以外の言語では何も報告しません。残りの 3 つのシグナルはすべてのファイルで動作します。

シグナル言語
環境変数のデフォルト値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 から読み込んでいれば、一切指摘しません。