Skip to main content

Scan git repos for leaked secrets and estimate their blast radius

Project description

๐Ÿ” Aysal-Scan

Detect leaked secrets in your git repos โ€” and find out exactly what damage they can cause.

Every other tool tells you "you have a leaked key."
Aysal-Scan tells you "you have a leaked AWS key โ€” it has AdministratorAccess on your production account. Here's how to fix it."


The Difference

Feature TruffleHog / GitLeaks Aysal-Scan
Regex-based detection โœ… โœ…
Shannon entropy analysis โœ… โœ…
Git history scanning โœ… โœ…
Is the key still active? โŒ โœ…
What permissions does it have? โŒ โœ…
Plain English remediation โŒ โœ…
Severity score with blast radius โŒ โœ…
Scan any GitHub URL directly โŒ โœ…
Interactive UI mode โŒ โœ…

Architecture

flowchart TD
    A1[Local directory] --> DE
    A2[Git history] --> DE
    A3[GitHub URL] --> DE
    A4[Staged changes] --> DE
    DE["๐Ÿ” Detection engine
    Regex ยท 17+ patterns ยท Shannon entropy"]
    DE --> DD["Deduplication
    SHA-256 per raw value"]
    DD --> BR["๐Ÿ’ฅ Blast radius engine
    Live API verify ยท Permission enumeration
    AWS ยท GitHub ยท OpenAI ยท Stripe ยท Slack ยท Twilio +12"]
    BR --> SS["Severity scoring + remediation
    CRITICAL โ†’ HIGH โ†’ MEDIUM โ†’ LOW"]
    SS --> O1[Terminal / Rich UI]
    SS --> O2[SARIF output]
    SS --> O3[JSON / HTML]
    style DE fill:#7F77DD,color:#fff,stroke:#534AB7
    style DD fill:#888780,color:#fff,stroke:#5F5E5A
    style BR fill:#D85A30,color:#fff,stroke:#993C1D
    style SS fill:#1D9E75,color:#fff,stroke:#0F6E56
    style O1 fill:#888780,color:#fff,stroke:#5F5E5A
    style O2 fill:#888780,color:#fff,stroke:#5F5E5A
    style O3 fill:#888780,color:#fff,stroke:#5F5E5A

Note: Live verification applies to most providers (AWS, GitHub, OpenAI, Stripe, Slack, Twilio, npm, SendGrid, Heroku, Google). PyPI, Azure, and GCP are flagged for manual review instead โ€” no safe verify endpoint, no tenant ID available, and avoiding audit-log noise, respectively.


Real-World Demo

Scanning a test repo with a live canary AWS key:

aysal-scan scan https://github.com/trufflesecurity/test_keys
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ๐Ÿ”ด [CRITICAL] AWS Access Key โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚   File    :  new_key (line 2)                                                        โ”‚
โ”‚   Secret  :  AKIA************ZAM2                                                    โ”‚
โ”‚                                                                                      โ”‚
โ”‚   Blast Radius:                                                                      โ”‚
โ”‚     Key status  : ACTIVE                                                             โ”‚
โ”‚     Account     : Account: 052310077262 | User: canarytokens.com@@c20nnjzl...        โ”‚
โ”‚     Permission  : Could not enumerate โ€” insufficient IAM permissions                 โ”‚
โ”‚                                                                                      โ”‚
โ”‚   Fix: 1. Go to AWS IAM Console โ†’ Users โ†’ Security Credentials                      โ”‚
โ”‚        2. Deactivate this access key immediately                                     โ”‚
โ”‚        3. Rotate + store in AWS Secrets Manager                                      โ”‚
โ”‚        4. Remove from git history with: git filter-repo                              โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

โœ— FAILED โ€” secrets detected  |  Exit code: 1

The blast radius engine called sts:GetCallerIdentity against live AWS, confirmed the key is active, retrieved the real account ID, and escalated severity to CRITICAL โ€” all automatically.


Install

pip install aysal-scan

Or from source:

git clone https://github.com/Rolex-1905/aysal-scan
cd aysal-scan
pip install -e .

Requires Python 3.11+


Quick Start

# Scan current directory
aysal-scan scan .

# Interactive mode โ€” guided, no flags needed
aysal-scan ui

All Commands

# โ”€โ”€ Scan targets โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
aysal-scan scan .                                      # current directory
aysal-scan scan /path/to/repo                          # specific path
aysal-scan scan secrets.env                            # single file
aysal-scan scan https://github.com/username/repo       # GitHub URL (auto-clones)

# โ”€โ”€ Git modes โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
aysal-scan scan --staged                               # staged changes only
aysal-scan scan --commits 20                           # last 20 commits
aysal-scan scan --full-history                         # entire git history

# โ”€โ”€ Output formats โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
aysal-scan scan . --report json                        # JSON (for CI pipelines)
aysal-scan scan . --report html --output report.html   # HTML report

# โ”€โ”€ Filters & options โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
aysal-scan scan . --min-severity HIGH                  # HIGH and CRITICAL only
aysal-scan scan . --no-blast-radius                    # skip API checks (offline)
aysal-scan scan . --no-fail                            # always exit 0
aysal-scan scan . --allow-list <id1>,<id2>             # suppress known findings by ID
aysal-scan scan . --verbose                            # show detailed blast radius debug output
aysal-scan scan . --report sarif --sarif-baseline old.sarif  # only alert on genuinely new findings

Supported Providers & Blast Radius Checks

Secret Type Detection Blast Radius Check
AWS Access Key Regex sts:GetCallerIdentity โ†’ IAM policy list
GitHub Token (PAT / OAuth) Regex /user โ†’ scopes โ†’ repo access
OpenAI API Key Regex /v1/models โ†’ billing exposure
Stripe Secret Key Regex /v1/balance โ†’ live account access
Stripe Publishable Key Regex Auto LOW
Twilio Account SID Regex /Accounts/{SID} โ†’ status check
SendGrid API Key Regex /v3/scopes โ†’ permission list
Slack Bot Token Regex auth.test โ†’ workspace + permissions
Slack Webhook URL Regex Probe โ†’ active/inactive check
npm Token Regex registry.npmjs.org/-/whoami
PyPI Token Regex Manual review (no safe verify endpoint)
GCP Service Account JSON JSON structure Auto CRITICAL (project ID + client email parsed)
Azure Client Secret Context-aware regex Manual review (tenant ID required to verify)
Heroku API Key Regex /account โ†’ email + app access
Google API Key Regex Probe enabled APIs
JWT Token Regex Decode header + expiry check
Private Key (RSA / EC / SSH) Regex Auto CRITICAL
Database URL (Postgres, MySQL, Redis, MongoDB) Regex Auto HIGH
High Entropy String Shannon entropy > 4.5 Flagged for manual review

Severity Levels

Level Meaning Exit Code
๐Ÿ”ด CRITICAL Key is active + has admin/write access 1
๐ŸŸ  HIGH Key is active + significant read access 1
๐ŸŸก MEDIUM Key appears valid but check failed or timed out 0
๐Ÿ”ต LOW Test/publishable key โ€” limited exposure 0
โšช INFO Likely a secret, unconfirmed 0

Exit code 1 on any CRITICAL or HIGH finding. Override with --no-fail.


GitHub Actions

steps:
  - uses: actions/checkout@v4
    with:
      fetch-depth: 0

  - name: Aysal-Scan Secret Scan
    uses: Rolex-1905/aysal-scan@v1.0.0
    with:
      path: '.'
      min-severity: 'HIGH'
      no-blast-radius: 'false'
      fail-on-findings: 'true'

  - name: Upload HTML Report
    uses: actions/upload-artifact@v4
    if: always()
    with:
      name: aysal-scan-report
      path: aysal-scan-report.html
      retention-days: 30

  - name: Upload SARIF to GitHub Security tab
    uses: github/codeql-action/upload-sarif@v3
    if: always()
    with:
      sarif_file: aysal-scan-results.sarif
      category: aysal-scan

Pre-commit Hook

Recommended โ€” remote repo mode (auto-installs, always up to date):

repos:
  - repo: https://github.com/Rolex-1905/aysal-scan
    rev: v1.0.0
    hooks:
      - id: aysal-scan               # fast โ€” no API calls, offline safe

With blast radius checks (slower โ€” calls provider APIs):

repos:
  - repo: https://github.com/Rolex-1905/aysal-scan
    rev: v1.0.0
    hooks:
      - id: aysal-scan-with-blast-radius

Local mode (if you have aysal-scan already installed):

repos:
  - repo: local
    hooks:
      - id: aysal-scan
        name: Aysal-Scan โ€” secret detection
        entry: aysal-scan scan --staged --no-blast-radius
        language: system
        pass_filenames: false

Install pre-commit and activate:

pip install pre-commit
pre-commit install

Ignoring Files

Aysal-Scan automatically skips node_modules/, .git/, dist/, build/, *.min.js, lock files, and binary files.

For custom rules, create an AysalScanignore file in your repo root (same syntax as .gitignore):

# Ignore test fixtures with intentional fake keys
tests/test_cli.py
tests/test_patterns.py

# Ignore example config files
*.example
*.sample
config.example.env

How Blast Radius Works

When a secret is detected, Aysal-Scan calls the provider's API using read-only operations only to answer three questions:

  1. Is this key still active?
  2. What can it access?
  3. How bad is it if someone already has it?

All checks run concurrently with a 10-second timeout per provider. A failed or timed-out check degrades gracefully to MEDIUM rather than crashing the scan. The raw secret is never stored โ€” only the masked value (AKIA****XMPL) appears in any output or report.


Project Structure

aysal_scan/
โ”œโ”€โ”€ cli.py                    # Typer CLI + interactive UI
โ”œโ”€โ”€ models.py                 # Pydantic models (Finding, ScanReport, etc.)
โ”œโ”€โ”€ scanner/
โ”‚   โ”œโ”€โ”€ patterns.py           # Regex patterns for 17+ secret types
โ”‚   โ”œโ”€โ”€ entropy.py            # Shannon entropy analysis
โ”‚   โ”œโ”€โ”€ file_scanner.py       # File + directory scanning
โ”‚   โ”œโ”€โ”€ git_utils.py          # Git history, staged, commit scanning
โ”‚   โ””โ”€โ”€ deduplicator.py       # Deduplicate across commits
โ”œโ”€โ”€ blast_radius/
โ”‚   โ”œโ”€โ”€ aws.py                # AWS IAM checks via STS (user, group, inline policies)
โ”‚   โ”œโ”€โ”€ github.py             # GitHub API scope check
โ”‚   โ”œโ”€โ”€ openai_checker.py     # OpenAI key validation
โ”‚   โ”œโ”€โ”€ stripe.py             # Stripe balance check
โ”‚   โ”œโ”€โ”€ slack.py              # Slack auth.test
โ”‚   โ”œโ”€โ”€ slack_webhook.py      # Slack webhook probe
โ”‚   โ”œโ”€โ”€ twilio.py             # Twilio account check
โ”‚   โ”œโ”€โ”€ sendgrid.py           # SendGrid scope list
โ”‚   โ”œโ”€โ”€ npm.py                # npm whoami
โ”‚   โ”œโ”€โ”€ pypi.py                # PyPI โ€” flags for manual review (no safe verify endpoint)
โ”‚   โ”œโ”€โ”€ heroku.py             # Heroku account check
โ”‚   โ”œโ”€โ”€ google.py             # Google API probe
โ”‚   โ”œโ”€โ”€ gcp.py                 # GCP Service Account JSON parsing
โ”‚   โ”œโ”€โ”€ azure.py                # Azure Client Secret โ€” manual review
โ”‚   โ”œโ”€โ”€ jwt_checker.py        # JWT decode + expiry
โ”‚   โ”œโ”€โ”€ base.py                 # Retry/backoff wrapper shared by all checkers
โ”‚   โ””โ”€โ”€ generic.py            # Fallback for unknown types
โ””โ”€โ”€ reporter/
    โ”œโ”€โ”€ terminal.py           # Rich-formatted terminal output
    โ”œโ”€โ”€ json_report.py        # JSON output for CI
    โ”œโ”€โ”€ html_report.py        # Interactive HTML report (collapsible, filterable)
    โ””โ”€โ”€ sarif_report.py        # SARIF 2.1.0 for GitHub Security tab

Tech Stack

Built with Python 3.11+ ยท Typer ยท Rich ยท Pydantic v2 ยท httpx ยท boto3 ยท GitPython


License

MIT ยฉ 2026 Aysal-Scan


Built by Neeraj Mudunuru

Project details


Download files

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

Source Distribution

aysal_scan-1.0.2.tar.gz (51.2 kB view details)

Uploaded Source

Built Distribution

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

aysal_scan-1.0.2-py3-none-any.whl (52.5 kB view details)

Uploaded Python 3

File details

Details for the file aysal_scan-1.0.2.tar.gz.

File metadata

  • Download URL: aysal_scan-1.0.2.tar.gz
  • Upload date:
  • Size: 51.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for aysal_scan-1.0.2.tar.gz
Algorithm Hash digest
SHA256 2c0e0e7fd5ce466618f6011f7ce49a5554b43c85c0d1915eeef290018f480b85
MD5 7c5d9b7a336327b832a08242f8542e8e
BLAKE2b-256 1936d0817d28013a31beaefe9ab1576dbce342b6fd376b6bec272a01519a4da7

See more details on using hashes here.

Provenance

The following attestation bundles were made for aysal_scan-1.0.2.tar.gz:

Publisher: publish.yml on Rolex-1905/aysal-scan

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

File details

Details for the file aysal_scan-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: aysal_scan-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 52.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for aysal_scan-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 be46126312970298d217d3d399716c462948e5c817192b8252e4e88ef817a0f4
MD5 b1aebef4b0e451a7f41de64ea4c4f956
BLAKE2b-256 53f1786fc0fe59d4321c9ed3c62c68f3cb40e041b74974cacec4720353ef2e92

See more details on using hashes here.

Provenance

The following attestation bundles were made for aysal_scan-1.0.2-py3-none-any.whl:

Publisher: publish.yml on Rolex-1905/aysal-scan

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