Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Domain Admin rights for SCS IaaS Customers #184

Open
fkr opened this issue Oct 12, 2022 · 6 comments
Open

Domain Admin rights for SCS IaaS Customers #184

fkr opened this issue Oct 12, 2022 · 6 comments
Assignees
Labels
epic Issues that are spread across multiple sprints IaaS Issues or pull requests relevant for Team1: IaaS IAM Issues or pull requests relevant for SIG IAM SCS-VP10 Related to tender lot SCS-VP10

Comments

@fkr
Copy link
Member

fkr commented Oct 12, 2022

SCS Clouds should provide a way to grant Domain Manager rights to SCS Customers. To avoid conflict with the unscoped admin role in OpenStack we want to refer to this as "Domain Manager" (domain-manager)

Action Items

@fkr fkr added IaaS Issues or pull requests relevant for Team1: IaaS epic Issues that are spread across multiple sprints IAM Issues or pull requests relevant for SIG IAM labels Oct 12, 2022
@garloff garloff changed the title Domain Admin rights for SCS Customers Domain Admin rights for SCS IaaS Customers Feb 15, 2023
@tibeer tibeer mentioned this issue Mar 29, 2023
@reqa
Copy link

reqa commented Jun 20, 2023

I found https://bugs.launchpad.net/keystone/+bug/1783659 , I guess that's what this issue is about. It references https://specs.openstack.org/openstack/keystone-specs/specs/keystone/ongoing/policy-goals-and-roadmap.html

Test confirms that an admin (domain and/or project) can see all other domains:

# Test domain scope visibility on CLI as in
#     https://bugs.launchpad.net/keystone/+bug/1783659
## Setup:
### Domain admin:
openstack --os-cloud admin domain create TestDomain
openstack --os-cloud admin user create --domain TestDomain --password password TestDomainAdmin1
openstack --os-cloud admin role add --domain TestDomain --user TestDomainAdmin1 admin
### Project admin:
openstack --os-cloud admin user create --domain TestDomain --password password TestDomainAdmin2
openstack --os-cloud admin project create --domain TestDomain TestDomainProject
openstack --os-cloud admin role add --project-domain TestDomain --project TestDomainProject --user TestDomainAdmin2 admin

## Test with domain admin:
openstack --os-auth-url https://api.testbed.osism.xyz:5000/v3 \
                    --os-username TestDomainAdmin1 --os-user-domain-name TestDomain \
                    --os-auth-type password --os-password password \
                    --os-domain-name TestDomain \
                    token issue
### "Domain Admin" sees all domains with this "domain scoped" token
### (see https://docs.openstack.org/keystone/latest/admin/tokens-overview.html):
openstack --os-endpoint https://api.testbed.osism.xyz:5000/v3 --os-token <$OS_TOKEN>  domain list

## Test with project admin:
openstack --os-auth-url https://api.testbed.osism.xyz:5000/v3 \
                    --os-username TestDomainAdmin2 --os-user-domain-name TestDomain \
                    --os-auth-type password --os-password password \
                    --os-project-name TestDomainProject --os-project-domain-name TestDomain \
                    token issue
### "Project Admin" sees all domains with this "project scoped" token
### (see https://docs.openstack.org/keystone/latest/admin/tokens-overview.html):
openstack --os-endpoint https://api.testbed.osism.xyz:5000/v3 --os-token <$OS_TOKEN> domain list

The interesting point is, that this seems to be independent of the question of domain or not domain. The point is the admin role. Even if you just use projects. But yes, in that sense domains don't seem to offer additional separation currently.

@markus-hentsch
Copy link

markus-hentsch commented Jul 27, 2023

Keystone policy-based domain admin concept

As documented before, OpenStack does not properly scope the "admin" role, making domain separation questionable for self-service approaches using that role.

As an alternative, using policy adjustments in Keystone, a new role could be established that acts as a counterpart to the "admin" role but scoped within domains. Below I have documented a prototype of such approach that I tried out with that goal in mind. This approach implements the following key changes:

  • it introduces a role named "domain-admin-role" in Keystone
    • the role is intended to be assigned to users within a domain by the cloud admin with "openstack role add --user $USER_NAME --domain $DOMAIN_NAME domain-admin-role"
    • users with that role are domain admins within a domain that can manage users, project and role assignments
  • it introduces API policy file changes to Keystone (i.e. policy.yaml, see https://docs.openstack.org/keystone/latest/configuration/policy.html)
    • domain admins may create, update and delete users within their domain
    • domain admins may create, update and delete projects within their domain
    • domain admins may assign and revoke roles between projects and users within the domain while adhering to the following restrictions:
      • they may only manage role assignments of specific roles ("member" in this example)
      • they may only change role assignments when both user and project belong to their domain

Notes regarding "Definition of Done":

  • this concept does not include the groups feature of Keystone yet but I assume it could easily be incorporated as it should be same adjustments as described for users and projects below
  • I'd argue that the "As a SCS Customer I have administrator rights for my resources to define roles and map them to access privileges" would require allowing Keystone API policy changes by the customer which seems unfeasible to me both from a security and an operational perspective
    • in the current state of this concept, roles and access levels would need to be globally predetermined and equal across all domains

Preparation

openstack domain create domain-a
openstack domain create domain-b

openstack user create --domain domain-a --password b0gusp4ss domain-a-admin
openstack user create --domain domain-b --password b0gusp4ss domain-b-admin

openstack project create --domain domain-a domain-a-project-1
openstack project create --domain domain-b domain-b-project-1

openstack role create domain-admin-role
openstack role add --user domain-a-admin --domain domain-a domain-admin-role
openstack role add --user domain-b-admin --domain domain-b domain-admin-role

openstack role assignment list --names --role domain-admin-role
+-------------------+-------------------------+-------+---------+----------+--------+-----------+
| Role              | User                    | Group | Project | Domain   | System | Inherited |
+-------------------+-------------------------+-------+---------+----------+--------+-----------+
| domain-admin-role | domain-a-admin@domain-a |       |         | domain-a |        | False     |
| domain-admin-role | domain-b-admin@domain-b |       |         | domain-b |        | False     |
+-------------------+-------------------------+-------+---------+----------+--------+-----------+

RC file examples

An RC file example for a domain admin would look like this:

export OS_REGION_NAME=RegionOne
export OS_INTERFACE=public
export OS_AUTH_URL=https://identity.mycloud.com/v3
export OS_DOMAIN_NAME=domain-a
export OS_USERNAME=domain-a-admin
export OS_VOLUME_API_VERSION=3
export OS_AUTH_TYPE=password
export OS_USER_DOMAIN_NAME=domain-a
export OS_DOMAIN_NAME=domain-a
export OS_PASSWORD=b0gusp4ss
export OS_IDENTITY_API_VERSION=3

Policy Definitions

    # classify domain admins with a special role
    "is_domain_admin": "role:domain-admin-role"

    # allow domain admins to retrieve their own domain
    "identity:get_domain": "(rule:is_domain_admin and token.domain.id:%(target.domain.id)s) or rule:admin_required"

    # specify a rule that whitelists roles which domain admins are permitted to assign and revoke
    "is_domain_role": "%(target.role.name)s:member"

    # list_domains is needed for GET /v3/domains?name=... requests
    # this is mandatory for things like "create user --domain $DOMAIN_NAME $USER_NAME" to correctly discover domains by name
    "identity:list_domains": "rule:is_domain_admin or rule:admin_required"

    # list_roles is needed for GET /v3/roles?name=... requests
    # this is mandatory for things like "role add ... $ROLE_NAME" to correctly discover roles by name
    "identity:list_roles": "rule:is_domain_admin or rule:admin_required"

    # allow domain admins to manage user within their domain
    "identity:list_users": "(rule:is_domain_admin and token.domain.id:%(target.domain_id)s) or rule:admin_required"
    "identity:get_user": "(rule:is_domain_admin and token.domain.id:%(target.user.domain_id)s) or rule:admin_required"
    "identity:create_user": "(rule:is_domain_admin and token.domain.id:%(target.user.domain_id)s) or rule:admin_required"
    "identity:update_user": "(rule:is_domain_admin and token.domain.id:%(target.user.domain_id)s) or rule:admin_required"
    "identity:delete_user": "(rule:is_domain_admin and token.domain.id:%(target.user.domain_id)s) or rule:admin_required"

    # allow domain admins to manage projects within their domain
    "identity:list_projects": "(rule:is_domain_admin and token.domain.id:%(target.domain_id)s) or rule:admin_required"
    "identity:get_project": "(rule:is_domain_admin and token.domain.id:%(target.project.domain_id)s) or rule:admin_required"
    "identity:create_project": "(rule:is_domain_admin and token.domain.id:%(target.project.domain_id)s) or rule:admin_required"
    "identity:update_project": "(rule:is_domain_admin and token.domain.id:%(target.project.domain_id)s) or rule:admin_required"
    "identity:delete_project": "(rule:is_domain_admin and token.domain.id:%(target.project.domain_id)s) or rule:admin_required"

    # allow domain admins to manage role assignments within their domain
    # (restricted to specific roles by the 'is_domain_role' rule)
    "identity:check_grant": "(rule:is_domain_admin and token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.project.domain_id)s and rule:is_domain_role) or rule:admin_required"
    "identity:list_grants": "(rule:is_domain_admin and token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.project.domain_id)s and rule:is_domain_role) or rule:admin_required"
    "identity:create_grant": "(rule:is_domain_admin and token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.project.domain_id)s and rule:is_domain_role) or rule:admin_required"
    "identity:revoke_grant": "(rule:is_domain_admin and token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.project.domain_id)s and rule:is_domain_role) or rule:admin_required"

    # allow 'role assignment list' scoped to the domain
    "identity:list_role_assignments": "(rule:is_domain_admin and token.domain.id:%(target.domain_id)s) or rule:admin_required"

Limitations

The approach described here currently has the following limitations:

  1. due to the "identity:list_domains" rule, domain admins are able to see all domains via "openstack domain list" and can inspect other domains with "openstack domain show"
    • this is due to the lack of proper domain-scoping for the domain list API, see [1]
  2. due to the "identity:list_roles" rule, domain admins are able to see all roles via "openstack role list" and can inspect other roles with "openstack role show"
  3. the described approach has not been extensively pentested yet

The result of points 1 and 2 is that the metadata of all domains and roles will be exposed to all domain admins!


[1] about the lack of domain-scoping for the domains API

When a command specifying an object per name is used, e.g. the domain in "openstack user create --domain my-domain ..." then openstackclient will attempt to resolve the domain name into the domain ID by internally retrieving the domain list via "GET /v3/domains?name=my-domain" before attempting to create the user object. That means, that even if the domain admin only needs their own domain, they need access to the domain list API to resolve the name to ID of their very own domain.
The same goes for the roles API: resolving a role name to ID is done via the roles list API in the client.

For "openstack project list" there is proper domain-scoping implemented:

This is currently not implemented for "openstack domain list":

This policy works for projects:

"identity:list_projects": "(rule:is_domain_admin and token.domain.id:%(target.domain_id)s) or rule:admin_required"

This policy does not work for domains:

"identity:list_domains": "(rule:is_domain_admin and token.domain.id:%(target.domain.id)s) or rule:admin_required"

and leads to the following error upon "openstack domain list":

You are not authorized to perform the requested action: identity:list_domains. (HTTP 403) (Request-ID: req-224b577d-c428-4720-a03e-cb195471afba)

This is why the policy has to be configured to allow domain admins to list all domains in order to enable them to manage user, projects and role assignments within their domain properly.

Follow up Action Item:

@reqa
Copy link

reqa commented Aug 9, 2023

Thank you very much @markus-hentsch for this valuable contribution and the research and expertise that have gone into it. We have discussed this in last weeks SCS SIG IAM and would like to implement this approach for SCS. We would like to call the role domain-manager instead for two reasons: 1. to avoid confusion with the unscoped admin role and to be inline with the upstream plan https://specs.openstack.org/openstack/keystone-specs/specs/keystone/2023.1/default-service-role.html .

@reqa
Copy link

reqa commented Aug 9, 2023

@matfechner where does this have to go? First to https://github.com/osism/testbed ? Or somewhere in https://github.com/osism/cfg-generics ?

@fkr
Copy link
Member Author

fkr commented Oct 18, 2023

This is going to be tested by AOV and arcodix in their greenfield deployments.

@markus-hentsch
Copy link

FTR, we discussed domain management with Arvid, Artem and Juan during the IAM SIG call on 2024-03-06 in the scope of the ongoing work on the Keycloak and identity federation. There is one very important point that we realized:

The Domain Manager Role for Keystone as per the current SCS standard draft is pretty much mutually exclusive to identity federation. Reason is that managing identity resources (users, projects, groups, role assignments) is not Keystone's responsibility anymore when using an external Identity Provider such as Keycloak. As a result, manipulating such resources and their relationships within Keystone is neither possible (at least not in a persistent fashion) nor desired.

In a federated setup the current Domain Manager Role is only useful for and applicable to the small subset of local Keystone user accounts not managed by any external Identity Provider or for setups that don't use identity federation at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
epic Issues that are spread across multiple sprints IaaS Issues or pull requests relevant for Team1: IaaS IAM Issues or pull requests relevant for SIG IAM SCS-VP10 Related to tender lot SCS-VP10
Projects
Status: Doing
Development

No branches or pull requests

4 participants