一键保护所有内部应用,无论是否经过“氛围编码”

Chythra MalapatiMatt RothenbergMatt Provost

阅读时间:6 分钟

本文另有 English繁體中文.

AI 让各团队员工能够比以往更快地构建应用程序。

然而,这种高速发展也让每位 CISO 夜不能寐:任何员工都可以构建应用程序、将其部署到公共互联网,并在不经意间暴露内部工作成果或公司数据。

今天,我们推出全新工具,让您轻松将托管在 Workers 上的应用程序保持私密。现在,您可以将 Cloudflare Access 直接应用于单个 Worker 或账户内的所有 Worker,如此一来,默认情况下应用会受到公司登录的保护,无需依赖于每个开发人员自行设置。 

您现在可以:

  • 在账户层级设置策略,确保所有预览环境和生产环境的部署默认受公司登录保护。
  • 为单个应用程序设置策略,确保在与该应用程序关联的每个域上都强制执行身份验证,无论以何种方式部署。
  • 精确掌握应用程序的访问者信息。直接在代码中获取每位已认证用户的电子邮件、姓名和所属群组——无需进行 JWT(JSON Web Token)验证。
  • 部署一个每次部署默认私密的内部平台。我们已开源一个示例:一个内部静态站点平台,其中每个已部署的 Worker 均默认保持私密。

Access on Workers 的工作原理

为 Worker 启用 Access 后,Cloudflare 会在任何请求到达应用程序代码之前强制执行身份验证。无论请求通过何种方式到达 Worker——自定义域、路由、workers.dev 子域还是预览 URL——只要启用了 Access,用户就必须先完成身份验证。

BLOG-3405 2.png

此前,您需要在主机名层级进行配置,这意味着要在 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 策略,账户内所有 Workers——无论当前已有的还是未来新建的——都将从创建之时起保持私密。

您可以选择策略的覆盖范围:仅预览 URL 流量、所有生产流量,或两者兼顾。仅预览环境模式适用于生产 Workers 有意公开,但您不希望进行中的部署被暴露的场景。

BLOG-3405 3.png

需要某个 Worker 对外公开?在该 Worker 上绕过账户层级策略即可。

BLOG-3405 4.png

保护特定 Worker

如果您不需要账户层级的默认策略,只想锁定某个特定 Worker,可以直接将 Access 应用于该 Worker。

BLOG-3405 5.png

Worker 视图中新增的 Access 选项卡清晰展示了哪些策略适用于该应用程序。若存在多条策略,优先级最高者将生效:主机名策略优先,其次是 Worker 策略,最后是账户策略。

查看应用程序的访问者信息

当 Access 保护您的 Worker 时,您可以获取每个请求的发起者信息——电子邮件、姓名及所属群组——从而实现内容个性化、权限管控或按用户记录访问日志。

这一功能通过 Worker 的 context 对象 (ctx) 实现。每个发往 Worker 的请求都携带一个 ctx,其中包含该请求的元数据。启用 Access 后,我们会将已认证用户的身份信息附加到 ctx 上,即 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 这个单一入口点传递。

在调度 Worker 上设置 Access 策略,则通过该平台部署的每个 Worker 默认设置为私密。

BLOG-3405 6.png

我们还提供了一个开源示例,帮助您部署自己的内部拖放式部署平台——只需在调度 Worker 上配置一次 Access,通过该平台部署的每个站点默认设置为私密。

点击下方按钮,立即部署!

Deploy to Cloudflare
BLOG-3405 7.png

如需了解完整架构,请参阅 Workers for Platforms 参考架构

坚实的技术基础

这项功能得益于 FL2,它是一款全新基于 Rust 的模块化代理,为 Cloudflare 边缘提供支持。Access 是应用程序的前置门卫,因此传统上在请求管道中,它在所有 Workers 逻辑之前执行。但是,为了让 Access 应用程序能够直接定位到特定 Workers 而不是其主机名,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 在工程与设计方面付出的努力,使这一功能得以实现!