Jump to: navigation, search


Keystone Domains

The intent of domain is to define the administrative boundaries for management of Keystone entities. A domain can represent an individual, company, or operator owned space.

Problem Addressed

Keystone’s lack of administrative boundaries prohibits the possibility of safely exposing administrative activities directly to users of the system. User Stories that currently are not possible:

  • As a cloud user I want to be able to administer a set of users:
    • create users (aka sub-accounts) who can have access to my tenants/services give users access to tenants in my domain. specify roles for users in my domain. create groups and place users into groups.
      • (ayoung) unclear if Groups should be separate from tenants
      • (termie) This appears to be unrelated to the required work for domains and should be a separate feature.
      • (jrouault) Yes, it can be addressed seperately, but it is important to point out that groups are not equivelent to domains, but instead reside in domains.
  • As a cloud user I want to be able to control the kind of access that users have to my tenants/services by specifying role assignments for groups.
    • (termie) This appears to be unrelated to the required work for domains and should be a separate feature (with above).
    • (gyee) Yes. Groups can be a separate feature.

(termie) Some comments: What appears to be being described is a way to define a user that is an admin for a variety of tenants, especially one where the boundaries between which tenants a user is admin for is very well defined. One thing of note here is that this feature was described before the flexibility and power of the internal policy engine was known and I think there is good reason to revisit the design in light of those features. Some examples:

  • Assuming the creation of a new Domain data object, rules could be described naively as:
   rule:add_user_to_tenant -> (role:keystone_admin || 
       (role:tenant_admin && tenant_id:%(target_tenant_id)s) || 
       (domain_role:domain_admin && domain_id:%(target_domain_id)s))

Meaning that three people would have the rights to add a user to a tenant: (jrouault) i would rephrase this as three people have rights to give users 'access' to a tenant

    • somebody who is an admin of the entire keystone service,
    • somebody who is the admin for that tenant, (gyee) that would be either the keystone admin or domain admin
    • somebody who is the admin for the domain that tenant is a member of.
  • Likewise for managing which tenants are part of a domain you'd have something like:
   rule:add_tenant_to_domain -> (role:keystone_admin ||
       (domain_role:domain_admin && domain_id:%(target_domain_id)s))

I see these rules, and Domain-aware rules like them as being most of the work required to assign permissions based on Domains. The rest of the work being adding Domain information to users and tenants.


  1. If the only service that needs to know about domains is Keystone, why do we need to include domainID on serveral of the GET calls?
    • Those calls are related to how a client/user interacts with the Keystone management system. If the client is a UI (e.g. Dashboard) it will want to know about domains in order to manage them.
  2. Will users of different domains be allowed within the same group?
    • Groups, as defined here, are bound to a domain. Only users of that domain can be a members of the groups defined in that domain (termie): I'd like to move the group concept out of this blueprint (gyee): no objection here
  3. Are domains required? If so, what level (can a user be created without a domain id)?
    • Not explicityl. If an operator does not want to deal with domains, then just one domain would be created and all users would reside in that domain.
  4. What is a real-world example of a company using domains?
    • It is all about multi-tenancy. With domains, a cloud customer can be the owner of the domain. They can then create additional users in their domain. Create groups and assign the users to those groups. Create roles, or leverage global roles, and then create role assignments for users to their tenants.. etc. etc...
  5. Can a tenant belong to more than one domain?
    • No. A domain can have more than one tenant.
    • A user from one domain can be assigned a role association to a tenant in another domain
    • (termie): So tenants are per-domain but users are global and can be part of tenants from other domains? This wouldn't allow "creating users in your domain" but it would allow you to add a created user to a tenant under your domain or give it roles within your domain. Most current projects will still require that their names be globally unique.
    • (gyee) users are per domain as well. Cross domain role assignment is allowed.
    • (jrouault) termie, we need to be clear with terminology here. One does not "add a created user to a tenant". Rather, one would grant a user access to a tenant via role assignment. That user may exist in the same domain as the tenant, or a different domain entirely.
  6. What do you see as the difference between the Admin roleRef and the Domain-Admin roleRef? Is the Admin roleRef assigned to services (nova) only, while Domain-Admin roleRef is assigned to actual cloud users?
    • Domain Admin role assignment would give a user the ability to manage all the Domain entities (users, groups, role assignments, etc.). The Admin role assignment is service specific (e.g. Nova, Glance) (termie): roleRefs as defined before no longer exist, but it does seem likely that domains will have a separate repository of roles within their domain that are not the same as the roles that are passed to services (I used "domain_role" above in the examples to mark that).
  7. How would you define trust relationships between domains? Is there a shared token? How can we prevent a rogue service from creating domains that include malicious endpoints?
    • The only way a user from one domain A can get access to a tenant in another domain B is, is for the Domain B Admin to setup a role assignment to that effect. Authorization needs to be setup in Keystone (not there now) to control these CRUD operations. (termie): I think the examples above should cover this.
  8. What should happen, with respect to domains, when a new service self-registers with Keystone? Ex: NewCompute starts up, securely identifes keystone, and attempts to make it's endpoint available within Keystone. Should it assume endpoint availability within all tenants (thereby all domains) or only the tenants that are connected via a defaulted domain?
    • The service and its endpoints would be available for all domains... just like global role definitions are available for all domains. Some things live in global namespace, other things live in Domain namespac (termie): my understanding is that other services are likely domain-agnostic, only keystone will be using them as an administrative option, and horizon may provide some additional ui. (jrouault) that is correct, with services being global in nature they are domain agnostic
    • Should token expiration be allowed to vary domain by domain?
      • That certainly would be a nice feature to have. Although, I don't think it is something required for Essex (termie): I'd say no, not worth our time. (gyee) +1
  9. Why cant we have Groups to be part of tenant and allow all the functions mentioned here.
    • Tenants, as currently defined by Keystone (good or bad) is just a collection of services/resources. I would keep groups at the Domain level at equal pairing with users and tenants. This allows you to leverage groups and role assignments across tenants within a domain. Would this not satisfy the needs? ie

True administrative boundaries and isolation Management put into the hands of the resource owners Better line of sight of control Users are responsible for their own changes and the ramifications Ease of management Custom groups to fit business needs Role assignments to groups to reduce administrative effort Opens the door for new types of roles Self Service, Password Management Custom Roles


  • For things like billing, everything up the stack will need to be aware of domains, since in most cases the cardholder for the account would be a domain admin, not a tenant admin. (jrouault) Actually, I do not see this a problem, but as a benefit. Having the domain be a top level billable entity allows for multiple user accounts and tenant usage to roll-up to a single bill if that is desired by the cloud operator

Keystone Admin API additions Domain Operations:

  • GET /domains Get a list of all domains GET /domains/{domainId} Get a specific domain POST /domains Create a domain PUT /domains/{domainId} Update a domain DELETE /domains/{domainId} Delete a domain GET /domains/{domainId}/users Get a domain's users GET /domains/{domainId}/tenants Get a domain's tenants GET /domains/{domainId}/roles Get a domain's roles GET /domains/{domainId}/groups Get a domain's groups (termie) drop groups? (gyee) we can do groups in another blueprint

Keystone Admin API changes User Operations

  • GET /users Response will change to include domainId for each user
  • POST /users Request will change to include a domainId
  • POST /users/{userId} Response will change to include the domainId
  • GET /users/{userId}/roles Response to include domainId for each role
  • GET /users/{userId}/roles/OS-KADM/{roleId} Response will change to include domainId

(termie): I'd not include the domain_id in the roles, and instead have a domain_roles call or the equivalent, the roles are checked separately and domain roles don't get returned to services. Additionally, users only have roles within tenants or within domains, so these last two calls are not needed / supported.

(jrouault) there are no role 'within' a tenant. There are roles that can be used to associate a user to a tenant (these are typically globally defined roles), and then there might be custom roles defined within in a domain that can be used for a similar purpose. Tentatively something closer to the following could work:

  • GET /users/{user_id}/domain/{domain_id}/domain_roles

(gyee) I am not sure if I unstanding your suggestion as all IDs (userId, roleId, etc) are globally unique. Why do we need to specify the domainId?

(jrouault) I would argue that user resource would hang off of the domain, and not the other way around as you show it. Tenant Operations

  • GET /tenants Response will change to include domainId POST /tenants Request will change to include the domainId GET /tenants/{tenantId}/users Response will change to include the domainId for each user GET /tenants/{tenantId}/OS-KSADM/roles Response will change to include the domainId for each role (termie): tenants don't have roles on their own, so this can be dropped (gyee) isn't tenant roles a fundamental concept in Keystone? Not sure if I understand your suggestion here. (jrouault) This call is listing the role associations that have been setup for the given tenant GET /tenants/{tenantId}/users/{userId}/roles Response will change to include domainId (termie): as mentioned above, user-domain roles are not the same as user-tenant roles so this call would not return user-domain roles. (gyee) tenants and users are always part of a domain. (jrouault) this call is listing the role associations that have been setup for the given user on the specified tenant

Role Operations

  • GET /OS-KSADM/roles Response will change to include domainId POST /OS-KSADM/roles Request will change to include domainId GET /OS-KSADM/roles/{roleId} Response will change to include domainId

(termie): in general none of these will need be touched as the domain-roles can be separate from these (gyee) again, roles will be part of a domain. Global roles are part of all domains. Compatibility Can we add to the spec how we will make this compatible with existing services running on the 2.0 API? Will this have any impact on other services? Will they need to store/manage/interact with domains, for example when storing tenant_id for project_id in Nova will Nova額 need to also store domain? Ideally current Keystone deployers and service developers can opt-in to this functionality and Keystone will use something like a default domain to abstract the concept from them There should be no impact to the Services API or Middle-ware. Those will remain the same. The only service that will need to know about domains is Keystone.

Looking at the discussion above it appears there is some confusion about roles and how they work in the domain. Let me try to expand on my thoughts here: Role Definitions basically creates a named role within the system that can then be assigned to one or more users. A Role Assignment maps subject (user/group) to a role, apart from role mapping it is also used to map subject (user/group) to a tenant. Role Definition Role definitions are available for use across all domains (global) or for a single domain. For example, Nova may may define a global role 'sysadmin' Alternatively, a domain administrator may create a custom role named 'FooBarAdmin' for use only within her domain. Role definitions are handled by Role Operations in the example API shown below. If the role object includes a domainId, then it means the definition is scoped to a specific domain

  • POST [KeystoneaseURI]/roles Create a role definition PUT [KeystoneBaseURI]/roles/\{roleId\} Update a role definition GET [KeystoneBaseURI]/roles?serviceId List role definitions. GET [KeystoneBaseURI]/roles/\{roleId\} Get role definition DELETE [KeystoneBaseURI]/roles/\{roleId\} Delete a role definition

Role Assignments Role assignments can come in two flavors: Tenant-User and User-Only role assignment. A user-only role assignment links a user to a role. A tenant-user role assignment links a user to a role and to a tenant. (heckj): The User-Only role assignment doesn't make sense to me, especially as we're removing any sense of "global" roles. In it's place, I think a domain<->user role would be sensible, and I believe achieves what you're after. The way I'm thinking of that is a domain role is a association between a user and domain with a given Role name. Example tenant role assignment: “Bob” has the “nova-admin” role for tenant “tenant01” Example user role assignement: "Alice" has the "domainAdmin" role for domain XYZ. Or, "Jake" has the "keystoneAdmin" role User-only role Assignments are handled by User operations as demonstrated in the sample API below

  • GET [KeystoneBaseURI]/users/\{userId\}roles?serviceId

List a users role assignments

  • PUT [KeystoneBaseURI]/users/\{userId\}/roles/\{roleId\}

Create a user's role assignment

  • DELETE [KeystoneBaseURI]/users/\{userId\}/roles/\{roleId\}

Delete a usres's global role assignment Tenant-User role Assignments are handled by Tenant operations as demonstrated in the sample API below

  • GET [KeystoneBaseURI]/tenants/\{tenantId\}/roles?serviceId List tenant role assignment GET [KeystoneBaseURI]/tenants/\{tenantId\}/users/\{userId\}/roles?serviceId List tenant role assignment for a user PUT [KeystoneBaseURI]/tenants/\{tenantId\}/users/\{userId\}/roles/\{roleId\} Create tenant role assignment for a user DELETE [KeystoneBaseURI]/tenants/\{tenantId\}/users/\{userId\}/roles/\{roleId\} Delete tenant role assignment for a user