Demos

What a stolen database looks like

Claims about encryption are cheap to make, so the smallest demo in the repository is built to be checked rather than believed. It writes a note, then prints the contents of the file it just wrote to, and leaves you to read the row. After that it does the half that encryption on its own cannot do, which is the part I find more interesting and which almost nobody asks about first.

Running it

The notes demo has no login provider, no user table and no password, which keeps the thing being demonstrated visible. Two commands bring the service up on port 8081:

curl -O https://raw.githubusercontent.com/sashyo/minidauth/main/docker-compose.yml
MC_ADMIN_TOKEN=$(openssl rand -hex 32) docker compose --profile public up

You write a note and it is encrypted in the browser, inside the enclave, under a policy the Tide network enforces. The server sees the ciphertext on its way to disk and never sees anything else. Then the page dumps the notes file onto the screen, and what is in there is ciphertext, not a redacted rendering of the row for demonstration purposes but the row as it was stored. Whether that is impressive depends entirely on the next paragraph.

Why there is nothing to steal alongside it

Encrypting rows is not new and on its own it is not worth much, because in most systems the key that opens those rows is a short walk away from the rows themselves, in an environment variable, in a managed key service the application is allowed to call, or in the memory of the process that just handled the request. An attacker who can read your database can usually also read the thing that decrypts it, which is why so many disclosures say the data was encrypted at rest and it makes no difference to anyone affected.

Here the key exists as shares held by independent nodes, fourteen of twenty have to cooperate to use it, and it is never assembled anywhere at any point, including on the machine running minidauth. There is no environment variable to read and no service that will hand it over on request.

A stolen copy of your database contains nothing readable, and no key to make it readable.

The half encryption cannot do

The same demo then asks the network to sign a payment instruction. Signing policies carry a contract, and the contract is handed the payload before the cohort will put a signature on it, so one of these comes back signed and the other does not:

// signed by the cohort
amount=250;to=alice

// refused, by fourteen nodes independently
amount=5000;to=alice

The refusal is the event worth watching, because it happens on fourteen machines that are not yours, running code you did not deploy, reading the bytes you actually asked them to sign. There is no sequence of events on your own server that produces that signature, since your server was never what produced signatures in the first place. Approving a release, authorising a refund above some limit, issuing a credential: all the same shape, and all things that are normally enforced by a conditional in the application that wants the operation to succeed.

What the demo does not claim

A demo that only shows the good part is a sales pitch, so the limits are worth stating in the same breath.

  • Whoever runs minidauth holds the vendor key and can ultimately authorise reads, and a quorum of your own operators can grant themselves a reading role. Both are on purpose, because access has to be recoverable. What goes away is any single party doing it alone.
  • Owning the host still means holding the vendor key. Signed grants stop silent forgery of roles, but they do not stop someone with your machine acting within the policies you deployed.
  • Reads that need decryption make a network call to a threshold of nodes, and sign-in does too. If every page load in your app decrypts something, you will feel that.

Where to go after it

The notes demo is deliberately the smallest thing that shows both halves working. payouts is the same idea as an app somebody might actually ship, on Supabase, with login and Postgres and a server holding a secret key: bank details stored as ciphertext, a reveal that takes a role only a quorum can grant, and payouts that exist only because the network signed them. Edit an amount directly in the Supabase table and the row shows as forged on the next load, which is checked with plain Ed25519 and no special tooling.

If the users of your app should not have to hold a second account, and most of the time they should not, tideless goes the other way: a quorum grants a role to the user id you already have, and minidauth acts on their behalf gated on that role, with no extra login anywhere and no token for them to carry.

More posts