This document is written for other developers working on OpenStack. Its goal is to describe various concepts in a way that other developers, who may not be familiar with keystone, can digest and use effectively in their projects. The introductory paragraph was phrased as if the v3 API just became a thing, when it has actually been around for a long time. It also eluded to underlying implementation details by mentioning paste pipelines, which we no longer use. This commit updates the introduction to be more relevant to the state of things today. Change-Id: I79564dc99fd65a5609bd548d12a0413ca3ee6b2a
11 KiB
Keystone for other services
This document provides a summary of some things that other services need to know about how keystone works, and specifically about how they can take advantage of the v3 API. The v3 API was introduced as a stable API in the Grizzly release.
Glossary
- Authentication
-
The process of determining if a user is who they claim to be (authN).
- Authorization
-
The process of determining if a user can do what they are requesting (authZ).
- Scope
-
A specific operating context. This is commonly used when describing the authorization a user may have. For example, a user with a role assignment on a project can get a token scoped to that project, ultimately operating within that project's scope.
- System
-
An assignment target that refers to a collection of API services as a whole. Users and groups can be granted authorization on the deployment system.
- Service
-
OpenStack services like identity, compute, image, etc.
- Domain
-
A container for users, projects, and groups. A domain is also an assignment target for users and groups. It's possible for users and groups to have authorization on domains outside of the domain associated to their reference.
- Project
-
A container and a namespace for resources isolated within OpenStack. A user, or group of users, must have a role assignment on a project in order to interact with it.
- Token
-
A self-service resource that proves a user's identity and authentication. It can optionally carry a user's authorization, allowing them to interact with OpenStack services.
- Role
-
A string that represents one or more permissions or capabilities.
- Role Assignment
-
An association between an actor and a target that results in authorization. Actors can be users or groups of users. Targets can be projects, domains, or the deployment system itself.
- User
-
A entity modeling an end-user of the system.
- Group
-
A container for users. Users indirectly inherit any authorization the group has on projects, domains, or the system.
Domains
A major new feature in v3 is domains. Every project, user, and user
group is owned by a domain (reflected by their domain_id
value) which provides them their own namespace. For example, unlike in
v2.0, usernames are no longer unique across the deployment. You can have
two users with the same name, but they must be in different domains.
However, user IDs are assigned to users by keystone and are expected to
be unique across the deployment. All of this logic applies to projects,
user groups and roles.
One of the great things about domains is that you can have one domain backed by SQL (for service users) and another backed by LDAP (the cloud is deployed into existing infrastructure).
The "default" domain
Note
The v2.0 API has been removed as of the Queens release. While this section references the v2.0 API, it is purely for historical reasons that clarify the existance of the default domain.
Domains were introduced as a v3-only feature. As a result, the v2.0 API didn't understand the concept of domains. To allow for both versions of the Identity API to run side-by-side, the idea of a default domain was established.
The default domain was a domain that was guaranteed to exist
and was created during the keystone-manage db_sync
process.
By default, the domain ID is default
and the name is
Default
, but it is possible to change these values through
keystone's configuration file. The v2.0 API would consider users and
projects existing within that domain as valid, but it would never expose
domain information through the API. This allowed the v2.0 API to operate
under the assumption that everything within the default domain
was accessible. This was crucial in avoiding namespace conflicts between
v2.0 and v3 where multiple domains existed. Using v3 allowed deployers
the ability to experiment with domains, while isolating them from the
v2.0 API.
As far as the v3 API is concerned, the default domain is simply a domain and doesn't carry any special connotation like it did with v2.0.
Authorization Scopes
End users use the Identity API as a way to express their authoritative power to other OpenStack services. This is done using tokens, which can be scoped to one of several targets depending on the users' role assignments. This is typically referred to as a token's scope. This happens when a user presents credentials, in some form or fashion, to keystone in addition to a desired scope. If keystone can prove the user is who they say they are (authN), it will then validate that the user has access to the scope they are requesting (authZ). If successful, the token response will contain a token ID and data about the transaction, such as the scope target and role assignments. Users can use this token ID in requests to other OpenStack services, which consume the authorization information associated to that token to make decisions about what that user can or cannot do within that service.
This section describes the various scopes available, and what they mean for services consuming tokens.
System Scope
A system-scoped token implies the user has authorization to act on the deployment system. These tokens are useful for interacting with resources that affect the deployment as a whole, or exposes resources that may otherwise violate project or domain isolation.
Good examples of system-scoped resources include:
- Services: Service entities within keystone that describe the services deployed in a cloud.
- Endpoints: Endpoints that tell users where to find services deployed in a cloud.
- Hypervisors: Hosts for servers that belong to various projects.
Domain Scope
A domain-scoped token carries a user's authorization on a specific domain. Ideally, these tokens would be useful for listing resources aggregated across all projects with that domain. They can also be useful for creating entities that must belong to a domain. Users and groups are good examples of this. The following is an example of how a domain-scoped token could be used against a service.
Assume a domain exists called Foo. and it contains projects call bar and baz. Let's also assume both projects contain compute servers running a workload. If Alice is a domain administrator for Foo, she should be able to pass her domain-scoped token to nova and ask for a list of instances. If nova supports domain-scoped token, the response would contain all instances in projects bar and baz.
Another example of using a domain-scoped token would be if Alice wanted to create a new project in domain Foo. When Alice sends a request for keystone to create a project, keystone should ensure the new project is created within the Foo domain, since that's the authorization associated to Alice's token.
Warning
This behavior isn't completely implemented, and is still in progress. This example describes the ideal behavior, specifically for developers looking to implement scope into their APIs.
Project Scope
A project-scoped token carries the role assignments a user has on a project. This type of scope is great for managing resources that fit nicely within project boundaries. Good examples of project-level resources that can be managed with project-scoped tokens are:
- Instances: Virtual compute servers that require a project association in order to be created.
- Volumes: Storage devices that can be attached to instances.
Unscoped
An unscoped token is a token that proves authentication, but doesn't carry any authorization. Users can obtain unscoped tokens by simply proving their identity with credentials. Unscoped tokens can be exchanged for any of the various scoped tokens if a user has authorization on the requested scope.
An example of where unscoped tokens are specifically useful is when users perform federated authentication. First, a user will receive an unscoped token pending successful federated authentication, which they can use to query keystone for a list of projects they're allowed to access. Then they can exchange their unscoped token for a project-scoped token allowing them to perform actions within a particular project.
Auth Token middleware
The auth_token
middleware handles token validation for
the different services. Conceptually, what happens is that
auth_token
pulls the token out of the
X-Auth-Token
request header, validates the token using
keystone, produces information about the identity (the API user) and
authorization context (the project, roles, etc) of the token, and sets
environment variables with that data. The services typically take the
environment variables, put them in the service's "context", and use the
context for policy enforcement via oslo.policy
.
Service tokens
Service tokens are a feature where the auth_token
middleware will also accept a service token in the
X-Service-Token
header. It does the same thing with the
service token as the user token, but the results of the token are passed
separately in environment variables for the service token (the service
user, project, and roles). If the service knows about these then it can
put this info in its "context" and use it for policy checks. For
example, assuming there's a special policy rule called
service_role
that works like the role
rule
except checks the service roles, you could have an
oslo.policy
rule like
service_role:service and user_id:%(user_id)s
such that a
service token is required along with the user owning the object.
Picking the version
Use version discovery to figure out what version the identity server supports rather than configuring the version. This will make it easier to adopt new API versions as they are implemented.
For information about how to accomplish service discovery with the keystoneauth library, please see the documentation.
Hierarchical Multitenancy
This feature is specific to v3 and allows projects to have parents, siblings, and children relationships with other projects.
Tokens scoped to projects in a hierarchical structure won't contain information about the hierarchy in the token response. If the service needs to know the hierarchy it should use the v3 API to fetch the hierarchy.