Security

Secrets Scanner

Find credentials, API keys, and tokens accidentally committed to a diff or repo, distinguishing real secrets from test fixtures and placeholders.

When to use this

  • Before every commit that touches config, environment setup, or connection strings, as a habit.
  • After discovering one leaked secret, to sweep for others of the same kind.
  • Not a substitute for a dedicated pre-commit secrets-scanning tool (gitleaks, trufflehog) where one is configured -- this is the manual/explanatory version.

The skill file

Copy this verbatim. It's written in the SKILL.md format (YAML frontmatter + markdown instructions) that Claude Code, and increasingly other agent tools, read directly.

SKILL.md
---
name: secrets-scanner
description: Scan a diff or file set for accidentally committed credentials, API keys, tokens, and private keys, distinguishing real secrets from test fixtures, examples, and placeholders. Use before committing config/infra changes or when auditing a repo for leaks.
---

# Secrets Scanner

## What to look for

- High-entropy strings assigned to variables named like `key`, `secret`,
  `token`, `password`, `credential`, `connectionString`.
- Known credential shapes: cloud provider access keys, private key PEM
  blocks, database connection URIs with embedded passwords, JWT-looking
  strings, webhook URLs with embedded tokens.
- `.env` files or config files that shouldn't be tracked, based on the
  repo's `.gitignore` intent.

## Distinguishing real secrets from noise

- A value in a `*.example`, `*.sample`, or clearly-named test fixture file
  using an obviously fake value (`sk-test-xxxx`, `password123` in a unit
  test) is not a finding.
- A placeholder that's structurally a real secret shape but is a
  well-known public example (documentation sample keys) is low-priority,
  note it but don't treat it as urgent.
- If genuinely unsure whether a value is real, say so and ask, rather than
  either suppressing it or crying wolf.

## If a real secret is found

1. Flag it immediately, with exact file:line.
2. State clearly that committing the fix (removing it from the current
   diff) is not sufficient if it was ever pushed -- the secret must be
   rotated, because it's already in git history.
3. Don't print the full secret value back in your output; reference it by
   location and a truncated/masked form.

## Output

List of findings (file:line, credential type, confidence), and for any
confirmed real secret, an explicit rotate-it reminder.

Installing it elsewhere

The frontmatter/body split above is Claude Code's convention. Here's how to carry the same instructions into other tools:

Claude Code
.claude/skills/secrets-scanner/SKILL.md

Save the file below verbatim (frontmatter included) at that path, project-local or in ~/.claude/skills/ for a user-level skill. Claude Code loads the name/description pair to decide when to pull it in, or you invoke it directly as /secrets-scanner.

Cursor
.cursor/rules/secrets-scanner.mdc

Convert the YAML frontmatter to Cursor's rule format (description, globs, alwaysApply: false) and keep the markdown body as the rule content. Cursor surfaces it by description match, same idea as Claude Code's auto-load.

Codex CLI / Copilot
AGENTS.md

Codex CLI (and increasingly other agentic CLIs) read AGENTS.md at the repo root as always-on instructions. Paste the markdown body under a heading like ## {title}; for GitHub Copilot's coding agent, the equivalent file is .github/copilot-instructions.md.

Windsurf
.windsurfrules

Append the markdown body to .windsurfrules at the repo root. Windsurf treats the whole file as always-on context, so keep only the instructions you want applied on every request.

Where this goes wrong
  • Printing the full secret value in the review output -- that just duplicates the leak into a second location (logs, chat history).
  • Treating "I removed it from the diff" as the fix -- if it was ever committed and pushed, it must be rotated.
  • Flooding the report with low-confidence test-fixture matches, burying the one real finding.