SovereignCloudStack / issues

This repository is used for issues that are cross-repository or not bound to a specific repository.
https://github.com/orgs/SovereignCloudStack/projects/6
2 stars 1 forks source link

Adjust keystone policy.yaml to allow "domain-manager" to manage groups. #383

Closed reqa closed 1 year ago

reqa commented 1 year ago

In https://github.com/SovereignCloudStack/issues/issues/184#issuecomment-1653699397 @markus-hentsch proposed a policy for a domain-manager role. That approach should be extended to also grant rights to manage groups.

Definition of Ready:

Definition of Done:

markus-hentsch commented 1 year ago

Necessary changes to policy.yaml

Extension of the Keystone policy.yaml changes for groups:

    # classify domain managers with a special role
    "is_domain_manager": "role:domain-manager"
    ...
    # (unmodified parts from https://github.com/SovereignCloudStack/issues/issues/184#issuecomment-1653699397 here)
    ...
    # allow domain managers to manage role assignments within their domain
    # (restricted to specific roles by the 'is_domain_role' rule)
    "is_domain_user_project_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.project.domain_id)s and rule:is_domain_role"
    "is_domain_group_project_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.project.domain_id)s and rule:is_domain_role"
    "domain_manager_grant": "rule:is_domain_manager and (rule:is_domain_user_project_grant or rule:is_domain_group_project_grant)"
    "identity:check_grant": "rule:domain_manager_grant or rule:admin_required"
    "identity:list_grants": "rule:domain_manager_grant or rule:admin_required"
    "identity:create_grant": "rule:domain_manager_grant or rule:admin_required"
    "identity:revoke_grant": "rule:domain_manager_grant or rule:admin_required"
    "identity:list_role_assignments": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:admin_required"

    # allow domain managers to manage groups within their domain
    "identity:list_groups": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:admin_required"
    "identity:get_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:admin_required"
    "identity:create_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:admin_required"
    "identity:update_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:admin_required"
    "identity:delete_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:admin_required"
    "identity:list_groups_for_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:admin_required"
    "identity:list_users_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:admin_required"
    "identity:remove_user_from_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:admin_required"
    "identity:check_user_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:admin_required"
    "identity:add_user_to_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:admin_required"

In comparison to the first draft in https://github.com/SovereignCloudStack/issues/issues/184#issuecomment-1653699397, it requires additional changes to the identity:*_grant rules to check group/project domain relations in the same manner as user/project domain relations.

Validation

Starting situation:

(domain) domain-a
├── (user) domain-a-manager [role:domain-manager@domain]
├── (user) domain-a-user [group:none, role:none]
└── (project) domain-a-project-1

(domain) domain-b
├── (user) domain-b-manager [role:domain-manager@domain]
├── (user) domain-b-user [group:domain-b-group-1, role:none]
└── (group) domain-b-group-1

Basic tests:

source domain-manager-a.openrc

# parameter --domain is mandatory for non-default domain
openstack group create domain-a-group-without-domaindef
    You are not authorized to perform the requested action: identity:create_group. (HTTP 403) (Request-ID: req-24935142-3411-4d9f-95f5-e3308056f61d)

# domain manager cannot create group in foreign domain
openstack group create --domain domain-b domain-b-group-1
    You are not authorized to perform the requested action: identity:create_group. (HTTP 403) (Request-ID: req-cb1c93a3-1d94-47ea-8788-f260ca0ea6ee)

# domain manager *can* create group in own domain
openstack group create --domain domain-a domain-a-group-1
    +-------------+----------------------------------+
    | Field       | Value                            |
    +-------------+----------------------------------+
    | description |                                  |
    | domain_id   | fb9f51b0647541cfb8e57e8a22d43182 |
    | id          | a2ee19d555b84db4b0da6342f848b730 |
    | name        | domain-a-group-1                 |
    +-------------+----------------------------------+

# change to domain manager of domain-b
source domain-manager-b.openrc

# domain manager cannot see groups of foreign domains
openstack group list
    # (no result)

# domain manager cannot edit groups of foreign domains
openstack group set --name domain-a-group-1a domain-a-group-1
    No group with a name or ID of 'domain-a-group-1' exists.

# domain manager cannot delete groups of foreign domains
openstack group delete domain-a-group-1
    Failed to delete group with name or ID 'domain-a-group-1a': No group with a name or ID of 'domain-a-group-1' exists.
    1 of 1 groups failed to delete.

# change to domain manager of domain-a
source domain-manager-a.openrc

openstack group contains user domain-a-group-1 domain-a-user
    domain-a-user not in group domain-a-group-1

# domain manager cannot inspect user-group relationships of foreign domains
openstack group contains user domain-a-group-1 domain-b-user
    No user with a name or ID of 'domain-b-user' exists.
openstack group contains user domain-b-group-1 domain-a-user
    No group with a name or ID of 'domain-b-group-1' exists.

# domain manager can add users to groups if both are part of their domain
openstack group add user domain-a-group-1 domain-a-user
openstack group contains user domain-a-group-1 domain-a-user
    domain-a-user in group domain-a-group-1
openstack user list --group domain-a-group-1
    +----------------------------------+---------------+
    | ID                               | Name          |
    +----------------------------------+---------------+
    | d50da63e400343e1855a10b508803e39 | domain-a-user |
    +----------------------------------+---------------+
openstack group list --user domain-a-user
    +----------------------------------+------------------+
    | ID                               | Name             |
    +----------------------------------+------------------+
    | c0c7cea304774e10832e7de9194383c7 | domain-a-group-1 |
    +----------------------------------+------------------+
openstack group add user domain-a-group-2 domain-a-user
openstack group list --user domain-a-user
    +----------------------------------+------------------+
    | ID                               | Name             |
    +----------------------------------+------------------+
    | 1084b0e73f2347f9a3508df2032f5053 | domain-a-group-2 |
    | c0c7cea304774e10832e7de9194383c7 | domain-a-group-1 |
    +----------------------------------+------------------+

# domain manager can assign/revoke roles to/from group within their domain
openstack role add --project domain-a-project-1 --group domain-a-group-1 member
openstack role assignment list --names
    +----------------+---------------------------+---------------------------+-----------------------------+----------+--------+-----------+
    | Role           | User                      | Group                     | Project                     | Domain   | System | Inherited |
    +----------------+---------------------------+---------------------------+-----------------------------+----------+--------+-----------+
    | member         |                           | domain-a-group-1@domain-a | domain-a-project-1@domain-a |          |        | False     |
    | domain-manager | domain-a-manager@domain-a |                           |                             | domain-a |        | False     |
    +----------------+---------------------------+---------------------------+-----------------------------+----------+--------+-----------+
openstack role remove --project domain-a-project-1 --group domain-a-group-1 member
openstack role assignment list --names
    +----------------+---------------------------+-------+---------+----------+--------+-----------+
    | Role           | User                      | Group | Project | Domain   | System | Inherited |
    +----------------+---------------------------+-------+---------+----------+--------+-----------+
    | domain-manager | domain-a-manager@domain-a |       |         | domain-a |        | False     |
    +----------------+---------------------------+-------+---------+----------+--------+-----------+

# domain manager can remove users from groups and delete groups themselves within their domain
openstack group remove user domain-a-group-2 domain-a-user
openstack group remove user domain-a-group-1 domain-a-user
openstack group list --user domain-a-user
    # (no result)
openstack group delete domain-a-group-2
openstack group list
    +----------------------------------+------------------+
    | ID                               | Name             |
    +----------------------------------+------------------+
    | c0c7cea304774e10832e7de9194383c7 | domain-a-group-1 |
    +----------------------------------+------------------+

# domain manager cannot manage group relationships for foreign domains
openstack group add user domain-a-group-1 domain-b-user
    domain-b-user not added to group domain-a-group-1: No user with a name or ID of 'domain-b-user' exists.
    1 of 1 users not added to group domain-a-group-1.
openstack group add user domain-b-group-1 domain-a-user
    No group with a name or ID of 'domain-b-group-1' exists.
openstack user list --group domain-b-group-1
    No group with a name or ID of 'domain-b-group-1' exists.
openstack group remove user domain-b-group-1 domain-b-user
    No group with a name or ID of 'domain-b-group-1' exists.
openstack group delete domain-b-group-1
    Failed to delete group with name or ID 'domain-b-group-1': No group with a name or ID of 'domain-b-group-1' exists.
    1 of 1 groups failed to delete.
openstack role add --project domain-a-project-1 --group domain-b-group-1 member
    No group with a name or ID of 'domain-b-group-1' exists.