From 1908a2d7ba14b830648078e6871fba0e6644fdf5 Mon Sep 17 00:00:00 2001 From: Joe Heck Date: Sun, 29 Jan 2012 13:47:29 -0800 Subject: format tweaks and moving old docs --- docs/source/backends.rst | 188 ---------- docs/source/configuringservices.rst | 174 +++++++++ docs/source/index.rst | 6 + docs/source/middleware_architecture.rst | 529 ++++++++++++++++++++++++++++ docs/source/nova-api-paste.rst | 142 ++++++++ docs/source/old/backends.rst | 188 ++++++++++ docs/source/old/configuringservices.rst | 333 ----------------- docs/source/old/middleware_architecture.rst | 529 ---------------------------- docs/source/old/nova-api-paste.rst | 142 -------- docs/source/setup.rst | 2 +- 10 files changed, 1040 insertions(+), 1193 deletions(-) delete mode 100644 docs/source/backends.rst create mode 100644 docs/source/configuringservices.rst create mode 100644 docs/source/middleware_architecture.rst create mode 100644 docs/source/nova-api-paste.rst create mode 100644 docs/source/old/backends.rst delete mode 100644 docs/source/old/configuringservices.rst delete mode 100644 docs/source/old/middleware_architecture.rst delete mode 100644 docs/source/old/nova-api-paste.rst diff --git a/docs/source/backends.rst b/docs/source/backends.rst deleted file mode 100644 index b3fc2d91..00000000 --- a/docs/source/backends.rst +++ /dev/null @@ -1,188 +0,0 @@ -.. - Copyright 2011 OpenStack, LLC - All Rights Reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); you may - not use this file except in compliance with the License. You may obtain - a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - License for the specific language governing permissions and limitations - under the License. - -======== -Backends -======== - -Keystone supports multiple types of data stores for things like users, tenants, and -tokens, including SQL, LDAP, and memcache. - -SQL -=== - -In the default backend configuration (SQL-only), Keystone depends on the following database tables. - -``users`` ---------- - -``id`` - Auto-incremented primary key. -``name`` - Unqiue username used for authentication via ``passwordCredentials``. -``password`` - Password used for authentication via ``passwordCredentials``. - - Salted and hashed using ``passlib``. -``email`` - Email address (uniqueness is expected, but not enforced). -``enabled`` - If false, the user is unable to authenticate and the user's tokens will fail validation. -``tenant_id`` - Default tenant for the user. - -``tokens`` ----------- - -``id`` - The actual token provided after successful authentication (*plaintext*). -``user_id`` - References the user who owns the token. -``tenant_id`` - (*optional*) References the tenant the token is scoped to. -``expires`` - Indicates the expiration date of the token, after which the token can no longer be validated successfully. - -``tenants`` ------------ - -``id`` - Auto-incremented primary key. -``name`` - Unique string identifying the tenant. -``desc`` - Description of the tenant. -``enabled`` - If false, users are unable to scope to the tenant. - -``roles`` ---------- - -``id`` - Auto-incremented primary key. -``name`` - Name of the role. - - If the role is owned by a service, the role name **must** follow the convention:: - - serviceName:roleName -``desc`` - Description of the role. -``service_id`` - (*optional*) References the service that owns the role. - -``user_roles`` --------------- - -Maps users to the roles that have been granted to them (*optionally*, within the scope of a tenant). - -``id`` - Auto-incremented primary key. -``user_id`` - References the user the role is granted to. -``role_id`` - References the granted role. -``tenant_id`` - (*optional*) References a tenant upon which this grant is applies. - -``services`` ------------- - -``id`` - Auto-incremented primary key. -``name`` - Unique name of the service. -``type`` - Indicates the type of service (e.g. ``compute``, ``object``, ``identity``, etc). - - This can also be extended to support non-core services. Extended services - follow the naming convention ``extension:type`` (e.g. ``dnsextension:dns``). -``desc`` - Describes the service. -``owner_id`` - (*optional*) References the user who owns the service. - -``credentials`` ---------------- - -Currently only used for Amazon EC2 credential storage, this table is designed to support multiple -types of credentials in the future. - -``id`` - Auto-incremented primary key. -``user_id`` - References the user who owns the credential. -``tenant_id`` - References the tenant upon which the credential is valid. -``types`` - Indicates the type of credential (e.g. ``Password``, ``APIKey``, ``EC2``). -``key`` - Amazon EC2 access key. -``secret`` - Amazon EC2 secret key. - -``endpoints`` -------------- - -Tenant-specific endpoints map endpoint templates to specific tenants. -The ``tenant_id`` which appears here replaces the -``%tenant_id%`` template variable in the specified endpoint template. - -``id`` - Auto-incremented primary key. -``tenant_id`` - References the tenant this endpoint applies to. -``endpoint_template_id`` - The endpoint template to appear in the user's service catalog. - -``endpoint_templates`` ----------------------- - -A multi-purpose model for the service catalog which can be: - -- Provided to users of a specific tenants via ``endpoints``, when ``is_global`` is false. -- Provided to all users as-is, when ``is_global`` is true. - -``id`` - Auto-incremented primary key. -``region`` - Identifies the geographic region the endpoint is physically located within. -``service_id`` - TODO: References the service which owns the endpoints? -``public_url`` - Appears in the service catalog [#first]_. - - Represents an endpoint available on the public Internet. -``admin_url`` - Appears in the service catalog [#first]_. - - Users of this endpoint must have an Admin or ServiceAdmin role. -``internal_url`` - Appears in the service catalog [#first]_. - - Represents an endpoint on an internal, unmetered network. -``enabled`` - If false, this endpoint template will not appear in the service catalog. -``is_global`` - If true, this endpoint can not be mapped to tenant-specific endpoints, and ``%tenant_id%`` will not be substituted in endpoint URL's. Additionally, this endpoint will appear for all users. -``version_id`` - Identifies the version of the API contract that endpoint supports. -``version_list`` - A URL which lists versions supported by the endpoint. -``version_info`` - A URL which provides detailed version info regarding the service. - -.. [#first] ``%tenant_id%`` may be replaced by actual tenant references, depending on the value of ``is_global`` and the existence of a corresponding ``endpoints`` record. diff --git a/docs/source/configuringservices.rst b/docs/source/configuringservices.rst new file mode 100644 index 00000000..88bb9c15 --- /dev/null +++ b/docs/source/configuringservices.rst @@ -0,0 +1,174 @@ +.. + Copyright 2011 OpenStack, LLC + All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); you may + not use this file except in compliance with the License. You may obtain + a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + License for the specific language governing permissions and limitations + under the License. + +========================================== +Configuring Services to work with Keystone +========================================== + +.. toctree:: + :maxdepth: 1 + + nova-api-paste + middleware_architecture + +Once Keystone is installed and running (see :doc:`configuration`), services need to be configured to work +with it. To do this, we primarily install and configure middleware for the OpenStack service to handle authentication tasks or otherwise interact with Keystone. + +In general: +* Clients making calls to the service will pass in an authentication token. +* The Keystone middleware will look for and validate that token, taking the appropriate action. +* It will also retrive additional information from the token such as user name, id, tenant name, id, roles, etc... + +The middleware will pass those data down to the service as headers. More details on the architecture of +that setup is described in :doc:`middleware_architecture` + +Setting up credentials +====================== + +Admin Token +----------- + +For a default installation of Keystone, before you can use the REST API, you +need to define an authorization token. This is configured in the keystone.conf file under the section ``[DEFAULT]``. In the sample file provided with the keystone project, the line defining this token is + + [DEFAULT] + admin_token = ADMIN + +This is a "shared secret" between keystone and other openstack services, and will need to be set the +same between those services in order for keystone services to function correctly. + +Setting up tenants, users, and roles +------------------------------------ + +You need to minimally define a tenant, user, and role to link the tenant and user as the most basic set of details to get other services authenticating and authorizing with keystone. See doc:`configuration` for a walk through on how to create tenants, users, and roles. + +Setting up services +=================== + +Defining Services +----------------- + +Keystone also acts as a service catalog to let other OpenStack systems know +where relevant API endpoints exist for OpenStack Services. The OpenStack +Dashboard, in particular, uses this heavily - and this **must** be configured +for the OpenStack Dashboard to properly function. + +Here's how we define the services:: + + keystone-manage service create name=nova service_type=compute description="Nova Compute Service" + keystone-manage service create name=ec2 service_type=ec2 description="EC2 Compatibility Layer" + keystone-manage service create name=glance service_type=image description="Glance Image Service" + keystone-manage service create name=keystone service_type=identity description="Keystone Identity Service" + keystone-manage service create name=swift service_type=object-store description="Swift Service" + +The endpoints for these services are defined in a template, an example of which is in the project as the file ``etc/default_catalog.templates``. + +Setting Up Middleware +===================== + +Keystone Auth-Token Middleware +-------------------------------- + +The Keystone auth_token middleware is a WSGI component that can be inserted in +the WSGI pipeline to handle authenticating tokens with Keystone. + +Configuring Nova to use Keystone +-------------------------------- + +To configure Nova to use Keystone for authentication, the Nova API service +can be run against the api-paste file provided by Keystone. This is most +easily accomplished by setting the `--api_paste_config` flag in nova.conf to +point to `examples/paste/nova-api-paste.ini` from Keystone. This paste file +included references to the WSGI authentication middleware provided with the +keystone installation. + +When configuring Nova, it is important to create a admin service token for +the service (from the Configuration step above) and include that as the key +'admin_token' in the nova-api-paste.ini. See the documented +:doc:`nova-api-paste` file for references. + +Configuring Swift to use Keystone +--------------------------------- + +Similar to Nova, swift can be configured to use Keystone for authentication +rather than it's built in 'tempauth'. + +1. Add a service endpoint for Swift to Keystone + +2. Configure the paste file for swift-proxy (`/etc/swift/swift-proxy.conf`) + +3. Reconfigure Swift's proxy server to use Keystone instead of TempAuth. + Here's an example `/etc/swift/proxy-server.conf`:: + + [DEFAULT] + bind_port = 8888 + user = + + [pipeline:main] + pipeline = catch_errors cache keystone proxy-server + + [app:proxy-server] + use = egg:swift#proxy + account_autocreate = true + + [filter:keystone] + use = egg:keystone#tokenauth + auth_protocol = http + auth_host = 127.0.0.1 + auth_port = 35357 + admin_token = 999888777666 + delay_auth_decision = 0 + service_protocol = http + service_host = 127.0.0.1 + service_port = 8100 + service_pass = dTpw + cache = swift.cache + + [filter:cache] + use = egg:swift#memcache + set log_name = cache + + [filter:catch_errors] + use = egg:swift#catch_errors + + Note that the optional "cache" property in the keystone filter allows any + service (not just Swift) to register its memcache client in the WSGI + environment. If such a cache exists, Keystone middleware will utilize it + to store validated token information, which could result in better overall + performance. + +4. Restart swift + +5. Verify that keystone is providing authentication to Swift + +Use `swift` to check everything works (note: you currently have to create a +container or upload something as your first action to have the account +created; there's a Swift bug to be fixed soon):: + + $ swift -A http://127.0.0.1:5000/v1.0 -U joeuser -K secrete post container + $ swift -A http://127.0.0.1:5000/v1.0 -U joeuser -K secrete stat -v + StorageURL: http://127.0.0.1:8888/v1/AUTH_1234 + Auth Token: 74ce1b05-e839-43b7-bd76-85ef178726c3 + Account: AUTH_1234 + Containers: 1 + Objects: 0 + Bytes: 0 + Accept-Ranges: bytes + X-Trans-Id: tx25c1a6969d8f4372b63912f411de3c3b + +.. WARNING:: + Keystone currently allows any valid token to do anything with any account. + diff --git a/docs/source/index.rst b/docs/source/index.rst index 8b12ff93..5d7c80fa 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -63,6 +63,12 @@ Developers Documentation developing architecture api_curl_examples + +Code Documentation +================== +.. toctree:: + :maxdepth: 1 + modules Indices and tables diff --git a/docs/source/middleware_architecture.rst b/docs/source/middleware_architecture.rst new file mode 100644 index 00000000..a8c38f3c --- /dev/null +++ b/docs/source/middleware_architecture.rst @@ -0,0 +1,529 @@ +.. + Copyright 2011 OpenStack, LLC + All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); you may + not use this file except in compliance with the License. You may obtain + a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + License for the specific language governing permissions and limitations + under the License. + +======================= +Middleware Architecture +======================= + +Abstract +======== + +The Keystone middleware architecture supports multiple authentication protocols +in a pluggable manner in OpenStack. By providing support for authentication via +pluggable authentication components, this architecture allows OpenStack +services to be integrated easily into existing deployment environments. It also +provides a path by which to implement support for emerging authentication +standards such as OAUTH. + +Rationale and Goals +=================== + +Keystone is the Identity service for OpenStack. To support the easy integrating +of OpenStack with existing authentication and identity management systems, +Keystone supports talking to multiple backends like LDAP. +And to support different deployment needs, it can support multiple +authentication protocols via pluggable 'authentication components' implemented +as WSGI middleware. + +In this document, we describe the responsibilities of the authentication +middleware. We describe how these interact with underlying OpenStack services +and how existing services can be modified to take advantage of pluggable +authentication. The goal is to allow OpenStack services to be integrated easily +into existing deployment environments and to provide a path by which to +implement support for emerging authentication standards such as OAUTH. + +Specification Overview +====================== + +'Authentication' is the process of determining that users are who they say they +are. Typically, 'authentication protocols' such as HTTP Basic Auth, Digest +Access, public key, token, etc, are used to verify a user's identity. In this +document, we define an ''authentication component'' as a software module that +implements an authentication protocol for an OpenStack service. + +At a high level, an authentication component is simply a reverse proxy that +intercepts HTTP calls from clients. Once it has verified a user's identity, the +authentication component extends the call with information about the current +user and forwards the request to the OpenStack service. Otherwise, if a user's +identity is not verified, the message is rejected before it gets to the +service. This is illustrated in :ref:`authComponent`. + +.. _authComponent: + +Authentication Component +------------------------ + +Figure 1. Authentication Component + +.. image:: images/graphs_authComp.svg + :width: 100% + :height: 180 + :alt: An Authentication Component + +Authentication components may operate in 'delegated mode'. In this mode, the +decision reject an unauthenticated client is delegated to the OpenStack +service. Delegated mode is illustrated in :ref:`authComponentDelegated`. + +Here, requests are forwarded to the OpenStack service with an identity status +message that indicates whether the client's identity has been confirmed or is +indeterminate. It is the OpenStack service that decides whether or not a reject +message should be sent to the client. Note that it is always the responsibility +of the Authentication Component to transmit reject messages to the client. + +.. _authComponentDelegated: + +Authentication Component (Delegated Mode) +----------------------------------------- + +Figure 2. Authentication Component (Delegated Mode) + +.. image:: images/graphs_authCompDelegate.svg + :width: 100% + :height: 180 + :alt: An Authentication Component (Delegated Mode) + +In this architecture, we define interactions between the authentication component +and the OpenStack service. Interactions between the client and the +authentication component are defined only for exceptional cases. For example, +we define the message that should be returned when the OpenStack service is +down. Other interactions, however, are defined by the underlying authentication +protocol and the OpenStack service and are considered out of scope. + +.. _deployStrategies: + +Deployment Strategies +===================== + +An authentication component may be integrated directly into the service +implementation, or it may be deployed separately as an HTTP reverse proxy. This +is illustrated in :ref:`deployment`, showing both approaches to +authentication, labeled Option (a) and Option (b). + +.. _deployment: + +Authentication Component Deployments Options +-------------------------------------------- + +Figure 3. Authentication Component Deployments Options + +.. image:: images/images_layouts.svg + :width: 100% + :height: 180 + :alt: Authentication Component Deployments Options + +In Option (a), the component is integrated into the service implementation. In +this case, communication between the authentication component and the service +can be efficiently implemented via a method call. In Option (b), the component +is deployed separately and communication between the service and the component +involves an HTTP request. In both cases, unauthenticated requests are filtered +before they reach the service. + +Each approach offers some benefits. Option (a) offers low latency and ease of +initial implementation, making it possibly most appropriate as a starting point +for simple configurations. Option (b) offers several key advantages that may be +of particular value in complex and dynamic configurations. It offers the +ability to scale horizontally in cases where authentication is computationally +expensive, such as when verifying digital signatures. Option (b) also allows +authentication components to be written in different programming languages. +Finally, Option (b) allows multiple authentication components to be deployed in +front of the same service. + +OpenStack services can support both embedded (Option (a)) and external (Option +(b)) deployment strategies. Individual authentication components should support +either strategy or they |may| support both strategies. In order to support +option (a), authentication components written in the Python programming +language should be written as WSGI middleware components (in accordance with +the Web Server Gateway Interface (WSGI) standard [PEP-333]_. + +Additionally, services should support the ability to swap between different +embedded or external authentication components via configuration options. + +Exchanging User Information +=========================== + +If a request is successfully authenticated, the authentication component must +extend the request by adding an ``X-Authorization`` header. The header |must| +be formatted as illustrated in :ref:`xAuthHeader`. + +.. _xAuthHeader: + +X-Authorization Header +---------------------- + +Example 1. X-Authorization Header:: + + X-Authorization: Proxy JoeUser + +Here, `Proxy` denotes that the authentication occurred via a proxy (in this +case authentication component) and ''JoeUser'' is the name of the user who +issued the request. + +.. note: + + We considered using an ``Authorization`` header rather than an + ``X-Authorization``, thereby following normal HTTP semantics. There are some + cases, however, where multiple ``Authorization`` headers need to be transmitted + in a single request. We want to assure ourselves that this will not break + common clients before we recommend the approach. + +Authentication components |may| extend the request with additional +information. For example, an authentication system may add additional headers +or modify the target URI to pass authentication information to the back-end +service. Additionally, an authentication component |may| strip sensitive +information — a plain text password, for example — from the request. That said, +an authentication component |should| pass the majority of the request +unmodified. + +Reverse Proxy Authentication +---------------------------- + +An OpenStack service |should| verify that it is receiving requests from a +trusted authentication component. This is particularly important in cases where +the authentication component and the OpenStack service are deployed separately. +In order to trust incoming requests, the OpenStack service should therefore +authenticate the authentication component. To avoid confusion, we call this +'reverse proxy authentication', since in this case the authentication +component is acting as an HTTP reverse proxy. + +Any HTTP-based authentication scheme may be used for reverse proxy +authentication; however, all OpenStack services and all authentication +components |must| support HTTP Basic Authentication as defined in +[RFC-2617]_. + +Whether or not reverse proxy authentication is required is strictly a +deployment concern. For example, an operations team may opt to utilize firewall +rules instead of an authentication protocol to verify the integrity of incoming +request. Because of this, both OpenStack services and authentication components +|must| also allow for unauthenticated communication. + +In cases where reverse proxy authentication is used, the authorization +component may receive an HTTP 401 authentication error or an HTTP 403 +authorization error. These errors indicate that the component does not have +access to the underlying OpenStack service. The authentication component +|must not| return these errors to the client application. Instead, the +component |must| return a 500 internal error. This is illustrated in +:ref:`proxyAuth` and :ref:`proxyAuthDelegated` below. The component +|should| format the errors in a manner that does not break the service +contract defined by the OpenStack service. :ref:`proxyAuthDelegated` +illustrates proxy authorization in delegated mode. Delegated mode is discussed +in detail in the next section. + +.. _proxyAuth: + +Reverse Proxy Authentication +---------------------------- + +Figure 4. Reverse Proxy Authentication + +.. image:: images/graphs_proxyAuth.svg + :width: 100% + :height: 180 + :alt: Reverse Proxy Authentication + +.. _proxyAuthDelegated: + +Reverse Proxy Authentication (Delegated Mode) +--------------------------------------------- + +Figure 5. Reverse Proxy Authentication (Delegated Mode) + +.. image:: images/graphs_delegate_forbiden_proxy.svg + :width: 100% + :height: 180 + :alt: Reverse Proxy Authentication (Delegated Mode) + +Delegated Mode +============== +In some cases, the decision to reject an unauthenticated request should be +delegated to the OpenStack service. An unauthenticated request may be +appropriate in cases when anonymous access is allowed. In order to support +these cases, an authentication component may be placed in Delegated Mode. In +this mode, the component forwards requests to the OpenStack service when the +client's identity has been confirmed or is indeterminate — that is when +credentials are missing. The authentication component directly rejects requests +with invalid credentials. Authentication components |must| extend the +request by adding an `X-Identity-Status` header. The identity status header +|must| contain one of the following values: + +Identity Status Values +---------------------- + +Confirmed + A `confirmed` value indicates that valid credentials were sent and identity + has been confirmed. The service can trust that the request has been sent on + behalf of the user specified in the `X-Authorization` header. + +Indeterminate + An `indeterminate` value indicates that no credentials were sent and + identity has not been confirmed. In this case, the service will receive an + `X-Authorization` header with no user entry as illustrated in + :ref:`xauth-header-indeterminate`. + +.. _xauth-header-indeterminate: + +Indeterminate Identity Headers +------------------------------ + +Example 2. Indeterminate Identity Headers:: + + X-Identity-Status: Indeterminate + X-Authorization: Proxy + +Services |may| reject a delegated request by issuing an HTTP 401 +authentication error or an HTTP 403 authorization error. These responses +|must| contain an ``WWW-Authenticate`` header with a value of ``Delegated`` as +illustrated in :ref:`unauthHeaders`. + +X-Identity-Status + Provides information on whether the request was authenticated or not. + +X-Tenant + Provides the tenant ID (as it appears in the URL in Keystone). This is to support any legacy implementations before Keystone switched to an ID/Name schema for tenants. + +X-Tenant-Id + The unique, immutable tenant Id + +X-Tenant-Name + The unique, but mutable (it can change) tenant name. + +X-User-Id + The user id of the user used to log in + +X-User-Name + The username used to log in + +X-User + The username used to log in. This is to support any legacy implementations before Keystone switched to an ID/Name schema for tenants. + +X-Roles + The roles associated with that user + +.. _unauthHeaders: + +Delegated WWW-Authenticate Header +--------------------------------- + +:: + + WWW-Authenticate: Delegated + +It is important to note that the actual reject message will likely be modified +by the authentication component in order to comply with the authentication +scheme it is implementing. This is illustrated in :ref:`delegateRejectBasic` and +:ref:`delegateRejectOAuth` below. + +.. _delegateRejectBasic: + +Delegated Reject Basic Auth +--------------------------- + +.. image:: images/graphs_delegate_reject_basic.svg + :width: 100% + :height: 180 + :alt: Delegated Reject Basic Auth + +.. _delegateRejectOAuth: + +Delegated Reject OAuth +---------------------- + +.. image:: images/graphs_delegate_reject_oauth.svg + :width: 100% + :height: 180 + :alt: Delegated Reject OAuth + +The presence of the `WWW-Authenticate` header with a value of `Delegated` +distinguishes a client authentication/authorization failure from a component +failure. For example, compare :ref:`delegateForbidden` with :ref:`proxyAuthDelegated`. In +:ref:`delegateForbidden`, the client is not allowed to access the OpenStack service. +In :ref:`proxyAuthDelegated`, it is the authentication component itself which is +unauthorized. + +.. _delegateForbidden: + +Delegated Reject Forbidden +-------------------------- + +Figure 8. Delegated Reject Forbidden + +.. image:: images/graphs_delegate_forbiden_basic.svg + :width: 100% + :height: 180 + :alt: Delegated Reject Forbidden + +Authentication components |must| support both delegated and undelegated +(standard) modes. Delegated mode |should| be configured via a configuration +option. Delegated mode |should| be disabled by default. + +OpenStack services are not required to support delegated mode. If a service +does not support delegated mode, it |must| respond with a 501 not implemented +error and an `WWW-Authenticate` header with a value of `Delegated`. The +authentication component |must not| return the error to the client +application. Instead, the component |must| return a 500 internal error; this is +illustrated in :ref:`delegateUnimplemented`. The component |should| +format the error in a manner that does not break the service contract defined +by the OpenStack service. The component should also log the error such that it +that will inform operators of the misconfiguration. + +.. _delegateUnimplemented: + +Unimplemented Delegated Mode +---------------------------- + +.. image:: images/graphs_delegate_unimplemented.svg + :width: 100% + :height: 180 + :alt: Unimplemented Delegated Mode + +Handling Direct Client Connections +================================== + +Requests from the authentication component to an OpenStack service |must| +contain an ``X-Authorization`` header. If the header is missing, and reverse +proxy authentication fails or is switched off, the OpenStack service |may| +assume that the request is coming directly from a client application. In this +case, the OpenStack service |must| redirect the request to the authentication +component by issuing an HTTP 305 User Proxy redirect. This is illustrated in +:ref:`redirect`. Note that the redirect response |must| include a ``Location`` header +specifying the authentication component's URL as shown in :ref:`redirect-response`. + +.. _redirect: + +Auth Component Redirect +----------------------- + +.. image:: images/graphs_305.svg + :width: 100% + :height: 280 + :alt: Auth Component Redirect + +.. _redirect-response: + +Auth Component Redirect Response +-------------------------------- + +:: + + HTTP/1.1 305 Use Proxy + Date: Thu, 28 Oct 2011 07:41:16 GMT + Location: http://sample.auth.openstack.com/path/to/resource + +Using Multiple Authentication Components +======================================== + +There are some use cases when a service provider might want to consider using +multiple authentication components for different purposes. For instance, a +service provider may have one authentication scheme to authenticate the users +of the service and another one to authenticate the administrators or operations +personnel that maintain the service. For such scenarios, we propose using a +mapper as illustrated in :ref:`multiAuth`. + +.. _multiAuth: + +Multiple Authentication Components +---------------------------------- + +.. image:: images/graphs_mapper.svg + :width: 100% + :height: 320 + :alt: Multiple Authentication Components + +At a high level, a mapper is a simple reverse proxy that intercepts HTTP calls +from clients and routes the request to the appropriate authentication +component. A mapper can make the routing decisions based on a number of routing +rules that map a resource to a specific authentication component. For example, +a request URI may determine whether a call should be authenticated via one +authentication component or another. + +Note that neither the authentication component nor the OpenStack service need +be aware of the mapper. Any external authentication component can be used +alongside others. Mappers may provide a means by which to offer support for +anonymous or guest access to a subset of service resources. A mapper may be +implemented via a traditional reverse proxy server such as Pound or Zeus. + +The Default Component +===================== + +Individual services |must| be distributed with a simple integrated +authentication component by default. Providing such a component lowers barriers +to the deployment of individual services. This is especially important to] +developers who may want to deploy OpenStack services on their own machines. +Also, since there is no direct dependency on an external authentication system, +OpenStack services can be deployed individually, without the need to stand up +and configure additional services. Finally, having a standard authentication +component that all services share promotes a separation of concerns. That is, +as a community we are explicitly stating that services should not develop their +own authentication mechanisms. Additional authentication components may be +developed, of course, but these components should not be intimately coupled to +any one particular service. + +As discussed in :ref:`deployStrategies`, an authentication component may be +integrated directly into the service implementation (Option (a)), or it may be +deployed separately as an HTTP reverse proxy (Option (b)). The default +component should be implemented to support Option (a) and services should +maintain support for Option (b). One way to achieve this is to provide a +method that allows the disabling of the default authentication component via +configuration. This is illustrated in :ref:`both`. Here, requests are +sent directly to the OpenStack service when the default authentication +component is disabled. + +We will discuss the design of the default component in an upcoming blueprint. + +.. _both: + +Disabled Embedded Component +--------------------------- + +.. image:: images/graphs_both.svg + :width: 100% + :height: 250 + :alt: Disabled Embedded Component + +Questions and Answers +===================== + +#. Why do authentication components send reject messages? Why not have + OpenStack services reject requests themselves? + + The content and format of an authentication failed message is determined by + the authentication scheme (or protocol). For the service to respond + appropriately, it would have to be aware of the authentication scheme in + which it participates; this defeats the purpose of pluggable authentication + components. + +#. Why require support for deploying authentication components in separate + nodes? + + The deployment strategy is very flexible. It allows for authentication + components to be horizontally scalable. It allows for components to be written + in different languages. Finally, it allows different authentication components + to be deployed simultaneously as described above. + +References +========== + +.. [PEP-333] pep0333 Phillip J Eby. 'Python Web Server Gateway Interface + v1.0.'' http://www.python.org/dev/peps/pep-0333/. + +.. [RFC-2617] rfc2617 J Franks. P Hallam-Baker. J Hostetler. S Lawrence. + P Leach. A Luotonen. L Stewart. ''HTTP Authentication: Basic and Digest + Access Authentication.'' http://tools.ietf.org/html/rfc2617. + +.. |must| replace:: must must +.. |should| replace:: should should +.. |may| replace:: may may +.. |must not| replace:: "must not" "must not" + diff --git a/docs/source/nova-api-paste.rst b/docs/source/nova-api-paste.rst new file mode 100644 index 00000000..586bac72 --- /dev/null +++ b/docs/source/nova-api-paste.rst @@ -0,0 +1,142 @@ +.. + Copyright 2011 OpenStack, LLC + All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); you may + not use this file except in compliance with the License. You may obtain + a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + License for the specific language governing permissions and limitations + under the License. + +nova-api-paste example +====================== +:: + + ####### + # EC2 # + ####### + + [composite:ec2] + use = egg:Paste#urlmap + /: ec2versions + /services/Cloud: ec2cloud + /services/Admin: ec2admin + /latest: ec2metadata + /2007-01-19: ec2metadata + /2007-03-01: ec2metadata + /2007-08-29: ec2metadata + /2007-10-10: ec2metadata + /2007-12-15: ec2metadata + /2008-02-01: ec2metadata + /2008-09-01: ec2metadata + /2009-04-04: ec2metadata + /1.0: ec2metadata + + [pipeline:ec2cloud] + pipeline = logrequest totoken authtoken keystonecontext cloudrequest authorizer ec2executor + + [pipeline:ec2admin] + pipeline = logrequest totoken authtoken keystonecontext adminrequest authorizer ec2executor + + [pipeline:ec2metadata] + pipeline = logrequest ec2md + + [pipeline:ec2versions] + pipeline = logrequest ec2ver + + [filter:logrequest] + paste.filter_factory = nova.api.ec2:RequestLogging.factory + + [filter:ec2lockout] + paste.filter_factory = nova.api.ec2:Lockout.factory + + [filter:totoken] + paste.filter_factory = keystone.middleware.ec2_token:EC2Token.factory + + [filter:ec2noauth] + paste.filter_factory = nova.api.ec2:NoAuth.factory + + [filter:authenticate] + paste.filter_factory = nova.api.ec2:Authenticate.factory + + [filter:cloudrequest] + controller = nova.api.ec2.cloud.CloudController + paste.filter_factory = nova.api.ec2:Requestify.factory + + [filter:adminrequest] + controller = nova.api.ec2.admin.AdminController + paste.filter_factory = nova.api.ec2:Requestify.factory + + [filter:authorizer] + paste.filter_factory = nova.api.ec2:Authorizer.factory + + [app:ec2executor] + paste.app_factory = nova.api.ec2:Executor.factory + + [app:ec2ver] + paste.app_factory = nova.api.ec2:Versions.factory + + [app:ec2md] + paste.app_factory = nova.api.ec2.metadatarequesthandler:MetadataRequestHandler.factory + + ############# + # Openstack # + ############# + + [composite:osapi] + use = egg:Paste#urlmap + /: osversions + /v1.1: openstackapi + + [pipeline:openstackapi] + pipeline = faultwrap authtoken keystonecontext ratelimit extensions osapiapp + + [filter:faultwrap] + paste.filter_factory = nova.api.openstack:FaultWrapper.factory + + [filter:auth] + paste.filter_factory = nova.api.openstack.auth:AuthMiddleware.factory + + [filter:noauth] + paste.filter_factory = nova.api.openstack.auth:NoAuthMiddleware.factory + + [filter:ratelimit] + paste.filter_factory = nova.api.openstack.limits:RateLimitingMiddleware.factory + + [filter:extensions] + paste.filter_factory = nova.api.openstack.extensions:ExtensionMiddleware.factory + + [app:osapiapp] + paste.app_factory = nova.api.openstack:APIRouter.factory + + [pipeline:osversions] + pipeline = faultwrap osversionapp + + [app:osversionapp] + paste.app_factory = nova.api.openstack.versions:Versions.factory + + ########## + # Shared # + ########## + + [filter:keystonecontext] + paste.filter_factory = keystone.middleware.nova_keystone_context:NovaKeystoneContext.factory + + [filter:authtoken] + paste.filter_factory = keystone.middleware.auth_token:filter_factory + service_protocol = http + service_host = 127.0.0.1 + service_port = 5000 + auth_host = 127.0.0.1 + auth_port = 35357 + auth_protocol = http + auth_uri = http://127.0.0.1:5000/ + admin_token = 999888777666 + ;Uncomment next line and check ip:port to use memcached to cache token requests + ;memcache_hosts = 127.0.0.1:11211 diff --git a/docs/source/old/backends.rst b/docs/source/old/backends.rst new file mode 100644 index 00000000..b3fc2d91 --- /dev/null +++ b/docs/source/old/backends.rst @@ -0,0 +1,188 @@ +.. + Copyright 2011 OpenStack, LLC + All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); you may + not use this file except in compliance with the License. You may obtain + a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + License for the specific language governing permissions and limitations + under the License. + +======== +Backends +======== + +Keystone supports multiple types of data stores for things like users, tenants, and +tokens, including SQL, LDAP, and memcache. + +SQL +=== + +In the default backend configuration (SQL-only), Keystone depends on the following database tables. + +``users`` +--------- + +``id`` + Auto-incremented primary key. +``name`` + Unqiue username used for authentication via ``passwordCredentials``. +``password`` + Password used for authentication via ``passwordCredentials``. + + Salted and hashed using ``passlib``. +``email`` + Email address (uniqueness is expected, but not enforced). +``enabled`` + If false, the user is unable to authenticate and the user's tokens will fail validation. +``tenant_id`` + Default tenant for the user. + +``tokens`` +---------- + +``id`` + The actual token provided after successful authentication (*plaintext*). +``user_id`` + References the user who owns the token. +``tenant_id`` + (*optional*) References the tenant the token is scoped to. +``expires`` + Indicates the expiration date of the token, after which the token can no longer be validated successfully. + +``tenants`` +----------- + +``id`` + Auto-incremented primary key. +``name`` + Unique string identifying the tenant. +``desc`` + Description of the tenant. +``enabled`` + If false, users are unable to scope to the tenant. + +``roles`` +--------- + +``id`` + Auto-incremented primary key. +``name`` + Name of the role. + + If the role is owned by a service, the role name **must** follow the convention:: + + serviceName:roleName +``desc`` + Description of the role. +``service_id`` + (*optional*) References the service that owns the role. + +``user_roles`` +-------------- + +Maps users to the roles that have been granted to them (*optionally*, within the scope of a tenant). + +``id`` + Auto-incremented primary key. +``user_id`` + References the user the role is granted to. +``role_id`` + References the granted role. +``tenant_id`` + (*optional*) References a tenant upon which this grant is applies. + +``services`` +------------ + +``id`` + Auto-incremented primary key. +``name`` + Unique name of the service. +``type`` + Indicates the type of service (e.g. ``compute``, ``object``, ``identity``, etc). + + This can also be extended to support non-core services. Extended services + follow the naming convention ``extension:type`` (e.g. ``dnsextension:dns``). +``desc`` + Describes the service. +``owner_id`` + (*optional*) References the user who owns the service. + +``credentials`` +--------------- + +Currently only used for Amazon EC2 credential storage, this table is designed to support multiple +types of credentials in the future. + +``id`` + Auto-incremented primary key. +``user_id`` + References the user who owns the credential. +``tenant_id`` + References the tenant upon which the credential is valid. +``types`` + Indicates the type of credential (e.g. ``Password``, ``APIKey``, ``EC2``). +``key`` + Amazon EC2 access key. +``secret`` + Amazon EC2 secret key. + +``endpoints`` +------------- + +Tenant-specific endpoints map endpoint templates to specific tenants. +The ``tenant_id`` which appears here replaces the +``%tenant_id%`` template variable in the specified endpoint template. + +``id`` + Auto-incremented primary key. +``tenant_id`` + References the tenant this endpoint applies to. +``endpoint_template_id`` + The endpoint template to appear in the user's service catalog. + +``endpoint_templates`` +---------------------- + +A multi-purpose model for the service catalog which can be: + +- Provided to users of a specific tenants via ``endpoints``, when ``is_global`` is false. +- Provided to all users as-is, when ``is_global`` is true. + +``id`` + Auto-incremented primary key. +``region`` + Identifies the geographic region the endpoint is physically located within. +``service_id`` + TODO: References the service which owns the endpoints? +``public_url`` + Appears in the service catalog [#first]_. + + Represents an endpoint available on the public Internet. +``admin_url`` + Appears in the service catalog [#first]_. + + Users of this endpoint must have an Admin or ServiceAdmin role. +``internal_url`` + Appears in the service catalog [#first]_. + + Represents an endpoint on an internal, unmetered network. +``enabled`` + If false, this endpoint template will not appear in the service catalog. +``is_global`` + If true, this endpoint can not be mapped to tenant-specific endpoints, and ``%tenant_id%`` will not be substituted in endpoint URL's. Additionally, this endpoint will appear for all users. +``version_id`` + Identifies the version of the API contract that endpoint supports. +``version_list`` + A URL which lists versions supported by the endpoint. +``version_info`` + A URL which provides detailed version info regarding the service. + +.. [#first] ``%tenant_id%`` may be replaced by actual tenant references, depending on the value of ``is_global`` and the existence of a corresponding ``endpoints`` record. diff --git a/docs/source/old/configuringservices.rst b/docs/source/old/configuringservices.rst deleted file mode 100644 index 083c3ec5..00000000 --- a/docs/source/old/configuringservices.rst +++ /dev/null @@ -1,333 +0,0 @@ -.. - Copyright 2011 OpenStack, LLC - All Rights Reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); you may - not use this file except in compliance with the License. You may obtain - a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - License for the specific language governing permissions and limitations - under the License. - -========================================== -Configuring Services to work with Keystone -========================================== - -.. toctree:: - :maxdepth: 1 - -Once Keystone is installed and running, services need to be configured to work -with it. These are the steps to configure a service to work with Keystone: - -1. Create or get credentials for the service to use - - A set of credentials are needed for each service (they may be - shared if you chose to). Depending on the service, these credentials are - either a username and password or a long-lived token.. - -2. Register the service, endpoints, roles and other entities - - In order for a service to have it's endpoints and roles show in the service - catalog returned by Keystone, a service record needs to be added for the - service. Endpoints and roles associated with that service can then be created. - - This can be done through the REST interface (using the OS-KSCATALOG extension) - or using keystone-manage. - -3. Install and configure middleware for the service to handle authentication - - Clients making calls to the service will pass in an authentication token. The - Keystone middleware will look for and validate that token, taking the - appropriate action. It will also retrive additional information from the token - such as user name, id, tenant name, id, roles, etc... - - The middleware will pass those data down to the service as headers. The - detailed description of this architecture is available here :doc:`middleware_architecture` - -Setting up credentials -====================== - -First admin user - bootstrapping --------------------------------- - -For a default installation of Keystone, before you can use the REST API, you -need to create your first initial user and grant that user the right to -administer Keystone. - -For the keystone service itself, two -Roles are pre-defined in the keystone configuration file -(:doc:`keystone.conf`). - - #Role that allows admin operations (access to all operations) - keystone-admin-role = Admin - - #Role that allows acting as service (validate tokens, register service, - etc...) - keystone-service-admin-role = KeystoneServiceAdmin - -In order to create your first user, once Keystone is running use -the `keystone-manage` command: - - $ keystone-manage user add admin secrete - $ keystone-manage role add Admin - $ keystone-manage role add KeystoneServiceAdmin - $ keystone-manage role grant Admin admin - $ keystone-manage role grant KeystoneServiceAdmin admin - -This creates the `admin` user (with a password of `secrete`), creates -two roles (`Admin` and `KeystoneServiceAdmin`), and assigns those roles to -the `admin` user. From here, you should now have the choice of using the -administrative API (as well as the :doc:`man/keystone-manage` commands) to -further configure keystone. There are a number of examples of how to use -that API at :doc:`adminAPI_curl_examples`. - - -Setting up services -=================== - -Defining Services and Service Endpoints ---------------------------------------- - -Keystone also acts as a service catalog to let other OpenStack systems know -where relevant API endpoints exist for OpenStack Services. The OpenStack -Dashboard, in particular, uses this heavily - and this **must** be configured -for the OpenStack Dashboard to properly function. - -Here's how we define the services:: - - $ keystone-manage service add nova compute "Nova Compute Service" - $ keystone-manage service add glance image "Glance Image Service" - $ keystone-manage service add swift storage "Swift Object Storage Service" - $ keystone-manage service add keystone identity "Keystone Identity Service" - -Once the services are defined, we create endpoints for them. Each service -has three relevant URL's associated with it that are used in the command: - -* the public API URL -* an administrative API URL -* an internal URL - -The "internal URL" is an endpoint the generally offers the same API as the -public URL, but over a high-bandwidth, low-latency, unmetered (free) network. -You would use that to transfer images from nova to glance for example, and -not the Public URL which would go over the internet and be potentially chargeable. - -The "admin URL" is for administering the services and is not exposed or accessible -to customers without the apporpriate privileges. - -An example of setting up the endpoint for Nova:: - - $ keystone-manage endpointTemplates add RegionOne nova \ - http://nova-api.mydomain:8774/v1.1/%tenant_id% \ - http://nova-api.mydomain:8774/v1.1/%tenant_id% \ - http://nova-api.mydomain:8774/v1.1/%tenant_id% \ - 1 1 - -Glance:: - - $ keystone-manage endpointTemplates add RegionOne glance \ - http://glance.mydomain:9292/v1 \ - http://glance.mydomain:9292/v1 \ - http://glance.mydomain:9292/v1 \ - 1 1 - -Swift:: - - $ keystone-manage endpointTemplates add RegionOne swift \ - http://swift.mydomain:8080/v1/AUTH_%tenant_id% \ - http://swift.mydomain:8080/v1.0/ \ - http://swift.mydomain:8080/v1/AUTH_%tenant_id% \ - 1 1 - -And setting up an endpoint for Keystone:: - - $ keystone-manage endpointTemplates add RegionOne keystone \ - http://keystone.mydomain:5000/v2.0 \ - http://keystone.mydomain:35357/v2.0 \ - http://keystone.mydomain:5000/v2.0 \ - 1 1 - - -Defining an Administrative Service Token ----------------------------------------- - -An Administrative Service Token is a bit of arbitrary text which is configured -in Keystone and used (typically configured into) Nova, Swift, Glance, and any -other OpenStack projects, to be able to use Keystone services. - -This token is an arbitrary text string, but must be identical between Keystone -and the services using Keystone. This token is bound to a user and tenant as -well, so those also need to be created prior to setting it up. - -The *admin* user was set up above, but we haven't created a tenant for that -user yet:: - - $ keystone-manage tenant add admin - -and while we're here, let's grant the admin user the 'Admin' role to the -'admin' tenant:: - - $ keystone-manage role add Admin - $ keystone-manage role grant Admin admin admin - -Now we can create a service token:: - - $ keystone-manage token add 999888777666 admin admin 2015-02-05T00:00 - -This creates a service token of '999888777666' associated to the admin user, -admin tenant, and expires on February 5th, 2015. This token will be used when -configuring Nova, Glance, or other OpenStack services. - -Securing Communications with SSL --------------------------------- - -To encrypt traffic between services and Keystone, see :doc:`ssl` - - -Setting up OpenStack users -========================== - -Creating Tenants, Users, and Roles ----------------------------------- - -Let's set up a 'demo' tenant:: - - $ keystone-manage tenant add demo - -And add a 'demo' user with the password 'guest':: - - $ keystone-manage user add demo guest - -Now let's add a role of "Member" and grant 'demo' user that role -as it pertains to the tenant 'demo':: - - $ keystone-manage role add Member - $ keystone-manage role grant Member demo demo - -Let's also add the admin user as an Admin role to the demo tenant:: - - $ keystone-manage role grant Admin admin demo - -Creating EC2 credentials ------------------------- - -To add EC2 credentials for the `admin` and `demo` accounts:: - - $ keystone-manage credentials add admin EC2 'admin' 'secretpassword' - $ keystone-manage credentials add admin EC2 'demo' 'secretpassword' - -If you have a large number of credentials to create, you can put them all -into a single large file and import them using :doc:`man/keystone-import`. The -format of the document looks like:: - - credentials add admin EC2 'username' 'password' - credentials add admin EC2 'username' 'password' - -Then use:: - - $ keystone-import `filename` - - -Setting Up Middleware -===================== - -Keystone Auth-Token Middleware --------------------------------- - -The Keystone auth_token middleware is a WSGI component that can be inserted in -the WSGI pipeline to handle authenticating tokens with Keystone. See :doc:`middleware` -for details on middleware and configuration parameters. - - -Configuring Nova to use Keystone --------------------------------- - -To configure Nova to use Keystone for authentication, the Nova API service -can be run against the api-paste file provided by Keystone. This is most -easily accomplished by setting the `--api_paste_config` flag in nova.conf to -point to `examples/paste/nova-api-paste.ini` from Keystone. This paste file -included references to the WSGI authentication middleware provided with the -keystone installation. - -When configuring Nova, it is important to create a admin service token for -the service (from the Configuration step above) and include that as the key -'admin_token' in the nova-api-paste.ini. See the documented -:doc:`nova-api-paste` file for references. - -Configuring Swift to use Keystone ---------------------------------- - -Similar to Nova, swift can be configured to use Keystone for authentication -rather than it's built in 'tempauth'. - -1. Add a service endpoint for Swift to Keystone - -2. Configure the paste file for swift-proxy (`/etc/swift/swift-proxy.conf`) - -3. Reconfigure Swift's proxy server to use Keystone instead of TempAuth. - Here's an example `/etc/swift/proxy-server.conf`:: - - [DEFAULT] - bind_port = 8888 - user = - - [pipeline:main] - pipeline = catch_errors cache keystone proxy-server - - [app:proxy-server] - use = egg:swift#proxy - account_autocreate = true - - [filter:keystone] - use = egg:keystone#tokenauth - auth_protocol = http - auth_host = 127.0.0.1 - auth_port = 35357 - admin_token = 999888777666 - delay_auth_decision = 0 - service_protocol = http - service_host = 127.0.0.1 - service_port = 8100 - service_pass = dTpw - cache = swift.cache - - [filter:cache] - use = egg:swift#memcache - set log_name = cache - - [filter:catch_errors] - use = egg:swift#catch_errors - - Note that the optional "cache" property in the keystone filter allows any - service (not just Swift) to register its memcache client in the WSGI - environment. If such a cache exists, Keystone middleware will utilize it - to store validated token information, which could result in better overall - performance. - -4. Restart swift - -5. Verify that keystone is providing authentication to Swift - -Use `swift` to check everything works (note: you currently have to create a -container or upload something as your first action to have the account -created; there's a Swift bug to be fixed soon):: - - $ swift -A http://127.0.0.1:5000/v1.0 -U joeuser -K secrete post container - $ swift -A http://127.0.0.1:5000/v1.0 -U joeuser -K secrete stat -v - StorageURL: http://127.0.0.1:8888/v1/AUTH_1234 - Auth Token: 74ce1b05-e839-43b7-bd76-85ef178726c3 - Account: AUTH_1234 - Containers: 1 - Objects: 0 - Bytes: 0 - Accept-Ranges: bytes - X-Trans-Id: tx25c1a6969d8f4372b63912f411de3c3b - -.. WARNING:: - Keystone currently allows any valid token to do anything with any account. - diff --git a/docs/source/old/middleware_architecture.rst b/docs/source/old/middleware_architecture.rst deleted file mode 100644 index a8c38f3c..00000000 --- a/docs/source/old/middleware_architecture.rst +++ /dev/null @@ -1,529 +0,0 @@ -.. - Copyright 2011 OpenStack, LLC - All Rights Reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); you may - not use this file except in compliance with the License. You may obtain - a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - License for the specific language governing permissions and limitations - under the License. - -======================= -Middleware Architecture -======================= - -Abstract -======== - -The Keystone middleware architecture supports multiple authentication protocols -in a pluggable manner in OpenStack. By providing support for authentication via -pluggable authentication components, this architecture allows OpenStack -services to be integrated easily into existing deployment environments. It also -provides a path by which to implement support for emerging authentication -standards such as OAUTH. - -Rationale and Goals -=================== - -Keystone is the Identity service for OpenStack. To support the easy integrating -of OpenStack with existing authentication and identity management systems, -Keystone supports talking to multiple backends like LDAP. -And to support different deployment needs, it can support multiple -authentication protocols via pluggable 'authentication components' implemented -as WSGI middleware. - -In this document, we describe the responsibilities of the authentication -middleware. We describe how these interact with underlying OpenStack services -and how existing services can be modified to take advantage of pluggable -authentication. The goal is to allow OpenStack services to be integrated easily -into existing deployment environments and to provide a path by which to -implement support for emerging authentication standards such as OAUTH. - -Specification Overview -====================== - -'Authentication' is the process of determining that users are who they say they -are. Typically, 'authentication protocols' such as HTTP Basic Auth, Digest -Access, public key, token, etc, are used to verify a user's identity. In this -document, we define an ''authentication component'' as a software module that -implements an authentication protocol for an OpenStack service. - -At a high level, an authentication component is simply a reverse proxy that -intercepts HTTP calls from clients. Once it has verified a user's identity, the -authentication component extends the call with information about the current -user and forwards the request to the OpenStack service. Otherwise, if a user's -identity is not verified, the message is rejected before it gets to the -service. This is illustrated in :ref:`authComponent`. - -.. _authComponent: - -Authentication Component ------------------------- - -Figure 1. Authentication Component - -.. image:: images/graphs_authComp.svg - :width: 100% - :height: 180 - :alt: An Authentication Component - -Authentication components may operate in 'delegated mode'. In this mode, the -decision reject an unauthenticated client is delegated to the OpenStack -service. Delegated mode is illustrated in :ref:`authComponentDelegated`. - -Here, requests are forwarded to the OpenStack service with an identity status -message that indicates whether the client's identity has been confirmed or is -indeterminate. It is the OpenStack service that decides whether or not a reject -message should be sent to the client. Note that it is always the responsibility -of the Authentication Component to transmit reject messages to the client. - -.. _authComponentDelegated: - -Authentication Component (Delegated Mode) ------------------------------------------ - -Figure 2. Authentication Component (Delegated Mode) - -.. image:: images/graphs_authCompDelegate.svg - :width: 100% - :height: 180 - :alt: An Authentication Component (Delegated Mode) - -In this architecture, we define interactions between the authentication component -and the OpenStack service. Interactions between the client and the -authentication component are defined only for exceptional cases. For example, -we define the message that should be returned when the OpenStack service is -down. Other interactions, however, are defined by the underlying authentication -protocol and the OpenStack service and are considered out of scope. - -.. _deployStrategies: - -Deployment Strategies -===================== - -An authentication component may be integrated directly into the service -implementation, or it may be deployed separately as an HTTP reverse proxy. This -is illustrated in :ref:`deployment`, showing both approaches to -authentication, labeled Option (a) and Option (b). - -.. _deployment: - -Authentication Component Deployments Options --------------------------------------------- - -Figure 3. Authentication Component Deployments Options - -.. image:: images/images_layouts.svg - :width: 100% - :height: 180 - :alt: Authentication Component Deployments Options - -In Option (a), the component is integrated into the service implementation. In -this case, communication between the authentication component and the service -can be efficiently implemented via a method call. In Option (b), the component -is deployed separately and communication between the service and the component -involves an HTTP request. In both cases, unauthenticated requests are filtered -before they reach the service. - -Each approach offers some benefits. Option (a) offers low latency and ease of -initial implementation, making it possibly most appropriate as a starting point -for simple configurations. Option (b) offers several key advantages that may be -of particular value in complex and dynamic configurations. It offers the -ability to scale horizontally in cases where authentication is computationally -expensive, such as when verifying digital signatures. Option (b) also allows -authentication components to be written in different programming languages. -Finally, Option (b) allows multiple authentication components to be deployed in -front of the same service. - -OpenStack services can support both embedded (Option (a)) and external (Option -(b)) deployment strategies. Individual authentication components should support -either strategy or they |may| support both strategies. In order to support -option (a), authentication components written in the Python programming -language should be written as WSGI middleware components (in accordance with -the Web Server Gateway Interface (WSGI) standard [PEP-333]_. - -Additionally, services should support the ability to swap between different -embedded or external authentication components via configuration options. - -Exchanging User Information -=========================== - -If a request is successfully authenticated, the authentication component must -extend the request by adding an ``X-Authorization`` header. The header |must| -be formatted as illustrated in :ref:`xAuthHeader`. - -.. _xAuthHeader: - -X-Authorization Header ----------------------- - -Example 1. X-Authorization Header:: - - X-Authorization: Proxy JoeUser - -Here, `Proxy` denotes that the authentication occurred via a proxy (in this -case authentication component) and ''JoeUser'' is the name of the user who -issued the request. - -.. note: - - We considered using an ``Authorization`` header rather than an - ``X-Authorization``, thereby following normal HTTP semantics. There are some - cases, however, where multiple ``Authorization`` headers need to be transmitted - in a single request. We want to assure ourselves that this will not break - common clients before we recommend the approach. - -Authentication components |may| extend the request with additional -information. For example, an authentication system may add additional headers -or modify the target URI to pass authentication information to the back-end -service. Additionally, an authentication component |may| strip sensitive -information — a plain text password, for example — from the request. That said, -an authentication component |should| pass the majority of the request -unmodified. - -Reverse Proxy Authentication ----------------------------- - -An OpenStack service |should| verify that it is receiving requests from a -trusted authentication component. This is particularly important in cases where -the authentication component and the OpenStack service are deployed separately. -In order to trust incoming requests, the OpenStack service should therefore -authenticate the authentication component. To avoid confusion, we call this -'reverse proxy authentication', since in this case the authentication -component is acting as an HTTP reverse proxy. - -Any HTTP-based authentication scheme may be used for reverse proxy -authentication; however, all OpenStack services and all authentication -components |must| support HTTP Basic Authentication as defined in -[RFC-2617]_. - -Whether or not reverse proxy authentication is required is strictly a -deployment concern. For example, an operations team may opt to utilize firewall -rules instead of an authentication protocol to verify the integrity of incoming -request. Because of this, both OpenStack services and authentication components -|must| also allow for unauthenticated communication. - -In cases where reverse proxy authentication is used, the authorization -component may receive an HTTP 401 authentication error or an HTTP 403 -authorization error. These errors indicate that the component does not have -access to the underlying OpenStack service. The authentication component -|must not| return these errors to the client application. Instead, the -component |must| return a 500 internal error. This is illustrated in -:ref:`proxyAuth` and :ref:`proxyAuthDelegated` below. The component -|should| format the errors in a manner that does not break the service -contract defined by the OpenStack service. :ref:`proxyAuthDelegated` -illustrates proxy authorization in delegated mode. Delegated mode is discussed -in detail in the next section. - -.. _proxyAuth: - -Reverse Proxy Authentication ----------------------------- - -Figure 4. Reverse Proxy Authentication - -.. image:: images/graphs_proxyAuth.svg - :width: 100% - :height: 180 - :alt: Reverse Proxy Authentication - -.. _proxyAuthDelegated: - -Reverse Proxy Authentication (Delegated Mode) ---------------------------------------------- - -Figure 5. Reverse Proxy Authentication (Delegated Mode) - -.. image:: images/graphs_delegate_forbiden_proxy.svg - :width: 100% - :height: 180 - :alt: Reverse Proxy Authentication (Delegated Mode) - -Delegated Mode -============== -In some cases, the decision to reject an unauthenticated request should be -delegated to the OpenStack service. An unauthenticated request may be -appropriate in cases when anonymous access is allowed. In order to support -these cases, an authentication component may be placed in Delegated Mode. In -this mode, the component forwards requests to the OpenStack service when the -client's identity has been confirmed or is indeterminate — that is when -credentials are missing. The authentication component directly rejects requests -with invalid credentials. Authentication components |must| extend the -request by adding an `X-Identity-Status` header. The identity status header -|must| contain one of the following values: - -Identity Status Values ----------------------- - -Confirmed - A `confirmed` value indicates that valid credentials were sent and identity - has been confirmed. The service can trust that the request has been sent on - behalf of the user specified in the `X-Authorization` header. - -Indeterminate - An `indeterminate` value indicates that no credentials were sent and - identity has not been confirmed. In this case, the service will receive an - `X-Authorization` header with no user entry as illustrated in - :ref:`xauth-header-indeterminate`. - -.. _xauth-header-indeterminate: - -Indeterminate Identity Headers ------------------------------- - -Example 2. Indeterminate Identity Headers:: - - X-Identity-Status: Indeterminate - X-Authorization: Proxy - -Services |may| reject a delegated request by issuing an HTTP 401 -authentication error or an HTTP 403 authorization error. These responses -|must| contain an ``WWW-Authenticate`` header with a value of ``Delegated`` as -illustrated in :ref:`unauthHeaders`. - -X-Identity-Status - Provides information on whether the request was authenticated or not. - -X-Tenant - Provides the tenant ID (as it appears in the URL in Keystone). This is to support any legacy implementations before Keystone switched to an ID/Name schema for tenants. - -X-Tenant-Id - The unique, immutable tenant Id - -X-Tenant-Name - The unique, but mutable (it can change) tenant name. - -X-User-Id - The user id of the user used to log in - -X-User-Name - The username used to log in - -X-User - The username used to log in. This is to support any legacy implementations before Keystone switched to an ID/Name schema for tenants. - -X-Roles - The roles associated with that user - -.. _unauthHeaders: - -Delegated WWW-Authenticate Header ---------------------------------- - -:: - - WWW-Authenticate: Delegated - -It is important to note that the actual reject message will likely be modified -by the authentication component in order to comply with the authentication -scheme it is implementing. This is illustrated in :ref:`delegateRejectBasic` and -:ref:`delegateRejectOAuth` below. - -.. _delegateRejectBasic: - -Delegated Reject Basic Auth ---------------------------- - -.. image:: images/graphs_delegate_reject_basic.svg - :width: 100% - :height: 180 - :alt: Delegated Reject Basic Auth - -.. _delegateRejectOAuth: - -Delegated Reject OAuth ----------------------- - -.. image:: images/graphs_delegate_reject_oauth.svg - :width: 100% - :height: 180 - :alt: Delegated Reject OAuth - -The presence of the `WWW-Authenticate` header with a value of `Delegated` -distinguishes a client authentication/authorization failure from a component -failure. For example, compare :ref:`delegateForbidden` with :ref:`proxyAuthDelegated`. In -:ref:`delegateForbidden`, the client is not allowed to access the OpenStack service. -In :ref:`proxyAuthDelegated`, it is the authentication component itself which is -unauthorized. - -.. _delegateForbidden: - -Delegated Reject Forbidden --------------------------- - -Figure 8. Delegated Reject Forbidden - -.. image:: images/graphs_delegate_forbiden_basic.svg - :width: 100% - :height: 180 - :alt: Delegated Reject Forbidden - -Authentication components |must| support both delegated and undelegated -(standard) modes. Delegated mode |should| be configured via a configuration -option. Delegated mode |should| be disabled by default. - -OpenStack services are not required to support delegated mode. If a service -does not support delegated mode, it |must| respond with a 501 not implemented -error and an `WWW-Authenticate` header with a value of `Delegated`. The -authentication component |must not| return the error to the client -application. Instead, the component |must| return a 500 internal error; this is -illustrated in :ref:`delegateUnimplemented`. The component |should| -format the error in a manner that does not break the service contract defined -by the OpenStack service. The component should also log the error such that it -that will inform operators of the misconfiguration. - -.. _delegateUnimplemented: - -Unimplemented Delegated Mode ----------------------------- - -.. image:: images/graphs_delegate_unimplemented.svg - :width: 100% - :height: 180 - :alt: Unimplemented Delegated Mode - -Handling Direct Client Connections -================================== - -Requests from the authentication component to an OpenStack service |must| -contain an ``X-Authorization`` header. If the header is missing, and reverse -proxy authentication fails or is switched off, the OpenStack service |may| -assume that the request is coming directly from a client application. In this -case, the OpenStack service |must| redirect the request to the authentication -component by issuing an HTTP 305 User Proxy redirect. This is illustrated in -:ref:`redirect`. Note that the redirect response |must| include a ``Location`` header -specifying the authentication component's URL as shown in :ref:`redirect-response`. - -.. _redirect: - -Auth Component Redirect ------------------------ - -.. image:: images/graphs_305.svg - :width: 100% - :height: 280 - :alt: Auth Component Redirect - -.. _redirect-response: - -Auth Component Redirect Response --------------------------------- - -:: - - HTTP/1.1 305 Use Proxy - Date: Thu, 28 Oct 2011 07:41:16 GMT - Location: http://sample.auth.openstack.com/path/to/resource - -Using Multiple Authentication Components -======================================== - -There are some use cases when a service provider might want to consider using -multiple authentication components for different purposes. For instance, a -service provider may have one authentication scheme to authenticate the users -of the service and another one to authenticate the administrators or operations -personnel that maintain the service. For such scenarios, we propose using a -mapper as illustrated in :ref:`multiAuth`. - -.. _multiAuth: - -Multiple Authentication Components ----------------------------------- - -.. image:: images/graphs_mapper.svg - :width: 100% - :height: 320 - :alt: Multiple Authentication Components - -At a high level, a mapper is a simple reverse proxy that intercepts HTTP calls -from clients and routes the request to the appropriate authentication -component. A mapper can make the routing decisions based on a number of routing -rules that map a resource to a specific authentication component. For example, -a request URI may determine whether a call should be authenticated via one -authentication component or another. - -Note that neither the authentication component nor the OpenStack service need -be aware of the mapper. Any external authentication component can be used -alongside others. Mappers may provide a means by which to offer support for -anonymous or guest access to a subset of service resources. A mapper may be -implemented via a traditional reverse proxy server such as Pound or Zeus. - -The Default Component -===================== - -Individual services |must| be distributed with a simple integrated -authentication component by default. Providing such a component lowers barriers -to the deployment of individual services. This is especially important to] -developers who may want to deploy OpenStack services on their own machines. -Also, since there is no direct dependency on an external authentication system, -OpenStack services can be deployed individually, without the need to stand up -and configure additional services. Finally, having a standard authentication -component that all services share promotes a separation of concerns. That is, -as a community we are explicitly stating that services should not develop their -own authentication mechanisms. Additional authentication components may be -developed, of course, but these components should not be intimately coupled to -any one particular service. - -As discussed in :ref:`deployStrategies`, an authentication component may be -integrated directly into the service implementation (Option (a)), or it may be -deployed separately as an HTTP reverse proxy (Option (b)). The default -component should be implemented to support Option (a) and services should -maintain support for Option (b). One way to achieve this is to provide a -method that allows the disabling of the default authentication component via -configuration. This is illustrated in :ref:`both`. Here, requests are -sent directly to the OpenStack service when the default authentication -component is disabled. - -We will discuss the design of the default component in an upcoming blueprint. - -.. _both: - -Disabled Embedded Component ---------------------------- - -.. image:: images/graphs_both.svg - :width: 100% - :height: 250 - :alt: Disabled Embedded Component - -Questions and Answers -===================== - -#. Why do authentication components send reject messages? Why not have - OpenStack services reject requests themselves? - - The content and format of an authentication failed message is determined by - the authentication scheme (or protocol). For the service to respond - appropriately, it would have to be aware of the authentication scheme in - which it participates; this defeats the purpose of pluggable authentication - components. - -#. Why require support for deploying authentication components in separate - nodes? - - The deployment strategy is very flexible. It allows for authentication - components to be horizontally scalable. It allows for components to be written - in different languages. Finally, it allows different authentication components - to be deployed simultaneously as described above. - -References -========== - -.. [PEP-333] pep0333 Phillip J Eby. 'Python Web Server Gateway Interface - v1.0.'' http://www.python.org/dev/peps/pep-0333/. - -.. [RFC-2617] rfc2617 J Franks. P Hallam-Baker. J Hostetler. S Lawrence. - P Leach. A Luotonen. L Stewart. ''HTTP Authentication: Basic and Digest - Access Authentication.'' http://tools.ietf.org/html/rfc2617. - -.. |must| replace:: must must -.. |should| replace:: should should -.. |may| replace:: may may -.. |must not| replace:: "must not" "must not" - diff --git a/docs/source/old/nova-api-paste.rst b/docs/source/old/nova-api-paste.rst deleted file mode 100644 index 586bac72..00000000 --- a/docs/source/old/nova-api-paste.rst +++ /dev/null @@ -1,142 +0,0 @@ -.. - Copyright 2011 OpenStack, LLC - All Rights Reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); you may - not use this file except in compliance with the License. You may obtain - a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - License for the specific language governing permissions and limitations - under the License. - -nova-api-paste example -====================== -:: - - ####### - # EC2 # - ####### - - [composite:ec2] - use = egg:Paste#urlmap - /: ec2versions - /services/Cloud: ec2cloud - /services/Admin: ec2admin - /latest: ec2metadata - /2007-01-19: ec2metadata - /2007-03-01: ec2metadata - /2007-08-29: ec2metadata - /2007-10-10: ec2metadata - /2007-12-15: ec2metadata - /2008-02-01: ec2metadata - /2008-09-01: ec2metadata - /2009-04-04: ec2metadata - /1.0: ec2metadata - - [pipeline:ec2cloud] - pipeline = logrequest totoken authtoken keystonecontext cloudrequest authorizer ec2executor - - [pipeline:ec2admin] - pipeline = logrequest totoken authtoken keystonecontext adminrequest authorizer ec2executor - - [pipeline:ec2metadata] - pipeline = logrequest ec2md - - [pipeline:ec2versions] - pipeline = logrequest ec2ver - - [filter:logrequest] - paste.filter_factory = nova.api.ec2:RequestLogging.factory - - [filter:ec2lockout] - paste.filter_factory = nova.api.ec2:Lockout.factory - - [filter:totoken] - paste.filter_factory = keystone.middleware.ec2_token:EC2Token.factory - - [filter:ec2noauth] - paste.filter_factory = nova.api.ec2:NoAuth.factory - - [filter:authenticate] - paste.filter_factory = nova.api.ec2:Authenticate.factory - - [filter:cloudrequest] - controller = nova.api.ec2.cloud.CloudController - paste.filter_factory = nova.api.ec2:Requestify.factory - - [filter:adminrequest] - controller = nova.api.ec2.admin.AdminController - paste.filter_factory = nova.api.ec2:Requestify.factory - - [filter:authorizer] - paste.filter_factory = nova.api.ec2:Authorizer.factory - - [app:ec2executor] - paste.app_factory = nova.api.ec2:Executor.factory - - [app:ec2ver] - paste.app_factory = nova.api.ec2:Versions.factory - - [app:ec2md] - paste.app_factory = nova.api.ec2.metadatarequesthandler:MetadataRequestHandler.factory - - ############# - # Openstack # - ############# - - [composite:osapi] - use = egg:Paste#urlmap - /: osversions - /v1.1: openstackapi - - [pipeline:openstackapi] - pipeline = faultwrap authtoken keystonecontext ratelimit extensions osapiapp - - [filter:faultwrap] - paste.filter_factory = nova.api.openstack:FaultWrapper.factory - - [filter:auth] - paste.filter_factory = nova.api.openstack.auth:AuthMiddleware.factory - - [filter:noauth] - paste.filter_factory = nova.api.openstack.auth:NoAuthMiddleware.factory - - [filter:ratelimit] - paste.filter_factory = nova.api.openstack.limits:RateLimitingMiddleware.factory - - [filter:extensions] - paste.filter_factory = nova.api.openstack.extensions:ExtensionMiddleware.factory - - [app:osapiapp] - paste.app_factory = nova.api.openstack:APIRouter.factory - - [pipeline:osversions] - pipeline = faultwrap osversionapp - - [app:osversionapp] - paste.app_factory = nova.api.openstack.versions:Versions.factory - - ########## - # Shared # - ########## - - [filter:keystonecontext] - paste.filter_factory = keystone.middleware.nova_keystone_context:NovaKeystoneContext.factory - - [filter:authtoken] - paste.filter_factory = keystone.middleware.auth_token:filter_factory - service_protocol = http - service_host = 127.0.0.1 - service_port = 5000 - auth_host = 127.0.0.1 - auth_port = 35357 - auth_protocol = http - auth_uri = http://127.0.0.1:5000/ - admin_token = 999888777666 - ;Uncomment next line and check ip:port to use memcached to cache token requests - ;memcache_hosts = 127.0.0.1:11211 diff --git a/docs/source/setup.rst b/docs/source/setup.rst index 25a43655..4f6b6137 100644 --- a/docs/source/setup.rst +++ b/docs/source/setup.rst @@ -150,7 +150,7 @@ If you want to check the version of Keystone you are running: >>> print keystone.version.version() 2012.1-dev -If you can import keystone successfully, you should be ready to move on to :doc:`testing` and :doc:`developing` +If you can import keystone successfully, you should be ready to move on to :doc:`developing` Troubleshooting =============== -- cgit