Skip to main content

pyl — fast secret scanner for your codebase

Project description

pyl

pyl — fast secret scanner for your codebase

A lightweight, zero-config secret scanner written in Rust — available as CLI tool and Python library. Scans source code for accidentally committed secrets, credentials, and sensitive data.


Features

  • 89 built-in detection rules covering cloud providers, LLMs, databases, HTTP auth, and more
  • Multiple output formats — pretty-printed, JSON, and SARIF
  • GitHub Actions integration — writes a formatted Job Summary to $GITHUB_STEP_SUMMARY
  • Inline suppression — annotate lines with # pyl-ignore to silence known false positives
  • Configurable via pyl.toml — restrict file extensions, exclude paths, disable rules
  • Sorted output — findings ordered by severity (CRITICAL → HIGH → MEDIUM → LOW → WARNING), then by file and line
  • Smart false-positive filtering — skips template variables, shell variables, and attribute references
  • Binary-safe — skips non-text files automatically
  • Respects .env files — always excluded from scanning

Installation

From source

git clone https://github.com/YOUR_USERNAME/pyl.git
cd pyl
cargo install --path .

via pip

pip install pyl-secret-leaks
pyl check .

Pre-built binaries

Download the latest binary for your platform from the Releases page:

Platform File
Linux x86_64 pyl-linux-amd64
Linux ARM64 pyl-linux-arm64
Windows x86_64 pyl-windows-amd64.exe
macOS Apple Silicon pyl-macos-arm64
# Linux / macOS — make executable and move to PATH
chmod +x pyl-linux-amd64
sudo mv pyl-linux-amd64 /usr/local/bin/pyl

Python Library

After installing via pip install pyl-secret-leaks, you can use pyl directly from Python — e.g. to scan text before sending it to an LLM:

from pyl import scan_text

findings = scan_text("My API key is sk-proj-abc123xyz...")
for f in findings:
    print(f.rule_id, f.severity, f.secret)

# Disable specific rules:
findings = scan_text(text, disable_rules=["http-insecure-url"])

Each finding has the attributes: rule_id, description, severity, line_number, line, secret, tags.


CLI Usage

# Scan the current directory
pyl check

# Scan a specific path
pyl check --source ./src

# JSON output (e.g. for piping)
pyl check --format json

# SARIF output (e.g. for GitHub Code Scanning)
pyl check --format sarif

# Verbose mode (shows every file scanned/skipped)
pyl check --verbose

# Include WARNING-level findings in detail output
pyl check --warnings

# Limit file size (default: 1024 KB)
pyl check --max-size 512

# Use a custom config file
pyl check --config /path/to/pyl.toml

# Write a GitHub Actions Job Summary
pyl check --github-summary

# List all built-in rules
pyl rules

# Generate a default config file
pyl init-config

Exit codes

Code Meaning
0 No findings (or only LOW/WARNING severity)
1 At least one CRITICAL, HIGH, or MEDIUM finding

Warnings

WARNING-level findings (e.g. plain HTTP URLs) are counted in the summary but suppressed in the detail output by default to reduce noise. Use --warnings to display them:

pyl check --warnings

The summary line always shows the WARNING count regardless of this flag.


Configuration

Run pyl init-config to create a pyl.toml in the current directory:

[scan]
# Leave empty to scan all files (except .env and .git).
# Restrict to specific extensions:
# extensions = ["py", "js", "ts", "go", "yaml", "toml"]
extensions = []
exclude_paths = []
exclude_files = []

[rules]
# Disable specific rules by ID:
# disable = ["jwt-token", "http-insecure-url"]
disable = []

pyl.toml is auto-loaded from the current directory if present.


Suppression

Add a suppression comment to any line to skip it:

api_url = "http://internal-service/api"  # pyl-ignore

Supported markers: # pyl-ignore, # noqa-secrets, # nosec-secrets

pyl also automatically skips common false positives:

Pattern Example
Python f-strings / Jinja postgresql://{DB_USER}:{DB_PASSWORD}@...
Shell variables $DB_PASSWORD
Python %-format %(password)s
Attribute references settings.DB_PASSWORD, config.secret_key
localhost HTTP URLs http://localhost:8080

Detection Coverage

Category Examples
Cloud / VCS AWS keys, GitHub/GitLab PATs, Google API keys, Stripe, Slack, NPM, Docker Hub
LLM / AI OpenAI, Anthropic, Cohere, Mistral, Hugging Face, Replicate, Groq, Perplexity
Azure / M365 Tenant/Client IDs, Storage keys, Service Bus, Cosmos DB, Teams webhooks, Graph API
Frontend / SaaS Firebase, Mapbox, Sentry DSN, Contentful, Shopify, Algolia, Linear, Postman, PlanetScale, Cloudflare
Databases PostgreSQL, MySQL, MongoDB, Redis, MSSQL, Elasticsearch, RabbitMQ, JDBC
Observability Datadog, New Relic, Grafana, Honeycomb, Lightstep, OTLP endpoints
HTTP Auth Basic Auth headers, Bearer tokens, credentials in URLs, curl commands
Crypto PEM private keys (RSA, EC, DSA, OpenSSH)
Generic High-entropy secrets matching common naming patterns, JWT tokens

Run pyl rules to see all 89 rules with IDs, severity levels, and tags.


Severity Levels

Level Description
CRITICAL Direct credential exposure — rotate immediately
HIGH Sensitive token or key with significant access
MEDIUM Potentially sensitive, context-dependent
LOW Low-risk exposure (e.g. publishable keys)
WARNING Best-practice violation (e.g. plain HTTP URLs) — shown with --warnings

GitHub Actions

Use pyl in your own pipeline

Add this job to any workflow to scan for secrets and write the results to the GitHub Job Summary:

jobs:
  pyl:
    name: pyl secret scan
    runs-on: ubuntu-latest
    permissions:
      contents: read

    steps:
      - uses: actions/checkout@v4

      - name: Install pyl
        run: |
          curl -sSfL \
            https://github.com/adrian-lorenz/pyl/releases/latest/download/pyl-linux-amd64 \
            -o /usr/local/bin/pyl
          chmod +x /usr/local/bin/pyl

      - name: Run scan
        run: pyl check --format markdown >> "$GITHUB_STEP_SUMMARY"

Or install via pip:

      - name: Install pyl
        run: pip install pyl-secret-leaks

      - name: Run scan
        run: pyl check --format markdown >> "$GITHUB_STEP_SUMMARY"

Two ready-to-use workflows are also included in .github/workflows/.

Secret scan on every push — scan.yml

Runs pyl check on every push and pull request, uploads results to GitHub Code Scanning as SARIF.

Replace YOUR_USERNAME in scan.yml with your GitHub username before pushing.

Release workflow — release.yml

Triggered automatically when you push a version tag:

git tag v1.0.0
git push origin v1.0.0

The workflow:

  1. Builds Linux amd64/arm64 and Windows amd64/arm64 in parallel on ubuntu-latest using cross
  2. Builds macOS arm64 natively on macos-latest
  3. Creates a GitHub Release with all 5 binaries attached and an auto-generated changelog

The release body includes a download table and install instructions automatically.


Project Structure

src/
├── lib.rs        Library root, PyO3 Python bindings
├── main.rs       CLI entry point, CLI dispatch
├── cli.rs        CLI types (Cli, Commands, OutputFormat)
├── config.rs     Configuration loading (pyl.toml)
├── rules.rs      Built-in detection rules and Severity type
├── scanner.rs    File and directory scanning logic
└── output.rs     Output formatters (pretty, JSON, SARIF, GitHub Summary)

License

MIT — Copyright (c) 2026 Adrian Lorenz <a.lorenz@noa-x.de>

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pyl_secret_leaks-0.5.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.5 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARM64

pyl_secret_leaks-0.5.2-cp38-abi3-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.8+Windows x86-64

pyl_secret_leaks-0.5.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

pyl_secret_leaks-0.5.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.5 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

pyl_secret_leaks-0.5.2-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (2.7 MB view details)

Uploaded CPython 3.8+macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file pyl_secret_leaks-0.5.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pyl_secret_leaks-0.5.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 1e784817a01c61449b39db6b38ace9efb7e3be26c14c65c271bf6a10d84a82db
MD5 7dd7b5559c93567763b9394db71bd9ab
BLAKE2b-256 5be0dc5e73e8c6dc818f190240b45632087140f4900e205496e3b7280ceef4f5

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyl_secret_leaks-0.5.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on adrian-lorenz/pyl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyl_secret_leaks-0.5.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pyl_secret_leaks-0.5.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 1f1fec8b0192a7395821eaf09f8dabcd0cfa94eda8a4e9c9466b55abe81ccfb5
MD5 91fbbefd2237c082e90145fca26df661
BLAKE2b-256 406388fcde59f916e310faa2fbcadc1a46b5ab562e62579e0d9991dac987d221

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyl_secret_leaks-0.5.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on adrian-lorenz/pyl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyl_secret_leaks-0.5.2-cp38-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for pyl_secret_leaks-0.5.2-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 08f63558d25a871bcbaff279dc38f16d583f41a2a963bae5812adbee1025bccf
MD5 1db036481df6a5fea891145bb5032e83
BLAKE2b-256 09c9bb5d9de9acdc07c2559f420b1d3b037e86b076b6c62f2f07952c8ee7f925

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyl_secret_leaks-0.5.2-cp38-abi3-win_amd64.whl:

Publisher: release.yml on adrian-lorenz/pyl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyl_secret_leaks-0.5.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyl_secret_leaks-0.5.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 28224bdfdcf17cc6237ed68733b68c2ec23a8f991ee6e31ba6d4cd1610ef51ea
MD5 c05badcb0ffe0c3ecbe55806ae4f3280
BLAKE2b-256 3ac3c7ec034a874fe85ccbcb5a9477ea61660a27a8c3913d9cc57496293ae7d9

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyl_secret_leaks-0.5.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on adrian-lorenz/pyl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyl_secret_leaks-0.5.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pyl_secret_leaks-0.5.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 590ddf7684d67133e52deda2a74c3424453cd5a529d4a9df90d61e5303c1dffd
MD5 64e51ca8713bc6f4f40f28f672d2ca41
BLAKE2b-256 40f23ed30a2c93408cf879f655341abf6bd420856013e21f024da5cd720cf67e

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyl_secret_leaks-0.5.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on adrian-lorenz/pyl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyl_secret_leaks-0.5.2-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for pyl_secret_leaks-0.5.2-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 f621bf9bc430d5e5f8f88fd9795903a5a19b5ee587112359b8a7ff910f69b0dc
MD5 d5f8171024b38963bf8861f7b841882f
BLAKE2b-256 074ce166784ca9bb8e59c0ffb0dda334e4d2636b66a5638cf0646646be2dd0ca

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyl_secret_leaks-0.5.2-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:

Publisher: release.yml on adrian-lorenz/pyl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page