LiveSecret is a Phoenix LiveView web application built for secure sharing of passwords or other secrets. The secret content is End-to-End Encrypted using your browser's built-in cryptography library, SubtleCrypto.
The following video demonstrates authoring a secret, unlocking it for a recipient, and the recipient decrypting it in another window.
livesecret-video-demo.mov
Because encryption is done within the browser, LiveSecret relies on the physical security of the user's personal computer or mobile device. You should only use LiveSecret from a trusted endpoint, and only if it's hosted by someone you trust.
Also, LiveSecret has not undergone a security audit, so it doesn't provide any guarantees, especially those regarding any technical claims made by the author.
As a user of LiveSecret you alone are responsible for securing secret content.
- End-to-End Encryption with out-of-band key
- Live Presence and Live Secrets
- Burn after reading
- Link expiration
- Admin view
When you author a secret with LiveSecret, it is encrypted within your browser. The ciphertext is written to the server, but the cleartext is only held locally, and it's removed from your browser's memory at some point after the encryption event; the exact timing is dependent on the browser.
LiveSecret always uses a passphrase-like encryption key to encrypt the secret content. When you author a secret, if you don't specifiy a passphrase, one will be generated for you. The passphrase is stored locally in the browser and is never transmitted to the server in any form.
As the author of a secret, you will be required to transmit the passphrase out-of-band with the intended recipient. You're responsible for the method used for this transmission.
Each secret created with LiveSecret has a unique non-enumerable URL. When a someone renders this URL in a browser, a Phoenix LiveView is loaded and the visitor's presence is tracked. All visitors to this page can view the presence of all other users, and metadata is displayed for each including:
- Admin | Recipient
- Peer address and port
- Timestamp of joining | timestamp of leaving
- Locked | Unlocked | Revealed status
The LiveView is updated for all users as the secret is Decrypted and Burned. You never need to refresh the page.
Live mode is for synchronous sharing. When a secret is in Live mode, all users are Locked by default, which means
the LiveSecret server will prevent the ciphertext from being sent to the client. This locks them out from decrypting
the secret even if they know the passphrase. An Admin can unlock a recipient by clicking the Locked
button in the Admin View. When a recipient is Unlocked, they will be prompted for the passphrase, and if correct,
the cleartext content is displayed.
Async mode is for asynchronous sharing. When a secret is in Async mode, all users are Unlocked by default. If an attacker intercepts the URL and passphrase before the secret is burned, they will be able to decrypt the message.
After a successful decryption event, the ciphertext is deleted from the server. This makes it very likely that the cleartext is revealed to exactly 2 people: the author and the receiver. While we can't give a cryptographic guarantee that exactly 2 clients were involved, Live Presence can help to bolster the likelihood. Also, Live-mode Secrets give near-certainty that the cleartext is revealed only to the expected recipient.
Once burned, the URL can still be visited, but there are no actions to be taken by any party. A burned secret is essentially a tombstone.
When you author a secret, you choose the expiration period for all the information stored on the server (ciphertext, iv, and metadata). After the expiration period, all this information will be deleted from the database. If a user visits the URL for this secret after the expiration, they will be informed that the secret does not exist.
The author of the secret can perform a limited set of actions on the secret after creation. This includes:
- Unlocking users in Live Presence
- Burning the secret
- Turning Live mode on or off
The Admin View cannot view or decrypt the ciphertext.
To start the LiveSecret Phoenix server:
- Install dependencies with
mix deps.get
- Install Tailwind CSS with
mix tailwind.install
- Create and migrate your database with
mix ecto.setup
- Start Phoenix endpoint with
mix phx.server
or inside IEx withiex -S mix phx.server
- Run the tests with
mix test
Now you can visit localhost:4000
from your browser.
Please check Phoenix's deployment guides.
We provide a compose.yaml: it uses nginx-proxy to set up a reverse proxy and acme-companion to manage the SSL certificate. We host a publicly accessible LiveSecret at livesecret.link, and the instructions here reflect that deployment.
You're encouraged to host your own server. If it's not publicly accessible, you'll have to change the configuration to suit your needs.
touch .env
# For livesecret.link, the .env file contains:
#
# export PHX_HOST=livesecret.link
# export SECRET_KEY_BASE=<result of mix phx.gen.secret>
# export DEFAULT_EMAIL=<my email address>
#
source .env
docker compose build
docker compose up -d
Standard Phoenix:
DATABASE_PATH
: Path to the sqlite database on the filesystemPHX_HOST
: The hostname that is presented to the user's browserPORT
: The port that Phoenix listens onSECRET_KEY_BASE
: Standard Phoenix env var for encrypting cookie, etc
Unique to LiveSecret:
BEHIND_PROXY
: When"true"
LiveSecret Presence discovers the user's IP address via the configured x-header. It is strongly recommended to use a reverse proxy.REMOTE_IP_HEADER
: The trusted x-header that presents the end user's IP address. It must start with "x-"
- Official website: https://www.phoenixframework.org/
- Guides: https://hexdocs.pm/phoenix/overview.html
- Docs: https://hexdocs.pm/phoenix
- Forum: https://elixirforum.com/c/phoenix-forum
- Source: https://github.com/phoenixframework/phoenix
- JavaScript and LiveView unit tests
- Change "Joined at" to "Joined since" and update incrementing counter