> ## Documentation Index
> Fetch the complete documentation index at: https:// zenveil.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Secrets Scanner

> Detect hardcoded credentials, exposed tokens, and OWASP security patterns in your codebase.

## Overview

The secrets scanner is ZenVeil's most comprehensive detector. It runs on `scan repo` and `scan github` targets and covers two categories:

1. **Credential patterns** — actual secrets that should never appear in source code
2. **Repository risk patterns** — OWASP anti-patterns that create security debt

## Credential patterns

These findings are always CRITICAL or HIGH severity. They indicate live credentials committed to source.

| Pattern | Severity | Confidence | Description |
| - | - | - | - |
| AWS access key | CRITICAL | 95% | `AKIA` + 16 alphanumeric characters |
| GitHub token | CRITICAL | 95% | `ghp_`, `gho_`, `ghu_`, `ghs_`, `ghr_` prefix |
| Private key block | CRITICAL | 98% | `-----BEGIN ... PRIVATE KEY-----` |
| Hardcoded API key | HIGH | 80% | `api_key = "..."`, `access_token = "..."` |
| Hardcoded password | HIGH | 75% | `password = "..."`, `passwd = "..."` |
| JWT token | HIGH | 85% | Three base64url segments separated by `.` |
| Slack token | HIGH | 90% | `xoxb-`, `xoxa-`, `xoxp-`, `xoxr-`, `xoxs-` |

### Example finding

```
ID:          ZG-A1B2C3
Severity:    CRITICAL
Title:       AWS access key
Scanner:     secrets
Category:    secrets
OWASP:       A02:2021 — Cryptographic Failures
Location:    src/config.js:14:23
Evidence:    AWS access key pattern matched; secret value redacted.
Confidence:  95%
Remediation: Revoke the AWS key, remove it from the repository, and
             load it from a secret manager or environment variable.
```

## Repository risk patterns

These findings surface OWASP anti-patterns that are common in AI-generated code. Severity ranges from MEDIUM to CRITICAL.

### Authentication & session management

| Pattern | Severity | OWASP |
| - | - | - |
| Predictable JWT signing secret (`changeme`, `secret`, etc.) | CRITICAL | A02:2021 |
| JWT signed inline with predictable secret | CRITICAL | A02:2021 |
| Token stored in `localStorage` or `sessionStorage` | HIGH | A02:2021, A07:2021 |
| Client-written cookie with token data | HIGH | A02:2021 |
| Long-lived session token (365d, `never`, `0`) | MEDIUM | A07:2021 |
| Client-side-only logout | MEDIUM | A07:2021 |

### Authorization

| Pattern | Severity | OWASP |
| - | - | - |
| Client-side admin gate (`isAdmin`, `role === 'admin'`) | MEDIUM | A01:2021 |
| Sensitive route without visible auth middleware | HIGH | A01:2021 |
| Object lookup by request-controlled ID (possible IDOR) | MEDIUM | A01:2021 |

### Frontend exposure

| Pattern | Severity | OWASP |
| - | - | - |
| Secret in `VITE_`, `NEXT_PUBLIC_`, `REACT_APP_` env var | HIGH | A02:2021 |
| Open redirect using request parameters | HIGH | A01:2021 |

### Infrastructure

| Pattern | Severity | OWASP |
| - | - | - |
| Debug mode enabled (`DEBUG=True`, `NODE_ENV=development`) | MEDIUM | A05:2021 |
| `USER root` in Dockerfile | HIGH | A05:2021 |
| Public database bind address | HIGH | A05:2021 |
| Weak password hashing (MD5, SHA1) | HIGH | A02:2021 |
| Low bcrypt cost factor (≤10) | MEDIUM | A02:2021 |

### Dependencies

| Pattern | Severity | OWASP |
| - | - | - |
| Install-time script in `package.json` | MEDIUM | A06:2021 |
| Unpinned Python dependency in `requirements.txt` | LOW | A06:2021 |

## Environment file hygiene

The secrets scanner also checks:

* **`.env` file committed** (HIGH, 97% confidence) — any `.env`, `.env.local`, `.env.production`, etc. found in the repo
* **`.env` not in `.gitignore`** (MEDIUM, 93% confidence) — the `.gitignore` doesn't contain an `.env` exclusion pattern

```bash theme={null}
# Fix both with:
git rm --cached .env
echo ".env*" >> .gitignore
git commit -m "Remove .env from tracking and add to gitignore"
```

## Files scanned

The scanner traverses all files in the repository except:

* `node_modules/`, `.venv/`, `__pycache__/`, `.git/`
* Binary files (images, archives, compiled artifacts)
* Files > 1MB (unlikely to contain useful patterns)

## Context-aware severity

Test, fixture, mock, and example files are scanned by default — because real credentials are routinely committed there. Instead of ignoring these files and creating blind spots, ZenVeil detects findings in all files but **adjusts severity based on file context**.

### How it works

When a secret is found outside of production code, ZenVeil:

1. Detects it with the same confidence as a production finding
2. Downgrades the severity by one or two tiers
3. Appends `(test file)`, `(fixture file)`, or `(example file)` to the title
4. Labels the finding with a context badge in the output

### Severity downgrade table

| Original severity | In test/fixture/example file |
| - | - |
| CRITICAL | → MEDIUM |
| HIGH | → LOW |
| MEDIUM | → LOW |
| LOW | → LOW |

### Context classification

Files are classified by their path:

| Context | Matched paths |
| - | - |
| `production` | Everything not matched below — full severity |
| `test` | `tests/`, `test/`, `spec/`, `__tests__/`, `e2e/`, `integration/`, `unit/`, `*.test.*`, `*.spec.*`, `test_*.py` |
| `fixture` | `fixtures/`, `mocks/`, `stubs/`, `fakes/`, `seeds/`, `factory/`, `testdata/` |
| `example` | `examples/`, `demos/`, `samples/` |

### Example

```
# Production file → CRITICAL
ZG-A1B2  CRITICAL  prod     secrets   AWS access key           src/config.py:14

# Test file → downgraded to MEDIUM
ZG-C3D4  MEDIUM    test     secrets   AWS access key (test file)   tests/test_auth.py:8
```

To skip non-production files entirely, use the `--exclude-tests` flag:

```bash theme={null}
zenveil scan github owner/repo --exclude-tests
```

This is not recommended as the default — credentials in test history are still in your git history and still exploitable. See [Context-aware scanning](https:// zenveil.dev/docs/cli/scan.md#context-aware-scanning) for the full rationale.

## Avoiding false positives

All secret values in findings are **redacted** — ZenVeil never logs, stores, or transmits actual credential values.

To suppress a confirmed false positive:

```bash theme={null}
zenveil ignore ZG-A1B2C3 --reason "Test fixture — not a real key"
```

To record it for the feedback loop:

```bash theme={null}
zenveil feedback ZG-A1B2C3 false_positive
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.