Dev,
Summary: I want to put in an email my thoughts on how group-based authorization
will work and how we can migrate to it from our current role-based approach.
Some of this work has already been done, some of this represents some
re-thinking on how to do the migration, and some of this is work that has yet
to be done. I think it will be useful to spell out the technical details and
get them in one place and I also look forward to your feedback. The basic
approach, that I expand upon below, is to migrate by creating “Gateway Users”,
“Admins” and “Read Only Admins” groups out of the current users that have those
roles (‘gateway-user’, ‘admin’, ‘admin-read-only’). Gateway resources (e.g.,
Application Deployments) will be shared with those groups as appropriate. The
“Admins” and “Read Only Admins” groups will be given some special treatment in
the API server: when a new gateway resource is created, the “Admins” group will
be automatically granted WRITE access and the “Read Only Admins” group will be
granted READ access. Post-migration, gateway admins will need to add a new
user to the “Gateway Users” group to give that user access to resources, but
that is up to the gateway admin and the gateway admin has the flexibility to
create and utilize groups as needed.
Data model changes:
* new thrift model, GatewayGroups:
struct GatewayGroups {
string gatewayId,
string adminGroupId,
string adminReadOnlyGroupId
}
Migration:
* The migration script will need to read in role information from Keycloak for
each user. Users who have the ‘gateway-user’ role be put into a “Gateway
Users” group, users with the ‘admin’ role go in the “Admins” group and users
with the ‘admin-read-only’ role go into the “Read Only Admins” group. For each
of these groups, the admin user (as identified by the username in the
GatewayResourceProfile.identityServerPwdCredToken) will be the owner and all
users in the “Admins” group will be added as group managers of the “Admins”,
“Read Only Admins” and “Gateway Users” groups.
* Populate the GatewayGroups model with the ids of the “Admins” and “Read Only
Admins” groups and persist
* Create a GroupResourceProfile out of the existing GatewayResourceProfile and
share it with “Gateway Users” with READ permission, with “Admins” with WRITE
permission and with “Read Only Admins” with READ permission
* For all Application Deployments share with “Gateway Users” with READ
permission, share with “Admins” with WRITE permission and with “Read Only
Admins” with READ permission.
* For all Projects and Experiments, share with “Admins” with WRITE permission
and with “Read Only Admins” with READ permission.
Enforcing group-based access:
* For Projects, Experiments, GroupResourceProfile and Application Deployments,
which are entities in the sharing registry, their create/read/update/delete API
methods should query the sharing registry to determine if the user has the
appropriate access before serving the request.
* When any user creates a new sharing registry managed entity, for example a
new Project, the API server will automatically give WRITE permission on that
entity to the “Admins” group. Likewise, READ permission will be given to the
“Read Only Admins” group.
* On the frontend, it’s no longer necessary to hide certain views from a user
based on their role. A UI for viewing/editing GroupResourceProfiles, for
example, would show the user only those GroupResourceProfile entities for which
the user has READ permission. Likewise the UI will only allow the user to edit
GroupResourceProfile entities for which the user has WRITE permission.
* However, not all the resources in the registry are yet entities in the
sharing registry so we need a way to authorize who can
create/read/update/delete those resources. The following are, I think, stopgap
measures until we convert all registry resources to being sharing registry
managed entities:
* For resources that aren’t yet entities in the sharing registry, we can
still do API method access control in the KeycloakSecurityManager by first
fetching the groups that a user belongs to. If a user is in the “Admins” group
then that user can access methods reserved for admins. If the user is in the
“Read Only Admins” group then that user can access methods reserved for
read-only admins.
* Likewise, on the Django side, when a user logs in, the Django portal will
retrieve whether the user is in the “Admins” group and the “Read Only Admins”
group and make this information available to views. For resources that are not
managed by the sharing registry, we can implement UI logic to only show the
view for that resource if the user is in the “Admins” or “Read Only Admins”
group. This is roughly analogous to how the current PGA restricts access to
views via roles.
The “everyone” group:
* Given the above, I no longer think we need an “everyone” group that is kept
up to date in the sharing registry to include every user of the gateway. The
“Gateway Users” group that I discuss above takes the place of the “everyone”
group. It will be up to the gateway admin to manage the “Gateway Users” group.
When new gateways are created:
* Create the admin user and the “Admins” group with the admin user as the owner
of the group and its only member. Also create an “Read Only Admins” group with
the admin user as the owner.
* Populate the GatewayGroups model with the ids of the “Admins” and “Read Only
Admins” groups and persist
I tried to balance thoroughness with succinctness above so if anything above
isn’t clear or needs further clarification please don’t hesitate to ask. I look
forward to your feedback.
Thanks,
Marcus