SOS权限配置指南:基于Library的自动权限继承

基于SOS 7.04官方文档的完整配置方案

📋 目录


问题背景

场景描述

在SOS管理的模拟库环境中,存在以下情况:

  • 一个project包含多个library(libraryA, libraryB, libraryC, libraryD)
  • 每个library由不同的group控制权限(groupA, groupB, groupC, groupD)
  • 同一个用户可能属于多个group
  • 用户在不同library下创建cell view时,需要文件自动继承该library的group权限

期望行为

1
2
3
4
5
6
7
project/                  (Group: proj_common_grp)
├── libraryA/            (Group: groupA, WRITE: group)
│   └── cell1/           ✅ 期望: Group自动设置为 groupA
│       └── schematic    ✅ 期望: Group自动设置为 groupA
└── libraryB/            (Group: groupB, WRITE: group)
    └── cell2/           ✅ 期望: Group自动设置为 groupB
        └── layout       ✅ 期望: Group自动设置为 groupB

默认行为问题

不使用trigger时:新创建的文件会使用sosd.cfg第一个定义的GROUP,而不是继承父目录的Group


SOS权限机制

核心概念

  1. Group属性:每个文件/目录都有一个Group属性,决定了访问权限
  2. ACL(访问控制列表):定义READ、WRITE和MODIFY_ACL权限
  3. DEFAULT_GROUP:用户的默认组(可选配置)

READ和WRITE权限说明

根据官方文档第114-115行:

权限类型 说明 可选值
READ 允许用户populate工作区文件,执行historydiff等只读命令 owner / group / world
WRITE 允许用户checkout、修改文件,执行tagsnapshotmodattr等写操作 owner / group / world
MODIFY_ACL 控制用户是否可以修改文件的访问控制属性 yes / no

READ权限对比

设置 效果 适用场景
READ world ✅ 所有用户都可以populate和查看 开放式协作环境
READ group ⚠️ 只有group成员可以populate和查看 严格权限控制(推荐)
READ owner ❌ 只有所有者可以populate和查看 极度敏感数据

重要:本文档推荐使用 READ group 以实现严格的权限隔离。

DEFAULT_GROUP规则

根据官方文档第150行:

By default, if there is no USER entry for a user, that user’s default group is the first group in the configuration file in which the user appears.

结论

  • ✅ 大部分用户不需要配置DEFAULT_GROUP
  • ✅ 用户会自动使用配置文件中第一个包含该用户的GROUP
  • ⚠️ 这个规则不适用于跨library权限控制场景

解决方案概述

方案对比

方案 优点 缺点
方案1: 配置DEFAULT_GROUP 简单直接 ❌ 每个用户都要配置
❌ 跨group用户无法解决
方案2: 路径匹配Trigger + 脚本 灵活强大 ❌ 需要维护脚本
❌ 配置复杂
方案3: 父目录继承Trigger ✅ 零维护
✅ 自动继承
✅ 官方推荐
需要设置trigger

✅ 推荐方案:父目录继承Trigger

根据官方文档第217行示例:

This example causes newly-created objects to inherit the Group attribute of their parent directory (which would not happen by default).

使用SOS预定义的$SOS_PARENT_Group环境变量实现自动继承。


详细配置步骤

步骤1: 配置 sosd.cfg - 定义GROUP和ACL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# ========== /repository/project/setup/sosd.cfg ==========

# 1. 定义管理员
ADMIN admin1, admin2;

# 2. 定义全局ACL(可选,作为默认值)
ACL {
    READ  group;   # 严格权限:只有组成员可读
    WRITE group;   # 只有组成员可写
    MODIFY_ACL yes;
}

# 3. 定义公共组(放在第一位!)
GROUP proj_common_grp {
    MEMBER user1, user2, user3, user4, user5;  # 所有团队成员
    ACL {
        READ  group;   # 只有proj_common_grp成员可读
        WRITE group;   # 只有proj_common_grp成员可写
        MODIFY_ACL yes;
    }
}

# 4. 定义各library的专有group
GROUP groupA {
    MEMBER user1, user2;
    ACL {
        READ  group;   # 只有groupA成员可读
        WRITE group;   # 只有groupA成员可写
        MODIFY_ACL yes;
    }
}

GROUP groupB {
    MEMBER user3, user4;
    ACL {
        READ  group;   # 只有groupB成员可读
        WRITE group;   # 只有groupB成员可写
        MODIFY_ACL yes;
    }
}

GROUP groupC {
    MEMBER user1, user5;
    ACL {
        READ  group;   # 只有groupC成员可读
        WRITE group;   # 只有groupC成员可写
        MODIFY_ACL yes;
    }
}

GROUP groupD {
    MEMBER user2, user3;
    ACL {
        READ  group;   # 只有groupD成员可读
        WRITE group;   # 只有groupD成员可写
        MODIFY_ACL yes;
    }
}

步骤2: 配置 sos.cfg - 设置继承Trigger

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# ========== sos.cfg(客户端配置文件)==========

# 关键配置:让新创建的文件自动继承父目录的Group属性
trigger cdsgdm_file_trigger {
    create {
        attribute Group {
            # SET关键字:将环境变量值赋给属性
            # $SOS_PARENT_Group:SOS自动设置为父目录的Group值
            value SET $SOS_PARENT_Group;
        }
    }
}

# 同样为目录设置继承
trigger dflt_dir_trigger {
    create {
        attribute Group {
            value SET $SOS_PARENT_Group;
        }
    }
}

重要说明

  • SOS_PARENT_Group是SOS预定义的环境变量
  • 根据官方文档 Table 14,SOS会自动设置这个变量
  • 用户不需要手动配置

步骤3: 初始化Library权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. checkin project根目录(自动使用proj_common_grp - 第一个GROUP)
cd /work_area/project
soscmd create .
soscmd ci . -m "Initial project structure"

# 2. 创建并checkin各个library
mkdir libraryA libraryB libraryC libraryD
soscmd create libraryA libraryB libraryC libraryD
soscmd ci libraryA libraryB libraryC libraryD -m "Create libraries"

# 3. 手动设置各library的Group属性
soscmd modattr libraryA -set Group=groupA
soscmd modattr libraryB -set Group=groupB
soscmd modattr libraryC -set Group=groupC
soscmd modattr libraryD -set Group=groupD

步骤4: 重启SOS服务器

1
2
3
# 使配置生效
sosadmin stop_server
sosadmin start_server

工作原理

执行流程

sequenceDiagram
    participant User as 用户
    participant Virtuoso as Virtuoso
    participant SOS as SOS Server
    participant Trigger as Trigger引擎

    User->>Virtuoso: 在libraryA下创建cell1
    Virtuoso->>SOS: soscmd create cell1
    SOS->>SOS: 检查父目录(libraryA)的Group属性 = groupA
    SOS->>Trigger: 设置 $SOS_PARENT_Group = groupA
    Trigger->>Trigger: 执行 value SET $SOS_PARENT_Group
    Trigger->>SOS: 设置 cell1 的 Group = groupA
    SOS-->>User: cell1 创建成功,Group=groupA

权限继承示例

1
2
3
4
5
6
7
8
9
10
11
12
13
project/                              (Group: proj_common_grp, READ: group, WRITE: group)
├── libraryA/                         (Group: groupA, READ: group, WRITE: group)
│   ├── cell1/                        🔄 继承 → Group: groupA
│   │   ├── schematic/                🔄 继承 → Group: groupA
│   │   └── layout/                   🔄 继承 → Group: groupA
│   └── cell2/                        🔄 继承 → Group: groupA
│       └── schematic/                🔄 继承 → Group: groupA
│
└── libraryB/                         (Group: groupB, READ: group, WRITE: group)
    ├── cellA/                        🔄 继承 → Group: groupB
    │   └── layout/                   🔄 继承 → Group: groupB
    └── cellB/                        🔄 继承 → Group: groupB
        └── schematic/                🔄 继承 → Group: groupB

权限检查机制

关键点:SOS会检查整个路径的权限

用户试图绕过权限

1
2
# 假设 user5 不在 groupA 中
soscmd populate project/libraryA/cell1/schematic

SOS的检查顺序(假设READ和WRITE都设置为group):

  1. 检查 project/ 的READ权限 → 需要在proj_common_grp中 ✅ (假设user5在)
  2. 检查 libraryA/ 的READ权限 → 需要在groupA中 ❌ (user5不在groupA中)
  3. 操作在READ权限检查时就被拒绝

结论:READ:group提供了更严格的权限控制,连查看都不允许


验证方法

1. 验证Trigger配置

1
2
3
4
5
6
7
8
9
10
# 查看所有SOS环境变量
cd /work_area/project
soscmd select libraryA
soscmd shell env | sort | grep SOS_PARENT

# 应该看到:
# SOS_PARENT_Group=groupA
# SOS_PARENT_Owner=...
# SOS_PARENT_ReadAccess=world
# SOS_PARENT_WriteAccess=group

2. 测试权限继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 在libraryA下创建测试cell
cd libraryA
mkdir test_cell
soscmd create test_cell
soscmd ci test_cell -m "Test"

# 检查Group属性
soscmd lsattr test_cell | grep Group
# 期望输出: Group: groupA

# 创建子目录测试
cd test_cell
mkdir schematic
soscmd create schematic
soscmd ci schematic -m "Test"
soscmd lsattr schematic | grep Group
# 期望输出: Group: groupA

3. 测试跨组用户

假设 user1 同时在 groupA 和 groupB:

1
2
3
4
5
6
7
8
9
# user1 在 libraryA 创建cell
cd /work_area/project/libraryA
soscmd create cell_in_A
# 期望: Group = groupA

# user1 在 libraryB 创建cell  
cd /work_area/project/libraryB
soscmd create cell_in_B
# 期望: Group = groupB

4. 测试权限控制

假设 user3 只在 groupB:

1
2
3
4
5
6
7
# user3 尝试修改 libraryA 的文件(应该失败)
soscmd co libraryA/cell1/schematic
# 期望: Permission denied

# user3 修改 libraryB 的文件(应该成功)
soscmd co libraryB/cellA/layout
# 期望: Checkout successful

常见问题

Q1: 是否需要为每个用户配置DEFAULT_GROUP?

答:不需要。

  • ✅ 使用trigger后,父目录继承机制会覆盖DEFAULT_GROUP
  • ✅ 大部分用户依赖”第一个GROUP”规则即可
  • ⚠️ 只有特殊需求用户才需要显式配置DEFAULT_GROUP

Q2: 如果用户不在某个library的group中会怎样?

答:既无法读取也无法修改(READ:group配置下)。

根据ACL配置:

  • READ group只有group成员可以读(populate、history、diff等)
  • WRITE group只有group成员可以写(checkout、checkin、tag等)

示例

  • user5不在groupA中 → 无法populate libraryA下的任何文件
  • user5不在groupA中 → 无法checkout libraryA下的任何文件
  • user5必须在groupA的MEMBER列表中才能访问libraryA

注意:如果设置为READ world,则所有人都可以读取,只是不能修改。

Q3: 已经存在的文件会自动更新Group吗?

答:不会。

  • Trigger只在create时生效
  • 已存在的文件需要手动修改:
    1
    
    soscmd modattr filename -set Group=newgroup
    

Q4: 如果父目录没有设置Group属性会怎样?

答:会使用空值或默认值。

建议在设置trigger前,先正确配置所有library的Group属性。

Q5: trigger配置在哪个文件?

答:sos.cfg(客户端配置文件)。

  • 不是 sosd.cfg(服务器配置文件)
  • 路径通常是:$CLIOSOFT_DIR/data/sos.cfg 或项目特定路径

Q6: 什么时候应该使用READ:world vs READ:group?

答:根据安全需求选择。

READ设置 优点 缺点 推荐场景
READ group ✅ 严格权限隔离
✅ libraryA的成员无法看到libraryB
⚠️ 跨library协作需要添加到多个组 🔒 严格安全要求
IP保护、竞品隔离
READ world ✅ 所有人可查看代码
✅ 便于学习和参考
✅ 简化权限管理
⚠️ 无法防止数据泄露
⚠️ 所有library对所有人可见
🔓 开放协作环境
教学、开源项目

推荐配置组合

1
2
3
4
5
6
7
8
9
10
11
# 方案1: 严格隔离(推荐用于生产环境)
ACL {
    READ  group;   # IP保护
    WRITE group;   # 修改权限控制
}

# 方案2: 开放协作(推荐用于学习环境)
ACL {
    READ  world;   # 便于学习参考
    WRITE group;   # 防止误修改
}

建议:生产环境推荐使用 READ group 以保护知识产权。

Q7: 为什么要把proj_common_grp放在第一位?

答:利用”第一个GROUP”规则。

  • 没有trigger时,新文件使用第一个GROUP
  • 设置trigger后,只有project根目录使用第一个GROUP
  • 所有子对象通过继承获得正确的Group

SOS预定义父目录属性

根据官方文档 Table 14,SOS提供以下父目录环境变量:

环境变量 说明
SOS_PARENT_Group 父目录所属的SOS组
SOS_PARENT_Owner 父目录的所有者
SOS_PARENT_ReadAccess 父目录是否可读
SOS_PARENT_WriteAccess 父目录是否可写
SOS_PARENT_Trigger 分配给父目录的TCL trigger
SOS_PARENT_User1 父目录的User1自定义属性值
SOS_PARENT_User2 父目录的User2自定义属性值
SOS_PARENT_User3 父目录的User3自定义属性值
SOS_PARENT_Icon 父目录的自定义图标

所有这些变量都由SOS自动设置,无需手动配置。


参考文档

本指南基于SOS 7.04官方文档:

  1. Groups配置
    Groups.htm
    • DEFAULT_GROUP规则(第150行)
    • 跨组用户示例(第155行)
  2. Trigger定义
    Defining_a_Trigger.htm
    • SET关键字说明(第215-225行)
    • 父目录继承示例(第217-224行)
  3. 预定义属性
    Predefined_Attributes.htm
    • Table 14: 父目录属性(第315-396行)
    • 环境变量访问(第398行)
  4. Group属性设置示例
    Example_Setting_the_Group_Attribute_when_Creating_a_File.htm
    • 跨组问题说明(第111行)
  5. 环境变量说明
    Using_Environment_Variables_in_Actions.htm
    • SOS_OBJ_PATH定义(第206-210行)

版本信息

  • SOS版本: 7.04
  • 文档日期: 2026-02-04
  • 适用场景: Cadence Virtuoso + SOS环境

总结

✅ 推荐方案优势

  1. 零维护成本 - 不需要为每个用户配置DEFAULT_GROUP
  2. 自动继承 - 基于父目录Group自动设置
  3. 安全可靠 - 无法绕过library层级权限
  4. 官方推荐 - SOS文档明确提供示例
  5. 灵活扩展 - 新增library只需设置Group属性

🔑 关键配置

1
2
3
4
5
6
7
8
# sos.cfg - 唯一需要的trigger配置
trigger cdsgdm_file_trigger {
    create {
        attribute Group {
            value SET $SOS_PARENT_Group;
        }
    }
}

📝 配置检查清单

  • sosd.cfg中定义了所有GROUP和ACL
  • sos.cfg中添加了继承trigger
  • 重启了SOS服务器
  • 设置了各library的Group属性
  • 使用测试用户验证了权限继承
  • 验证了跨组用户的行为
  • 测试了权限控制(读/写分离)

配置完成后,您的SOS环境将实现真正的基于Library的自动权限控制! 🎉