As a fully distributed team at Articulate, we often have to share sensitive bits of information, such as passwords, API tokens, and customer data. While this isn’t unique to us as a distributed team, security does become more of a challenge when there are hundreds of miles between two people who want to share something sensitive.
We started out much like most teams struggling with a technical problem do: We looked to see if there were any tools on the market that would solve the problem.
We tried using a free web tool that promised secure note sharing, but we really had no way to verify these claims, so we never felt great about using it.
We are big fans of 1Password at Articulate and hoped that shared team vaults synced through Dropbox would help. Unfortunately, there was too much overhead involved in configuring a shared vault for the occasional secret sharing between people on different teams. We needed something with more guarantees about security and less friction to start using it.
Nothing worked, so we built our own tool.
Shush is Born
During one of last year’s hackathons, Luke van der Hoeven and I paired up to solve this issue. We wanted Articulate employees to be able to share sensitive information that would be destroyed after it was read. We called it Shush.
The goals were fairly straight-forward. We knew the notes and secrets needed to be secure, simple to work with, and self-destructing. We decided to store Shush content in memory using Redis and destroy the data once it had been viewed. Sinatra was our framework of choice because we like Ruby and wanted something lightweight. All data is encrypted using SHA-256 over HTTPS/TLS during transmission to our servers.
Although we planned to store the secrets in memory rather than on disk, security was one of the most important considerations for this project, so leaving them in plain text wasn’t good enough. We chose to use Salsa20 cipher with Poly1305 encryption algorithm provided by the NaCl cryptography library to securely store the data in memory.
How Shush Works
When a user puts his or her content into Shush, a unique fingerprint is generated as part of the URL. The fingerprints look something like this:
…And are practically impossible to guess during your lifetime—or the combined lifetimes of all humans on earth.
The fingerprint acts as a lookup key, authenticating the visitor to the secret data in Redis. If the lookup succeeds, Shush will decrypt the value and then display the unencrypted secret to the visitor.
By default, notes are destroyed the first time they are opened. This means the same URL cannot be used more than once to access that note. If you wanted to share the note again, you would have to create a new one.
Shush has some additional note expiration options: 10 minutes, one hour, one day, or one week. These options allow a single note to be accessed multiple times until it expires according to the time limit chosen. We find that the default behavior of destroying a note when it’s first read works best for most cases (and is the most secure option), but there are times when you want to share something more than once.
You can also choose to have us email you automatically when your note is viewed. This can act as a confirmation that the person you’ve sent the note to has read it. Lastly, if a note goes unread for a week, Shush automatically destroys it for you so the link can not be used by future snoopers.
How to Get Involved With Shush
You can find Shush at https://shush.articulate.com and the project is open source on GitHub at https://github.com/articulate/shush.
We have more plans for Shush, but in the meantime, if you have ideas for improvement, please open an issue or pull request on our GitHub repo.