Feature #20640
Updated by Peter Amstutz 7 months ago
Requested by user:
They would like to synchronize permissions set in Arvados to another system. This system does not support OpenID, users will log in with LDAP and they can do a mapping between username and arvados uuid. However it is not convenient to generate and use Arvados tokens in order to do permission lookups on the fly.
Proposed solution is to have an admin API where the client can send a list of users and/or projects and get back the permissions associated with each user and/or project. This would make it possible to write a policy plug-in that queries permissions for a given user or project from Arvados on demand applies them to the 3rd party system.
Design sketch:
Implement a "list" API that behaves similarly to other list APIs, supporting our filter syntax. It return a list of items with the user uuid, target uuid, and permission level.
The permission level is numeric internally but it might make sense to transform it to can_read, can_write or can_manage for the external API -- because if we ever want to tweak the implementation or introduce new types of permission, it would be better not to be committed to a specific numeric representation of permission.
Since it is read only and rows don't have standalone identifiers, the endpoint would only support "list" method and not "get" or anything else.
It should be usable by admins only -and regular users.-
Admins have unrestricted access.
-Regular users are limited to permissions for targets which they have "manage" access (this includes "self" so they can always see their own permissions), implemented as a self-join on the permission table.-
Detailed design:
endpoint: /arvados/v1/materialized_permissions
User accessing the endpoint must be admin, otherwise returns 403.
|Field|Type|Description|
|user_uuid|string|user account that has permission|
|target_uuid|string|target of the permission|
|perm_level|string|one of "can_read", "can_write" or "can_manage"|
method:
*list*
|Argument|Type|Description|
|limit|integer|same as other API methods|
|count|string|only supports 'none'|
|order|array|same as other API methods|
|select|array|same as other API methods|
|filters|array|same as other API methods|
* perm_level isn't indexed, so we should disallow filtering or ordering on it.
* I'm omitting "offset" because it is not needed for keyset paging
* several fields are of limited use, but I propose including them here so that the Python keyset_list_all method can be used to query permissions.
** keyset_list_all assumes the the record has a 'uuid' field, it should be tweaked to allow specifying an alternate tiebreaker field