The primary use-case is sharing sensitive data by making the information self-destructed, accessible only once and protected by easy-to-share PIN code. I just needed a simple and better alternative to the most popular way of passing passwords, which is why this project was created. Doing this by email always made me concerned about the usual "security" of sending user and password info in two different emails - which is just a joke.
It runs on safesecret.info for real. Feel free to use it if you are crazy enough to trust me, or just run your own from prepared docker image. And of course, you can build from sources as well.
Create a safesecret link to your message by entering 3 things:
- Content of your secret message
- Expiration time of your secret message
- Secret PIN
This will give you a link which you can send by email, chat or share by using any other means. As soon as your recipient opens the link they will be asked for the secret PIN and see your secret message. The PIN is (typically) numeric and easy to pass by a voice call or text message. Each link can be opened only once and the number of attempts to enter a wrong PIN is limited to 3 times by default.
- It doesn't keep your original message or PIN anywhere, but encrypts your message with PIN (hashed as well)
- It doesn't keep any sensitive info in any logs
- It doesn't keep anything on a disk in any form (in case of default engine)
- As soon as a message is read or expired it will be deleted and destroyed permanently
- In order to steal your message, bad guys would need access to your link as well as PIN code
Feel free to suggest any other ways to make the process safer.
- Download
docker-compose.yml
andsecrets-nginx.conf
- Adjust your local
docker-compose.yml
with:- TZ - your local time zone
- SIGN_KEY - something long and random
- MAX_EXPIRE - maximum lifetime period, default 24h
- PIN_SIZE - size (in characters) of the pin, default 5
- PIN_ATTEMPTS - maximum number of failed attempts to enter pin, default 3
- DOMAIN - your domain name (e.g., example.com)
- PROTOCOL - http or https
- Setup SSL:
- The system can make valid certificates for you automatically with integrated nginx-le. Just set:
- LETSENCRYPT=true
- LE_EMAIL=[email protected]
- LE_FQDN=www.example.com
- In case you have your own certificates, copy them to
etc/ssl
and set:- SSL_CERT - SSL certificate (file name, not path)
- SSL_KEY - SSL key (file name, not path)
- The system can make valid certificates for you automatically with integrated nginx-le. Just set:
- Run the system with
docker-compose up -d
. This will download a prepared image from docker hub and start all components. - if you want to build it from sources -
docker-compose build
will do it, and thendocker-compose up -d
.
See docker-compose.yml for more details
You can also run Safesecret directly without Docker:
./secrets [OPTIONS]
Available Options:
-e, --engine=[MEMORY|BOLT]
- storage engine (default: MEMORY)-k, --key=
- sign key (required for security)--pinsize=
- pin size in characters (default: 5)--expire=
- max lifetime for messages (default: 24h)--pinattempts=
- max attempts to enter pin (default: 3)--bolt=
- path to boltdb file when using BOLT engine (default: /tmp/secrets.bd)--web=
- web UI static files location (development only, uses embedded files if not set)--branding=
- application title/branding text (default: "Safe Secrets")-d, --domain=
- site domain (required for generating message links)-p, --protocol=[http|https]
- site protocol (default: https)--dbg
- enable debug mode
Environment Variables:
All options can also be set via environment variables:
ENGINE
- storage engineSIGN_KEY
- sign keyPIN_SIZE
- pin sizeMAX_EXPIRE
- max lifetimePIN_ATTEMPTS
- max pin attemptsBOLT_FILE
- boltdb file pathWEB
- web UI location (development only, uses embedded files if not set)BRANDING
- application title/branding textDOMAIN
- site domainPROTOCOL
- site protocol
Example:
# Run with in-memory storage
./secrets -k "your-secret-key" -d "example.com" -p https
# Run with persistent storage (BoltDB)
./secrets -e BOLT --bolt=/var/lib/secrets/data.db -k "your-secret-key" -d "example.com"
# Run with custom branding
./secrets -k "your-secret-key" -d "example.com" --branding="Acme Corp Secrets"
Safesecret usually deployed via docker-compose and has two containers in:
- application
secrets
container providing both backend (API) and frontend (UI) - nginx-le container with nginx proxy and let's encrypt SSL support
Application container is fully functional without nginx proxy and can be used in stand-alone mode. You may want such setup in case you run safesecret behind different proxy, i.e. haproxy, AWS ELB/ALB and so on.
- Raycast Extension - quickly share any text with Safesecret from Raycast
- Shortcut - a shortcut for Shortcuts app on Apple platforms. Adds integration with Safesecret to Share menu on iOS and to Share menu and Services menu on macOS
Safesecret provides trivial REST to save and load messages.
POST /api/v1/message
, body - {"message":"some top secret info", "exp": 120, "pin": "12345"}
exp
expire in N secondspin
fixed-size pin code$ http POST https://safesecret.info/api/v1/message pin=12345 message=testtest-12345678 exp:=1000 HTTP/1.1 201 Created { "exp": "2016-06-25T13:33:45.11847278-05:00", "key": "f1acfe04-277f-4016-518d-16c312ab84b5" }
GET /api/v1/message/:key/:pin
```
$ http GET https://safesecret.info/api/v1/message/6ceab760-3059-4a52-5670-649509b128fc/12345
HTTP/1.1 200 OK
{
"key": "6ceab760-3059-4a52-5670-649509b128fc",
"message": "testtest-12345678"
}
```
GET /ping
or GET /api/v1/ping
Both endpoints work and return the same response. The ping middleware intercepts any path ending with /ping
.
```
$ http https://safesecret.info/ping
HTTP/1.1 200 OK
pong
```
```
$ http https://safesecret.info/api/v1/ping
HTTP/1.1 200 OK
pong
```
GET /api/v1/params
```
$ http https://safesecret.info/api/v1/params
HTTP/1.1 200 OK
{
"max_exp_sec": 86400,
"max_pin_attempts": 3,
"pin_size": 5
}
```