recon_git_secrets
Scan git repository history to detect exposed secrets in commit messages, author information, branches, and deleted files for security auditing.
Instructions
Search git history for secrets: commit messages, author info, branches, deleted files. Returns secrets_in_code_history, unique_authors, branches, deleted_files_summary, and suspicious_commit_messages. Read-only git operations on local repository.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| repo_path | Yes | Path to the git repository |
Implementation Reference
- src/tools/recon.ts:373-444 (handler)The `recon_git_secrets` tool handler is defined here. It performs git operations to search for secrets, list authors/branches/deleted files and scan commit messages for sensitive keywords within a local git repository.
server.tool( "recon_git_secrets", "Search git history for secrets: commit messages, author info, branches, deleted files. Returns secrets_in_code_history, unique_authors, branches, deleted_files_summary, and suspicious_commit_messages. Read-only git operations on local repository.", { repo_path: z.string().describe("Path to the git repository"), }, async ({ repo_path }) => { requireTool("git"); const repo = path.resolve(repo_path); if (!fs.existsSync(path.join(repo, ".git"))) { const result = { error: `Not a git repository: ${repo}` }; return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; } // Search commit content for secrets const secretPatterns = [ "password", "secret", "api_key", "apikey", "token", "private_key", "aws_access", "aws_secret", ]; const secretHits: string[] = []; for (const pattern of secretPatterns) { const res = await runCmd( "git", ["-C", repo, "log", "--all", "-S", pattern, "--oneline"], { timeout: 30 } ); if (res.stdout) { for (const line of parseLines(res.stdout).slice(0, 5)) { secretHits.push(`[${pattern}] ${line}`); } } } // Author enumeration const authors = await runCmd( "git", ["-C", repo, "log", "--format=%an <%ae>", "--all"], { timeout: 15 } ); const uniqueAuthors = [...new Set(parseLines(authors.stdout))]; // All branches const branches = await runCmd( "git", ["-C", repo, "branch", "-a"], { timeout: 10 } ); // Deleted files const deleted = await runCmd( "git", ["-C", repo, "log", "--diff-filter=D", "--summary", "--all", "--oneline"], { timeout: 30 } ); // Commit messages with keywords const msgHits = await runShell( `git -C '${repo}' log --all --oneline 2>/dev/null | grep -iE 'key|secret|password|credential|token|fix.*leak' | head -20` ); const result = { secrets_in_code_history: secretHits.slice(0, 50), unique_authors: uniqueAuthors.slice(0, 30), branches: parseLines(branches.stdout).slice(0, 30), deleted_files_summary: parseLines(deleted.stdout).slice(0, 30), suspicious_commit_messages: parseLines(msgHits.stdout).slice(0, 20), }; return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; } );