Metadata-Version: 2.5
Name: loosekeys
Version: 0.1.0
Summary: Find API keys and tokens sitting in plain text on your machine: shell history, .env files, AI tool configs. Masked output, nothing leaves your computer.
Project-URL: Homepage, https://github.com/ArkaKhorchidian/loosekeys
Project-URL: Issues, https://github.com/ArkaKhorchidian/loosekeys/issues
Author: Arka Khorchidian
License-Expression: MIT
License-File: LICENSE
Keywords: api-keys,cli,credentials,devsecops,dotenv,mcp,secret-scanning,secrets,security,shell-history
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Security
Classifier: Topic :: Utilities
Requires-Python: >=3.9
Requires-Dist: rich>=13
Provides-Extra: test
Requires-Dist: pytest>=7; extra == 'test'
Description-Content-Type: text/markdown

<h1 align="center">loosekeys</h1>

<p align="center"><b>Find the API keys sitting in plain text on your laptop.</b><br>
Shell history, forgotten <code>.env</code> files, AI tool and MCP configs, CLI credential stores. One command, nothing leaves your machine.</p>

<p align="center">
  <a href="https://pypi.org/project/loosekeys/"><img src="https://img.shields.io/pypi/v/loosekeys.svg" alt="PyPI"></a>
  <a href="https://github.com/ArkaKhorchidian/loosekeys/actions/workflows/ci.yml"><img src="https://github.com/ArkaKhorchidian/loosekeys/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
  <img src="https://img.shields.io/pypi/pyversions/loosekeys.svg" alt="Python">
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT"></a>
</p>

```bash
uvx loosekeys        # or: pipx run loosekeys
```

<p align="center">
  <img src="docs/demo.gif" alt="loosekeys scanning a home directory and finding API keys in shell history, .env files and MCP configs" width="760">
  <br><sub>Demo run against a sandboxed home directory filled with fake keys.</sub>
</p>

Repo scanners like gitleaks and trufflehog guard what you *commit*. But most leaked keys never
get near a commit. They're the `export OPENAI_API_KEY=sk-...` you typed into your terminal
eight months ago and your shell has saved ever since; the `.env` in a side project you forgot
existed; the GitHub token you pasted into an MCP server config. loosekeys looks where those
end up.

## What it checks

| Where | Why it matters |
|---|---|
| **Shell & REPL history** (zsh, bash, fish, PowerShell, Python, Node, psql, MySQL, ...) | Every key you ever typed or pasted, saved in plain text, forever |
| **Shell config** (`.zshrc`, `.bashrc`, `.profile`, fish, PowerShell profile) | Exported keys are readable by every program you run, including every npm `postinstall` script |
| **AI tools & MCP servers** (Claude Code & Desktop, Cursor, Windsurf, VS Code, Continue, aider, Gemini CLI, Codex, Zed, llm) | Keys pasted into JSON config files |
| **Project files** (`.env*`, `secrets.toml`, `*.tfvars`, service-account JSON, docker-compose, ...) across your home folder | Flags files **committed to git** and projects you haven't touched in 6+ months |
| **CLI credential stores** (`~/.aws`, `.npmrc`, `.pypirc`, `.netrc`, Docker, kubectl, gcloud, gh, Cargo, ...) | Where tools expect logins to live, but still plain text |
| **SSH keys** | Private keys with no passphrase |

It recognizes 30+ token formats precisely: OpenAI, Anthropic, GitHub, GitLab, AWS, Google, Stripe,
Slack, Hugging Face, npm, PyPI, Groq, xAI, OpenRouter, Supabase, DigitalOcean, Twilio, SendGrid,
Telegram, database URLs with passwords, private keys, and more. It also catches `SOMETHING_API_KEY=...`
style assignments while ignoring placeholders like `your_key_here`, `${VAR}` and `changeme`.

## Clean up

```bash
loosekeys --redact-history
```

This replaces every secret in your history files with `[REDACTED]`:
- every other byte stays untouched, including zsh's history encoding
- it keeps a backup first (`.zsh_history.loosekeys.bak`, owner-only permissions)
- it writes atomically

Close other terminal sessions first: open shells hold their history in memory and can write it back.

Redacting doesn't make a leaked key safe. The report links to each provider's page for **rotating**
the keys that ended up in history, shell config or git, and tells you what to do about the rest.

## Privacy

- **Nothing leaves your machine.** loosekeys makes no network requests, ever.
- **Secrets are never printed.** Values show as `sk-proj••••••Gi`, in the terminal and in `--json`
  alike. The test suite asserts no full secret appears in any output.
- **It's read-only** unless you pass `--redact-history`.

## Options

```bash
loosekeys ~/code ~/work      # search these folders for project files instead of your whole home
loosekeys --no-projects      # only check the well-known locations (fast)
loosekeys --json             # machine-readable, still masked; exit code 1 if anything is found
```

## Install

```bash
pipx install loosekeys       # or: uv tool install loosekeys / pip install loosekeys
```

Python 3.9+ on macOS, Linux and Windows. Zero config. The only dependency is
[rich](https://github.com/Textualize/rich).

## Contributing

New token formats and new tool config locations are the most useful contributions. Add the
pattern in `detectors.py`, add a fake example in `tests/fakehome.py` (built at runtime, never
committed as a literal), and run `pytest`.

## License

MIT
