Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Api Patterns

ASecurity

The Keeper Secrets Manager tool surface as exposed through Conduit: the nine read-only tools and their access tiers, the ten blocked tools and whether each is withheld by policy or broken upstream, the arguments stripped from `generate_password`, how the KSM application bounds everything the connection can see, the `configBase64` credential, and the error vocabulary.

48 stars
0 votes
0 copies
1 views
Added 10/2/2026
ai-agentsgodockergitapisecurity

Works with

terminalcliapimcp

Security Analysis

A100/100

Scanned 10/2/2026

$npx -y skills add wyre-technology/msp-claude-plugins --skill api-patterns --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Api Patterns?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Api Patterns
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wyre-technology-api-patterns-9614d91c/badge)](https://www.skillsdirectory.com/skills/wyre-technology-api-patterns-9614d91c)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: "Keeper Secrets Manager API Patterns"
description: >
  The Keeper Secrets Manager tool surface as exposed through Conduit: the
  nine read-only tools and their access tiers, the ten blocked tools and
  whether each is withheld by policy or broken upstream, the arguments
  stripped from `generate_password`, how the KSM application bounds
  everything the connection can see, the `configBase64` credential, and
  the error vocabulary.
when_to_use: >-
  When calling any Keeper tool, deciding whether an operation is possible
  at all, or diagnosing a Keeper connection failure. Use when: keeper
  secrets manager, ksm, keeper mcp, keeper tools, keeper auth, keeper 401,
  configBase64, keeper read-only, or "can Claude write to Keeper".
---

# Keeper Secrets Manager Tools & API Patterns

## Overview

Keeper Secrets Manager (KSM) is Keeper's machine-access product: an
*application* is granted access to specific shared folders in a Keeper
vault, and clients authenticate as that application rather than as a
person. This plugin documents the KSM tool surface reached through the
WYRE Conduit gateway, which fronts Keeper's
[ksm-mcp](https://github.com/Keeper-Security/keeper-mcp-golang-docker)
server.

Two boundaries govern everything here, and they sit in different places:

- **What the connection can see** is set in Keeper, by the KSM
  application's folder grants. Conduit cannot widen it. See
  [application-setup](../application-setup/SKILL.md).
- **What the connection can do** is set at the bridge: v1 is
  **read-only**, enforced by an allowlist, not by a setting.

## The v1 tool surface — nine tools

| Tool | Tier | Returns |
|------|------|---------|
| `list_secrets` | read | Record metadata for the application's scope; optional folder filter |
| `list_folders` | read | Folders shared to the application |
| `health_check` | read | Server and KSM connectivity status |
| `get_server_version` | read | Upstream server version |
| `search_secrets` | **admin** | Record metadata matching a query — but the *match* runs over notes and field values, so a hit reveals that the query string appears in a secret |
| `get_secret` | **admin** | A full record; sensitive fields masked unless `unmask: true` |
| `get_field` | **admin** | One value, addressed by KSM notation |
| `get_totp_code` | **admin** | A live TOTP code for a record carrying a TOTP field |
| `generate_password` | **admin** | A generated password string |

`search_secrets` is the one whose tier does not follow from its return
value. It returns metadata — `uid`, `title`, `type`, `folder` — and nothing
else. But it matches case-insensitively against the record's notes and the
values of its `login`, `url`, `hostname` and `address` fields, so a caller
who never receives a secret can still ask "does any record in scope contain
this substring?" and get a reliable yes/no. That is a confirmation oracle
over credential material, so it is classified **admin** even though its
response carries no secret. Read the tier from what a tool can *reveal*, not
from what it returns.

The tier is Conduit's access classification, not a Keeper concept. Every
tool that can return credential material is **admin**, which outranks
write in Conduit's model — a Keeper read *is* a credential read. Five
metadata tools sit at read. Grant accordingly: a technician who needs to
find records does not need the admin four.

## What is not exposed, and why

Ten upstream tools are blocked at the bridge. They are absent from
`tools/list`, and a direct call returns an error rather than executing.
Do not plan around them or offer them.

The **reason** column matters when someone asks for one to be turned on.
Eight are withheld by policy — a decision that could in principle be
revisited. Two are blocked because they do not work at the pinned
upstream version; no policy change would make them functional.

| Blocked tool | Why | Category |
|--------------|-----|----------|
| `create_secret`, `update_secret`, `delete_secret` | Vault writes | Policy |
| `create_folder`, `delete_folder` | Vault structure writes | Policy |
| `upload_file` | Vault writes | Policy |
| `get_all_secrets_unmasked` | One call dumps every secret in the application's scope, unmasked, into model context | Policy — permanent |
| `ksm_execute_confirmed_action` | Upstream's confirmation-bypass executor | Policy — permanent |
| `get_record_type_schema` | Returns `record templates not loaded` on every call at the pinned version | **Broken upstream** |
| `download_file` | Cannot return file contents, in any configuration | **Broken upstream** |

The two permanent entries stay blocked even if a later version enables
writes. When a user asks for a bulk export of their vault, the answer is
that the capability is deliberately absent — then offer the read-side
equivalent: `list_secrets` for the inventory, and `get_field` per value
actually needed.

### The two broken-upstream entries, in detail

Both were exposed in an earlier draft of this integration and removed
after the upstream source was read. Knowing *why* saves a technician from
diagnosing a healthy connection, and saves anyone from filing a request
to re-enable them.

**`get_record_type_schema`** would have returned a record type's field
schema. The embedded templates are loaded by a function the shipped
server never calls — `LoadRecordTemplates` has no non-test caller and the
package has no `init` — so `GetSchema` always takes its
templates-are-nil branch and every call fails with
`record templates not loaded. Call LoadRecordTemplates first`. A message
naming an internal function reads like a server fault; it is not one, and
it is not fixable from the client.

Nothing is lost: **`get_secret` with `unmask` unset is the better answer
anyway.** Its response keys *are* the field names KSM notation addresses,
read from the actual record rather than from a type template, with
sensitive values masked. Skills route field-name discovery there not as a
workaround but because it is the correct tool for the question.

**`download_file`** would have fetched an attachment. Upstream's client
signature is `DownloadFile(uid, fileUID, savePath string) error` — it
returns only an error and writes the bytes to `savePath` on the server's
filesystem, so the caller never receives file content under any
argument. Passing `save_path` through would let one tenant write
attacker-chosen paths into a container shared with every other tenant's
child process; stripping it leaves no destination. There is no
configuration of this tool that both works and is safe, so it is out.

**Attachments are therefore not retrievable through this connection at
all.** `get_secret` still lists them — `name`, `title`, `size`, `type` —
so the correct response to "send me the VPN profile from that record" is
to confirm the attachment exists, name it and its size, say which record
holds it, and send the user to the Keeper vault to download it.

### Stripped arguments

One allowed tool has its write-capable arguments **stripped from both the
advertised schema and the inbound call**, so the affordance is never
visible:

| Tool | Stripped | Would otherwise |
|------|----------|-----------------|
| `generate_password` | `save_to_secret`, `folder_uid` | Create a record |

`generate_password` therefore always returns the password to the caller.
It cannot be used as Keeper's "generate without showing the AI" flow —
that flow requires the stripped arguments. Treat its output as secret
material like any other.

## Connection & authentication

The credential is configured **in the Conduit connection UI**, not on the
technician's machine and not in local environment variables. One field:

| Field | Label in Conduit | Value |
|-------|------------------|-------|
| `configBase64` | KSM Base64 Configuration | The KSM application's device configuration, base64-encoded (starts `ewog…`) |

Get it from Keeper Vault → **Secrets Manager** → the application →
**Devices** tab → **Add Device**, choosing the base64 configuration
output. The blob decodes to JSON containing `clientId`, `privateKey`,
`appKey` and `hostname`; the bridge validates that shape and returns
**HTTP 401** if it does not decode to it. It never falls back to any
other credential, which is what keeps one tenant's request from reaching
another tenant's vault.

The configuration is a device credential, not a user credential. It
carries the application's scope and nothing else — no vault-wide access,
no admin console access, no ability to re-share.

## Scope is the application, not the vault

Every list, search and get is bounded by the folders shared to the KSM
application. A record the application cannot see does not appear in
`list_secrets`, is not found by `search_secrets`, and returns not-found
by UID. That is correct behaviour, not a failure:

- Do not report "record not found" as an outage or a broken credential.
  Confirm scope first with `list_folders`.
- Do not conclude a vault is empty because `list_secrets` came back
  short. It reflects one application's grants.

## Error handling

| Symptom | Meaning | Action |
|---------|---------|--------|
| HTTP 401 from the gateway | `configBase64` missing, not base64, or missing a required key | Re-submit the connection in Conduit with a fresh device config |
| `no active session` | The upstream server has no usable KSM configuration | Connection-level problem; re-submit the credential |
| Tool absent from `tools/list` | Either blocked by the read-only allowlist (policy) or broken in the pinned upstream — the two are not the same and only one could ever be revisited | Not recoverable client-side — check the blocked table above for which reason applies |
| `record not found` | Out of the application's scope, or the UID is wrong | `list_folders`, then `search_secrets` by title |
| `field '<name>' not found` | Field name is not on the record | Inspect the record with a masked `get_secret`; its keys are the field names |
| `failed to parse notation: …` | Malformed KSM notation | See [notation-queries](../notation-queries/SKILL.md) |
| `invalid UID: UID must be between 16 and 32 characters` | A title was passed where a UID is required | Resolve the title to a UID first |
| `search query contains suspicious patterns` | The query contains a word the input validator rejects | Search a different token — see [finding-secrets](../finding-secrets/SKILL.md) |
| Tool named in a request is not in the list above | Blocked — see the table for whether it is policy or broken upstream | Do not retry; say which it is |
| `no TOTP field found in secret` | The record carries no TOTP seed | Record content, not permissions |

Tool failures arrive as JSON-RPC error code `-32002`; a rate-limit
rejection arrives as `-32029` with `Rate limit exceeded`.

## A note on confirmation prompts

Upstream ksm-mcp asks a human to confirm unmasking and every write, over
the terminal. There is no terminal in a container, so the upstream offers
only two settings: refuse those operations outright, or auto-approve them
all. The deployment runs in batch mode, where they auto-approve — which
is precisely why the write and bulk-disclosure tools are removed at the
bridge instead of being left to a prompt that would never be shown. Do
not describe unmasking to a user as "confirmed by Keeper"; the control
that is actually enforcing anything is the allowlist, plus the
application's own scope.

## Related Skills

- [finding-secrets](../finding-secrets/SKILL.md) — discovery and UID resolution
- [retrieving-credentials](../retrieving-credentials/SKILL.md) — masking semantics and handling discipline
- [notation-queries](../notation-queries/SKILL.md) — `get_field` notation grammar
- [application-setup](../application-setup/SKILL.md) — scoping the KSM application before connecting

Attribution

WYRE-AIWYRE-AI
View sourceSee grades on GitHubMore from wyre-technology →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Terse caveman voice: answer first, fluff gone, every technical fact kept. Use for /caveman, "caveman mode", "talk like caveman", "be brief", "less tokens". Stays on until "stop caveman" or "normal mode".

1100021 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

698461 votes

Writing Skills

Create and manage Claude Code skills in HASH repository following Anthropic best practices. Use when creating new skills, modifying skill-rules.json, understanding trigger patterns, working with hooks, debugging skill activation, or implementing progressive disclosure. Covers skill structure, YAML frontmatter, trigger types (keywords, intent patterns), UserPromptSubmit hook, and the 500-line rule. Includes validation and debugging with SKILL_DEBUG. Examples include rust-error-stack, cargo-dep...

3931 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3421 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Amp, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Grok Build, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

741 votes
View all in ai-agents →