Chapter 11. Policies Each OpenStack service contains resources that are managed by access policies. For example, a resource might include the following functions: Permission to create and start instances The ability to attach a volume to an instance If you are a Red Hat OpenStack Platform (RHOSP) administrator, you can create custom policies to introduce new roles with varying levels of access, or to change the default behavior of existing roles. Important Red Hat does not support customized roles or policies. Syntax errors or misapplied authorization can negatively impact security or usability. If you need customized roles or policies in your production environment, contact Red Hat support for a support exception. 11.1. Reviewing existing policies Policy files for services traditionally existed in the /etc/USDservice directory. For example, the full path of the policy.json file for Compute (nova) was /etc/nova/policy.json . There are two important architectural changes that affect how you can find existing policies: Red Hat OpenStack Platform is now containerized. Policy files, if present, are in the traditional path if you view them from inside the service container: Policy files, if present, are in the following path if you view them from outside the service container: Each service has default policies that are provided in code, with files that are available only if you created them manually, or if they are generated with oslopolicy tooling. To generate a policy file, use the oslopolicy-policy-generator from within a container, as in the following example: By default, generated policies are pushed to stdout by oslo.policy CLI tools. 11.2. Understanding service policies Service policy file statements are either alias definitions or rules. Alias definitions exist at the top of the file. The following list contains an explanation of the alias definitions from the generated policy.json file for Compute (nova): "context_is_admin": "role:admin" When rule:context_is_admin appears after a target, the policy checks that the user is operating with an administrative context before it allows that action. "admin_or_owner": "is_admin:True or project_id:%(project_id)s" When admin_or_owner appears after a target, the policy checks that the user is either an admin, or that their project ID matches the owning project ID of the target object before it allows that action. "admin_api": "is_admin:True When admin_api appears after a target, the policy checks that the user is an admin before it allows that action. 11.3. Policy syntax Policy.json files support certain operators so that you can control the target scope of these settings. For example, the following keystone setting contains the rule that only admin users can create users: The section to the left of the : character describes the privilege, and the section to the right defines who can use the privilege. You can also use operators to the right side to further control the scope: ! - No user (including admin) can perform this action. @ and "" - Any user can perform this action. not , and , or - Standard operator functions are available. For example, the following setting means that no users have permission to create new users: 11.4. Using policy files for access control Important Red Hat does not support customized roles or policies. Syntax errors or misapplied authorization can negatively impact security or usability. If you need customized roles or policies in your production environment, contact Red Hat support for a support exception. To override the default rules, edit the policy.json file for the appropriate OpenStack service. For example, the Compute service has a policy.json in the nova directory, which is the correct location of the file for containerized services when you view it from inside the container. Note You must thoroughly test changes to policy files in a staging environment before implementing them in production. You must check that any changes to the access control policies do not unintentionally weaken the security of any resource. In addition, any changes to a policy.json file are effective immediately and do not require a service restart. Example: Creating a power user role To customize the permissions of a keystone role, update the policy.json file of a service. This means that you can more granularly define the permissions that you assign to a class of users. This example creates a power user role for your deployment with the following privileges: Start an instance. Stop an instance. Manage the volumes that are attached to instances. The intention of this role is to grant additional permissions to certain users, without the need to then grant admin access. To use these privileges, you must grant the following permissions to a custom role: Start an instance: "os_compute_api:servers:start": "role:PowerUsers" Stop an instance: "os_compute_api:servers:stop": "role:PowerUsers" Configure an instance to use a particular volume: "os_compute_api:servers:create:attach_volume": "role:PowerUsers" List the volumes that are attached to an instance: "os_compute_api:os-volumes-attachments:index": "role:PowerUsers" Attach a volume: "os_compute_api:os-volumes-attachments:create": "role:PowerUsers" View the details of an attached volume: "os_compute_api:os-volumes-attachments:show": "role:PowerUsers" Change the volume that is attached to an instance: "os_compute_api:os-volumes-attachments:update": "role:PowerUsers" Delete a volume that is attached to an instance: "os_compute_api:os-volumes-attachments:delete": "role:PowerUsers" Note When you modify the policy.json file, you override the default policy. As a result, members of PowerUsers are the only users that can perform these actions. To allow admin users to retain these permissions, you can create rules for admin_or_power_user. You can also use some basic conditional logic to define role:PowerUsers or role:Admin . Create the custom keystone role: Add an existing user to the role, and assign the role to a project: Note A role assignment is paired exclusively with one project. This means that when you assign a role to a user, you also define the target project at the same time. If you want the user to receive the same role but for a different project, you must assign the role to them again separately but target the different project. Log in to a Controller node as the tripleo-admin user. Optional: On a Controller, view the default nova policy settings: Test policy changes. On each Controller node, complete the following: Extract the Compute service policy.json file: Create custom permissions for the new PowerUsers role by adding the following entries to the /tmp/policy.json : Implement changes by saving this file to the nova container. Users that are added to the PowerUsers keystone role recieve these privileges. Make changes permanent through an update in heat policy files. For more information see Modifying policies with heat . 11.5. Example: Limiting access based on attributes Important Red Hat does not support customized roles or policies. Syntax errors or misapplied authorization can negatively impact security or usability. If you need customized roles or policies in your production environment, contact Red Hat support for a support exception. You can create policies that will restrict access to API calls based on the attributes of the user making that API call. For example, the following default rule states that keypair deletion is allowed if run from an administrative context, or if the user ID of the token matches the user ID associated with the target. NOTE: * Newly implemented features are not guaranteed to be in every service with each release. Therefore, it is important to write rules using the conventions of the target service's existing policies. For details on viewing these policies, see Reviewing existing policies. * All policies should be rigorously tested in a non-production environment for every version on which they will be deployed, as policies are not guaranteed for compatibility across releases. Based on the above example, you can craft API rules to expand or restrict access to users based on whether or not they own a resource. Additionally, attributes can be combined with other restrictions to form rules as seen in the example below: Considering the examples above, you can create a unique rule limited to administrators and users, and then use that rule to further restrict actions: Additional resources Policy syntax . 11.6. Modifying policies with heat Important Red Hat does not support customized roles or policies. Syntax errors or misapplied authorization can negatively impact security or usability. If you need customized roles or policies in your production environment, contact Red Hat support for a support exception. You can use heat to configure access policies for certain services in the overcloud. Use the following parameters to set policies on the respective services: Table 11.1. Policy Parameters Parameter Description KeystonePolicies A hash of policies to configure for OpenStack Identity (keystone). IronicApiPolicies A hash of policies to configure for OpenStack Bare Metal (ironic) API. BarbicanPolicies A hash of policies to configure for OpenStack Key Manager (barbican). NeutronApiPolicies A hash of policies to configure for OpenStack Networking (neutron) API. SaharaApiPolicies A hash of policies to configure for OpenStack Clustering (sahara) API. NovaApiPolicies A hash of policies to configure for OpenStack Compute (nova) API. CinderApiPolicies A hash of policies to configure for OpenStack Block Storage (cinder) API. GlanceApiPolicies A hash of policies to configure for OpenStack Image Storage (glance) API. HeatApiPolicies A hash of policies to configure for OpenStack Orchestration (heat) API. To configure policies for a service, give the policy parameter a hash value that contains the service's policies For example: OpenStack Identity (keystone) uses the KeystonePolicies parameter. Set this parameter in the parameter_defaults section of an environment file: OpenStack Compute (nova) uses the NovaApiPolicies parameter. Set this parameter in the parameter_defaults section of an environment file: 11.7. Auditing your users and roles You can use tools available in Red Hat OpenStack Platform to build a report of role assignments per user and associated privileges. Prerequisites You have an installed Red Hat OpenStack Platform environment. You are logged into the director as stack. Procedure Run the openstack role list command to see the roles currently in your environment: Run the openstack role assignment list command to list all users that are members of a particular role. For example, to see all users that have the admin role, run the following: Note You can use the -f {csv,json,table,value,yaml} parameter to export these results. 11.8. Auditing API access You can audit the API calls a given role can access. Repeating this process for each role will result in a comprehensive report on the accessible APIs for each role. Prerequisites An authentication file to source as a user in the target role. An access token in JSON format. A policy file for each service's API you wish to audit. Procedure Start by sourcing an authentication file of a user in the desired role. Capture a Keystone generated token and save it to a file. You can do this by running any openstack-cli command and using the --debug option, which prints the provided token to stdout. You can copy this token and save it to an access file. Use the following command to do this as a single step: Create a policy file. This can be done on an overcloud node that hosts the containerized service of interest. The following example creates a policy file for the cinder service: Using these files, you can now audit the role in question for access to cinder's APIs:

Commands:
/etc/USDservice/policy.json
/var/lib/config-data/puppet-generated/USDservice/etc/USDservice/policy.json
exec -i keystone oslopolicy-policy-generator --namespace keystone
"identity:create_user": "rule:admin_required"
"identity:create_user": "!"
openstack role create PowerUsers +-----------+----------------------------------+ | Field | Value | +-----------+----------------------------------+ | domain_id | None | | id | 7061a395af43455e9057ab631ad49449 | | name | PowerUsers | +-----------+----------------------------------+
openstack role add --project [PROJECT_NAME] --user [USER_ID] [PowerUsers-ROLE_ID]
sudo podman exec -i nova_compute oslopolicy-policy-generator --namespace nova
sudo podman exec -it nova_compute oslopolicy-policy-generator --namespace nova > /tmp/nova-policy.json
"os_compute_api:servers:start": "role:PowerUsers", "os_compute_api:servers:stop": "role:PowerUsers" "os_compute_api:servers:create:attach_volume": "role:PowerUsers" "os_compute_api:os-volumes-attachments:index": "role:PowerUsers" "os_compute_api:os-volumes-attachments:create": "role:PowerUsers" "os_compute_api:os-volumes-attachments:show": "role:PowerUsers" "os_compute_api:os-volumes-attachments:update": "role:PowerUsers" "os_compute_api:os-volumes-attachments:delete": "role:PowerUsers"
cp /tmp/nova-policy.json nova_compute:etc/nova/policy.json
"os_compute_api:os-keypairs:delete": "rule:admin_api or user_id:%(user_id)s"
"admin_or_owner": "is_admin:True or project_id:%(project_id)s"
"admin_or_user": "is_admin:True or user_id:%(user_id)s" "os_compute_api:os-instance-actions": "rule:admin_or_user"
parameter_defaults: KeystonePolicies: { keystone-context_is_admin: { key: context_is_admin, value: 'role:admin' } }
parameter_defaults: NovaApiPolicies: { nova-context_is_admin: { key: 'compute:get_all', value: '@' } }
openstack role list -c Name -f value swiftoperator ResellerAdmin admin _member_ heat_stack_user
openstack role assignment list --names --role admin +-------+------------------------------------+-------+-----------------+------------+--------+-----------+ | Role | User | Group | Project | Domain | System | Inherited | +-------+------------------------------------+-------+-----------------+------------+--------+-----------+ | admin | heat-cfn@Default | | service@Default | | | False | | admin | placement@Default | | service@Default | | | False | | admin | neutron@Default | | service@Default | | | False | | admin | zaqar@Default | | service@Default | | | False | | admin | swift@Default | | service@Default | | | False | | admin | admin@Default | | admin@Default | | | False | | admin | zaqar-websocket@Default | | service@Default | | | False | | admin | heat@Default | | service@Default | | | False | | admin | ironic-inspector@Default | | service@Default | | | False | | admin | nova@Default | | service@Default | | | False | | admin | ironic@Default | | service@Default | | | False | | admin | glance@Default | | service@Default | | | False | | admin | mistral@Default | | service@Default | | | False | | admin | heat_stack_domain_admin@heat_stack | | | heat_stack | | False | | admin | admin@Default | | | | all | False | +-------+------------------------------------+-------+-----------------+------------+--------+-----------+
openstack token issue --debug 2>&1 | egrep ^'{\"token\":' > access.file.json
ssh tripleo-admin@CONTROLLER-1 sudo podman exec cinder_api oslopolicy-policy-generator --config-file /etc/cinder/cinder.conf --namespace cinder > cinderpolicy.json
oslopolicy-checker --policy cinderpolicy.json --access access.file.json