OPA 鉴权策略
概述
OPA 鉴权策略是云开发提供的 环境级请求鉴权能力,基于开源策略引擎 Open Policy Agent (OPA) 和策略语言 Rego 构建。通过在云开发控制台编写一段策略代码,可以为整个环境的 HTTP API 和 HTTP 网关 请求定义统一的访问控制规则。
云开发会在每次收到请求时执行策略,根据 用户身份、HTTP 请求、环境上下文 三类信息做出"放行 / 拦截"决策,再将请求转发到实际调用的资源。
用户请求
↓
云开发
↓
构造 input(subject + request + cloudbase)
↓
执行 OPA 策略评估
├─ allow = true 且 deny = false → 放行 → 访问实际资源
└─ deny = true → 拒绝,返回 403 + 原因
默认情况下,云开发为 HTTP API 和 HTTP 网关内置一套平台默认策略,覆盖各类资源在不同身份下的默认放通与拒绝规则,具体策略规则见 附录 A:平台默认策略。
用户策略可在平台默认策略之上进行追加调整:
- 用户策略中定义的
allow(放通)可放开被平台默认拒绝的请求 - 用户策略中定义的
deny(拒绝)可拒绝被平台默认放通的请求(deny优先级高于allow)
通过用户策略的调整,可灵活、细粒度地定义基于 HTTP 请求、用户身份、访问资源或多种条件组合的鉴权规则,实现高度可定制的权限管控。通过编写 OPA 策略,可实现下列需求:
- 按资源与身份放通或拒绝访问
- 只放通指定的云函数
- IP 白名单访问控制
- 按访问入口执行不同规则
- ...
关于完整实现示例,请参考 实战案例。
适用范围(客户端 SDK)
OPA 策略作用于底层通过 HTTP API 和 HTTP 网关 访问云开发的请求,因此只有调用链路走 HTTP API / HTTP 网关的客户端才受其管控,具体适用范围见下表:
| 客户端 / 调用方式 | 是否受 OPA 管控 |
|---|---|
JS SDK v3+(@cloudbase/js-sdk) | ✅ |
Node SDK v4+(@cloudbase/node-sdk)/ wx-server-sdk v5.0+ | ✅ |
| 官方 Flutter SDK/C# SDK | ✅ |
| 直接调用 HTTP API / HTTP 网关 | ✅ |
微信小程序原生 SDK 调用 PG 环境云函数及云存储接口 wx.cloud.callFunction/wx.cloud.uploadFile | ✅ |
微信小程序原生 SDK 调用 PG 环境文档云数据库接口 wx.cloud.database().collection('foobar') | ❌ |
核心能力
| 能力 | 说明 |
|---|---|
| 多条件组合鉴权 | 可基于用户身份、请求特征、环境信息等多维度条件灵活组合鉴权规则,实现细粒度访问控制 |
| 统一策略入口 | 同一份策略同时覆盖 HTTP API 和 HTTP 网关(云函数/云托管/静态托管等)入口,统一管控公网流量 |
| 拒绝原因可溯源 | 拒绝请求时可向调用方返回可读的拒绝原因,便于快速排查权限问题 |
| 在平台默认策略基础上定制 | 平台已内置各资源类型的默认放通/拒绝规则,你只需编写策略调整需要覆盖的规则,无需从零开始 |
| 支持标准 Rego 语法 | 基于 OPA 开源策略引擎,使用通用的 Rego 策略语言,学习成本低,社区资源丰富 |
与其他安全能力的关系
云开发提供了多层安全能力,OPA 鉴权策略位于请求入口的 访问控制 层,与其他能力协作形成防护体系:
| 能力 | 作用域 | 控制维度 | 何时选用 |
|---|---|---|---|
| OPA 鉴权策略 | 环境内所有 HTTP API 和 HTTP 网关 请求 | 用户 + 请求 + 环境上下文 | 需要复杂条件组合、基于请求级别、可编程的访问控制 |
| 限频设置 | 云函数、云托管 | QPS(资源维度 / 客户端维度) | 防刷、防过载 |
| 静态托管安全配置 | 静态托管资源 | Referer / IP / QPS | 静态资源防盗链 |
| 安全来源 | 客户端 SDK 调用 | 域名白名单 | 限制 SDK 调用来源 |
在控制台配置 OPA 策略
云开发控制台已将 OPA 策略的配置过程做了封装,你无需直接接触底层配置,只需按可视化操作完成设置。控制台提供 表单模式 与 语法模式 两种操作方式:
| 操作模式 | 适用场景 | 说明 |
|---|---|---|
| 表单模式 | 对某个资源放开(允许访问),是最常用的场景 | 通过表单下拉选择,逐条配置,无需写代码 |
| 语法模式 | 表单无法承载的复杂场景,如自定义域名、请求路径、HTTP 方法等条件的组合控制 | 切换到语法视图,直接编写 Rego 策略 |
配置入口
- 登录 云开发控制台,进入目标环境。
- 在左侧菜单中找到 鉴权策略(路径示意:环境 → 鉴权策略)。
- 点击 新建策略 进入配置页面。

表单模式(推荐)
对于"对某类资源放开访问"这类常用需求,建议使用表单模式,通过下拉选择即可完成配置,无需编写任何代码:
- 在配置页面选择 表单模式。
- 在表单中通过下拉框选择需要放开的 资源类型(如云函数、云存储、云托管等)。
- 选择允许访问的 角色 / 用户身份。
- 点击 保存 完成配置。


表单模式覆盖了大多数"按资源、按角色放开访问"的场景。建议优先使用表单模式,当需求超出表单可表达的范围时,再切换到语法模式。
语法模式
当需要基于 请求路径、HTTP 方法、自定义域名 等条件做更细粒度的组合控制时,表单无法承载,此时需切换到 语法模式 编写 Rego 策略:
- 在配置页面切换至 语法视图。
- 在编辑器中粘贴 / 编写 Rego 策略(完整语法见 策略上下文 与 输出:allow / deny)。
- 点击 保存,保存时会执行校验(包名为
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_id | string | C 端用户 ID;未登录为 "" |
auth_type | string | 内置身份认证类型,见下表;区分大小写 |
groups | []string | 请求关联的用户角色,对应请求 JWT 中的 groups 字段 |
auth_type 的全部取值:
| 值 | 含义 |
|---|---|
administrator | 管理员 |
internal | 内部用户 |
external | 外部用户 |
anonymous | 匿名登录用户 |
unauthenticated | 未登录 / 无 AccessToken |
service_role | (仅使用 PostgreSQL 环境存在)service_role,超级权限 |
anon | (仅使用 PostgreSQL 环境存在)匿名角色 |
authenticated | (仅使用 PostgreSQL 环境存在)已认证角色 |
请求信息(request)
| 字段 | 类型 | 说明 |
|---|---|---|
method | string | HTTP 方法,已统一为大写 |
raw_host | string | 原始 Host 请求头,未经规整 |
host | string | 规整后的 Host(去除端口、统一小写) |
path | string | 请求路径,保留 URL 编码 |
query | object<string,string> | URL query 参数;多值参数以 & 拼接 |
client_ip | string | 客户端 IP,可能为 "" / IPv4 / IPv6 |
header | object<string,array<string>> | 请求头,保留多值 |
header_map | object<string,string> | 请求头 |
header 与 header_map 的差别:
header | header_map | |
|---|---|---|
| 值类型 | array<string> | string |
| 读法 | input.request.header["X-Foo"][0] | input.request.header_map["X-Env-Id"] |
Header key 必须使用 HTTP Canonical 形式(如 X-Env-Id、Content-Type),小写或全大写均无法读取。Authorization / Cookie 等敏感头已被云开发剔除,策略无法访问。
环境信息(cloudbase)
| 字段 | 类型 | 说明 |
|---|---|---|
env_id | string | 当前环境 ID |
region | string | 环境所属地域,如 "ap-shanghai" |
entrypoint_type | string | 接入入口类型,见下 |
resource_type | string | 当前请求命中的资源类型,见下 |
entrypoint_type 取值:
| 值 | 含义 |
|---|---|
tcbopenapi | HTTP API 链路,域名为 {envid}.api.tcloudbasegateway.com |
tcbgateway | HTTP 网关 / 云托管 / 静态托管 / 云存储等 HTTP 接入类服务,默认域名包括 .app.tcloudbase.com / .service.tcloudbase.com(HTTP 网关)、.tcloudbaseapp.com(静态托管)、.tcb.qcloud.la(云存储)、.run.tcloudbase.com(云托管) 等;也包括为上述链路绑定的自定义域名 |
resource_type 取值:
| 资源标识 | 标识 | 说明 |
|---|---|---|
| 云存储 | storages | 对象存储操作 |
| 云函数 | functions | 云函数调用 |
| 云托管 | cloudrun | 云托管服务访问 |
| 大模型 | ai | AI 大模型接入 |
| AI 智能体 | aibot | AI 智能体服务 |
| 数据模型 | model | 数据模型管理 |
| MySQL 访问 | rdb | MySQL 数据库访问 |
输出:allow / deny
策略需在 package authz.user 下声明 allow 或 deny,至少其一:
| 规则 | 类型 | 写法 |
|---|---|---|
allow | bool | default allow := falseallow if { ... } |
deny | bool 或 set of string | deny if { ... } 或 deny contains "拒绝原因" if { ... } |
deny 支持两种写法:
- 布尔模式
deny if { ... }— 拦截,不返回原因。 - 集合模式
deny contains "msg" if { ... }— 拦截,并把消息回显给终端用户:Access denied by policy. Reason: msg。
allow 只能放开被平台默认拒绝的请求,不能收紧:default allow := false 不会拦截任何请求。要限制访问(IP 白名单、路径管控、HTTP 方法限制等),必须写 deny。
引擎独立求值每条规则,最终根据 allow 和 deny 的结果决定是否放行。
策略编写注意点
- 强制 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 策略评估的请求:云开发平台内部请求和集成中心回调请求不会经过策略评估。
实战案例
按场景选择,每个例子都是一份独立的完整策略。未命中的请求按平台默认策略处理。
放通访问
- 放通云函数
- 放通云存储
- 只放通指定函数(HTTP API)
- 只放通指定函数(HTTP 网关)
需求:允许未登录和匿名登录用户调用云函数。
package authz.user
allow if {
input.cloudbase.resource_type == "functions"
input.subject.auth_type == "anonymous"
}
HTTP API 请求必须通过认证,不会出现 unauthenticated。
需求:允许未登录和匿名登录用户访问云存储。
package authz.user
allow if {
input.cloudbase.resource_type == "storages"
input.subject.auth_type == "anonymous"
}
需要限定到具体对象时,再叠加 input.request.path。
需求:HTTP API 只放通 login 函数。
package authz.user
allow if {
input.cloudbase.resource_type == "functions"
startswith(input.request.path, "/v1/functions/login")
input.subject.auth_type == "anonymous"
}
函数路径为 /v1/functions/{函数名},用前缀匹配覆盖函数名及其子路径。
需求:HTTP 网关只放通 /api/login 接口。
package authz.user
allow if {
input.cloudbase.resource_type == "functions"
startswith(input.request.path, "/api/login")
input.subject.auth_type == "anonymous"
}
HTTP 网关的路径是你在 HTTP 访问服务 中配置的访问路径。
拦截访问
- 拒绝匿名与未登录
- 拒绝匿名与未登录访问云存储
- 拦截指定路径
需求:云函数只允许已登录用户调用。
package authz.user
deny contains "请登录后访问" if {
input.cloudbase.resource_type == "functions"
input.subject.auth_type in {"anonymous", "unauthenticated"}
}
平台默认放通未登录请求,收紧访问只能写 deny。
需求:云存储只允许已登录用户访问。
package authz.user
deny contains "请登录后访问" if {
input.cloudbase.resource_type == "storages"
input.subject.auth_type in {"anonymous", "unauthenticated"}
}
需求:禁止公网访问 internalSync 云函数及其子路径。
package authz.user
deny contains "该接口不对外开放" if {
input.cloudbase.resource_type == "functions"
startswith(input.request.path, "/v1/functions/internalSync")
}
入口与白名单
- 只允许 HTTP API 调用
- 禁止 HTTP 网关访问
- IP 白名单
- 按角色控制
需求:云函数只允许通过 HTTP API 调用。
package authz.user
allow if {
input.cloudbase.entrypoint_type == "tcbopenapi"
input.cloudbase.resource_type == "functions"
}
需求:禁止从 HTTP 网关直接访问云函数。
package authz.user
deny contains "该云函数不允许从 HTTP 访问服务访问" if {
input.cloudbase.entrypoint_type == "tcbgateway"
input.cloudbase.resource_type == "functions"
}
需求:只允许办公网 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
}
需求:只允许 ops 和 dev 组访问,其中 dev 组不能删除。
package authz.user
allowed_groups := {"ops", "dev"}
has_allowed_group if {
some g in input.subject.groups
g in allowed_groups
}
deny contains "user group is not authorized in this env" if not has_allowed_group
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_role、anon、authenticated
下表中未列出的资源类型,代表平台对超管 / 内部用户 / 外部用户 / 访客四类身份均默认放通。
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.send、net.lookup_ip_addr、providers.aws.sign_req |
| 时间 | time.* |
| 正则 | regex.*、re_match(改用 startswith / endswith / contains / glob.match) |
| JWT 解析 | io.jwt.* |
| 编解码 | base64.*、base64url.*、hex.*、urlquery.* |
| YAML | yaml.*(改用 json.*) |
| 反射 / 元数据 | opa.runtime、rego.metadata.*、rego.parse_module |
| 调试 | trace、print |
| 资源消耗 | walk、net.cidr_expand、numbers.range、numbers.range_step、graph.*、graphql.*、strings.render_template |
| 证书 / 密钥 | crypto.x509.*、crypto.parse_private_keys |
| 其他 | uuid.*、rand.intn、semver.*、units.*、json.patch、json.match_schema、json.verify_schema |