{
    "componentChunkName": "component---src-templates-post-js",
    "path": "/ai-ezientodechai-fen-gazeng-etanode-secret-scanning-wo-pre-commit-ci-niji-setemita/",
    "result": {"data":{"ghostPost":{"id":"Ghost__Post__69e7c6da781e37000184e786","title":"gitleaksを使ってsecretの誤コミット対策してみた","slug":"ai-ezientodechai-fen-gazeng-etanode-secret-scanning-wo-pre-commit-ci-niji-setemita","featured":false,"feature_image":null,"excerpt":"こんにちは、いわむらです。\n\nAI\nエージェントといっしょに作業することが増えてきました。速くて助かる一方で、ローカルの設定値や検証用トークンが、気づかないうちにコミットに紛れ込むリスクは前より意識するようになりました。\n\n間違ってコミットに含まれてしまうのを避けるため、機密情報はコミット前に機械的に止めるやり方にチャレンジしてみた内容を共有できたらと思っています。今回は、gitleaks\nを lefthook から pre-commit で実行する構成にしています。\n\n本記事で紹介するのは次の3点です。\n\n * なぜ git-secrets ではなく gitleaks に寄せたのか\n * ローカルで止める最小構成\n * ローカルで漏れた場合に GitHub Actions でどう拾うか\n\n人の注意に頼る場所を減らして、フローの中で止める形にしてみてます。\n\ngitleaks に寄せた理由\nもともとは git-secrets を使っていました。AWS 系の検知が優秀なのですが、それ以外のサービスには標準では対応していません。今回は AWS\n以外も最初から広めに見たかったので、gitle","custom_excerpt":null,"visibility":"public","created_at_pretty":"21 April, 2026","published_at_pretty":"11 May, 2026","updated_at_pretty":"11 May, 2026","created_at":"2026-04-22T03:50:02.000+09:00","published_at":"2026-05-11T09:27:00.000+09:00","updated_at":"2026-05-11T09:27:00.000+09:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"name":"Jun Iwamura","slug":"jun","bio":null,"profile_image":null,"twitter":null,"facebook":null,"website":null}],"primary_author":{"name":"Jun Iwamura","slug":"jun","bio":null,"profile_image":null,"twitter":null,"facebook":null,"website":null},"primary_tag":null,"tags":[],"plaintext":"こんにちは、いわむらです。\n\nAI\nエージェントといっしょに作業することが増えてきました。速くて助かる一方で、ローカルの設定値や検証用トークンが、気づかないうちにコミットに紛れ込むリスクは前より意識するようになりました。\n\n間違ってコミットに含まれてしまうのを避けるため、機密情報はコミット前に機械的に止めるやり方にチャレンジしてみた内容を共有できたらと思っています。今回は、gitleaks\nを lefthook から pre-commit で実行する構成にしています。\n\n本記事で紹介するのは次の3点です。\n\n * なぜ git-secrets ではなく gitleaks に寄せたのか\n * ローカルで止める最小構成\n * ローカルで漏れた場合に GitHub Actions でどう拾うか\n\n人の注意に頼る場所を減らして、フローの中で止める形にしてみてます。\n\ngitleaks に寄せた理由\nもともとは git-secrets を使っていました。AWS 系の検知が優秀なのですが、それ以外のサービスには標準では対応していません。今回は AWS\n以外も最初から広めに見たかったので、gitleaks のデフォルトのルールセットで Stripe のシークレットキーや Slack の Webhook\nURL、Vercel のアクセストークンなど、100 種類以上のサービス固有のパターンに対応していることから選択してみました。\n\nもうひとつは Windows への導入のしやすさです。チームメンバーで Windows を利用している方も多く、git-secrets\nだと導入に手こずっている方もいました。gitleaks は Scoop を利用することで導入が簡単にできるので、より良い運用に乗せやすいと判断しました。\n\nローカルで止める最小構成\n以下は gitleaks v8 系を前提にした例です。\n\nまずは gitleaks を入れます。\n\n# macOS\nbrew install gitleaks\n\n# Windows\nscoop install gitleaks\n\ngitleaks version\n\n\nlefthook はバイナリで入れます。\n\n# macOS\nbrew install lefthook\n\n# Windows\nscoop install lefthook\n\n\nclone してきたら、一度だけ次のコマンドを実行します。\n\nlefthook install\n\n\nこれはリポジトリごとに一度だけ必要です。.git/hooks/ に hook が書き込まれ、以降は自動で動きます。\n\n全リポジトリにグローバルで適用したい場合は、lefthook を使わず git のグローバル hooks を直接使う方法もあります。\n\nmkdir -p ~/.git-hooks\ncat > ~/.git-hooks/pre-commit << 'EOF'\n#!/bin/sh\ngitleaks git --staged --redact --verbose\nEOF\nchmod +x ~/.git-hooks/pre-commit\ngit config --global core.hooksPath ~/.git-hooks\n\n\nただし、グローバル設定は自分のマシンにしか効かないため、チームへの展開には向きません。チームで同じルールを共有するなら、リポジトリに lefthook\nの設定を置く方式のほうが確実です。\n\nlefthook の設定は次のようにしています。\n\npre-commit:\n  commands:\n    gitleaks:\n      run: gitleaks git --staged --redact --verbose\n\n\nここでやりたいのは、コミットの直前に一度ブレーキをかけることです。--redact を付けているのは、検知時の出力に secret をそのまま出さないためです。\n--verbose は、導入直後に何が起きているか追いやすくするために入れています。\n\n初回導入時にやっておいたこと\npre-commit だけだと、これから入る差分しか止められません。既存の履歴を一度見ておきたいので、初回導入時はリポジトリ全体もスキャンしました。\n\ngitleaks git --redact --verbose\n\n\nここで検知が出たら、まずは本物の secret かどうかを確認します。誤検知だけを allowlist に寄せるほうが安全です。\n\nallowlist は狭く書く\ngitleaks を使い始めると、サンプル文字列やドキュメントで誤検知が出ることがあります。そこで allowlist\nを入れますが、ここを雑に広げると後で本物を見逃します。\n\n例えば、ドキュメント配下の EXAMPLE だけを許可するなら、次のように条件を絞って書きます。\n\ntitle = \"team gitleaks config\"\n\n[extend]\nuseDefault = true\n\n[[allowlists]]\ndescription = \"allow documented placeholders only in docs\"\ncondition = \"AND\"\npaths = ['''^docs/''']\nregexTarget = \"match\"\nregexes = ['''\\bEXAMPLE\\b''']\n\n\n「とりあえず docs を全部通す」のような書き方は避けたほうが安心だと考えてます。\n\nCI でもう一度見る\nここでひとつ大事なのは、CI は GitHub に入る前に止める仕組みではない、という点です。push や pull_request で動かす以上、差分はすでに\nGitHub にはあります。\n\nそれでも CI を置く意味はあります。ローカルで拾えなかったものを PR で止めることと、デフォルトブランチに流し込まないことです。\n\nGitHub Actions は次のようにしています。\n\nname: gitleaks\n\non:\n  pull_request:\n  push:\n    branches: [main]\n  workflow_dispatch:\n\npermissions:\n  contents: read\n\njobs:\n  scan:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n      - uses: gitleaks/gitleaks-action@v2\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          GITLEAKS_CONFIG: .gitleaks.toml\n          GITLEAKS_ENABLE_COMMENTS: false\n          # Organization リポジトリで使う場合だけ追加\n          # GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}\n\n\nfetch-depth: 0 を入れているのは、履歴を見られる状態にするためです。push を main に絞っているのは、不要な実行を増やしすぎないためです。\n\n検知後にやること\n検知して終わりにはしません。もし本物の secret が push\n済みなら、回収とローテーションまでやれるようになると良いかなと思っていますが今回は割愛します。\n\nまとめ\nAI エージェントで差分が増えるなら、機密情報対策は「気を付ける」だけでは足りないと考えてます。コミット前に止める。漏れたら CI\nでもう一度見る。その二段にしておくほうが、実際の運用はかなり楽になります。\n\ngit-secrets は今でも良いツールです。ただ、今回は AWS 以外も広く見たかったことと、Windows\nを含めて配りやすくしたかったことから、gitleaks に寄せました。\n\nまずは pre-commit で止めるところから始めて、必要になったら CI と allowlist\nを育てていく。この順番がいちばん無理なく入れられるんじゃないかなと思います。","html":"<p>こんにちは、いわむらです。</p><p>AI エージェントといっしょに作業することが増えてきました。速くて助かる一方で、ローカルの設定値や検証用トークンが、気づかないうちにコミットに紛れ込むリスクは前より意識するようになりました。</p><p>間違ってコミットに含まれてしまうのを避けるため、機密情報はコミット前に機械的に止めるやり方にチャレンジしてみた内容を共有できたらと思っています。今回は、gitleaks を lefthook から pre-commit で実行する構成にしています。</p><p>本記事で紹介するのは次の3点です。</p><ul><li>なぜ git-secrets ではなく gitleaks に寄せたのか</li><li>ローカルで止める最小構成</li><li>ローカルで漏れた場合に GitHub Actions でどう拾うか</li></ul><p>人の注意に頼る場所を減らして、フローの中で止める形にしてみてます。</p><h2 id=\"gitleaks-%E3%81%AB%E5%AF%84%E3%81%9B%E3%81%9F%E7%90%86%E7%94%B1\">gitleaks に寄せた理由</h2><p>もともとは git-secrets を使っていました。AWS 系の検知が優秀なのですが、それ以外のサービスには標準では対応していません。今回は AWS 以外も最初から広めに見たかったので、gitleaks のデフォルトのルールセットで Stripe のシークレットキーや Slack の Webhook URL、Vercel のアクセストークンなど、100 種類以上のサービス固有のパターンに対応していることから選択してみました。</p><p>もうひとつは Windows への導入のしやすさです。チームメンバーで Windows を利用している方も多く、git-secrets だと導入に手こずっている方もいました。gitleaks は Scoop を利用することで導入が簡単にできるので、より良い運用に乗せやすいと判断しました。</p><h2 id=\"%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%81%A7%E6%AD%A2%E3%82%81%E3%82%8B%E6%9C%80%E5%B0%8F%E6%A7%8B%E6%88%90\">ローカルで止める最小構成</h2><p>以下は gitleaks v8 系を前提にした例です。</p><p>まずは gitleaks を入れます。</p><pre><code class=\"language-bash\"># macOS\nbrew install gitleaks\n\n# Windows\nscoop install gitleaks\n\ngitleaks version\n</code></pre><p>lefthook はバイナリで入れます。</p><pre><code class=\"language-bash\"># macOS\nbrew install lefthook\n\n# Windows\nscoop install lefthook\n</code></pre><p>clone してきたら、一度だけ次のコマンドを実行します。</p><pre><code class=\"language-bash\">lefthook install\n</code></pre><p>これはリポジトリごとに一度だけ必要です。<code>.git/hooks/</code> に hook が書き込まれ、以降は自動で動きます。</p><p>全リポジトリにグローバルで適用したい場合は、lefthook を使わず git のグローバル hooks を直接使う方法もあります。</p><pre><code class=\"language-bash\">mkdir -p ~/.git-hooks\ncat &gt; ~/.git-hooks/pre-commit &lt;&lt; 'EOF'\n#!/bin/sh\ngitleaks git --staged --redact --verbose\nEOF\nchmod +x ~/.git-hooks/pre-commit\ngit config --global core.hooksPath ~/.git-hooks\n</code></pre><p>ただし、グローバル設定は自分のマシンにしか効かないため、チームへの展開には向きません。チームで同じルールを共有するなら、リポジトリに lefthook の設定を置く方式のほうが確実です。</p><p>lefthook の設定は次のようにしています。</p><pre><code class=\"language-yaml\">pre-commit:\n  commands:\n    gitleaks:\n      run: gitleaks git --staged --redact --verbose\n</code></pre><p>ここでやりたいのは、コミットの直前に一度ブレーキをかけることです。<code>--redact</code> を付けているのは、検知時の出力に secret をそのまま出さないためです。<code>--verbose</code> は、導入直後に何が起きているか追いやすくするために入れています。</p><h2 id=\"%E5%88%9D%E5%9B%9E%E5%B0%8E%E5%85%A5%E6%99%82%E3%81%AB%E3%82%84%E3%81%A3%E3%81%A6%E3%81%8A%E3%81%84%E3%81%9F%E3%81%93%E3%81%A8\">初回導入時にやっておいたこと</h2><p>pre-commit だけだと、これから入る差分しか止められません。既存の履歴を一度見ておきたいので、初回導入時はリポジトリ全体もスキャンしました。</p><pre><code class=\"language-bash\">gitleaks git --redact --verbose\n</code></pre><p>ここで検知が出たら、まずは本物の secret かどうかを確認します。誤検知だけを allowlist に寄せるほうが安全です。</p><h2 id=\"allowlist-%E3%81%AF%E7%8B%AD%E3%81%8F%E6%9B%B8%E3%81%8F\">allowlist は狭く書く</h2><p>gitleaks を使い始めると、サンプル文字列やドキュメントで誤検知が出ることがあります。そこで allowlist を入れますが、ここを雑に広げると後で本物を見逃します。</p><p>例えば、ドキュメント配下の <code>EXAMPLE</code> だけを許可するなら、次のように条件を絞って書きます。</p><pre><code class=\"language-toml\">title = \"team gitleaks config\"\n\n[extend]\nuseDefault = true\n\n[[allowlists]]\ndescription = \"allow documented placeholders only in docs\"\ncondition = \"AND\"\npaths = ['''^docs/''']\nregexTarget = \"match\"\nregexes = ['''\\bEXAMPLE\\b''']\n</code></pre><p>「とりあえず docs を全部通す」のような書き方は避けたほうが安心だと考えてます。</p><h2 id=\"ci-%E3%81%A7%E3%82%82%E3%81%86%E4%B8%80%E5%BA%A6%E8%A6%8B%E3%82%8B\">CI でもう一度見る</h2><p>ここでひとつ大事なのは、CI は GitHub に入る前に止める仕組みではない、という点です。<code>push</code> や <code>pull_request</code> で動かす以上、差分はすでに GitHub にはあります。</p><p>それでも CI を置く意味はあります。ローカルで拾えなかったものを PR で止めることと、デフォルトブランチに流し込まないことです。</p><p>GitHub Actions は次のようにしています。</p><pre><code class=\"language-yaml\">name: gitleaks\n\non:\n  pull_request:\n  push:\n    branches: [main]\n  workflow_dispatch:\n\npermissions:\n  contents: read\n\njobs:\n  scan:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n      - uses: gitleaks/gitleaks-action@v2\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          GITLEAKS_CONFIG: .gitleaks.toml\n          GITLEAKS_ENABLE_COMMENTS: false\n          # Organization リポジトリで使う場合だけ追加\n          # GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}\n</code></pre><p><code>fetch-depth: 0</code> を入れているのは、履歴を見られる状態にするためです。<code>push</code> を <code>main</code> に絞っているのは、不要な実行を増やしすぎないためです。</p><h2 id=\"%E6%A4%9C%E7%9F%A5%E5%BE%8C%E3%81%AB%E3%82%84%E3%82%8B%E3%81%93%E3%81%A8\">検知後にやること</h2><p>検知して終わりにはしません。もし本物の secret が push 済みなら、回収とローテーションまでやれるようになると良いかなと思っていますが今回は割愛します。</p><h2 id=\"%E3%81%BE%E3%81%A8%E3%82%81\">まとめ</h2><p>AI エージェントで差分が増えるなら、機密情報対策は「気を付ける」だけでは足りないと考えてます。コミット前に止める。漏れたら CI でもう一度見る。その二段にしておくほうが、実際の運用はかなり楽になります。</p><p>git-secrets は今でも良いツールです。ただ、今回は AWS 以外も広く見たかったことと、Windows を含めて配りやすくしたかったことから、gitleaks に寄せました。</p><p>まずは pre-commit で止めるところから始めて、必要になったら CI と allowlist を育てていく。この順番がいちばん無理なく入れられるんじゃないかなと思います。</p>","url":"https://ghost.tech.anti-pattern.co.jp/ai-ezientodechai-fen-gazeng-etanode-secret-scanning-wo-pre-commit-ci-niji-setemita/","canonical_url":null,"uuid":"4925cd1b-bdc9-4bc3-b945-d8e3409001f4","page":null,"codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"69e7c6da781e37000184e786","reading_time":3}},"pageContext":{"slug":"ai-ezientodechai-fen-gazeng-etanode-secret-scanning-wo-pre-commit-ci-niji-setemita"}},
    "staticQueryHashes": ["176528973","2358152166","2561578252","2731221146","4145280475"]}