Help us improve
Share bugs, ideas, or general feedback.
From keys-keeper
Securely save/retrieve API keys, SSH keys, server credentials, and domain info using the OS-native credential store (macOS Keychain / Windows Credential Manager / Linux Secret Service, with an encrypted-file fallback on headless servers) via the `keys` CLI. Use when the user mentions saving, getting, or referencing secrets, API keys, tokens, SSH keys, server addresses, or domain configs. Never produces plaintext secret values in output — uses CLI commands that handle files and clipboard directly.
npx claudepluginhub kyzdes/claude-skills --plugin keys-keeperHow this skill is triggered — by the user, by Claude, or both
Slash command
/keys-keeper:keys-keeperThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
<!-- generated from src/keys_keeper/agent_rules/canonical.py; regenerate with `keys init <target> --force`, do not edit by hand -->
Fetches up-to-date library and framework documentation via Context7 MCP for setup questions, API references, and code examples.
Share bugs, ideas, or general feedback.
Storage CLI is keys (run which keys / Get-Command keys to find the install path; typically wherever pipx installed it). Run keys --help for the full surface.
You MUST NOT:
keys reveal (this command exists for the human, not for you)keys output containing values into Edit/Write/Bash echoYou CAN:
keys list / keys info NAME — metadata only, no valueskeys copy NAME — value goes to clipboard with 30s auto-clear, never stdoutkeys inject NAME --file PATH --as ENV — value goes directly to filekeys resolve PATH — placeholder substitution in file (writes back to the same path)keys add NAME --from-clipboard / --from-file PATH / --stdin (when the user already piped)keys ssh NAME — opens ssh session with resolved key (CLI manages tempfile with locked-down permissions: POSIX 0600 on macOS/Linux, icacls user-restricted ACL on Windows)keys rm NAME (use --cascade if the entry is referenced by others)keys edit NAME — change tags / note / non-secret fields (--field key=value)keys audit --name X --since 7d / --op copy — search the audit logkeys doctor — paths + keychain sync check, useful when a value is missingkeys quickstart — read-only getting-started (config dir, command tour, first-key walkthrough); shows no valuesOnly run this flow when the user explicitly asks to set up, install, or get started with keys-keeper (or invokes the skill directly). Do NOT volunteer to migrate existing secrets or restructure their setup unprompted.
keys --version (or
which keys / Get-Command keys). If it works → skip to step 4.pipx install git+https://github.com/kyzdes/keys-keeper-skill.git
(no pipx? macOS brew install pipx && pipx ensurepath; Linux
python3 -m pip install --user pipx && pipx ensurepath)python -m pipx install "git+https://github.com/kyzdes/keys-keeper-skill.git"sudo apt install libsecret-tools.keys may need a fresh terminal for PATH to
pick it up. Re-check with keys --version.keys quickstart. It's read-only, shows no secret
values, and prints the config dir, entry count, the core commands, and a
first-key walkthrough. Then offer concrete next steps and let the user pick:
(a) add their first key, (b) open the admin with keys serve, (c) install a
quick-launch shortcut with keys app install.keys add NAME --from-clipboard …
commands for them to run, and remind them any value already pasted into this
chat is compromised and should be rotated.keys add NAME --type TYPE --from-clipboard --tag ... --note "...".--from-file path) or open keys serve and use the web form (clipboard truncation can corrupt long PEMs).keys serve → Bulk import page (the parser handles key=value lines, multi-line PEMs, tags, and type override per-line).ALWAYS use keys inject or keys resolve. Never Edit with the value. Never Bash with $(keys ...) substitution that echoes the value.
Examples:
keys inject openrouter-cline --file .env --as OPENROUTER_API_KEYkeys resolve .envkeys info NAME for non-sensitive fields (host, user, port).keys ssh NAME to actually connect — the CLI handles key material itself.keys: write __KEYS:name__ placeholders, then keys resolve PATH at runtime.keys serve — opens a browser to a tokenized URL. The token migrates from ?t= into an HttpOnly session cookie on the first hit; subsequent navigations don't carry it in the URL. The server idle-shuts-down after 15 min, or via the Settings → Shutdown button.keys app install — drops an OS-native shortcut so the user can launch keys serve without a terminal. On macOS: a Spotlight-searchable Keys Keeper.app in ~/Applications (Cmd+Space → "Keys Keeper"). On Windows: a Keys Keeper.lnk in the per-user Start Menu Programs folder.--force overwrites an existing install. --system (macOS only) targets /Applications and may need sudo.keys app uninstall removes it.~/Library/Logs/keys-keeper.log.keys serve, the CLI prints a one-line tip suggesting this command; once installed, the tip stops showing.keys audit --name X — most recent first, shows op + caller + file target where applicable.--op {copy,inject,reveal,resolve,add,edit,delete} (matches both bare ops and the mcp.* prefix used when the call came in via MCP), --since 24h / 7d / 30d (free-form), --limit N./audit page has the same data plus charts; either is fine.keys list for everything, with filters --type, --tag, --search.keys info NAME shows refs both ways (used-by reverse refs).Even if you accidentally bypass the rules above by importing the Python package directly (e.g. running python -c "from keys_keeper.composition import build_backend; print(build_backend().get('kk:...'))"), the keychain backend returns a Sealed wrapper whose __repr__/__str__ is "<sealed>" — a bare print / f-string / log statement renders <sealed>, not the value. The only path to plaintext is an explicit .unseal() call. This is defense-in-depth, not a license to try; the rules above still apply.
If you're not sure whether an operation might leak a value, ask the user first rather than guess. The cost of asking is one round-trip; the cost of leaking is permanent.