十五年前,TLS 是用来保护应用中最敏感区域的东西。后来,Google、Let's Encrypt、EFF 等推动了 HTTPS 的全面普及,使加密成为每个请求的默认设置。没有它,浏览器和服务器之间的任何人都可以读取和篡改流量。
OAuth、OIDC、DBSC 及相关标准已经为安全认证提供了构建模块,但仅靠标准并不能让安全方法成为常态。HTTPS 需要让加密变得简单的工具,以及使其成为预期的持续推动。机器对机器认证仍然类似于 2010 年的 HTTPS,一些供应商和企业在引领潮流,而长期静态凭证仍然是许多 SaaS 供应商和基础设施提供商的默认选择。
在 Vercel,我们希望让快速和安全成为整个网络的默认,包括在我们自己的服务和市场中的集成。我们构建了 OIDC UI,一个 shadcn/ui 注册表,为提供商提供信任策略表单和令牌验证代码。我们正在扩大 Vercel 对 OIDC 的支持,并为市场提供商设定新的认证要求。
长期静态凭证不安全
长期静态凭证是应用程序不断重复使用的机密,如 API 密钥和数据库密码,通常没有过期时间。随着代理承担更多有用的工作,我们通过凭证授予它们访问我们的系统、工具和数据的权限,这些凭证可以授予远超当前任务的权限。
这些凭证可能泄露到代码仓库或聊天中,在服务或依赖被入侵时被盗,或在提示注入导致代理泄露时暴露。无论哪种情况,攻击者都可以使用该凭证及其授予的权限,直到它过期或被撤销。最近全行业的凭证盗窃和供应链事件表明,当恶意代码可以在生产环境中读取应用程序的凭证时,为什么静态加密还不够。
轮换暴露的凭证需要时间和跨使用它们的系统进行协调,错误可能会中断生产。在 Vercel,我们之前出于谨慎,在多次非常痛苦的密钥轮换中花费了数千个工程小时,我们再也不想这样做了。
更好的解决方案已经存在
使用 OIDC,你的应用程序可以在不存储长期提供商密钥的情况下进行认证。受信任的颁发者提供签名的短期令牌来标识应用程序,接收服务在决定授予什么访问权限之前验证该令牌。
被盗的令牌在过期后停止工作,限制了该副本的使用时间,即使泄露未被发现。你的应用程序可以通过编程方式获取新凭证,无需在使用它的系统中分发和手动轮换持久提供商密钥。
我们一直在 Vercel 中优先考虑 OIDC,以便应用程序可以访问 Blob、AI Gateway 和 Sandbox,而无需为这些服务存储长期密钥。我们的 OIDC 联合 自 2024 年起普遍可用,允许在 Vercel 上运行的应用程序根据配置的项目和环境信任策略,将 Vercel 颁发的身份令牌交换为临时的 AWS、Google Cloud 和 Azure 凭证。但要让开发者停止管理长期密钥,这种支持必须扩展到他们应用程序所依赖的所有服务。
网络的其他部分尚未跟进
我们调查了 1000 多家 SaaS 供应商,发现只有 8.4% 支持安全认证方法。
但让供应商支持安全认证只是问题的一部分。即使服务提供了安全方法,开发者通常选择静态密钥,因为它使用起来更简单。我们看到更广泛采用的三个主要障碍:
- 工具和设置使安全认证比使用静态密钥更复杂。
- 在请求路径上获取或交换令牌带来的额外延迟。
- 供应商提供和优先考虑安全认证的激励薄弱。
我们的目标是让安全认证成为 Vercel 上的默认,同时利用我们的市场帮助推动更多供应商支持它。
我们对更安全网络的承诺
我们有责任在我们运行的服务、开发者使用的工具以及我们与合作伙伴构建的集成中,使这一变革切实可行。
让安全认证更易于使用
使用安全令牌必须比粘贴密钥更容易,否则开发者会继续粘贴密钥。在 Vercel 上,代码通过函数调用检索 OIDC 令牌,并通过自定义受众指定接收该令牌的服务。
使用 Vercel Connect,应用程序和代理使用其部署身份在运行时请求提供商令牌,而无需在环境变量中存储长期提供商机密。一旦连接器配置并链接到项目,且用户账户已连接,代码就可以为该用户请求具有提供商支持范围的令牌。
app/api/agent/route.ts
import { getToken } from '@vercel/connect';
const token = await getToken('oauth/linear', {
subject: { type: 'user', id: 'user_123' },
scopes: ['read'],
});
通过 Vercel Connect 为用户请求 Linear 访问权限
我们还在扩展 Vercel API 和 CLI 中的 OIDC 支持,以消除部署工作流中对长期 Vercel 令牌的需求。
面向 API 提供商的 OIDC UI
OIDC UI 是一个 shadcn/ui 组件注册表,包含信任策略配置器和服务器端令牌验证器。它包括针对 Vercel、GitHub、GitLab、Google、Bitbucket、AWS、Azure 和自定义 OIDC 颁发者的提供商表单。提供商可以让客户为特定 Vercel 项目的生产环境配置信任,然后根据该策略验证传入的令牌,而无需从头构建配置界面和验证代码。




为你的服务生成信任策略表单和令牌验证代码。
降低安全身份验证的性能开销
环境变量中的静态密钥在函数运行时已经可用,因此读取它不需要网络请求。获取令牌或将其交换为提供商凭证会增加网络延迟,因此减少这些调用是让安全身份验证切实可行的一部分。
Vercel Functions 会在请求头中收到平台签发的令牌,SDK 会读取它,而无需再获取另一个令牌。平台会复用未过期的令牌,而 Vercel Connect 会在进程内缓存提供商令牌,并在临近过期时刷新它们。自定义受众和提供商交换需要网络调用。
例如,应用可以使用 Azure SDK 以临时凭证访问 Cosmos DB,而不是使用数据库密钥。当 Azure 配置为信任该 Vercel 项目及其默认令牌受众时,回调会向 ClientAssertionCredential 提供 Vercel OIDC 令牌,后者将其交换为 CosmosClient 所使用的 Azure 访问令牌。
lib/cosmos.ts
import { getVercelOidcToken } from '@vercel/oidc';
import { ClientAssertionCredential } from '@azure/identity';
import { CosmosClient } from '@azure/cosmos';
const credentialsProvider = new ClientAssertionCredential(
process.env.AZURE_TENANT_ID!,
process.env.AZURE_CLIENT_ID!,
() => getVercelOidcToken(),
);
const cosmosClient = new CosmosClient({
endpoint: process.env.COSMOS_DB_ENDPOINT!,
aadCredentials: credentialsProvider,
});
将 Vercel OIDC 令牌交换为 Azure Cosmos DB 访问权限
激励提供商支持安全身份验证
Vercel Marketplace 提供对第三方数据库、内容管理系统、可观测性工具等的访问。我们的目标是让所有这些供应商都支持短期的、基于身份的身份验证,无论他们是直接接受 OIDC 令牌,还是将其交换为临时凭证。我们正在努力让集成在开发者连接服务时自动配置该身份验证,从而无需单独的设置步骤。
HTTPS 的全面普及并非仅靠易用性取胜。Chrome 给纯 HTTP 打上了“不安全”标签,随后又设定了截止期限。现在我们也要设定自己的期限。到 2026 年 11 月 30 日,不支持从 Vercel 到其服务的 OIDC 身份验证、并使用长期密钥进行身份验证的供应商,其列表上将会出现类似的“不安全”提示。到 2027 年 1 月,不提供安全身份验证的供应商将被下架。我们要求 Vercel API 和我们自己的原生集成也达到同样的标准。
从静态到动态
十五年前,加密每个请求还像是小题大做。如今,挂锁图标已如此普遍,以至于我们只有在它缺失时才会注意到。服务之间的安全身份验证也应变得同样寻常,这样开发者就能连接他们所需的系统,而无需再存储一个长期密钥。从静态到动态一直是 Vercel 的使命。它始于页面,如今则延伸到了凭证。
其他资源
- OIDC 联合介绍了部署如何获取短期身份令牌,并附有面向 AWS、GCP、Azure 和你自己的 API 的指南。
- 自定义 OIDC 令牌受众将每个令牌限定为只供其预期接收的那一个服务使用。
- Vercel Connect在运行时请求短期的、限定范围的提供商令牌,因此代码和代理永远不会存储凭证。
- Vercel Connect 指南逐步介绍了如何以这种方式构建代理,从 Slack 机器人到 GitHub 代理。
