返回博客

权限配置指南

coomia-dip 采用三层权限模型:RBAC(基于角色)控制功能访问、ABAC(基于属性)控制数据访问、Row-Level Security(行级安全)控制记录级可见性。本文通过完整示例介绍如何配置和管理这三层权限,包括角色定义、策略编写、权限继承和审计日志。

Coomia发布于 2026年1月20日10 分钟阅读
分享本文Twitter / X

系列:S12 开发者教程 · 第 11 篇 | 难度:中级 | 阅读时间:15 分钟

权限配置指南

#TL;DR

coomia-dip 采用三层权限模型:RBAC(基于角色)控制功能访问、ABAC(基于属性)控制数据访问、Row-Level Security(行级安全)控制记录级可见性。本文通过完整示例介绍如何配置和管理这三层权限,包括角色定义、策略编写、权限继承和审计日志。

#1. 权限模型概述

#1.1 三层权限架构

Code
┌──────────────────────────────────────┐
│        Layer 1: RBAC                 │
│     (角色 → 功能/API 权限)            │
├──────────────────────────────────────┤
│        Layer 2: ABAC                 │
│     (属性条件 → 数据访问策略)          │
├──────────────────────────────────────┤
│        Layer 3: Row-Level Security   │
│     (用户上下文 → 行级过滤)           │
└──────────────────────────────────────┘

#1.2 权限检查流程

Code
用户请求
    │
    ▼
① RBAC 检查: 用户角色是否有权执行此操作?
    │ 通过
    ▼
② ABAC 检查: 用户属性是否满足访问策略?
    │ 通过
    ▼
③ RLS 过滤: 自动注入行级过滤条件
    │
    ▼
返回过滤后的数据

#2. RBAC 配置

#2.1 定义角色

YAML
# permissions/roles.yaml
roles:
  - name: platform_admin
    display_name: 平台管理员
    description: 拥有所有权限
    permissions:
      - "*"  # 全部权限

  - name: data_admin
    display_name: 数据管理员
    permissions:
      - "schema:*"           # Schema 全部操作
      - "object:read"
      - "object:create"
      - "object:update"
      - "object:delete"
      - "relation:*"
      - "pipeline:*"
      - "metric:*"
      - "dashboard:read"
      - "dashboard:create"

  - name: data_analyst
    display_name: 数据分析师
    permissions:
      - "object:read"
      - "relation:read"
      - "metric:read"
      - "metric:query"
      - "dashboard:read"
      - "dashboard:create"
      - "oql:execute"
      - "function:invoke"

  - name: business_user
    display_name: 业务用户
    permissions:
      - "object:read"
      - "action:execute"
      - "dashboard:read"
      - "metric:read"

  - name: viewer
    display_name: 只读用户
    permissions:
      - "object:read"
      - "dashboard:read"
      - "metric:read"

#2.2 Python API 管理角色

Python
from ontology_sdk import OntoPlatform
from ontology_sdk.permissions import Role, Permission

platform = OntoPlatform(
    control_plane_url="localhost:50051"
)

pm = platform.permissions

# 创建角色
pm.create_role(
    Role(
        name="project_manager",
        display_name="项目经理",
        permissions=[
            Permission("object:read"),
            Permission("object:create", resource_type="Project"),
            Permission("object:update", resource_type="Project"),
            Permission("action:execute"),
            Permission("dashboard:read"),
            Permission("dashboard:create"),
            Permission("metric:read"),
            Permission("metric:query"),
        ]
    )
)

# 角色继承
pm.create_role(
    Role(
        name="senior_analyst",
        display_name="高级分析师",
        inherits=["data_analyst"],  # 继承数据分析师的所有权限
        additional_permissions=[
            Permission("pipeline:create"),
            Permission("pipeline:execute"),
            Permission("function:create"),
        ]
    )
)

# 分配角色给用户
pm.assign_role("user-001", "project_manager")
pm.assign_role("user-002", ["data_analyst", "viewer"])

# 查看用户权限
user_perms = pm.get_user_permissions("user-001")
print(f"用户权限: {[p.name for p in user_perms.permissions]}")
print(f"角色: {user_perms.roles}")

#2.3 细粒度资源权限

Python
# 指定资源类型的权限
pm.create_role(
    Role(
        name="hr_manager",
        display_name="HR 经理",
        permissions=[
            # 只能操作 Employee 和 Department 对象
            Permission("object:read", resource_type="Employee"),
            Permission("object:create", resource_type="Employee"),
            Permission("object:update", resource_type="Employee"),
            Permission("object:delete", resource_type="Employee"),
            Permission("object:read", resource_type="Department"),
            Permission("object:update", resource_type="Department"),
            # 只能执行 HR 相关的 Action
            Permission("action:execute", resource_pattern="hr_*"),
            # 只能查看 HR 相关的 Dashboard
            Permission("dashboard:read", resource_pattern="hr_*"),
        ]
    )
)

#3. ABAC 策略配置

#3.1 ABAC 策略结构

YAML
# permissions/policies/data_access.yaml
policies:
  - name: department_data_isolation
    display_name: 部门数据隔离
    description: 用户只能访问本部门的数据
    effect: allow
    target:
      object_types: [Employee, Task, Project]
    conditions:
      all:
        - subject.department == resource.department
        - subject.status == "active"
    priority: 100

  - name: sensitive_salary_access
    display_name: 薪资数据限制
    description: 只有 HR 和管理层可以查看薪资字段
    effect: deny
    target:
      object_types: [Employee]
      properties: [salary, bonus, stock_options]
    conditions:
      none:
        - subject.role IN ["hr_manager", "platform_admin", "cfo"]
    priority: 200

  - name: customer_tier_access
    display_name: 客户等级访问控制
    description: 普通用户只能访问银牌及以下客户
    effect: deny
    target:
      object_types: [Customer]
    conditions:
      all:
        - resource.tier IN ["platinum", "gold"]
        - subject.role NOT IN ["account_manager", "sales_director", "platform_admin"]
    priority: 150

#3.2 Python API 管理策略

Python
from ontology_sdk.permissions import Policy, Condition

# 创建 ABAC 策略
pm.create_policy(
    Policy(
        name="department_data_isolation",
        display_name="部门数据隔离",
        effect="allow",
        target_object_types=["Employee", "Task", "Project"],
        conditions=[
            Condition.equals("subject.department", "resource.department"),
            Condition.equals("subject.status", "active"),
        ],
        priority=100,
    )
)

# 属性级策略(字段屏蔽)
pm.create_policy(
    Policy(
        name="sensitive_field_masking",
        display_name="敏感字段脱敏",
        effect="mask",
        target_object_types=["Employee"],
        target_properties=["phone", "id_card", "bank_account"],
        conditions=[
            Condition.not_in("subject.role", ["hr_manager", "platform_admin"]),
        ],
        masking_rules={
            "phone": "partial",       # 138****1234
            "id_card": "partial",     # 310***********1234
            "bank_account": "full",   # ****************
        },
        priority=200,
    )
)

# 时间段策略
pm.create_policy(
    Policy(
        name="after_hours_readonly",
        display_name="非工作时间只读",
        effect="deny",
        target_actions=["object:create", "object:update", "object:delete"],
        conditions=[
            Condition.time_outside("08:00", "20:00", timezone="Asia/Shanghai"),
            Condition.not_in("subject.role", ["platform_admin"]),
        ],
        priority=50,
    )
)

#3.3 策略评估

Python
# 检查权限(不实际执行)
result = pm.check_access(
    subject={"user_id": "user-001", "role": "data_analyst", "department": "Engineering"},
    action="object:read",
    resource={"type": "Employee", "department": "Engineering", "properties": ["name", "salary"]}
)

print(f"允许访问: {result.allowed}")
print(f"适用策略: {[p.name for p in result.applied_policies]}")
print(f"被屏蔽字段: {result.masked_properties}")
# 输出: 被屏蔽字段: ['salary'](因为 data_analyst 无权查看薪资)

# 批量权限检查
batch_results = pm.check_access_batch(
    subject={"user_id": "user-001", "role": "business_user"},
    checks=[
        {"action": "object:read", "resource": {"type": "Project"}},
        {"action": "object:update", "resource": {"type": "Project"}},
        {"action": "object:delete", "resource": {"type": "Project"}},
        {"action": "pipeline:execute", "resource": {"name": "employee_import"}},
    ]
)

for check, result in zip(checks, batch_results):
    status = "ALLOW" if result.allowed else "DENY"
    print(f"  {check['action']}: {status}")

#4. Row-Level Security (RLS)

#4.1 RLS 规则定义

YAML
# permissions/rls/department_isolation.yaml
rls_rules:
  - name: dept_employee_filter
    display_name: 部门员工可见性
    object_type: Employee
    filter:
      department: $user.department
    apply_to:
      roles: [business_user, data_analyst]
    exclude:
      roles: [platform_admin, hr_manager]

  - name: region_customer_filter
    display_name: 区域客户可见性
    object_type: Customer
    filter:
      region: $user.region
    apply_to:
      roles: [sales_rep, regional_manager]

  - name: project_participant_filter
    display_name: 项目参与者可见性
    object_type: Project
    filter_query: |
      FIND Project
      TRAVERSE participates_in <- Employee
      WHERE Employee.rid = $user.employee_rid
    apply_to:
      roles: [project_member]

#4.2 Python API 管理 RLS

Python
from ontology_sdk.permissions import RLSRule, RLSFilter

# 创建 RLS 规则
pm.create_rls_rule(
    RLSRule(
        name="dept_employee_filter",
        display_name="部门员工可见性",
        object_type="Employee",
        filter=RLSFilter.equals("department", "$user.department"),
        apply_to_roles=["business_user", "data_analyst"],
        exclude_roles=["platform_admin", "hr_manager"],
    )
)

# 复杂 RLS(多条件)
pm.create_rls_rule(
    RLSRule(
        name="multi_condition_filter",
        display_name="多条件数据过滤",
        object_type="Order",
        filter=RLSFilter.all_of([
            RLSFilter.equals("region", "$user.region"),
            RLSFilter.greater_than("total_amount", 0),
            RLSFilter.in_list("status", ["confirmed", "shipped", "delivered"]),
        ]),
        apply_to_roles=["sales_rep"],
    )
)

# 基于关系的 RLS
pm.create_rls_rule(
    RLSRule(
        name="manager_team_visibility",
        display_name="经理团队可见性",
        object_type="Employee",
        filter_query="""
            FIND Employee
            TRAVERSE reports_to -> Employee AS manager
            WHERE manager.rid = $user.employee_rid
            UNION
            FIND Employee WHERE rid = $user.employee_rid
        """,
        apply_to_roles=["team_manager"],
    )
)

#4.3 RLS 的自动注入

RLS 规则会自动注入到所有查询中:

Python
# 用户 A(sales_rep, region=华东)执行查询
# 原始 OQL:
results = platform.oql.execute("FIND Customer SELECT name, tier, revenue")

# 实际执行的 OQL(RLS 自动注入):
# FIND Customer WHERE region = '华东' SELECT name, tier, revenue

# 用户 B(platform_admin)执行同样的查询
# 原始 OQL = 实际 OQL(admin 不受 RLS 限制)

#5. 权限组与继承

#5.1 组织架构权限

Python
# 创建权限组
pm.create_group(
    name="engineering_dept",
    display_name="工程部",
    members=["user-001", "user-002", "user-003"],
    roles=["data_analyst"],
    attributes={"department": "Engineering", "region": "Shanghai"}
)

pm.create_group(
    name="engineering_leads",
    display_name="工程部技术主管",
    parent_group="engineering_dept",  # 继承工程部的基础权限
    members=["user-001"],
    additional_roles=["project_manager"],
    attributes={"level": "lead"}
)

# 组的权限自动继承
# engineering_leads 拥有: data_analyst + project_manager 角色

#5.2 多租户权限隔离

Python
# 租户级隔离
pm.create_tenant_policy(
    tenant_id="tenant-001",
    name="tenant_isolation",
    rules=[
        # 所有对象自动添加 tenant_id 过滤
        RLSRule(
            object_type="*",
            filter=RLSFilter.equals("tenant_id", "$user.tenant_id"),
            apply_to_roles=["*"],
            exclude_roles=["super_admin"],
        ),
        # 租户管理员只能管理本租户用户
        Policy(
            name="tenant_user_management",
            effect="allow",
            target_actions=["user:*"],
            conditions=[
                Condition.equals("resource.tenant_id", "subject.tenant_id"),
            ],
        ),
    ]
)

#6. 审计日志

#6.1 查看审计日志

Python
# 查询权限相关的审计日志
logs = pm.audit_log.query(
    time_range=("2025-01-01", "2025-03-31"),
    user_id="user-001",
    actions=["object:read", "object:update"],
    result="denied",
    limit=50
)

for log in logs:
    print(f"[{log.timestamp}] {log.user_id} -> {log.action}")
    print(f"  资源: {log.resource_type}:{log.resource_id}")
    print(f"  结果: {log.result}")
    print(f"  原因: {log.reason}")
    print(f"  策略: {log.applied_policy}")
    print("---")

# 权限变更审计
changes = pm.audit_log.query_changes(
    time_range=("2025-01-01", "2025-03-31"),
    change_types=["role_assigned", "role_revoked", "policy_created", "policy_updated"]
)

for change in changes:
    print(f"[{change.timestamp}] {change.operator} {change.change_type}")
    print(f"  对象: {change.target}")
    print(f"  详情: {change.details}")

#6.2 权限报告

Python
# 生成权限矩阵报告
matrix = pm.generate_permission_matrix(
    roles=["data_analyst", "project_manager", "business_user"],
    resource_types=["Project", "Employee", "Customer", "Order"]
)

print("权限矩阵:")
print(f"{'角色':<20} {'Project':<15} {'Employee':<15} {'Customer':<15} {'Order':<15}")
for role_row in matrix.rows:
    perms = [','.join(role_row.permissions.get(rt, ['-'])) for rt in matrix.resource_types]
    print(f"{role_row.role:<20} {perms[0]:<15} {perms[1]:<15} {perms[2]:<15} {perms[3]:<15}")

# 用户权限详情报告
user_report = pm.generate_user_report("user-001")
print(f"\n用户: {user_report.user_name}")
print(f"角色: {user_report.roles}")
print(f"权限组: {user_report.groups}")
print(f"有效权限: {len(user_report.effective_permissions)}")
print(f"RLS 规则: {len(user_report.rls_rules)}")
print(f"ABAC 策略: {len(user_report.applicable_policies)}")

#7. 完整实战:企业权限配置

Python
from ontology_sdk import OntoPlatform
from ontology_sdk.permissions import Role, Policy, RLSRule, Condition, RLSFilter, Permission

platform = OntoPlatform(control_plane_url="localhost:50051")
pm = platform.permissions

# === 第一步:定义角色体系 ===
roles = [
    Role(name="admin", display_name="管理员", permissions=[Permission("*")]),
    Role(name="dept_manager", display_name="部门经理", permissions=[
        Permission("object:read"), Permission("object:update"),
        Permission("action:execute"), Permission("dashboard:*"),
        Permission("metric:*"), Permission("oql:execute"),
    ]),
    Role(name="employee", display_name="普通员工", permissions=[
        Permission("object:read"), Permission("action:execute"),
        Permission("dashboard:read"), Permission("metric:read"),
    ]),
]
for role in roles:
    pm.create_role(role)

# === 第二步:ABAC 策略 ===
policies = [
    Policy(
        name="dept_isolation",
        effect="allow",
        target_object_types=["Employee", "Task"],
        conditions=[Condition.equals("subject.department", "resource.department")],
        priority=100,
    ),
    Policy(
        name="salary_protection",
        effect="mask",
        target_object_types=["Employee"],
        target_properties=["salary", "bonus"],
        conditions=[Condition.not_in("subject.role", ["admin", "hr_manager"])],
        masking_rules={"salary": "full", "bonus": "full"},
        priority=200,
    ),
]
for policy in policies:
    pm.create_policy(policy)

# === 第三步:RLS 规则 ===
rls_rules = [
    RLSRule(
        name="dept_filter",
        object_type="Employee",
        filter=RLSFilter.equals("department", "$user.department"),
        apply_to_roles=["employee", "dept_manager"],
        exclude_roles=["admin"],
    ),
    RLSRule(
        name="project_access",
        object_type="Project",
        filter_query="""
            FIND Project TRAVERSE participates_in <- Employee
            WHERE Employee.rid = $user.employee_rid
        """,
        apply_to_roles=["employee"],
    ),
]
for rule in rls_rules:
    pm.create_rls_rule(rule)

# === 第四步:分配角色 ===
pm.assign_role("user-admin", "admin")
pm.assign_role("user-mgr-001", "dept_manager")
pm.assign_role("user-emp-001", "employee")

# === 验证 ===
result = pm.check_access(
    subject={"user_id": "user-emp-001", "role": "employee", "department": "Engineering"},
    action="object:read",
    resource={"type": "Employee", "department": "Engineering"}
)
print(f"员工访问本部门数据: {result.allowed}")  # True

result2 = pm.check_access(
    subject={"user_id": "user-emp-001", "role": "employee", "department": "Engineering"},
    action="object:read",
    resource={"type": "Employee", "department": "Finance"}
)
print(f"员工访问其他部门数据: {result2.allowed}")  # False

#Key Takeaways

  1. 三层防御:RBAC 控制功能访问、ABAC 控制数据策略、RLS 控制记录可见性
  2. 声明式策略:YAML 定义策略,Python API 管理,支持热更新
  3. 自动注入:RLS 规则自动注入所有查询,开发者无需手动过滤
  4. 字段脱敏:ABAC 支持属性级别的脱敏策略
  5. 完整审计:所有权限操作和变更记录可追溯
  6. 多租户支持:租户级隔离策略开箱即用

#Next Article

下一篇:S12-12 数据接入指南 — 学习如何将各种数据源接入 coomia-dip 平台。

Tags: 权限 RBAC ABAC RLS 安全 数据隔离 coomia-dip