ChatGPT-API-Scanner: a Selenium crawler that searches GitHub for leaked OpenAI keys
Scan GitHub for available OpenAI API Keys
At a glance
- What is it?
- The tool drives a real Chrome session through GitHub's web search to find API key patterns that the official search API cannot express, then stores what it finds in a local SQLite file. It is a research instrument with a deliberately narrow scope, and GitHub's push protection has been shrinking that scope since 2024.
- Who is it for?
- Adopt it if you are doing authorized secret-exposure research and want a small, readable Python codebase that writes findings into a single SQLite file you can query yourself. Do not adopt it if you need an automated remediation pipeline, continuous coverage, or anything that works without a logged-in browser session, and do not treat it as a way to obtain working API access: the README states that keys found this way may expire within hours or days.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 152 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem: GitHub search cannot express a key pattern
OpenAI keys follow a recognizable prefix, which means a regex is the natural way to find one. GitHub's official search API does not accept regex queries; only the web search interface does. That single gap is the reason this project exists. The README states the choice plainly: "We use regex search to have the best search results. However, the official GitHub search API does not support regex search, only web-based search does." Everything else in the design follows from that constraint, including the use of Selenium and the need for a browser login.
The intended user is a security researcher, not a developer looking for cheap API access. The repository carries a disclaimer in capital letters that the project is "ONLY FOR SECURITY RESEARCH" and that the authors are not responsible for misuse. If you are looking for a way to obtain working API access, this is the wrong tool, and the README says so indirectly by noting that keys found this way may expire within hours or days.
How the scanner works: Selenium, language sharding and a SQLite sink
The pipeline is short. Selenium opens a Chrome instance, you authenticate with your own GitHub account in the browser, and the script issues web search queries built from a keyword list and a language list. It parses the result pages for strings matching the key pattern, then checks each candidate against OpenAI and records the outcome.
The language list is not cosmetic. The README explains that web search only returns the first five pages of results, and that limiting the programming language breaks the result set into smaller slices so more keys can be retrieved. This is a workaround for a pagination ceiling, and it means recall depends heavily on how the default language and keyword lists are chosen. Passing your own values with -l and -k changes the coverage directly.
Results land in github.db, a SQLite database created in the same directory as the script. The README shows screenshots of the database containing keys in different status states, which implies the schema records whether a key was still valid at check time. The README does not document the table names or column definitions, so you will need to inspect the file with a SQLite browser before writing queries against it. That is a real gap for anyone who wants to automate downstream reporting.
Multithreading is deliberately absent. The FAQ states that GitHub search and OpenAI are both rate-limited, so parallel workers would not meaningfully improve throughput. That is a defensible call, but it also means a full scan is slow and there is no documented way to resume mid-run beyond the --from-iter parameter.
Installing ChatGPT-API-Scanner and running a first scan
The prerequisites are Google Chrome and uv, which the README describes as a Python package manager that handles the Python install automatically. Note that pyproject.toml declares requires-python = ">=3.14", so the interpreter uv provisions is a recent one.
Clone the repository and let uv resolve the environment. The README gives these exact commands:
git clone https://github.com/Junyi-99/ChatGPT-API-Scanner
cd ChatGPT-API-ScannerThen synchronize dependencies. The README states that uv reads pyproject.toml and uv.lock and provisions the matching Python version from .python-version:
uv syncIf you also want the linting tools (pylint, flake8, ruff), the README documents an extended sync:
uv sync --all-groupsThe first real run is a single command. Expect a browser window to open and a prompt to log in to GitHub, which the README instructs you to complete:
uv run main.pyFor a shorter run you can start from a later iteration, or restrict the scan to keys already recorded in the database:
uv run main.py --from-iter 100
uv run main.py --check-existed-keys-onlyWhen the run finishes, open github.db with any SQLite browser. The README points to that file as the only result store, and the screenshots show rows with differing key statuses.
Push protection is the limitation that matters most
The README carries two dated notes that undercut the tool's own premise. As of March 11, 2024, secret scanning and push protection were enabled by default for all new user-owned public repositories. As of August 21, 2024, GitHub enabled push protection to prevent API key leakage, which the README says "could significantly impact this repository."
That is the honest framing of the ceiling here. Push protection blocks a push when a known sensitive pattern is detected, so more keys are stopped before they ever become searchable. The scanner can only find what was already committed, which means its yield declines as the platform's guardrails improve. A researcher running this in 2026 should expect a much thinner result set than the screenshots from earlier runs suggest, and the README does not offer a revised baseline.
There are secondary failure modes. The tool depends on GitHub's web search markup, so a frontend change can break parsing without any error the script explains. It depends on a logged-in browser session, so it cannot run headless in a scheduled job without the README documenting a way to persist credentials, and it does not document one. It also depends on OpenAI's key-checking endpoint, which is rate-limited by design. Finally, the repository ships a github.db file at the top level, which means a fresh clone may already contain someone else's scan results; the FAQ addresses this by warning that the example keys in the repository may expire and telling users to scan for their own.
Where ChatGPT-API-Scanner sits against trufflehog and gitleaks
The obvious comparison is with dedicated secret scanners such as trufflehog and gitleaks. Those tools work from the inside out: you point them at a repository, a filesystem or a git history you already have access to, and they verify or report credentials in code you own or are authorized to audit. They are built for CI pipelines and pre-commit hooks, and they do not need a browser or a GitHub login.
ChatGPT-API-Scanner works from the outside in. It searches a public platform for repositories it does not control, using regex queries that the platform's API will not accept, and it verifies each candidate against OpenAI. That is a different job with a different threat model. If your goal is to stop your own team from committing keys, a pre-commit hook running gitleaks is the right shape of tool, and this project will not help you. If your goal is to measure how much key material is exposed across public GitHub for a research question, the web-search-regex approach is the only one of the three that can express the query at all, which is exactly the trade-off the README's first FAQ describes.
Maintenance, licence and what a fresh clone actually contains
The repository is not archived. Its last push was on 2026-04-17, which is roughly five months before the date of this article, so it is not reasonable to describe it as actively developed on the strength of that alone. The most recent tagged release is v1.5 from 2024-10-22, with v1.4 and v1.3 before it in 2024. The gap between the release history and the commit history suggests ongoing small changes rather than a new release line.
The licence is MIT, which permits commercial and private use with attribution and without warranty. Nothing in the repository suggests a copyleft obligation or a usage restriction beyond the README disclaimer, which is a statement of intent rather than a licence term. That distinction matters: the disclaimer does not change what MIT allows, and it does not grant you permission to scan repositories you have no authorization to inspect. Treat the legal question of authorized scanning as separate from the licence question, and get it answered by someone qualified before running the tool against third-party code.
Upgrade cost is low in the mechanical sense. Dependencies are pinned through uv.lock and the runtime is a single main.py plus a src/ directory, so a version bump means re-running uv sync. The real cost is drift in the things the project does not control: GitHub's search markup, GitHub's push protection defaults, and OpenAI's key validation behaviour. Each of those can change the tool's output without a commit to this repository. The README does not document a rollback procedure or a compatibility matrix, so pinning uv.lock and keeping your own copy of github.db is the practical way to compare runs over time.
Editorial conclusion
Adopt it if you are doing authorized secret-exposure research and want a small, readable Python codebase that writes findings into a single SQLite file you can query yourself. Do not adopt it if you need an automated remediation pipeline, continuous coverage, or anything that works without a logged-in browser session, and do not treat it as a way to obtain working API access: the README states that keys found this way may expire within hours or days. Before running anything, verify that your engagement permits scanning third-party repositories, check that GitHub push protection is not going to make your keyword list useless, and confirm you have Chrome and uv installed as the prerequisites section requires.
Frequently asked questions
Why does ChatGPT-API-Scanner use Selenium instead of the GitHub Search API?
The README states that the tool uses regex search to get the best results, and the official GitHub search API does not support regex search while the web-based search does. Selenium drives a real browser so the script can issue those queries.
Why does ChatGPT-API-Scanner limit the programming language in each search?
Web search only returns the first five pages of results, so the README splits the search by language to break the result set into smaller slices and retrieve more keys. You can override the defaults with the -l and -k arguments.
Why doesn't ChatGPT-API-Scanner use multithreading?
The README's FAQ says GitHub searches and OpenAI are rate-limited, so multithreading would not significantly increase efficiency. The scan is therefore sequential.
Where does ChatGPT-API-Scanner store its results?
Results are written to github.db, a SQLite database created in the same directory as the script. The README says you can open it with any SQLite database browser, and it does not document the table schema.
Why are the API keys shown in the ChatGPT-API-Scanner repository not working?
The README explains that the screenshots only demonstrate the tool's scanning ability and that those keys may expire within hours or days. It tells users to scan for their own keys rather than relying on the examples.
What is push protection and how does it affect ChatGPT-API-Scanner?
Push protection is a GitHub feature that scans pushed code for known sensitive patterns and blocks the push when one is found. The README notes that it was enabled by default for new public repositories on March 11, 2024 and broadly on August 21, 2024, and says this could significantly impact the repository.
Community notes