Ask a human for an API key without ever holding it in the open

PinchPass generates a one-time, end-to-end encrypted secret request link. The person on the other end opens it, types the value, and hits submit. The value is encrypted in their browser, handed to your process, and written into .env — it never appears in the relay's memory, your shell history, the logs, or the agent's context window.

MIT licensed Go, single binary no account, no server Pi + OpenClaw native 70+ agents via skills.sh

Why this exists

An agent hits a step that needs a credential it does not have. The usual answers all leak it somewhere:

  • Paste it in chat — the plaintext lands in the session transcript, which is stored, replayed as context, and often synced to a provider.
  • Read it from a file you hand over — now the agent has a copy, and so does every log line that echoes it.
  • Paste it into a third-party secret service — the vendor's servers hold your plaintext, and you need an account to use it.
  • Type it into a form on a relay — if the relay terminates the crypto, the relay sees the secret.

PinchPass closes the loop: the human's keyboard is the only place the value exists in plaintext outside your own machine, and the last hop is one-time, expiring, and readable by exactly one process.

Two ways to collect a secret

Native dialog (Pi)

Inside a Pi session, request_secret opens a masked overlay. The value travels from the keyboard to disk — no server starts, no network is touched, the model is never handed the value.

zero network no binary needed

One-time link

Anywhere else, PinchPass serves a single-use form on a random local port and prints a URL. Add -tunnel and it publishes a public bore.pub address so the human does not have to be on your machine.

works over plain HTTP no account

How the link flow works

Four properties make the link safe to hand over a public channel:

One-time
The first accepted submission claims the request. Every later request against that URL gets a 404 — a leaked link is worthless after it is used once.
Time-limited
The server shuts itself down and the link dies when the TTL lapses (30 minutes by default, -ttl to change it).
End-to-end encrypted
The key is generated locally, lives only in the URL fragment, and is never transmitted. Even the tunnel operator sees ciphertext.
No install for the sender
The form is a single self-contained page with TweetNaCl embedded — no WebCrypto, no HTTPS, no app, no account.

Quickstart

shell
# collect one secret over a public link, print JSON for the agent
npx @pinchpass/cli request GEMINI_API_KEY -tunnel -json

# collect several at once into a project .env
pinchpass request DB_HOST DB_PORT DB_USER DB_PASSWORD -out config/secrets.env

# dry run on localhost only, short-lived link
pinchpass request STRIPE_KEY -ttl 5 -note "Stripe restricted key, read-only"

The command blocks until the human submits or the TTL expires, then writes the value and exits. Full list of channels on the install page and every flag in the CLI reference.

What the relay can and cannot see

The relay carries one base64 blob per request and nothing else. It cannot decrypt it, and it never receives the key. What it can observe is metadata: the fact that a request happened, its size, and its timing.

Never leaves your machine in plaintext

The secret value, and the URL fragment containing the decryption key.

Visible to the tunnel relay

That a connection occurred, the byte size of the encrypted blob, and the local port you exposed. The request path is derived from your secret's name (GEMINI_API_KEY becomes /claim/gemini_api_key), so treat the name as public and the value as protected.

The full threat model, with the exact crypto and protocol details →

Built for agents, usable by humans

Agent tool

pi install npm:@pinchpass/cli registers a request_secret tool that chooses a dialog or a link, and returns the saved path and key names.

Agent skill

npx skills add rubybear-lgtm/pinchpass teaches any of 70+ agents when and how to reach for the CLI.

Plain CLI

Scriptable with -json, quiet by default, exits non-zero when the request times out so a pipeline can react.

Agent integration guide →

Common questions

Is the secret ever sent to a third-party server?

No. By default the form is served from 127.0.0.1 and never leaves your machine. With -tunnel, the ciphertext passes through bore.pub, which relays bytes without the key required to read them.

What stops someone who guesses the URL from submitting junk?

Nothing, and it does not matter — a stale or hostile submission is unusable without the key in the fragment, and a wrong value fails to decrypt. Encryption is what protects the secret; one-time use and the TTL are what shrink the window. Details in the threat model.

Does it need HTTPS?

No. The payload is encrypted before it leaves the browser, so a plain http:// link is safe for the value itself. HTTPS would still protect the surrounding metadata from a network observer.

What if the human never submits?

The process exits non-zero and nothing is written. In JSON mode you get {"success": false}, so an agent can retry, switch channels, or ask again.

More questions →