secure-secret-drop — Claude Code skill: secrets off-chat
This skill spins up a temporary Cloudflare Quick Tunnel link so you can hand an agent a password or key without pasting it into chat.
npx skills add moeadham/secure-secret-drop --skill secure-secret-drop -a claude-codeWhat secure-secret-drop does
Reach for it when an agent needs an API key or password and you would rather not type it into the conversation. The skill creates a one-time public link backed by an HTTP form bound only to 127.0.0.1. You open the link, submit the values once, and they land in the file you named in advance — never in model context.
Under the hood there is a single Python script, scripts/handoff.py, plus cloudflared. No Python packages, no Cloudflare account, domain or token. Run doctor before the first form: if it reports cloudflared=missing, the skill works out your OS and package manager and installs the binary from Cloudflare's official channel. If cloudflared sits outside PATH, point CLOUDFLARED_BIN at it.
The flow goes doctor, then create --field API_KEY --ttl 600, send the link, wait for the user to confirm, run status RECEIPT_ID, then consume into the approved path. Existing keys in the destination need --overwrite. Public TLS terminates at Cloudflare's edge, so Cloudflare sits inside the trust boundary — a deliberate trade-off, not browser end-to-end encryption. Pending form data and receipts are plaintext at rest under $XDG_STATE_HOME/secure-secret-drop/ or ~/.local/state/secure-secret-drop/, so consume or cancel soon after the drop.
What it helps with
- hand an API key to an agent without pasting it in chat
- take a password from a teammate through a one-time link
- write submitted values straight into an agreed
.envpath - check whether a submission arrived with
status, without revealing values - close a form early with
cancel
Example prompts for the agent
- Create a form for API_KEY and API_SECRET and send me the link.
- Check the status of RECEIPT_ID, don't show the values.
- Consume the submission into /exact/approved/path.env.
How to install secure-secret-drop
1Skills CLI (Vercel)
npx skills add moeadham/secure-secret-drop --skill secure-secret-drop -a claude-code2Manually: put the files in place
~/.claude/skills/secure-secret-drop/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/secure-secret-drop/
1Skills CLI (Vercel)
npx skills add moeadham/secure-secret-drop --skill secure-secret-drop -a codex2Manually: put the files in place
.agents/skills/secure-secret-drop/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add moeadham/secure-secret-drop --skill secure-secret-drop -a cursor2Manually: put the files in place
.cursor/skills/secure-secret-drop/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install moeadham/secure-secret-drop secure-secret-drop2Manually: put the files in place
.github/skills/secure-secret-drop/SKILL.md1Skills CLI (Vercel)
npx skills add moeadham/secure-secret-drop --skill secure-secret-drop -a gemini-cli2Platform CLI
gemini skills install https://github.com/moeadham/secure-secret-dropManually: put the files in place
.devin/skills/secure-secret-drop/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add moeadham/secure-secret-drop --skill secure-secret-drop -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about secure-secret-drop
How do I install secure-secret-drop in Claude?
Run npx skills add moeadham/secure-secret-drop --skill secure-secret-drop -a claude-code. The skill lands at ~/.claude/skills/secure-secret-drop/SKILL.md.
What does secure-secret-drop do?
It creates a temporary public Cloudflare Quick Tunnel link with a one-time form. The secret goes into a file you approve, bypassing chat and model context.
What does the skill need to run?
Python 3 with the standard library, the cloudflared executable and outbound access to Cloudflare. No Cloudflare account, domain or token is required.
Source text
SKILL.md · MIT
---
name: secure-secret-drop
description: "Use when someone needs dead-simple secret sharing with an AI agent. Creates a temporary public capability URL via Cloudflare Quick Tunnels for dropping a password, credential, or other secret without putting it in chat or model context."
version: 1.1.1
license: MIT
platforms: [linux, macos]
metadata:
hermes:
tags: [secrets, handoff, cloudflare, one-time-form]
---
# Secure Secret Drop
Use this local skill when a user needs to provide secrets without chat or vault. It creates a temporary public capability URL over an isolated Cloudflare Quick Tunnel backed by an HTTP origin bound only to `127.0.0.1`, then writes submitted bytes directly to an explicitly authorized destination file without placing them in model context.
## Requirements and first-run setup
Required:
- Python 3 with the standard library; no Python packages are needed.
- The `cloudflared` executable.
- Outbound network access to Cloudflare. The local form origin binds only to `127.0.0.1`.
A Cloudflare account, domain, API token, `cloudflared tunnel login`, named tunnel, DNS record, and background service are **not** required. This skill creates an anonymous, temporary Quick Tunnel for each drop.
Before creating the first form, run `doctor`. If it reports `cloudflared=missing`, do not attempt `create` and do not tell the user to solve it manually when terminal tools are available. Read [Cloudflared setup](references/cloudflared-setup.md), identify the host OS and package manager, explain the proposed installation, obtain any approval required for package installation or `sudo`, install from Cloudflare's official distribution channel, and rerun both `cloudflared --version` and `doctor`. Never run `cloudflared tunnel login`, create DNS, install a tunnel service, or alter an existing Cloudflare configuration for this skill.
If `cloudflared` is installed outside `PATH`, set `CLOUDFLARED_BIN` to its absolute executable path for the command invocation or agent service environment. The CLI also checks common macOS/Linux locations automatically.
## Workflow
1. Run `doctor`.
2. Create the form and send the returned URL to the user. Never ask them to paste values in chat.
3. The user submits once and says only that submission is complete.
4. Run `status RECEIPT_ID`; it reveals status and field names, never values, lengths, or hashes.
5. Consume directly into the exact path the user approved, or discard a dummy test receipt.
Resolve the installed skill directory from the skill loader; do not copy an author-specific absolute path. Then use its script:
```bash
PY="$(command -v python3)"
CLI="<installed-skill-directory>/scripts/handoff.py"
$PY "$CLI" doctor
$PY "$CLI" create --field API_KEY --field API_SECRET --ttl 600
$PY "$CLI" status RECEIPT_ID
$PY "$CLI" consume RECEIPT_ID --env-file /exact/approved/path.env
$PY "$CLI" consume RECEIPT_ID --json-file /exact/approved/path.json
$PY "$CLI" consume RECEIPT_ID --env-file /exact/path.env --overwrite
$PY "$CLI" consume RECEIPT_ID --discard
$PY "$CLI" cancel RECEIPT_ID
```
Options: repeat `--field NAME`; use `--label NAME=Visible label`; use `--plain NAME` only for a declared non-secret field. Names initially must match uppercase environment-key style. Default TTL is 10 minutes.
## Operational rules
- Never call `read_file`, `cat`, `show`, or another display command on a receipt. The CLI intentionally has no raw-output command.
- Never put values in arguments, URLs, logs, status output, or chat.
- Existing destination keys require `--overwrite`. A destination path explicitly named by the user already counts as authorization; do not ask again before consuming. Ask only when the destination is missing or ambiguous, or when overwrite approval is required.
- A failed destination validation/write leaves the submitted receipt retriable.
- GET and HEAD are non-consuming; only one valid POST succeeds. Link scanners therefore do not consume the form.
- Forms expire and their local origin/tunnel self-terminate. `cancel` closes early. A successful POST invalidates the capability immediately, allows approximately two seconds for the complete confirmation response to reach the browser, then stops serving; the receipt waits for explicit consumption.
- Use absolute script and destination paths so fresh Hermes sessions behave consistently.
- Keep the form visually restrained and professional; do not use purple in its palette.
## Trust and storage model
This is a TLS-only MVP, not browser end-to-end encryption. The URL is a temporary public capability URL. Cloudflare terminates public TLS at its edge and forwards over the Quick Tunnel to an HTTP origin bound only to `127.0.0.1`. Cloudflare is therefore in the trust boundary. The tunnel is launched with `tunnel --no-autoupdate --config /dev/null --url http://127.0.0.1:<random-port>`; it does not touch named tunnels, existing config, DNS, Workers, or sudo.
Pending form capability/CSRF material and submitted receipts live outside the skill under `$XDG_STATE_HOME/secure-secret-drop/` or `~/.local/state/secure-secret-drop/` by default (directory mode 0700, files mode 0600). Set `SECURE_SECRET_DROP_STATE_DIR` to override it. Receipts are plaintext at rest for this approved MVP and inherit the security of the local user account and disk encryption. Consume or cancel promptly. Receipt/private-form data is deleted after consume, cancel, or expiry; a minimal nonsecret status record remains so `status` can report the terminal state.
See [Security model](references/security-model.md) for limits and invariants.
© moeadham · MIT · moeadham/secure-secret-drop