WhisperBin is a secure web application for sharing short text snippets (such as tokens, SSH keys, or passwords) via links that can be viewed exactly once. After retrieval, secrets are deleted automatically.
It is built in Go with server-side rendered HTML templates and optimized for simplicity, privacy, and technical transparency.
As a Kotlin developer, I like exploring new programming languages. Go is well suited for building small, fast server applications, and this project was a good way to try it out.
WhisperBin is designed to be lightweight and easy to run, for example on a Raspberry Pi in a home network. I use it to share passwords and other secrets between different devices.
- One-time retrieval (secret deleted on first access)
- Optional secure mode with manual recipient approval (passcode flow)
- Optional TTL (secret expires automatically after a configurable time)
- Encrypted in-memory storage (AES-GCM with per-instance key)
- No database required
- No storage of sensitive logs
- CSRF protection on all forms
- Per-IP rate limiting
- Minimal and clean UI, no JS frameworks required
- User submits a secret via
/form. - WhisperBin generates a random ID and stores the encrypted secret in memory.
- A one-time link is generated:
https://yourhost/{id} - The recipient visits the link:
- If secure mode is enabled: recipient requests approval with a passcode.
- Otherwise: a reveal page is shown; clicking "Reveal Secret" shows the secret and immediately deletes it.
- The link is invalid after first use or after TTL expiration.
- Backend: Go (net/http, crypto/rand, html/template)
- Frontend: HTML templates (SSR) with Pico.css for minimal styling
- Storage: In-memory map (sync.Mutex protected)
- Routing:
GET /— Submit secret formPOST /secret— Store secretGET /{id}— Reveal page (does not consume the secret)POST /{id}— Reveal and delete the secret (CSRF-protected)POST /confirm/{id}— Manual approval (secure mode)GET /status/{id}— Status polling (secure mode)GET /sse?id={id}— SSE delivery (secure mode)
- Random IDs: 128-bit, securely generated with
crypto/rand - Encryption: AES-GCM with per-instance 256-bit key
- One-time access: Secret is deleted after first view; revealing requires a POST, so link-preview scanners cannot consume it
- TTL support: Expired secrets are automatically purged
- Secure mode: Optional manual recipient approval via passcode + SSE unlock flow
- Rate limiting: Per-IP rate limiting implemented (golang.org/x/time/rate)
- CSRF: All forms protected with CSRF tokens
- No sensitive logging: No storage of secret content or access logs
git clone https://github.com/hkanthak/whisperbin.git
cd whisperbin
go run ./cmd/whisperbinAccess via: http://localhost:8080
go build -o whisperbin ./cmd/whisperbinThe included multi-stage Dockerfile builds from source — no prebuilt binary required:
docker build -t whisperbin .
docker run -p 8080:8080 whisperbinWhisperBin runs behind any TLS-terminating reverse proxy (Traefik, Nginx, Caddy). It can also be deployed straight from this Git repository by any Docker-based PaaS (e.g. Dokploy) that builds the image itself. Behind a proxy, set ALLOWED_ORIGIN to the public URL and TRUST_PROXY=true.
| Environment Variable | Description |
|---|---|
SECRET_KEY |
Optional 32-byte base64-encoded encryption key. If unset, a random key is generated at startup. |
ALLOWED_ORIGIN |
Allowed origin for SSE connections and the base for generated links. Default: http://localhost:8080. |
TRUST_PROXY |
Set to true behind a reverse proxy so rate limiting uses the real client IP (X-Forwarded-For / X-Real-IP). |
.
├── cmd/whisperbin/main.go # Main entrypoint
├── internal/storage/ # In-memory storage + encryption logic
├── internal/web/ # HTTP handlers, templates, CSRF, rate limiting
├── ui/templates/ # HTML templates
├── ui/static/ # CSS, favicon, optional images
└── README.md
WhisperBin is a minimal proof-of-concept for safe sharing of secrets in technical contexts. It is provided as-is without warranty. Do not use it for highly sensitive production data without independent security review.
MIT License — see LICENSE file.

