# Secrets scanning

> **Warning:** This product is in Beta stage and we may release breaking changes.

Hardcoded credentials in source code are one of the most common and most preventable security incidents. The SonarQube CLI ships secrets scanning in three forms, each tuned for a different moment in the developer workflow:

* **Ad-hoc:** `sonar analyze secrets` scans files or stdin from your terminal or a script.
* **Git layer:** `sonar integrate git` installs a hook that blocks commits or pushes containing secrets.
* **AI agent layer:** `sonar integrate claude` installs a `UserPromptSubmit` hook (scans the prompt you send to Claude) and a `PreToolUse` hook (runs before file reads/writes). `sonar integrate copilot` installs a pre-tool-use hook. `sonar integrate codex` installs a `UserPromptSubmit` hook for Codex. These integrations block any operation that would expose a secret.

You can use any combination of the three.

## Prerequisites

* [The SonarQube CLI is installed and authenticated](/sonarqube-developer-tools/sonarqube-cli/quickstart-guide.md).

Secrets scanning runs **locally** on your machine. No code leaves your machine for the scan itself.

## Scan on demand

`sonar analyze secrets` reads files (or standard input) and reports any hardcoded credentials it finds. Use it to check a file before committing, audit an `.env` file, or run as part of a CI step.

### Scan a single file

```bash
sonar analyze secrets src/config.ts
```

### Scan multiple paths or a directory

```bash
sonar analyze secrets src/ infra/
```

### Scan from standard input

```bash
cat .env | sonar analyze secrets --stdin
```

### Use in a script

The command exits with code `51` when it finds secrets and `0` when it finds none. Wire it into any pipeline:

```bash
sonar analyze secrets .
if [ $? -eq 51 ]; then
  echo "Secrets found — failing the build."
  exit 1
fi
```

See [Exit codes](/sonarqube-developer-tools/sonarqube-cli/using-sonarqube-cli/exit-codes.md) for the full table.

## Block secrets at the Git layer

Install a Git hook so commits or pushes containing secrets are rejected before they reach a remote:

```bash
sonar integrate git --hook pre-commit
```

Pre-push hooks and global (machine-wide) installation are also supported. For setup, hook behavior with Husky and the pre-commit framework, and override options, see [Git hooks](/sonarqube-developer-tools/sonarqube-cli/integrations/git-hooks.md).

## Block secrets at the AI agent layer

When you give an AI coding assistant access to your repository, it can accidentally exfiltrate secrets by reading and including them in prompts sent to the model provider. The SonarQube CLI prevents this by installing a hook that runs **before** the agent reads or writes files.

* **Claude Code:** [Claude Code](/sonarqube-developer-tools/sonarqube-cli/integrations/claude-code.md)
* **GitHub Copilot:** [GitHub Copilot](/sonarqube-developer-tools/sonarqube-cli/integrations/github-copilot.md)

After installation, restart the agent. From then on, any attempt by the agent to access a file containing a secret is blocked, and the agent is told why.

## False positives and tuning

Secrets scanning is intentionally sensitive; missing a real credential is much worse than catching test fixtures. The analyzer already ignores obviously fake values, so most false positives come from test fixtures that look like real provider-issued credentials.

When that happens:

* **Keep realistic-looking test fixtures outside of source.** Move them into ignored files (`.env.test`) or fixture directories outside `src/`.
* **Use environment variables in tests** where possible, even when the value is a fake.

If you believe a finding is genuinely wrong, share it on the [community forum](https://community.sonarsource.com/tag/secrets); we use these reports to tune detection.

### Allowlist known secrets

`sonar analyze secrets` can ignore a known credential, for example a test fixture that genuinely looks like a real provider-issued token. Secrets are stored as SHA-256 hashes on disk; the file lives next to the CLI binary by default and can be relocated via the `SONAR_SECRETS_CACHE_DIR` environment variable.

| Subcommand                                          | Description                                                                                                                |
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `sonar analyze secrets allowlist add [--key <key>]` | Add a secret interactively or via stdin. The optional `--key` flag provides a human-readable identifier (`[0-9a-zA-Z_-]`). |
| `sonar analyze secrets allowlist remove`            | Remove an entry by its key.                                                                                                |
| `sonar analyze secrets allowlist show`              | List all allowlisted keys.                                                                                                 |
| `sonar analyze secrets allowlist clear`             | Remove all entries from the allowlist.                                                                                     |

### Surface low-confidence findings

By default the scanner silently drops candidates that look like placeholders (e.g. `password`, `letmein`) and skips files that look like tests. For benchmarking, evaluation, or to investigate why an expected secret is not reported, two flags surface these as **low-confidence** findings, with the filter name appended to the issue message:

| Flag                            | Effect                                                                                                                                                                                                                                    |
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--disable-entropy-filter`      | Low-entropy matches that would normally be silently dropped are reported as low-confidence issues. Useful for benchmark or evaluation projects.                                                                                           |
| `--disable-test-file-detection` | Files automatically identified as test files are no longer filtered out. Findings in those files are reported but marked as low-confidence. Has no effect on files explicitly declared as tests via the SonarQube `sonar.tests` property. |

### Custom secret rules from SonarQube Server

When the SonarQube CLI is authenticated against a SonarQube Server instance, it automatically downloads and executes custom secret rules (instances of the rule template **S6784**) defined on that server. Rules are cached locally and refreshed on each run. If the download fails, the SonarQube CLI falls back to a stale cache with a warning. No CLI flag is required; the feature activates automatically when the SonarQube CLI is authenticated.

> **Note:** Custom secret rules are not yet available on SonarQube Cloud. Support is planned.

## What the scanner looks for

Secrets scanning uses the same engine that powers SonarQube's server-side secret detection rules. It looks for patterns issued by major providers (AWS, GCP, GitHub, Stripe, SonarQube tokens, and many more) as well as generic high-entropy strings used in credential-shaped contexts.

## Why an obvious "password" is not always reported

Secrets scanning is a layered pipeline that intentionally filters aggressively to keep false-positive rates low. Working through the layers, common reasons a hardcoded value is not reported:

1. **The file extension is in the rejected-extensions list.** For example, `.md`, `.mdx`, `.html`, `.adoc`, `.example`, `.sample`, `.template`, `.dist` are skipped by every rule. This is the most likely reason.
2. **The value is a simple word** (e.g. `password`, `mypassword`, `123456`), rejected by the fake-password filter.
3. **The value has low entropy** (e.g. `letmein`, `abc123def`), rejected by the entropy filter. Pass `--disable-entropy-filter` to surface it as a low-confidence finding.
4. **The file is in a `docs/` or `test/` directory**, or is named like a test file, silently skipped by automatic test-file detection. Pass `--disable-test-file-detection` to surface findings in those files as low-confidence.
5. **The file extension is not in the inclusions list** (and the file has no assigned language), never reached by the scanner at all.

All of these layers are intentional. The goal is to surface real, leaked credentials, not every string that looks vaguely secret-like.

## Feedback

Found a false positive, a crash, or a pattern that should be detected? Tell us on the [Sonar Community forum, secrets tag](https://community.sonarsource.com/tag/secrets).

## Related pages <a href="#related-pages" id="related-pages"></a>

* [Git hooks](/sonarqube-developer-tools/sonarqube-cli/integrations/git-hooks.md)
* [Claude Code](/sonarqube-developer-tools/sonarqube-cli/integrations/claude-code.md)
* [GitHub Copilot](/sonarqube-developer-tools/sonarqube-cli/integrations/github-copilot.md)
* [Exit codes](/sonarqube-developer-tools/sonarqube-cli/using-sonarqube-cli/exit-codes.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.sonarsource.com/sonarqube-developer-tools/sonarqube-cli/analysis/secrets-scanning.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
