AI 让各个团队的员工都能以前所未有的速度构建应用。
但这种速度也让每一位 CISO 夜不能寐:任何员工都可以构建应用并部署到公共互联网,从而意外暴露内部工作成果或公司数据。
今天,我们推出了一系列新工具,让托管在 Workers 上的应用轻松保持私有。你现在可以把 Cloudflare Access 直接应用于单个 Worker,或账户中的每一个 Worker,这样你的应用默认就位于公司登录之后,而无需依赖每位开发者自己去设置。
你现在可以:
- 在账户层面设置策略,确保所有预览和生产部署默认都位于公司登录之后。
- 为单个应用设置策略,确保与它关联的每个域名都强制执行身份验证,无论它以何种方式部署。
- 准确了解谁在访问你的应用。直接在代码中获取每位已认证用户的邮箱、姓名和所属群组,无需验证 JWT(JSON Web Token)。
- 部署一个每次部署默认都私有的内部平台。我们开源了一个示例:一个内部静态站点平台,其上部署的每个 Worker 都是私有的。
Workers 上的 Access:工作原理
当你为某个 Worker 启用 Access 后,Cloudflare 会在任何请求到达你的应用代码之前强制执行身份验证。请求以何种方式到达你的 Worker 并不重要,无论是通过自定义域名、路由、workers.dev 子域名还是预览 URL。只要启用了 Access,用户就必须先通过认证。

以前,你必须在主机名层面进行配置,也就是为你的 Worker 可访问的每个域名分别设置 Access 策略。如果你想为 Worker 添加一个新的自定义域名,就得先更新 Access 策略,否则该主机名无需认证即可访问。
现在,策略直接附加在 Worker 本身上,因此与该 Worker 关联的任何域名或 URL 都会自动受到保护。你可以选择保护的范围:只保护预览 URL,或保护所有主机名。
如果设置为仅预览,那么每次你部署新版本时,为该应用创建的每个预览 URL(无论是 workers.dev 预览 URL,还是你用于预览的自定义域名)都需要认证。如果设置为所有主机名,那么与该 Worker 关联的每个域名都会受到保护,包括自定义域名、路由、workers.dev 子域名和预览 URL。
Access 让你可以控制用户的认证方式。你可以接入现有的身份提供商,让员工使用已有的凭据登录,也可以把访问限制在特定的邮箱地址、邮箱域名或群组。对于智能体,你可以通过服务令牌授予访问权限。
更多内容请参阅此处的 Cloudflare Access for Workers 文档。
让账户中的每个 Worker 默认保持私有
如果你的组织中有许多开发者在部署 Workers,你不会希望依赖每个人都记得启用 Access。你想要的是默认私有。
你只需在账户层面设置一次 Access 策略,账户中的每个 Worker,无论是现有的还是未来新建的,从创建那一刻起就是私有的。
不仅如此,你还可以选择策略覆盖的范围:仅预览 URL 流量、所有生产流量,或两者兼有。如果你的生产环境 Worker 有意设为公开,但又不想让进行中的部署暴露出去,那么仅预览模式就很有用。

需要让某个 Worker 公开?可以单独为该 Worker 绕过账户范围的策略。

保护特定的 Worker
如果你不需要账户范围的默认设置,只想锁定某一个特定的 Worker,可以直接对该 Worker 应用 Access。

Worker 视图中新增的 Access 标签页会准确显示哪些策略适用于该应用。如果存在多条策略,最具体的那条优先:先是主机名策略,然后是 Worker 策略,最后是账户策略。
查看谁在访问你的应用
当 Access 保护着你的 Worker 时,你可以获取每个请求的发起者信息,包括其邮箱、姓名和群组,从而个性化他们看到的内容、执行权限控制,或按用户记录活动日志。
这是通过 Worker 的上下文对象(ctx)实现的。发往你的 Worker 的每个请求都带有一个 ctx,其中包含该请求的元数据。启用 Access 后,我们会把已认证用户的身份以 ctx.access 的形式附加到其中。随后调用 ctx.access.getIdentity(),即可取回用户的邮箱、姓名及更多信息。
以前,这意味着你要自己验证 JWT:解析令牌、校验签名并提取声明。现在,当你的 Worker 启用了 Access,每个已认证的请求都会包含 ctx.access。
获取用户身份只需下面这些:
export default {
async fetch(request, env, ctx) {
if (!ctx.access) {
return new Response("Access required", { status: 403 });
}
const identity = await ctx.access.getIdentity();
const email = identity?.email ?? "unknown";
return new Response(`Hello, ${email}`);
}
};
部署前先在本地测试
我们已经展示了如何使用 ctx.access.getIdentity() 让你的 Worker 获知请求发起者的信息,包括其邮箱、姓名和群组。
在使用 wrangler dev 进行本地开发时也可以这样用。在你的 wrangler.jsonc 中添加一个 access 配置块,即可模拟已认证的用户:
{
"access": {
"dev": {
"aud": "my-app",
"identity": { "email": "admin@company.com" }
}
}
}
你的 Worker 会通过 ctx.access.getIdentity() 获取它,返回的身份对象与你在生产环境中得到的结构一致。把配置中的邮箱换成另一个,就可以以其他用户的身份进行测试。
这意味着你可以验证正确的内容是否展示给了正确的用户,而无需在每次修改后都重新部署并通过 Access 登录。
部署一个每个应用默认都私有的内部平台
如果你管理着一个供员工原型开发和部署应用的内部平台,你需要每个应用都是私有的,而不必为每个应用单独配置访问控制。
Workers for Platforms 让你可以大规模部署 Workers。每个 Worker 都位于某个命名空间内,发往该命名空间的所有流量都经过唯一的入口:调度 Worker(dispatch Worker)。
只需在调度 Worker 上设置一条 Access 策略,通过它部署的每个 Worker 就默认是私有的。

我们还提供了一个开源示例,你可以用它部署自己的内部拖拽式部署平台:只需在调度 Worker 上配置一次访问控制,通过它部署的每个站点就默认是私有的。
点击下方按钮,自己动手部署吧!

完整架构请参阅我们的 Workers for Platforms 参考架构。
建立在坚实的基础之上
这一功能得以实现,要归功于 FL2,即驱动 Cloudflare 边缘的全新基于 Rust 的模块化代理。Access 是你应用的前门,因此传统上它在请求管线中先于所有 Workers 逻辑运行。但要让 Access 应用以单个 Worker 本身而不是其主机名为目标,Access 就需要知道某个请求究竟要到达哪个 Worker。因此,我们需要把 Workers 的路由与 Workers 的执行拆分开,并移动路由逻辑,使其能在 Access 之前运行。
在我们旧的、基于 NGINX 和 Lua 模块的 FL1 系统中,这样的改动会既复杂又有风险。产品之间的交互可能很微妙,如果把逻辑移到请求管线更靠前的阶段,而它又依赖于被另一个产品修改的共享状态,就可能不安全。
FL2 让这件事变得容易。它严格的模块系统把逻辑划分为定义明确、顺序一致的阶段,并静态声明各自的输入和输出。我们得以借助编译器来暴露阶段之间任何有问题的交互,并有信心地逐步推出这次重构。
立即试用
现在所有人都可以使用。在控制台中试一试,或阅读 Cloudflare Access for Workers 文档开始上手。
致谢
感谢 Jesse Li、Brandon Strittmatter、Kyle Hiller、Kenny Johnson、Matt "TK" Taylor、Brendan Irvine-Broque、Yomna Shousha 和 Mike Aizatsky,是他们的工程与设计工作促成了这一切!
