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

Draft: Roles Standard #590

Draft
wants to merge 25 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6be442b
First parts of the role standards draft
markus-hentsch May 14, 2024
dfc7b04
Add further details and open question section
markus-hentsch May 14, 2024
76444ea
Content additions and rephrasing for better clarity
markus-hentsch May 15, 2024
717642a
Remove reader role and add reasoning
markus-hentsch May 15, 2024
acd431c
Document necessary future changes to the standard
markus-hentsch May 15, 2024
f7513f3
Add reference to service list standard
markus-hentsch May 15, 2024
c8885cd
Add remark about Barbican inaccessibility for users
markus-hentsch May 15, 2024
6a59376
Add test script for checking role presence
markus-hentsch May 15, 2024
5b571b3
Integrate Barbican adjustments
markus-hentsch May 16, 2024
a0b332a
Add rationale for keeping the creator role for service accounts
markus-hentsch May 16, 2024
77a7c5b
Downgrade "manager" role to service-specific roles
markus-hentsch May 17, 2024
8546f35
Implement tests for verifying Key Manager role permissions
markus-hentsch May 17, 2024
148e3a5
Add README for test suite
markus-hentsch May 17, 2024
20e9567
Cleanup application credential after testing
markus-hentsch May 17, 2024
65d72d4
Update remarks about oslo.policy options to reflect latest findings
markus-hentsch Jun 28, 2024
0fde99f
Address review comments
markus-hentsch Aug 31, 2024
beb6557
Update standard to reflect latest changes in SCS and upstream
markus-hentsch Sep 2, 2024
df70355
Add more regulation to policy rules, add Octavia quirks
markus-hentsch Sep 9, 2024
dca05da
Update test instructions to re-use the manager role if possible
markus-hentsch Sep 19, 2024
1557c08
Add remark about the standard being applicable to 2024.2 and later
markus-hentsch Sep 19, 2024
67a4a1d
Improve phrasing
markus-hentsch Sep 19, 2024
2af152e
Move role overview to design considerations
markus-hentsch Sep 19, 2024
ed3b755
Remove paragraph about Barbican creator role
markus-hentsch Sep 30, 2024
5bfe232
Reference the Key Manager standard in related documents
markus-hentsch Sep 30, 2024
688da00
Remove outdated tests from test script
markus-hentsch Sep 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 211 additions & 0 deletions Standards/scs-03XX-v1-standard-roles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
---
title: SCS Standard Roles
type: Standard
status: Draft
track: IAM
---

## Introduction

SCS aims to provide a standardized role model for Role-Based Access Control (RBAC) across all supported OpenStack API services.
The goal of this standard is to define IaaS roles for SCS clouds with sensible and consistent permission sets.
It is closely guided by the OpenStack defaults to achieve compatibility and interoperability.

:::note

The standard described below is only applicable to OpenStack releases 2024.2 or later.

:::

## Terminology

The following special terms are used throughout this standard document:

| Term | Meaning |
|---|---|
| API | Application Programming Interface, often referring to the REST API interfaces provided by OpenStack and related services |
| CSP | Cloud Service Provider, provider managing the OpenStack infrastructure |
| IaaS | Infrastructure-as-a-Service |
| IAM | Identity and Access Management |
| RBAC | Role-Based Access Control[^1] established by OpenStack Keystone |

[^1]: [OpenStack Documentation: Role-Based Access Control Overview](https://static.opendev.org/docs/patrole/latest/rbac-overview.html)

## Motivation

The permission settings of OpenStack RBAC roles are preconfigured in the OpenStack API implementations and can optionally be adjusted in service-specific deployment configuration files (usually the respective "`policy.yaml`") individually.
In contrast to many of OpenStack's IAM and IaaS resources however, these settings cannot be changed via its API at runtime, only via configuration files.
Changing these settings can also have a wide range of implications and requires careful testing and maintenance.
For these reasons it is important to have a secure and sensible default configuration in SCS clouds that is both intuitive and flexible enough to cover all necessary use cases of permission models desired by CSPs and customers.

## Design Considerations

One key aspect of the design considerations for this standard is to be as close to the native (upstream) OpenStack role model and role definitions as possible to not introduce unnecessary complexity or divergence from OpenStack.
Meanwhile the standardized roles and permission sets should cover all scenarios and use cases that SCS deems necessary.

Due to the high level of modularity and the large amount of available services for OpenStack clouds, this standard cannot address all possible manifestations of OpenStack clouds.
This standard will therefore only cover IaaS APIs and services that are classified as either mandatory or supported by the SCS project.

### Core Roles

The following overview will list the roles which are considered core roles by this standard and explain their purposes as well as target scopes.
Roles marked as "internal" are roles only meant to be assigned to technical user accounts intended for internal use by OpenStack services.

Core Roles:

| Role | Primary Target(s) | Purpose |
|---|---|---|
| reader | customer | read-only access to resources in the scope of authentication (e.g. project) |
| member | customer | read and write access to resources in the scope of authentication (e.g. project) |
| manager | customer | identity self-service capability within a domain, to assign/revoke roles between users, groups and projects |
| admin | CSP | cloud-level global administrative access to all resources (cross-domain, cross-project) |
| service | internal | internal technical user role for service communication |

### Scope Enforcement Compatibility

The API policy library used by OpenStack (oslo.policy) introduced two new [configuration options](https://docs.openstack.org/oslo.policy/latest/configuration/#oslo-policy) during the ongoing RBAC rework of OpenStack[^2]:

- `enforce_scope`
- `enforce_new_defaults`

Using those new defaults and scope-enforcing options [will currently break](https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#the-issues-we-are-facing-with-scope-concept) orchestration tooling such as **OpenStack Heat** and Tacker.
This must be considered when making decisions in this standard.
Careful evaluation of benefits as well as implications of adopting these changes is necessary.
The new options are not adopted equally across all OpenStack services yet in context of the ongoing rework.

Some service-specific role sets currently found in OpenStack services can only be eliminated and streamlined with the general roles (reader, member etc.) when those new options are enabled.

[^2]: [OpenStack Technical Committee Governance Documents: Consistent and Secure Default RBAC](https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html)

#### Core Role Set

Independently from any service-specific roles, the set of core roles is fundamentally affected by the scope enforcement options as well.

The proper distinction between reader, member and manager roles is only fully implemented in all services when the `enforce_scope` and `enforce_new_defaults` oslo.policy options are used.
Otherwise the OpenStack APIs will oftentimes fall back to their earlier policy implementations which do not fully differentiate between reader, member and manager.

This results in more elevated permissions for users possessing the reader role than its role description suggests.
If this standard cannot mandate or expect the use of the aforementioned oslo.policy options due to their current compatibility issues as stated above, the usefulness of the reader role would be limited and unexpected behavior would be introduced when using it.
In such case, the standard should omit the reader role in its current state.

#### Barbican Role Set

The Key Manager component Barbican [established a set of dedicated roles](https://docs.openstack.org/barbican/2024.1/admin/access_control.html#default-policy):

- key-manager:service-admin
- creator
- observer
- audit

This set of roles is Barbican-specific and not used by any other API.
It became deprecated during the RBAC rework of OpenStack[^2].

Due to its deprecation it is possible to enable Barbican's use of the already established reader, member and admin roles instead.
This however requires the olso.policy options `enforce_scope` and `enforce_new_default` to be enabled.

#### Octavia Role Set

The Load-Balancer-as-a-Service (LBaaS) component Octavia comes with a set of specific roles in its default API policy configuration:

- load-balancer_observer
- load-balancer_global_observer
- load-balancer_member
- load-balancer_quota_admin
- load-balancer_admin

This set of roles is Octavia-specific and not used by any other API.
However, Octavia also [officially supports alternative policy configurations](https://docs.openstack.org/octavia/2024.1/configuration/policy.html#openstack-default-roles-policy-override-file) that use the already established reader, member and admin roles instead.

Using the alternative configurations would streamline Octavia's policies with the rest of the services and reduce complexity as well as ambiguity in the global role model of this standard.

However, both of the alternative policy files that omit the Octavia-specific roles currently state "The [oslo_policy] `enforce_scope` and `enforce_new_defaults` must be `True`.".
This would require the new defaults and scope-enforcing options.

### Inclusion of the "manager" role

The current RBAC rework in upstream OpenStack[^2] describes a "project-manager" persona utilizing a new "manager" role on project scope to perform more privileged operations than "member" (see "Phase 3" of the document).
This role is intended to be used across various OpenStack services.
As of the OpenStack release 2024.1 this role is not implemented in any of the core services yet, only in Ironic with `enforce_new_defaults` enabled[^3].

On the other hand, the SCS project is making use of this role to implement a Domain Manager persona (see the [SCS Domain Manager standard under "Related Documents"](#scs-domain-manager-standard)).
This persona will be available as a native upstream feature in Keystone starting with the 2024.2 release of OpenStack.

As a result, the "manager" role has no effect outside of the Keystone Identity API until phase 3 of the RBAC rework is implemented upstream but can be used for identity-related functionality in Keystone.

[^3]: [Implementation of the "manager" role in Ironic for the 2024.1 release](https://github.com/openstack/ironic/blob/stable/2024.1/ironic/common/policy.py#L76-L82)

## Standard

### Roles

This standard establishes the following default roles in SCS clouds.
The roles mentioned below MUST be present in the Identity API at all times.

- reader
- member
- manager
- admin
- service

### API configuration

All API services MUST be configured to use the Secure RBAC role model by enabling `enforce_new_defaults` and `enforce_scope` of the oslo.policy library.

If custom policy rules are added to an API by a CSP the `policy_file` option of the oslo.policy library SHOULD be explicitly set to the name of the policy override file and not rely on the corresponding default path.

Example configuration entries:

```ini
[oslo_policy]
enforce_new_defaults = True
enforce_scope = True
policy_file = policy.yaml
```

#### API Policies

The following applies to all APIs that use RBAC policies:

- Custom policy rules MUST NOT extend the privileges of the core roles mentioned in this standard beyond their default permissions.
- If roles with custom permission sets are required, new roles and corresponding policies MAY be added as long as their names differ from the core roles and they do not impact the core roles.

The following applies only to the Octavia v2 LBaaS API:

- The scoping-compatible variant of [OpenStack Default Roles Policy Override File](https://docs.openstack.org/octavia/2024.1/configuration/policy.html#openstack-default-roles-policy-override-file) MUST be used as a base to align the LBaaS API with the standardized reader, member and admin role set.
As of the 2024.1 release of Octavia, this template is provided as [keystone_default_roles_scoped-policy.yaml](https://github.com/openstack/octavia/blob/stable/2024.1/etc/policy/keystone_default_roles_scoped-policy.yaml).

## Related Documents

### SCS Mandatory and Supported IaaS Services

**Description:** SCS standard that lists mandatory and supported OpenStack APIs for SCS clouds.
This list is decisive for the standard on roles as all applicable services need to be taken into consideration.

**Link:** TBD <!-- https://github.com/SovereignCloudStack/standards/pull/587 -->
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be replaced by a genuine link once #587 is merged.


### SCS Domain Manager standard

**Description:** SCS standard that describes the Domain Manager role introduced by SCS and its configuration.

**Link:** [SCS Standards: Domain Manager configuration for Keystone](https://docs.scs.community/standards/scs-0302-v1-domain-manager-role)

### SCS Key Manager standard role adjustment

**Description:** Implementation notes of the [SCS Key Manager standard](https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0116-v1-key-manager-standard.md) that describe a policy adjustment to redirect the "creator" role to the "member" role for Key Manager setups not yet using the `enforce_new_defaults` option in order to enable generic project members to manage secrets and access encryption functionalities.

**Link:** [SCS Standards: Key Manager Standard Implementation Notes](https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0116-w1-key-manager-implementation-testing.md#policies)

### Consistent and Secure Default RBAC

**Description:** Upstream rework of the default role definitions and hierarchy across all OpenStack services.
Explains the reasoning for the `enforce_scope` and `enforce_new_defaults` options and the transition process.

**Link:** [OpenStack Technical Committee Governance Documents: Consistent and Secure Default RBAC](https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html)

## Conformance Tests

Conformance tests verify that the roles mandated by the standard exist and the Key Manager API adjustments are implemented.

There is a test suite in [`standard-roles-check.py`](https://github.com/SovereignCloudStack/standards/blob/main/Tests/iam/iaas-roles/standard-roles-check.py).
The test suite connects to the OpenStack API, queries the role list and verifies the behavior of the Key Manager API.
Please consult the associated [README.md](https://github.com/SovereignCloudStack/standards/blob/main/Tests/iam/iaas-roles/README.md) for detailed setup and testing instructions.
92 changes: 92 additions & 0 deletions Tests/iam/iaas-roles/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Standard Roles Test Suite

## Test Environment Setup

### API User Account

The test suite strictly requires an OpenStack user that possesses the following access rights:

1. the "`member`" role in the project referenced as authentication target
2. access permissions to the "`list_roles`" in the Identity API

The second requirement (access to "`list_roles`") is usually not granted to users with the "`member`" role in default configurations and only works for user accounts also possessing the "`manager`" role in the domain.
So the test would require an user account possessing both the "`member`" role in a project as well as the "`manager`" role in the domain.

Note that the "`manager`" role only works this way starting with OpenStack Keystone 2024.2.
If an older Keystone release is used, see the alternative instructions below.

#### Alternative using a dedicated role

One alternative way to address this is for older Keystone releases is to create a dedicated role in the cloud environment which only has access to the role list endpoint and assign it to the user account intended for testing (in addition to the "`member`" role).

To achieve this, first the role has to be created and assigned:

```sh
openstack role create scs-conformance-tester
openstack role add --user ... --project ... member
openstack role add --user ... --project ... scs-conformance-tester
```

Finally, the Keystone API policy definition for the role list endpoint has to be extended to allow this role.
The following is an example entry for `/etc/keystone/policy.yaml` of the Keystone service:

```yaml
"identity:list_roles": "... or role:scs-conformance-tester"
```

("`...`" is a placeholder and must be replaced by the current content of the `"identity:list_roles"` rule!)

The credentials of the resulting user must be specified in the "`clouds.yaml`" accordingly (see below).

### Test Execution Environment

To execute the test suite a valid cloud configuration for the OpenStack SDK in the shape of "`clouds.yaml`" is mandatory[^1].
**The file is expected to be located in the current working directory where the test script is executed unless configured otherwise.**

[^1]: [OpenStack Documentation: Configuring OpenStack SDK Applications](https://docs.openstack.org/openstacksdk/latest/user/config/configuration.html)

The test execution environment can be located on any system outside of the cloud infrastructure that has OpenStack API access.
Make sure that the API access is configured properly in "`clouds.yaml`".

It is recommended to use a Python virtual environment[^2].
Next, install the OpenStack SDK required by the test suite:

```bash
pip3 install openstacksdk
```

Within this environment execute the test suite.

[^2]: [Python 3 Documentation: Virtual Environments and Packages](https://docs.python.org/3/tutorial/venv.html)

## Test Execution

The test suite is executed as follows:

```bash
python3 standard-roles-check.py --os-cloud mycloud
```

As an alternative to "`--os-cloud`", the "`OS_CLOUD`" environment variable may be specified instead.
The parameter is used to look up the correct cloud configuration in "`clouds.yaml`".
For the example command above, this file should contain a `clouds.mycloud` section like this:

```yaml
---
clouds:
mycloud:
auth:
auth_url: ...
...
...
```

For any further options consult the output of "`python3 standard-roles-check.py --help`".

### Script Behavior & Test Results

The script will print all executed tests and their results to `stdout`.

If all tests pass, the script will return with an exit code of `0`.

If any test fails, the script will abort, print the failed test to `stdout` and return with a non-zero exit code.
92 changes: 92 additions & 0 deletions Tests/iam/iaas-roles/standard-roles-check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import argparse
import getpass
import os
import typing

import openstack

CORE_ROLES = {
"reader",
"member",
"admin",
"service"
}


def connect(cloud_name: str, password: typing.Optional[str] = None
) -> openstack.connection.Connection:
"""Create a connection to an OpenStack cloud

:param string cloud_name:
The name of the configuration to load from clouds.yaml.

:param string password:
Optional password override for the connection.

:returns: openstack.connnection.Connection
"""

if password:
return openstack.connect(
cloud=cloud_name,
password=password
)
else:
return openstack.connect(
cloud=cloud_name,
)


def check_list_of_roles(conn: openstack.connection.Connection,
expected_roles: typing.Iterable[str]) -> None:
"""
Retrieves the list of roles from the Identity API and verifies that
it contains all role names specified in the given expected_roles list.
"""
actual_roles = [role.name for role in conn.identity.roles()]
for role in expected_roles:
assert role in actual_roles, (
f"Expected role '{role}' was not found."
)
print(f"Role '{role}' is present: PASS")


def main():
parser = argparse.ArgumentParser(
description="SCS Standard Roles Conformance Checker")
parser.add_argument(
"--os-cloud", type=str,
help="Name of the cloud from clouds.yaml, alternative "
"to the OS_CLOUD environment variable"
)
parser.add_argument(
"--ask",
help="Ask for password interactively instead of reading it from the "
"clouds.yaml",
action="store_true"
)
parser.add_argument(
"--debug", action="store_true",
help="Enable OpenStack SDK debug logging"
)
args = parser.parse_args()
openstack.enable_logging(debug=args.debug)

# parse cloud name for lookup in clouds.yaml
cloud = os.environ.get("OS_CLOUD", None)
if args.os_cloud:
cloud = args.os_cloud
assert cloud, (
"You need to have the OS_CLOUD environment variable set to your "
"cloud name or pass it via --os-cloud"
)
conn = connect(
cloud,
password=getpass.getpass("Enter password: ") if args.ask else None
)

check_list_of_roles(conn, CORE_ROLES)


if __name__ == "__main__":
main()