JWT 签名密钥
Best practices on managing keys used by Supabase Auth to create and verify JSON Web Tokens
Supabase Auth 会持续为每个用户会话发放新的 JWT,只要用户保持登录状态。JWT 签名密钥可以对这个重要的安全流程进行精细控制,保障你的应用安全。
🌐 Supabase Auth continuously issues a new JWT for each user session, for as long as the user remains signed in. JWT signing keys provide fine grained control over this important process for the security of your application.
在继续之前,请查看关于 Sessions 的综合指南,了解 Auth 如何为用户的会话创建令牌的所有细节。如果你不熟悉基础知识,可以先阅读 JWTs。
🌐 Before continuing check the comprehensive guide on Sessions for all the details about how Auth creates tokens for a user's session. Read up on JWTs if you are not familiar with the basics.
概览 #
🌐 Overview
当 Supabase Auth 发布 JWT 时,用来创建其签名的密钥被称为签名密钥。Supabase 提供了两种处理签名密钥的系统:基于 JWT 密钥的旧系统,以及新的签名密钥系统。
🌐 When a JWT is issued by Supabase Auth, the key used to create its signature is known as the signing key. Supabase provides two systems for dealing with signing keys: the Legacy system based on the JWT secret, and the new Signing keys system.
| 系统 | 类型 | 描述 |
|---|---|---|
| 传统 | JWT 密钥 | 最初 Supabase 设计是使用单个共享秘密密钥来签署所有的 JWT。这包括 anon 和 service_role 密钥,所有用户访问令牌,包括一些 Storage 预签名 URL。不再推荐使用。 仅为向后兼容而保留。 |
| 签名密钥 | 非对称密钥 (RSA, 椭圆曲线) | 基于 公钥加密(RSA,椭圆曲线)的 JWT 签名密钥,遵循行业最佳实践,显著提升应用的安全性、可靠性和性能。 |
| 签名密钥 | 共享秘密密钥 | 基于 共享秘钥 的 JWT 签名密钥。 |
签名密钥系统的好处 #
🌐 Benefits of the signing keys system
我们设计了签名密钥系统来解决旧系统的许多问题。它与可发布和秘密的 API 密钥密切配合使用。
🌐 We've designed the Signing keys system to address many problems the legacy system had. It goes hand-in-hand with the publishable and secret API keys.
| 优势 | 传统 JWT 密钥 | JWT 签名密钥 |
|---|---|---|
| 性能 | 由于 JWT 验证由认证服务器完成,应用延迟增加。 | 如果使用非对称签名密钥,JWT 验证速度快,并且不涉及认证服务器。 |
| 可靠性 | 为了确保安全吊销,认证服务器在你的应用的关键路径中。 | 如果使用非对称签名密钥,JWT 验证是本地的、快速的,不涉及认证服务器。 |
| 安全性 | 需要更改你应用的后台组件来完全吊销被泄露的密钥。 | 如果使用非对称签名密钥,通过密钥发现端点可以自动吊销。 |
| 零停机轮换 | 有停机,有时可能比较长。需要与 API 密钥 小心协调。 | 无停机,因为每个轮换步骤都是独立且可逆的。 |
| 用户在轮换期间登出 | 当前活跃用户会立即被登出。 | 没有用户被登出。 |
| 独立于 API 密钥 | anon 和 service_role 必须同时轮换。 | 可发布和秘密 API 密钥 不再基于 JWT 签名密钥,可以独立管理。 |
| 安全合规框架(SOC2 等) | 难以保持一致,因为秘密可能从 Supabase 中被提取。 | 更容易保持一致,因为私钥或共享秘密不能被提取。行级安全有强大的密钥撤销保障。 |
入门 #
🌐 Getting started
你可以通过 Supabase 仪表板开始迁移离开旧的 JWT 密钥。这个过程不会导致你的应用出现停机。
🌐 You can start migrating away from the legacy JWT secret through the Supabase dashboard. This process does not cause downtime for your application.
- 首先点击 JWT 签名密钥 页面上的 迁移 JWT 密钥 按钮。这一步会将现有的旧版 JWT 密钥导入到新的 JWT 签名密钥系统中。
- 同时,我们正在为你创建一个新的非对称 JWT 签名密钥以供轮换使用。这个密钥最初是备用密钥——也就是说,它被宣传为未来 Supabase Auth 用来生成 JWT 的密钥。
- 如果你现在还没准备好切换掉旧的 JWT 密钥,可以在这里停下,也不会有任何问题。如果你想使用不同的签名密钥——无论是为了使用不同的签名算法(RSA、椭圆曲线或者共享密钥),还是为了导入你已有的私钥或共享密钥——都可以先把备用密钥移动到“以前使用过”,再最终移到“已吊销”。
- 如果你确实希望开始对所有新的 JWT 使用备用密钥,请使用“轮换密钥”按钮。有几个重要的注意事项:
- 确保你的应用不要直接依赖旧版的 JWT 密钥。如果你的应用是用旧版 JWT 密钥去验证每一个 JWT(使用像
jose、jsonwebtoken或类似的库),继续轮换密钥可能会导致这些组件出问题。 - 如果你正在使用带有“验证 JWT”设置的 Edge Functions,继续旋转可能会导致你的应用出问题。你需要关闭这个设置。
- 在这两种情况下,修改或添加代码到你的应用或 Edge Function 来验证 JWT。使用
supabase.auth.getClaims()函数,或者阅读更多关于从 Supabase 验证 JWT 的最佳方法。
- 确保你的应用不要直接依赖旧版的 JWT 密钥。如果你的应用是用旧版 JWT 密钥去验证每一个 JWT(使用像
- 旋转密钥会立即导致认证服务器为已登录用户发出使用新密钥签名的新 JWT 访问令牌。未过期的访问令牌仍会被接受,所以不会强制用户退出。
- 计划撤销旧的 JWT 密钥。
- 如果你的访问令牌过期时间设置为 1 小时,至少等 1 小时 15 分钟后再撤销旧的 JWT 密钥——现在它在“以前使用过”部分下。
- 这可以防止当前活跃的用户被强制登出。
- 在某些情况下,比如发生安全事件时,你可能想立即撤销旧版 JWT 密钥。
轮换和撤销密钥 #
🌐 Rotating and revoking keys
密钥轮换和吊销是维护你的项目和应用安全的最重要的过程之一。签名密钥系统让你能够高效地执行这些操作,而不会导致应用停机,这是旧系统的一个不足之处。下面是一些常见的情况,说明你什么时候以及为什么应该考虑进行密钥轮换和吊销。
🌐 Key rotation and revocation are one of the most important processes for maintaining the security of your project and applications. The signing keys system allows you to efficiently execute these without causing downtime of your app, a deficiency present in the legacy system. Below are some common reasons when and why you should consider key rotation and revocation.
恶意行为者滥用传统 JWT 密钥或导入的私钥
- 旧的 JWT 密钥已经在日志中泄露、提交到源码控制,或者在你应用的前端构建、库、桌面或移动应用包等中意外暴露了。
- 你怀疑组织中的一名成员可能已经失去了对其设备的控制,恶意行为者可能通过 Supabase 仪表板或访问你应用的后端配置获取了 JWT 密钥。
- 你怀疑你们组织的一名前团队成员可能是恶意行为者,利用旧的 JWT 密钥所带来的权限作恶。
- 确保你也切换到 可发布和私密 API 密钥,并禁用
anon和service_role密钥。 - 如果你导入了一个私钥,并且你怀疑这个私钥在你这边也可能被泄露了。
更贴近安全最佳实践和合规框架(SOC2、PCI-DSS、ISO27000、HIPAA,...)
- 最好每年至少更换一次签名密钥。
- 一些安全合规框架非常鼓励或要求频繁更换加密密钥。
- 如果你在大型企业中使用 Supabase,你们的安全部门可能会要求这样做。
- 为你需要应对活跃安全事件的时间建立肌肉记忆。
因技术原因更改密钥算法
- 你可能希望因为兼容性问题或为了简化你那边的开发而更换签名算法。
签名密钥的使用寿命 #
🌐 Lifetime of a signing key
新创建的密钥一开始是备用状态,然后在轮换时投入使用(成为当前密钥),原来的当前密钥则变成以前使用过的密钥。
🌐 A newly created key starts off as standby, before being rotated into in use (becoming the current key) while the existing current key becomes previously used.
在任何时候,你都可以把之前使用过或已撤销的密钥移回待命状态,然后切换到它。这样如果你在轮换过程中发现问题,比如忘记更新依赖特定密钥的应用组件(例如旧的 JWT 密钥),你就可以放心地回退到旧的密钥。
🌐 At any point you can move a key from the previously used or revoked states back to being a standby key, and rotate to it. This gives you the confidence to revert back to an older key if you identify problems with the rotation, such as forgetting to update a component of your application that is relying on a specific key (for example, the legacy JWT secret).
每个按键上的操作都是可逆的(永久删除除外)。
🌐 Each action on a key is reversible (except permanent deletion).
| 动作 | 接受的 JWT 签名 | 描述 |
|---|---|---|
| 创建一个新密钥 | 当前密钥而已,新密钥还没有创建任何 JWT。 | 当你首次创建密钥时,在选择签名算法或导入已有的私钥后,它会以待机状态开始。如果使用非对称密钥(RSA、椭圆曲线),它的公钥会在发现端点可用。Supabase Auth 不会使用这个密钥来创建新的 JWT。 |
| 轮换密钥 | 两个密钥都在轮换中。 | 轮换仅改变 Supabase Auth 用来创建新 JWT 的密钥,但与两个密钥的信任关系保持不变。 |
| 撤销密钥 | 仅从当前密钥开始。 | 一旦所有定期有效的 JWT 都已过期(或更早),撤销之前使用的密钥以撤销对它的信任。 |
| 从已撤销移至待机 | 当前和之前已撤销的密钥。 | 如果你出了差错或需要更多时间调整你的应用,你可以把已撤销的密钥移到待机状态。之后再进行一次轮换,确保 Auth 再次使用最初撤销的密钥来生成新的 JWT。 |
| 从之前使用的移动到待机 | 两个密钥 | 这只会准备最后一次轮换使用的密钥,以便认证使用它来生成新的 JWT。 |
| 删除键 | - | 永久销毁密钥的私钥或共享密钥,因此将无法再次重用或重新轮换它。 |
公钥发现与缓存 #
🌐 Public key discovery and caching
当你的签名密钥使用基于公钥加密的不对称算法时,Supabase Auth 会在 JSON Web Key Set 发现端点公开公钥,任何人都可以查看。这是一个重要的安全功能,让你可以在不需要部署应用后端新版本的情况下轮换和吊销密钥。
🌐 When your signing keys use an asymmetric algorithm based on public-key cryptography Supabase Auth exposes the public key in the JSON Web Key Set discovery endpoint, for anyone to see. This is an important security feature allowing you to rotate and revoke keys without needing to deploy new versions of your app's backend infrastructure.
通过以下端点访问当前受信任的签名密钥:
🌐 Access the currently trusted signing keys at the following endpoint:
1GET https://project-id.supabase.co/auth/v1/.well-known/jwks.json请注意,这是安全的,因为公钥是不可逆的,只能用来验证 JSON Web 令牌的签名,而不能用来创建新的令牌。
🌐 Note that this is secure as public keys are irreversible and can only be used to verify the signature of JSON Web Tokens, but not create new ones.
这个发现端点会被 Supabase 的边缘服务器缓存 10 分钟。此外,Supabase 客户端库可能会在内存中额外缓存密钥 10 分钟。如果你的应用不只是依赖 Supabase 客户端库,它可能会有不同的缓存行为。
🌐 This discovery endpoint is cached by Supabase's edge servers for 10 minutes. Furthermore the Supabase client libraries may cache the keys in memory for an additional 10 minutes. Your application may be using different caching behavior if you're not relying only on the Supabase client library.
这个多级缓存是一种折衷方案,它允许快速验证 JWT,同时不把认证服务器放在应用的关键路径上,从而提高了可靠性和性能。
🌐 This multi-level cache is a trade-off allowing fast JWT verification without placing the Auth server in the hot path of your application, increasing its reliability and performance.
重要的是,Supabase 产品不依赖这个缓存,因此在密钥被撤销时可以提供更强的安全保障。如果你的应用只使用行级安全策略,并且没有其他后端组件(比如 API、Edge Functions、服务器等),那么密钥的轮换和撤销都是瞬间完成的。
🌐 Importantly Supabase products do not rely on this cache, so stronger security guarantees are provided especially when keys are revoked. If your application only uses Row Level Security policies and does not have any other backend components (such as APIs, Edge Functions, servers, etc.) key rotation and revocation are instantaneous.
最后,这个多级缓存每20分钟清理一次,如果你有自定义设置,可能会更久。考虑一下可能因此出现的以下问题:
🌐 Finally this multi-level cache is cleared every 20 minutes, or longer if you have a custom setup. Consider the following problems that may arise due to it:
- 紧急密钥吊销。 如果你遇到需要紧急吊销签名密钥的安全事件,由于多级缓存,你的应用组件可能仍然会信任并验证使用已吊销密钥签署的 JWT。Supabase 产品(Auth、Data API、Storage、Realtime)不依赖于此缓存,吊销是即时生效的。 如果这对你来说是个问题,请确保你在应用的后端基础设施中构建了缓存清除机制。
- 快速创建和轮换密钥。 如果你正在迁移离开传统的 JWT 密钥,或者只使用
supabase.auth.getClaims()方法,这种情况会为你自动处理。如果你自己验证 JWT,而不借助 Supabase 客户端库,请确保 你应用中的所有缓存 都已经获取到新创建的备用密钥,然后再进行轮换。
选择合适的签名算法 #
🌐 Choosing the right signing algorithm
为了在性能、安全性和易用性之间取得恰当的平衡,JWT 签名密钥基于 Web Crypto API 提供的功能。
🌐 To strike the right balance between performance, security and ease-of-use, JWT signing keys are based on capabilities available in the Web Crypto API.
| 算法 | JWT alg | 信息 |
|---|---|---|
| NIST P-256 曲线 (非对称) | ES256 | 椭圆曲线比 RSA 更快,同时提供相当的安全性。对于认证使用场景尤其重要的是,P-256 曲线生成的签名比 RSA 的签名短很多,这有助于减少数据传输量和管理 cookie 大小。Web Crypto 和大多数其他加密库及运行时都支持这条曲线。 |
| RSA 2048 (非对称) | RS256 | RSA 是最古老、支持最广泛的公钥密码系统。虽然手动编码很容易,但在某些方面它可能比椭圆曲线慢很多。我们建议改用 P-256 椭圆曲线。 |
| Ed25519 曲线 (非对称) | EdDSA | 即将推出。这个算法基于一个开放开发的不同椭圆曲线密码系统,不像 P-256 曲线那么通用。Web Crypto 或其他加密库可能并不在所有运行环境下支持它,所以使用起来可能有点麻烦。 |
| 使用共享密钥的 HMAC (对称) | HS256 | 不推荐用于生产环境。 共享密钥使用消息认证码来验证 JSON Web Token 的真实性。这要求 JWT 的创建者(Auth)和验证 JWT 的系统都知道该密钥。由于没有公钥对应项,撤销这个密钥可能需要对应用的后端基础设施进行更改。 |
使用用共享密钥签名的 JWT 几乎没有什么好处。虽然它在计算上更高效,手动编写验证也更简单,但使用这种方法可能会让你的项目数据暴露在重大安全漏洞或弱点中。
🌐 There is almost no benefit from using a JWT signed with a shared secret. Although it's computationally more efficient and verification is simpler to code by hand, using this approach can expose your project's data to significant security vulnerabilities or weaknesses.
考虑一下以下内容:
🌐 Consider the following:
- 使用共享密钥可能会让保持符合 SOC2、PCI-DSS、ISO27000、HIPAA 等安全合规框架变得更困难。
- 如果一个共享的秘密落入恶意行为者手中,他们可以用它来冒充你的用户,或让自己访问敏感的操作或数据。
- 很难发现或确定共享的秘密何时或如何被提供给了恶意行为者。
- 考虑一下谁可能会偶然接触到共享密钥:系统、员工、设备(以及它们的磁盘加密和漏洞修补状态)。
- 一个恶意行为者可以在很久以后使用共享密钥,所以即使现在没有被入侵的证据,也不意味着你的数据是安全的。
- 在公开可用的源代码中,比如你的网站、前端、移动应用包或其他可执行文件中,意外泄露共享密钥是很容易发生的。尤其是当你不小心把密钥放在以
NEXT_PUBLIC_、VITE_、PUBLIC_或其他由 Web 框架约定的前缀开头的环境变量中时,这种情况更容易发生。 - 轮换共享密钥可能需要小心协调,以避免你的应用停机。
常见问题 #
🌐 Frequently asked questions
为什么不可能从 Supabase 提取私钥或共享密钥? #
🌐 Why is it not possible to extract the private key or shared secret from Supabase?
你只能提取旧版的 JWT 密钥。一旦你开始使用 JWT 签名密钥功能,就无法从 Supabase 中提取私钥或共享密钥了。这能确保你组织中的任何人都无法冒充你的用户或获取项目数据的特权访问权限。
🌐 You can only extract the legacy JWT secret. Once you've moved to using the JWT signing keys feature extracting of the private key or shared secret from Supabase is not possible. This ensures that no one in your organization is able to impersonate your users or gain privileged access to your project's data.
此保证可让你的应用与安全合规框架(SOC2、PCI-DSS、ISO27000、HIPAA)和安全最佳实践紧密对齐。
🌐 This guarantee provides your application with close alignment with security compliance frameworks (SOC2, PCI-DSS, ISO27000, HIPAA) and security best practices.
如果无法访问私钥或共享密钥,如何创建(生成)JWT? #
🌐 How to create (mint) JWTs if access to the private key or shared secret is not possible?
如果你想自己生成 JWT,或者能访问 Supabase 使用的私钥或共享密钥,你可以通过导入私钥或者自己设置共享密钥来创建一个新的 JWT 签名密钥。
🌐 If you wish to make your own JWTs or have access to the private key or shared secret used by Supabase, you can create a new JWT signing key by importing a private key or setting a shared secret yourself.
使用 Supabase CLI 安全地生成一个可导入的私钥:
🌐 Use the Supabase CLI to securely generate a private key ready for import:
1supabase gen signing-key --algorithm ES256确保你把这个私钥存放在安全的地方,因为它无法从 Supabase 中提取出来。
🌐 Make sure you store this private key in a secure location, as it will not be extractable from Supabase.
要将生成的私钥导入到你的项目中,请在仪表板上创建一个新的备用密钥 :
🌐 To import the generated private key to your project, create a new standby key from the dashboard:
1{2 "kty": "EC",3 "kid": "3a18cfe2-7226-43b0-bbb4-7c5242f2406e",4 "d": "RDbwqThwtGP4WnvACvO_0nL0oMMSmMFSYMPosprlAog",5 "crv": "P-256",6 "x": "gyLVvp9dyEgylYH7nR2E2qdQ_-9Pv5i1tk7c2qZD4Nk",7 "y": "CD9RfYOTyjR5U-PC9UDlsthRpc7vAQQQ2FTt8UsX0fY"8}导入后,点击 Rotate key 来激活你的新签名密钥。任何用旧密钥签名的 JWT 都可以继续使用,直到你的旧签名密钥被手动撤销。
🌐 Once imported, click Rotate key to activate your new signing key. Any JWT signed by your old key will continue to be usable until your old signing key is manually revoked.
要使用非对称签名密钥铸造新的 JWT,你需要将以下 JWT 头部 设置为与你生成的私钥匹配。
🌐 To mint a new JWT using the asymmetric signing key, you need to set the following JWT headers to match your generated private key.
1{2 "alg": "ES256",3 "kid": "3a18cfe2-7226-43b0-bbb4-7c5242f2406e",4 "typ": "JWT"5}kid 头用于识别你的公钥以进行验证。在平台导入时,你必须使用相同的值。
🌐 The kid header is used to identify your public key for verification. You must use the same value when importing on platform.
另外,你需要在 JWT 负载中提供以下自定义声明。
🌐 In addition, you need to provide the following custom claims as the JWT payload.
1{2 "sub": "ef0493c9-3582-425f-a362-aef909588df7",3 "role": "authenticated",4 "exp": 17577494665}sub是一个可选的 UUID,用于唯一标识你想在auth.users表中模拟的用户。role必须设置为你数据库中已存在的 Postgres 角色,比如anon、authenticated或service_role。exp必须设置为将来某个时间的时间戳(自1970年以来的秒数),表示此令牌过期时间。建议使用寿命较短的令牌。
为了简单起见,使用以下 CLI 命令生成带有所需头部和负载的令牌。
🌐 For simplicity, use the following CLI command to generate tokens with the desired header and payload.
1supabase gen bearer-jwt --role authenticated --sub ef0493c9-3582-425f-a362-aef909588df7最后,你可以通过将 Authorization: Bearer <JWT> 头设置到所有 数据 API 请求 上来使用你新生成的 JWT。
🌐 Finally, you can use your newly minted JWT by setting the Authorization: Bearer <JWT> header to all Data API requests.
要访问你项目的 API,需要一个单独的 apikey 头。这可以是可发布、秘密或传统的 anon 或 service_role 密钥。不能在这个头中使用你生成的 JWT。
🌐 A separate apikey header is required to access your project's APIs. This can be a publishable, secret or the legacy anon or service_role keys. Using your minted JWT is not possible in this header.
为什么更改签名密钥状态时要等待5分钟? #
🌐 Why is a 5 minute wait imposed when changing signing key states?
更改 JWT 签名密钥的状态会在 Supabase 平台内引发许多变化。为了确保设置一致,大多数更改 JWT 签名密钥状态的操作会被限制大约 5 分钟。
🌐 Changing a JWT signing key's state sets off many changes inside the Supabase platform. To ensure a consistent setup, most actions that change the state of a JWT signing key are throttled for approximately 5 minutes.
为什么不允许删除旧的 JWT 密钥? #
🌐 Why is deleting the legacy JWT secret disallowed?
这是为了确保你在需要时有能力回到旧的 JWT 密钥。将来,这个功能将可以从仪表板上使用。
🌐 This is to ensure you have the ability, should you need it, to go back to the legacy JWT secret. In the future this capability will be allowed from the dashboard.
为什么撤销旧的 JWT 密钥需要禁用 anon 和 service_role#
🌐 Why does revoking the legacy JWT secret require disabling of anon and service_role API keys?
不幸的是,anon 和 service_role 不仅是 API 密钥,同时也是有效的 JSON Web 令牌(JWT),由旧的 JWT 密钥签署。撤销旧的 JWT 密钥意味着你的应用将不再信任任何使用它签署的 JWT。因此,在你撤销旧的 JWT 密钥之前,你必须先禁用 anon 和 service_role,以确保安全设置的一致性。
🌐 Unfortunately anon and service_role are not only API keys, but are also valid JSON Web Tokens, signed by the legacy JWT secret. Revoking the legacy JWT secret means that your application no longer trusts any JWT signed with it. Therefore before you revoke the legacy JWT secret, you must disable the anon and service_role to ensure a consistent security setup.
在移动端、桌面端或命令行应用中使用基于 JWT 的 anon 密钥,并且需要轮换 service_role#
🌐 Using JWT-based anon key in a mobile, desktop, or CLI application and need to rotate a service_role JWT secret?
如果 JWT 密钥是安全的,可以用你在仪表板的 设置 > API 密钥 部分创建的新密钥替换 service_role 基于 JWT 的密钥。这样可以防止你的应用出现停机。
🌐 If the JWT secret is secure, substitute the service_role JWT-based key with a new secret key which you can create in the Settings > API Keys section of the Dashboard. This prevents downtime for your application.
为什么不再推荐使用基于 JWT 的 anon 和 service_role#
🌐 Why are anon and service_role JWT-based keys no longer recommended?
自从 Supabase 开始以来,基于 JWT 的 anon 和 service_role 密钥对你的项目来说,是在简化和相对安全之间的合理折中。不过它们在实际应用中确实会带来一些挑战,尤其是在密钥轮换和安全最佳实践方面。
🌐 Since the start of Supabase, the JWT-based anon and service_role keys were the right trade-off against simplicity and relative security for your project. Unfortunately they pose some real challenges in live applications, especially around rotation and security best practices.
选择可发布和私密密钥(sb_publishable_... 和 `sb_secret_...``)的主要原因是为了避免使用传统基于 JWT 的密钥时出现以下缺点:
🌐 The main reasons for preferring the publishable and secret keys (sb_publishable_... and sb_secret_...) are to avoid the following shortcomings of the legacy JWT-based keys:
- JWT 密钥(本身也可能被泄露,如果你自己生成 JWT)、
anon(低权限)、service_role(高权限)以及authenticated(由 Supabase Auth 发放)的 Postgres 角色之间的紧密耦合。 - 无法在不暂停的情况下独立旋转每个键的各个部分。
- 无法回滚不必要或有问题的 JWT 密钥轮换。
- 发布移动应用的新版本可能需要几天,甚至在苹果 App Store 和谷歌 Play 商店的应用审查阶段经常需要几周时间。强制更新可能会导致移动应用用户数周无法使用。
- 用户仍然可以使用非常旧版本的桌面、命令行和移动应用,这使得在不强制升级版本的情况下无法进行轮换。
- JWT 的有效期有 10 年,这给了恶意攻击者更多可乘之机。
- JWT 是自我引用的,里面有很多对实现其主要目的没有必要的冗余信息。
- JWT 很大,很难解析、验证和操作——这会导致不安全的日志记录或糟糕的安全做法。
- 它们是用对称的 JWT 密钥签名的。
在启用可发布和秘密密钥后,你还能使用旧的 anon 和 service-role#
🌐 Can you still use an old anon and service-role API keys after enabling the publishable and secret keys?
是的。这让你可以在两组密钥都处于激活状态时,通过逐步更换客户端来实现 API 密钥的无缝切换。关于如何在所有客户端切换完成后停用密钥,请看下一个问题。
🌐 Yes. This allows you to transition between the API keys with zero downtime by gradually swapping your clients while both sets of keys are active. See the next question for how to deactivate your keys once all your clients are switched over.
在改用可发布和秘密密钥后,如何停用 anon 和 service_role#
🌐 How to deactivate the anon and service_role JWT-based API keys after moving to publishable and secret keys?
你可以在仪表板的 设置 > API 密钥 部分执行此操作。为了防止应用组件发生停机,请在停用之前使用页面上的最后使用标记来确认这些 API 密钥不再被使用。
🌐 You can do this in the Settings > API Keys section of the Dashboard. To prevent downtime in your application's components, use the last used indicators on the page to confirm that these are no longer used before deactivating.
如果你需要的话,你可以重新激活它们。
🌐 You can re-activate them should you need to.
在托管平台上,可发布密钥和秘密密钥是如何实现的? #
🌐 How are publishable and secret keys implemented on the hosted platform?
当你的应用使用 Supabase API 时,它们会通过 Supabase 托管平台上的一个叫做 API 网关的组件。这为我们(因此也为你)提供了以下功能:
🌐 When your applications use the Supabase APIs they go through a component called the API Gateway on the Supabase hosted platform. This provides us (and therefore you) with the following features:
- 可观察性和日志记录。
- 性能和请求路由(比如到只读副本)。
- 安全,用于在全球范围内阻止恶意模式或行为。
这个 API 网关组件可以验证 API 密钥(通过 apikey 请求头发送,或者在 WebSocket 中通过查询参数发送)是否在你项目的可发布和秘密密钥列表中。如果匹配成功,它会生成一个临时的、短期有效的 JWT,然后将其转发到你项目的服务器。
🌐 This API Gateway component is able to verify the API key (sent in the apikey request header, or for WebSocket in a query param) against your project's publishable and secret key list. If the match is found, it mints a temporary, short-lived JWT that is then forwarded down to your project's servers.
如果你自己托管,可能可以通过使用可编程代理,例如 Kong、Envoy、NGINX 或类似的工具来复制类似的行为。
🌐 It may be possible to replicate similar behavior if you self-host by using programmable proxies such as Kong, Envoy, NGINX or similar.