gitleaksとは?シークレット検出の仕組みとv8.30時点の使い方・設定
gitleaksは、ソースコードやGitのコミット履歴に紛れ込んだAPIキー・トークン・パスワードを検出するコマンドラインツールです。MITライセンスで公開され、222個の既定ルールを内蔵しています。ただし2026年7月時点のgitleaksには、日本語の解説記事の多くが前提のままにしている変化が3つあります。コマンド体系がdetectからgitへ移行したこと、Ubuntuのaptで入るバージョンが3年前で止まっていること、そして開発者が「機能追加は終了」を宣言したことです。
まとめ
gitleaksは正規表現とエントロピー判定でシークレットを探し、Gitの全コミット履歴まで遡ってスキャンできる点が、ワーキングツリーだけを見るLinterとの決定的な違いです。最新版はv8.30.1(2026年3月21日公開)で、導入はHomebrew・winget・Scoop・Dockerが確実です。Linuxだけは事情が違い、aptで入る版が8.16.0で止まるためGitHubリリースのtar.gzを展開します。
実行時にまず押さえるべきは、v8.19.0(2024年9月14日)でdetectとprotectが非推奨になり、git・dir・stdinの3コマンドへ再編された点です。旧コマンドも動きますが--helpから隠されており、検索で見つかる記事の多くは非推奨の書式のままです。誤検知は.gitleaksignoreへのFingerprint登録、gitleaks:allowコメント、baselineの3手段で抑え込みます。
採用判断で効いてくるのは、公式READMEが「Gitleaks is feature complete」と明示し、今後のリリースをセキュリティ修正のみとしたことです。既存の運用を続ける分には支障ありませんが、新規に長期採用を決めるなら後半の「「feature complete」宣言後の採用判断」を確認してください。
gitleaksの検出方式とスキャン対象
正規表現とエントロピーによる二段の絞り込み
gitleaksの検出エンジンは、ルールごとに定義されたGo言語の正規表現でマッチ候補を拾い、必要に応じてシャノンエントロピーの閾値でランダム性の低い文字列を落とす構成です。公式が配布する既定設定(config/gitleaks.toml)には222個のルールIDが登録されており、AWSのアクセスキー、1Passwordのサービスアカウントトークン、Anthropicの管理APIキーなど、サービス固有の書式が個別に定義されています。
検出結果は1件ごとにRuleID・エントロピー値・ファイル・行番号・コミットハッシュ・Fingerprintを持ちます。このFingerprintが後述の除外設定のキーになるため、出力の読み方を先に押さえておくと運用が楽になります。
gitleaks git -v
Finding: "export BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafebabe:deadbeef"
Secret: cafebabe:deadbeef
RuleID: sidekiq-secret
Entropy: 2.609850
File: cmd/generate/config/rules/sidekiq.go
Line: 23
Commit: cd5226711335c68be1e720b318b7bc3135a30eb2
Fingerprint: cd5226711335c68be1e720b318b7bc3135a30eb2:cmd/generate/config/rules/sidekiq.go:sidekiq-secret:23
実際の出力には、これに加えてコミットのAuthor・Email・Dateも並びます。誰がいつ持ち込んだ鍵かを追う際は、この3行が起点になります。
正規表現ベースである以上、ルールに書式が登録されていない自社独自のトークンは検出できません。ここは静的解析とは何か?ソースコードを実行せずに品質を確保する手法で扱う静的解析全般の限界と同じで、既定ルールに独自ルールを足す前提で設計します。
git履歴・ディレクトリ・標準入力の3つのスキャン対象
gitleaksが扱う対象は3種類です。gitコマンドはリポジトリのコミット履歴(内部的にはgit log -p相当の出力)を走査し、過去のコミットで追加されて後から削除された鍵まで検出します。dirコマンドはGit管理下かどうかに関係なくディレクトリやファイルを走査し、stdinコマンドは標準入力に流したデータを検査します。
履歴を遡れることが、コミット済みの鍵を洗い出す用途でgitleaksが選ばれる理由です。特定のコミット範囲だけを見たい場合は--log-optsでgit logのオプションをそのまま渡せます。
# リポジトリの全履歴をスキャン
gitleaks git -v path_to_repo
# コミット範囲を限定
gitleaks git -v --log-opts="--all commitA..commitB" path_to_repo
# Git管理外のディレクトリやファイルをスキャン
gitleaks dir -v path_to_directory_or_file
# 標準入力を検査
cat some_file | gitleaks -v stdin
v8.19.0で変わったコマンド体系
detect・protectからgit・dirへの書き換え
v8.19.0(2024年9月14日公開)でdetectとprotectは非推奨になりました。両コマンドは後方互換のため今も動きますが、gitleaks --helpの一覧から隠されています。現在も「gitleaks detect」で検索した先に出てくる日本語記事の多くは2023年前後の執筆で、この変更を反映していません。旧記事の手順をそのまま写すと、公式ドキュメントと突き合わせたときに整合しなくなります。
| 旧コマンド(非推奨) | 現行コマンド | 対象 |
|---|---|---|
| gitleaks detect | gitleaks git | コミット履歴 |
| gitleaks detect –no-git | gitleaks dir | ファイル・ディレクトリ |
| gitleaks detect –no-git –pipe | gitleaks stdin | 標準入力 |
| gitleaks protect | gitleaks git –pre-commit | 未コミットの差分 |
| gitleaks protect –staged | gitleaks git –pre-commit –staged | ステージ済みの差分 |
あわせて、旧来の--sourceフラグによる対象指定は位置引数へ変わりました。位置引数を省略した場合はカレントディレクトリが対象になります。protectが担っていた作業中の差分の検査はgitleaks git --pre-commitに引き継がれており、公式のpre-commitフックもこの書式を内部で呼び出しています。
終了コードとCIでの成否判定
CIに組み込む際に必要なのは終了コードの仕様です。gitleaksは検出なしで0、検出またはエラーで1、不明なフラグを渡された場合に126を返します。検出時のコードは--exit-codeで変更できるため、導入初期に「検出は報告するがビルドは落とさない」運用にしたい場合は0を指定します。
# 検出があってもジョブを失敗させない(導入初期の可視化フェーズ向け)
gitleaks git -v --exit-code 0 --report-path gitleaks-report.json
ログや成果物に生のシークレットを残したくない場合は--redactを付けます。値を指定すると伏せ字にする割合を調整でき、レポートを共有する運用では併用が前提になります。
レポート形式は--report-formatでjson・csv・junit・sarif・templateから選べます。sarifを選んでgithub/codeql-action/upload-sarifへ渡せば、検出結果をGitHubのCode Scanningタブに集約でき、プルリクエスト上で他のセキュリティ検査と同じ導線に載せられます。
OS別のインストール手順
Windowsでのwinget・Scoop・zip導入
公式READMEのインストール例はHomebrew・Docker・ソースビルドの3種のみで、Windowsのパッケージマネージャーは案内されていません。実際にはWindowsではパッケージマネージャー経由が最短です。wingetの公式リポジトリにはパッケージID Gitleaks.Gitleaks として8.30.1が登録されており、Scoopのmainバケットも同じ8.30.1です。どちらも使わない場合は、GitHubリリースのgitleaks_8.30.1_windows_x64.zipを展開してPATHに置きます。ARM版のwindows_arm64、32bit版のwindows_x32も同時配布です。
winget install Gitleaks.Gitleaks
# または Scoop
scoop install gitleaks
# 導入後の確認
gitleaks version
macOSとDockerでの導入
macOSはHomebrewが公式の案内どおりで、2026年7月時点のstableは8.30.1とリリース最新版に追随済みです。CI環境やローカルを汚したくない場合はDockerイメージを使います。配布先はDocker HubとGitHub Container Registryの両方で、スキャン対象はボリュームマウントで渡します。
brew install gitleaks
# Docker(GitHub Container Registry。Docker Hub は zricethezav/gitleaks)
docker pull ghcr.io/gitleaks/gitleaks:latest
docker run -v $(pwd):/path ghcr.io/gitleaks/gitleaks:latest dir /path -v
Linuxのapt版が8.16.0で止まる問題
Linuxで最も事故が起きやすいのがここです。Ubuntuの公式リポジトリに入っているgitleaksは、24.04 LTS(noble)・25.04・25.10・26.04 LTS(resolute)のいずれも8.16.0です。2023年2月26日に公開された版がそのまま据え置かれています。Debianもtrixieが8.16.0で、8.26.0が入るのはsidとforky、そしてUbuntu 26.10(開発中)に限られます。
8.16.0はコマンド再編が入ったv8.19.0より前の版なので、apt install gitleaksで導入した環境ではgitleaks gitもgitleaks dirも存在しません。本記事や公式READMEどおりに打つと「unknown command」で失敗します。さらに[[rules.allowlists]]を導入したv8.21.0より前でもあるため、新しい書式の設定ファイルを共有すると環境ごとに挙動が割れます。
したがってLinuxではaptを使わず、GitHubリリースのtar.gzを展開してください。導入の手軽さより、CIとローカルでバージョンを揃えられない代償のほうが高くつきます。
VER=8.30.1
BASE="https://github.com/gitleaks/gitleaks/releases/download/v${VER}"
curl -sSLO "${BASE}/gitleaks_${VER}_linux_x64.tar.gz"
curl -sSLO "${BASE}/gitleaks_${VER}_checksums.txt"
# 配布物の改ざん検知
sha256sum -c "gitleaks_${VER}_checksums.txt" --ignore-missing
tar -xzf "gitleaks_${VER}_linux_x64.tar.gz" gitleaks
sudo mv gitleaks /usr/local/bin/
gitleaks version
ここで-oを使ってファイル名を変えてしまうと、チェックサムファイルの記載名と一致せず--ignore-missingで全件スキップされます。照合が1件も走らないまま処理が進むため、取得時は-Oで元の名前を保ってください。
.gitleaks.tomlによるルール定義
設定ファイルの探索順と既定ルールの継承
設定の読み込みには明確な優先順位があります。--config(-c)で明示したパス、環境変数GITLEAKS_CONFIG、設定内容そのものを渡すGITLEAKS_CONFIG_TOML、対象パス直下の.gitleaks.tomlという順です。どれも無ければ内蔵の既定設定が使われます。CIで設定が効かないときは、この4段階のどこで拾われているかを先に確認してください。
自前の設定を書く場合も、222個の既定ルールはextendで引き継ぐのが基本です。既定ルールのうち誤検知が多いものだけをdisabledRulesで外せます。generic-api-keyは汎用パターンのため誤検知源になりやすく、除外候補の筆頭です。
[extend]
useDefault = true
disabledRules = ["generic-api-key"]
独自ルールの必須項目とエントロピー閾値
独自ルールは[[rules]]テーブルで追加します。必須なのはidと、regexまたはpathのいずれか一方だけです。両方とも空だと「this rule will have no effect」として設定の読み込み自体が失敗します。descriptionは任意ですが、検出結果の可読性に直結するため実務では記述します。
マッチのどのグループを秘密情報として扱うかはsecretGroupで指定します。entropyに閾値を与えると、そのグループのシャノンエントロピーが値未満のマッチは落ちます。keywordsは正規表現を走らせる前の高速な文字列一致による足切りで、v8.6.0以降で利用可能です。
なお、gitleaksの正規表現はGoの標準エンジンを使うため、先読み(lookahead)は書けません。他ツールの正規表現をそのまま持ち込むと構文エラーになる箇所です。
[[rules]]
id = "internal-service-token"
description = "社内サービスの発行トークン"
regex = '''(?i)svc_token_([0-9a-z]{32})'''
secretGroup = 1
entropy = 3.5
keywords = ["svc_token_"]
tags = ["internal", "token"]
v8.21.0で複数形になったallowlists
ルール単位の除外設定は、v8.21.0(2024年10月15日公開)で[rules.allowlist]から[[rules.allowlists]]へ変わりました。旧書式も動作しますが、複数形にすることで1ルールに複数の除外条件を並べられます。いずれか1つでも一致すれば検出は無視されます。
各allowlistにはconditionでOR(既定)とANDを指定できます。pathsやcommitsのような条件を並べて「どれかに当たれば無視」としたいならOR、「特定ファイルかつ特定パターンのときだけ無視」としたいならANDです。regexesの照合先は既定で検出されたSecretですが、regexTargetにmatchやlineを指定すれば、マッチ全体や行全体に対して判定できます。
[[rules]]
id = "internal-service-token"
description = "社内サービスの発行トークン"
regex = '''(?i)svc_token_([0-9a-z]{32})'''
secretGroup = 1
[[rules.allowlists]]
description = "ロックファイルは対象外"
condition = "OR"
paths = ['''go\.sum''', '''package-lock\.json''']
[[rules.allowlists]]
description = "テスト用ダミー値のみ除外"
condition = "AND"
regexTarget = "line"
regexes = ['''(?i)dummy|example''']
paths = ['''_test\.go''']
複数ルールに同じ除外を効かせたい場合は、ルール単位ではなくファイル直下のグローバル[[allowlists]]を使います。こちらもv8.25.0で[allowlist]から複数形へ変わり、同時にtargetRulesが追加されました。共通の除外を1か所で定義して対象ルールのidを列挙できるため、ロックファイルやテストフィクスチャのような横断的な除外はこちらへ寄せるほうが保守しやすくなります。
誤検知の抑制と既存検出の切り分け
.gitleaksignoreへのFingerprint登録
設定ファイルを触らずに個別の検出だけを黙らせる手段が.gitleaksignoreです。書式は1行1件のFingerprintで、「コミットハッシュ:ファイルパス:ルールID:行番号」の形をそのまま貼り付けます。gitleaks自身のリポジトリでも、テスト用のダミー鍵を黙らせるためにこの形式が使われています。
418edf165dbb63d6f46993ae8f8818ffd87ea582:cmd/generate/config/rules/jwt.go:jwt:17
525d9792b1e3670b4630b8fcc385ca22e8544f9b:cmd/generate/config/rules/sidekiq.go:sidekiq-sensitive-url:46
この4要素はgitスキャン時の形式で、dirでのスキャンにはコミットが無いため「ファイルパス:ルールID:行番号」の3要素になります。探索先の既定はカレントディレクトリで、-i(--gitleaks-ignore-path)でファイルまたは格納フォルダを指定できます。キーには行番号まで含まれるので、対象行がずれれば除外は外れて再び検出対象に戻る点に注意してください。
ただしFingerprintはv8.10.0でレポートに追加された値で、公式READMEは現在も「experimental(将来変更の可能性あり)」と注記中です。長期の除外をこれだけに依存させるのは避けてください。
gitleaks:allowコメントとbaselineの使い分け
ソース側で明示したい場合は、該当行にgitleaks:allowというコメントを書けば無視されます。CIでこの逃げ道を封じたいときは--ignore-gitleaks-allowを付けて実行します。開発者が自分で抑止できる代わりに、監査時には無効化できる二段構えです。
一方、既存リポジトリに導入した初日に数百件が出るケースでは、1件ずつ潰すよりbaselineが現実的です。まず--report-pathでレポートを出し、それを--baseline-pathで指定すると、以後はレポートに載っている既存の検出が無視され、新規に増えた分だけが報告されます。
# 現状をベースラインとして固定
gitleaks git --report-path gitleaks-report.json
# 以後は新規検出だけを findings.json へ書き出す
gitleaks git --baseline-path gitleaks-report.json --report-path findings.json -v
3手段の使い分けは、恒久的な仕様なら設定ファイルのallowlist、単発の例外なら.gitleaksignore、導入時の一括棚上げならbaselineです。どれを選ぶにせよ、除外は誤検知を消す作業であって、本物の漏洩を見落とす経路にもなります。誤検知との向き合い方は静的コード解析の誤検知と限界|レビュー・テストとの責任分担で整理した考え方がそのまま当てはまります。
本物を検出したときの対処順序
誤検知でないと判断したら、最優先は当該キーの失効とローテーションで、Gitの履歴書き換えは後回しにします。コミットされた時点で鍵は公開されたものと見なすべきで、リポジトリが非公開でもクローン・フォーク・CIログ・ローカルの複製を通じて外部に出ている可能性が消えないためです。
履歴の書き換え(git filter-repo等)は、失効を済ませてから着手する事後処理です。書き換えた地点以降のコミットハッシュがすべて変わるため共同作業者への影響が大きく、それ自体は漏洩の停止にならない点も踏まえて判断してください。
pre-commitフックとGitHub Actionsへの組み込み
pre-commitフレームワーク経由の導入
コミット前に止めるなら、自作のGitフックを書くよりpre-commitフレームワークを使うほうが管理が楽です。リポジトリ直下に設定ファイルを置き、pre-commit installを実行すればフックが有効になります。rev(バージョン)はpre-commit autoupdateで更新します。
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.30.1
hooks:
- id: gitleaks
検出時はコミットが失敗します。緊急時にフックだけ飛ばしたい場合はSKIP=gitleaks git commit -m "..."のように環境変数で個別にスキップできます。--no-verifyで全フックを無効化するより影響範囲が狭く、運用ルールとして案内しやすい形です。
gitleaks-action v3への移行と組織アカウントのライセンス
GitHub Actionsで動かす場合は公式のgitleaks-actionを使います。現行はv3.0.0(2026年5月30日公開)で、実質はGitHub Actionsランタイムを Node 20 から Node 24 へ移しただけです。入力・出力・挙動に変更はないため、移行はワークフローファイルの1行修正で済みます。あわせてactions/checkoutもNode 24対応のv6へ上げます。
この移行には期限がある点に注意してください。公式リリースノートによれば、2026年6月2日にランナー既定がNode 24へ切り替わり、2026年9月16日にNode 20がGitHubホストランナーから削除され、v2は動作しなくなります。セルフホストランナーを使っている場合は、Node 24対応のためランナー本体をv2.327.1以上に上げておく必要もあります。
履歴全体を検査させるにはfetch-depth: 0が必須です。既定の浅いクローンのままだと過去コミットが取得されず、検出漏れの原因になります。
name: gitleaks
on:
pull_request:
push:
schedule:
- cron: "0 4 * * *"
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: gitleaks/gitleaks-action@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}
ここで詰まりやすいのがGITLEAKS_LICENSEです。組織(Organization)アカウント配下のリポジトリをスキャンする場合はライセンスキーが必須で、個人アカウントのリポジトリでは不要です。キー自体はgitleaks.ioで無料で取得でき、暗号化シークレットとして登録します。CLI本体はMITで制限が無いのにActionだけ組織で追加手続きが要る、という非対称がつまずきの正体です。
スキャンするgitleaks本体のバージョンはGITLEAKS_VERSIONで固定できます。既定はAction側にハードコードされた版が使われるため、ローカルのpre-commitとバージョンを揃えたい場合は明示します。ジョブ全体の組み方はGitHub Actionsでビルド・自動テストを設定する方法|CI/CDワークフローの作り方の構成に、このステップを1つ足す形が扱いやすいです。
trufflehog・git-secretsとの使い分け
trufflehogとの検出方針とライセンスの違い
比較対象として最も名前が挙がるのがtrufflehogです。最大の違いは検出後の扱いで、trufflehogは--results=verifiedを付けると、見つかった鍵を実際に対象サービスのAPIへ投げて有効かどうかを検証します。「まだ生きている鍵」だけに絞れるため、大量の過去検出を優先度付けする局面では強力です。gitleaksにこの検証機構はありません。
もう一つ、見落とされがちですが実務上は重い違いがライセンスです。gitleaksはMIT、trufflehogはAGPL-3.0です。AGPLは改変して外部提供する形態に条件が付くため、自社サービスへ組み込む前提なら法務確認の対象になります。CIで実行ファイルとして呼ぶだけなら通常は問題になりませんが、SaaSに組み込む設計では扱いが変わります。
| ツール | ライセンス | 最新版(2026-07時点) | 特徴 |
|---|---|---|---|
| gitleaks | MIT | v8.30.1(2026-03) | 正規表現とエントロピー・機能追加終了 |
| trufflehog | AGPL-3.0 | v3.96.0(2026-07) | 鍵の有効性を実検証・開発活発 |
| git-secrets | Apache-2.0 | 1.3.0(タグ/最終push 2025-09) | AWS製・フック特化 |
| detect-secrets | Apache-2.0 | v1.5.0(2024-05) | Yelp製・baseline運用が中心 |
git-secrets・detect-secrets・GitHub側機能との住み分け
git-secretsはAWS製で、Gitフックとして動かす用途に特化しています。ただしGitHubリリースは1件も無くタグの最新が1.3.0、リポジトリの最終更新も2025年9月で、新規採用の理由は薄いのが実情です。detect-secrets(Yelp)はPython製で、baselineファイルを軸に「既知の検出を固定して差分だけ見る」運用が最初から前提になっています。ただしリリースはv1.5.0(2024年5月)から出ておらず、更新が続くのはリポジトリ本体のみという点は把握しておいてください。
これらCLIとは別に、GitHub側にもSecret ScanningとPush Protectionがあります。プラットフォーム側はリポジトリ全体を継続監視し、パートナー連携で漏洩トークンの自動失効まで届く点が違います。gitleaksは手元とCIで早期に止める役、GitHub側は取りこぼしを面で拾う役として重ねるのが現実的です。有償機能の範囲はGitHub Advanced Securityの料金は?価格体系と主要機能をわかりやすく解説で確認できます。
「feature complete」宣言後の採用判断
2026年7月時点の公式READMEには、警告として「gitleaksは機能的に完成しており、新機能のマージは行わない。今後のリリースはセキュリティ修正のみ」という趣旨が明記され、作者は後継プロジェクトのBetterleaksへ注力すると宣言しています。Betterleaksのリポジトリは2026年2月3日に作成され、MITライセンスで更新が続いています。
この宣言をどう読むかは分かれますが、判断ははっきり分けられます。すでにgitleaksをCIやpre-commitで回している組織は、今すぐ乗り換える理由はありません。検出ロジックは正規表現の集合であり、既定ルールの更新が止まっても既存の検出が壊れるわけではなく、セキュリティ修正は継続されます。222ルールの守備範囲で足りているなら、そのまま運用するのが妥当です。
一方で、これから新規に長期採用を決める場合、gitleaks単体に寄せるのは推奨しません。新しいSaaSのトークン書式は今後も増え続けますが、機能追加を止めたプロジェクトに既定ルールの追随を期待するのは筋が悪いためです。この場合は、自社で[[rules]]を追加保守する体制を前提に置くか、開発が続くtrufflehogやプラットフォーム側の機能と組み合わせます。Betterleaksへの本番投入は、2026年2月開始で実績が薄く時期尚早です。いずれの構成でも、ルール保守と誤検知対応の工数を誰が持つかを決めずに入れると、検出結果が放置されて形骸化します。
よくある質問
gitleaks detectはもう使えないのですか
動作します。非推奨になり--helpから隠されただけで、後方互換は保たれています。ただし新しく書く手順書やCI設定はgit・dir・stdinに揃えてください。逆にaptで導入した8.16.0の環境では、detectしか使えません。
gitleaksのライセンスは何ですか。商用利用に費用はかかりますか
CLI本体はMITライセンスで、商用利用を含めて無償です。費用が関わるのはGitHub Actions版で、組織アカウント配下のリポジトリをスキャンする場合にライセンスキーの登録が必要になります。このキー自体もgitleaks.ioで無料で取得できます。
Windowsに入れるにはどうすればよいですか
wingetでwinget install Gitleaks.Gitleaksを実行するのが最短です。Scoopのmainバケットにも同じ8.30.1があります。どちらも使えない環境では、リリースページのzipを展開してPATHの通ったディレクトリに置いてください。
誤検知が多すぎる場合はどこから手を付けますか
まずdisabledRulesでgeneric-api-keyのような汎用ルールを外し、次にロックファイルやテストデータのパスを除外します。複数ルールにまたがる除外なら、ルール単位ではなくグローバル[[allowlists]]にtargetRulesで対象idを列挙するほうが管理が楽です。それでも既存分が多い場合はbaselineで現状を固定し、新規検出だけを見る運用に切り替えます。
gitleaksとtrufflehogはどちらを選ぶべきですか
過去の履歴から「今も有効な鍵」を優先度付けして洗い出したいならtrufflehogです。Git以外にS3やDockerイメージも走査対象にできるので、コード以外に漏れが散っている環境にも向く点が強みです。CIとpre-commitに軽く常駐させ、MITライセンスで法務確認の負荷を避けたいならgitleaksが適します。両者は排他ではなく、日常のゲートをgitleaks、定期的な棚卸しをtrufflehogに分ける構成も取れます。