Metadata-Version: 2.4
Name: secret-scan
Version: 0.2.0
Summary: A simple secret/credential scanner for source code repositories.
Author-email: Your Name <you@example.com>
License: MIT License
        
        Copyright (c) 2025 amitu314, harshahemanth
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
        
Project-URL: Homepage, https://github.com/harshahemanth/secret-scan
Project-URL: Repository, https://github.com/harshahemanth/secret-scan
Project-URL: Issues, https://github.com/harshahemanth/secret-scan/issues
Project-URL: Documentation, https://github.com/harshahemanth/secret-scan#readme
Keywords: security,secrets,credentials,scanner
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Topic :: Security
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# secret-scan

[![PyPI version](https://img.shields.io/pypi/v/secret-scan)](https://pypi.org/project/secret-scan/)
[![PyPI downloads](https://img.shields.io/pypi/dm/secret-scan)](https://pypi.org/project/secret-scan/)
[![CI](https://github.com/harshahemanth/secret-scan/actions/workflows/ci.yml/badge.svg)](https://github.com/harshahemanth/secret-scan/actions/workflows/ci.yml)

A fast, lightweight CLI tool to detect secrets in source code. Zero dependencies — stdlib only.

`secret-scan` scans directories for sensitive data such as:

- AWS Access Keys and Secret Keys
- GitHub tokens (PAT, OAuth, App, fine-grained)
- Slack tokens (bot, user)
- Stripe keys (live and test)
- Google API keys
- OpenAI API keys
- npm and PyPI tokens
- Twilio and SendGrid API keys
- Heroku and HashiCorp Vault tokens
- Passwords, Bearer tokens, and JWTs
- SSH/RSA/PGP private keys
- Azure storage keys
- Database connection strings

It skips binary files, ignores common junk directories (node_modules, .git, venv, etc.), avoids scanning large files, and supports extensible detection rules.

## Installation

    pip install secret-scan

To upgrade:

    pip install --upgrade secret-scan

## Basic Usage

Scan the current directory:

    secret-scan .

Scan a specific directory:

    secret-scan ~/projects/my-repo

Write results to a file (default: docsCred.txt):

    secret-scan . --output secrets.txt

## Exit Codes

`secret-scan` returns meaningful exit codes for CI/CD integration:

| Exit Code | Meaning              |
|-----------|----------------------|
| 0         | No secrets found     |
| 1         | Secrets were found   |

Use `--no-fail` to always exit with 0 (advisory mode):

    secret-scan . --no-fail

## JSON Output

Generate JSON output (useful for CI pipelines):

    secret-scan . --json

Example output:

    [
      {
        "file": "config/settings.py",
        "line": 20,
        "match": "AWS_ACCESS_KEY_ID=AKIA1234567890ABCD12",
        "rule_id": "aws-access-key-assignment",
        "rule_name": "AWS Access Key Assignment",
        "severity": "error",
        "column": 0,
        "end_column": 42
      }
    ]

## SARIF Output

Generate SARIF v2.1.0 output for integration with GitHub Code Scanning, GitLab SAST, and other security tools:

    secret-scan . --sarif

Upload to GitHub Code Scanning:

    secret-scan . --sarif > results.sarif
    gh api repos/{owner}/{repo}/code-scanning/sarifs \
      -X POST -F "sarif=@results.sarif"

## Suppressing False Positives

### .secretscanignore

Create a `.secretscanignore` file in your project root to suppress known false positives:

    # Ignore entire files or directories
    tests/fixtures/*.json
    docs/**

    # Ignore a specific rule for a specific file
    config/settings.py:generic-secret

    # Ignore matches containing specific text
    !match:EXAMPLE_KEY_DO_NOT_USE

### Inline suppression

Add `# nosecret` to any line to suppress detection on that line:

```python
DEFAULT_KEY = "sk-placeholder-not-real"  # nosecret
```

Use `--no-ignore` to bypass all suppression rules:

    secret-scan . --no-ignore

## Command-Line Options

| Flag              | Description                                      |
|-------------------|--------------------------------------------------|
| --output \<file\> | Save text results (default: docsCred.txt)        |
| --skip-ext .log   | Skip specific file extensions                    |
| --skip-dir \<dir\>| Skip specific directories                        |
| --max-size-mb N   | Scan only files smaller than N MB                |
| --json            | Print JSON results to stdout                     |
| --sarif           | Print SARIF v2.1.0 results to stdout             |
| --no-fail         | Always exit 0 even if secrets are found          |
| --no-ignore       | Do not read .secretscanignore file               |

Example:

    secret-scan . --skip-ext .log --skip-dir build --json

## What It Detects

Each detection rule has a unique `rule_id` and a severity level (`error`, `warning`, or `note`).

### Cloud Providers
| Provider | What | Severity |
|----------|------|----------|
| AWS | Access Key IDs (AKIA...), Secret Access Keys | error |
| Azure | Storage account keys, Account keys | error |
| Google | API keys (AIza...) | error |
| Heroku | API key assignments | error |
| HashiCorp Vault | Service tokens (hvs.) | error |

### SaaS / API Platforms
| Provider | What | Severity |
|----------|------|----------|
| GitHub | PAT, OAuth, App, Refresh, Fine-grained tokens | error |
| Slack | Bot tokens (xoxb-), User tokens (xoxp-) | error |
| Stripe | Live secret/publishable/restricted keys | error/warning |
| Stripe | Test keys | note |
| OpenAI | API keys (sk-) | error |
| Twilio | API keys (SK...) | error |
| SendGrid | API keys (SG.) | error |
| npm | Access tokens | error |
| PyPI | API tokens | error |

### Generic Patterns
| What | Severity |
|------|----------|
| Password assignments (password=, passwd=, pwd=) | warning |
| Bearer tokens | error |
| JWT tokens | warning |
| API key/token assignments | warning |
| Private key blocks (PEM headers) | error |
| SSH RSA public keys | note |
| Database connection strings | warning |
| Generic secret assignments | warning |

## Automatic Skips

The scanner automatically ignores:

- .git, .hg, .svn
- node_modules
- Python virtual environments (venv, .venv, env)
- IDE directories (.idea, .vscode)
- Binary files (null-byte detection)
- Large files (over 5 MB by default)
- Common non-text extensions (images, archives, executables)

## Extending Detection Patterns

Detection patterns are defined as `SecretPattern` dataclass instances in:

    src/secret_scanner/patterns.py

Each pattern has a `rule_id`, `name`, `severity`, `pattern` (regex), and `description`. You can add new patterns by appending to the `PATTERNS` list.

## Programmatic Usage

Example using the Python API:

```python
from pathlib import Path
from secret_scanner import scan_directory

matches = scan_directory(Path("."), output_path=None)
for m in matches:
    print(f"[{m['severity']}] {m['rule_name']}: {m['file']}:{m['line']}")
```

## Running Tests

    PYTHONPATH=src pytest tests/ -q

## Contributing

Contributions are welcome.

1. Fork the repository
2. Create a feature branch
3. Add tests for new functionality
4. Open a pull request

## License

This project is licensed under the MIT License. See the LICENSE file for full details.
