Linked App Token(关联应用令牌) 策略选择器允许一个应用程序上的 Access 策略接受为另一个应用程序签发的令牌。当一个应用程序需要代表用户向另一个应用程序发出经过身份验证的请求时,这非常有用——例如,MCP 服务器调用内部 API,或者微服务将用户身份转发给下游服务。
Linked App Token 支持两种流程:
- Self-hosted to self-hosted(自托管到自托管) — 自托管应用程序将其 Access JWT 转发给另一个自托管应用程序。这是最简单的设置,不需要其他 OAuth 配置。
- SaaS to self-hosted(SaaS 到自托管) — 针对 SaaS 的 Access 应用程序(例如使用 OAuth 的 MCP 服务器)向自托管应用程序发送其 OAuth 访问令牌。
在此流程中,应用程序 A 是一个自托管 Access 应用程序,需要向另一个自托管 Access 应用程序——应用程序 B 发出请求。当用户通过应用程序 A 的身份验证时,Cloudflare Access 会在 Cf-Access-Jwt-Assertion 请求头中将用户的 JWT 发送给应用程序 A。应用程序 A 随后可以在 Cf-Access-Token 请求头中将该令牌转发给应用程序 B。Access 将根据应用程序 B 策略上的 Linked App Token 规则验证该令牌,如果该令牌是为应用程序 A 签发的,则允许请求。
flowchart LR
accTitle: 自托管到自托管 linked app token 流程
User["用户"] --> appA["应用程序 A <br> (自托管)"]
appA -- "Cf-Access-Token: <JWT>" --> appB["应用程序 B <br> (自托管)"]
idp["身份提供商"] <--> appA
在应用程序 B(将接收转发请求的下游应用程序)上创建策略:
-
在 Cloudflare 仪表板 ↗中,前往 Zero Trust > Access controls(访问控制) > Applications(应用程序)。
选择 应用程序 B,然后选择 Edit(编辑)。
-
前往 Policies(策略) 选项卡,然后选择 Create new policy(创建新策略)。
-
将策略 Action(操作) 设置为 Service Auth。
-
对于 Selector(选择器),选择 Linked App Token。
对于 Value(值),选择 应用程序 A。例如:
Action(操作) Rule type(规则类型) Selector(选择器) Value(值) Service Auth(服务身份验证) Include(包含) Linked App Token application-a-
保存策略。
在 应用程序 B 中,将策略添加到 Access policies(Access 策略) 列表。
-
保存应用程序。
获取 应用程序 A 的
uid:
At least one of the following token permissions is required:Required API token permissions
Access: Apps and Policies RevokeAccess: Apps and Policies WriteAccess: Apps and Policies Read
List Access applicationsbash curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/access/apps" \ --request GET \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"{ "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "uid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "type": "self_hosted", "name": "application-a", ... }在下游应用程序上创建 Access 策略,将
app_uid值替换为 应用程序 A 的uid:
At least one of the following token permissions is required:Required API token permissions
Access: Apps and Policies Write
Create an Access reusable policybash curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/access/policies" \ --request POST \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ --json '{ "name": "允许来自应用程序 A 的请求", "decision": "non_identity", "include": [ { "linked_app_token": { "app_uid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" } } ] }'
当 Cloudflare Access 对应用程序 A 的用户进行身份验证时,它会在 Cf-Access-Jwt-Assertion 请求头中发送一个签名的 JWT。应用程序 A 必须在 Cf-Access-Token 请求头中将此令牌转发给应用程序 B:
Cf-Access-Token: <JWT from Cf-Access-Jwt-Assertion>当 Access 收到对应用程序 B 的请求时,它将:
- 从
Cf-Access-Token请求头中提取令牌。 - 验证令牌是否是为应用程序 A 签发的(与 Linked App Token 规则中的
app_uid匹配)。 - 如果有效,Access 将签发一个针对应用程序 B 的 AUD 标签作用域的新
Cf-Access-Jwt-Assertion,将其转发到应用程序 B 的源站,并在审计日志中将该请求归因于原始用户。
在此示例中,一个针对 SaaS 的 Access 应用程序(例如,实现了 OAuth ↗ 的 MCP 服务器)需要向自托管 Access 应用程序(应用程序 B)发起请求。SaaS 应用程序从 Cloudflare Access 获取一个 OAuth 访问令牌,并在 Authorization: Bearer 请求头中将其发送给自托管应用程序。
flowchart LR
accTitle: SaaS 到自托管 linked app token 流程
User["用户"] --> appA["应用程序 A <br> (Access for SaaS)"]
appA -- "Authorization: Bearer <token>" --> appB["应用程序 B <br> (自托管)"]
idp["身份提供商"] <--> appA
在自托管应用程序(应用程序 B)上创建策略:
-
在 Cloudflare 仪表板 ↗中,前往 Zero Trust > Access controls(访问控制) > Applications(应用程序)。
选择 自托管应用程序 (应用程序 B),然后选择 Edit(编辑)。
-
前往 Policies(策略) 选项卡,然后选择 Create new policy(创建新策略)。
-
将策略 Action(操作) 设置为 Service Auth。
-
对于 Selector(选择器),选择 Linked App Token。
对于 Value(值),选择 针对 SaaS 的 Access 应用程序 (应用程序 A)。例如:
Action(操作) Rule type(规则类型) Selector(选择器) Value(值) Service Auth(服务身份验证) Include(包含) Linked App Token application-a-
保存策略。
在 自托管应用程序 (应用程序 B) 中,将策略添加到 Access policies(Access 策略) 列表。
-
保存应用程序。
获取 针对 SaaS 的 Access 应用程序 (应用程序 A) 的
uid:
At least one of the following token permissions is required:Required API token permissions
Access: Apps and Policies RevokeAccess: Apps and Policies WriteAccess: Apps and Policies Read
List Access applicationsbash curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/access/apps" \ --request GET \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"{ "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "uid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "type": "saas", "name": "my-saas-app", ... }在下游应用程序上创建 Access 策略,将
app_uid值替换为 针对 SaaS 的 Access 应用程序 (应用程序 A) 的uid:
At least one of the following token permissions is required:Required API token permissions
Access: Apps and Policies Write
Create an Access reusable policybash curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/access/policies" \ --request POST \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ --json '{ "name": "允许来自 SaaS 应用程序的请求", "decision": "non_identity", "include": [ { "linked_app_token": { "app_uid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" } } ] }'
SaaS 应用程序必须在 HTTP 请求头中将 OAuth access_token 转发给自托管应用程序:
Authorization: Bearer ACCESS_TOKEN端到端流程为:
- 用户通过 OAuth 对针对 SaaS 的 Access 应用程序进行身份验证。
- 成功后,应用程序接收到一个
access_token。 - 应用程序向自托管应用程序发出请求,并在
Authorization: Bearer请求头中携带该令牌。 - Cloudflare Access 检查该令牌并根据
linked_app_token规则对其进行验证。如果有效,则允许该请求。
- 关联应用令牌策略只能添加到自托管应用程序,无法添加到 SaaS 应用程序或其他应用程序类型。
- 该功能最适合依赖 Cloudflare Access JWT 进行身份验证和身份识别的应用程序。如果下游应用程序在 Cloudflare Access 之后实现了自己的身份验证层,通过 Access 验证的请求仍可能被该应用程序本身拒绝。
- 当上游应用程序使用 Managed OAuth 时,客户端收到的是不透明访问令牌,而非 JWT。客户端无法将此令牌作为
Cf-Access-Token标头直接转发给下游应用程序。此时,上游应用程序的源站必须读取Cf-Access-Jwt-Assertion标头(其中包含已解析的 JWT),并将其作为Cf-Access-Token转发给下游应用程序。如果您希望客户端无需代理即可访问多个端点,请考虑改用多域 Access 应用程序。