权限约定
历史背景
我们在 GitLab 中使用 DeclarativePolicy 框架进行授权,这使得添加新权限变得简单直接。直到 2024 年,关于何时引入新权限以及如何命名它们,一直没有明确的指导。这种缺乏指导是权限数量变得难以管理的重要原因。
本文档旨在提供以下指导:
- 何时引入新权限,何时重用现有权限
- 如何命名新权限
Policy类中应该包含什么,不应该包含什么
引入新权限
仅在绝对必要时才引入新权限。始终先尝试使用现有权限。例如,当我们已经有了 read_issue 权限时,就不需要 read_issue_description 权限,因为两者都需要相同的角色。同样,既然已经有 create_pipeline 权限,我们就不需要 create_build 权限。
引入新权限时,始终尝试遵循命名约定。尝试创建通用权限,而不是特定权限。例如,添加 create_member_role 权限比添加 create_member_role_name 更好。如果您不确定,请咨询 Govern:Authorization 团队 的后端工程师,寻求建议或例外批准。
命名权限
我们的目标是让所有权限都遵循一致的模式:action_resource(_subresource)。资源和子资源应该始终使用单数形式,并与所操作的对象相匹配。例如,如果某个操作是针对 Project 进行的评估,那么权限名称的格式应该是 action_project。此外,我们旨在限制使用的操作以确保清晰度。首选操作包括:
create- 用于创建对象。例如,create_issue。read- 用于读取对象。例如,read_issue。update- 用于更新对象。例如,update_issue。delete- 用于删除对象。例如,delete_issue。push和download- 这些是文件相关权限的特定操作。在提供合理理由后,可以允许使用其他行业术语。
我们认识到这组操作是有限的,并不适用于每个功能。以下是一些虽然必要但应重新表述以符合上述约定的操作:
approve- 例如,approve_merge_request。虽然approve暗示的角色低于manage,但可以重新表述为create_merge_request_approval。
首选操作
- 优先使用
create而不是build或import - 优先使用
read而不是access - 优先使用
push而不是upload - 优先使用
delete而不是destroy
例外情况
如果您认为需要不遵循这些约定的新权限,请咨询 Govern:Authorization 团队。我们总是乐于讨论,这些指导原则旨在让工程师的工作更轻松,而不是使其复杂化。
Policy 类中应包含的内容
角色
Policy 类应包含对预定义角色和自定义角色的检查。
示例:
rule { developer } # 静态角色检查
rule { can?(:developer_access) } # 某些类中使用的另一种方法
rule { custom_role_enables_read_dependency } # 自定义角色检查与当前用户相关的检查
包含根据当前用户与对象的关系而变化的检查,例如作为指派人或作者。
示例:
rule { is_author }.policy do
enable :read_note
enable :update_note
enable :delete_note
end