Keyward — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Keyward (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
<p align="center"> <img src="docs/images/cover.png" alt="keyward — a secret broker for AI agents" width="100%"> </p>
<h1 align="center">keyward</h1>
<p align="center"> <strong>Store your API keys once. Let any AI tool request them with your approval — without ever seeing the value.</strong> </p>
<p align="center"> <a href="https://github.com/arturayupov/keyward/actions"><img src="https://github.com/arturayupov/keyward/actions/workflows/ci.yml/badge.svg" alt="CI"></a> <img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT"> <img src="https://img.shields.io/badge/MCP-compatible-5E6AD2" alt="MCP compatible"> <img src="https://img.shields.io/badge/macOS%20%7C%20Windows%20%7C%20Linux-informational" alt="cross platform"> </p>
keyward is an open-source, local, encrypted secret broker for AI coding agents. Instead of pasting API keys into chat (where they leak into context and transcripts) or re-entering the same key in every new session, project, and IDE, you keep your keys in one encrypted vault. When Claude Code, Cursor, Gemini CLI, or any MCP-capable tool needs a key, it requests it by name, you approve that single request in a native OS prompt, and keyward injects only that key into your project. The model never receives the value.
AI tool ──request_key("STRIPE_KEY", project)──▶ keyward ──native approval──▶ you
│ approved
◀── "injected STRIPE_KEY → ./.env" ─────────┘ (value never shown to the model)~/.keyward/vault.age, 0600). The master key lives in the OS keystore (macOS Keychain / Windows Credential Manager / Linux libsecret), never on disk in plaintext.list_keys, request_key) for AI tools, and a `keyward` CLI for everything else.list_keys returns names only; request_key returns a confirmation; the audit log records the decision but never the value.# Homebrew (macOS / Linux)
brew install arturayupov/tap/keyward
# Scoop (Windows)
scoop bucket add arturayupov https://github.com/arturayupov/scoop-bucket
scoop install keyward
# Go
go install github.com/arturayupov/keyward/cmd/keyward@latestPre-built binaries (macOS/Windows/Linux, amd64+arm64) are also attached to each release. See INSTALL.md for per-OS notes (incl. Linux libsecret) and TROUBLESHOOTING.md if something doesn't work.
# 1. create the encrypted vault (master key goes into your OS keystore)
keyward init
# 2. import keys you already have scattered in .env files
keyward import ~/projects
# 3. point your AI tool at keyward's MCP server (see below), then just ask:
# "use my STRIPE_KEY for this project" → approve the prompt → donekeyward is a standard stdio MCP server, registered the same way as the official MCP servers. Two steps:
1. Install the binary (once) — go install above, or Homebrew/Scoop (soon), or a release binary.
2. Register it with your AI tool:
# Claude Code — one command:
claude mcp add keyward -- keyward serve-mcpOr add it to the config by hand (~/.claude.json, or a project .mcp.json):
{ "mcpServers": { "keyward": { "command": "keyward", "args": ["serve-mcp"] } } }Cursor, Windsurf, Cline, and other MCP clients use the same command/args shape in their MCP settings. Restart the tool and ask it to use a key by name.
Why not "paste a repo URL"? No MCP client auto-installs a server from a GitHub link — by design, clients won't run arbitrary remote code. keyward is also intentionally local (it needs your OS keystore and writes to your local files), so it isn't a remote/hosted URL server. The two steps above are the standard, secure install path. Full walkthrough in USAGE.md.
| Command | Description |
|---|---|
keyward init | Create the encrypted vault and master key |
keyward import [root] | Import secrets from .env files under root, grouped by project |
keyward add NAME --ns NS | Add/update one secret, value read from stdin (for non-.env creds) |
keyward ls [--ns NS] | List key names and namespaces (never values) |
keyward inject NAME --ns NS --into PATH | Inject one key into a target env file (prompts for approval) |
keyward serve-mcp | Run the MCP server over stdio |
request_key injects it into a target file and returns only a confirmation.~/.keyward/audit.jsonl records tool, key, namespace, target, decision — no value) and never printed by ls/inject.age; the master key lives in the OS keystore.These invariants are enforced by automated tests. Details and threat model in SECURITY.md.
| keyward | envchain | pass / sops | 1Password CLI | |
|---|---|---|---|---|
| Encrypted local store | ✅ | ✅ (Keychain) | ✅ | ✅ (cloud) |
| Agent requests a key by name | ✅ | ❌ | ❌ | ❌ |
| Per-request human approval | ✅ | ❌ | ❌ | ❌ |
| Value never reaches the model | ✅ | n/a | n/a | n/a |
| MCP server for AI tools | ✅ | ❌ | ❌ | ❌ |
| Open source | ✅ (MIT) | ✅ | ✅ | ❌ |
The encrypted-storage problem is solved; keyward adds the missing agent-facing, approval-gated broker on top. See docs/comparisons for honest long-form comparisons (including when each alternative is the better choice).
Full detail in ROADMAP.md. Highlights:
target: "env" injection.Contributions welcome — see CONTRIBUTING.md. Found a security issue? See SECURITY.md for responsible disclosure.
MIT © 2026 Artur Ayupov
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.