Oracle Label Security(OLS)

Oracle Label Security(OLS)

适用版本:Oracle Database 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07


1. 概述

Oracle Label Security(OLS,标签安全) 是 Oracle 提供的行级访问控制方案[1],基于数据敏感度标签:

核心特性

  • 行级访问控制
  • 基于标签(Label)的权限
  • 多级安全(MLS)
  • 无需编写代码

典型场景

  • 政府/军事机密分级
  • 数据敏感度控制
  • 多级访问权限

2. OLS 概念

2.1 标签组件

Label = Level + Compartment + Group

示例:
Level:    TS (Top Secret) > S (Secret) > C (Confidential) > U (Unclassified)
Compartment: FIN, HR, IT
Group:    EAST, WEST

2.2 标签示例

TS:FIN:EAST     - Top Secret, Finance, East
S:HR            - Secret, HR
C               - Confidential
U               - Unclassified

2.3 用户标签 vs 数据标签

  • 用户标签:用户可访问的最高级别
  • 数据标签:数据行的敏感度级别
  • 比较规则:用户标签 >= 数据标签 才能访问

3. 启用 OLS

3.1 安装 OLS

# DBCA 启用 OLS
$ORACLE_HOME/bin/dbca -silent -configureDatabase \
  -sid ORCL \
  -addOption OLS

# 或手动
SQL> @?/rdbms/admin/catols.sql

3.2 启用 LBAC

-- 启用 Label Security
ALTER SYSTEM SET "_system_trig_enabled" = TRUE SCOPE=BOTH;

-- 检查
SELECT * FROM dba_ols_status;

3.3 创建 Policy

BEGIN
  SA_SYSDBA.CREATE_POLICY(
    policy_name => 'data_access',
    column_name => 'data_label'
  );
END;
/

4. 配置标签组件

4.1 创建 Level

BEGIN
  SA_COMPONENTS.CREATE_LEVEL(
    policy_name => 'data_access',
    level_num => 40,
    short_name => 'TS',
    long_name => 'Top Secret'
  );
  
  SA_COMPONENTS.CREATE_LEVEL(
    policy_name => 'data_access',
    level_num => 30,
    short_name => 'S',
    long_name => 'Secret'
  );
  
  SA_COMPONENTS.CREATE_LEVEL(
    policy_name => 'data_access',
    level_num => 20,
    short_name => 'C',
    long_name => 'Confidential'
  );
  
  SA_COMPONENTS.CREATE_LEVEL(
    policy_name => 'data_access',
    level_num => 10,
    short_name => 'U',
    long_name => 'Unclassified'
  );
END;
/

4.2 创建 Compartment

BEGIN
  SA_COMPONENTS.CREATE_COMPARTMENT(
    policy_name => 'data_access',
    comp_num => 100,
    short_name => 'FIN',
    long_name => 'Finance'
  );
  
  SA_COMPONENTS.CREATE_COMPARTMENT(
    policy_name => 'data_access',
    comp_num => 200,
    short_name => 'HR',
    long_name => 'Human Resources'
  );
END;
/

4.3 创建 Group

BEGIN
  SA_COMPONENTS.CREATE_GROUP(
    policy_name => 'data_access',
    group_num => 1000,
    short_name => 'EAST',
    long_name => 'East Region'
  );
END;
/

5. 创建标签

5.1 创建数据标签

BEGIN
  SA_LABEL_ADMIN.CREATE_LABEL(
    policy_name => 'data_access',
    label_tag => 1,
    label_value => 'TS:FIN:EAST',
    data_label => TRUE
  );
  
  SA_LABEL_ADMIN.CREATE_LABEL(
    policy_name => 'data_access',
    label_tag => 2,
    label_value => 'S:HR',
    data_label => TRUE
  );
  
  SA_LABEL_ADMIN.CREATE_LABEL(
    policy_name => 'data_access',
    label_tag => 3,
    label_value => 'C',
    data_label => TRUE
  );
END;
/

5.2 查看标签

SELECT * FROM dba_sa_labels;
SELECT * FROM all_sa_labels;

6. 应用 Policy 到表

6.1 应用 Policy

BEGIN
  SA_POLICY_ADMIN.APPLY_TABLE_POLICY(
    policy_name => 'data_access',
    schema_name => 'scott',
    table_name => 'employees',
    table_options => 'LABEL_DEFAULT, HIDE, READ_CONTROL, WRITE_CONTROL, CHECK_CONTROL',
    label_function => 'data_access_label_func',
    predicate => NULL
  );
END;
/

6.2 选项说明

选项说明
LABEL_DEFAULT默认标签
HIDE隐藏标签列
READ_CONTROL读控制
WRITE_CONTROL写控制
CHECK_CONTROL检查控制
INSERT_CONTROL插入控制
DELETE_CONTROL删除控制
UPDATE_CONTROL更新控制

7. 用户权限

7.1 创建 User Label

-- 给用户 alice 设置标签
BEGIN
  SA_USER_ADMIN.SET_USER_LABELS(
    policy_name => 'data_access',
    user_name => 'alice',
    max_read_label => 'TS:FIN:EAST',
    max_write_label => 'TS:FIN:EAST',
    min_write_label => 'C',
    def_label => 'S:FIN:EAST',
    row_label => 'S:FIN'
  );
END;
/

7.2 设置权限

BEGIN
  SA_USER_ADMIN.SET_USER_PRIVS(
    policy_name => 'data_access',
    user_name => 'alice',
    privileges => 'FULL'
  );
END;
/

7.3 权限类型

权限说明
FULL完全访问
READ读访问
WRITE写访问
ACCESS标准访问
PROFILE配置文件访问

8. 数据操作

8.1 插入数据

-- alice 插入数据
INSERT INTO scott.employees (id, name, data_label) 
VALUES (1, 'Alice', CHAR_TO_LABEL('data_access', 'TS:FIN:EAST'));

-- 或自动标签
INSERT INTO scott.employees (id, name)
VALUES (1, 'Alice');
-- data_label 自动设置为 alice 的 def_label

8.2 查询数据

-- alice 查询
SELECT * FROM scott.employees;
-- 仅返回 alice 可读的行(标签 <= TS:FIN:EAST)

-- bob 查询(标签 S:HR)
SELECT * FROM scott.employees;
-- 仅返回 bob 可读的行

8.3 更新数据

-- 仅能更新可写的行
UPDATE scott.employees SET name = 'Alice2' WHERE id = 1;

9. 监控 OLS

9.1 Policy 信息

SELECT * FROM dba_sa_policies;

9.2 表 Policy

SELECT * FROM dba_sa_table_policies;

9.3 用户标签

SELECT * FROM dba_sa_user_labels;

9.4 标签

SELECT * FROM dba_sa_labels;

10. 常见坑与排错

10.1 ORA-12406: 未授权策略

修复

-- 给用户授权
BEGIN
  SA_USER_ADMIN.SET_USER_PRIVS(
    policy_name => 'data_access',
    user_name => 'alice',
    privileges => 'FULL'
  );
END;
/

10.2 ORA-12407: 标签无效

修复

-- 1. 检查标签
SELECT * FROM all_sa_labels;

-- 2. 检查标签格式
-- Level:Compartment:Group

10.3 查询不到数据

修复

-- 1. 检查用户标签
SELECT * FROM dba_sa_user_labels WHERE user_name='ALICE';

-- 2. 检查数据标签
SELECT id, name, label_to_char(data_label) FROM scott.employees;

-- 3. 确认用户标签 >= 数据标签

10.4 插入失败 ORA-12408

修复

-- 1. 检查 def_label
SELECT * FROM dba_sa_user_labels WHERE user_name='ALICE';

-- 2. 调整权限
BEGIN
  SA_USER_ADMIN.SET_USER_LABELS(
    policy_name => 'data_access',
    user_name => 'alice',
    def_label => 'S:FIN'
  );
END;
/

10.5 SYS 用户绕过 OLS

修复

-- OLS 不影响 SYS/SYSDBA
-- 需要 OLS 的用户不能是 SYS

11. 最佳实践

  1. 合理规划标签层次:避免过深
  2. 使用 Label Function:自动标签
  3. 生产用 OLS + VPD:多层防护
  4. 监控标签使用:dba_sa_labels
  5. 标签列加索引:性能优化
  6. 避免标签频繁变更:稳定设计
  7. PDB 中独立配置:多租户隔离
  8. 审计 OLS 操作:合规要求
  9. 结合 Database Vault:更严格
  10. 生产前测试:验证配置

12. 参考资料

[1] Oracle Label Security Administrator’s Guide 19c https://docs.oracle.com/en/database/oracle/oracle-database/19/olsag/

[2] Oracle Database Security Guide 19c, “Label Security” https://docs.oracle.com/en/database/oracle/oracle-database/19/dbseg/