What would you like to see implemented?
RoleAssignment should be able to grant a role on the system scope, not only on a project or a domain. This is the Keystone call behind openstack role add --system all --user <user> <role> (PUT /v3/system/users/{user_id}/roles/{role_id}, plus the group variant PUT /v3/system/groups/{group_id}/roles/{role_id}).
Today RoleAssignmentResourceSpec requires exactly one of projectRef or domainRef, so a system role assignment cannot be expressed.
A possible API, following Keystone's own representation ("scope": {"system": {"all": true}} in responses, scope.system=all as a list filter):
apiVersion: openstack.k-orc.cloud/v1alpha1
kind: RoleAssignment
metadata:
name: glance-system-reader
spec:
cloudCredentialsRef:
cloudName: openstack
secretName: openstack-clouds
managementPolicy: managed
resource:
roleRef: reader
userRef: glance
system: all
spec.resource.system: optional, an enum whose only value is all, the only system Keystone has. The existing rule becomes "exactly one of projectRef, domainRef or system".
spec.import.filter.system: the same selector, for imports.
status.resource.system: all when the observed assignment is system-scoped.
An enum rather than a bool keeps the field's shape if Keystone ever gets more than one system, and it matches the scope.system=all filter. A different shape is fine with us if you prefer one.
gophercloud v2.14.0, which ORC already uses, supports all of this:
roles.AssignOpts.System and roles.UnassignOpts.System
roles.ListAssignmentsOpts.ScopeSystem = "all"
roles.RoleAssignment.Scope.System.All on the results
The change stays inside internal/controllers/roleassignment:
buildListOpts gains the system filter.
CreateResource gets a third scope case. It has no ORC dependency to wait for.
DeleteResource passes System to UnassignOpts, taken from the observed scope.
- The status writer records the system scope.
Keystone's default policy lets a project-scoped admin create system grants: identity:create_system_grant_for_user is admin_required with scope types system and project. The credentials ORC already uses are therefore enough.
Additional information
A service that enforces Keystone unified limits through oslo.limit needs its service user to hold reader on the system, for two reasons:
GET /v3/limits returns only the caller's own project's limits unless the token is system-scoped. A project-scoped service token never sees the per-project limits it is supposed to enforce.
- oslo.limit finds the service's own endpoint through
list_services and list_endpoints, which require admin or a system reader.
Glance's install guide therefore has operators run openstack role add --user glance --user-domain Default --system all reader (Configure quotas). With RegisteredLimit (#782) and Limit (#868) in ORC, this role assignment is the last piece needed to set up unified limits for a service declaratively. We need it for Glance quotas in CobaltCore (C5C3/cobaltcore#732), and we are happy to implement it.
Link to reference documentation
https://docs.openstack.org/api-ref/identity/v3/index.html#assign-a-system-role-to-a-user
What would you like to see implemented?
RoleAssignmentshould be able to grant a role on the system scope, not only on a project or a domain. This is the Keystone call behindopenstack role add --system all --user <user> <role>(PUT /v3/system/users/{user_id}/roles/{role_id}, plus the group variantPUT /v3/system/groups/{group_id}/roles/{role_id}).Today
RoleAssignmentResourceSpecrequires exactly one ofprojectRefordomainRef, so a system role assignment cannot be expressed.A possible API, following Keystone's own representation (
"scope": {"system": {"all": true}}in responses,scope.system=allas a list filter):spec.resource.system: optional, an enum whose only value isall, the only system Keystone has. The existing rule becomes "exactly one ofprojectRef,domainReforsystem".spec.import.filter.system: the same selector, for imports.status.resource.system:allwhen the observed assignment is system-scoped.An enum rather than a bool keeps the field's shape if Keystone ever gets more than one system, and it matches the
scope.system=allfilter. A different shape is fine with us if you prefer one.gophercloud v2.14.0, which ORC already uses, supports all of this:
roles.AssignOpts.Systemandroles.UnassignOpts.Systemroles.ListAssignmentsOpts.ScopeSystem = "all"roles.RoleAssignment.Scope.System.Allon the resultsThe change stays inside
internal/controllers/roleassignment:buildListOptsgains the system filter.CreateResourcegets a third scope case. It has no ORC dependency to wait for.DeleteResourcepassesSystemtoUnassignOpts, taken from the observed scope.Keystone's default policy lets a project-scoped admin create system grants:
identity:create_system_grant_for_userisadmin_requiredwith scope typessystemandproject. The credentials ORC already uses are therefore enough.Additional information
A service that enforces Keystone unified limits through oslo.limit needs its service user to hold
readeron the system, for two reasons:GET /v3/limitsreturns only the caller's own project's limits unless the token is system-scoped. A project-scoped service token never sees the per-project limits it is supposed to enforce.list_servicesandlist_endpoints, which require admin or a system reader.Glance's install guide therefore has operators run
openstack role add --user glance --user-domain Default --system all reader(Configure quotas). WithRegisteredLimit(#782) andLimit(#868) in ORC, this role assignment is the last piece needed to set up unified limits for a service declaratively. We need it for Glance quotas in CobaltCore (C5C3/cobaltcore#732), and we are happy to implement it.Link to reference documentation
https://docs.openstack.org/api-ref/identity/v3/index.html#assign-a-system-role-to-a-user