访问控制 Cluster(AccessControl)
Cluster ID: 0x001F |
所在 Endpoint: 固定在 Endpoint 0(根端点)
AccessControl 是 Matter 设备的权限管理中枢 —— 决定了「谁」可以对「哪些资源」执行「什么操作」。
每台 Matter 设备都必须在 Endpoint 0 上实现此 Cluster。
它没有命令(Command),所有配置通过直接写入 ACL 属性完成。
ACL 按 Fabric 隔离 —— 每个 Fabric(控制域)维护独立的权限条目列表,互不干扰。 Commissioning 完成后,设备会自动为 Commissioner 创建一条 Administer 权限条目, 这是后续所有操作的基础。如果 ACL 配置错误,可能导致设备「失联」,只能通过恢复出厂设置解决。
属性详解
AccessControl Cluster 的属性分为两组:ACL 数据(可读写的权限配置)和容量限制(只读的设备能力上限)。 点击下方汇总表中的属性 ID 可跳转到对应的详细说明。
| ID | 名称 | 类型 | 分组 | 说明 |
|---|---|---|---|---|
0x0000 |
ACL | list<AccessControlEntryStruct> | ACL 数据 | 权限条目列表(核心属性) |
0x0001 |
Extension | list<AccessControlExtensionStruct> | ACL 数据 | 厂商自定义扩展数据 |
0x0002 |
SubjectsPerAccessControlEntry | uint16 | 容量限制 | 每条 ACL 最多包含多少个 Subject |
0x0003 |
TargetsPerAccessControlEntry | uint16 | 容量限制 | 每条 ACL 最多包含多少个 Target |
0x0004 |
AccessControlEntriesPerFabric | uint16 | 容量限制 | 每个 Fabric 最多有多少条 ACL |
0x0005 |
CommissioningARL | list<CommissioningAccessRestrictionEntryStruct> | 访问限制 | Commissioning 阶段的访问限制列表 |
0x0006 |
ARL | list<AccessRestrictionEntryStruct> | 访问限制 | 运行时访问限制列表 |
ACL 数据(0x0000, 0x0001)
权限条目和扩展数据,这是 AccessControl 的核心可写属性。
| ID | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0000 |
ACL(访问控制列表) | list<AccessControlEntryStruct> | 设备的权限条目列表。每个条目定义一条「谁可以做什么」的规则。 按 Fabric 隔离 —— 每个 Fabric 只能读写自己的条目。 写入时必须整体替换(不支持增量修改单条),需要 Administer 权限。 结构体详情见 AccessControlEntryStruct |
0x0001 |
Extension(扩展数据) | list<AccessControlExtensionStruct> | 厂商自定义的权限扩展。每条包含一个不超过 128 字节的 TLV 编码数据。 标准 Matter 实现通常不使用此字段。需要 EXTS 特性。 写入需要 Administer 权限 |
写入 ACL 是整体替换操作 —— 你必须把完整的条目列表一次性写入,不能只修改其中一条。 如果新写入的列表中没有包含自己的 Administer 条目,你将永久失去对设备的管理权限, 只能恢复出厂设置。建议写入前先读取当前 ACL,在其基础上修改,再整体写回。
容量限制(0x0002 ~ 0x0004)
只读属性,描述设备对 ACL 条目的容量上限。写入 ACL 前应先读取这些值,避免超出设备能力。
| ID | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0002 |
SubjectsPerAccessControlEntry | uint16 | 单条 ACL 中 subjects 列表的最大长度。最小值为 4 |
0x0003 |
TargetsPerAccessControlEntry | uint16 | 单条 ACL 中 targets 列表的最大长度。最小值为 3 |
0x0004 |
AccessControlEntriesPerFabric | uint16 | 每个 Fabric 可以拥有的 ACL 条目总数上限。最小值为 4(至少容纳一条管理员条目和几条用户条目) |
大多数设备的典型值:SubjectsPerAccessControlEntry = 4,TargetsPerAccessControlEntry = 3, AccessControlEntriesPerFabric = 4。资源受限的设备(如电池供电传感器)可能更小, 开发时务必先读取这三个值再做规划。
访问限制(0x0005, 0x0006)— MNGD 特性
Access Restriction List(ARL)是 MNGD(Managed Device)特性引入的高级功能, 允许设备制造商限制某些资源的访问权限,即使 ACL 允许也不行。 普通设备通常不实现此特性。
| ID | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0005 |
CommissioningARL | list | Commissioning 阶段的访问限制。设备在配网时告知 Commissioner 哪些资源受限。需要 MNGD 特性 |
0x0006 |
ARL | list | 运行时的访问限制列表。即使 ACL 授予了权限,ARL 中列出的资源仍然不可访问。需要 MNGD 特性 |
结构体详解
AccessControlEntryStruct —— 权限条目
ACL 的核心数据结构。每条记录定义了一组主体(谁)在一组目标(哪些资源)上拥有的权限级别。
| 字段 | 类型 | 说明 |
|---|---|---|
| Privilege | AccessControlEntryPrivilegeEnum | 授予的权限级别(View / Operate / Manage / Administer) |
| AuthMode | AccessControlEntryAuthModeEnum | 认证方式(PASE / CASE / Group) |
| Subjects | list<subject-id> / null |
允许访问的主体列表(Node ID 或 Group ID)。
null 表示同 Fabric 下的所有节点都可以访问
|
| Targets | list<AccessControlTargetStruct> / null |
允许访问的目标范围。
null 表示设备上所有 Endpoint 和 Cluster 都可以访问
|
| FabricIndex | fabric-idx | 此条目所属的 Fabric 索引(由设备自动填充,不需要手动指定) |
null 在 ACL 中表示「不限制」而非「拒绝」。
Subjects = null 意味着同 Fabric 内所有节点都匹配;
Targets = null 意味着设备上所有 Endpoint 和 Cluster 都在范围内。
默认的管理员条目通常设置 Targets = null,因为管理员需要访问一切。
AccessControlTargetStruct —— 访问目标
定义 ACL 条目允许访问的具体资源范围。三个字段中至少指定一个,未指定的字段表示不限制。
| 字段 | 类型 | 说明 |
|---|---|---|
| Cluster | cluster-id / null | 限定到特定 Cluster。null = 不限制 Cluster |
| Endpoint | endpoint-no / null | 限定到特定 Endpoint。null = 不限制 Endpoint |
| DeviceType | devtype-id / null | 限定到特定设备类型。null = 不限制设备类型 |
Endpoint 和 DeviceType 不能同时指定 —— 要么按 Endpoint 编号精确匹配,
要么按设备类型模糊匹配。如果两个都设了值,设备会拒绝此条目。
最常用的方式是只指定 Endpoint。
AccessControlExtensionStruct —— 扩展数据
厂商自定义的扩展结构,需要启用 EXTS 特性。标准 Matter 开发中很少用到。
| 字段 | 类型 | 说明 |
|---|---|---|
| Data | octstr(最大 128 字节) | TLV 编码的扩展数据,内容由厂商定义 |
| FabricIndex | fabric-idx | 所属 Fabric 索引 |
枚举类型
AccessControlEntryPrivilegeEnum —— 权限级别
定义 ACL 条目授予的权限等级。权限是包含关系 —— 高级别权限自动包含低级别权限的所有能力。 例如 Operate 包含 View 的能力,Administer 包含所有能力。
Administer ⊃ Manage ⊃ Operate ⊃ View。 给用户分配 Operate 权限后,他自动拥有 View 的能力,不需要再单独加一条 View 的 ACL。
AccessControlEntryAuthModeEnum —— 认证方式
指定 ACL 条目匹配的认证方式。不同认证方式决定了 Subjects 字段中 ID 的含义。
事件(Events)
AccessControl Cluster 通过事件记录 ACL 的变更历史。每次写入 ACL 或 Extension 属性时, 设备都会生成对应的事件。这些事件对安全审计和故障排查非常重要。
| ID | 名称 | 优先级 | 说明 |
|---|---|---|---|
0x00 |
AccessControlEntryChanged | Info | ACL 条目发生变更(新增、修改或删除)。事件数据包含变更类型(Changed/Added/Removed)、最新条目内容、操作者 Node ID 和 Fabric 索引 |
0x01 |
AccessControlExtensionChanged | Info | Extension 扩展数据发生变更。结构与上一个事件类似,记录了扩展数据的增删改。需要 EXTS 特性 |
0x02 |
FabricRestrictionReviewUpdate | Info | Fabric 访问限制审核更新。当 ARL 规则变化时触发。需要 MNGD 特性 |
在生产环境中,建议订阅 AccessControlEntryChanged 事件。
如果有人意外修改了 ACL(比如误删了管理员条目),可以通过事件记录快速定位问题。
Feature 位图
AccessControl Cluster 通过 FeatureMap(0xFFFC)声明设备支持的扩展能力:
大多数消费级设备的 FeatureMap 为 0x0000(不启用任何特性)。
EXTS 用于有自定义权限需求的厂商设备,MNGD 用于云平台管理的设备。
示例数据
一台典型智能灯在 Commissioning 完成并添加了一条用户权限后的 AccessControl Cluster 读取结果:
{
// --- ACL 权限条目(列表,每个 Fabric 独立维护)---
"0x0000": [ // ACL — AccessControlEntryStruct 列表
{
"privilege": 5, // Administer(管理员)
"authMode": 2, // CASE 认证
"subjects": [112233], // 绑定到 Commissioner Node ID
"targets": null, // null = 可访问所有 Endpoint 和 Cluster
"fabricIndex": 1
},
{
"privilege": 3, // Operate(操作权限)
"authMode": 2, // CASE 认证
"subjects": null, // null = 同 Fabric 下所有节点
"targets": [ // 限定可访问的范围
{ "cluster": null, "endpoint": 1, "deviceType": null }
],
"fabricIndex": 1
}
],
// --- 容量限制 ---
"0x0002": 4, // SubjectsPerAccessControlEntry = 4
"0x0003": 3, // TargetsPerAccessControlEntry = 3
"0x0004": 4 // AccessControlEntriesPerFabric = 4
}
第一条 ACL(Privilege = 5, Administer)是 Commissioning 时自动创建的,绝对不能删除。 添加用户权限时,先读取完整的 ACL 列表,追加新条目,再整体写回。 注意 Extension(0x0001)只有在 FeatureMap 包含 EXTS 时才存在。
常见场景
场景 1:默认管理员 ACL(Commissioning 后自动生成)
设备完成 Commissioning 后,会自动为 Commissioner(通常是手机 App 或 Hub)创建一条管理员权限条目:
- Privilege = Administer(5)—— 最高权限
- AuthMode = CASE(2)—— 基于证书的安全认证
- Subjects = [Commissioner 的 Node ID] —— 只有这个控制器
- Targets = null —— 可访问设备上的一切
这条 ACL 是后续所有操作的基础。如果误删了它,设备将无法被控制,只能恢复出厂设置。
场景 2:为家庭成员添加操作权限
管理员想让家庭成员(另一台手机)可以控制灯和开关,但不能修改设备配置:
- 读取当前 ACL 列表(确保包含管理员条目)
- 追加一条新条目:
- Privilege = Operate(3)
- AuthMode = CASE(2)
- Subjects = [家庭成员的 Node ID]
- Targets = [{ endpoint: 1 }](只允许操作功能端点)
- 将包含管理员条目和新条目的完整列表写入 ACL
写入后,家庭成员可以开关灯,但不能修改 ACL、设备名称或上电行为等管理级配置。
场景 3:设置 Group 组播权限
需要通过组播(Multicast)同时控制一组灯,例如「客厅全部灯」:
- 先为每盏灯配置 Group Key(通过 GroupKeyManagement Cluster)
- 在每盏灯的 ACL 中添加一条 Group 权限:
- Privilege = Operate(3)
- AuthMode = Group(3)
- Subjects = [Group ID]
- Targets = [{ endpoint: 1 }]
- 之后向该 Group 发送 OnOff 命令,所有灯同时响应
Group 模式下的权限级别最高只能到 Operate,不允许通过 Group 执行管理或 Administer 操作。
场景 4:排查「操作被拒绝」问题
当设备返回 UNSUPPORTED_ACCESS 或 ACCESS_DENIED 错误时,排查步骤:
- 读取设备的 ACL(0x0000),确认是否有匹配当前 Node 的条目
- 检查匹配条目的 Privilege 是否足够(例如写入属性需要 Manage,修改 ACL 需要 Administer)
- 检查 AuthMode 是否匹配(CASE 认证的节点不会匹配 Group 类型的 ACL 条目)
- 检查 Targets 是否覆盖了目标 Endpoint 和 Cluster
- 确认容量限制 —— 读取 SubjectsPerAccessControlEntry 和 AccessControlEntriesPerFabric,看是否超限