Vault
在 Postgres 中管理密钥。
Vault 是一个 Postgres 扩展程序和配套的 Supabase UI,可以安全且轻松地将加密密钥和其他数据存储在数据库中。这为使用 Postgres 的方式打开了许多可能性,超越了标准发行版的功能。
在底层,Vault 是一个使用 认证加密 在磁盘上存储的密钥表。然后,它们可以通过 Postgres 视图以解密的形式提供,以便应用程序可以从 SQL 中使用这些密钥。由于密钥以加密和认证的形式存储在磁盘上,因此所有备份或复制流也以无法解密或伪造的方式保留此加密。
Supabase 为 Vault 提供了一个仪表板 UI,使存储密钥变得容易。单击一个按钮,输入您的密钥,然后保存。
您可以使用 Vault 存储密钥 - 从环境变量到 API 密钥,一切皆可。然后,您可以在数据库中的任何地方使用这些密钥:Postgres 函数、触发器和 Webhooks。从 SQL 的角度来看,访问密钥就像查询一个表(或者在这种情况下,一个视图)一样简单。底层的密钥表将以加密形式存储。
使用 Vault#
您可以从 UI 或使用 SQL 管理密钥。
添加密钥#
还有一个方便的函数可以创建密钥,名为 vault.create_secret()
1select vault.create_secret('my_s3kre3t');该函数返回新密钥的 UUID。
显示结果
1-[ RECORD 1 ]-+-------------------------------------2create_secret | c9b00867-ca8b-44fc-a81d-d20b8169be17密钥还可以具有可选的唯一名称和可选的描述。这些也是 vault.create_secret() 的参数
1select vault.create_secret('another_s3kre3t', 'unique_name', 'This is the description');显示结果
1-[ RECORD 1 ]-----------------------------------------------------------------2id | 7095d222-efe5-4cd5-b5c6-5755b451e2233name | unique_name4description | This is the description5secret | 3mMeOcoG84a5F2uOfy2ugWYDp9sdxvCTmi6kTeT97bvA8rCEsG5DWWZtTU8VVeE=6key_id |7nonce | \x9f2d60954ba5eb566445736e0760b0e38created_at | 2022-12-14 02:34:23.85159+009updated_at | 2022-12-14 02:34:23.85159+00查看密钥#
如果您查看 vault.secrets 表,您会看到您的数据以加密形式存储。要解密数据,有一个自动创建的视图 vault.decrypted_secrets。此视图将在运行时解密密钥数据
1select * 2from vault.decrypted_secrets 3order by created_at desc 4limit 3;显示结果
1-[ RECORD 1 ]----+-----------------------------------------------------------------2id | 7095d222-efe5-4cd5-b5c6-5755b451e2233name | unique_name4description | This is the description5secret | 3mMeOcoG84a5F2uOfy2ugWYDp9sdxvCTmi6kTeT97bvA8rCEsG5DWWZtTU8VVeE=6decrypted_secret | another_s3kre3t7key_id |8nonce | \x9f2d60954ba5eb566445736e0760b0e39created_at | 2022-12-14 02:34:23.85159+0010updated_at | 2022-12-14 02:34:23.85159+0011-[ RECORD 2 ]----+-----------------------------------------------------------------12id | c9b00867-ca8b-44fc-a81d-d20b8169be1713name |14description |15secret | a1CE4vXwQ53+N9bllJj1D7fasm59ykohjb7K90PPsRFUd9IbBdxIGZNoSQLIXl4=16decrypted_secret | another_s3kre3t17key_id |18nonce | \x1d3b2761548c4efb2d29ca11d44aa22f19created_at | 2022-12-14 02:32:50.58921+0020updated_at | 2022-12-14 02:32:50.58921+0021-[ RECORD 3 ]----+-----------------------------------------------------------------22id | d91596b8-1047-446c-b9c0-66d98af6d00123name |24description |25secret | S02eXS9BBY+kE3r621IS8beAytEEtj+dDHjs9/0AoMy7HTbog+ylxcS22A==26decrypted_secret | s3kre3t_k3y27key_id |28nonce | \x3aa2e92f9808e496aa4163a59304b89529created_at | 2022-12-14 02:29:21.3625+0030updated_at | 2022-12-14 02:29:21.3625+00请注意,此视图有一个 decrypted_secret 列,其中包含解密的密钥。视图不会存储在磁盘上,它们仅在查询时运行,因此密钥在磁盘上以及任何备份转储或复制流中都保持加密状态。
您应始终确保使用适当的 SQL 权限设置来保护对此视图的访问,因为任何访问该视图的人都可以访问解密的密钥。
更新密钥#
可以使用 vault.update_secret() 函数更新密钥,此函数使更新密钥变得容易,只需提供密钥 UUID 作为第一个参数,然后提供更新后的密钥、更新后的可选唯一名称或更新后的描述
1select2 vault.update_secret(3 '7095d222-efe5-4cd5-b5c6-5755b451e223',4 'n3w_upd@ted_s3kret',5 'updated_unique_name',6 'This is the updated description'7 );显示结果
1-[ RECORD 1 ]-+-2update_secret |34postgres=> select * from vault.decrypted_secrets where id = '7095d222-efe5-4cd5-b5c6-5755b451e223';5-[ RECORD 1 ]----+---------------------------------------------------------------------6id | 7095d222-efe5-4cd5-b5c6-5755b451e2237name | updated_unique_name8description | This is the updated description9secret | lhb3HBFxF+qJzp/HHCwhjl4QFb5dYDsIQEm35DaZQOovdkgp2iy6UMufTKJGH4ThMrU=10decrypted_secret | n3w_upd@ted_s3kret11key_id |12nonce | \x9f2d60954ba5eb566445736e0760b0e313created_at | 2022-12-14 02:34:23.85159+0014updated_at | 2022-12-14 02:51:13.938396+00深入了解#
如我们所提到的,Vault 使用透明列加密 (TCE) 以认证加密的形式存储密钥。您可能对其中一些细节感到好奇。认证是什么意思?加密密钥存储在哪里?本节将解释这些细节。
带有关联数据的认证加密#
TCE 的第一个重要特性是它使用基于 libsodium 的 带有关联数据的认证加密 算法。
加密密钥位置#
认证加密意味着除了数据被加密之外,它也被签名,因此无法被伪造。您可以保证数据是由您信任的人加密的,而单独加密则无法保证这一点。解密函数在解密值之前会验证签名是否有效。
关联数据意味着您可以将同一行中的任何其他列包含在签名计算中。这不会加密这些其他列 - 而是确保您的加密值仅与该行的列相关联。如果攻击者将加密值从另一行复制到当前行,签名将被拒绝(假设您在关联数据中使用了唯一的列)。
另一个重要特性是加密密钥从不与加密数据一起存储在数据库中。即使攻击者可以捕获整个数据库的转储,他们只会看到加密的数据,永远不会看到加密密钥本身。
这是一个重要的安全预防措施 - 将加密密钥存储在数据库本身中价值很小,这就像锁上您的前门,但把钥匙留在锁里!将密钥存储在数据库外部可以解决此问题。
密钥存储在哪里?Supabase 在我们安全的后端系统中创建和管理加密密钥。我们安全地将此密钥与您的数据分开保存。您仍然可以控制您的密钥 - 提供了一个单独的 API 端点,您可以使用它来访问密钥,如果您想在 Supabase 外部解密您的数据,可以使用它。
应仔细考虑哪些角色应该具有对 vault.secrets 表的访问权限。授予访问权限的两种方法是,首先,postgres 用户可以显式授予对 vault 表本身的访问权限。
资源#
- 在 博客文章 中了解有关 Supabase Vault 的更多信息
- Supabase Vault 在 GitHub 上
- 列加密