Secret Sentinel について
Secret Sentinel は、AIコーディングワークフロー向けのローカル秘密情報スキャン用MCPサーバー、コマンドラインツール、エージェントフックです。コード、Gitの変更、プロンプト、ツール呼び出し、エージェント設定の認証情報を検出し、会話ログに入る前に伏せ字にします。
主な機能
- 01Base64スキャンを含む64種類の検出器
- 02ファイル、ディレクトリ、Git変更、設定をスキャン
- 03テキストやツール出力の秘密情報を伏せ字化
- 04フックで危険なプロンプトやツール呼び出しを遮断
- 05アカウントやネットワーク通信なしでローカル実行
活用シーン
- 01コミット前にステージ済みの変更を確認する
- 02MCPとエージェントの設定ファイルを監査する
- 03プロンプト内の認証情報の送信を防ぐ
- 04ログを共有する前に秘密情報を伏せ字にする
MCP 対応
MCPサーバーはスキャン、伏せ字化、検出器一覧のツールに加え、ガイド付きプロンプトとパターンリソースを提供します。スキャンツールは読み取り専用として示され、構造化された結果を返します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
9掲載時のツール一覧 · 1 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| text | string | はい | |
| source_name | string | いいえ | |
| max_findings | integer | いいえ |
詳細
mcp-secret-sentinel
AI コーディングエージェント向けのローカルなシークレット保護機能です。 MCP サーバー、CLI、エージェントフックによって、API キー、トークン、秘密鍵、パスワードがコード、コミット、プロンプト、ツール呼び出し、MCP 設定に含まれていないかを、マシンの外に送信される前に検出します。検出器は64種類で、Base64にも対応し、検出結果はすべてマスキングされます。アカウント不要、ネットワーク呼び出しもありません。
シークレットが漏れる原因は、ハッカーよりもコミットであることが多く、今ではエージェント経由の漏えいも増えています。GitGuardian の State of Secrets Sprawl 2026 によると、2025年に公開 GitHub で新たに確認されたシークレットは2,865万件(前年比34%増)で、AI サービスのキーは81%増加しました。また、MCP 設定ファイルから24,008種類のシークレットが確認され、AI コーディングアシスタントと共同で作成したコミットでは漏えい率が高くなっています。.mcp.json に貼り付けたキー、cat .env の出力としてトランスクリプトに記録されたキー、エージェントが急いで設定ファイルに書き込んだキーは、次のコミットで削除したとしても、その時点で漏えいしたことになります。
Secret Sentinel は、こうした各場面にチェックポイントを設けます。
| 場面 | 防止するもの |
|---|---|
| エージェントが、追跡対象のファイル、シェルコマンド、MCP 呼び出しにキーを書き込もうとした場合 | エージェントフックがツール呼び出しを拒否します(Claude Code、Codex、Cursor) |
| プロンプトにキーを貼り付けた場合 | エージェントフックがモデルに届く前にプロンプトをブロックします |
ツールがキーを出力した場合(cat .env、設定ファイルの Read、詳細ログなど) | エージェントフックがモデルに表示される前に [REDACTED:<detector>] に置き換えます |
.mcp.json、claude_desktop_config.json、CLAUDE.md などにキーが含まれている場合 | **scan_agent_configs**がすべての MCP クライアントとエージェントのファイルを監査し、Git の追跡対象になっているものを警告します |
| コミットまたはプッシュによって公開されようとしている場合 | scan_git_staged / scan_git_range、pre-commit フック、GitHub Action が検出します |
| ログや出力を共有する必要がある場合 | **redact_text**がすべてのシークレットをマスキングし、それ以外はそのまま保持します |
シークレットの値が出力に表示されることは一切ないため、会話のトランスクリプトに含まれることもありません。
インストール
Claude Code プラグイン(スキル、エージェントフック、MCP サーバーを一度に導入):
/plugin marketplace add AleBrito124356/mcp-secret-sentinel
/plugin install secret-sentinel@secret-sentinel
フックはプラグインのチェックアウトから直接実行でき、Python 3.10 以降で動作します(標準ライブラリのみを使用します)。MCP サーバーの起動には uv を使用します。
MCP サーバーのみ(任意の MCP クライアント向け):
claude mcp add secret-sentinel -- uvx mcp-secret-sentinel
{
"mcpServers": {
"secret-sentinel": { "command": "uvx", "args": ["mcp-secret-sentinel"] }
}
}
CLI(Git フック、CI、スクリプト向け):pipx install mcp-secret-sentinel または pip install mcp-secret-sentinel を実行します。PyPI ではなく GitHub の最新コードを実行するには、uvx --from git+https://github.com/AleBrito124356/mcp-secret-sentinel mcp-secret-sentinel を使用します。
エージェントスキルのみ(Agensi、skills.sh、SKILL.md を読み込む任意のエージェント向け):スキルは skills/secret-sentinel にあります。スキャンを実行するタイミング、検出結果の修正方法、漏えいした認証情報のローテーション方法をエージェントに伝え、利用可能な場合は MCP ツールまたは CLI を使用します。
エージェントフック
mcp-secret-sentinel hook は、stdin から 1 つのフックイベントを JSON として読み取り、エージェントの判断を出力します。プラグインが自動で設定します。プラグインを使わない場合:
mcp-secret-sentinel install-agent-hooks --agent claude # .claude/settings.json (shared)
mcp-secret-sentinel install-agent-hooks --agent claude --scope local # .claude/settings.local.json
mcp-secret-sentinel install-agent-hooks --agent cursor # .cursor/hooks.json
インストーラーは既存の設定にマージし、他のすべてのフックを保持します。再実行すると、エントリが重複するのではなく、独自のエントリが更新されます。
| エージェントイベント | 動作 |
|---|---|
Claude Code / Codex の Write、Edit、MultiEdit、NotebookEdit、Bash、PowerShell、mcp__* ツールに対する PreToolUse | 新しいコンテンツ、コマンド、MCP 引数にシークレットが含まれる場合、呼び出しを拒否します(permissionDecision: "deny" と、シークレットを伏せた理由および修正方法を返します)。Git の無視対象ファイル(ローカルの .env など)や、リポジトリ外のファイルへの書き込みは許可されます。シークレットはそのような場所に置くものです。追跡対象の .env は引き続き保護されます。.secret-sentinel.toml、ベースライン、[tool.secret-sentinel] テーブルの編集には "ask" と応答するため、保護対象のエージェントが自らのガードをひそかに緩めることはできません。 |
UserPromptSubmit | プロンプトをブロックし、suppressOriginalPrompt を設定して、キーがブロックメッセージにそのまま出力されないようにします。 |
Read、Bash、PowerShell、Grep、WebFetch、mcp__* ツールに対する PostToolUse | 同じ形式を保った updatedToolOutput を返し、すべてのシークレットを置き換えます(秘密鍵はヘッダーからフッターまで全体を置き換えます)。さらに、シークレットを復元しようとしないようモデルに伝える注記を添えます。 |
Cursor の beforeShellExecution、beforeMCPExecution、beforeReadFile、beforeSubmitPrompt | シークレットを伏せたメッセージとともに、permission: "deny" / continue: false を返します。 |
デフォルトでは、フックは high および critical の検出結果をブロックし、medium の検出結果(JWT、高エントロピー文字列)は許可します。hook --fail-on medium を指定すると、より厳格になります。.secret-sentinel.toml の除外パスは尊重されます。コンソールのコードページにかかわらず、イベントは UTF-8 として読み取られるため、Windows でもアクセント記号を含むプロジェクトパスを扱えます。予期しない事態(不正な JSON、設定の破損、内部エラー)が発生した場合は、ブロックしない終了ステータスでフェイルオープンし、フックがエージェントの動作を妨げないようにします。「リポジトリではありません」以外の Git エラーが発生しても、スキャンは続行されます。独自の MCP ツールは、意図的にシークレットを受け取るため、スキャン対象外です。
MCP ツール
| ツール | 引数 | 戻り値 |
|---|---|---|
scan_text | text, source_name="input", max_findings=200 | 生のスニペット(コード、設定、差分、ログ)の検出結果 |
scan_file | path, max_findings=200 | 1 つのファイルの検出結果。BOM に基づいて UTF-8/16/32 をデコードし、バイナリファイルと 5 MB を超えるファイルはスキップします |
scan_directory | path, max_files=500, max_findings=200 | 再帰的なスキャン。Git リポジトリ内では、ファイル一覧を Git 自体から取得します(各 .gitignore、否定パターン、グローバル除外設定がすべて適用されます) |
scan_git_staged | repo_path, max_findings=200 | git diff --cached で追加された行のみ。次のコミットで公開される内容そのものです |
scan_git_range | repo_path, base="@{upstream}", head="HEAD", max_commits=200, max_findings=200 | base..head のコミット。デフォルトでは、次の git push で公開される内容そのものです |
scan_git_history | repo_path, max_commits=50, all_branches=false, max_findings=200 | 直近 N 件のコミット(HEAD、またはすべてのブランチ、タグ、スタッシュ)で追加された行。それぞれの行にコミット情報が付与されます |
scan_agent_configs | project_path, include_user=true, include_transcripts=false, max_findings=200 | MCP クライアントの設定ファイルとエージェント指示ファイルの監査(以下を参照) |
redact_text | text | {"text", "redactions", "by_pattern"}:すべてのシークレットを [REDACTED:<detector>] に置き換えたテキスト |
list_patterns | — | 重要度と修正方法のアドバイスを含む有効な検出器、および許可リストのルール |
すべてのツールには読み取り専用の注釈(readOnlyHint、オープンワールドアクセスなし)が付いているため、クライアントは確認プロンプトなしで実行できます。スキャンツールは outputSchema を公開し、structuredContent を返します(MCP SDK 1.10+ / 2.x)。サーバーは 3 つのプロンプト pre_push_check、leak_response、audit_agent_configs と、secret-sentinel://patterns リソースも提供します。
すべてのスキャンツールは同じ形式を返します。
{
"clean": false,
"findings": [
{
"file": "config/notify.yaml",
"line": 14,
"pattern": "Slack incoming webhook",
"severity": "high",
"redacted": "hook…(77 chars)",
"advice": "Anyone with this URL can post messages to your workspace. Regenerate the webhook in your Slack app settings and load the URL from an environment variable."
}
],
"files_scanned": 6,
"summary": "Found 1 potential secret(s) across 6 scanned file(s): 1 high. Do NOT commit or push until these are removed or rotated."
}
インラインコメントによって検出結果が抑制された場合は suppressed が、ベースラインによって一部が許容された場合は baselined が追加されます。応答サイズの制限: 各スキャンが一覧表示する検出結果は最大 max_findings 件です(デフォルトは 200 件、重要度の高い順、0 = 無制限)。結果を切り詰める必要がある場合、レポートには truncated: true が示され、total_findings、counts_by_severity、counts_by_pattern、top_files が保持されます。そのため、検出結果の多いツリーでエージェントのコンテキストがあふれることはありません。
エージェントと MCP クライアントの設定の監査
scan_agent_configs(CLI:mcp-secret-sentinel agents [PROJECT])は次を確認します。
- プロジェクトファイル:
.mcp.json、.claude/settings.json、.claude/settings.local.json、.cursor/mcp.json、.vscode/mcp.json、.vscode/settings.json、.gemini/settings.json、.codex/config.toml、.windsurf/mcp.json、.amazonq/mcp.json、.kiro/settings/mcp.json、.roo/mcp.json、opencode.json、およびエージェント指示ファイルCLAUDE.md、CLAUDE.local.md、AGENTS.md、GEMINI.md、.cursorrules、.windsurfrules、.github/copilot-instructions.md。それぞれについて、Git に追跡されているかどうかを報告します。 - ユーザーファイル:Claude Code(
~/.claude.json、~/.claude/settings.json、~/.claude/CLAUDE.md)、Claude Desktop、Cursor、VS Code、Cline、Windsurf、Gemini CLI、Codex、Amazon Q、Kiro、Continue、Zed、opencode、Goose、LM Studio。 - セッショントランスクリプト(オプトイン):最新の Claude Code と Codex の
*.jsonlログ。ここで見つかったキーは、モデルプロバイダーにも送信されたものです。
検出結果があるファイルには、そのクライアントでリテラルの代わりに環境変数を参照する方法を示す hint が付きます。たとえば、Claude Code の .mcp.json では "env": {"API_KEY": "${API_KEY}"}、VS Code では ${input:...} のプロンプトが例として示されます。
検出対象
64 個の正規表現検出器に加え、エントロピー検査と Base64 デコードを実行します。
| ファミリー | 検出器 |
|---|---|
| AI と LLM | OpenAI(sk-proj-、sk-svcacct-、sk-admin-、レガシー形式)、Anthropic、xAI、DeepSeek 形式の sk-<hex>、Perplexity、OpenRouter、Groq、NVIDIA、Hugging Face、Replicate、Together AI、Cerebras、AWS Bedrock API キー |
| LLM ツール | LangSmith、Langfuse、Pinecone、Firecrawl、Tavily |
| コードホスティングとパッケージ | GitHub(ghp_、gho_、ghu_、ghs_、ghr_、github_pat_)、GitLab(glpat-、glptt-、gldt-、glrt-)、npm、PyPI |
| クラウドとインフラストラクチャ | AWS アクセスキーとシークレットキー、Azure ストレージキー、Google API キーと OAuth クライアントシークレット、DigitalOcean、Cloudflare、Vercel、Supabase(sb_secret_、sbp_)、Neon、PlanetScale、Fly.io、Databricks、HashiCorp Vault、Doppler |
| 決済、メッセージング、SaaS | Stripe の本番用キー、Square、Shopify、SendGrid、Resend、Mailchimp、Twilio、Slack トークンと Webhook、Discord Webhook、Telegram ボット、Linear、Notion、Atlassian、Postman、Sentry、Grafana、PostHog |
| キーとトークン | 秘密鍵ブロック(RSA、EC、DSA、OPENSSH、PGP、暗号化済み)、age の秘密鍵、JWT |
| URL 内の認証情報 | データベースおよびキューの接続文字列(Postgres、MySQL/MariaDB、MongoDB、AMQP、Redis)、および user:password@ を含む http(s)/ftp/smtp URL |
| 汎用 | 引用符で囲まれたコード内の password/secret/api_key/token 形式の代入、および dotenv 形式の UPPER_CASE=value 行 |
- エントロピー:特定の検出器が該当箇所を検出していない場合に、変数へ代入された 20 文字以上の引用符付き文字列で、実測エントロピーが 1 文字あたり 4.5 ビット以上のもの。
- Base64:20 文字以上の Base64 文字(標準または URL セーフ)の連続部分が印字可能なテキストにデコードされる場合、1 回デコードして再スキャンします。これにより、Kubernetes Secret マニフェスト、Basic 認証ヘッダー、エンコードされた PEM キー内の認証情報も検出できます。検出結果には内部の検出器名に
(base64)が付きます。 - 形式は gitleaks、betterleaks、trufflehog のルールセットに由来します。公開を前提とした
sb_publishable_キーは報告されません。
URL 内の認証情報については、報告される値はパスワードです。許可リストではパスワードだけを判定します。postgres://app:<literal>@${DB_HOST}/app も引き続き報告されます。
意図的に無視するもの(許可リスト)
各候補値は、報告前に次のヒューリスティックでチェックされます。
- 短すぎる値:8 文字未満の値。
- マスクされた値:値の大部分(80% 以上)が
X、x、*、またはドットであるもの。ベンダーのプレフィックスの後にXXXX…が続く場合も含みます。 example、placeholder、changeme、your-…-here のマーカー、および<angle brackets>。- テンプレート:
${VAR}、{{ jinja }}、{% … %}、<%= … %>、#{…}。 - 変数参照:値が
$UPPER_CASE_VAR、$(command)、$env:VAR、または%VAR%だけであるもの。 - 書式プレースホルダー:
%(name)sまたは{name}。 - 環境変数の参照:
os.environまたはprocess.envを参照する値。 - 汎用の代入およびエントロピーのみの検出:リテラルではなくコードであるもの(
os.getenv("X")、settings.DB_PASSWORD、SECRETS[0]、文字列結合の片側など)、正規表現のような形式の値(^(Write|Edit)$、[a-z]{32})、認証情報、クエリ、フラグメントを含まない通常のリンク、エージェント設定を埋めるファイルシステムのパス(C:\Users\...、~/...、/usr/local/...)。これらのルールがベンダー形式に適用されることはありません。 - 予約済みのドキュメント用ホスト:
example.com/.net/.org、*.example、または*.invalidを指す、認証情報付き URL。
インライン抑制
TEST_DSN = "postgres://ci:ci-only-password@db:5432/test" # secret-sentinel: ignore
detect-secrets の pragma: allowlist secret と gitleaks の gitleaks:allow も機能するため、これらのツール向けに注釈済みのファイルは変更不要です。マーカーは大文字と小文字を区別せず、記述された行のみを対象とし、ステージ済みの行とコミット済みの行に適用されます。抑制された検出結果は suppressed に計上され、黙って隠されることはありません。
プロジェクト設定
mcp-secret-sentinel init は、コメント付きの .secret-sentinel.toml を作成します。同じキーは、pyproject.toml の [tool.secret-sentinel] テーブルでも使用できます。設定ファイルはスキャン対象のパスから上位へ検索され、リポジトリのルートで停止します。CLI、MCP ツール、エージェントフックのすべてに適用されます。
exclude_paths = ["tests/fixtures/**", "*.snap"] # globs relative to this file; ** spans directories
allowlist = ["^sk_test_"] # regexes matched against the secret value
disable = ["JSON Web Token"] # detector names, "High-entropy string" included
baseline = ".secret-sentinel-baseline.json" # optional
[[rules]]
name = "Acme internal token"
regex = 'acme_[a-f0-9]{32}'
severity = "critical" # critical | high | medium
advice = "Revoke it in the Acme console."
不明なキー、不明な検出器名、無効な正規表現は、ファイル名とキーを示すエラーになります。そのため、タイプミスによってスキャンの保護が気付かないうちに弱まることはありません。カスタムルールは組み込みの検出器より先に実行され、SARIF では独自のルールとして表示されます。
ベースライン
既存のリポジトリにスキャナーを導入する場合、通常はいくつか既知の検出結果(古いテスト用フィクスチャ、失効したキーなど)が見つかります。それらを確認してから、承認します。
mcp-secret-sentinel baseline # writes .secret-sentinel-baseline.json
以降のスキャンでは、ベースラインにないシークレットのみが報告され、残りは baselined にカウントされます。このファイルには各値のソルト付き PBKDF2 フィンガープリント(値そのものや高速ハッシュは保存されません)に加えて、レビュアーの参考用にファイルと行が保存されます。一致判定では行を無視するため、周囲のコードが移動しても承認済みの値は引き続き承認されます。検出されるヘッダーがすべての鍵で同じになる秘密鍵については、ファイル名も照合対象になります。このファイルはスキャン対象の場所に書き込まれます。設定の baseline パスが指定されていればそこに、指定されていなければプロジェクトルートに保存されます。コミットしてください。scan --no-config はこのファイルを無視します。
コマンドライン
mcp-secret-sentinel は引数なしで起動すると stdio サーバーを開始するため、MCP クライアントの設定を一語のままにできます。コマンドを指定すると CLI として動作します。
mcp-secret-sentinel scan # the current directory
mcp-secret-sentinel scan src config/app.yaml # files and directories
git diff | mcp-secret-sentinel scan - # stdin
mcp-secret-sentinel scan --staged # what the next commit would add
mcp-secret-sentinel scan --range # what the next push would publish (@{upstream}..HEAD)
mcp-secret-sentinel scan --history 100 --all-branches
mcp-secret-sentinel scan --format sarif -o secrets.sarif
mcp-secret-sentinel redact app.log > app.redacted.log
mcp-secret-sentinel agents . # audit agent / MCP client configs
mcp-secret-sentinel install-hook # git pre-commit hook
mcp-secret-sentinel install-agent-hooks --agent claude
mcp-secret-sentinel baseline
mcp-secret-sentinel init
mcp-secret-sentinel patterns # detectors, allowlist rules, suppression markers
$ mcp-secret-sentinel scan src
src/billing.py:2 [critical] Stripe live key sk_l…(32 chars)
Roll the key in the Stripe Dashboard (Developers -> API keys). Live keys grant access to real payment data.
src/notify.py:3 [high] Slack incoming webhook hook…(69 chars)
Anyone with this URL can post messages to your workspace. Regenerate the webhook in your Slack app settings and load the URL from an environment variable.
Found 2 potential secret(s) across 2 scanned file(s): 1 critical, 1 high. Do NOT commit or push until these are removed or rotated.
オプション(scan) | 説明 |
|---|---|
--format text|json|sarif | 人間向けのレポート(デフォルト)、MCP JSON レポート、または SARIF 2.1.0 |
--fail-on critical|high|medium | 終了ステータスを 1 にする最低深刻度(デフォルトは medium、つまり検出結果があれば該当) |
--max-findings N | 深刻度の高い順に最大 N 件の検出結果を一覧表示します(デフォルトは 200、0 は上限なし、SARIF は指定がない限りすべてを一覧表示します) |
--max-files N | ディレクトリのスキャンを N 個のファイルで停止します(デフォルトは 5000) |
--max-commits N | --range と併用し、直近の N 件のコミットまでスキャンします(デフォルトは 200) |
--config FILE / --no-config | 指定した設定を使用するか、設定とベースラインを無視します |
--baseline FILE | FILE に記録された検出結果を承認します |
-o, --output FILE | レポートをファイルに書き込みます。一行の要約は stderr に出力されます |
終了ステータス: 0 問題なし(または --fail-on 未満の検出結果のみ)、1 --fail-on 以上の検出結果あり、2 使用法エラー(不正なオプション、パスの指定漏れ、Git リポジトリではない、リビジョンが不明、設定の破損)。すべての形式で出力は秘匿化されます。
Git フックでコミットをブロックする
mcp-secret-sentinel install-hook # in the repository, or: install-hook path/to/repo
.git/hooks/pre-commit(または core.hooksPath が指すディレクトリ)に書き込みます。このフックはインストールに使用した Python で scan --staged を実行するため、ステージされた行にシークレットが含まれている間はコミットが拒否されます。git commit --no-verify を使うと、その回に限りフックをスキップできます。インストーラーは --force を指定しない限り、ほかのツールのフックを上書きしません。指定した場合は、既存のフックを pre-commit.bak として保存します。
pre-commit フレームワークを使用する場合:
repos:
- repo: https://github.com/AleBrito124356/mcp-secret-sentinel
rev: v0.3.0
hooks:
- id: secret-sentinel
GitHub Action
name: secrets
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write # for the SARIF upload
steps:
- uses: actions/checkout@v4
- uses: AleBrito124356/[email protected]
with:
fail-on: high # critical | high | medium
# range: origin/main..HEAD # scan only new commits (checkout with fetch-depth: 0)
use-config: ${{ github.event_name != 'pull_request' }} # a PR could edit the config
このアクションは、秘匿化された SARIF レポートをコードスキャンに書き込み(各検出器につき 1 つのルールと security-severity を含む)、テキストレポートをジョブの概要に追加し、fail-on 以上の検出結果があるとステップを失敗させます。スキャンを実行できない場合(範囲の指定が不正、浅いクローン、設定の破損など)は、検出結果として報告するのではなく、専用のエラーで失敗します。CLI で --format sarif を指定すると、ほかの CI でも同じ SARIF 2.1.0 ログを生成できます。
仕組み
flowchart TD
A[Agent hook, MCP tool or CLI] --> B{Source}
B -->|text / file| C[Decode by BOM, split on newline only]
B -->|directory| D[git ls-files, or a walk outside git;<br/>skip caches, envs, binaries, lockfiles,<br/>config excludes] --> C
B -->|staged / range / history| E[git diff / git log -p, zero context,<br/>diff config overridden, no external programs] --> P[Hunk-counting parser:<br/>added lines, real paths, commit tags] --> C
C --> S{Inline marker?}
S -->|yes| U[Counted in suppressed]
S -->|no| F[Custom rules, then 64 detectors;<br/>specific patterns claim spans first]
F --> G[Base64 runs decoded and rescanned]
G --> H2[Entropy >= 4.5 bits/char on<br/>assigned strings of 20+ chars]
H2 --> H{Allowlist: placeholders, templates,<br/>variables, code, regexes, config allowlist}
H -->|placeholder| I[Dropped]
H -->|real candidate| BL{In the baseline?}
BL -->|yes| BB[Counted in baselined]
BL -->|no| J[Redact: at most 4 chars and<br/>a quarter of the value, + length]
J --> K[Report, SARIF, hook decision<br/>or REDACTED marker]
エンコーディングと行番号
ファイルはバイナリチェックの前に、バイトオーダーマーク(UTF-8、UTF-16 LE/BE、UTF-32)に基づいてデコードされます。また、BOM のない UTF-16 も認識されるため、Windows PowerShell 5.1 の > や Out-File の出力もスキップされずにスキャンされます。行の分割には \n のみを使用するため、行内のフォームフィード、\x85、U+2028、U+2029 によって報告される行番号がずれることはありません。
編集保証
各検出結果に表示されるのは、先頭の最大4文字、値全体の4分の1を超えない文字数、および合計文字数です。例:"hook…(77 chars)"、"Tr…(8 chars)"。完全な値が出力、トランスクリプト、フックの判定、ログに現れることはありません。これはコード内の単一の redact() 集約ポイントと、シリアライズされた結果、フックの判定、構造化コンテンツを含む実際の MCP 標準入出力トラフィックに生の値が含まれないことを検証するテストスイートによって保証されています。
Git スキャンは差分設定ではなくテキストを読み取ります
Git ツールは git diff / git log -p の出力を解析しますが、ローカル設定によって出力が変わる可能性があります。外部差分ツールは差分を置き換え、diff.mnemonicPrefix や diff.noprefix はファイル名を壊します。そのため、すべての Git 呼び出しで --no-ext-diff --no-textconv --src-prefix=a/ --dst-prefix=b/ -U0 --inter-hunk-context=0 --no-color を渡し、-c で core.quotePath、core.fsmonitor、diff.noprefix、diff.mnemonicPrefix、diff.relative、diff.submodule、log.showSignature、log.showRoot を上書きし、GIT_EXTERNAL_DIFF / GIT_DIFF_OPTS を除外し、任意のロックを取得せず、標準入力を閉じ、- で始まるリビジョンを拒否します。差分パーサーはハンクの行数に基づくステートマシンです。そのため、+++ something と書かれた追加行はコンテンツとして扱われ、ファイルヘッダーとして扱われることはありません。
制限事項
- 検証ではなく正規表現による検出:検出結果はプロバイダーに照会して確認されません(照会すると秘密情報がネットワーク経由で送信されるためです)。何百ものルールと任意のライブ検証を備えた gitleaks、betterleaks、trufflehog などの専用スキャナーもパイプラインに組み込んでください。これは、エージェントがコミット前に実行する高速なローカルチェックポイントです。
- Git の外では、ルートの
.gitignoreにある単純なパターンのみが適用されます(否定パターン、**、ネストされたファイルは対象外です)。Git 作業ツリー内では、ファイル一覧は Git から取得され、すべてのルールが適用されます。 - エントロピーには多様性が必要です:4.5 ビット/文字の基準を満たすには、候補に少なくとも23種類の文字が必要です。短いランダム文字列は、代わりに正規表現検出器で検出されます。
- 引用符で囲まれていない一般的な代入は、dotenv 形式の
UPPER_CASE=value行でのみ検出されます。これは誤検出との意図的なトレードオフです。 - 行単位の照合:複数行にまたがる秘密情報は、最初の行(
BEGIN PRIVATE KEYヘッダーなど)でのみ検出されます。Base64 は1段階までデコードされます。 - インライン抑制は同じ行に限られます。コンテキストがゼロの差分では、通常、1行上が表示されないためです。
- マージコミットは差分対象外です(
git log -pのデフォルト動作)。そのため、コンフリクト解決時にのみ導入された秘密情報は、範囲スキャンと履歴スキャンでは検出されません。scan_git_stagedは、マージコミットの作成前に引き続き検出できます。 - Git 内のバイナリファイルはスキャンされません。概要にはファイル名が表示されます。
- Cursor のフックサポートは、公開されている Cursor のフックプロトコルに準拠しています。Claude Code のフックは、実際のパイプを使ったエンドツーエンドテストでカバーされています。
開発
git clone https://github.com/AleBrito124356/mcp-secret-sentinel
cd mcp-secret-sentinel
pip install -e ".[dev]"
python -m pytest
ソースツリーから python -m mcp_secret_sentinel を実行すると、CLI(引数なしでは MCP サーバー)が起動します。core.py、config.py、agents.py、hooks.py は標準ライブラリのみを使用し、server.py に MCP の接続処理が含まれています。
テストスイートには、現実的な秘密情報のリテラルは一切含まれていません。肯定テストのすべてのフィクスチャは実行時に文字列を連結して組み立てられ、リポジトリをスキャンしてクリーンであることを必須とするテストもあります。すべての検出器、許可リスト、Base64 デコード、エントロピー、編集、エンコーディング、行番号、実際のリポジトリを使った Git 解析、サブプロセスとしての CLI、フックの判定(プラグインのシェルランチャー経由を含む)、エージェント設定の監査、設定とベースライン、および SDK 独自のクライアントを使った実際の標準入出力経由での MCP サーバー(構造化出力を含む)をテストします。CI では、Linux、Windows、macOS 上で、Python 3.10~3.13、および MCP SDK の両方のメジャーバージョンを対象にテストを実行します。
関連する MCP サーバー
依存関係を抑えた小規模な MCP サーバー群の一部です。
- mcp-decision-lab:感度分析を備えた重み付き意思決定マトリックス
- mcp-devils-advocate:悪魔の代弁者、プレモーテム、前提条件の監査で主張をストレステストします
- mcp-git-historian:変更頻度の高い箇所、blame の要約、バス係数
- mcp-memory-vault:SQLite FTS5 検索を備えた永続メモリ
ライセンス
MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。