{
  "markdown": "<div align=\"center\">\n\n<img src=\"https://www.apilocker.app/brand/logo-256.png?v=2\" alt=\"API Locker mascot\" width=\"180\" height=\"180\" />\n\n# API Locker\n\n**One vault, three types of credentials. Replace your `.env` file with one token.**\n\n[![npm](https://img.shields.io/npm/v/apilocker?color=0ea5e9&label=npm)](https://www.npmjs.com/package/apilocker)\n[![license](https://img.shields.io/badge/license-MIT-0ea5e9)](./LICENSE)\n[![website](https://img.shields.io/badge/website-apilocker.app-0ea5e9)](https://www.apilocker.app)\n[![mcp](https://img.shields.io/badge/MCP-compatible-10b981)](https://www.apilocker.app/docs/mcp)\n\n</div>\n\nAPI Locker is an encrypted credential vault for developers. Store your LLM API keys, service API keys, and OAuth credentials in one place — then inject them into any command with `apilocker run -- npm start`. Your raw credentials never touch disk, never live in shell history, never get committed to git.\n\nFree to use. [Try it →](https://www.apilocker.app)\n\n---\n\n## What it does\n\n```bash\n# Install\nnpm install -g apilocker\n\n# One-click browser confirmation — no pasted tokens\napilocker register\n\n# Store a credential (for any of 34 provider templates, plus \"custom\")\napilocker store --name OPENAI_API_KEY --provider openai --key sk-proj-...\n\n# Run any command with your vault secrets injected as env vars\napilocker run -- npm start\n#  ↑\n#  process.env.OPENAI_API_KEY is populated for the lifetime of this command,\n#  then gone. No .env file. Nothing on disk. Nothing in shell history.\n```\n\nThat's the whole pitch. Everything else in this repo is making that flow work for every kind of credential a developer has to deal with.\n\n## One vault, three types of credentials\n\nAPI Locker distinguishes three credential types because they're used differently:\n\n<table>\n<tr>\n<td width=\"33%\" valign=\"top\">\n\n### 🧠 LLM API Keys\nSingle opaque tokens for model APIs.\n\nOpenAI, Anthropic, Gemini, Groq, Mistral.\n\n```bash\napilocker store --name OPENAI_API_KEY \\\n  --provider openai \\\n  --key sk-proj-xxxxx\n```\n\n</td>\n<td width=\"33%\" valign=\"top\">\n\n### ⚡ Service API Keys\nSingle tokens for everyday SaaS.\n\nStripe, Twilio, Resend, ElevenLabs, Cloudflare, GitHub, Clerk, Sentry, PostHog, Cloudinary, Mux, SendGrid, Vercel, Upstash, LemonSqueezy.\n\n```bash\napilocker store --name STRIPE_SECRET_KEY \\\n  --provider stripe \\\n  --key sk_live_xxxxx\n```\n\n</td>\n<td width=\"33%\" valign=\"top\">\n\n### 🔗 OAuth Credentials\nMulti-field credentials for sign-in flows.\n\nGoogle, GitHub, Slack, Microsoft, Notion, Spotify, Twitter/X, LinkedIn, Discord, Zoom, Dropbox, Salesforce, HubSpot.\n\n```bash\napilocker store --oauth \\\n  --name google-oauth \\\n  --provider google-oauth \\\n  --client-id ... \\\n  --client-secret ...\n```\n\n</td>\n</tr>\n</table>\n\nUnder the hood, LLM and Service credentials share the same single-string encrypted storage. OAuth is a multi-field encrypted JSON blob. Users experience three product surfaces; implementation shares one foundation.\n\n## Why not just use `.env` files?\n\n| Problem | `.env` file | API Locker |\n|---|---|---|\n| Secrets on disk | ✅ (plaintext) | ❌ (encrypted, AES-256-GCM) |\n| Secrets in git history if misconfigured | ✅ | ❌ |\n| Secrets in shell history when debugging | ✅ | ❌ |\n| Sharing across machines | Manual copy-paste | ✅ (one `apilocker register` per device) |\n| Rotation | Manual edit in every copy | One dashboard click |\n| Audit log of who accessed what | ❌ | ✅ (every reveal + proxy call) |\n| Revocation of a specific device | Nuke every local copy | One `apilocker devices revoke` |\n| AI agent access (Claude, Cursor, etc.) | \"Paste this into Cursor settings\" | Native MCP integration |\n\n## Features\n\n- **Encrypted vault** — AES-256-GCM on every stored credential. Keys never leave the vault in plaintext except when explicitly revealed to an authenticated master-token holder.\n- **Runtime injection** — `apilocker run -- cmd` injects your vault secrets as env vars for the duration of one command, then clears them.\n- **Smart proxy** — `POST /v1/proxy/:keyId` forwards authenticated calls upstream (Stripe, OpenAI, etc.) with the raw key injected server-side. Your app code never sees the secret.\n- **Scoped tokens with rotation** — OAuth2 refresh-token flow with reuse detection. Static, hourly, daily, weekly, monthly rotation cadences. Scoped tokens can only call a pre-approved subset of keys.\n- **Per-device master tokens** — RFC 8628 device authorization flow. Each machine gets its own token; revoke one without affecting others.\n- **Lossless rename** — Renaming a credential never breaks existing `.apilockerrc` files. Old aliases transparently resolve via a `previous_names` fallback.\n- **Pause / resume** — Freeze proxy access without losing the credential. Useful for incident response.\n- **Audit logs** — Every reveal, every proxy call, every rotation, every rename logged with source IP, country, and timestamp. Stream live with `apilocker activity --follow`.\n- **Vault health check** — `apilocker doctor` surfaces stale rotations, unused keys, expiring tokens, and local config permission issues.\n- **Import from `.env`** — `apilocker import .env` migrates an existing project into the vault in one command.\n- **First-class MCP server** — Works with Claude Code, Claude Desktop, Cursor, Zed, Continue, and any other MCP-compatible client. 21 tools give your AI agent the same surface as the CLI.\n\n## Connect your AI assistant (MCP)\n\nAPI Locker exposes a full [Model Context Protocol](https://modelcontextprotocol.io) server so AI agents can read and manage your vault directly.\n\n**Claude Code** (one command):\n```bash\nclaude mcp add apilocker -- apilocker mcp\n```\n\n**Claude Desktop, Cursor, Zed, Continue** — use the `apilocker mcp` stdio bridge in your client's config:\n```json\n{\n  \"mcpServers\": {\n    \"apilocker\": {\n      \"command\": \"apilocker\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\n**Full MCP docs with the 21-tool catalog and per-client setup instructions:** [apilocker.app/docs/mcp](https://www.apilocker.app/docs/mcp)\n\n## Repository layout\n\nThis is a monorepo. The three surfaces are kept together because they share types, provider templates, and product conventions.\n\n```\napilocker/\n├── cli/         # The `apilocker` npm package (published as apilocker)\n├── api/         # Cloudflare Worker backend (api.apilocker.app)\n├── site/        # Marketing site + dashboard + docs (www.apilocker.app)\n└── README.md    # You are here\n```\n\n- **[`cli/`](./cli)** — The published `apilocker` npm package. Built with Node 18+ and Commander. See [`cli/README.md`](./cli/README.md) for the full command reference.\n- **[`api/`](./api)** — The Cloudflare Worker that powers everything: D1 for metadata, KV for encrypted blobs, a Durable Object for rate limiting, and a fully-featured MCP server at `/v1/mcp`.\n- **[`site/`](./site)** — The static marketing site, the dashboard, the `/docs/mcp` integration guide, and a hidden admin analytics page.\n\n## How it works (one minute)\n\n1. **You register a device.** `apilocker register` opens your browser, you click Authorize once, the CLI writes a per-device master token to `~/.apilocker/config.json` (mode 0600).\n2. **You store credentials via the CLI or dashboard.** Each credential is encrypted with AES-256-GCM and the ciphertext lives in Cloudflare KV. Only metadata (name, provider, tags, rotation status) lives in D1.\n3. **Your app uses credentials in one of three ways:**\n   - **Runtime injection:** `apilocker run -- npm start` reveals the needed credentials for one command and exports them as env vars.\n   - **Proxy:** Your app holds a scoped token, calls `POST /v1/proxy/:keyId`, and the API Locker Worker injects the raw key into the upstream call server-side. Your app never sees the secret.\n   - **AI agent:** An MCP-compatible client (Claude Code, Cursor, etc.) connects through the `apilocker mcp` stdio bridge and gets the same 21-tool surface as the CLI.\n4. **Rotation, rename, pause, revoke are all one-click.** Credentials in use stay in use — scoped tokens are unaffected by rotation, `.apilockerrc` files are unaffected by rename, and revoking a device never touches any other device.\n\n## Security posture\n\n- **Per-credential AES-256-GCM encryption** with a unique IV per blob\n- **Encryption key** lives as a Worker secret, never in source\n- **Session cookies:** HttpOnly, Secure, SameSite=Lax, domain-scoped to `.apilocker.app`\n- **CSRF protection** on all OAuth flows via single-use state tokens (10-minute TTL in KV)\n- **RFC 8628 device authorization flow** for CLI sign-in — no pasted master tokens\n- **Per-device master tokens** with independent revocation\n- **Audit log on every access** — reveal, rotate, rename, pause, resume, proxy, MCP call\n- **Rate limiting** via Cloudflare Durable Objects (TrafficMonitor)\n- **Worker self-hosts its own OAuth secrets in its own vault** — vault is the source of truth even for the app's own sign-in credentials (meta-dogfooding)\n\n## Status\n\n**Free plan available.** Unlimited keys, unlimited tokens, unlimited proxy calls. Early adopters get grandfathered into free Pro permanently when paid plans launch.\n\n- **CLI:** [v1.0.2](https://www.npmjs.com/package/apilocker) on npm\n- **API:** live at `api.apilocker.app`\n- **Dashboard:** live at `www.apilocker.app/dashboard`\n- **Docs:** [`/docs/mcp`](https://www.apilocker.app/docs/mcp)\n- **MCP Registry:** [`io.github.apilocker/apilocker`](https://registry.modelcontextprotocol.io)\n\n## Contributing\n\nIssues and PRs welcome. The repo is intentionally kept as a monorepo so a single PR can touch the CLI, API, and site in coordinated steps.\n\n## Contact\n\nThe right address depends on what you want to talk about:\n\n- **Bugs & reproducible issues:** [open a GitHub issue](https://github.com/apilocker/apilocker/issues)\n- **Feature requests, ideas, advice, what's missing:** [feedback@apilocker.app](mailto:feedback@apilocker.app)\n- **General support, account questions:** [support@apilocker.app](mailto:support@apilocker.app)\n- **Security disclosures:** [security@apilocker.app](mailto:security@apilocker.app) — please don't open public issues for security findings\n- **Privacy questions:** [privacy@apilocker.app](mailto:privacy@apilocker.app)\n\n## License\n\n[MIT](./LICENSE)\n",
  "bytes": 10175,
  "sha": "2292f8fe81085b9e6a791d78a14cbf856edf7d9e5339e86dc93ace615529437f",
  "repo_slug": "apilocker/apilocker",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_apilocker_apilocker_ead2e7c9/readme"
}