Skip to main content

Security tool for detecting exposed LLM/AI API keys in public repositories

Project description

LLMLeaks

A security auditing tool for detecting exposed API keys in public GitHub repositories. Built with async Python for high performance and designed with SOLID principles for extensibility.

Overview

LLMLeaks scans GitHub repositories for accidentally committed API keys and validates their status against provider APIs. This tool is designed for:

  • Security researchers conducting authorized vulnerability assessments
  • Organizations auditing their own repositories for leaked credentials
  • DevSecOps teams implementing proactive secret detection

Features

  • Asynchronous scanning with rate limit handling
  • Support for multiple AI/LLM providers:
    • OpenAI
    • Anthropic (Claude)
    • Google Gemini
    • DeepSeek
    • Groq
    • Perplexity
    • Hugging Face
  • Extensible validator architecture
  • Real-time validation of discovered keys
  • Configurable concurrency and output

Installation

From PyPI

pip install llmleaks

From Source

git clone https://github.com/fariiixm/llmleaks.git
cd llmleaks
pip install -e .

Development Installation

pip install -e ".[dev]"

Usage

Command Line

# Basic usage
llmleaks --token YOUR_GITHUB_TOKEN --query "API_KEY"

# Scan with custom parameters
llmleaks --token YOUR_GITHUB_TOKEN \
    --query "sk-proj-" \
    --pages 10 \
    --out results.txt \
    --concurrency 3

# Using environment variable for token
export GITHUB_TOKEN=ghp_xxxxxxxxxxxx
llmleaks --query "OPENAI_API_KEY"

As a Python Module

python -m auditor --token YOUR_GITHUB_TOKEN --query "API_KEY"

Programmatic Usage

import asyncio
from auditor import AsyncKeyAuditor

async def main():
    auditor = AsyncKeyAuditor(
        github_token="YOUR_GITHUB_TOKEN",
        max_concurrent=5
    )
    
    stats = await auditor.run(
        query="API_KEY",
        pages=5,
        output_file="results.txt"
    )
    
    print(f"Found {stats['valid']} valid keys")

asyncio.run(main())

Adding Custom Validators

from auditor.core.base import Validator
from auditor.core.factory import ValidatorFactory

class CustomValidator(Validator):
    name = "custom"
    
    async def validate(self, client, key):
        response = await client.get(
            "https://api.example.com/verify",
            headers={"Authorization": f"Bearer {key}"}
        )
        return response.status_code == 200

# Register the validator
ValidatorFactory.register(
    "custom",
    r"custom-[a-z0-9]{32}",
    CustomValidator()
)

CLI Options

Option Short Description Default
--token GitHub Personal Access Token $GITHUB_TOKEN
--query -q GitHub code search query API_KEY
--pages -p Number of result pages to scan 5
--out -o Output file for valid keys valid_keys.txt
--concurrency -c Maximum concurrent requests 5
--quiet Suppress progress output false
--verbose -v Enable debug logging false
--list-providers List supported API providers

Architecture

llmleaks/
├── src/auditor/
│   ├── __init__.py          # Package exports
│   ├── __main__.py          # Module entry point
│   ├── cli.py               # Command-line interface
│   ├── core/
│   │   ├── base.py          # Abstract Validator class
│   │   ├── factory.py       # ValidatorFactory registry
│   │   └── engine.py        # AsyncKeyAuditor engine
│   └── validators/
│       └── llm.py           # LLM provider validators
├── tests/                   # Test suite
├── docs/                    # Documentation
└── pyproject.toml          # Project configuration

Design Principles

  • Strategy Pattern: Validators implement a common interface for different providers
  • Factory Pattern: Centralized registry for validator management
  • Dependency Injection: Validators are injected via the factory
  • Async I/O: Non-blocking network operations for performance
  • Rate Limiting: Built-in throttling and cooldown handling

Requirements

  • Python 3.10+
  • GitHub Personal Access Token with repo scope

Creating a GitHub Token

  1. Go to GitHub Settings > Developer settings > Personal access tokens
  2. Click "Generate new token (classic)"
  3. Select the repo scope
  4. Copy the generated token

Development

Running Tests

pytest

Running Tests with Coverage

pytest --cov=auditor --cov-report=html

Code Quality

# Linting
ruff check src tests

# Type checking
mypy src

Ethical Use

This tool is intended for authorized security research only. Users must:

  1. Only scan repositories they own or have explicit authorization to audit
  2. Follow responsible disclosure practices for any vulnerabilities found
  3. Comply with GitHub's Terms of Service and API usage policies
  4. Never use discovered keys for unauthorized access

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/new-validator)
  3. Commit your changes (git commit -am 'Add new validator')
  4. Push to the branch (git push origin feature/new-validator)
  5. Open a Pull Request

See CONTRIBUTING.md for detailed guidelines.

Quick Start Guides

License

MIT License - see LICENSE for details.

Changelog

See CHANGELOG.md for version history.

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

llmleaks-1.0.0.tar.gz (12.2 kB view details)

Uploaded Source

Built Distribution

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

llmleaks-1.0.0-py3-none-any.whl (14.5 kB view details)

Uploaded Python 3

File details

Details for the file llmleaks-1.0.0.tar.gz.

File metadata

  • Download URL: llmleaks-1.0.0.tar.gz
  • Upload date:
  • Size: 12.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for llmleaks-1.0.0.tar.gz
Algorithm Hash digest
SHA256 7bebbf2b451be2919b854f17ec20add238053cf41853b50222ab9e0445aaffed
MD5 287ea935b544e8257b9ae19c5c59d7de
BLAKE2b-256 1cbdf724a9bc54479199adca21d0079a2c7a7223ec0142107e3ff610dad23210

See more details on using hashes here.

File details

Details for the file llmleaks-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: llmleaks-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 14.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for llmleaks-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c849b3203d9f6c53a428fe3655fd41b72fb072309d58caa2e5f84cd5b3517985
MD5 d9c5a92947d95771502dc4b7151ecefa
BLAKE2b-256 1ecdd2e44b030bfe35ae06922ffb707388e205c526d54b9628e6be6a5c52b4bc

See more details on using hashes here.

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