summaryrefslogtreecommitdiff
path: root/doc/source
diff options
context:
space:
mode:
authorGuang Yee <guang.yee@hp.com>2012-12-19 15:50:34 -0800
committerGuang Yee <guang.yee@hp.com>2013-01-15 22:06:56 -0800
commit3dfb8437fc9135465f2b66b2c420bf20899fcf10 (patch)
treec5e0524df91c2e64729ce74dcb0d6bb32f015b2b /doc/source
parent4851cc175180e7803a693e556c92611de5c0ced8 (diff)
downloadpython-keystoneclient-3dfb8437fc9135465f2b66b2c420bf20899fcf10.tar.gz
Blueprint memcache-protection: enable memcache value encryption/integrity check
DocImpact Change-Id: I8b733256a3c2cdcf7c2ec5edac491ac4739aa847
Diffstat (limited to 'doc/source')
-rw-r--r--doc/source/images/graphs_authComp.svg48
-rw-r--r--doc/source/images/graphs_authCompDelegate.svg53
-rw-r--r--doc/source/middlewarearchitecture.rst309
3 files changed, 410 insertions, 0 deletions
diff --git a/doc/source/images/graphs_authComp.svg b/doc/source/images/graphs_authComp.svg
new file mode 100644
index 0000000..6be629c
--- /dev/null
+++ b/doc/source/images/graphs_authComp.svg
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545)
+ -->
+<!-- Title: AuthComp Pages: 1 -->
+<svg width="510pt" height="118pt"
+ viewBox="0.00 0.00 510.00 118.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 114)">
+<title>AuthComp</title>
+<polygon fill="white" stroke="white" points="-4,5 -4,-114 507,-114 507,5 -4,5"/>
+<!-- AuthComp -->
+<g id="node2" class="node"><title>AuthComp</title>
+<polygon fill="#fdefe3" stroke="#c00000" points="292,-65 194,-65 194,-25 292,-25 292,-65"/>
+<text text-anchor="middle" x="243" y="-48.4" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text>
+<text text-anchor="middle" x="243" y="-32.4" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text>
+</g>
+<!-- Reject -->
+<!-- AuthComp&#45;&gt;Reject -->
+<g id="edge3" class="edge"><title>AuthComp&#45;&gt;Reject</title>
+<path fill="none" stroke="black" d="M193.933,-51.2787C157.514,-55.939 108.38,-62.2263 73.8172,-66.649"/>
+<polygon fill="black" stroke="black" points="73.0637,-63.2168 63.5888,-67.9578 73.9522,-70.1602 73.0637,-63.2168"/>
+<text text-anchor="middle" x="129" y="-97.4" font-family="Times,serif" font-size="14.00">Reject</text>
+<text text-anchor="middle" x="129" y="-82.4" font-family="Times,serif" font-size="14.00">Unauthenticated</text>
+<text text-anchor="middle" x="129" y="-67.4" font-family="Times,serif" font-size="14.00">Requests</text>
+</g>
+<!-- Service -->
+<g id="node6" class="node"><title>Service</title>
+<polygon fill="#d1ebf1" stroke="#1f477d" points="502,-65 408,-65 408,-25 502,-25 502,-65"/>
+<text text-anchor="middle" x="455" y="-48.4" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text>
+<text text-anchor="middle" x="455" y="-32.4" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text>
+</g>
+<!-- AuthComp&#45;&gt;Service -->
+<g id="edge5" class="edge"><title>AuthComp&#45;&gt;Service</title>
+<path fill="none" stroke="black" d="M292.17,-45C323.626,-45 364.563,-45 397.52,-45"/>
+<polygon fill="black" stroke="black" points="397.917,-48.5001 407.917,-45 397.917,-41.5001 397.917,-48.5001"/>
+<text text-anchor="middle" x="350" y="-77.4" font-family="Times,serif" font-size="14.00">Forward</text>
+<text text-anchor="middle" x="350" y="-62.4" font-family="Times,serif" font-size="14.00">Authenticated</text>
+<text text-anchor="middle" x="350" y="-47.4" font-family="Times,serif" font-size="14.00">Requests</text>
+</g>
+<!-- Start -->
+<!-- Start&#45;&gt;AuthComp -->
+<g id="edge7" class="edge"><title>Start&#45;&gt;AuthComp</title>
+<path fill="none" stroke="black" d="M59.1526,-21.4745C90.4482,-25.4792 142.816,-32.1802 183.673,-37.4084"/>
+<polygon fill="black" stroke="black" points="183.43,-40.9057 193.793,-38.7034 184.318,-33.9623 183.43,-40.9057"/>
+</g>
+</g>
+</svg>
diff --git a/doc/source/images/graphs_authCompDelegate.svg b/doc/source/images/graphs_authCompDelegate.svg
new file mode 100644
index 0000000..4788829
--- /dev/null
+++ b/doc/source/images/graphs_authCompDelegate.svg
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545)
+ -->
+<!-- Title: AuthCompDelegate Pages: 1 -->
+<svg width="588pt" height="104pt"
+ viewBox="0.00 0.00 588.00 104.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 100)">
+<title>AuthCompDelegate</title>
+<polygon fill="white" stroke="white" points="-4,5 -4,-100 585,-100 585,5 -4,5"/>
+<!-- AuthComp -->
+<g id="node2" class="node"><title>AuthComp</title>
+<polygon fill="#fdefe3" stroke="#c00000" points="338,-65 240,-65 240,-25 338,-25 338,-65"/>
+<text text-anchor="middle" x="289" y="-48.4" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text>
+<text text-anchor="middle" x="289" y="-32.4" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text>
+</g>
+<!-- Reject -->
+<!-- AuthComp&#45;&gt;Reject -->
+<g id="edge3" class="edge"><title>AuthComp&#45;&gt;Reject</title>
+<path fill="none" stroke="black" d="M239.6,-50.1899C191.406,-55.2531 118.917,-62.8686 73.5875,-67.6309"/>
+<polygon fill="black" stroke="black" points="73.0928,-64.1635 63.5132,-68.6893 73.8242,-71.1252 73.0928,-64.1635"/>
+<text text-anchor="middle" x="152" y="-83.4" font-family="Times,serif" font-size="14.00">Reject Requests</text>
+<text text-anchor="middle" x="152" y="-68.4" font-family="Times,serif" font-size="14.00">Indicated by the Service</text>
+</g>
+<!-- Service -->
+<g id="node6" class="node"><title>Service</title>
+<polygon fill="#d1ebf1" stroke="#1f477d" points="580,-65 486,-65 486,-25 580,-25 580,-65"/>
+<text text-anchor="middle" x="533" y="-48.4" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text>
+<text text-anchor="middle" x="533" y="-32.4" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text>
+</g>
+<!-- AuthComp&#45;&gt;Service -->
+<g id="edge5" class="edge"><title>AuthComp&#45;&gt;Service</title>
+<path fill="none" stroke="black" d="M338.009,-49.0804C344.065,-49.4598 350.172,-49.7828 356,-50 405.743,-51.8535 418.259,-51.9103 468,-50 470.523,-49.9031 473.101,-49.7851 475.704,-49.6504"/>
+<polygon fill="black" stroke="black" points="476.03,-53.1374 485.807,-49.0576 475.62,-46.1494 476.03,-53.1374"/>
+<text text-anchor="middle" x="412" y="-68.4" font-family="Times,serif" font-size="14.00">Forward Requests</text>
+<text text-anchor="middle" x="412" y="-53.4" font-family="Times,serif" font-size="14.00">with Identiy Status</text>
+</g>
+<!-- Service&#45;&gt;AuthComp -->
+<g id="edge7" class="edge"><title>Service&#45;&gt;AuthComp</title>
+<path fill="none" stroke="black" d="M495.062,-24.9037C486.397,-21.2187 477.064,-17.9304 468,-16 419.314,-5.63183 404.743,-5.9037 356,-16 349.891,-17.2653 343.655,-19.116 337.566,-21.2803"/>
+<polygon fill="black" stroke="black" points="336.234,-18.0426 328.158,-24.9003 338.748,-24.5757 336.234,-18.0426"/>
+<text text-anchor="middle" x="412" y="-33.4" font-family="Times,serif" font-size="14.00">Send Response OR</text>
+<text text-anchor="middle" x="412" y="-18.4" font-family="Times,serif" font-size="14.00">Reject Message</text>
+</g>
+<!-- Start -->
+<!-- Start&#45;&gt;AuthComp -->
+<g id="edge9" class="edge"><title>Start&#45;&gt;AuthComp</title>
+<path fill="none" stroke="black" d="M59.0178,-20.8384C99.2135,-25.0613 175.782,-33.1055 229.492,-38.7482"/>
+<polygon fill="black" stroke="black" points="229.265,-42.2435 239.576,-39.8076 229.997,-35.2818 229.265,-42.2435"/>
+</g>
+</g>
+</svg>
diff --git a/doc/source/middlewarearchitecture.rst b/doc/source/middlewarearchitecture.rst
new file mode 100644
index 0000000..59a6db0
--- /dev/null
+++ b/doc/source/middlewarearchitecture.rst
@@ -0,0 +1,309 @@
+..
+ Copyright 2011-2012 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 a common authentication protocol
+in use between the OpenStack projects. By using keystone as a common
+authentication and authorization mechanisms, the OpenStack project can plug in
+to existing authentication and authorization systems in use by existing
+environments.
+
+In this document, we describe the architecture and responsibilities of the
+authentication middleware which acts as the internal API mechanism for
+OpenStack projects based on the WSGI standard.
+
+For the architecture of keystone and its services, please see
+:doc:`architecture`. This documentation primarily describes the implementation
+in ``keystoneclient/middleware/auth_token.py``
+(:py:class:`keystoneclient.middleware.auth_token.AuthProtocol`)
+
+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. OpenStack is
+using a token based mechanism to represent authentication and authorization.
+
+At a high level, an authentication middleware component is a proxy that
+intercepts HTTP calls from clients and populates HTTP headers in the request
+context for other WSGI middleware or applications to use. The general flow
+of the middleware processing is:
+
+* clear any existing authorization headers to prevent forgery
+* collect the token from the existing HTTP request headers
+* validate the token
+
+ * if valid, populate additional headers representing the identity that has
+ been authenticated and authorized
+ * in invalid, or not token present, reject the request (HTTPUnauthorized)
+ or pass along a header indicating the request is unauthorized (configurable
+ in the middleware)
+ * if the keystone service is unavailable to validate the token, reject
+ the request with HTTPServiceUnavailable.
+
+.. _authComponent:
+
+Authentication Component
+------------------------
+
+Figure 1. Authentication Component
+
+.. image:: images/graphs_authComp.svg
+ :width: 100%
+ :height: 180
+ :alt: An Authentication Component
+
+The middleware may also be configured to operated in a 'delegated mode'.
+In this mode, the decision reject an unauthenticated client is delegated to
+the OpenStack service, as 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.
+
+.. _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)
+
+.. _deployStrategies:
+
+Deployment Strategy
+===================
+
+The middleware is intended to be used inline with OpenStack wsgi components,
+based on the openstack-common WSGI middleware class. It is typically deployed
+as a configuration element in a paste configuration pipeline of other
+middleware components, with the pipeline terminating in the service
+application. The middleware conforms to the python WSGI standard [PEP-333]_.
+In initializing the middleware, a configuration item (which acts like a python
+dictionary) is passed to the middleware with relevant configuration options.
+
+Configuration
+-------------
+
+The middleware is configured within the config file of the main application as
+a WSGI component. Example for the auth_token middleware::
+
+ [app:myService]
+ paste.app_factory = myService:app_factory
+
+ [pipeline:main]
+ pipeline = tokenauth myService
+
+ [filter:tokenauth]
+ paste.filter_factory = keystone.middleware.auth_token:filter_factory
+ auth_host = 127.0.0.1
+ auth_port = 35357
+ auth_protocol = http
+ auth_uri = http://127.0.0.1:5000/
+ admin_token = Super999Sekret888Password777
+ admin_user = admin
+ admin_password = SuperSekretPassword
+ admin_tenant_name = service
+ ;Uncomment next line to use Swift MemcacheRing
+ ;cache = swift.cache
+ ;Uncomment next line and check ip:port to use memcached to cache tokens
+ ;memcache_servers = 127.0.0.1:11211
+ ;Uncomment next 2 lines to turn on memcache protection
+ ;memcache_security_strategy = ENCRYPT
+ ;memcache_secret_key = change_me
+ ;Uncomment next 2 lines if Keystone server is validating client cert
+ ;certfile = <path to middleware public cert>
+ ;keyfile = <path to middleware private cert>
+
+For services which have separate paste-deploy ini file, auth_token middleware
+can be alternatively configured in [keystone_authtoken] section in the main
+config file. For example in Nova, all middleware parameters can be removed
+from api-paste.ini::
+
+ [filter:authtoken]
+ paste.filter_factory = keystone.middleware.auth_token:filter_factory
+
+and set in nova.conf::
+
+ [DEFAULT]
+ ...
+ auth_strategy=keystone
+
+ [keystone_authtoken]
+ auth_host = 127.0.0.1
+ auth_port = 35357
+ auth_protocol = http
+ auth_uri = http://127.0.0.1:5000/
+ admin_user = admin
+ admin_password = SuperSekretPassword
+ admin_tenant_name = service
+
+Note that middleware parameters in paste config take priority, they must be
+removed to use values in [keystone_authtoken] section.
+
+Configuration Options
+---------------------
+
+* ``auth_host``: (required) the host providing the keystone service API endpoint
+ for validating and requesting tokens
+* ``admin_token``: either this or the following three options are required. If
+ set, this is a single shared secret with the keystone configuration used to
+ validate tokens.
+* ``admin_user``, ``admin_password``, ``admin_tenant_name``: if ``admin_token``
+ is not set, or invalid, then admin_user, admin_password, and
+ admin_tenant_name are defined as a service account which is expected to have
+ been previously configured in Keystone to validate user tokens.
+
+* ``delay_auth_decision``: (optional, default `0`) (off). If on, the middleware
+ will not reject invalid auth requests, but will delegate that decision to
+ downstream WSGI components.
+* ``auth_port``: (optional, default `35357`) the port used to validate tokens
+* ``auth_protocol``: (optional, default `https`)
+* ``auth_uri``: (optional, defaults to `auth_protocol`://`auth_host`:`auth_port`)
+* ``certfile``: (required, if Keystone server requires client cert)
+* ``keyfile``: (required, if Keystone server requires client cert) This can be
+ the same as the certfile if the certfile includes the private key.
+
+Caching for improved response
+-----------------------------
+
+In order to prevent every service request, the middleware may be configured
+to utilize a cache, and the keystone API returns the tokens with an
+expiration (configurable in duration on the keystone service). The middleware
+supports memcache based caching.
+
+* ``memcache_servers``: (optonal) if defined, the memcache server(s) to use for
+ cacheing. It will be ignored if Swift MemcacheRing is used instead.
+* ``token_cache_time``: (optional, default 300 seconds) Only valid if
+ memcache_servers is defined.
+
+When deploying auth_token middleware with Swift, user may elect
+to use Swift MemcacheRing instead of the local Keystone memcache.
+The Swift MemcacheRing object is passed in from the request environment
+and it defaults to 'swift.cache'. However it could be
+different, depending on deployment. To use Swift MemcacheRing, you must
+provide the ``cache`` option.
+
+* ``cache``: (optional) if defined, the environment key where the Swift
+ MemcacheRing object is stored.
+
+Memcached and System Time
+=========================
+
+When using `memcached`_ with ``auth_token`` middleware, ensure that the system
+time of memcached hosts is set to UTC. Memcached uses the host's system
+time in determining whether a key has expired, whereas Keystone sets
+key expiry in UTC. The timezone used by Keystone and memcached must
+match if key expiry is to behave as expected.
+
+.. _`memcached`: http://memcached.org/
+
+Memcache Protection
+===================
+
+When using memcached, we are storing user tokens and token validation
+information into the cache as raw data. Which means anyone who have access
+to the memcache servers can read and modify data stored there. To mitigate
+this risk, ``auth_token`` middleware provides an option to either encrypt
+or authenticate the token data stored in the cache.
+
+* ``memcache_security_strategy``: (optional) if defined, indicate whether token
+ data should be encrypted or authenticated. Acceptable values are ``ENCRYPT``
+ or ``MAC``. If ``ENCRYPT``, token data is encrypted in the cache. If
+ ``MAC``, token data is authenticated (with HMAC) in the cache. If its value
+ is neither ``MAC`` nor ``ENCRYPT``, ``auth_token`` will raise an exception
+ on initialization.
+* ``memcache_secret_key``: (optional, mandatory if
+ ``memcache_security_strategy`` is defined) if defined,
+ a random string to be used for key derivation. If
+ ``memcache_security_strategy`` is defined and ``memcache_secret_key`` is
+ absent, ``auth_token`` will raise an exception on initialization.
+
+Exchanging User Information
+===========================
+
+The middleware expects to find a token representing the user with the header
+``X-Auth-Token`` or ``X-Storage-Token``. `X-Storage-Token` is supported for
+swift/cloud files and for legacy Rackspace use. If the token isn't present and
+the middleware is configured to not delegate auth responsibility, it will
+respond to the HTTP request with HTTPUnauthorized, returning the header
+``WWW-Authenticate`` with the value `Keystone uri='...'` to indicate where to
+request a token. The auth_uri returned is configured with the middleware.
+
+The authentication middleware extends the HTTP request with the header
+``X-Identity-Status``. If a request is successfully authenticated, the value
+is set to `Confirmed`. If the middleware is delegating the auth decision to the
+service, then the status is set to `Invalid` if the auth request was
+unsuccessful.
+
+Extended the request with additional User Information
+-----------------------------------------------------
+
+:py:class:`keystone.middleware.auth_token.AuthProtocol` extends the request
+with additional information if the user has been authenticated.
+
+
+X-Identity-Status
+ Provides information on whether the request was authenticated or not.
+
+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-Roles
+ The roles associated with that user
+
+Deprecated additions
+--------------------
+
+X-Tenant
+ Provides the tenant name. This is to support any legacy implementations
+ before Keystone switched to an ID/Name schema for tenants.
+
+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-Role
+ The roles associated with that user
+
+References
+==========
+
+.. [PEP-333] pep0333 Phillip J Eby. 'Python Web Server Gateway Interface
+ v1.0.'' http://www.python.org/dev/peps/pep-0333/.