RBAC Testing Validation

RBAC Testing Validation

Overview

RBAC Testing Validation is broken up into 3 stages:

  1. “Expected” stage. Determine whether the test should be able to succeed or fail based on the test role defined by [patrole] rbac_test_role) and the policy action that the test enforces.

  2. “Actual” stage. Run the test by calling the API endpoint that enforces the expected policy action using the test role.

  3. Comparing the outputs from both stages for consistency. A “consistent” result is treated as a pass and an “inconsistent” result is treated as a failure. “Consistent” (or successful) cases include:

    • Expected result is True and the test passes.
    • Expected result is False and the test fails.

    “Inconsistent” (or failing) cases include:

    • Expected result is False and the test passes. This results in an RbacOverPermission exception getting thrown.
    • Expected result is True and the test fails. This results in a Forbidden exception getting thrown.

    For example, a 200 from the API call and a True result from oslo.policy or a 403 from the API call and a False result from oslo.policy are successful results.

The RBAC Rule Validation Module

High-level module that implements decorator inside which the “Expected” stage is initiated.

patrole_tempest_plugin.rbac_rule_validation.action(service, rule=”, admin_only=False, expected_error_code=403, extra_target_data=None)

A decorator for verifying policy enforcement.

A decorator which allows for positive and negative RBAC testing. Given:

  • an OpenStack service,
  • a policy action (rule) enforced by that service, and
  • the test role defined by [patrole] rbac_test_role

determines whether the test role has sufficient permissions to perform an API call that enforces the rule.

This decorator should only be applied to an instance or subclass of
tempest.base.BaseTestCase.

The result from _is_authorized is used to determine the expected test result. The actual test result is determined by running the Tempest test this decorator applies to.

Below are the following possibilities from comparing the expected and actual results:

  1. If expected is True and the test passes (actual), this is a success.
  2. If expected is True and the test fails (actual), this results in a Forbidden exception failure.
  3. If expected is False and the test passes (actual), this results in an OverPermission exception failure.
  4. If expected is False and the test fails (actual), this is a success.

As such, negative and positive testing can be applied using this decorator.

Parameters:
  • service – A OpenStack service. Examples: “nova” or “neutron”.
  • rule

    A policy action defined in a policy.json file (or in code).

    Note

    Patrole currently only supports custom JSON policy files.

  • admin_only – Skips over oslo.policy check because the policy action defined by rule is not enforced by the service’s policy enforcement engine. For example, Keystone v2 performs an admin check for most of its endpoints. If True, rule is effectively ignored.
  • expected_error_code

    Overrides default value of 403 (Forbidden) with endpoint-specific error code. Currently only supports 403 and 404. Support for 404 is needed because some services, like Neutron, intentionally throw a 404 for security reasons.

    Warning

    A 404 should not be provided unless the endpoint masks a Forbidden exception as a Not Found exception.

  • extra_target_data

    Dictionary, keyed with oslo.policy generic check names, whose values are string literals that reference nested tempest.base.BaseTestCase attributes. Used by oslo.policy for performing matching against attributes that are sent along with the API calls. Example:

    extra_target_data={
        "target.token.user_id":
        "os_alt.auth_provider.credentials.user_id"
    })
    
Raises:
  • NotFound – If service is invalid or if Tempest credentials cannot be found.
  • Forbidden – For item (2) above.
  • RbacOverPermission – For item (3) above.

Examples:

@rbac_rule_validation.action(
    service="nova", rule="os_compute_api:os-agents")
def test_list_agents_rbac(self):
    # The call to ``switch_role`` is mandatory.
    self.rbac_utils.switch_role(self, toggle_rbac_role=True)
    self.agents_client.list_agents()

The Policy Authority Module

Using the Policy Authority Module, policy verification is performed by:

  1. Pooling together the default in-code policy rules.
  2. Overriding the defaults with custom policy rules located in a policy.json, if the policy file exists and the custom policy definition is explicitly defined therein.
  3. Confirming that the policy action – for example, “list_users” – exists. (oslo.policy otherwise claims that role “foo” is allowed to perform policy action “bar”, for example, because it defers to the “default” policy rule and oftentimes the default can be “anyone allowed”).
  4. Performing a call with all necessary data to oslo.policy and returning the expected result back to rbac_rule_validation decorator.
class patrole_tempest_plugin.policy_authority.PolicyAuthority(project_id, user_id, service, extra_target_data=None)

A class for parsing policy rules into lists of allowed roles.

RBAC testing requires that each rule in a policy file be broken up into the roles that constitute it. This class automates that process.

The list of roles per rule can be reverse-engineered by checking, for each role, whether a given rule is allowed using oslo policy.

__init__(project_id, user_id, service, extra_target_data=None)

Initialization of Rbac Policy Parser.

Parses a policy file to create a dictionary, mapping policy actions to roles. If a policy file does not exist, checks whether the policy file is registered as a namespace under oslo.policy.policies. Nova, for example, doesn’t use a policy.json file by default; its policy is implemented in code and registered as ‘nova’ under oslo.policy.policies.

If the policy file is not found in either place, raises an exception.

Additionally, if the policy file exists in both code and as a policy.json (for example, by creating a custom nova policy.json file), the custom policy file over the default policy implementation is prioritized.

Parameters:
  • project_id (uuid) – project_id of object performing API call
  • user_id (uuid) – user_id of object performing API call
  • service (string) – service of the policy file
  • extra_target_data (dict) – dictionary containing additional object data needed by oslo.policy to validate generic checks
classmethod validate_service(service)

Validate whether the service passed to __init__ exists.

Creative Commons Attribution 3.0 License

Except where otherwise noted, this document is licensed under Creative Commons Attribution 3.0 License. See all OpenStack Legal Documents.