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权限机制
核心概念
- Group属性:每个文件/目录都有一个Group属性,决定了访问权限
- ACL(访问控制列表):定义READ、WRITE和MODIFY_ACL权限
- DEFAULT_GROUP:用户的默认组(可选配置)
READ和WRITE权限说明
根据官方文档第114-115行:
| 权限类型 | 说明 | 可选值 |
|---|---|---|
| READ | 允许用户populate工作区文件,执行history、diff等只读命令 |
owner / group / world |
| WRITE | 允许用户checkout、修改文件,执行tag、snapshot、modattr等写操作 |
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):
- 检查
project/的READ权限 → 需要在proj_common_grp中 ✅ (假设user5在) - 检查
libraryA/的READ权限 → 需要在groupA中 ❌ (user5不在groupA中) - 操作在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官方文档:
- Groups配置
Groups.htm- DEFAULT_GROUP规则(第150行)
- 跨组用户示例(第155行)
- Trigger定义
Defining_a_Trigger.htm- SET关键字说明(第215-225行)
- 父目录继承示例(第217-224行)
- 预定义属性
Predefined_Attributes.htm- Table 14: 父目录属性(第315-396行)
- 环境变量访问(第398行)
- Group属性设置示例
Example_Setting_the_Group_Attribute_when_Creating_a_File.htm- 跨组问题说明(第111行)
- 环境变量说明
Using_Environment_Variables_in_Actions.htm- SOS_OBJ_PATH定义(第206-210行)
版本信息
- SOS版本: 7.04
- 文档日期: 2026-02-04
- 适用场景: Cadence Virtuoso + SOS环境
总结
✅ 推荐方案优势
- 零维护成本 - 不需要为每个用户配置DEFAULT_GROUP
- 自动继承 - 基于父目录Group自动设置
- 安全可靠 - 无法绕过library层级权限
- 官方推荐 - SOS文档明确提供示例
- 灵活扩展 - 新增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和ACLsos.cfg中添加了继承trigger- 重启了SOS服务器
- 设置了各library的Group属性
- 使用测试用户验证了权限继承
- 验证了跨组用户的行为
- 测试了权限控制(读/写分离)
配置完成后,您的SOS环境将实现真正的基于Library的自动权限控制! 🎉