Open achimnol opened 2 years ago
One idea by @fregataa:
groups("groupY").vfolder_host_permissions = {"storage1": {"access": "rw", "allow_override": True}}
)Another way is to split the permission level ("ro" or "rw") into fine-grained set of 'atomic' actions like generic RBAC and merge them by taking the union sets:
domains("domainA").vfolder_host_permissions = {"storge1": ["mount"]}
groups("groupX").vfolder_host_permissions = {"storage1": ["mount", "create-vfolder"]}
keypair_resource_policies("researchers").vfolder_host_permissions = {"storage1": ["mount", "create-vfolder", "delete-vfolder"]}
-> merged result: {"storage1": ["mount", "create-vfolder", "delete-vfolder"]}
domains("domainA").vfolder_host_permissions = {"storge1": ["mount", "create-vfolder"]}
groups("groupX").vfolder_host_permissions = {"storage1": ["mount"]}
keypair_resource_policies("researchers").vfolder_host_permissions = {}
-> merged result: {"storage1": ["mount", "create-vfolder"]}
In this case, it is no longer needed to store these information as columns of existing object entities but as a separate RBAC table for improved caching.
Here is a good discussion about RBAC and ReBAC, with the "role explosion" issue, presented in PyCon KR (Korean): https://youtu.be/DXf_rQtpLZQ
Things to think about:
In this PR's design, we don't have a separate "role" property of an ACL entry but the subject itself may have a collective persona/identity (e.g., a domain applies to all of its users) and the caller of rule checker should provide the full list of multiple, contextual personas.
There are some user scenarios that admins want to allow a specific project X members to mount read-only vfolders from the vfolder host A while they can freely create/use vfolders in the vfolder host B—and they want to prohibit the project X member's vfolder creation on the vfolder host A at the same time.
Currently, we only have the per-vfolder access control table (
vfolder_permissions
) and the access permission to vfolder hosts as a simple boolean set (merged fromdomains
,groups
, andkeypair_resource_policies
). As such, it is impossible to define a "read-only" permission to a specific vfolder host like that users may mount vfolders in the host but may not create new vfolders there.The problem
Since we have
allowed_vfolder_hosts
defined in 3 different objects (domains
,groups
, andkeypair_resource_policies
), we need to first define how to merge them when each object has different properties like below:In the above cases, should what access permission be applied?
Even if we extend the problem scope to a generic RBAC, the same issue arises with multiple subjects sharing the same target object and allowed action lists.
Design (2022/09/30)
ACL checks will be done in the server-side, while the configuration APIs should be exposed to the control panel and webui.
ai.backend.manager.models.acl
acl
table schemaid: uuid
subject_type: str
subject_id: uuid
(no explicit foreign key yet)target_type: str
target_id: uuid
(no explicit foreign key yet)allowed_actions: list[str]
blocked_actions: list[str]
target_type
: "vfolder_host"ai.backend.manager.manager.models.acl
modulecheck_acl(root_ctx, subject_type, subject_id, target_type, target_id, action) -> bool
acl
tablebegin_readonly()
for better concurrency in the databasecheck_merged_acl(root_ctx, subjects: list[tuple[subject_type, subject_id]], target_type, target_id, action) -> bool
merged_allowed_actions = {take the union of allowed_actions of the all matched rows}
merged_blocked_actions = {take the union of blocked_actions of the all matched rows}
result = action in (allowed_actions - blocked_actions)
begin_readonly()
for better concurrency in the databaseget_available_actions(target_type) -> list[str]
create_vfolder
delete_vfolder
mount_vfolder
list_vfolder
GET /acl/actions?target_type={}
to query the available action list based onget_available_actions()
acl
table.domains.allowed_vfolder_hosts
,groups.allowed_vfolder_hosts
,keypair_resource_policies.allowed_vfolder_hosts
to theacl
table using the default: all actions are allowed for each record. Drop the old columns during the alembic migration.check_acl()
andcheck_merged_acl()
to the required places including session creation routines (mount_vfolder
), and replace all invocations toget_allowed_vfolder_hosts_by_*()
functions inai.backend.manager.models.vfolder
with the newcheck_merged_acl()
function, etc.domains
table to allow reference fromacl.subject_id
.vfolder_hosts
table defined inai.backend.manager.models.storage
acl.target_id
can refer them.config
APIs to use the new GraphQL APIs implemented above.Follow-ups
acl
table should be logged in the audit logs as well.