Skip to content
Back to skills

secret-sharing

ASecurity

Share secrets securely using zKettle — a zero-knowledge, self-destructing secret sharing tool. Create, read, revoke, generate, and audit secrets via MCP tools. Secrets are encrypted client-side with AES-256-GCM; the server never sees plaintext. Use for credential sharing, API key rotation, temporary access grants, and secure dead drops.

  • 3 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added May 26, 2026
securitygogitapisecurity

Works with

  • terminal
  • cli
  • api
  • mcp

Security analysis

A100/100

Pro scans all 20 files and shows the line behind each finding

Scanned May 27, 2026

npx -y skills add benderterminal/zkettle --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of secret-sharing?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for secret-sharing
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/benderterminal-secret-sharing/badge)](https://www.skillsdirectory.com/skills/benderterminal-secret-sharing)

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

Download with Pro
SKILL.md
---
name: secret-sharing
description: |
  Share secrets securely using zKettle — a zero-knowledge, self-destructing secret sharing tool.
  Create, read, revoke, generate, and audit secrets via MCP tools. Secrets are encrypted client-side
  with AES-256-GCM; the server never sees plaintext. Use for credential sharing, API key rotation,
  temporary access grants, and secure dead drops.
allowed-tools: mcp__zkettle__create_secret mcp__zkettle__read_secret mcp__zkettle__revoke_secret mcp__zkettle__list_secrets mcp__zkettle__generate_secret
metadata:
  author: benderterminal
  version: "1.0.0"
---

# Secret Sharing with zKettle

Share passwords, API keys, tokens, certificates, and other sensitive data via self-destructing, one-time URLs. All encryption happens client-side — the server stores only ciphertext.

## Prerequisites

This skill requires a running zKettle MCP server. If zKettle is not installed or configured, see the [zKettle README](https://github.com/benderterminal/zkettle) for installation and MCP setup instructions. zKettle also offers a CLI, HTTP API, and Web UI — refer to the README if the MCP tools are insufficient for a particular workflow.

## How It Works

- Secrets are encrypted with AES-256-GCM on the client
- The decryption key lives in the URL fragment (`#key`) — never sent to the server
- Secrets auto-delete after a configurable view count or time limit
- The server is zero-knowledge: it stores only ciphertext and metadata

## Tools

### `create_secret`

Encrypt and store a secret, returning an expiring URL.

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `content` | string | no | — | Plaintext to encrypt (max 500KB). Visible in conversation context — use `file` instead for maximum security. |
| `file` | string | no | — | Read secret from this file path instead of `content`. Keeps plaintext out of conversation. |
| `views` | integer | no | `1` | Max views before auto-delete (1–100) |
| `minutes` | integer | no | `1440` | Minutes until expiry (1–43200) |

Provide exactly one of `content` or `file`. Returns `url` (with decryption key in fragment) and `delete_token`.

### `read_secret`

Decrypt a secret from a zKettle URL. **Consumes one view.**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `url` | string | yes | Full zKettle URL including the `#key` fragment |
| `file` | string | no | Write decrypted secret to this file path (0600 permissions) instead of returning it |
| `clipboard` | boolean | no | Copy to system clipboard instead of returning. Mutually exclusive with `file`. |

Returns decrypted plaintext by default, or a confirmation message when `file` or `clipboard` is used.

### `revoke_secret`

Permanently delete a secret before it expires.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | string | yes | Secret ID |
| `delete_token` | string | yes | Token returned by `create_secret` |

### `list_secrets`

List all active secrets (metadata only — no content or keys). Returns IDs, creation time, expiry, and remaining views.

### `generate_secret`

Generate a cryptographically random secret. Optionally encrypt and store it in one step.

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `length` | integer | no | `32` | Length in characters (1–4096) |
| `charset` | string | no | `"alphanumeric"` | Character set: `alphanumeric`, `symbols`, `hex`, `base64url` |
| `create` | boolean | no | `false` | If true, encrypt and store the generated secret |
| `views` | integer | no | `1` | When `create=true`, max views (1–100) |
| `minutes` | integer | no | `1440` | When `create=true`, minutes until expiry (1–43200) |

Returns raw generated text, or `url` + `delete_token` when `create=true`.

## Defaults

- **1 view** if `views` is omitted (single-use)
- **1440 minutes** (24 hours) if `minutes` is omitted

## Limits

- **500KB** max plaintext per secret
- **100 views** max per secret
- **43200 minutes** (30 days) max TTL

## Secure Patterns

Plaintext secrets can appear in conversation context (tool inputs/outputs). Use these patterns to minimize exposure.

### Creating secrets — keep plaintext out of context

- `create_secret(file="/path/to/secret.txt")` — reads from file, plaintext never in tool call. Ask the user before deleting the source file afterward.
- `generate_secret(create=true)` — generates + encrypts in one step, plaintext never in response
- Prefer these over `create_secret(content="...")` which puts the raw value in conversation context

### Reading secrets — keep plaintext out of context

- `read_secret(url="...", file="/tmp/secret.txt")` — writes to file, returns confirmation only
- `read_secret(url="...", clipboard=true)` — copies to user's clipboard, returns confirmation only
- Subagents can read the file at the written path without the secret entering conversation context
- Default `read_secret(url="...")` returns plaintext directly into conversation — warn the user before using this form
- **File cleanup**: Files written by `file` do NOT self-destruct. After the secret has been used, ask the user for permission to delete the file, then remove it. Do not leave secret files on disk.

## Common Workflows

### Share a credential with someone

```
1. create_secret(file="/path/to/credential.txt", views=1, minutes=60)
   — or create_secret(content="the-password", views=1, minutes=60) if plaintext exposure is acceptable
2. Share the returned URL with the recipient
```

The secret vanishes after one view or 60 minutes, whichever comes first.

### Rotate an API key

```
1. generate_secret(create=true, length=48, charset="alphanumeric", views=2, minutes=240)
2. Share the URL with the team member who needs it
3. revoke_secret(id="old-secret-id", delete_token="old-token") to kill the old one
```

### Temporary access grant

```
1. create_secret(content="temp-token", views=1, minutes=30)
2. Send the one-time link — expires after a single view or 30 minutes
```

### Audit active secrets

```
1. list_secrets() — review what's still live
2. revoke_secret() on any that are no longer needed
```

### Read a shared secret

```
1. Receive a zKettle URL from a human or another agent
2. read_secret(url="https://example.com/s/abc123#key", file="/tmp/secret.txt")
   — or read_secret(url="...", clipboard=true) to copy to clipboard
   — or read_secret(url="...") to return plaintext directly (enters conversation context)
3. Use the decrypted content
```

## Agent-to-Agent Secret Sharing

zKettle is well-suited for secure coordination between agents — subagents, teammates, or any multi-agent workflow where credentials need to move between contexts without leaking into conversation logs.

### When to use

- A subagent needs a credential to complete its task (e.g., an engineer agent needs a deploy token)
- Agents on a team need to pass secrets to each other without the lead's context window seeing the plaintext
- A workflow generates a credential in one agent and consumes it in another

### Pattern: file-based handoff (recommended)

The creating agent writes the secret to zKettle, passes only the URL to the receiving agent. The receiving agent reads it to a file, uses it, then cleans up.

```
Agent A (creator):
1. create_secret(content="deploy-token-xyz", views=1, minutes=30)
2. Send the URL to Agent B via message

Agent B (consumer):
1. read_secret(url="...", file="/tmp/deploy-token.txt")
2. Use the file contents for the task
3. Delete /tmp/deploy-token.txt when done
```

The plaintext never enters either agent's conversation context — Agent A sees only the URL and delete token, Agent B sees only a confirmation message.

### Pattern: generated credential handoff

When the secret doesn't need to be a specific value (e.g., a new API key, a temporary password):

```
Agent A:
1. generate_secret(create=true, length=48, views=2, minutes=60)
2. Send the URL to Agent B and keep the delete_token
3. After Agent B confirms usage, revoke_secret() to clean up
```

### Guidelines

- Set `views` to the exact number of agents that need to read the secret — no more
- Use short TTLs (`minutes`) appropriate to the workflow duration
- The creating agent should retain the `delete_token` and revoke after the workflow completes
- Prefer `file` on the read side so plaintext stays out of all conversation contexts
- The receiving agent is responsible for deleting the local file after use

## Gotchas

- **URL fragments matter**: The `#key` portion contains the decryption key. Some tools strip URL fragments — always ensure the full URL (including `#key`) is passed to `read_secret`.
- **Reading consumes a view**: If the secret has only 1 view remaining, `read_secret` permanently destroys it. Warn the user before reading single-view secrets.
- **`list_secrets` is metadata only**: It returns IDs, creation time, expiry, and remaining views — never content or decryption keys.
- **Conversation exposure**: Using `create_secret(content="...")` puts the plaintext in the conversation context. Use `generate_secret(create=true)` when the user doesn't need a specific value.

Files in this skill

  • .golangci.yml235 B
  • Dockerfile599 B
  • Makefile1.1 KB
  • SKILL.md9.1 KB
  • baseurl/baseurl.go459 B
  • baseurl/baseurl_test.go923 B
  • cmd/banner.go585 B
  • cmd/cmd_test.go6.7 KB
  • cmd/config.go983 B
  • cmd/create.go3.9 KB
  • cmd/errors.go571 B
  • cmd/flags.go1.1 KB
  • cmd/flags_test.go1.9 KB
  • cmd/generate.go1015 B
  • cmd/generate_test.go2.1 KB
  • cmd/httpclient.go200 B
  • cmd/list.go1.9 KB
  • cmd/mcp.go4.1 KB
  • cmd/read.go3 KB
  • cmd/revoke.go1.3 KB

Attribution

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

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.