Trust delegation in Openstack using Keystone trusts

In one of our blog posts we presented a basic tool which extends the Openstack Nova client and supports executing API calls at some point in the future. Much has evolved since then: the tool is not just a wrapper around Openstack clients anymore and instead we rebuilt it in the context of the Openstack Mistral project which provides very nice workflow as service capabilities – this will be elaborated a bit more in a future blog post. During this process we came across a very interesting feature in Keystone which we were not aware of – Trusts. Trusts is a mechanism in Keystone which enables delegation of roles and even impersonation of users from a trustor to a  trustee; it has many uses but is particularly useful in an Openstack administration context. In this blog post we will cover basic command line instructions to create  and use trusts.

Setting up

First of all – trusts are only available in Keystone v3, v3 endpoints must be exposed for Keystone.

Check your openstack-client and keystone version. We had issues where Keystone Trusts were not working due to an outdated client version. Here we use openstack-client version 3.0.1 and keystone 10.0.0. Versions can be checked as follows:

:# openstack --version
:# keystone-manage --version

The openstack client can be updated using pip as follows:

:# sudo pip install --upgrade python-openstackclient

Example of users and projects

For all the commands shown in this blog post we will use the following users and projects so it is easier for you to understand what each command does. Each user has admin and member roles in their respective projects – the admin user only has access to the admin project and the alt_demo user only has access to alt_demo project.

| User ID                          | Name     |
| 54e64304fec34a06b20893b35acbdbfa | alt_demo |
| a91584188d074a36886247eff94ee1de | admin    |

| Project ID                       | Name               |
| aec1f0c8e503439ebaf7a612dcb60d96 | admin              |
| ff777ec62c7842e280db0194a27bd3dc | alt_demo           |

Creating trusts

Creating a trust relationship between users is fairly straightforward. The basic premise is that one user can authorize another user to act on her behalf by creating an Openstack trust object. More concretely, the trustor creates a trust object which enables a trustee to act on her behalf: the trustee uses her own credentials and the trust_id and is then able to act on behalf of the trustor.

The basic syntax of the command is shown below; This command returns a trust_id which can be used to authenticate operations in any Openstack service.

Here, we assume that credentials are configured as environment variables as is standard practice, so we don’t have to provide them as parameters in the command itself.

openstack trust create –project <project-id> –role <role-id> –impersonate  <trustor-user-id> <trustee-user-id>

# Alt_demo user granting member access to alt_demo project for admin user

openstack trust create --impersonate --project ff777ec62c7842e280db0194a27bd3dc --role 9fe2ff9ee4384b1894a90878d3e92bab(*member role) 54e64304fec34a06b20893b35acbdbfa a91584188d074a36886247eff94ee1de

In this case a trustor, alt_demo, gives a specific role, member, in a project, alt_demo, for a trustee, admin. The trustee, admin, then will be able to perform any Openstack operations in that project based on the role provided.

Note that the trustor can only grant trusts of roles and projects for which it has authorization; e.g. if the trustor is only a member in a certain project he cannot provide delegated admin role for another user in that same project using trusts.

The impersonate flag changes the attribute user in the token created using the trust_id, the user will be the trustor itself in case the flag is present otherwise the user in the token is the trustee.

Acting on the trustor’s behalf

In order to use the trust_id provided by the command above first we need to remove any environment variables related to projects and domains. This information is already included in the token created by the trust_id (an exception is thrown if there is a conflict between the environment variables and the trust_id).

To check for environment variables and remove them use the commands below:

:# env | grep OS

:# unset {VARIABLE_NAME}

Without any project or domain variable in our environment now we are good to go using Openstack API calls!

openstack --os-trust-id 99905e50d80749b5a24292e830fff10c server create --flavor 1 --image <image-id> Server-Test

This command, executed with the trustee credentials, creates a VM in the project specified by the trust_id, which is associated with the trustor: the trustor can log into the Openstack web interface and will see this VM as if she had created it herself.

In case you don’t use environment variables there are very few changes to make in the API call:

openstack --os-trust-id 99905e50d80749b5a24292e830fff10c --os-username admin --os-password REDACTED --os-auth-url --os-region-name RegionOne server create --flavor 1 --image <image-id> Server-Test

Adding these parameters after the command openstack will be the same as using environment variables allowing the admin user to create a VM in the alt_demo project.


In this blog post we gave an introduction to Keystone Trust and an example of how it can be used. Note that the trust mechanisms do not solve the general problem of Openstack admins being able to act on the user’s behalf (eg creating VMs for the user based on snapshots etc) as the users still need to authorize them to do so, although there known workarounds.  However, it is very useful capability which is used in more complex configurations such as those where Openstack services need to act on behalf of a user.

1 Comment

  1. Glad you found them useful . Trusts were originally developed for Heat, to be able to perform operations on a users behalf long after the user is no longer available to authorize them. Glad to find they are usable to a wider array of uses

Leave a Reply

Your email address will not be published. Required fields are marked *