Quantum uses the Keystone identity service (openstack.keystone.org) as the default authentication service. When keystone is enabled Users submitting requests to the Quantum service must provide an authentication token in X-Auth-Token request header. The aforementioned token should have been obtained by authenticating with the keystone endpoint. For more information concerning authentication with Keystone, please refer to the Keystone documentation. When keystone is enabled, it is not mandatory to specify tenant_id for resources in create requests, as the tenant identifier will be derived from the Authentication token. Please note that the default authorization settings only allow administrative users to create resources on behalf of a different tenant. Quantum uses information received from Keystone to authorize user requests. Quantum handles two kind of authorization policies:
Operation-based: policies specify access criteria for specific operations, possibly with fine-grained control over specific attributes;
Resource-based: whether access to specific resource might be granted or not according to the permissions configured for the resource (currently available only for the network resource). The actual authorization policies enforced in Quantum might vary from deployment to deployment.
The policy engine reads entries from the policy.json
file. The actual location of this file might vary from distribution to distribution. Entries
can be updated while the system is running, and no service restart is required. That is to
say, everytime the policy file is updated, the policies will be automatically reloaded.
Currently the only way of updating such policies is to edit the policy file. Please note
that in this section we will use both the terms "policy" and "rule" to refer to objects
which are specified in the same way in the policy file; in other words, there are no syntax
differences between a rule and a policy. We will define a policy something which is matched
directly from the quantum policy engine, whereas we will define a rule as the elements of
such policies which are then evaluated. For instance in create_subnet:
[["admin_or_network_owner"]]
, create_subnet is
regarded as a policy, whereas admin_or_network_owner is
regarded as a rule.
Policies are triggered by the Quantum policy engine whenever one of them matches a Quantum
API operation or a specific attribute being used in a given operation. For instance the
create_subnet
policy is triggered every time a POST
/v2.0/subnets
request is sent to the Quantum server; on the other hand
create_network:shared
is triggered every time the shared attribute is explicitly specified (and set to a value different from
its default) in a POST /v2.0/networks
request. It is also worth mentioning that
policies can be also related to specific API extensions; for instance
extension:provider_network:set
will be triggered if the attributes defined
by the Provider Network extensions are specified in an API request.
An authorization policy can be composed by one or more rules. If more rules are specified, evaluation policy will be successful if any of the rules evaluates successfully; if an API operation matches multiple policies, then all the policies must evaluate successfully. Also, authorization rules are recursive. Once a rule is matched, the rule(s) can be resolved to another rule, until a terminal rule is reached.
The Quantum policy engine currently defines the following kinds of terminal rules:
Role-based rules: evaluate successfully if the user submitting the request has the specified role. For instance
"role:admin"
is successful if the user submitting the request is an administrator.Field-based rules: evaluate successfully if a field of the resource specified in the current request matches a specific value. For instance
"field:networks:shared=True"
is successful if the attribute shared of the network resource is set to true.Generic rules: compare an attribute in the resource with an attribute extracted from the user's security credentials and evaluates successfully if the comparison is successful. For instance
"tenant_id:%(tenant_id)s"
is successful if the tenant identifier in the resource is equal to the tenant identifier of the user submitting the request.
The following is an extract from the default policy.json file:
{
"admin_or_owner": [["role:admin"], ["tenant_id:%(tenant_id)s"]],
[1]
"admin_or_network_owner": [["role:admin"],
["tenant_id:%(network_tenant_id)s"]],
"admin_only": [["role:admin"]], "regular_user": [],
"shared": [["field:networks:shared=True"]],
"default": [["rule:admin_or_owner"]],
[2]
"create_subnet": [["rule:admin_or_network_owner"]],
"get_subnet": [["rule:admin_or_owner"], ["rule:shared"]],
"update_subnet": [["rule:admin_or_network_owner"]],
"delete_subnet": [["rule:admin_or_network_owner"]],
"create_network": [],
"get_network": [["rule:admin_or_owner"], ["rule:shared"]],
[3]
"create_network:shared": [["rule:admin_only"]],
[4]
"update_network": [["rule:admin_or_owner"]],
"delete_network": [["rule:admin_or_owner"]],
"create_port": [],
"create_port:mac_address": [["rule:admin_or_network_owner"]],
[5]
"create_port:fixed_ips": [["rule:admin_or_network_owner"]],
"get_port": [["rule:admin_or_owner"]],
"update_port": [["rule:admin_or_owner"]],
"delete_port": [["rule:admin_or_owner"]]
}
[1] is a rule which evaluates successfully if the current user is an administrator or the owner of the resource specified in the request (tenant identifier is equal).
[2] is the default policy which is always evaluated if an API operation does not match any of the policies in policy.json.
[3] This policy will evaluate successfully if either admin_or_owner, or shared evalutes successfully.
[4] This policy will restrict the ability of manipulating the shared attribute for a network to administrators only.
[5] This policy will restrict the ability of manipilating the mac_address attribute for a port only to administrators and the owner of the network where the port is attached.
In some cases, some operations should be restricted to administrators only; therefore, as a further example, let us consider how this sample policy file should be modified in a scenario where tenants are allowed only to define networks and see their resources, and all the other operations can be performed only in an administrative context:
{
"admin_or_owner": [["role:admin"], ["tenant_id:%(tenant_id)s"]],
"admin_only": [["role:admin"]], "regular_user": [],
"default": [["rule:admin_only"]],
"create_subnet": [["rule:admin_only"]],
"get_subnet": [["rule:admin_or_owner"]],
"update_subnet": [["rule:admin_only"]],
"delete_subnet": [["rule:admin_only"]],
"create_network": [],
"get_network": [["rule:admin_or_owner"]],
"create_network:shared": [["rule:admin_only"]],
"update_network": [["rule:admin_or_owner"]],
"delete_network": [["rule:admin_or_owner"]],
"create_port": [["rule:admin_only"]],
"get_port": [["rule:admin_or_owner"]],
"update_port": [["rule:admin_only"]],
"delete_port": [["rule:admin_only"]]
}