apps/www/_blog/2022-12-16-vault-now-in-beta.mdx
During our last Launch Week we announced Supabase Vault as our “one more thing”. Today we're releasing it progressively across the platform.
Vault is a new Postgres extension and accompanying Supabase UI that makes it safe and easy to store encrypted secrets and encrypt other stored data in your database. This foundation opens up a lot of possibilities for Postgres that go beyond what is available in a stock distribution. From a product perspective we're grouping various features under the “Vault banner”. Let's explore a few of these features.
<div className="bg-gray-300 rounded-lg px-6 py-2 bold">❇️ UPDATE JUNE 2023 ❇️
Supabase Vault is now available on every Supabase project. Check it out
</div>Practically speaking, the Vault is a table of Secrets and Encryption Keys that are stored using Authenticated Encryption on disk, but available in decrypted form through a Postgres view so that the secrets can be used by applications from SQL. Because the secrets are stored encrypted and authenticated, any backups or replication streams also preserve this encryption in a way that can't be forged.
We've created a dashboard UI for the Vault that makes storing secrets easy. Click a button and type in your secret, optionally create a new key that is referenced by id (or use the existing default), and submit. Your secret is now stored on disk encrypted using the specified key id.
<video width="99%" muted playsInline controls={true}> <source src="/images/blog/launch-week-6/vault/vault-hello-compressed.mp4" type="video/mp4" /> </video>There are two main parts to the Vault UI, Secrets and Encryption Keys:
Our recent blog post describes TCE in-depth. TCE is one of the safest ways to encrypt your data so that it doesn't leak into logs and backups, as well as providing your users with row-level authenticated encryption. TCE is the foundational feature of the Vault, but you can use it on your own tables if you choose to if the Vault isn't sufficient for your needs, for example if you have multiple tables that you wish to have encrypted columns. Any Postgres value that can be cast to text or bytea can use TCE to encrypt the data that is stored to disk.
In the “New Column” flow on the Dashboard, you can select that a text or bytea column is encrypted, and select an existing key id or create a new one. This is functionally identical to the Vault above, but you can apply it to any of your existing tables. In a sense the Vault is a pre-created table and UI for you to get started quickly storing secrets, and to be a centralized point for “global” secrets management, but your not stuck with just that, you can encrypt multiple columns in multiple tables, how you want to store your secret data can be entirely up to you.
Once you've setup an encrypted column, just insert data into the table like you would any other table. If you put in an email address for example, you will see that what is stored is not an email at all, but an encrypted value.
Decrypted data can be accessed by a special view that is automatically created whenever you create an encrypted column on a table. This view decrypts the data row-by-row as you access it. By default this view is called decrypted_<your-table-name>, so in the example provided, the decryption view for the profiles table is decrypted_profiles. In addition to the existing emails column, there is a new column in the view called decrypted_emails that contains the decrypted email value. It's that simple!
As we mentioned, the Vault uses pgsodium's Transparent Column Encryption (TCE) to store secrets in an authenticated encrypted form. There are some details around that you may be curious about, what does authenticated mean, and where are encryption keys store? This section explains those details.
The first important feature of TCE is that it uses an Authenticated Encryption with Associated Data encryption algorithm based on libsodium. “Authenticated Encryption” means that in addition to the data being encrypted, it is also “signed” so that it cannot be forged, the decryption function verifies that the signature is valid before decrypting the value. “Associated Data” means that in addition to signing the secret, you can include any other columns in your row in the signature computation, “associating” those columns with the secret. This doesn't encrypt those other columns, but it does ensure that they are authentic and cannot be forged because they are included in the secret's signature. So you know when you restore your database dumps, not only are the secrets safe, but also the “associated” columns are also authentic and unforged.
Another important feature of pgsodium is that the encryption keys are never stored in the database alongside the encrypted data, instead, only a Key ID is stored, which refers to a key that is only accessible outside of SQL. Even if an attacker can capture a dump of your entire database, they will see only encrypted data and key ids, never the raw key itself. This is an important safety precaution, there would be no point in storing the encryption key in the database alongside the encrypted data, this would be like locking your front door but leaving the key in the lock! Storing the key outside the database fixes this issue.
You might be wondering, ok then where are the keys stored? Supabase creates and manages the root keys from which all key ids are derived in our internal customer backend systems. We keep this key safe and separate from your data, and provide an alternate dashboard endpoint for accessing the key if you want to decrypt your data outside of Supabase.
Privacy is becoming one of the most important features in a modern product. Supabase's embrace of the pgsodium extension aims to make this simple. Some of the possibilities we are looking into are:
To learn how to use Supabase Vault, check out the docs. Supabase Vault is now available on all Supabase projects (some projects will have to enable via request).