跳到主要内容

OPA 鉴权策略


概述

OPA 鉴权策略是云开发提供的 环境级请求鉴权能力,基于开源策略引擎 Open Policy Agent (OPA) 和策略语言 Rego 构建。通过在云开发控制台编写一段策略代码,可以为整个环境的 HTTP APIHTTP 网关 请求定义统一的访问控制规则。

云开发会在每次收到请求时执行策略,根据 用户身份、HTTP 请求、环境上下文 三类信息做出"放行 / 拦截"决策,再将请求转发到实际调用的资源。

用户请求

云开发

构造 input(subject + request + cloudbase)

执行 OPA 策略评估
├─ allow = true 且 deny = false → 放行 → 访问实际资源
└─ deny = true → 拒绝,返回 403 + 原因

默认情况下,云开发为 HTTP API 和 HTTP 网关内置一套平台默认策略,覆盖各类资源在不同身份下的默认放通与拒绝规则,具体策略规则见 附录 A:平台默认策略

用户策略可在平台默认策略之上进行追加调整:

  • 用户策略中定义的 allow(放通)可放开被平台默认拒绝的请求
  • 用户策略中定义的 deny (拒绝)可拒绝被平台默认放通的请求(deny 优先级高于 allow)

通过用户策略的调整,可灵活、细粒度地定义基于 HTTP 请求、用户身份、访问资源或多种条件组合的鉴权规则,实现高度可定制的权限管控。通过编写 OPA 策略,可实现下列需求:

  • IP 白名单访问控制
  • 按用户身份控制读写权限
  • 保护管理后台接口
  • 按访问入口执行不同规则
  • ...

关于完整实现示例,请参考 实战案例

核心能力

能力说明
多条件组合鉴权可基于用户身份、请求特征、环境信息等多维度条件灵活组合鉴权规则,实现细粒度访问控制
统一策略入口同一份策略同时覆盖 HTTP API 和 HTTP 网关(云函数/云托管/静态托管等)入口,统一管控公网流量
拒绝原因可溯源拒绝请求时可向调用方返回可读的拒绝原因,便于快速排查权限问题
在平台默认策略基础上定制平台已内置各资源类型的默认放通/拒绝规则,你只需编写策略调整需要覆盖的规则,无需从零开始
支持标准 Rego 语法基于 OPA 开源策略引擎,使用通用的 Rego 策略语言,学习成本低,社区资源丰富

与其他安全能力的关系

云开发提供了多层安全能力,OPA 鉴权策略位于请求入口的 访问控制 层,与其他能力协作形成防护体系:

能力作用域控制维度何时选用
OPA 鉴权策略环境内所有 HTTP APIHTTP 网关 请求用户 + 请求 + 环境上下文需要复杂条件组合、基于请求级别、可编程的访问控制
限频设置云函数、云托管QPS(资源维度 / 客户端维度)防刷、防过载
静态托管安全配置静态托管资源Referer / IP / QPS静态资源防盗链
安全来源客户端 SDK 调用域名白名单限制 SDK 调用来源

在控制台配置 OPA 策略

云开发控制台已将 OPA 策略的配置过程做了封装,你无需直接接触底层配置,只需按可视化操作完成设置。控制台提供 表单模式语法模式 两种操作方式:

操作模式适用场景说明
表单模式对某个资源放开(允许访问),是最常用的场景通过表单下拉选择,逐条配置,无需写代码
语法模式表单无法承载的复杂场景,如自定义域名、请求路径、HTTP 方法等条件的组合控制切换到语法视图,直接编写 Rego 策略

配置入口

  1. 登录 云开发控制台,进入目标环境。
  2. 在左侧菜单中找到 鉴权策略(路径示意:环境 → 鉴权策略)。
  3. 点击 新建策略 进入配置页面。

控制台入口

表单模式(推荐)

对于"对某类资源放开访问"这类常用需求,建议使用表单模式,通过下拉选择即可完成配置,无需编写任何代码:

  1. 在配置页面选择 表单模式
  2. 在表单中通过下拉框选择需要放开的 资源类型(如云函数、云存储、云托管等)。
  3. 选择允许访问的 角色 / 用户身份
  4. 点击 保存 完成配置。

表单模式-1

表单模式-2

表单模式覆盖了大多数"按资源、按角色放开访问"的场景。建议优先使用表单模式,当需求超出表单可表达的范围时,再切换到语法模式。

语法模式

当需要基于 请求路径、HTTP 方法、自定义域名 等条件做更细粒度的组合控制时,表单无法承载,此时需切换到 语法模式 编写 Rego 策略:

  1. 在配置页面切换至 语法视图
  2. 在编辑器中粘贴 / 编写 Rego 策略(完整语法见 策略上下文输出:allow / deny)。
  3. 点击 保存,保存时会执行校验(包名为 authz.user、大小与规则条数限制等,详见 策略编写注意点)。

语法模式

生效与校验

  • 保存后策略 立即生效,无需重启或重新部署。
  • 策略会覆盖当前环境中 HTTP API 与 HTTP 访问服务的请求。
  • 保存时控制台会执行校验,不合法(如 Rego v0 语法、包名不符合要求)的策略会被拒绝并提示原因。
提示

平台为 HTTP API 与 HTTP 访问服务内置了一套默认策略,你在控制台配置的规则是在此基础上做追加调整。默认策略明细见 附录 A:平台默认策略


快速开始

以下为一段最小可用策略:

package authz.user

# 默认拒绝
default allow := false

# 管理员访问 /v1/ 路径放行
allow if {
input.subject.auth_type == "administrator"
startswith(input.request.path, "/v1/")
}

# 未认证用户禁止 DELETE
deny contains "DELETE requires authentication" if {
input.request.method == "DELETE"
input.subject.auth_type == "unauthenticated"
}

示例中的 startswith 是 Rego 内建函数。完整语法与内建函数清单见 Rego 语言参考Rego 内建函数列表;出于安全考虑,CloudBase 仅启用其中的一个白名单子集,常见禁用函数见附录 B

策略输入 input 由云开发在每次请求时构造,完整结构如下,字段详细定义请参考 策略上下文:

{
"subject": {
"user_id": "c-user-123",
"auth_type": "administrator",
"groups": ["developer"]
},
"request": {
"method": "GET",
"raw_host": "env-xxx.api.tcloudbasegateway.com",
"host": "env-xxx.api.tcloudbasegateway.com",
"path": "/v1/functions/foo",
"query": {"page": "1"},
"client_ip": "10.1.2.3",
"header": {"X-Env-Id": ["env-xxx"]},
"header_map": {"X-Env-Id": "env-xxx"}
},
"cloudbase": {
"env_id": "env-xxx",
"region": "ap-shanghai",
"entrypoint_type": "tcbopenapi",
"resource_type": "functions"
}
}

决策矩阵速查(下表 allow / deny 均指用户策略中的规则):

用户 deny用户 allow平台默认策略最终结果
命中任意任意拒绝deny 优先级最高)
未命中true任意允许
未命中false / 未定义放通允许(用户 allow 为假不构成拒绝)
未命中false / 未定义拒绝拒绝

平台默认策略的放通 / 拒绝规则见 附录 A:平台默认策略


策略上下文(input)

input 是策略可读取的唯一外部数据,固定包含三个顶层字段:

input.subject # 请求主体(用户)
input.request # 当前 HTTP 请求
input.cloudbase # CloudBase 环境上下文

用户信息(subject)

字段类型说明
user_idstringC 端用户 ID;未登录为 ""
auth_typestring内置身份认证类型,见下表;区分大小写
groups[]string请求关联的用户角色,对应请求 JWT 中的 groups 字段

auth_type 的全部取值:

含义
administrator管理员
internal内部用户
external外部用户
anonymous匿名登录用户
unauthenticated未登录 / 无 AccessToken
service_role(仅使用 PostgreSQL 环境存在)service_role,超级权限
anon(仅使用 PostgreSQL 环境存在)匿名角色
authenticated(仅使用 PostgreSQL 环境存在)已认证角色

请求信息(request)

字段类型说明
methodstringHTTP 方法,已统一为大写
raw_hoststring原始 Host 请求头,未经规整
hoststring规整后的 Host(去除端口、统一小写)
pathstring请求路径,保留 URL 编码
queryobject<string,string>URL query 参数;多值参数以 & 拼接
client_ipstring客户端 IP,可能为 "" / IPv4 / IPv6
headerobject<string,array<string>>请求头,保留多值
header_mapobject<string,string>请求头

headerheader_map 的差别:

headerheader_map
值类型array<string>string
读法input.request.header["X-Foo"][0]input.request.header_map["X-Env-Id"]

Header key 必须使用 HTTP Canonical 形式(如 X-Env-IdContent-Type),小写或全大写均无法读取。Authorization / Cookie 等敏感头已被云开发剔除,策略无法访问。

环境信息(cloudbase)

字段类型说明
env_idstring当前环境 ID
regionstring环境所属地域,如 "ap-shanghai"
entrypoint_typestring接入入口类型,见下
resource_typestring当前请求命中的资源类型,见下

entrypoint_type 取值:

含义
tcbopenapiHTTP API 链路,域名为 {envid}.api.tcloudbasegateway.com
tcbgatewayHTTP 网关 / 云托管 / 静态托管 / 云存储等 HTTP 接入类服务,默认域名包括 .app.tcloudbase.com / .service.tcloudbase.com(HTTP 网关)、.tcloudbaseapp.com(静态托管)、.tcb.qcloud.la(云存储)、.run.tcloudbase.com(云托管) 等;也包括为上述链路绑定的自定义域名

resource_type 取值:

资源标识标识说明
云存储storages对象存储操作
云函数functions云函数调用
云托管cloudrun云托管服务访问
大模型aiAI 大模型接入
AI 智能体aibotAI 智能体服务
数据模型model数据模型管理
MySQL 访问rdbMySQL 数据库访问

输出:allow / deny

策略需在 package authz.user 下声明 allowdeny,至少其一:

规则类型写法
allowbooldefault allow := false
allow if { ... }
denyboolset of stringdeny if { ... }deny contains "拒绝原因" if { ... }

deny 支持两种写法:

  • 布尔模式 deny if { ... } — 拦截,不返回原因。
  • 集合模式 deny contains "msg" if { ... }— 拦截,并把消息回显给终端用户:Access denied by policy. Reason: msg
警告

allow 只能放开被平台默认拒绝的请求,不能收紧default allow := false 不会拦截任何请求。要限制访问(IP 白名单、路径管控、HTTP 方法限制等),必须写 deny

引擎独立求值每条规则,最终根据 allowdeny 的结果决定是否放行。


策略编写注意点

  • 强制 Rego v1:无需写 import rego.v1;v0 已废弃语法(如 allow { ... })在保存时会被拒绝。
  • package 必须精确为 authz.user:不符合要求的包名在保存时均会被拒绝。
  • 策略大小 ≤ 2 KiB(含注释和空行)。
  • default 规则数 ≤ 20 条:每个 allow if {...}deny if {...}deny contains "msg" if {...} 各算一条;default 声明不计入。
  • deny 原因不应包含敏感信息deny 集合中的消息会回显给终端用户,避免拼接内部 userID、SQL、token 等内容。
  • 严格模式:保存策略时启用 OPA strict mode,未使用的 import 与未使用的函数参数(非通配符)会被拒绝。
  • 可用的内建函数受限:本引擎采用白名单机制,常见的被禁用函数见附录 B
  • 不会经过 OPA 策略评估的请求:云开发平台内部请求和集成中心回调请求不会经过策略评估。

实战案例

按用户身份控制读写权限

需求:未认证用户只读,C 端登录用户可读写但不能删除。

由于平台默认放通未认证请求,"只读"这类限制必须通过 deny 表达:

package authz.user

write_methods := {"POST", "PUT", "PATCH", "DELETE"}

# 收紧:未认证用户禁止写操作
deny contains "unauthenticated user cannot perform write operations" if {
input.subject.auth_type == "unauthenticated"
input.request.method in write_methods
}

# 收紧:C 端登录用户禁止删除
deny contains "regular user cannot perform delete operations" if {
input.subject.auth_type in {"internal", "external", "anonymous"}
input.request.method == "DELETE"
}

# 放开:访客(匿名登录)在 HTTP 访问服务链路下被平台默认拒绝,此处放通其读操作
allow if {
input.subject.auth_type == "anonymous"
input.request.method in {"GET", "HEAD", "OPTIONS"}
}

管理接口仅限管理员调用

需求/admin/ 路径下的接口只允许管理员访问。

平台默认策略不感知请求路径,因此路径级管控必须用 deny

package authz.user

# 收紧:非管理员访问 /admin/ 一律拒绝
deny contains "admin endpoints require administrator identity" if {
startswith(input.request.path, "/admin/")
input.subject.auth_type != "administrator"
}

IP 白名单

需求:只允许办公网 IP 访问,其他来源一律拒绝。

package authz.user

office_cidrs := ["10.0.0.0/8", "192.168.0.0/16"]

in_office if {
some cidr in office_cidrs
net.cidr_contains(cidr, input.request.client_ip)
}

# 收紧:不在白名单内的来源一律拒绝
deny contains "access source is not in the ip allowlist" if {
input.request.client_ip != ""
not in_office
}

按 JWT groups 做角色控制

需求:只允许 opsdev 组访问,其中 dev 组不能删除。

package authz.user

allowed_groups := {"ops", "dev"}

has_allowed_group if {
some g in input.subject.groups
g in allowed_groups
}

# 收紧:不属于任何允许角色的请求一律拒绝(未登录请求的 groups 为空,同样会被拒绝)
deny contains "user group is not authorized in this env" if not has_allowed_group

# 收紧:dev 组禁止删除
deny contains "dev group cannot perform delete operations" if {
"dev" in input.subject.groups
input.request.method == "DELETE"
}

附录 A:平台默认策略

平台默认策略基于链路资源类型身份三个维度做出决策。用户策略在此基础上追加调整:用户的 allow 可放开被默认拒绝的请求,用户的 deny 可拒绝被默认放通的请求(deny 优先于 allow)。下表中,✅ 表示平台默认放通,❌ 表示平台默认拒绝。

以下身份在所有链路、所有资源下平台均默认放通,不在下表中重复列出:

  • 未登录(unauthenticated):需在用户策略中追加 deny 才会被拦截
  • PostgreSQL 环境身份:service_roleanonauthenticated
信息

下表中未列出的资源类型,代表平台对超管 / 内部用户 / 外部用户 / 访客四类身份均默认放通

HTTP API 默认策略

提示

HTTP API 链路标识为:entrypoint_type == "tcbopenapi"

业务模块(resource_type)超管(administrator)内部用户(internal)外部用户(external)访客(anonymous)
云托管(cloudrun)、知识库(knowledge)
大模型(ai)

HTTP 网关默认策略

提示

HTTP 网关链路标识为:entrypoint_type == "tcbgateway"

业务模块(resource_type)超管(administrator)内部用户(internal)外部用户(external)访客(anonymous)
云函数(functions)、云存储(storages)、云托管(cloudrun)

附录 B:被禁用的内建函数

本引擎对内建函数采用白名单机制,常见的被禁用函数如下;不在表内的函数请以保存时的校验结果为准。

类别被禁用的函数
网络外联http.sendnet.lookup_ip_addrproviders.aws.sign_req
时间time.*
正则regex.*re_match(改用 startswith / endswith / contains / glob.match)
JWT 解析io.jwt.*
编解码base64.*base64url.*hex.*urlquery.*
YAMLyaml.*(改用 json.*)
反射 / 元数据opa.runtimerego.metadata.*rego.parse_module
调试traceprint
资源消耗walknet.cidr_expandnumbers.rangenumbers.range_stepgraph.*graphql.*strings.render_template
证书 / 密钥crypto.x509.*crypto.parse_private_keys
其他uuid.*rand.intnsemver.*units.*json.patchjson.match_schemajson.verify_schema

下一步