字段级访问控制
字段级访问控制允许你按角色和操作精确控制可访问的字段。一个角色在读取时可以看到哪些列、写入时可以修改哪些列——都可以通过 fields.include 和 fields.exclude 精细定义。
基本语法
json
{
"role": "auditor",
"actions": [
{
"action": "read",
"fields": {
"include": ["*"],
"exclude": ["salary", "password_hash"]
}
}
]
}| 字段 | 说明 |
|---|---|
include | 允许访问的字段列表。["*"] 表示全部字段 |
exclude | 从 include 中排除的字段列表。通常与 "*" 配合使用 |
工作方式
字段过滤在引擎层执行,对 REST、GraphQL 和 MCP 三种协议同时生效:
text
请求到达
↓
引擎查找该角色在该实体上的权限配置
↓
提取 fields.include / fields.exclude
↓
比较请求中引用的字段
├── 在 include 列表中且不在 exclude 中 → 允许
└── 不在 include 中 或 在 exclude 中 → 拒绝
├── REST:返回 400 Bad Request
├── GraphQL:返回 errors
└── MCP:工具调用返回错误
↓
响应:
├── 不指定 $select 时:自动排除被 exclude 的字段
└── 指定 $select 时:引用被禁字段返回 400配置示例
排除敏感字段
审计员可以读取全部数据,但看不到薪资和密码:
json
{
"role": "auditor",
"actions": [
{
"action": "read",
"fields": {
"include": ["*"],
"exclude": ["salary", "password_hash", "internal_notes"]
}
}
]
}精确限定可见字段
客服角色在读取时只能看到客户的联系字段:
json
{
"role": "support",
"actions": [
{
"action": "read",
"fields": {
"include": ["id", "name", "email", "phone", "lastContactDate"],
"exclude": []
}
}
]
}不写 exclude 时等同于空数组。
不同操作不同字段
读取时排除敏感字段,创建时只能写入特定字段:
json
{
"role": "user",
"actions": [
{
"action": "read",
"fields": {
"include": ["*"],
"exclude": ["password_hash", "role"]
}
},
{
"action": "create",
"fields": {
"include": ["name", "email", "profile_image"]
}
},
"update"
]
}update 操作没有指定 fields 限制——意味着可以更新任何字段。不同操作可以独立配置字段控制粒度。
与数据库策略结合
字段控制可以与行级策略同时生效:
json
{
"role": "department_manager",
"actions": [
{
"action": "read",
"fields": {
"include": ["*"],
"exclude": ["salary", "performance_score", "termination_date"]
},
"policy": {
"database": "@item.departmentId eq @claims.departmentId"
}
}
]
}部门经理可以读取本部门员工的数据,但看不到薪资和绩效评分——行级 + 字段级双重过滤。
不传 $select 时的行为
REST 请求不传 $select 时,引擎返回该角色有权访问的全部字段。如果配置了 fields.exclude,被排除的字段自动不出现在响应中——无需客户端配合。
bash
# 不传 $select,salary 字段自动不出现在响应中
curl http://localhost:5000/api/Employee传了被排除字段时的行为
如果客户端通过 $select(REST)或 GraphQL 查询显式请求了被排除的字段:
- REST:返回
400 Bad Request,"Invalid field 'salary' in $select"。 - GraphQL:请求失败,
errors中包含字段不可访问的错误信息。 - MCP 工具:
read_records调用失败。
被排除的字段在引擎层面就不可访问,客户端无法绕过。
include / exclude 规则
| 规则 | 说明 |
|---|---|
include: ["*"] | 包含所有字段(默认行为) |
include: ["id", "name"] | 只允许访问列出的字段 |
exclude 必须在 include 范围内 | 排除不在 include 中的字段没有意义,引擎会忽略 |
include 和 exclude 同时存在 | 先取 include 结果集,再从中移除 exclude 指定的字段 |
不配置 fields | 等同于 include: ["*"],exclude: []——无字段限制 |
字段名引用
include 和 exclude 中使用的是 API 层字段名(如果有 alias 配置,使用别名),不是数据库原始列名。
json
{
"fields": [
{ "name": "sku_product_title", "alias": "title" }
]
}字段控制中应使用 "title",而不是 "sku_product_title"。
CLI 配置
bash
# 授予角色读权限并排除敏感字段
dab update Employee --permissions "auditor:read" \
--fields.include "*" \
--fields.exclude "salary,password_hash"安全建议
| 建议 | 说明 |
|---|---|
| 用 exclude 而非 include | include: ["*"] + exclude: [...] 是更安全的默认行为——新字段自动可见,只需排除敏感字段 |
| 用 include 做极致控制 | 如果不希望新字段被自动暴露,用 include 精确列出允许的字段 |
| 每个操作独立配置 | read 和 update 可能需要不同的字段控制策略 |
| 不要依赖客户端自觉 | 字段过滤在服务端强制执行,客户端无论怎么传参都无法绕过 |
| 别名后引用 | 配置了 fields.alias 后,字段控制中使用别名 |
