A simple, secure, self-destructing message service that uses HashiCorp Vault as a backend for temporary secret storage. Share sensitive information with confidence knowing it will be automatically deleted after being read once.
π Security First: Messages are stored in Vault's cubbyhole backend with one-time tokens and automatic expiration.
Read more about the reasoning behind this project in the relevant blog post.
- π₯ Self-Destructing Messages: Messages are automatically deleted after first read
- β° Configurable TTL: Set custom expiration times (default 48h, max 7 days)
- π File Upload Support: Share files up to 50MB with base64 encoding
- π Vault-Backed Security: Uses HashiCorp Vault's cubbyhole for tamper-proof storage
- π« One-Time Tokens: Vault tokens with exactly 2 uses (create + retrieve)
- π¦ Rate Limiting: Built-in protection (10 requests/second)
- π TLS/HTTPS Support:
- Automatic TLS via Let's Encrypt
- Manual certificate configuration
- HTTP to HTTPS redirection
- π No External Dependencies: All assets self-hosted for privacy
- π¦ Lightweight: Only 8.9KB JavaScript (no jQuery)
- π³ Docker Ready: Multi-platform images (amd64, arm64) with SBOM
- βΈοΈ Kubernetes Support: Helm chart included
- π₯οΈ CLI Integration: Shell functions for Bash, Zsh, and Fish
- Features
- Frontend Dependencies
- Quick Start
- Deployment
- Configuration
- Command Line Usage
- Helm Chart
- API Reference
- Development
- Contributing
- License
The web interface is built with modern vanilla JavaScript and has minimal external dependencies:
| Dependency | Size | Purpose |
|---|---|---|
| ClipboardJS v2.0.11 | 8.9KB | Copy to clipboard functionality |
| Montserrat Font | 46KB | Self-hosted typography |
| Custom CSS | 2.3KB | Application styling |
β No external CDNs or tracking - All dependencies are self-hosted for privacy and security.
π¦ Total JavaScript bundle size: 8.9KB (previously 98KB with jQuery)
Get up and running in less than 2 minutes:
# Clone the repository
git clone https://github.com/algolia/sup3rS3cretMes5age.git
cd sup3rS3cretMes5age
# Start with Docker Compose (recommended)
make run
# Access the application
open http://localhost:8082The service will start with:
- Application: http://localhost:8082
- Vault dev server: In-memory storage with token
supersecret
# Start Vault dev server
docker run -d --name vault-dev -p 8200:8200 \
-e VAULT_DEV_ROOT_TOKEN_ID=supersecret \
hashicorp/vault:latest
# Build and run the application
go build -o sup3rs3cret cmd/sup3rS3cretMes5age/main.go
VAULT_ADDR=http://localhost:8200 \
VAULT_TOKEN=supersecret \
SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS=":8080" \
./sup3rs3cretmake run # Start services (Vault + App)
make logs # View logs
make stop # Stop services
make clean # Remove containersdocker compose -f deploy/docker-compose.yml up --build -dBy default, the application runs on port 8082 in HTTP mode: http://localhost:8082
π‘ You can modify deploy/docker-compose.yml to enable HTTPS, HTTP redirection, or change ports. See Configuration options.
The image is available at:
- Docker Hub:
algolia/supersecretmessage:latest - Platforms: linux/amd64, linux/arm64
Build multi-platform images with SBOM and provenance attestations:
# Build for multiple architectures
make image
# Builds: linux/amd64, linux/arm64 with SBOM and provenanceFor detailed step-by-step instructions on deploying to AWS, see our comprehensive AWS Deployment Guide. The guide covers:
- ECS with Fargate (recommended) - Serverless containers with Application Load Balancer
- EKS (Kubernetes) - Using the provided Helm chart on Amazon EKS
- EC2 with Docker - Simple deployment using Docker Compose
# Build for multiple architectures
make image
# Builds: linux/amd64, linux/arm64 with SBOM and provenanceDeploy using your preferred orchestration tool:
| Platform | Documentation |
|---|---|
| Kubernetes | See Helm Chart below |
| Docker Swarm | Use the provided docker-compose.yml |
| AWS ECS | Use the Docker image with ECS task definition |
Important: Deploy alongside a production Vault server. Configure via environment variables:
VAULT_ADDR: Your Vault server URLVAULT_TOKEN: Vault authentication token
See configuration examples below.
β οΈ Critical: Always run this service behind SSL/TLS in production. Secrets sent over HTTP are vulnerable to interception!
Option 1: Inside the Container (Recommended for simplicity)
- Configure via environment variables
- Automatic Let's Encrypt certificates
- See Configuration examples - TLS
Option 2: External Load Balancer/Reverse Proxy
- Simpler certificate management
- Offload TLS processing
- Ensure secure network between proxy and container
- Examples: AWS ALB, Nginx, Traefik, Cloudflare
- β Use HTTPS/TLS in production
- β Use a production Vault server (not dev mode)
- β Rotate Vault tokens regularly
- β Enable rate limiting (built-in: 10 req/s)
- β Monitor Vault audit logs
- β Use strong Vault policies
- β Keep dependencies updated
Deploy to Kubernetes using the included Helm chart:
helm install supersecret ./deploy/charts/supersecretmessage \
--set config.vault.address=http://vault.default.svc.cluster.local:8200 \
--set config.vault.token_secret.name=vault-tokenChart Details:
- Chart Version: 0.1.0
- App Version: 0.2.5
- Includes: Deployment, Service, Ingress, HPA, ServiceAccount
For full documentation, see the Helm Chart README
Endpoint: POST /secret
Content-Type: multipart/form-data
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
msg |
string | Yes | The secret message content |
ttl |
string | No | Time-to-live (default: 48h, max: 168h) |
file |
file | No | File to upload (max 50MB) |
Response:
{
"token": "s.abc123def456",
"filetoken": "s.xyz789uvw012", // If file uploaded
"filename": "secret.pdf" // If file uploaded
}Example:
# Text message
curl -X POST -F 'msg=This is a secret' http://localhost:8082/secret
# With custom TTL
curl -X POST -F 'msg=Short-lived secret' -F 'ttl=1h' http://localhost:8082/secret
# With file
curl -X POST -F 'msg=Check this file' -F 'file=@secret.pdf' http://localhost:8082/secretEndpoint: GET /secret?token=<token>
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
token |
string | Yes | The token from POST response |
Response:
{
"msg": "This is a secret"
}Example:
curl "http://localhost:8082/secret?token=s.abc123def456"Endpoint: GET /health
Response: OK (HTTP 200)
For convenient command line integration and automation, see our comprehensive CLI Guide which includes shell functions for Bash, Zsh, Fish, and WSL.
Quick example:
# Add to your ~/.bashrc or ~/.zshrc
o() { cat "$@" | curl -sF 'msg=<-' https://your-domain.com/secret | jq -r .token | awk '{print "https://your-domain.com/getmsg?token="$1}'; }
# Usage
echo "secret message" | o
o secret-file.txtVAULT_ADDR: address of the Vault server used for storing the temporary secrets.VAULT_TOKEN: Vault token used to authenticate to the Vault server.SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS: HTTP binding address (e.g.:80).SUPERSECRETMESSAGE_HTTPS_BINDING_ADDRESS: HTTPS binding address (e.g.:443).SUPERSECRETMESSAGE_HTTPS_REDIRECT_ENABLED: whether to enable HTTPS redirection or not (e.g.true).SUPERSECRETMESSAGE_TLS_AUTO_DOMAIN: domain to use for "Auto" TLS, i.e. automatic generation of certificate with Let's Encrypt. See Configuration examples - TLS - Auto TLS.SUPERSECRETMESSAGE_TLS_CERT_FILEPATH: certificate filepath to use for "manual" TLS.SUPERSECRETMESSAGE_TLS_CERT_KEY_FILEPATH: certificate key filepath to use for "manual" TLS.SUPERSECRETMESSAGE_VAULT_PREFIX: vault prefix for secrets (defaultcubbyhole/)
Here is an example of a functionnal docker-compose.yml file
version: '3.2'
services:
vault:
image: vault:latest
container_name: vault
environment:
VAULT_DEV_ROOT_TOKEN_ID: root
cap_add:
- IPC_LOCK
expose:
- 8200
supersecret:
build: ./
image: algolia/supersecretmessage:latest
container_name: supersecret
environment:
VAULT_ADDR: http://vault:8200
VAULT_TOKEN: root
SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS: ":80"
SUPERSECRETMESSAGE_HTTPS_BINDING_ADDRESS: ":443"
SUPERSECRETMESSAGE_HTTPS_REDIRECT_ENABLED: "true"
SUPERSECRETMESSAGE_TLS_AUTO_DOMAIN: secrets.example.com
ports:
- "80:80"
- "443:443"
depends_on:
- vaultVAULT_ADDR=http://vault:8200
VAULT_TOKEN=root
SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS=:80VAULT_ADDR=http://vault:8200
VAULT_TOKEN=root
SUPERSECRETMESSAGE_HTTPS_BINDING_ADDRESS=:443
SUPERSECRETMESSAGE_TLS_AUTO_DOMAIN=secrets.example.comVAULT_ADDR=http://vault:8200
VAULT_TOKEN=root
SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS=:80
SUPERSECRETMESSAGE_HTTPS_BINDING_ADDRESS=:443
SUPERSECRETMESSAGE_HTTPS_REDIRECT_ENABLED=true
SUPERSECRETMESSAGE_TLS_AUTO_DOMAIN=secrets.example.comVAULT_ADDR=http://vault:8200
VAULT_TOKEN=root
SUPERSECRETMESSAGE_HTTPS_BINDING_ADDRESS=:443
SUPERSECRETMESSAGE_TLS_CERT_FILEPATH=/mnt/ssl/cert_secrets.example.com.pem
SUPERSECRETMESSAGE_TLS_CERT_KEY_FILEPATH=/mnt/ssl/key_secrets.example.com.pemClean, intuitive interface for creating self-destructing messages with optional file uploads and custom TTL.
Simple, secure interface for viewing self-destructing messages that are permanently deleted upon retrieval.
- Go 1.25.1 or later
- Docker (for Vault dev server)
- Make (optional, for convenience)
# Clone the repository
git clone https://github.com/algolia/sup3rS3cretMes5age.git
cd sup3rS3cretMes5age
# Download dependencies
go mod download
# Build the binary
go build -o sup3rs3cret cmd/sup3rS3cretMes5age/main.go# Run all tests
make test
# Or directly with go
go test ./... -v# Format code
gofmt -s -w .
# Lint
golangci-lint run --timeout 300s
# Static analysis
go vet ./....
βββ cmd/sup3rS3cretMes5age/ # Application entry point
β βββ main.go # (23 lines)
βββ internal/ # Core business logic
β βββ config.go # Configuration (77 lines)
β βββ handlers.go # HTTP handlers (88 lines)
β βββ server.go # Server setup (94 lines)
β βββ vault.go # Vault integration (174 lines)
βββ web/static/ # Frontend assets
β βββ index.html # Message creation page
β βββ getmsg.html # Message retrieval page
β βββ application.css # Styling
β βββ clipboard-2.0.11.min.js
βββ deploy/ # Deployment configs
β βββ Dockerfile # Multi-stage build
β βββ docker-compose.yml # Local dev stack
β βββ charts/ # Helm chart
βββ Makefile # Build automation
Total Code: 609 lines of Go across 7 files
Contributions are welcome! π
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Write tests for new features
- Follow existing code style
- Update documentation as needed
- Ensure all tests pass (
make test) - Run linters (
golangci-lint run)
All pull requests will be reviewed by the Algolia team.
This project is licensed under the MIT License - see the LICENSE file for details.
This project is built on the shoulders of giants:
- HashiCorp Vault - Secure secret storage backend
- Echo - High performance Go web framework
- Let's Encrypt - Free SSL/TLS certificates
- ClipboardJS - Modern clipboard functionality


