diff options
author | WuKong <rebirthmonkey@gmail.com> | 2015-06-30 18:47:29 +0200 |
---|---|---|
committer | WuKong <rebirthmonkey@gmail.com> | 2015-06-30 18:47:29 +0200 |
commit | b8c756ecdd7cced1db4300935484e8c83701c82e (patch) | |
tree | 87e51107d82b217ede145de9d9d59e2100725bd7 /keystone-moon/doc | |
parent | c304c773bae68fb854ed9eab8fb35c4ef17cf136 (diff) |
migrate moon code from github to opnfv
Change-Id: Ice53e368fd1114d56a75271aa9f2e598e3eba604
Signed-off-by: WuKong <rebirthmonkey@gmail.com>
Diffstat (limited to 'keystone-moon/doc')
36 files changed, 9059 insertions, 0 deletions
diff --git a/keystone-moon/doc/Makefile b/keystone-moon/doc/Makefile new file mode 100644 index 00000000..79861705 --- /dev/null +++ b/keystone-moon/doc/Makefile @@ -0,0 +1,159 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build +SOURCEDIR = source +SPHINXAPIDOC = sphinx-apidoc + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make <target>' where <target> is one of" + @echo " autodoc generate the autodoc templates" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +autodoc: + $(SPHINXAPIDOC) -f -o $(SOURCEDIR) ../keystone + +html: autodoc + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/keystone.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/keystone.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/keystone" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/keystone" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/keystone-moon/doc/README.rst b/keystone-moon/doc/README.rst new file mode 100644 index 00000000..a9537b9a --- /dev/null +++ b/keystone-moon/doc/README.rst @@ -0,0 +1,9 @@ +Building Docs +============= + +Developer documentation is generated using Sphinx. To build this documentation, +run the following from the root of the repository:: + + $ tox -e docs + +The documentation will be built at ``doc/build/``. diff --git a/keystone-moon/doc/ext/__init__.py b/keystone-moon/doc/ext/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/keystone-moon/doc/ext/__init__.py diff --git a/keystone-moon/doc/ext/apidoc.py b/keystone-moon/doc/ext/apidoc.py new file mode 100644 index 00000000..435d388f --- /dev/null +++ b/keystone-moon/doc/ext/apidoc.py @@ -0,0 +1,45 @@ +# Copyright 2013 OpenStack Foundation +# +# 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. + +# NOTE(dstanek): Uncomment the [pbr] section in setup.cfg and remove this +# Sphinx extension when https://launchpad.net/bugs/1260495 is fixed. + +import os.path as path + +from sphinx import apidoc + + +# NOTE(dstanek): pbr will run Sphinx multiple times when it generates +# documentation. Once for each builder. To run this extension we use the +# 'builder-inited' hook that fires at the beginning of a Sphinx build. +# We use ``run_already`` to make sure apidocs are only generated once +# even if Sphinx is run multiple times. +run_already = False + + +def run_apidoc(app): + global run_already + if run_already: + return + run_already = True + + package_dir = path.abspath(path.join(app.srcdir, '..', '..', 'keystone')) + source_dir = path.join(app.srcdir, 'api') + apidoc.main(['apidoc', package_dir, '-f', + '-H', 'Keystone Modules', + '-o', source_dir]) + + +def setup(app): + app.connect('builder-inited', run_apidoc) diff --git a/keystone-moon/doc/keystone_compat_flows.sdx b/keystone-moon/doc/keystone_compat_flows.sdx new file mode 100644 index 00000000..f1fcc5f0 --- /dev/null +++ b/keystone-moon/doc/keystone_compat_flows.sdx @@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<diagram> +<source><![CDATA[client:client "Client" +compat:compat "Compat" +token:token "Token Service" +identity:identity "Identity Service" +catalog:catalog "Catalog Service" + +[c "Auth, No Tenant"] +client:{token, user, service_catalog}=compat.POST /v2.0/tokens {'username': user, 'password': password} + compat:(user, password, None)=identity.authenticate(user, password, tenant=None) + compat:(id, user, password, None)=token.create_token(user, password, tenant=None) + compat:{service_catalog (includes all tenants)}=catalog.get_catalog(user, None) +[/c] + +[c "Auth, With Tenant"] +client:{scoped_token, user, service_catalog}=compat.POST /v2.0/tokens {'username': user, 'password': password, 'tenant': tenant} + compat:(user, password, tenant)=identity.authenticate(user, password, tenant) + compat:(id, user, password, tenant)=token.create_token(user, password, tenant) + compat:{service_catalog (includes all tenants)}=catalog.get_catalog(user, tenant) +[/c] + +[c "Validate Token, Unscoped"] +client:{token, user, tenant=None}=compat.GET /v2.0/tokens/$token +compat:{token, user, tenant}=token.get_token($token) +[/c] + +[c "Validate Token, With Tenant"] +client:{token, user, tenant}=compat.GET /v2.0/tokens/$token?belongs_to=$tenant +compat:{token, user, tenant}=token.get_token($token) +[/c] + +[c "Tenants for Token"] +client:{tenants}=compat.(X-Auth-Token: $token) GET /v2.0/tenants +compat:{token, user, tenant}=token.get_token($token) +compat:{token, user, tenant}=identity.get_tenants($user) +[/c]]]></source> +<configuration> +<property name="activationBarBorderThickness" value="1"/> +<property name="actorWidth" value="25"/> +<property name="arrowColor" value="-14803256"/> +<property name="arrowSize" value="6"/> +<property name="arrowThickness" value="1"/> +<property name="colorizeThreads" value="true"/> +<property name="destructorWidth" value="30"/> +<property name="explicitReturns" value="false"/> +<property family="Dialog" name="font" size="12" style="0"/> +<property name="fragmentBorderThickness" value="2"/> +<property name="fragmentEdgeColor" value="-16751616"/> +<property name="fragmentLabelBgColor" value="-36"/> +<property name="fragmentMargin" value="8"/> +<property name="fragmentPadding" value="10"/> +<property name="fragmentTextPadding" value="3"/> +<property name="glue" value="10"/> +<property name="headHeight" value="35"/> +<property name="headLabelPadding" value="5"/> +<property name="headWidth" value="100"/> +<property name="initialSpace" value="10"/> +<property name="labeledBoxBgColor" value="-76"/> +<property name="leftMargin" value="5"/> +<property name="lifelineThickness" value="1"/> +<property name="lineWrap" value="false"/> +<property name="lowerMargin" value="5"/> +<property name="mainLifelineWidth" value="8"/> +<property name="messageLabelSpace" value="3"/> +<property name="messagePadding" value="6"/> +<property name="noteBgColor" value="-76"/> +<property name="noteBorderThickness" value="1"/> +<property name="noteMargin" value="6"/> +<property name="notePadding" value="6"/> +<property name="opaqueMessageText" value="false"/> +<property name="returnArrowVisible" value="true"/> +<property name="rightMargin" value="5"/> +<property name="selfMessageHorizontalSpace" value="15"/> +<property name="separatorBottomMargin" value="8"/> +<property name="separatorTopMargin" value="15"/> +<property name="shouldShadowParticipants" value="true"/> +<property name="slackMode" value="false"/> +<property name="spaceBeforeActivation" value="2"/> +<property name="spaceBeforeAnswerToSelf" value="10"/> +<property name="spaceBeforeConstruction" value="6"/> +<property name="spaceBeforeSelfMessage" value="7"/> +<property name="subLifelineWidth" value="6"/> +<property name="tc0" value="-1118482"/> +<property name="tc1" value="-256"/> +<property name="tc2" value="-65536"/> +<property name="tc3" value="-16776961"/> +<property name="tc4" value="-16711936"/> +<property name="tc5" value="-4144960"/> +<property name="tc6" value="-65281"/> +<property name="tc7" value="-14336"/> +<property name="tc8" value="-20561"/> +<property name="tc9" value="-12566464"/> +<property name="threadNumbersVisible" value="false"/> +<property name="threaded" value="true"/> +<property name="upperMargin" value="5"/> +<property name="verticallySplit" value="true"/> +</configuration> +</diagram> diff --git a/keystone-moon/doc/source/apache-httpd.rst b/keystone-moon/doc/source/apache-httpd.rst new file mode 100644 index 00000000..c075512f --- /dev/null +++ b/keystone-moon/doc/source/apache-httpd.rst @@ -0,0 +1,93 @@ + +.. + Copyright 2011-2012 OpenStack Foundation + 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. + +========================= +Running Keystone in HTTPD +========================= + +.. WARNING:: + + Running Keystone under HTTPD in the recommended (and tested) configuration + does not support the use of ``Transfer-Encoding: chunked``. This is due to + a limitation with the WSGI spec and the implementation used by + ``mod_wsgi``. It is recommended that all clients assume Keystone will not + support ``Transfer-Encoding: chunked``. + + +Files +----- + +Copy the file httpd/wsgi-keystone.conf to the appropriate location for your +Apache server, most likely:: + + /etc/httpd/conf.d/wsgi-keystone.conf + +Update this file to match your system configuration (for example, some +distributions put httpd logs in the ``apache2`` directory and some in the +``httpd`` directory; also, enable TLS). + +Create the directory ``/var/www/cgi-bin/keystone/``. You can either hardlink or +softlink the files ``main`` and ``admin`` to the file ``keystone.py`` in this +directory. For a distribution appropriate place, it should probably be copied +to:: + + /usr/share/openstack/keystone/httpd/keystone.py + +Keystone's primary configuration file (``etc/keystone.conf``) and the +PasteDeploy configuration file (``etc/keystone-paste.ini``) must be readable to +HTTPD in one of the default locations described in :doc:`configuration`. + +SELinux +------- + +If you are running with SELinux enabled (and you should be) make sure that the +file has the appropriate SELinux context to access the linked file. If you +have the file in /var/www/cgi-bin, you can do this by running: + +.. code-block:: bash + + $ sudo restorecon /var/www/cgi-bin + +Putting it somewhere else requires you set up your SELinux policy accordingly. + +Keystone Configuration +---------------------- + +Make sure that when using a token format that requires persistence, you use a +token persistence driver that can be shared between processes. The SQL and +memcached token persistence drivers provided with keystone can be shared +between processes. + +.. WARNING:: + + The KVS (``keystone.token.persistence.backends.kvs.Token``) token + persistence driver cannot be shared between processes so must not be used + when running keystone under HTTPD (the tokens will not be shared between + the processes of the server and validation will fail). + +For SQL, in ``/etc/keystone/keystone.conf`` set:: + + [token] + driver = keystone.token.persistence.backends.sql.Token + +For memcached, in ``/etc/keystone/keystone.conf`` set:: + + [token] + driver = keystone.token.persistence.backends.memcache.Token + +All servers that are storing tokens need a shared backend. This means that +either all servers use the same database server or use a common memcached pool. diff --git a/keystone-moon/doc/source/api_curl_examples.rst b/keystone-moon/doc/source/api_curl_examples.rst new file mode 100644 index 00000000..a4b31553 --- /dev/null +++ b/keystone-moon/doc/source/api_curl_examples.rst @@ -0,0 +1,1153 @@ +.. + Copyright 2011-2012 OpenStack Foundation + 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. + +======================= +API Examples using Curl +======================= + +-------------------------- +v3 API Examples Using Curl +-------------------------- + +Tokens +====== + +Default scope +------------- + +Get an token with default scope (may be unscoped): + +.. code-block:: bash + + curl -i \ + -H "Content-Type: application/json" \ + -d ' + { "auth": { + "identity": { + "methods": ["password"], + "password": { + "user": { + "name": "admin", + "domain": { "id": "default" }, + "password": "adminpwd" + } + } + } + } + }' \ + http://localhost:5000/v3/auth/tokens ; echo + +Example response:: + + HTTP/1.1 201 Created + X-Subject-Token: MIIFvgY... + Vary: X-Auth-Token + Content-Type: application/json + Content-Length: 1025 + Date: Tue, 10 Jun 2014 20:55:16 GMT + + {"token": {"methods": ["password"], "roles": [{"id": + "9fe2ff9ee4384b1894a90878d3e92bab", "name": "_member_"}, {"id": + "c703057be878458588961ce9a0ce686b", "name": "admin"}], "expires_at": + "2014-06-10T2:55:16.806001Z", "project": {"domain": {"id": "default", "name": + "Default"}, "id": "8538a3f13f9541b28c2620eb19065e45", "name": "admin"}, + "catalog": [{"endpoints": [{"url": "http://localhost:3537/v2.0", "region": + "RegionOne", "interface": "admin", "id": "29beb2f1567642eb810b042b6719ea88"}, + {"url": "http://localhost:5000/v2.0", "region": "RegionOne", "interface": + "internal", "id": "8707e3735d4415c97ae231b4841eb1c"}, {"url": + "http://localhost:5000/v2.0", "region": "RegionOne", "interface": "public", + "id": "ef303187fc8d41668f25199c298396a5"}], "type": "identity", "id": + "bd73972c0e14fb69bae8ff76e112a90", "name": "keystone"}], "extras": {}, + "user": {"domain": {"id": "default", "name": "Default"}, "id": + "3ec3164f750146be97f21559ee4d9c51", "name": "admin"}, "issued_at": + "201406-10T20:55:16.806027Z"}} + + +Project-scoped +-------------- + +Get a project-scoped token: + +.. code-block:: bash + + curl -i \ + -H "Content-Type: application/json" \ + -d ' + { "auth": { + "identity": { + "methods": ["password"], + "password": { + "user": { + "name": "admin", + "domain": { "id": "default" }, + "password": "adminpwd" + } + } + }, + "scope": { + "project": { + "name": "demo", + "domain": { "id": "default" } + } + } + } + }' \ + http://localhost:5000/v3/auth/tokens ; echo + +Example response:: + + HTTP/1.1 201 Created + X-Subject-Token: MIIFfQ... + Vary: X-Auth-Token + Content-Type: application/json + Content-Length: 960 + Date: Tue, 10 Jun 2014 20:40:14 GMT + + {"token": {"methods": ["password"], "roles": [{"id": + "c703057be878458588961ce9a0ce686b", "name": "admin"}], "expires_at": + "2014-06-10T21:40:14.360795Z", "project": {"domain": {"id": "default", + "name": "Default"}, "id": "3d4c2c82bd5948f0bcab0cf3a7c9b48c", "name": + "demo"}, "catalog": [{"endpoints": [{"url": + "http://localhost:35357/v2.0", "region": "RegionOne", "interface": "admin", + "id": "29beb2f1567642eb810b042b6719ea88"}, {"url": + "http://localhost:5000/v2.0", "region": "RegionOne", "interface": + "internal", "id": "87057e3735d4415c97ae231b4841eb1c"}, {"url": + "http://localhost:5000/v2.0", "region": "RegionOne", "interface": "public", + "id": "ef303187fc8d41668f25199c298396a5"}], "type": "identity", "id": + "bd7397d2c0e14fb69bae8ff76e112a90", "name": "keystone"}], "extras": {}, + "user": {"domain": {"id": "default", "name": "Default"}, "id": + "3ec3164f750146be97f21559ee4d9c51", "name": "admin"}, "issued_at": + "2014-06-10T20:40:14.360822Z"}} + + +Domain-Scoped +------------- + +Get a domain-scoped token (Note that you're going to need a role-assignment on +the domain first!): + +.. code-block:: bash + + curl -i \ + -H "Content-Type: application/json" \ + -d ' + { "auth": { + "identity": { + "methods": ["password"], + "password": { + "user": { + "name": "admin", + "domain": { "id": "default" }, + "password": "adminpwd" + } + } + }, + "scope": { + "domain": { + "id": "default" + } + } + } + }' \ + http://localhost:5000/v3/auth/tokens ; echo + +Example response:: + + HTTP/1.1 201 Created + X-Subject-Token: MIIFNg... + Vary: X-Auth-Token + Content-Type: application/json + Content-Length: 889 + Date: Tue, 10 Jun 2014 20:52:59 GMT + + {"token": {"domain": {"id": "default", "name": "Default"}, "methods": + ["password"], "roles": [{"id": "c703057be878458588961ce9a0ce686b", "name": + "admin"}], "expires_at": "2014-06-10T21:52:58.852167Z", "catalog": + [{"endpoints": [{"url": "http://localhost:35357/v2.0", "region": "RegionOne", + "interface": "admin", "id": "29beb2f1567642eb810b042b6719ea88"}, {"url": + "http://localhost:5000/v2.0", "region": "RegionOne", "interface": "internal", + "id": "87057e3735d4415c97ae231b4841eb1c"}, {"url": + "http://localhost:5000/v2.0", "region": "RegionOne", "interface": "public", + "id": "ef303187fc8d41668f25199c298396a5"}], "type": "identity", "id": + "bd7397d2c0e14fb69bae8ff76e112a90", "name": "keystone"}], "extras": {}, + "user": {"domain": {"id": "default", "name": "Default"}, "id": + "3ec3164f750146be97f21559ee4d9c51", "name": "admin"}, "issued_at": + "2014-06-10T20:52:58.852194Z"}} + + +Getting a token from a token +---------------------------- + +Get a token from a token: + +.. code-block:: bash + + curl -i \ + -H "Content-Type: application/json" \ + -d ' + { "auth": { + "identity": { + "methods": ["token"], + "token": { + "id": "'$OS_TOKEN'" + } + } + } + }' \ + http://localhost:5000/v3/auth/tokens ; echo + + +Example response:: + + HTTP/1.1 201 Created + X-Subject-Token: MIIFxw... + Vary: X-Auth-Token + Content-Type: application/json + Content-Length: 1034 + Date: Tue, 10 Jun 2014 21:00:05 GMT + + {"token": {"methods": ["token", "password"], "roles": [{"id": + "9fe2ff9ee4384b1894a90878d3e92bab", "name": "_member_"}, {"id": + "c703057be878458588961ce9a0ce686b", "name": "admin"}], "expires_at": + "2014-06-10T21:55:16.806001Z", "project": {"domain": {"id": "default", + "name": "Default"}, "id": "8538a3f13f9541b28c2620eb19065e45", "name": + "admin"}, "catalog": [{"endpoints": [{"url": "http://localhost:35357/v2.0", + "region": "RegionOne", "interface": "admin", "id": + "29beb2f1567642eb810b042b6719ea88"}, {"url": "http://localhost:5000/v2.0", + "region": "RegionOne", "interface": "internal", "id": + "87057e3735d4415c97ae231b4841eb1c"}, {"url": "http://localhost:5000/v2.0", + "region": "RegionOne", "interface": "public", "id": + "ef303187fc8d41668f25199c298396a5"}], "type": "identity", "id": + "bd7397d2c0e14fb69bae8ff76e112a90", "name": "keystone"}], "extras": {}, + "user": {"domain": {"id": "default", "name": "Default"}, "id": + "3ec3164f750146be97f21559ee4d9c51", "name": "admin"}, "issued_at": + "2014-06-10T21:00:05.548559Z"}} + + +.. note:: + + If a scope was included in the request body then this would get a token + with the new scope. + + +DELETE /v3/auth/tokens +---------------------- + +Revoke a token: + +.. code-block:: bash + + curl -i -X DELETE \ + -H "X-Auth-Token: $OS_TOKEN" \ + -H "X-Subject-Token: $OS_TOKEN" \ + http://localhost:5000/v3/auth/tokens + +If there's no error then the response is empty. + + +Domains +======= + +GET /v3/domains +--------------- + +List domains: + +.. code-block:: bash + + curl -s \ + -H "X-Auth-Token: $OS_TOKEN" \ + http://localhost:5000/v3/domains | python -mjson.tool + +Example response: + +.. code-block:: javascript + + { + "domains": [ + { + "description": "Owns users and tenants (i.e. projects) available on Identity API v2.", + "enabled": true, + "id": "default", + "links": { + "self": "http://identity-server:5000/v3/domains/default" + }, + "name": "Default" + } + ], + "links": { + "next": null, + "previous": null, + "self": "http://identity-server:5000/v3/domains" + } + } + + +POST /v3/domains +---------------- + +Create a domain: + +.. code-block:: bash + + curl -s \ + -H "X-Auth-Token: $OS_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ "domain": { "name": "newdomain"}}' \ + http://localhost:5000/v3/domains | python -mjson.tool + +Example response: + +.. code-block:: javascript + + { + "domain": { + "enabled": true, + "id": "3a5140aecd974bf08041328b53a62458", + "links": { + "self": "http://identity-server:5000/v3/domains/3a5140aecd974bf08041328b53a62458" + }, + "name": "newdomain" + } + } + + +Projects +======== + +GET /v3/projects +---------------- + +List projects: + +.. code-block:: bash + + curl -s \ + -H "X-Auth-Token: $OS_TOKEN" \ + http://localhost:5000/v3/projects | python -mjson.tool + +Example response: + +.. code-block:: javascript + + { + "links": { + "next": null, + "previous": null, + "self": "http://localhost:5000/v3/projects" + }, + "projects": [ + { + "description": null, + "domain_id": "default", + "enabled": true, + "id": "3d4c2c82bd5948f0bcab0cf3a7c9b48c", + "links": { + "self": "http://localhost:5000/v3/projects/3d4c2c82bd5948f0bcab0cf3a7c9b48c" + }, + "name": "demo" + } + ] + } + + +PATCH /v3/projects/{id} +----------------------- + +Disable a project: + +.. code-block:: bash + + curl -s -X PATCH \ + -H "X-Auth-Token: $OS_TOKEN" \ + -H "Content-Type: application/json" \ + -d ' + { + "project": { + "enabled": false + } + }'\ + http://localhost:5000/v3/projects/$PROJECT_ID | python -mjson.tool + +Example response: + +.. code-block:: javascript + + { + "project": { + "description": null, + "domain_id": "default", + "enabled": false, + "extra": {}, + "id": "3d4c2c82bd5948f0bcab0cf3a7c9b48c", + "links": { + "self": "http://localhost:5000/v3/projects/3d4c2c82bd5948f0bcab0cf3a7c9b48c" + }, + "name": "demo" + } + } + + +GET /v3/services +================ + +List the services: + +.. code-block:: bash + + curl -s \ + -H "X-Auth-Token: $OS_TOKEN" \ + http://localhost:5000/v3/services | python -mjson.tool + +Example response: + +.. code-block:: javascript + + { + "links": { + "next": null, + "previous": null, + "self": "http://localhost:5000/v3/services" + }, + "services": [ + { + "description": "Keystone Identity Service", + "enabled": true, + "id": "bd7397d2c0e14fb69bae8ff76e112a90", + "links": { + "self": "http://localhost:5000/v3/services/bd7397d2c0e14fb69bae8ff76e112a90" + }, + "name": "keystone", + "type": "identity" + } + ] + } + + + +GET /v3/endpoints +================= + +List the endpoints: + +.. code-block:: bash + + curl -s \ + -H "X-Auth-Token: $OS_TOKEN" \ + http://localhost:5000/v3/endpoints | python -mjson.tool + +Example response: + +.. code-block:: javascript + + { + "endpoints": [ + { + "enabled": true, + "id": "29beb2f1567642eb810b042b6719ea88", + "interface": "admin", + "links": { + "self": "http://localhost:5000/v3/endpoints/29beb2f1567642eb810b042b6719ea88" + }, + "region": "RegionOne", + "service_id": "bd7397d2c0e14fb69bae8ff76e112a90", + "url": "http://localhost:35357/v2.0" + } + ], + "links": { + "next": null, + "previous": null, + "self": "http://localhost:5000/v3/endpoints" + } + } + + +Users +===== + +GET /v3/users +------------- + +List users: + +.. code-block:: bash + + curl -s \ + -H "X-Auth-Token: $OS_TOKEN" \ + http://localhost:5000/v3/users | python -mjson.tool + +POST /v3/users +-------------- + +Create a user: + +.. code-block:: bash + + curl -s \ + -H "X-Auth-Token: $OS_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"user": {"name": "newuser", "password": "changeme"}}' \ + http://localhost:5000/v3/users | python -mjson.tool + +Example response: + +.. code-block:: javascript + + { + "user": { + "domain_id": "default", + "enabled": true, + "id": "ec8fc20605354edd91873f2d66bf4fc4", + "links": { + "self": "http://identity-server:5000/v3/users/ec8fc20605354edd91873f2d66bf4fc4" + }, + "name": "newuser" + } + } + +GET /v3/users/{user_id} +----------------------- + +Show details for a user: + +.. code-block:: bash + + USER_ID=ec8fc20605354edd91873f2d66bf4fc4 + + curl -s \ + -H "X-Auth-Token: $OS_TOKEN" \ + http://localhost:5000/v3/users/$USER_ID | python -mjson.tool + +Example response: + +.. code-block:: javascript + + { + "user": { + "domain_id": "default", + "enabled": true, + "id": "ec8fc20605354edd91873f2d66bf4fc4", + "links": { + "self": "http://localhost:5000/v3/users/ec8fc20605354edd91873f2d66bf4fc4" + }, + "name": "newuser" + } + } + +POST /v3/users/{user_id}/password +--------------------------------- + +Change password (using the default policy, this can be done as the user): + +.. code-block:: bash + + USER_ID=b7793000f8d84c79af4e215e9da78654 + ORIG_PASS=userpwd + NEW_PASS=newuserpwd + + curl \ + -H "X-Auth-Token: $OS_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ "user": {"password": "'$NEW_PASS'", "original_password": "'$ORIG_PASS'"} }' \ + http://localhost:5000/v3/users/$USER_ID/password + +.. note:: + + This command doesn't print anything if the request was successful. + +PATCH /v3/users/{user_id} +------------------------- + +Reset password (using the default policy, this requires admin): + +.. code-block:: bash + + USER_ID=b7793000f8d84c79af4e215e9da78654 + NEW_PASS=newuserpwd + + curl -s -X PATCH \ + -H "X-Auth-Token: $OS_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ "user": {"password": "'$NEW_PASS'"} }' \ + http://localhost:5000/v3/users/$USER_ID | python -mjson.tool + +Example response: + +.. code-block:: javascript + + { + "user": { + "default_project_id": "3d4c2c82bd5948f0bcab0cf3a7c9b48c", + "domain_id": "default", + "email": "demo@example.com", + "enabled": true, + "extra": { + "email": "demo@example.com" + }, + "id": "269348fdd9374b8885da1418e0730af1", + "links": { + "self": "http://localhost:5000/v3/users/269348fdd9374b8885da1418e0730af1" + }, + "name": "demo" + } + } + + +PUT /v3/projects/{project_id}/groups/{group_id}/roles/{role_id} +=============================================================== + +Create group role assignment on project: + +.. code-block:: bash + + curl -s -X PUT \ + -H "X-Auth-Token: $OS_TOKEN" \ + http://localhost:5000/v3/projects/$PROJECT_ID/groups/$GROUP_ID/roles/$ROLE_ID | + python -mjson.tool + +There's no data in the response if the operation is successful. + + +POST /v3/OS-TRUST/trusts +======================== + +Create a trust: + +.. code-block:: bash + + curl -s \ + -H "X-Auth-Token: $OS_TOKEN" \ + -H "Content-Type: application/json" \ + -d ' + { "trust": { + "expires_at": "2014-12-30T23:59:59.999999Z", + "impersonation": false, + "project_id": "'$PROJECT_ID'", + "roles": [ + { "name": "admin" } + ], + "trustee_user_id": "'$DEMO_USER_ID'", + "trustor_user_id": "'$ADMIN_USER_ID'" + }}'\ + http://localhost:5000/v3/OS-TRUST/trusts | python -mjson.tool + +Example response: + +.. code-block:: javascript + + { + "trust": { + "expires_at": "2014-12-30T23:59:59.999999Z", + "id": "394998fa61f14736b1f0c1f322882949", + "impersonation": false, + "links": { + "self": "http://localhost:5000/v3/OS-TRUST/trusts/394998fa61f14736b1f0c1f322882949" + }, + "project_id": "3d4c2c82bd5948f0bcab0cf3a7c9b48c", + "remaining_uses": null, + "roles": [ + { + "id": "c703057be878458588961ce9a0ce686b", + "links": { + "self": "http://localhost:5000/v3/roles/c703057be878458588961ce9a0ce686b" + }, + "name": "admin" + } + ], + "roles_links": { + "next": null, + "previous": null, + "self": "http://localhost:5000/v3/OS-TRUST/trusts/394998fa61f14736b1f0c1f322882949/roles" + }, + "trustee_user_id": "269348fdd9374b8885da1418e0730af1", + "trustor_user_id": "3ec3164f750146be97f21559ee4d9c51" + } + } + + +------------------------------- +Service API Examples Using Curl +------------------------------- + +The service API is defined to be a subset of the Admin API and, by +default, runs on port 5000. + +GET / +===== + +This call is identical to that documented for the Admin API, except +that it uses port 5000, instead of port 35357, by default: + +.. code-block:: bash + + $ curl http://0.0.0.0:5000 + +or: + +.. code-block:: bash + + $ curl http://0.0.0.0:5000/v2.0/ + +See the `Admin API Examples Using Curl`_ for more info. + +GET /extensions +=============== + +This call is identical to that documented for the Admin API. + +POST /tokens +============ + +This call is identical to that documented for the Admin API. + +GET /tenants +============ + +List all of the tenants your token can access: + +.. code-block:: bash + + $ curl -H "X-Auth-Token:887665443383838" http://localhost:5000/v2.0/tenants + +Returns: + +.. code-block:: javascript + + { + "tenants_links": [], + "tenants": [ + { + "enabled": true, + "description": "None", + "name": "customer-x", + "id": "1" + } + ] + } + +----------------------------- +Admin API Examples Using Curl +----------------------------- + +These examples assume a default port value of 35357, and depend on the +``sampledata`` bundled with keystone. + +GET / +===== + +Discover API version information, links to documentation (PDF, HTML, WADL), +and supported media types: + +.. code-block:: bash + + $ curl http://0.0.0.0:35357 + +or: + +.. code-block:: bash + + $ curl http://0.0.0.0:35357/v2.0/ + +Returns: + +.. code-block:: javascript + + { + "version":{ + "id":"v2.0", + "status":"beta", + "updated":"2011-11-19T00:00:00Z", + "links":[ + { + "rel":"self", + "href":"http://127.0.0.1:35357/v2.0/" + }, + { + "rel":"describedby", + "type":"text/html", + "href":"http://docs.openstack.org/" + }, + ], + "media-types":[ + { + "base":"application/json", + "type":"application/vnd.openstack.identity-v2.0+json" + } + ] + } + } + +GET /extensions +=============== + +Discover the API extensions enabled at the endpoint: + +.. code-block:: bash + + $ curl http://localhost:35357/v2.0/extensions/ + +Returns: + +.. code-block:: javascript + + { + "extensions":{ + "values":[] + } + } + +POST /tokens +============ + +Authenticate by exchanging credentials for an access token: + +.. code-block:: bash + + $ curl -d '{"auth":{"tenantName": "customer-x", "passwordCredentials": {"username": "joeuser", "password": "secrete"}}}' -H "Content-type: application/json" http://localhost:35357/v2.0/tokens + +Returns: + +.. code-block:: javascript + + { + "access":{ + "token":{ + "expires":"2012-02-05T00:00:00", + "id":"887665443383838", + "tenant":{ + "id":"1", + "name":"customer-x" + } + }, + "serviceCatalog":[ + { + "endpoints":[ + { + "adminURL":"http://swift.admin-nets.local:8080/", + "region":"RegionOne", + "internalURL":"http://127.0.0.1:8080/v1/AUTH_1", + "publicURL":"http://swift.publicinternets.com/v1/AUTH_1" + } + ], + "type":"object-store", + "name":"swift" + }, + { + "endpoints":[ + { + "adminURL":"http://cdn.admin-nets.local/v1.1/1", + "region":"RegionOne", + "internalURL":"http://127.0.0.1:7777/v1.1/1", + "publicURL":"http://cdn.publicinternets.com/v1.1/1" + } + ], + "type":"object-store", + "name":"cdn" + } + ], + "user":{ + "id":"1", + "roles":[ + { + "tenantId":"1", + "id":"3", + "name":"Member" + } + ], + "name":"joeuser" + } + } + } + +.. note:: + + Take note of the value ['access']['token']['id'] value produced here (``887665443383838``, above), as you can use it in the calls below. + +GET /tokens/{token_id} +====================== + +.. note:: + + This call refers to a token known to be valid, ``887665443383838`` in this case. + +Validate a token: + +.. code-block:: bash + + $ curl -H "X-Auth-Token:999888777666" http://localhost:35357/v2.0/tokens/887665443383838 + +If the token is valid, returns: + +.. code-block:: javascript + + { + "access":{ + "token":{ + "expires":"2012-02-05T00:00:00", + "id":"887665443383838", + "tenant":{ + "id":"1", + "name":"customer-x" + } + }, + "user":{ + "name":"joeuser", + "tenantName":"customer-x", + "id":"1", + "roles":[ + { + "serviceId":"1", + "id":"3", + "name":"Member" + } + ], + "tenantId":"1" + } + } + } + +HEAD /tokens/{token_id} +======================= + +This is a high-performance variant of the GET call documented above, which +by definition, returns no response body: + +.. code-block:: bash + + $ curl -I -H "X-Auth-Token:999888777666" http://localhost:35357/v2.0/tokens/887665443383838 + +... which returns ``200``, indicating the token is valid:: + + HTTP/1.1 200 OK + Content-Length: 0 + Content-Type: None + Date: Tue, 08 Nov 2011 23:07:44 GMT + +GET /tokens/{token_id}/endpoints +================================ + +List all endpoints for a token: + +.. code-block:: bash + + $ curl -H "X-Auth-Token:999888777666" http://localhost:35357/v2.0/tokens/887665443383838/endpoints + +Returns: + +.. code-block:: javascript + + { + "endpoints_links": [ + { + "href": "http://127.0.0.1:35357/tokens/887665443383838/endpoints?'marker=5&limit=10'", + "rel": "next" + } + ], + "endpoints": [ + { + "internalURL": "http://127.0.0.1:8080/v1/AUTH_1", + "name": "swift", + "adminURL": "http://swift.admin-nets.local:8080/", + "region": "RegionOne", + "tenantId": 1, + "type": "object-store", + "id": 1, + "publicURL": "http://swift.publicinternets.com/v1/AUTH_1" + }, + { + "internalURL": "http://localhost:8774/v1.0", + "name": "nova_compat", + "adminURL": "http://127.0.0.1:8774/v1.0", + "region": "RegionOne", + "tenantId": 1, + "type": "compute", + "id": 2, + "publicURL": "http://nova.publicinternets.com/v1.0/" + }, + { + "internalURL": "http://localhost:8774/v1.1", + "name": "nova", + "adminURL": "http://127.0.0.1:8774/v1.1", + "region": "RegionOne", + "tenantId": 1, + "type": "compute", + "id": 3, + "publicURL": "http://nova.publicinternets.com/v1.1/ + }, + { + "internalURL": "http://127.0.0.1:9292/v1.1/", + "name": "glance", + "adminURL": "http://nova.admin-nets.local/v1.1/", + "region": "RegionOne", + "tenantId": 1, + "type": "image", + "id": 4, + "publicURL": "http://glance.publicinternets.com/v1.1/" + }, + { + "internalURL": "http://127.0.0.1:7777/v1.1/1", + "name": "cdn", + "adminURL": "http://cdn.admin-nets.local/v1.1/1", + "region": "RegionOne", + "tenantId": 1, + "type": "object-store", + "id": 5, + "publicURL": "http://cdn.publicinternets.com/v1.1/1" + } + ] + } + +GET /tenants +============ + +List all of the tenants in the system (requires an Admin ``X-Auth-Token``): + +.. code-block:: bash + + $ curl -H "X-Auth-Token:999888777666" http://localhost:35357/v2.0/tenants + +Returns: + +.. code-block:: javascript + + { + "tenants_links": [], + "tenants": [ + { + "enabled": false, + "description": "None", + "name": "project-y", + "id": "3" + }, + { + "enabled": true, + "description": "None", + "name": "ANOTHER:TENANT", + "id": "2" + }, + { + "enabled": true, + "description": "None", + "name": "customer-x", + "id": "1" + } + ] + } + +GET /tenants/{tenant_id} +======================== + +Retrieve information about a tenant, by tenant ID: + +.. code-block:: bash + + $ curl -H "X-Auth-Token:999888777666" http://localhost:35357/v2.0/tenants/1 + +Returns: + +.. code-block:: javascript + + { + "tenant":{ + "enabled":true, + "description":"None", + "name":"customer-x", + "id":"1" + } + } + +GET /tenants/{tenant_id}/users/{user_id}/roles +============================================== + +List the roles a user has been granted on a tenant: + +.. code-block:: bash + + $ curl -H "X-Auth-Token:999888777666" http://localhost:35357/v2.0/tenants/1/users/1/roles + +Returns: + +.. code-block:: javascript + + { + "roles_links":[], + "roles":[ + { + "id":"3", + "name":"Member" + } + ] + } + +GET /users/{user_id} +==================== + +Retrieve information about a user, by user ID: + +.. code-block:: bash + + $ curl -H "X-Auth-Token:999888777666" http://localhost:35357/v2.0/users/1 + +Returns: + +.. code-block:: javascript + + { + "user":{ + "tenantId":"1", + "enabled":true, + "id":"1", + "name":"joeuser" + } + } + +GET /tokens/revoked +=================== + +Get the revocation list: + +.. code-block:: bash + + curl -s -H "X-Auth-Token: $OS_TOKEN" \ + http://localhost:35357/v2.0/tokens/revoked | + jq -r .signed | + openssl cms -verify \ + -certfile /etc/keystone/ssl/certs/signing_cert.pem \ + -CAfile /etc/keystone/ssl/certs/ca.pem \ + -inform PEM \ + -nosmimecap -nodetach -nocerts -noattr 2>/dev/null | + python -m json.tool + +Example response: + +.. code-block:: javascript + + { + "revoked": [ + { + "expires": "2014-06-10T21:40:14Z", + "id": "e6e2b5c9092751f88d2bcd30b09777a9" + }, + { + "expires": "2014-06-10T21:47:29Z", + "id": "883ef5d610bd1c68fbaa8ac528aa9f17" + }, + { + "expires": "2014-06-10T21:51:52Z", + "id": "41775ff4838f8f406b7bad28bea0dde6" + } + ] + } diff --git a/keystone-moon/doc/source/architecture.rst b/keystone-moon/doc/source/architecture.rst new file mode 100644 index 00000000..75b0ceae --- /dev/null +++ b/keystone-moon/doc/source/architecture.rst @@ -0,0 +1,307 @@ +.. + Copyright 2011-2012 OpenStack Foundation + 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. + +Keystone Architecture +===================== + +Much of the design is precipitated from the expectation that the auth backends +for most deployments will actually be shims in front of existing user systems. + + +------------ +The Services +------------ + +Keystone is organized as a group of internal services exposed on one or many +endpoints. Many of these services are used in a combined fashion by the +frontend, for example an authenticate call will validate user/project +credentials with the Identity service and, upon success, create and return a +token with the Token service. + + +Identity +-------- + +The Identity service provides auth credential validation and data about Users, +Groups. + +In the basic case all this data is managed by the service, allowing the service +to manage all the CRUD associated with the data. + +In other cases from an authoritative backend service. An example of this would +be when backending on LDAP. See `LDAP Backend` below for more details. + + +Resource +-------- + +The Resource service provides data about Projects and Domains. + +Like the Identity service, this data may either be managed directly by the +service or be pulled from another authoritative backend service, such as LDAP. + + +Assignment +---------- + +The Assignment service provides data about Roles and Role assignments to the +entities managed by the Identity and Resource services. Again, like these two +services, this data may either be managed directly by the Assignment service +or be pulled from another authoritative backend service, such as LDAP. + + +Token +----- + +The Token service validates and manages Tokens used for authenticating requests +once a user's credentials have already been verified. + + +Catalog +------- + +The Catalog service provides an endpoint registry used for endpoint discovery. + + +Policy +------ + +The Policy service provides a rule-based authorization engine and the +associated rule management interface. + + +------------------------ +Application Construction +------------------------ + +Keystone is an HTTP front-end to several services. Like other OpenStack +applications, this is done using python WSGI interfaces and applications are +configured together using Paste_. The application's HTTP endpoints are made up +of pipelines of WSGI middleware, such as: + +.. code-block:: ini + + [pipeline:api_v3] + pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth + json_body ec2_extension_v3 s3_extension service_v3 + +These in turn use a subclass of :mod:`keystone.common.wsgi.ComposingRouter` to +link URLs to Controllers (a subclass of +:mod:`keystone.common.wsgi.Application`). Within each Controller, one or more +Managers are loaded (for example, see :mod:`keystone.catalog.core.Manager`), +which are thin wrapper classes which load the appropriate service driver based +on the Keystone configuration. + +* Assignment + + * :mod:`keystone.assignment.controllers.GrantAssignmentV3` + * :mod:`keystone.assignment.controllers.ProjectAssignmentV3` + * :mod:`keystone.assignment.controllers.TenantAssignment` + * :mod:`keystone.assignment.controllers.Role` + * :mod:`keystone.assignment.controllers.RoleAssignmentV2` + * :mod:`keystone.assignment.controllers.RoleAssignmentV3` + * :mod:`keystone.assignment.controllers.RoleV3` + +* Authentication + + * :mod:`keystone.auth.controllers.Auth` + +* Catalog + + * :mod:`keystone.catalog.controllers.EndpointV3` + * :mod:`keystone.catalog.controllers.RegionV3` + * :mod:`keystone.catalog.controllers.ServiceV3` + +* Identity + + * :mod:`keystone.identity.controllers.GroupV3` + * :mod:`keystone.identity.controllers.UserV3` + +* Policy + + * :mod:`keystone.policy.controllers.PolicyV3` + +* Resource + + * :mod:`keystone.resource.controllers.DomainV3` + * :mod:`keystone.resource.controllers.ProjectV3` + +* Token + + * :mod:`keystone.token.controllers.Auth` + + +.. _Paste: http://pythonpaste.org/ + + +---------------- +Service Backends +---------------- + +Each of the services can be configured to use a backend to allow Keystone to fit a +variety of environments and needs. The backend for each service is defined in +the keystone.conf file with the key ``driver`` under a group associated with +each service. + +A general class under each backend named ``Driver`` exists to provide an +abstract base class for any implementations, identifying the expected service +implementations. The drivers for the services are: + +* :mod:`keystone.assignment.core.Driver` +* :mod:`keystone.assignment.core.RoleDriver` +* :mod:`keystone.catalog.core.Driver` +* :mod:`keystone.identity.core.Driver` +* :mod:`keystone.policy.core.Driver` +* :mod:`keystone.resource.core.Driver` +* :mod:`keystone.token.core.Driver` + +If you implement a backend driver for one of the Keystone services, you're +expected to subclass from these classes. + + +SQL Backend +----------- + +A SQL based backend using SQLAlchemy to store data persistently. The +``keystone-manage`` command introspects the backends to identify SQL based backends +when running "db_sync" to establish or upgrade schema. If the backend driver +has a method db_sync(), it will be invoked to sync and/or migrate schema. + + +Templated Backend +----------------- + +Largely designed for a common use case around service catalogs in the Keystone +project, a Catalog backend that simply expands pre-configured templates to +provide catalog data. + +Example paste.deploy config (uses $ instead of % to avoid ConfigParser's +interpolation):: + + [DEFAULT] + catalog.RegionOne.identity.publicURL = http://localhost:$(public_port)s/v2.0 + catalog.RegionOne.identity.adminURL = http://localhost:$(public_port)s/v2.0 + catalog.RegionOne.identity.internalURL = http://localhost:$(public_port)s/v2.0 + catalog.RegionOne.identity.name = 'Identity Service' + + +LDAP Backend +------------ + +The LDAP backend stores Users and Projects in separate Subtrees. Roles are recorded +as entries under the Projects. + + +---------- +Data Model +---------- + +Keystone was designed from the ground up to be amenable to multiple styles of +backends and as such many of the methods and data types will happily accept +more data than they know what to do with and pass them on to a backend. + +There are a few main data types: + + * **User**: has account credentials, is associated with one or more projects or domains + * **Group**: a collection of users, is associated with one or more projects or domains + * **Project**: unit of ownership in OpenStack, contains one or more users + * **Domain**: unit of ownership in OpenStack, contains users, groups and projects + * **Role**: a first-class piece of metadata associated with many user-project pairs. + * **Token**: identifying credential associated with a user or user and project + * **Extras**: bucket of key-value metadata associated with a user-project pair. + * **Rule**: describes a set of requirements for performing an action. + +While the general data model allows a many-to-many relationship between Users +and Groups to Projects and Domains; the actual backend implementations take +varying levels of advantage of that functionality. + + +---------------- +Approach to CRUD +---------------- + +While it is expected that any "real" deployment at a large company will manage +their users, groups, projects and domains in their existing user systems, a +variety of CRUD operations are provided for the sake of development and testing. + +CRUD is treated as an extension or additional feature to the core feature set +in that it is not required that a backend support it. It is expected that +backends for services that don't support the CRUD operations will raise a +:mod:`keystone.exception.NotImplemented`. + + +---------------------------------- +Approach to Authorization (Policy) +---------------------------------- + +Various components in the system require that different actions are allowed +based on whether the user is authorized to perform that action. + +For the purposes of Keystone there are only a couple levels of authorization +being checked for: + + * Require that the performing user is considered an admin. + * Require that the performing user matches the user being referenced. + +Other systems wishing to use the policy engine will require additional styles +of checks and will possibly write completely custom backends. By default, +Keystone leverages Policy enforcement that is maintained in Oslo-Incubator, +found in `keystone/openstack/common/policy.py`. + + +Rules +----- + +Given a list of matches to check for, simply verify that the credentials +contain the matches. For example: + +.. code-block:: python + + credentials = {'user_id': 'foo', 'is_admin': 1, 'roles': ['nova:netadmin']} + + # An admin only call: + policy_api.enforce(('is_admin:1',), credentials) + + # An admin or owner call: + policy_api.enforce(('is_admin:1', 'user_id:foo'), credentials) + + # A netadmin call: + policy_api.enforce(('roles:nova:netadmin',), credentials) + +Credentials are generally built from the user metadata in the 'extras' part +of the Identity API. So, adding a 'role' to the user just means adding the role +to the user metadata. + + +Capability RBAC +--------------- + +(Not yet implemented.) + +Another approach to authorization can be action-based, with a mapping of roles +to which capabilities are allowed for that role. For example: + +.. code-block:: python + + credentials = {'user_id': 'foo', 'is_admin': 1, 'roles': ['nova:netadmin']} + + # add a policy + policy_api.add_policy('action:nova:add_network', ('roles:nova:netadmin',)) + + policy_api.enforce(('action:nova:add_network',), credentials) + +In the backend this would look up the policy for 'action:nova:add_network' and +then do what is effectively a 'Simple Match' style match against the credentials. diff --git a/keystone-moon/doc/source/cli_examples.rst b/keystone-moon/doc/source/cli_examples.rst new file mode 100644 index 00000000..57735db5 --- /dev/null +++ b/keystone-moon/doc/source/cli_examples.rst @@ -0,0 +1,316 @@ +.. + Copyright 2011-2012 OpenStack Foundation + 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. + +=============================== +Command Line Interface Examples +=============================== + +The Keystone command line interface packaged in `python-keystoneclient`_ only +supports the Identity v2.0 API. The OpenStack common command line interface +packaged in `python-openstackclient`_ supports both v2.0 and v3 APIs. + +.. NOTE:: + + As of the Juno release, it is recommended to use ``python-openstackclient``, + as it supports both v2.0 and v3 APIs. For the purpose of backwards compatibility, + the CLI packaged in ``python-keystoneclient`` is not being removed. + +.. _`python-openstackclient`: http://docs.openstack.org/developer/python-openstackclient/ +.. _`python-keystoneclient`: http://docs.openstack.org/developer/python-keystoneclient/ + +Using python-openstackclient (v3 or v2.0) +========================================= + +A complete list of OpenStackClient commands with full examples are located at +OpenStackClient's `Command List`_ page. Additionally, for details related to +authentication, refer to OpenStackClient's `Authentication`_ page. + +.. _`Command List`: http://docs.openstack.org/developer/python-openstackclient/command-list.html +.. _`Authentication`: http://docs.openstack.org/developer/python-openstackclient/authentication.html + +Using python-keystoneclient (v2.0-only) +======================================= + +------- +Tenants +------- + +``tenant-create`` +----------------- + +keyword arguments + +* name +* description (optional, defaults to None) +* enabled (optional, defaults to True) + +example: + +.. code-block:: bash + + $ keystone tenant-create --name=demo + +creates a tenant named "demo". + +``tenant-delete`` +----------------- + +arguments + +* tenant_id + +example: + +.. code-block:: bash + + $ keystone tenant-delete f2b7b39c860840dfa47d9ee4adffa0b3 + +----- +Users +----- + +``user-create`` +--------------- + +keyword arguments + +* name +* pass +* email +* tenant_id (optional, defaults to None) +* enabled (optional, defaults to True) + +example: + +.. code-block:: bash + + $ keystone user-create + --name=admin \ + --pass=secrete \ + --tenant_id=2395953419144b67955ac4bab96b8fd2 \ + --email=admin@example.com + +``user-delete`` +--------------- + +keyword arguments + +* user_id + +example: + +.. code-block:: bash + + $ keystone user-delete f2b7b39c860840dfa47d9ee4adffa0b3 + +``user-list`` +------------- + +list users in the system, optionally by a specific tenant (identified by tenant_id) + +arguments + +* tenant_id (optional, defaults to None) + +example: + +.. code-block:: bash + + $ keystone user-list + +``user-update`` +--------------------- + +arguments + +* user_id + +keyword arguments + +* name Desired new user name (Optional) +* email Desired new email address (Optional) +* enabled <true|false> Enable or disable user (Optional) + + +example: + +.. code-block:: bash + + $ keystone user-update 03c84b51574841ba9a0d8db7882ac645 --email=newemail@example.com + +``user-password-update`` +------------------------ + +arguments + +* user_id +* password + +example: + +.. code-block:: bash + + $ keystone user-password-update --pass foo 03c84b51574841ba9a0d8db7882ac645 + +----- +Roles +----- + +``role-create`` +--------------- + +arguments + +* name + +example: + +.. code-block:: bash + + $ keystone role-create --name=demo + +``role-delete`` +--------------- + +arguments + +* role_id + +example: + +.. code-block:: bash + + $ keystone role-delete 19d1d3344873464d819c45f521ff9890 + +``role-list`` +------------- + +example: + +.. code-block:: bash + + $ keystone role-list + +``role-get`` +------------ + +arguments + +* role_id + +example: + +.. code-block:: bash + + $ keystone role-get 19d1d3344873464d819c45f521ff9890 + + +``user-role-add`` +----------------- + +keyword arguments + +* user <user-id> +* role <role-id> +* tenant_id <tenant-id> + +example: + +.. code-block:: bash + + $ keystone user-role-add \ + --user=96a6ebba0d4c441887aceaeced892585 \ + --role=f8dd5a2e4dc64a41b96add562d9a764e \ + --tenant_id=2395953419144b67955ac4bab96b8fd2 + +``user-role-remove`` +-------------------- + +keyword arguments + +* user <user-id> +* role <role-id> +* tenant_id <tenant-id> + +example: + +.. code-block:: bash + + $ keystone user-role-remove \ + --user=96a6ebba0d4c441887aceaeced892585 \ + --role=f8dd5a2e4dc64a41b96add562d9a764e \ + --tenant_id=2395953419144b67955ac4bab96b8fd2 + +-------- +Services +-------- + +``service-create`` +------------------ + +keyword arguments + +* name +* type +* description + +example: + +.. code-block:: bash + + $ keystone service-create \ + --name=nova \ + --type=compute \ + --description="Nova Compute Service" + +``service-list`` +---------------- + +arguments + +* service_id + +example: + +.. code-block:: bash + + $ keystone service-list + +``service-get`` +--------------- + +arguments + +* service_id + +example: + +.. code-block:: bash + + $ keystone service-get 08741d8ed88242ca88d1f61484a0fe3b + +``service-delete`` +------------------ + +arguments + +* service_id + +example: + +.. code-block:: bash + + $ keystone service-delete 08741d8ed88242ca88d1f61484a0fe3b diff --git a/keystone-moon/doc/source/community.rst b/keystone-moon/doc/source/community.rst new file mode 100644 index 00000000..e1df0b89 --- /dev/null +++ b/keystone-moon/doc/source/community.rst @@ -0,0 +1,101 @@ +.. + Copyright 2011-2012 OpenStack Foundation + 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. + +================ +Getting Involved +================ + +The OpenStack community is a very friendly group and there are places online to +join in with the community. Feel free to ask questions. This document points +you to some of the places where you can communicate with people. + +How to Join the Community +========================= + +Our community welcomes all people interested in open source cloud computing, +and there are no formal membership requirements. The best way to join the +community is to talk with others online or at a meetup and offer contributions +through Launchpad_, the wiki_, or blogs. We welcome all types of contributions, + +from blueprint designs to documentation to testing to deployment scripts. + +.. _Launchpad: https://launchpad.net/keystone +.. _wiki: http://wiki.openstack.org/ + +#openstack-keystone on Freenode IRC Network +------------------------------------------- + +You can find Keystone folks in `<irc://freenode.net/#openstack-keystone>`_. +This is usually the best place to ask questions and find your way around. IRC +stands for Internet Relay Chat and it is a way to chat online in real time. +You can also ask a question and come back to the log files to read the answer +later. Logs for the #openstack IRC channels are stored at +`<http://eavesdrop.openstack.org/irclogs/>`_. + +For more information regarding OpenStack IRC channels please visit the +`OpenStack IRC Wiki <https://wiki.openstack.org/wiki/IRC>`_. + +OpenStack Wiki +-------------- + +The wiki is a living source of knowledge. It is edited by the community, and +has collections of links and other sources of information. Typically the pages +are a good place to write drafts for specs or documentation, describe a +blueprint, or collaborate with others. + +`OpenStack Wiki <http://wiki.openstack.org/>`_ + +* `useful Keystone project links <http://wiki.openstack.org/Keystone>`_ + +Keystone on Launchpad +--------------------- + +Launchpad is a code hosting that OpenStack is using to track bugs, feature +work, and releases of OpenStack. Like other OpenStack projects, Keystone source +code is hosted on GitHub + +* `Keystone Project Page on Launchpad <http://launchpad.net/keystone>`_ +* `Keystone Source Repository on GitHub <http://github.com/openstack/keystone>`_ + +Within launchpad, we use +`blueprints <https://blueprints.launchpad.net/keystone>`_, to track feature +work, and track `bugs <https://bugs.launchpad.net/keystone>`_ as well. If +you are looking for a place to get started contributing to keystone, please +look at any bugs for Keystone that are tagged as `low-hanging-fruit +<https://bugs.launchpad.net/keystone/+bugs?field.tag=low-hanging-fruit>`_. + +OpenStack Blog +-------------- + +The OpenStack blog includes a weekly newsletter that aggregates OpenStack news +from around the internet, as well as providing inside information on upcoming +events and posts from OpenStack contributors. + +`OpenStack Blog <http://openstack.org/blog>`_ + +See also: `Planet OpenStack <http://planet.openstack.org/>`_, an aggregation of +blogs about OpenStack from around the internet, combined into a web site and +RSS feed. If you'd like to contribute with your blog posts, there are +instructions for `adding your blog <http://wiki.openstack.org/AddingYourBlog>`_. + + +Twitter +------- + +Because all the cool kids do it: `@openstack <http://twitter.com/openstack>`_. +Also follow the `#openstack <http://search.twitter.com/search?q=%23openstack>`_ +tag for relevant tweets. + diff --git a/keystone-moon/doc/source/conf.py b/keystone-moon/doc/source/conf.py new file mode 100644 index 00000000..fe46f326 --- /dev/null +++ b/keystone-moon/doc/source/conf.py @@ -0,0 +1,274 @@ +# 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. + +# +# keystone documentation build configuration file, created by +# sphinx-quickstart on Mon Jan 9 12:02:59 2012. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath('..')) # NOTE(dstanek): path for our + # Sphinx extension + +# NOTE(dstanek): adds _ to the builtins so keystone modules can be imported +__builtins__['_'] = str + +# -- General configuration ---------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['sphinx.ext.autodoc', + 'sphinx.ext.todo', + 'sphinx.ext.coverage', + 'sphinx.ext.viewcode', + 'oslosphinx', + # NOTE(dstanek): Uncomment the [pbr] section in setup.cfg and + # remove this Sphinx extension when + # https://launchpad.net/bugs/1260495 is fixed. + 'ext.apidoc', + ] + +todo_include_todos = True + +# Add any paths that contain templates here, relative to this directory. +# if os.getenv('HUDSON_PUBLISH_DOCS'): +# templates_path = ['_ga', '_templates'] +# else: +# templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'keystone' +copyright = u'2012, OpenStack, LLC' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['old'] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +show_authors = True + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +modindex_common_prefix = ['keystone.'] + +# -- Options for man page output -------------------------------------------- + +# Grouping the document tree for man pages. +# List of tuples 'sourcefile', 'target', u'title', u'Authors name', 'manual' + +man_pages = [ + ('man/keystone-manage', 'keystone-manage', u'Keystone Management Utility', + [u'OpenStack'], 1), + ('man/keystone-all', 'keystone-all', u'Keystone Startup Command', + [u'OpenStack'], 1), +] + + +# -- Options for HTML output -------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# html_theme_path = ["."] +# html_theme = '_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# "<project> v<release> documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#html_static_path = ['images'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' +git_cmd = "git log --pretty=format:'%ad, commit %h' --date=local -n1" +html_last_updated_fmt = os.popen(git_cmd).read() + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a <link> tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'keystonedoc' + + +# -- Options for LaTeX output ------------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + #'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples (source +# start file, target name, title, author, documentclass +# [howto/manual]). +latex_documents = [ + ('index', 'keystone.tex', u'Keystone Documentation', + u'OpenStack', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for Texinfo output ----------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'keystone', u'Keystone Documentation', + u'OpenStack', 'keystone', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + + +# Example configuration for intersphinx: refer to the Python standard library. +#intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/keystone-moon/doc/source/configuration.rst b/keystone-moon/doc/source/configuration.rst new file mode 100644 index 00000000..e365f0ed --- /dev/null +++ b/keystone-moon/doc/source/configuration.rst @@ -0,0 +1,1734 @@ +.. + Copyright 2011-2012 OpenStack Foundation + 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 Keystone +==================== + +.. toctree:: + :maxdepth: 1 + + man/keystone-manage + man/keystone-all + +Once Keystone is installed, it is configured via a primary configuration file +(``etc/keystone.conf``), a PasteDeploy configuration file +(``etc/keystone-paste.ini``), possibly a separate logging configuration file, +and initializing data into Keystone using the command line client. + +By default, Keystone starts a service on `IANA-assigned port 35357 +<http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt>`_. +This may overlap with your system's ephemeral port range, so another process +may already be using this port without being explicitly configured to do so. To +prevent this scenario from occurring, it's recommended that you explicitly +exclude port 35357 from the available ephemeral port range. On a Linux system, +this would be accomplished by: + +.. code-block:: bash + + $ sysctl -w 'sys.net.ipv4.ip_local_reserved_ports=35357' + +To make the above change persistent, +``net.ipv4.ip_local_reserved_ports = 35357`` should be added to +``/etc/sysctl.conf`` or to ``/etc/sysctl.d/keystone.conf``. + +Starting and Stopping Keystone under Eventlet +============================================= + +.. WARNING:: + + Running keystone under eventlet has been deprecated as of the Kilo release. + Support for utilizing eventlet will be removed as of the M-release. The + recommended deployment is to run keystone in a WSGI server + (e.g. ``mod_wsgi`` under ``HTTPD``). + +Keystone can be run using either its built-in eventlet server or it can be run +embedded in a web server. While the eventlet server is convenient and easy to +use, it's lacking in security features that have been developed into Internet- +based web servers over the years. As such, running the eventlet server as +described in this section is not recommended. + +Start Keystone services using the command: + +.. code-block:: bash + + $ keystone-all + +Invoking this command starts up two ``wsgi.Server`` instances, ``admin`` (the +administration API) and ``main`` (the primary/public API interface). Both +services are configured to run in a single process. + +.. NOTE:: + + The separation into ``admin`` and ``main`` interfaces is an historical + anomaly. The new V3 API provides the same interface on both the admin and + main interfaces (this can be configured in ``keystone-paste.ini``, but the + default is to have both the same). The V2.0 API provides a limited public + API (getting and validating tokens) on ``main``, and an administrative API + (which can include creating users and such) on the ``admin`` interface. + +Stop the process using ``Control-C``. + +.. NOTE:: + + If you have not already configured Keystone, it may not start as expected. + + +Configuration Files +=================== + +The Keystone configuration files are an ``ini`` file format based on Paste_, a +common system used to configure Python WSGI based applications. The PasteDeploy +configuration entries (WSGI pipeline definitions) can be provided in a separate +``keystone-paste.ini`` file, while general and driver-specific configuration +parameters are in the primary configuration file ``keystone.conf``. + +.. NOTE:: + + Since keystone's PasteDeploy configuration file has been separated + from the main keystone configuration file, ``keystone.conf``, all + local configuration or driver-specific configuration parameters must + go in the main keystone configuration file instead of the PasteDeploy + configuration file, i.e. configuration in ``keystone-paste.ini`` + is not supported. + +The primary configuration file is organized into the following sections: + +* ``[DEFAULT]`` - General configuration +* ``[assignment]`` - Assignment system driver configuration +* ``[auth]`` - Authentication plugin configuration +* ``[cache]`` - Caching layer configuration +* ``[catalog]`` - Service catalog driver configuration +* ``[credential]`` - Credential system driver configuration +* ``[endpoint_filter]`` - Endpoint filtering extension configuration +* ``[endpoint_policy]`` - Endpoint policy extension configuration +* ``[eventlet_server]`` - Eventlet server configuration +* ``[eventlet_server_ssl]`` - Eventlet server SSL configuration +* ``[federation]`` - Federation driver configuration +* ``[identity]`` - Identity system driver configuration +* ``[identity_mapping]`` - Identity mapping system driver configuration +* ``[kvs]`` - KVS storage backend configuration +* ``[ldap]`` - LDAP configuration options +* ``[memcache]`` - Memcache configuration options +* ``[oauth1]`` - OAuth 1.0a system driver configuration +* ``[os_inherit]`` - Inherited role assignment extension +* ``[paste_deploy]`` - Pointer to the PasteDeploy configuration file +* ``[policy]`` - Policy system driver configuration for RBAC +* ``[resource]`` - Resource system driver configuration +* ``[revoke]`` - Revocation system driver configuration +* ``[role]`` - Role system driver configuration +* ``[saml]`` - SAML configuration options +* ``[signing]`` - Cryptographic signatures for PKI based tokens +* ``[ssl]`` - SSL certificate generation configuration +* ``[token]`` - Token driver & token provider configuration +* ``[trust]`` - Trust extension configuration + +The Keystone primary configuration file is expected to be named +``keystone.conf``. When starting Keystone, you can specify a different +configuration file to use with ``--config-file``. If you do **not** specify a +configuration file, Keystone will look in the following directories for a +configuration file, in order: + +* ``~/.keystone/`` +* ``~/`` +* ``/etc/keystone/`` +* ``/etc/`` + +PasteDeploy configuration file is specified by the ``config_file`` parameter in +``[paste_deploy]`` section of the primary configuration file. If the parameter +is not an absolute path, then Keystone looks for it in the same directories as +above. If not specified, WSGI pipeline definitions are loaded from the primary +configuration file. + +Domain-specific Drivers +----------------------- + +.. NOTE:: + + This functionality is new in Juno. + +Keystone supports the option (disabled by default) to specify identity driver +configurations on a domain by domain basis, allowing, for example, a specific +domain to have its own LDAP or SQL server. This is configured by specifying the +following options: + +.. code-block:: ini + + [identity] + domain_specific_drivers_enabled = True + domain_config_dir = /etc/keystone/domains + +Setting ``domain_specific_drivers_enabled`` to ``True`` will enable this +feature, causing Keystone to look in the ``domain_config_dir`` for config files +of the form:: + + keystone.<domain_name>.conf + +Options given in the domain specific configuration file will override those in +the primary configuration file for the specified domain only. Domains without a +specific configuration file will continue to use the options from the primary +configuration file. + +.. NOTE:: + + It is important to notice that by enabling this configuration, the + operations of listing all users and listing all groups are not supported, + those calls will need that either a domain filter is specified or the usage + of a domain scoped token. + +.. NOTE:: + + Keystone does not support moving the contents of a domain (i.e. "its" users + and groups) from one backend to another, nor group membership across + backend boundaries. + +.. NOTE:: + + To delete a domain that uses a domain specific backend, it's necessary to + first disable it, remove its specific configuration file (i.e. its + corresponding keystone.<domain_name>.conf) and then restart the Identity + server. + +.. NOTE:: + + Although Keystone supports multiple LDAP backends via domain specific + configuration files, it currently only supports one SQL backend. This could + be either the default driver or a single domain-specific backend, perhaps + for storing service users in a predominantly LDAP installation. + +Due to the need for user and group IDs to be unique across an OpenStack +installation and for Keystone to be able to deduce which domain and backend to +use from just a user or group ID, it dynamically builds a persistent identity +mapping table from a public ID to the actual domain, local ID (within that +backend) and entity type. The public ID is automatically generated by Keystone +when it first encounters the entity. If the local ID of the entity is from a +backend that does not guarantee to generate UUIDs, a hash algorithm will +generate a public ID for that entity, which is what will be exposed by +Keystone. + +The use of a hash will ensure that if the public ID needs to be regenerated +then the same public ID will be created. This is useful if you are running +multiple keystones and want to ensure the same ID would be generated whichever +server you hit. + +While Keystone will dynamically maintain the identity mapping, including +removing entries when entities are deleted via the Keystone, for those entities +in backends that are managed outside of Keystone (e.g. a Read Only LDAP), +Keystone will not know if entities have been deleted and hence will continue to +carry stale identity mappings in its table. While benign, keystone provides an +ability for operators to purge the mapping table of such stale entries using +the keystone-manage command, for example: + +.. code-block:: bash + + $ keystone-manage mapping_purge --domain-name DOMAINA --local-id abc@de.com + +A typical usage would be for an operator to obtain a list of those entries in +an external backend that had been deleted out-of-band to Keystone, and then +call keystone-manage to purge those entries by specifying the domain and +local-id. The type of the entity (i.e. user or group) may also be specified if +this is needed to uniquely identify the mapping. + +Since public IDs can be regenerated **with the correct generator +implementation**, if the details of those entries that have been deleted are +not available, then it is safe to simply bulk purge identity mappings +periodically, for example: + +.. code-block:: bash + + $ keystone-manage mapping_purge --domain-name DOMAINA + +will purge all the mappings for DOMAINA. The entire mapping table can be purged +with the following command: + +.. code-block:: bash + + $ keystone-manage mapping_purge --all + +Public ID Generators +-------------------- + +Keystone supports a customizable public ID generator and it is specified in the +``[identity_mapping]`` section of the configuration file. Keystone provides a +sha256 generator as default, which produces regeneratable public IDs. The +generator algorithm for public IDs is a balance between key size (i.e. the +length of the public ID), the probability of collision and, in some +circumstances, the security of the public ID. The maximum length of public ID +supported by Keystone is 64 characters, and the default generator (sha256) uses +this full capability. Since the public ID is what is exposed externally by +Keystone and potentially stored in external systems, some installations may +wish to make use of other generator algorithms that have a different trade-off +of attributes. A different generator can be installed by configuring the +following property: + +* ``generator`` - identity mapping generator. Defaults to + ``keystone.identity.generators.sha256.Generator`` + +.. WARNING:: + + Changing the generator may cause all existing public IDs to be become + invalid, so typically the generator selection should be considered + immutable for a given installation. + +Authentication Plugins +---------------------- + +.. NOTE:: + + This feature is only supported by Keystone for the Identity API v3 clients. + +Keystone supports authentication plugins and they are specified in the +``[auth]`` section of the configuration file. However, an authentication plugin +may also have its own section in the configuration file. It is up to the plugin +to register its own configuration options. + +* ``methods`` - comma-delimited list of authentication plugin names +* ``<plugin name>`` - specify the class which handles to authentication method, + in the same manner as one would specify a backend driver. + +Keystone provides three authentication methods by default. ``password`` handles +password authentication and ``token`` handles token authentication. +``external`` is used in conjunction with authentication performed by a +container web server that sets the ``REMOTE_USER`` environment variable. For +more details, refer to :doc:`External Authentication <external-auth>`. + +How to Implement an Authentication Plugin +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +All authentication plugins must extend the +``keystone.auth.core.AuthMethodHandler`` class and implement the +``authenticate()`` method. The ``authenticate()`` method expects the following +parameters. + +* ``context`` - Keystone's request context +* ``auth_payload`` - the content of the authentication for a given method +* ``auth_context`` - user authentication context, a dictionary shared by all + plugins. It contains ``method_names`` and ``extras`` by default. + ``method_names`` is a list and ``extras`` is a dictionary. + +If successful, the ``authenticate()`` method must provide a valid ``user_id`` +in ``auth_context`` and return ``None``. ``method_name`` is used to convey any +additional authentication methods in case authentication is for re-scoping. For +example, if the authentication is for re-scoping, a plugin must append the +previous method names into ``method_names``. Also, a plugin may add any +additional information into ``extras``. Anything in ``extras`` will be conveyed +in the token's ``extras`` field. + +If authentication requires multiple steps, the ``authenticate()`` method must +return the payload in the form of a dictionary for the next authentication +step. + +If authentication is unsuccessful, the ``authenticate()`` method must raise a +``keystone.exception.Unauthorized`` exception. + +Simply add the new plugin name to the ``methods`` list along with your plugin +class configuration in the ``[auth]`` sections of the configuration file to +deploy it. + +If the plugin requires additional configurations, it may register its own +section in the configuration file. + +Plugins are invoked in the order in which they are specified in the ``methods`` +attribute of the ``authentication`` request body. If multiple plugins are +invoked, all plugins must succeed in order to for the entire authentication to +be successful. Furthermore, all the plugins invoked must agree on the +``user_id`` in the ``auth_context``. + +The ``REMOTE_USER`` environment variable is only set from a containing +webserver. However, to ensure that a user must go through other authentication +mechanisms, even if this variable is set, remove ``external`` from the list of +plugins specified in ``methods``. This effectively disables external +authentication. For more details, refer to :doc:`ExternalAuthentication +<external-auth>`. + + +Token Persistence Driver +------------------------ + +Keystone supports customizable token persistence drivers. These can be +specified in the ``[token]`` section of the configuration file. Keystone +provides three non-test persistence backends. These can be set with the +``[token]\driver`` configuration option. + +The drivers Keystone provides are: + +* ``keystone.token.persistence.backends.memcache_pool.Token`` - The pooled + memcached token persistence engine. This backend supports the concept of + pooled memcache client object (allowing for the re-use of the client + objects). This backend has a number of extra tunable options in the + ``[memcache]`` section of the config. + +* ``keystone.token.persistence.backends.sql.Token`` - The SQL-based (default) + token persistence engine. + +* ``keystone.token.persistence.backends.memcache.Token`` - The memcached based + token persistence backend. This backend relies on ``dogpile.cache`` and + stores the token data in a set of memcached servers. The servers URLs are + specified in the ``[memcache]\servers`` configuration option in the Keystone + config. + + +.. WARNING:: + It is recommended you use the + ``keystone.token.persistence.backends.memcache_pool.Token`` backend instead + of ``keystone.token.persistence.backends.memcache.Token`` as the token + persistence driver if you are deploying Keystone under eventlet instead of + Apache + mod_wsgi. This recommendation is due to known issues with the use + of ``thread.local`` under eventlet that can allow the leaking of memcache + client objects and consumption of extra sockets. + + +Token Provider +-------------- + +Keystone supports customizable token provider and it is specified in the +``[token]`` section of the configuration file. Keystone provides both UUID and +PKI token providers. However, users may register their own token provider by +configuring the following property. + +* ``provider`` - token provider driver. Defaults to + ``keystone.token.providers.uuid.Provider`` + + +UUID, PKI, PKIZ, or Fernet? +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Each token format uses different technologies to achieve various performance, +scaling and architectural requirements. + +UUID tokens contain randomly generated UUID4 payloads that are issued and +validated by the identity service. They are encoded using their hex digest for +transport and are thus URL-friendly. They must be persisted by the identity +service in order to be later validated. Revoking them is simply a matter of +deleting them from the token persistence backend. + +Both PKI and PKIZ tokens contain JSON payloads that represent the entire token +validation response that would normally be retrieved from keystone. The payload +is then signed using `Cryptographic Message Syntax (CMS) +<http://en.wikipedia.org/wiki/Cryptographic_Message_Syntax>`_. The combination +of CMS and the exhaustive payload allows PKI and PKIZ tokens to be verified +offline using keystone's public signing key. The only reason for them to be +persisted by the identity service is to later build token revocation *lists* +(explicit lists of tokens that have been revoked), otherwise they are +theoretically ephemeral when supported by token revocation *events* (which +describe invalidated tokens rather than enumerate them). PKIZ tokens add zlib +compression after signing to achieve a smaller overall token size. To make them +URL-friendly, PKI tokens are base64 encoded and then arbitrarily manipulated to +replace unsafe characters with safe ones whereas PKIZ tokens use conventional +base64url encoding. Due to the size of the payload and the overhead incurred by +the CMS format, both PKI and PKIZ tokens may be too long to fit in either +headers or URLs if they contain extensive service catalogs or other additional +attributes. Some third-party applications such as web servers and clients may +need to be recompiled from source to customize the limitations that PKI and +PKIZ tokens would otherwise exceed). Both PKI and PKIZ tokens require signing +certificates which may be created using ``keystone-manage pki_setup`` for +demonstration purposes (this is not recommended for production deployments: use +certificates issued by an trusted CA instead). + +Fernet tokens contain a limited amount of identity and authorization data in a +`MessagePacked <http://msgpack.org/>`_ payload. The payload is then wrapped as +a `Fernet <https://github.com/fernet/spec>`_ message for transport, where +Fernet provides the required web safe characteristics for use in URLs and +headers. Fernet tokens require symmetric encryption keys which can be +established using ``keystone-manage fernet_setup`` and periodically rotated +using ``keystone-manage fernet_rotate``. + +.. WARNING:: + UUID, PKI, PKIZ, and Fernet tokens are all bearer tokens, meaning that they + must be protected from unnecessary disclosure to prevent unauthorized + access. + +Caching Layer +------------- + +Keystone supports a caching layer that is above the configurable subsystems +(e.g. ``token``, ``identity``, etc). Keystone uses the `dogpile.cache`_ library +which allows for flexible cache backends. The majority of the caching +configuration options are set in the ``[cache]`` section. However, each section +that has the capability to be cached usually has a ``caching`` boolean value +that will toggle caching for that specific section. The current default +behavior is that subsystem caching is enabled, but the global toggle is set to +disabled. + +``[cache]`` configuration section: +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* ``enabled`` - enables/disables caching across all of keystone +* ``debug_cache_backend`` - enables more in-depth logging from the cache + backend (get, set, delete, etc) +* ``backend`` - the caching backend module to use e.g. + ``dogpile.cache.memcached`` + + .. NOTE:: + A given ``backend`` must be registered with ``dogpile.cache`` before it + can be used. The default backend is the ``Keystone`` no-op backend + (``keystone.common.cache.noop``). If caching is desired a different + backend will need to be specified. Current functional backends are: + + * ``dogpile.cache.memcached`` - Memcached backend using the standard + `python-memcached`_ library + * ``dogpile.cache.pylibmc`` - Memcached backend using the `pylibmc`_ + library + * ``dogpile.cache.bmemcached`` - Memcached using `python-binary-memcached`_ + library. + * ``dogpile.cache.redis`` - `Redis`_ backend + * ``dogpile.cache.dbm`` - local DBM file backend + * ``dogpile.cache.memory`` - in-memory cache + * ``keystone.cache.mongo`` - MongoDB as caching backend + * ``keystone.cache.memcache_pool`` - An eventlet safe implementation of + ``dogpile.cache.memcached``. This implementation also provides client + connection re-use. + + .. WARNING:: + ``dogpile.cache.memory`` is not suitable for use outside of unit + testing as it does not cleanup its internal cache on cache + expiration, does not provide isolation to the cached data (values + in the store can be inadvertently changed without extra layers of + data protection added), and does not share cache between processes. + This means that caching and cache invalidation will not be + consistent or reliable when using ``Keystone`` and the + ``dogpile.cache.memory`` backend under any real workload. + + .. WARNING:: + Do not use ``dogpile.cache.memcached`` backend if you are deploying + Keystone under eventlet. There are known issues with the use of + ``thread.local`` under eventlet that can allow the leaking of + memcache client objects and consumption of extra sockets. + +* ``expiration_time`` - int, the default length of time to cache a specific + value. A value of ``0`` indicates to not cache anything. It is recommended + that the ``enabled`` option be used to disable cache instead of setting this + to ``0``. +* ``backend_argument`` - an argument passed to the backend when instantiated + ``backend_argument`` should be specified once per argument to be passed to + the backend and in the format of ``<argument name>:<argument value>``. e.g.: + ``backend_argument = host:localhost`` +* ``proxies`` - comma delimited list of `ProxyBackends`_ e.g. + ``my.example.Proxy, my.example.Proxy2`` + +Current Keystone systems that have caching capabilities: + * ``token`` + The token system has a separate ``cache_time`` configuration option, + that can be set to a value above or below the global + ``expiration_time`` default, allowing for different caching behavior + from the other systems in ``Keystone``. This option is set in the + ``[token]`` section of the configuration file. + + The Token Revocation List cache time is handled by the configuration + option ``revocation_cache_time`` in the ``[token]`` section. The + revocation list is refreshed whenever a token is revoked. It typically + sees significantly more requests than specific token retrievals or + token validation calls. + * ``resource`` + The resource system has a separate ``cache_time`` configuration option, + that can be set to a value above or below the global + ``expiration_time`` default, allowing for different caching behavior + from the other systems in ``Keystone``. This option is set in the + ``[resource]`` section of the configuration file. + + Currently ``resource`` has caching for ``project`` and ``domain`` + specific requests (primarily around the CRUD actions). The + ``list_projects`` and ``list_domains`` methods are not subject to + caching. + + .. WARNING:: + Be aware that if a read-only ``resource`` backend is in use, the + cache will not immediately reflect changes on the back end. Any + given change may take up to the ``cache_time`` (if set in the + ``[resource]`` section of the configuration) or the global + ``expiration_time`` (set in the ``[cache]`` section of the + configuration) before it is reflected. If this type of delay (when + using a read-only ``resource`` backend) is an issue, it is + recommended that caching be disabled on ``resource``. To disable + caching specifically on ``resource``, in the ``[resource]`` section + of the configuration set ``caching`` to ``False``. + * ``role`` + Currently ``role`` has caching for ``get_role``, but not for ``list_roles``. + The role system has a separate ``cache_time`` configuration option, + that can be set to a value above or below the global ``expiration_time`` + default, allowing for different caching behavior from the other systems in + ``Keystone``. This option is set in the ``[role]`` section of the + configuration file. + + .. WARNING:: + Be aware that if a read-only ``role`` backend is in use, the cache + will not immediately reflect changes on the back end. Any given change + may take up to the ``cache_time`` (if set in the ``[role]`` + section of the configuration) or the global ``expiration_time`` (set in + the ``[cache]`` section of the configuration) before it is reflected. + If this type of delay (when using a read-only ``role`` backend) is + an issue, it is recommended that caching be disabled on ``role``. + To disable caching specifically on ``role``, in the ``[role]`` + section of the configuration set ``caching`` to ``False``. + +For more information about the different backends (and configuration options): + * `dogpile.cache.backends.memory`_ + * `dogpile.cache.backends.memcached`_ + * `dogpile.cache.backends.redis`_ + * `dogpile.cache.backends.file`_ + * :py:mod:`keystone.common.cache.backends.mongo` + +.. _`dogpile.cache`: http://dogpilecache.readthedocs.org/en/latest/ +.. _`python-memcached`: http://www.tummy.com/software/python-memcached/ +.. _`pylibmc`: http://sendapatch.se/projects/pylibmc/index.html +.. _`python-binary-memcached`: https://github.com/jaysonsantos/python-binary-memcached +.. _`Redis`: http://redis.io/ +.. _`dogpile.cache.backends.memory`: http://dogpilecache.readthedocs.org/en/latest/api.html#memory-backend +.. _`dogpile.cache.backends.memcached`: http://dogpilecache.readthedocs.org/en/latest/api.html#memcached-backends +.. _`dogpile.cache.backends.redis`: http://dogpilecache.readthedocs.org/en/latest/api.html#redis-backends +.. _`dogpile.cache.backends.file`: http://dogpilecache.readthedocs.org/en/latest/api.html#file-backends +.. _`ProxyBackends`: http://dogpilecache.readthedocs.org/en/latest/api.html#proxy-backends +.. _`PyMongo API`: http://api.mongodb.org/python/current/api/pymongo/index.html + + +Certificates for PKI +-------------------- + +PKI stands for Public Key Infrastructure. Tokens are documents, +cryptographically signed using the X509 standard. In order to work correctly +token generation requires a public/private key pair. The public key must be +signed in an X509 certificate, and the certificate used to sign it must be +available as Certificate Authority (CA) certificate. These files can be either +externally generated or generated using the ``keystone-manage`` utility. + +The files used for signing and verifying certificates are set in the Keystone +configuration file. The private key should only be readable by the system user +that will run Keystone. The values that specify the certificates are under the +``[signing]`` section of the configuration file. The configuration values are: + +* ``certfile`` - Location of certificate used to verify tokens. Default is + ``/etc/keystone/ssl/certs/signing_cert.pem`` +* ``keyfile`` - Location of private key used to sign tokens. Default is + ``/etc/keystone/ssl/private/signing_key.pem`` +* ``ca_certs`` - Location of certificate for the authority that issued the + above certificate. Default is ``/etc/keystone/ssl/certs/ca.pem`` + +Signing Certificate Issued by External CA +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You may use a signing certificate issued by an external CA instead of generated +by ``keystone-manage``. However, certificate issued by external CA must satisfy +the following conditions: + +* all certificate and key files must be in Privacy Enhanced Mail (PEM) format +* private key files must not be protected by a password + +The basic workflow for using a signing certificate issued by an external CA +involves: + +1. `Request Signing Certificate from External CA`_ +2. Convert certificate and private key to PEM if needed +3. `Install External Signing Certificate`_ + + +Request Signing Certificate from External CA +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +One way to request a signing certificate from an external CA is to first +generate a PKCS #10 Certificate Request Syntax (CRS) using OpenSSL CLI. + +First create a certificate request configuration file (e.g. ``cert_req.conf``): + +.. code-block:: ini + + [ req ] + default_bits = 2048 + default_keyfile = keystonekey.pem + default_md = default + + prompt = no + distinguished_name = distinguished_name + + [ distinguished_name ] + countryName = US + stateOrProvinceName = CA + localityName = Sunnyvale + organizationName = OpenStack + organizationalUnitName = Keystone + commonName = Keystone Signing + emailAddress = keystone@openstack.org + +Then generate a CRS with OpenSSL CLI. **Do not encrypt the generated private +key. The -nodes option must be used.** + +For example: + +.. code-block:: bash + + $ openssl req -newkey rsa:2048 -keyout signing_key.pem -keyform PEM -out signing_cert_req.pem -outform PEM -config cert_req.conf -nodes + + +If everything is successfully, you should end up with ``signing_cert_req.pem`` +and ``signing_key.pem``. Send ``signing_cert_req.pem`` to your CA to request a +token signing certificate and make sure to ask the certificate to be in PEM +format. Also, make sure your trusted CA certificate chain is also in PEM +format. + + +Install External Signing Certificate +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Assuming you have the following already: + +* ``signing_cert.pem`` - (Keystone token) signing certificate in PEM format +* ``signing_key.pem`` - corresponding (non-encrypted) private key in PEM format +* ``cacert.pem`` - trust CA certificate chain in PEM format + +Copy the above to your certificate directory. For example: + +.. code-block:: bash + + $ mkdir -p /etc/keystone/ssl/certs + $ cp signing_cert.pem /etc/keystone/ssl/certs/ + $ cp signing_key.pem /etc/keystone/ssl/certs/ + $ cp cacert.pem /etc/keystone/ssl/certs/ + $ chmod -R 700 /etc/keystone/ssl/certs + +**Make sure the certificate directory is root-protected.** + +If your certificate directory path is different from the default +``/etc/keystone/ssl/certs``, make sure it is reflected in the ``[signing]`` +section of the configuration file. + + +Generating a Signing Certificate using pki_setup +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``keystone-manage pki_setup`` is a development tool. We recommend that you do +not use ``keystone-manage pki_setup`` in a production environment. In +production, an external CA should be used instead. This is because the CA +secret key should generally be kept apart from the token signing secret keys so +that a compromise of a node does not lead to an attacker being able to generate +valid signed Keystone tokens. This is a low probability attack vector, as +compromise of a Keystone service machine's filesystem security almost certainly +means the attacker will be able to gain direct access to the token backend. + +When using the ``keystone-manage pki_setup`` to generate the certificates, the +following configuration options in the ``[signing]`` section are used: + +* ``ca_key`` - Default is ``/etc/keystone/ssl/private/cakey.pem`` +* ``key_size`` - Default is ``2048`` +* ``valid_days`` - Default is ``3650`` + +If ``keystone-manage pki_setup`` is not used then these options don't need to +be set. + + +Encryption Keys for Fernet +-------------------------- + +``keystone-manage fernet_setup`` will attempt to create a key repository as +configured in the ``[fernet_tokens]`` section of ``keystone.conf`` and +bootstrap it with encryption keys. + +A single 256-bit key is actually composed of two smaller keys: a 128-bit key +used for SHA256 HMAC signing and a 128-bit key used for AES encryption. See the +`Fernet token <https://github.com/fernet/spec>`_ specification for more detail. + +``keystone-manage fernet_rotate`` will rotate encryption keys through the +following states: + +* **Staged key**: In a key rotation, a new key is introduced into the rotation + in this state. Only one key is considered to be the *staged* key at any given + time. This key will become the *primary* during the *next* key rotation. This + key is only used to validate tokens and serves to avoid race conditions in + multi-node deployments (all nodes should recognize all *primary* keys in the + deployment at all times). In a multi-node Keystone deployment this would + allow for the *staged* key to be replicated to all Keystone nodes before + being promoted to *primary* on a single node. This prevents the case where a + *primary* key is created on one Keystone node and tokens encryted/signed with + that new *primary* are rejected on another Keystone node because the new + *primary* doesn't exist there yet. + +* **Primary key**: In a key rotation, the old *staged* key is promoted to be + the *primary*. Only one key is considered to be the *primary* key at any + given time. This is the key used to generate new tokens. This key is also + used to validate previously generated tokens. + +* **Secondary keys**: In a key rotation, the old *primary* key is demoted to be + a *secondary* key. *Secondary* keys are only used to validate previously + generated tokens. You can maintain any number of *secondary* keys, up to + ``[fernet_tokens] max_active_keys`` (where "active" refers to the sum of all + recognized keys in any state: *staged*, *primary* or *secondary*). When + ``max_active_keys`` is exceeded during a key rotation, the oldest keys are + discarded. + +When a new primary key is created, all new tokens will be encrypted using the +new primary key. The old primary key is demoted to a secondary key, which can +still be used for validating tokens. Excess secondary keys (beyond +``[fernet_tokens] max_active_keys``) are revoked. Revoked keys are permanently +deleted. + +Rotating keys too frequently, or with ``[fernet_tokens] max_active_keys`` set +too low, will cause tokens to become invalid prior to their expiration. + +Service Catalog +--------------- + +Keystone provides two configuration options for your service catalog. + +SQL-based Service Catalog (``sql.Catalog``) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A dynamic database-backed driver fully supporting persistent configuration. + +``keystone.conf`` example: + +.. code-block:: ini + + [catalog] + driver = keystone.catalog.backends.sql.Catalog + +.. NOTE:: + + A `template_file` does not need to be defined for the sql.Catalog driver. + +To build your service catalog using this driver, see the built-in help: + +.. code-block:: bash + + $ openstack --help + $ openstack help service create + $ openstack help endpoint create + +You can also refer to `an example in Keystone (tools/sample_data.sh) +<https://github.com/openstack/keystone/blob/master/tools/sample_data.sh>`_. + +File-based Service Catalog (``templated.Catalog``) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The templated catalog is an in-memory backend initialized from a read-only +``template_file``. Choose this option only if you know that your service +catalog will not change very much over time. + +.. NOTE:: + + Attempting to change your service catalog against this driver will result + in ``HTTP 501 Not Implemented`` errors. This is the expected behavior. If + you want to use these commands, you must instead use the SQL-based Service + Catalog driver. + +``keystone.conf`` example: + +.. code-block:: ini + + [catalog] + driver = keystone.catalog.backends.templated.Catalog + template_file = /opt/stack/keystone/etc/default_catalog.templates + +The value of ``template_file`` is expected to be an absolute path to your +service catalog configuration. An example ``template_file`` is included in +Keystone, however you should create your own to reflect your deployment. + +Another such example is `available in devstack +(files/default_catalog.templates) +<https://github.com/openstack-dev/devstack/blob/master/files/default_catalog.templates>`_. + +Logging +------- + +Logging is configured externally to the rest of Keystone. Configure the path to +your logging configuration file using the ``[DEFAULT] log_config`` option of +``keystone.conf``. If you wish to route all your logging through syslog, set +the ``[DEFAULT] use_syslog`` option. + +A sample ``log_config`` file is included with the project at +``etc/logging.conf.sample``. Like other OpenStack projects, Keystone uses the +`Python logging module`, which includes extensive configuration options for +choosing the output levels and formats. + +.. _Paste: http://pythonpaste.org/ +.. _`Python logging module`: http://docs.python.org/library/logging.html + +SSL +--- + +Keystone may be configured to support SSL and 2-way SSL out-of-the-box. The +X509 certificates used by Keystone can be generated by ``keystone-manage`` +or obtained externally and configured for use with Keystone as described in +this section. Here is the description of each of them and their purpose: + +.. WARNING:: + + The SSL configuration options available to the eventlet server + (``keystone-all``) described here are severely limited. A secure + deployment should have Keystone running in a web server (such as Apache + HTTPd), or behind an SSL terminator. When running Keystone in a web server + or behind an SSL terminator the options described in this section have no + effect and SSL is configured in the web server or SSL terminator. + +Types of certificates +^^^^^^^^^^^^^^^^^^^^^ + +* ``cacert.pem``: Certificate Authority chain to validate against. +* ``ssl_cert.pem``: Public certificate for Keystone server. +* ``middleware.pem``: Public and private certificate for Keystone + middleware/client. +* ``cakey.pem``: Private key for the CA. +* ``ssl_key.pem``: Private key for the Keystone server. + +Note that you may choose whatever names you want for these certificates, or +combine the public/private keys in the same file if you wish. These +certificates are just provided as an example. + +Configuration +^^^^^^^^^^^^^ + +To enable SSL modify the ``etc/keystone.conf`` file under the ``[ssl]`` and +``[eventlet_server_ssl]`` sections. The following is an SSL configuration +example using the included sample certificates: + +.. code-block:: ini + + [eventlet_server_ssl] + enable = True + certfile = <path to keystone.pem> + keyfile = <path to keystonekey.pem> + ca_certs = <path to ca.pem> + cert_required = False + + [ssl] + ca_key = <path to cakey.pem> + key_size = 1024 + valid_days=3650 + cert_subject=/C=US/ST=Unset/L=Unset/O=Unset/CN=localhost + +* ``enable``: True enables SSL. Defaults to False. +* ``certfile``: Path to Keystone public certificate file. +* ``keyfile``: Path to Keystone private certificate file. If the private key is + included in the certfile, the keyfile may be omitted. +* ``ca_certs``: Path to CA trust chain. +* ``cert_required``: Requires client certificate. Defaults to False. + +When generating SSL certificates the following values are read + +* ``key_size``: Key size to create. Defaults to 1024. +* ``valid_days``: How long the certificate is valid for. Defaults to 3650 + (10 years). +* ``ca_key``: The private key for the CA. Defaults to + ``/etc/keystone/ssl/certs/cakey.pem``. +* ``cert_subject``: The subject to set in the certificate. Defaults to + ``/C=US/ST=Unset/L=Unset/O=Unset/CN=localhost``. When setting the subject it + is important to set CN to be the address of the server so client validation + will succeed. This generally means having the subject be at least + ``/CN=<keystone ip>`` + +Generating SSL certificates +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Certificates for encrypted HTTP communication can be generated by: + +.. code-block:: bash + + $ keystone-manage ssl_setup + +This will create a private key, a public key and a certificate that will be +used to encrypt communications with keystone. In the event that a Certificate +Authority is not given a testing one will be created. + +It is likely in a production environment that these certificates will be +created and provided externally. Note that ``ssl_setup`` is a development tool +and is only recommended for developments environment. We do not recommend using +``ssl_setup`` for production environments. + + +User CRUD extension for the V2.0 API +------------------------------------ + +.. NOTE:: + + The core V3 API includes user operations so no extension needs to be + enabled for the V3 API. + +For the V2.0 API, Keystone provides a user CRUD filter that can be added to the +public_api pipeline. This user crud filter allows users to use a HTTP PATCH to +change their own password. To enable this extension you should define a +user_crud_extension filter, insert it after the ``*_body`` middleware and +before the ``public_service`` app in the public_api WSGI pipeline in +``keystone-paste.ini`` e.g.: + +.. code-block:: ini + + [filter:user_crud_extension] + paste.filter_factory = keystone.contrib.user_crud:CrudExtension.factory + + [pipeline:public_api] + pipeline = url_normalize token_auth admin_token_auth json_body debug ec2_extension user_crud_extension public_service + +Each user can then change their own password with a HTTP PATCH : + +.. code-block:: bash + + $ curl -X PATCH http://localhost:5000/v2.0/OS-KSCRUD/users/<userid> -H "Content-type: application/json" \ + -H "X_Auth_Token: <authtokenid>" -d '{"user": {"password": "ABCD", "original_password": "DCBA"}}' + +In addition to changing their password all of the user's current tokens will be +revoked. + + +Inherited Role Assignment Extension +----------------------------------- + +Keystone provides an optional extension that adds the capability to assign +roles on a project or domain that, rather than affect the project or domain +itself, are instead inherited to the project subtree or to all projects owned +by that domain. This extension is disabled by default, but can be enabled by +including the following in ``keystone.conf``: + +.. code-block:: ini + + [os_inherit] + enabled = True + + +Token Binding +------------- + +Token binding refers to the practice of embedding information from external +authentication providers (like a company's Kerberos server) inside the token +such that a client may enforce that the token only be used in conjunction with +that specified authentication. This is an additional security mechanism as it +means that if a token is stolen it will not be usable without also providing +the external authentication. + +To activate token binding you must specify the types of authentication that +token binding should be used for in ``keystone.conf`` e.g.: + +.. code-block:: ini + + [token] + bind = kerberos + +Currently only ``kerberos`` is supported. + +To enforce checking of token binding the ``enforce_token_bind`` parameter +should be set to one of the following modes: + +* ``disabled`` disable token bind checking +* ``permissive`` enable bind checking, if a token is bound to a mechanism that + is unknown to the server then ignore it. This is the default. +* ``strict`` enable bind checking, if a token is bound to a mechanism that is + unknown to the server then this token should be rejected. +* ``required`` enable bind checking and require that at least 1 bind mechanism + is used for tokens. +* named enable bind checking and require that the specified authentication + mechanism is used. e.g.: + + .. code-block:: ini + + [token] + enforce_token_bind = kerberos + + *Do not* set ``enforce_token_bind = named`` as there is not an authentication + mechanism called ``named``. + +Limiting the number of entities returned in a collection +-------------------------------------------------------- + +Keystone provides a method of setting a limit to the number of entities +returned in a collection, which is useful to prevent overly long response times +for list queries that have not specified a sufficiently narrow filter. This +limit can be set globally by setting ``list_limit`` in the default section of +``keystone.conf``, with no limit set by default. Individual driver sections may +override this global value with a specific limit, for example: + +.. code-block:: ini + + [resource] + list_limit = 100 + +If a response to ``list_{entity}`` call has been truncated, then the response +status code will still be 200 (OK), but the ``truncated`` attribute in the +collection will be set to ``true``. + +Sample Configuration Files +-------------------------- + +The ``etc/`` folder distributed with Keystone contains example configuration +files for each Server application. + +* ``etc/keystone.conf.sample`` +* ``etc/keystone-paste.ini`` +* ``etc/logging.conf.sample`` +* ``etc/default_catalog.templates`` + +.. _`API protection with RBAC`: + +Keystone API protection with Role Based Access Control (RBAC) +============================================================= + +Like most OpenStack projects, Keystone supports the protection of its APIs by +defining policy rules based on an RBAC approach. These are stored in a JSON +policy file, the name and location of which is set in the main Keystone +configuration file. + +Each Keystone v3 API has a line in the policy file which dictates what level of +protection is applied to it, where each line is of the form:: + + <api name>: <rule statement> or <match statement> + +where: + +``<rule statement>`` can contain ``<rule statement>`` or ``<match statement>`` + +``<match statement>`` is a set of identifiers that must match between the token +provided by the caller of the API and the parameters or target entities of the +API call in question. For example: + +.. code-block:: javascript + + "identity:create_user": "role:admin and domain_id:%(user.domain_id)s" + +Indicates that to create a user you must have the admin role in your token and +in addition the domain_id in your token (which implies this must be a domain +scoped token) must match the domain_id in the user object you are trying to +create. In other words, you must have the admin role on the domain in which you +are creating the user, and the token you are using must be scoped to that +domain. + +Each component of a match statement is of the form:: + + <attribute from token>:<constant> or <attribute related to API call> + +The following attributes are available + +* Attributes from token: user_id, the domain_id or project_id depending on + the scope, and the list of roles you have within that scope + +* Attributes related to API call: Any parameters that are passed into the API + call are available, along with any filters specified in the query string. + Attributes of objects passed can be referenced using an object.attribute + syntax (e.g. user.domain_id). The target objects of an API are also available + using a target.object.attribute syntax. For instance: + + .. code-block:: javascript + + "identity:delete_user": "role:admin and domain_id:%(target.user.domain_id)s" + + would ensure that the user object that is being deleted is in the same + domain as the token provided. + +Every target object has an `id` and a `name` available as `target.<object>.id` +and `target.<object>.name`. Other attributes are retrieved from the database +and vary between object types. Moreover, some database fields are filtered out +(e.g. user passwords). + +List of object attributes: + +* role: + * target.role.id + * target.role.name + +* user: + * target.user.default_project_id + * target.user.description + * target.user.domain_id + * target.user.enabled + * target.user.id + * target.user.name + +* group: + * target.group.description + * target.group.domain_id + * target.group.id + * target.group.name + +* domain: + * target.domain.enabled + * target.domain.id + * target.domain.name + +* project: + * target.project.description + * target.project.domain_id + * target.project.enabled + * target.project.id + * target.project.name + +The default policy.json file supplied provides a somewhat basic example of API +protection, and does not assume any particular use of domains. For multi-domain +configuration installations where, for example, a cloud provider wishes to +allow administration of the contents of a domain to be delegated, it is +recommended that the supplied policy.v3cloudsample.json is used as a basis for +creating a suitable production policy file. This example policy file also shows +the use of an admin_domain to allow a cloud provider to enable cloud +administrators to have wider access across the APIs. + +A clean installation would need to perhaps start with the standard policy file, +to allow creation of the admin_domain with the first users within it. The +domain_id of the admin domain would then be obtained and could be pasted into a +modified version of policy.v3cloudsample.json which could then be enabled as +the main policy file. + +.. _`prepare your deployment`: + +Preparing your deployment +========================= + +Step 1: Configure keystone.conf +------------------------------- + +Ensure that your ``keystone.conf`` is configured to use a SQL driver: + +.. code-block:: ini + + [identity] + driver = keystone.identity.backends.sql.Identity + +You may also want to configure your ``[database]`` settings to better reflect +your environment: + +.. code-block:: ini + + [database] + connection = sqlite:///keystone.db + idle_timeout = 200 + +.. NOTE:: + + It is important that the database that you specify be different from the + one containing your existing install. + +Step 2: Sync your new, empty database +------------------------------------- + +You should now be ready to initialize your new database without error, using: + +.. code-block:: bash + + $ keystone-manage db_sync + +To test this, you should now be able to start ``keystone-all`` and use the +OpenStack Client to list your projects (which should successfully return an +empty list from your new database): + +.. code-block:: bash + + $ openstack --os-token ADMIN --os-url http://127.0.0.1:35357/v2.0/ project list + +.. NOTE:: + + We're providing the default OS_TOKEN and OS_URL values from + ``keystone.conf`` to connect to the Keystone service. If you changed those + values, or deployed Keystone to a different endpoint, you will need to + change the provided command accordingly. + +Initializing Keystone +===================== + +``keystone-manage`` is designed to execute commands that cannot be administered +through the normal REST API. At the moment, the following calls are supported: + +* ``db_sync``: Sync the database. +* ``db_version``: Print the current migration version of the database. +* ``mapping_purge``: Purge the identity mapping table. +* ``pki_setup``: Initialize the certificates used to sign tokens. +* ``saml_idp_metadata``: Generate identity provider metadata. +* ``ssl_setup``: Generate certificates for SSL. +* ``token_flush``: Purge expired tokens + +Invoking ``keystone-manage`` by itself will give you additional usage +information. + +The private key used for token signing can only be read by its owner. This +prevents unauthorized users from spuriously signing tokens. +``keystone-manage pki_setup`` Should be run as the same system user that will +be running the Keystone service to ensure proper ownership for the private key +file and the associated certificates. + +Adding Users, Projects, and Roles via Command Line Interfaces +============================================================= + +Keystone APIs are protected by the rules in the policy file. The default policy +rules require admin credentials to administer ``users``, ``projects``, and +``roles``. See section +`Keystone API protection with Role Based Access Control (RBAC)`_ for more +details on policy files. + +The Keystone command line interface packaged in `python-keystoneclient`_ only +supports the Identity v2.0 API. The OpenStack common command line interface +packaged in `python-openstackclient`_ supports both v2.0 and v3 APIs. + +With both command line interfaces there are two ways to configure the client to +use admin credentials, using either an existing token or password credentials. + +.. NOTE:: + + As of the Juno release, it is recommended to use + ``python-openstackclient``, as it supports both v2.0 and v3 APIs. For the + purpose of backwards compatibility, the CLI packaged in + ``python-keystoneclient`` is not being removed. + +.. _`python-openstackclient`: http://docs.openstack.org/developer/python-openstackclient/ +.. _`python-keystoneclient`: http://docs.openstack.org/developer/python-keystoneclient/ + +Authenticating with a Token +--------------------------- + +.. NOTE:: + + If your Keystone deployment is brand new, you will need to use this + authentication method, along with your ``[DEFAULT] admin_token``. + +To authenticate with Keystone using a token and ``python-openstackclient``, set +the following flags. + +* ``--os-url OS_URL``: Keystone endpoint the user communicates with +* ``--os-token OS_TOKEN``: User's service token + +To administer a Keystone endpoint, your token should be either belong to a user +with the ``admin`` role, or, if you haven't created one yet, should be equal to +the value defined by ``[DEFAULT] admin_token`` in your ``keystone.conf``. + +You can also set these variables in your environment so that they do not need +to be passed as arguments each time: + +.. code-block:: bash + + $ export OS_URL=http://localhost:35357/v2.0 + $ export OS_TOKEN=ADMIN + +Instead of ``python-openstackclient``, if using ``python-keystoneclient``, set +the following: + +* ``--os-endpoint OS_SERVICE_ENDPOINT``: equivalent to ``--os-url OS_URL`` +* ``--os-service-token OS_SERVICE_TOKEN``: equivalent to + ``--os-token OS_TOKEN`` + + +Authenticating with a Password +------------------------------ + +To authenticate with Keystone using a password and ``python-openstackclient``, +set the following flags, note that the following user referenced below should +be granted the ``admin`` role. + +* ``--os-username OS_USERNAME``: Name of your user +* ``--os-password OS_PASSWORD``: Password for your user +* ``--os-project-name OS_PROJECT_NAME``: Name of your project +* ``--os-auth-url OS_AUTH_URL``: URL of the Keystone authentication server + +You can also set these variables in your environment so that they do not need +to be passed as arguments each time: + +.. code-block:: bash + + $ export OS_USERNAME=my_username + $ export OS_PASSWORD=my_password + $ export OS_PROJECT_NAME=my_project + $ export OS_AUTH_URL=http://localhost:35357/v2.0 + +If using ``python-keystoneclient``, set the following instead: + +* ``--os-tenant-name OS_TENANT_NAME``: equivalent to + ``--os-project-name OS_PROJECT_NAME`` + + +Example usage +------------- + +``python-openstackclient`` is set up to expect commands in the general form of: + +.. code-block:: bash + + $ openstack [<global-options>] <object-1> <action> [<object-2>] [<command-arguments>] + +For example, the commands ``user list`` and ``project create`` can be invoked +as follows: + +.. code-block:: bash + + # Using token authentication, with environment variables + $ export OS_URL=http://127.0.0.1:35357/v2.0/ + $ export OS_TOKEN=secrete_token + $ openstack user list + $ openstack project create demo + + # Using token authentication, with flags + $ openstack --os-token=secrete --os-url=http://127.0.0.1:35357/v2.0/ user list + $ openstack --os-token=secrete --os-url=http://127.0.0.1:35357/v2.0/ project create demo + + # Using password authentication, with environment variables + $ export OS_USERNAME=admin + $ export OS_PASSWORD=secrete + $ export OS_PROJECT_NAME=admin + $ export OS_AUTH_URL=http://localhost:35357/v2.0 + $ openstack user list + $ openstack project create demo + + # Using password authentication, with flags + $ openstack --os-username=admin --os-password=secrete --os-project-name=admin --os-auth-url=http://localhost:35357/v2.0 user list + $ openstack --os-username=admin --os-password=secrete --os-project-name=admin --os-auth-url=http://localhost:35357/v2.0 project create demo + +For additional examples using ``python-keystoneclient`` refer to +`python-keystoneclient examples`_, likewise, for additional examples using +``python-openstackclient``, refer to `python-openstackclient examples`_. + +.. _`python-keystoneclient examples`: cli_examples.html#using-python-keystoneclient-v2-0 +.. _`python-openstackclient examples`: cli_examples.html#using-python-openstackclient-v3 + + +Removing Expired Tokens +======================= + +In the SQL backend expired tokens are not automatically removed. These tokens +can be removed with: + +.. code-block:: bash + + $ keystone-manage token_flush + +The memcache backend automatically discards expired tokens and so flushing is +unnecessary and if attempted will fail with a NotImplemented error. + + +Configuring the LDAP Identity Provider +====================================== + +As an alternative to the SQL Database backing store, Keystone can use a +directory server to provide the Identity service. An example Schema for +OpenStack would look like this:: + + dn: dc=openstack,dc=org + dc: openstack + objectClass: dcObject + objectClass: organizationalUnit + ou: openstack + + dn: ou=Projects,dc=openstack,dc=org + objectClass: top + objectClass: organizationalUnit + ou: groups + + dn: ou=Users,dc=openstack,dc=org + objectClass: top + objectClass: organizationalUnit + ou: users + + dn: ou=Roles,dc=openstack,dc=org + objectClass: top + objectClass: organizationalUnit + ou: roles + +The corresponding entries in the Keystone configuration file are: + +.. code-block:: ini + + [ldap] + url = ldap://localhost + user = dc=Manager,dc=openstack,dc=org + password = badpassword + suffix = dc=openstack,dc=org + use_dumb_member = False + allow_subtree_delete = False + + user_tree_dn = ou=Users,dc=openstack,dc=org + user_objectclass = inetOrgPerson + + project_tree_dn = ou=Projects,dc=openstack,dc=org + project_objectclass = groupOfNames + + role_tree_dn = ou=Roles,dc=openstack,dc=org + role_objectclass = organizationalRole + +The default object classes and attributes are intentionally simplistic. They +reflect the common standard objects according to the LDAP RFCs. However, in a +live deployment, the correct attributes can be overridden to support a +preexisting, more complex schema. For example, in the user object, the +objectClass posixAccount from RFC2307 is very common. If this is the underlying +objectclass, then the *uid* field should probably be *uidNumber* and *username* +field either *uid* or *cn*. To change these two fields, the corresponding +entries in the Keystone configuration file are: + +.. code-block:: ini + + [ldap] + user_id_attribute = uidNumber + user_name_attribute = cn + + +There is a set of allowed actions per object type that you can modify depending +on your specific deployment. For example, the users are managed by another tool +and you have only read access, in such case the configuration is: + +.. code-block:: ini + + [ldap] + user_allow_create = False + user_allow_update = False + user_allow_delete = False + + project_allow_create = True + project_allow_update = True + project_allow_delete = True + + role_allow_create = True + role_allow_update = True + role_allow_delete = True + +There are some configuration options for filtering users, tenants and roles, if +the backend is providing too much output, in such case the configuration will +look like: + +.. code-block:: ini + + [ldap] + user_filter = (memberof=CN=openstack-users,OU=workgroups,DC=openstack,DC=org) + project_filter = + role_filter = + +In case that the directory server does not have an attribute enabled of type +boolean for the user, there is several configuration parameters that can be +used to extract the value from an integer attribute like in Active Directory: + +.. code-block:: ini + + [ldap] + user_enabled_attribute = userAccountControl + user_enabled_mask = 2 + user_enabled_default = 512 + +In this case the attribute is an integer and the enabled attribute is listed in +bit 1, so the if the mask configured *user_enabled_mask* is different from 0, +it gets the value from the field *user_enabled_attribute* and it makes an ADD +operation with the value indicated on *user_enabled_mask* and if the value +matches the mask then the account is disabled. + +It also saves the value without mask to the user identity in the attribute +*enabled_nomask*. This is needed in order to set it back in case that we need +to change it to enable/disable a user because it contains more information than +the status like password expiration. Last setting *user_enabled_mask* is needed +in order to create a default value on the integer attribute (512 = NORMAL +ACCOUNT on AD) + +In case of Active Directory the classes and attributes could not match the +specified classes in the LDAP module so you can configure them like: + +.. code-block:: ini + + [ldap] + user_objectclass = person + user_id_attribute = cn + user_name_attribute = cn + user_mail_attribute = mail + user_enabled_attribute = userAccountControl + user_enabled_mask = 2 + user_enabled_default = 512 + user_attribute_ignore = tenant_id,tenants + project_objectclass = groupOfNames + project_id_attribute = cn + project_member_attribute = member + project_name_attribute = ou + project_desc_attribute = description + project_enabled_attribute = extensionName + project_attribute_ignore = + role_objectclass = organizationalRole + role_id_attribute = cn + role_name_attribute = ou + role_member_attribute = roleOccupant + role_attribute_ignore = + +Debugging LDAP +-------------- + +For additional information on LDAP connections, performance (such as slow +response time), or field mappings, setting ``debug_level`` in the [ldap] +section is used to enable debugging: + +.. code-block:: ini + + debug_level = 4095 + +This setting in turn sets OPT_DEBUG_LEVEL in the underlying python library. +This field is a bit mask (integer), and the possible flags are documented in +the OpenLDAP manpages. Commonly used values include 255 and 4095, with 4095 +being more verbose. + +.. WARNING:: + Enabling ``debug_level`` will negatively impact performance. + +Enabled Emulation +----------------- + +Some directory servers do not provide any enabled attribute. For these servers, +the ``user_enabled_emulation`` and ``project_enabled_emulation`` attributes +have been created. They are enabled by setting their respective flags to True. +Then the attributes ``user_enabled_emulation_dn`` and +``project_enabled_emulation_dn`` may be set to specify how the enabled users +and projects (tenants) are selected. These attributes work by using a +``groupOfNames`` and adding whichever users or projects (tenants) that you want +enabled to the respective group. For example, this will mark any user who is a +member of ``enabled_users`` as enabled: + +.. code-block:: ini + + [ldap] + user_enabled_emulation = True + user_enabled_emulation_dn = cn=enabled_users,cn=groups,dc=openstack,dc=org + +The default values for user and project (tenant) enabled emulation DN is +``cn=enabled_users,$user_tree_dn`` and ``cn=enabled_tenants,$project_tree_dn`` +respectively. + +Secure Connection +----------------- + +If you are using a directory server to provide the Identity service, it is +strongly recommended that you utilize a secure connection from Keystone to the +directory server. In addition to supporting LDAP, Keystone also provides +Transport Layer Security (TLS) support. There are some basic configuration +options for enabling TLS, identifying a single file or directory that contains +certificates for all the Certificate Authorities that the Keystone LDAP client +will recognize, and declaring what checks the client should perform on server +certificates. This functionality can easily be configured as follows: + +.. code-block:: ini + + [ldap] + use_tls = True + tls_cacertfile = /etc/keystone/ssl/certs/cacert.pem + tls_cacertdir = /etc/keystone/ssl/certs/ + tls_req_cert = demand + +A few points worth mentioning regarding the above options. If both +tls_cacertfile and tls_cacertdir are set then tls_cacertfile will be used and +tls_cacertdir is ignored. Furthermore, valid options for tls_req_cert are +demand, never, and allow. These correspond to the standard options permitted by +the TLS_REQCERT TLS option. + +Read Only LDAP +-------------- + +Many environments typically have user and group information in directories that +are accessible by LDAP. This information is for read-only use in a wide array +of applications. Prior to the Havana release, we could not deploy Keystone with +read-only directories as backends because Keystone also needed to store +information such as projects, roles, domains and role assignments into the +directories in conjunction with reading user and group information. + +Keystone now provides an option whereby these read-only directories can be +easily integrated as it now enables its identity entities (which comprises +users, groups, and group memberships) to be served out of directories while +resource (which comprises projects and domains), assignment and role +entities are to be served from different Keystone backends (i.e. SQL). To +enable this option, you must have the following ``keystone.conf`` options set: + +.. code-block:: ini + + [identity] + driver = keystone.identity.backends.ldap.Identity + + [resource] + driver = keystone.resource.backends.sql.Resource + + [assignment] + driver = keystone.assignment.backends.sql.Assignment + + [role] + driver = keystone.assignment.role_backends.sql.Role + +With the above configuration, Keystone will only lookup identity related +information such users, groups, and group membership from the directory, while +resources, roles and assignment related information will be provided by the SQL +backend. Also note that if there is an LDAP Identity, and no resource, +assignment or role backend is specified, they will default to LDAP. Although +this may seem counterintuitive, it is provided for backwards compatibility. +Nonetheless, the explicit option will always override the implicit option, so +specifying the options as shown above will always be correct. Finally, it is +also worth noting that whether or not the LDAP accessible directory is to be +considered read only is still configured as described in a previous section +above by setting values such as the following in the ``[ldap]`` configuration +section: + +.. code-block:: ini + + [ldap] + user_allow_create = False + user_allow_update = False + user_allow_delete = False + +.. NOTE:: + + While having identity related infomration backed by LDAP while other + information is backed by SQL is a supported configuration, as shown above; + the opposite is not true. If either resource or assignment drivers are + configured for LDAP, then Identity must also be configured for LDAP. + +Connection Pooling +------------------ + +Various LDAP backends in Keystone use a common LDAP module to interact with +LDAP data. By default, a new connection is established for LDAP operations. +This can become highly expensive when TLS support is enabled which is a likely +configuraton in enterprise setup. Re-using of connectors from a connection pool +drastically reduces overhead of initiating a new connection for every LDAP +operation. + +Keystone now provides connection pool support via configuration. This change +will keep LDAP connectors alive and re-use for subsequent LDAP operations. A +connection lifespan is going to be configurable with other pooling specific +attributes. The change is made in LDAP handler layer logic which is primarily +responsible for LDAP connection and shared common operations. + +In LDAP identity driver, Keystone authenticates end user by LDAP bind with user +DN and provided password. These kind of auth binds can fill up the pool pretty +quickly so a separate pool is provided for those end user auth bind calls. If a +deployment does not want to use pool for those binds, then it can disable +pooling selectively by ``use_auth_pool`` as false. If a deployment wants to use +pool for those auth binds, then ``use_auth_pool`` needs to be true. For auth +pool, a different pool size (``auth_pool_size``) and connection lifetime +(``auth_pool_connection_lifetime``) can be specified. With enabled auth pool, +its connection lifetime should be kept short so that pool frequently re-binds +the connection with provided creds and works reliably in end user password +change case. When ``use_pool`` is false (disabled), then auth pool +configuration is also not used. + +Connection pool configuration is added in ``[ldap]`` configuration section: + +.. code-block:: ini + + [ldap] + # Enable LDAP connection pooling. (boolean value) + use_pool=false + + # Connection pool size. (integer value) + pool_size=10 + + # Maximum count of reconnect trials. (integer value) + pool_retry_max=3 + + # Time span in seconds to wait between two reconnect trials. + # (floating point value) + pool_retry_delay=0.1 + + # Connector timeout in seconds. Value -1 indicates indefinite wait for + # response. (integer value) + pool_connection_timeout=-1 + + # Connection lifetime in seconds. (integer value) + pool_connection_lifetime=600 + + # Enable LDAP connection pooling for end user authentication. If use_pool + # is disabled, then this setting is meaningless and is not used at all. + # (boolean value) + use_auth_pool=false + + # End user auth connection pool size. (integer value) + auth_pool_size=100 + + # End user auth connection lifetime in seconds. (integer value) + auth_pool_connection_lifetime=60 + diff --git a/keystone-moon/doc/source/configure_federation.rst b/keystone-moon/doc/source/configure_federation.rst new file mode 100644 index 00000000..2da5f822 --- /dev/null +++ b/keystone-moon/doc/source/configure_federation.rst @@ -0,0 +1,336 @@ +.. + 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 Keystone for Federation +=================================== + +----------- +Definitions +----------- +* `Service Provider (SP)`: provides a service to an end-user. +* `Identity Provider (IdP)`: service that stores information about users and + groups. +* `SAML assertion`: contains information about a user as provided by an IdP. + +----------------------------------- +Keystone as a Service Provider (SP) +----------------------------------- + +.. NOTE:: + + This feature is considered stable and supported as of the Juno release. + +Prerequisites +------------- + +This approach to federation supports Keystone as a Service Provider, consuming +identity properties issued by an external Identity Provider, such as SAML +assertions or OpenID Connect claims. + +Federated users are not mirrored in the Keystone identity backend +(for example, using the SQL driver). The external Identity Provider is +responsible for authenticating users, and communicates the result of +authentication to Keystone using identity properties. Keystone maps these +values to Keystone user groups and assignments created in Keystone. + +The following configuration steps were performed on a machine running +Ubuntu 12.04 and Apache 2.2.22. + +To enable federation, you'll need to: + +1. Run Keystone under Apache, rather than using ``keystone-all``. +2. Configure Apache to use a federation capable authentication method. +3. Enable ``OS-FEDERATION`` extension. + +Configure Apache to use a federation capable authentication method +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +There are many ways to configure Federation in the Apache HTTPD server. +Using Shibboleth and OpenID Connect are documented so far. + +* To use Shibboleth, follow the steps outlined at: `Setup Shibboleth`_. +* To use OpenID Connect, follow the steps outlined at: `Setup OpenID Connect`_. + +.. _`Setup Shibboleth`: extensions/shibboleth.html +.. _`Setup OpenID Connect`: extensions/openidc.html + +Enable the ``OS-FEDERATION`` extension +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Follow the steps outlined at: `Enabling Federation Extension`_. + +.. _`Enabling Federation Extension`: extensions/federation.html + +Configuring Federation +---------------------- + +Now that the Identity Provider and Keystone are communicating we can start to +configure the ``OS-FEDERATION`` extension. + +1. Add local Keystone groups and roles +2. Add Identity Provider(s), Mapping(s), and Protocol(s) + +Create Keystone groups and assign roles +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As mentioned earlier, no new users will be added to the Identity backend, but +the Identity Service requires group-based role assignments to authorize +federated users. The federation mapping function will map the user into local +Identity Service groups objects, and hence to local role assignments. + +Thus, it is required to create the necessary Identity Service groups that +correspond to the Identity Provider's groups; additionally, these groups should +be assigned roles on one or more projects or domains. + +You may be interested in more information on `group management +<http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3.html#create-group>`_ +and `role assignments +<http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3.html#grant-role-to-group-on-project>`_, +both of which are exposed to the CLI via `python-openstackclient +<https://pypi.python.org/pypi/python-openstackclient/>`_. + +Add Identity Provider(s), Mapping(s), and Protocol(s) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To utilize federation the following must be created in the Identity Service: + +* Identity Provider +* Mapping +* Protocol + +More information on ``OS-FEDERATION`` can be found `here +<http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3-os-federation-ext.html>`__. + +~~~~~~~~~~~~~~~~~ +Identity Provider +~~~~~~~~~~~~~~~~~ + +Create an Identity Provider object in Keystone, which represents the Identity +Provider we will use to authenticate end users. + +More information on identity providers can be found `here +<http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3-os-federation-ext.html#register-an-identity-provider>`__. + +~~~~~~~ +Mapping +~~~~~~~ +A mapping is a list of rules. The only Identity API objects that will support mapping are groups +and users. + +Mapping adds a set of rules to map federation protocol attributes to Identity API objects. +An Identity Provider has exactly one mapping specified per protocol. + +Mapping objects can be used multiple times by different combinations of Identity Provider and Protocol. + +More information on mapping can be found `here +<http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3-os-federation-ext.html#create-a-mapping>`__. + +~~~~~~~~ +Protocol +~~~~~~~~ + +A protocol contains information that dictates which Mapping rules to use for an incoming +request made by an IdP. An IdP may have multiple supported protocols. + +Add `Protocol object +<http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3-os-federation-ext.html#add-a-protocol-and-attribute-mapping-to-an-identity-provider>`__ and specify the mapping id +you want to use with the combination of the IdP and Protocol. + +Performing federated authentication +----------------------------------- + +1. Authenticate externally and generate an unscoped token in Keystone +2. Determine accessible resources +3. Get a scoped token + +Get an unscoped token +~~~~~~~~~~~~~~~~~~~~~ + +Unlike other authentication methods in the Identity Service, the user does not +issue an HTTP POST request with authentication data in the request body. To +start federated authentication a user must access the dedicated URL with +Identity Provider's and Protocol's identifiers stored within a protected URL. +The URL has a format of: +``/v3/OS-FEDERATION/identity_providers/{identity_provider}/protocols/{protocol}/auth``. + +In this instance we follow a standard SAML2 authentication procedure, that is, +the user will be redirected to the Identity Provider's authentication webpage +and be prompted for credentials. After successfully authenticating the user +will be redirected to the Service Provider's endpoint. If using a web browser, +a token will be returned in XML format. + +In the returned unscoped token, a list of Identity Service groups the user +belongs to will be included. + +More information on getting an unscoped token can be found `here +<http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3-os-federation-ext.html#authenticating>`__. + +~~~~~~~~~~~~ +Example cURL +~~~~~~~~~~~~ + +Note that the request does not include a body. The following url would be +considered protected by ``mod_shib`` and Apache, as such a request made +to the URL would be redirected to the Identity Provider, to start the +SAML authentication procedure. + +.. code-block:: bash + + $ curl -X GET -D - http://localhost:5000/v3/OS-FEDERATION/identity_providers/{identity_provider}/protocols/{protocol}/auth + +Determine accessible resources +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +By using the previously returned token, the user can issue requests to the list +projects and domains that are accessible. + +* List projects a federated user can access: ``GET /OS-FEDERATION/projects`` +* List domains a federated user can access: ``GET /OS-FEDERATION/domains`` + +More information on listing resources can be found `here +<http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3-os-federation-ext.html#listing-projects-and-domains>`__. + +~~~~~~~~~~~~ +Example cURL +~~~~~~~~~~~~ + +.. code-block:: bash + + $ curl -X GET -H "X-Auth-Token: <unscoped token>" http://localhost:5000/v3/OS-FEDERATION/projects + +or + +.. code-block:: bash + + $ curl -X GET -H "X-Auth-Token: <unscoped token>" http://localhost:5000/v3/OS-FEDERATION/domains + +Get a scoped token +~~~~~~~~~~~~~~~~~~ + +A federated user may request a scoped token, by using the unscoped token. A +project or domain may be specified by either ``id`` or ``name``. An ``id`` is +sufficient to uniquely identify a project or domain. + +More information on getting a scoped token can be found `here +<http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3-os-federation-ext.html#request-a-scoped-os-federation-token>`__. + +~~~~~~~~~~~~ +Example cURL +~~~~~~~~~~~~ + +.. code-block:: bash + + $ curl -X POST -H "Content-Type: application/json" -d '{"auth":{"identity":{"methods":["saml2"],"saml2":{"id":"<unscoped_token_id>"}},"scope":{"project":{"domain": {"name": "Default"},"name":"service"}}}}' -D - http://localhost:5000/v3/auth/tokens + +-------------------------------------- +Keystone as an Identity Provider (IdP) +-------------------------------------- + +.. NOTE:: + + This feature is experimental and unsupported in Juno (with several issues + that will not be backported). These issues have been fixed and this feature + is considered stable and supported as of the Kilo release. + +Configuration Options +--------------------- + +There are certain settings in ``keystone.conf`` that must be setup, prior to +attempting to federate multiple Keystone deployments. + +Within ``keystone.conf``, assign values to the ``[saml]`` related fields, for +example: + +.. code-block:: ini + + [saml] + certfile=/etc/keystone/ssl/certs/ca.pem + keyfile=/etc/keystone/ssl/private/cakey.pem + idp_entity_id=https://keystone.example.com/v3/OS-FEDERATION/saml2/idp + idp_sso_endpoint=https://keystone.example.com/v3/OS-FEDERATION/saml2/sso + idp_metadata_path=/etc/keystone/saml2_idp_metadata.xml + +Though not necessary, the follow Organization configuration options should +also be setup. It is recommended that these values be URL safe. + +.. code-block:: ini + + idp_organization_name=example_company + idp_organization_display_name=Example Corp. + idp_organization_url=example.com + +As with the Organizaion options, the Contact options, are not necessary, but +it's advisable to set these values too. + +.. code-block:: ini + + idp_contact_company=example_company + idp_contact_name=John + idp_contact_surname=Smith + idp_contact_email=jsmith@example.com + idp_contact_telephone=555-55-5555 + idp_contact_type=technical + +Generate Metadata +----------------- + +In order to create a trust between the IdP and SP, metadata must be exchanged. +To create metadata for your Keystone IdP, run the ``keystone-manage`` command +and pipe the output to a file. For example: + +.. code-block:: bash + + $ keystone-manage saml_idp_metadata > /etc/keystone/saml2_idp_metadata.xml + +.. NOTE:: + The file location should match the value of the configuration option + ``idp_metadata_path`` that was assigned in the previous section. + +Create a Service Provider (SP) +------------------------------ + +In this example we are creating a new Service Provider with an ID of ``BETA``, +a ``sp_url`` of ``http://beta.example.com/Shibboleth.sso/POST/ECP`` and a +``auth_url`` of ``http://beta.example.com:5000/v3/OS-FEDERATION/identity_providers/beta/protocols/saml2/auth`` +. The ``sp_url`` will be used when creating a SAML assertion for ``BETA`` and +signed by the current Keystone IdP. The ``auth_url`` is used to retrieve the +token for ``BETA`` once the SAML assertion is sent. + +.. code-block:: bash + + $ curl -s -X PUT \ + -H "X-Auth-Token: $OS_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"service_provider": {"auth_url": "http://beta.example.com:5000/v3/OS-FEDERATION/identity_providers/beta/protocols/saml2/auth", "sp_url": "https://example.com:5000/Shibboleth.sso/SAML2/ECP"}' \ + http://localhost:5000/v3/service_providers/BETA | python -mjson.tool + +Testing it all out +------------------ + +Lastly, if a scoped token and a Service Provider region are presented to +Keystone, the result will be a full SAML Assertion, signed by the IdP +Keystone, specifically intended for the Service Provider Keystone. + +.. code-block:: bash + + $ curl -s -X POST \ + -H "Content-Type: application/json" \ + -d '{"auth": {"scope": {"service_provider": {"id": "BETA"}}, "identity": {"token": {"id": "d793d935b9c343f783955cf39ee7dc3c"}, "methods": ["token"]}}}' \ + http://localhost:5000/v3/auth/OS-FEDERATION/saml2 + +At this point the SAML Assertion can be sent to the Service Provider Keystone +using the provided ``auth_url`` in the ``X-Auth-Url`` header present in the +response containing the SAML Assertion, and a valid OpenStack token, issued by +a Service Provider Keystone, will be returned. + diff --git a/keystone-moon/doc/source/configuringservices.rst b/keystone-moon/doc/source/configuringservices.rst new file mode 100644 index 00000000..3ffa13e7 --- /dev/null +++ b/keystone-moon/doc/source/configuringservices.rst @@ -0,0 +1,162 @@ +.. + Copyright 2011-2012 OpenStack Foundation + 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 (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 retrieve additional information from the token such as user + name, user id, project name, project 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 the +`authentication middleware documentation`_. + +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 ``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 + +A "shared secret" that can be used to bootstrap Keystone. This token does not +represent a user, and carries no explicit authorization. +To disable in production (highly recommended), remove AdminTokenAuthMiddleware +from your paste application pipelines (for example, in keystone-paste.ini) + +Setting up projects, users, and roles +------------------------------------- + +You need to minimally define a project, user, and role to link the project and +user as the most basic set of details to get other services authenticating +and authorizing with Keystone. + +You will also want to create service users for nova, glance, swift, etc. to +be able to use to authenticate users against Keystone. The ``auth_token`` +middleware supports using either the shared secret described above as +`admin_token` or users for each service. + +See :doc:`configuration` for a walk through on how to create projects, users, +and roles. + +Setting up services +=================== + +Creating Service Users +---------------------- + +To configure the OpenStack services with service users, we need to create +a project for all the services, and then users for each of the services. We +then assign those service users an ``admin`` role on the service project. This +allows them to validate tokens - and to authenticate and authorize other user +requests. + +Create a project for the services, typically named ``service`` (however, the +name can be whatever you choose): + +.. code-block:: bash + + $ openstack project create service + +Create service users for ``nova``, ``glance``, ``swift``, and ``neutron`` +(or whatever subset is relevant to your deployment): + +.. code-block:: bash + + $ openstack user create nova --password Sekr3tPass --project service + +Repeat this for each service you want to enable. + +Create an administrative role for the service accounts, typically named +``admin`` (however the name can be whatever you choose). For adding the +administrative role to the service accounts, you'll need to know the +name of the role you want to add. If you don't have it handy, you can look it +up quickly with: + +.. code-block:: bash + + $ openstack role list + +Once you have it, grant the administrative role to the service users. This is +all assuming that you've already created the basic roles and settings as +described in :doc:`configuration`: + +.. code-block:: bash + + $ openstack role add admin --project service --user nova + +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. + +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``. + +Keystone supports two means of defining the services, one is the catalog +template, as described above - in which case everything is detailed in that +template. + +The other is a SQL backend for the catalog service, in which case after +Keystone is online, you need to add the services to the catalog: + +.. code-block:: bash + + $ openstack service create compute --name nova \ + --description "Nova Compute Service" + $ openstack service create ec2 --name ec2 \ + --description "EC2 Compatibility Layer" + $ openstack service create image --name glance \ + --description "Glance Image Service" + $ openstack service create identity --name keystone \ + --description "Keystone Identity Service" + $ openstack service create object-store --name swift \ + --description "Swift Service" + + +Setting Up Auth-Token Middleware +================================ + +The Keystone project provides the auth-token middleware which validates that +the request is valid before passing it on to the application. This must be +installed and configured in the applications (such as Nova, Glance, Swift, +etc.). The `authentication middleware documentation`_ describes how to install +and configure this middleware. + +.. _`authentication middleware documentation`: http://docs.openstack.org/developer/keystonemiddleware/middlewarearchitecture.html diff --git a/keystone-moon/doc/source/developing.rst b/keystone-moon/doc/source/developing.rst new file mode 100644 index 00000000..33b2dd58 --- /dev/null +++ b/keystone-moon/doc/source/developing.rst @@ -0,0 +1,771 @@ +.. + Copyright 2011-2012 OpenStack Foundation + 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. + +======================== +Developing with Keystone +======================== + +Setup +----- + +Get your development environment set up according to :doc:`setup`. The +instructions from here will assume that you have installed Keystone into a +virtualenv. If you chose not to, simply exclude "tools/with_venv.sh" from the +example commands below. + + +Configuring Keystone +-------------------- + +Keystone requires a configuration file. There is a sample configuration file +that can be used to get started: + +.. code-block:: bash + + $ cp etc/keystone.conf.sample etc/keystone.conf + +The defaults are enough to get you going, but you can make any changes if +needed. + + +Running Keystone +---------------- + +To run the Keystone Admin and API server instances, use: + +.. code-block:: bash + + $ tools/with_venv.sh bin/keystone-all + +This runs Keystone with the configuration the etc/ directory of the project. +See :doc:`configuration` for details on how Keystone is configured. By default, +Keystone is configured with SQL backends. + + +Interacting with Keystone +------------------------- + +You can interact with Keystone through the command line using +:doc:`man/keystone-manage` which allows you to initialize keystone, etc. + +You can also interact with Keystone through its REST API. There is a Python +Keystone client library `python-keystoneclient`_ which interacts exclusively +through the REST API, and which Keystone itself uses to provide its +command-line interface. + +When initially getting set up, after you've configured which databases to use, +you're probably going to need to run the following to your database schema in +place: + +.. code-block:: bash + + $ bin/keystone-manage db_sync + +.. _`python-keystoneclient`: https://github.com/openstack/python-keystoneclient + +If the above commands result in a ``KeyError``, or they fail on a +``.pyc`` file with the message, ``You can only have one Python script per +version``, then it is possible that there are out-of-date compiled Python +bytecode files in the Keystone directory tree that are causing problems. This +can occur if you have previously installed and ran older versions of Keystone. +These out-of-date files can be easily removed by running a command like the +following from the Keystone root project directory: + +.. code-block:: bash + + $ find . -name "*.pyc" -delete + +Database Schema Migrations +-------------------------- + +Keystone uses SQLAlchemy-migrate_ to migrate +the SQL database between revisions. For core components, the migrations are +kept in a central repository under ``keystone/common/sql/migrate_repo``. + +.. _SQLAlchemy-migrate: http://code.google.com/p/sqlalchemy-migrate/ + +Extensions should be created as directories under ``keystone/contrib``. An +extension that requires SQL migrations should not change the common repository, +but should instead have its own repository. This repository must be in the +extension's directory in ``keystone/contrib/<extension>/migrate_repo``. In +addition, it needs a subdirectory named ``versions``. For example, if the +extension name is ``my_extension`` then the directory structure would be +``keystone/contrib/my_extension/migrate_repo/versions/``. For the migration to +work, both the ``migrate_repo`` and ``versions`` subdirectories must have +``__init__.py`` files. SQLAlchemy-migrate will look for a configuration file in +the ``migrate_repo`` named ``migrate.cfg``. This conforms to a key/value `ini` +file format. A sample configuration file with the minimal set of values is:: + + [db_settings] + repository_id=my_extension + version_table=migrate_version + required_dbs=[] + +The directory ``keystone/contrib/example`` contains a sample extension +migration. + +Migrations must be explicitly run for each extension individually. To run a +migration for a specific extension, simply run: + +.. code-block:: bash + + $ keystone-manage db_sync --extension <name> + +Initial Sample Data +------------------- + +There is an included script which is helpful in setting up some initial sample +data for use with keystone: + +.. code-block:: bash + + $ OS_SERVICE_TOKEN=ADMIN tools/with_venv.sh tools/sample_data.sh + +Notice it requires a service token read from an environment variable for +authentication. The default value "ADMIN" is from the ``admin_token`` +option in the ``[DEFAULT]`` section in ``etc/keystone.conf``. + +Once run, you can see the sample data that has been created by using the +`python-keystoneclient`_ command-line interface: + +.. code-block:: bash + + $ tools/with_venv.sh keystone --os-token ADMIN --os-endpoint http://127.0.0.1:35357/v2.0/ user-list + +Filtering responsibilities between controllers and drivers +---------------------------------------------------------- + +Keystone supports the specification of filtering on list queries as part of the +v3 identity API. By default these queries are satisfied in the controller +class when a controller calls the ``wrap_collection`` method at the end of a +``list_{entity}`` method. However, to enable optimum performance, any driver +can implement some or all of the specified filters (for example, by adding +filtering to the generated SQL statements to generate the list). + +The communication of the filter details between the controller level and its +drivers is handled by the passing of a reference to a Hints object, +which is a list of dicts describing the filters. A driver that satisfies a +filter must delete the filter from the Hints object so that when it is returned +to the controller level, it knows to only execute any unsatisfied +filters. + +The contract for a driver for ``list_{entity}`` methods is therefore: + +* It MUST return a list of entities of the specified type +* It MAY either just return all such entities, or alternatively reduce the + list by filtering for one or more of the specified filters in the passed + Hints reference, and removing any such satisfied filters. An exception to + this is that for identity drivers that support domains, then they should + at least support filtering by domain_id. + +Entity list truncation by drivers +--------------------------------- + +Keystone supports the ability for a deployment to restrict the number of +entries returned from ``list_{entity}`` methods, typically to prevent poorly +formed searches (e.g. without sufficient filters) from becoming a performance +issue. + +These limits are set in the configuration file, either for a specific driver or +across all drivers. These limits are read at the Manager level and passed into +individual drivers as part of the Hints list object. A driver should try and +honor any such limit if possible, but if it is unable to do so then it may +ignore it (and the truncation of the returned list of entities will happen at +the controller level). + +Identity entity ID management between controllers and drivers +------------------------------------------------------------- + +Keystone supports the option of having domain-specific backends for the +identity driver (i.e. for user and group storage), allowing, for example, +a different LDAP server for each domain. To ensure that Keystone can determine +to which backend it should route an API call, starting with Juno, the +identity manager will, provided that domain-specific backends are enabled, +build on-the-fly a persistent mapping table between Keystone Public IDs that +are presented to the controller and the domain that holds the entity, along +with whatever local ID is understood by the driver. This hides, for instance, +the LDAP specifics of whatever ID is being used. + +To ensure backward compatibility, the default configuration of either a +single SQL or LDAP backend for Identity will not use the mapping table, +meaning that public facing IDs will be the unchanged. If keeping these IDs +the same for the default LDAP backend is not required, then setting the +configuration variable ``backward_compatible_ids`` to ``False`` will enable +the mapping for the default LDAP driver, hence hiding the LDAP specifics of the +IDs being used. + +Testing +------- + +Running Tests +============= + +Before running tests, you should have ``tox`` installed and available in your +environment (in addition to the other external dependencies in :doc:`setup`): + +.. code-block:: bash + + $ pip install tox + +.. NOTE:: + + You may need to perform both the above operation and the next inside a + python virtualenv, or prefix the above command with ``sudo``, depending on + your preference. + +To execute the full suite of tests maintained within Keystone, simply run: + +.. code-block:: bash + + $ tox + +This iterates over multiple configuration variations, and uses external +projects to do light integration testing to verify the Identity API against +other projects. + +.. NOTE:: + + The first time you run ``tox``, it will take additional time to build + virtualenvs. You can later use the ``-r`` option with ``tox`` to rebuild + your virtualenv in a similar manner. + +To run tests for one or more specific test environments (for example, the most +common configuration of Python 2.7 and PEP-8), list the environments with the +``-e`` option, separated by spaces: + +.. code-block:: bash + + $ tox -e py27,pep8 + +See ``tox.ini`` for the full list of available test environments. + +Running with PDB +~~~~~~~~~~~~~~~~ + +Using PDB breakpoints with tox and testr normally doesn't work since the tests +just fail with a BdbQuit exception rather than stopping at the breakpoint. + +To run with PDB breakpoints during testing, use the ``debug`` tox environment +rather than ``py27``. Here's an example, passing the name of a test since +you'll normally only want to run the test that hits your breakpoint: + +.. code-block:: bash + + $ tox -e debug keystone.tests.test_auth.AuthWithToken.test_belongs_to + +For reference, the ``debug`` tox environment implements the instructions +here: https://wiki.openstack.org/wiki/Testr#Debugging_.28pdb.29_Tests + +Disabling Stream Capture +~~~~~~~~~~~~~~~~~~~~~~~~ + +The stdout, stderr and log messages generated during a test are captured and +in the event of a test failure those streams will be printed to the terminal +along with the traceback. The data is discarded for passing tests. + +Each stream has an environment variable that can be used to force captured +data to be discarded even if the test fails: `OS_STDOUT_CAPTURE` for stdout, +`OS_STDERR_CAPTURE` for stderr and `OS_LOG_CAPTURE` for logging. If the value +of the environment variable is not one of (True, true, 1, yes) the stream will +be discarded. All three variables default to 1. + +For example, to discard logging data during a test run: + +.. code-block:: bash + + $ OS_LOG_CAPTURE=0 tox -e py27 + +Test Structure +============== + +Not all of the tests in the tests directory are strictly unit tests. Keystone +intentionally includes tests that run the service locally and drives the entire +configuration to achieve basic functional testing. + +For the functional tests, an in-memory key-value store is used to keep the +tests fast. + +Within the tests directory, the general structure of the tests is a basic +set of tests represented under a test class, and then subclasses of those +tests under other classes with different configurations to drive different +backends through the APIs. + +For example, ``test_backend.py`` has a sequence of tests under the class +``IdentityTests`` that will work with the default drivers as configured in +this projects etc/ directory. ``test_backend_sql.py`` subclasses those tests, +changing the configuration by overriding with configuration files stored in +the tests directory aimed at enabling the SQL backend for the Identity module. + +Likewise, ``test_v2_keystoneclient.py`` takes advantage of the tests written +against ``KeystoneClientTests`` to verify the same tests function through +different drivers and releases of the Keystone client. + +The class ``CompatTestCase`` does the work of checking out a specific version +of python-keystoneclient, and then verifying it against a temporarily running +local instance to explicitly verify basic functional testing across the API. + +Testing Schema Migrations +========================= + +The application of schema migrations can be tested using SQLAlchemy Migrate’s +built-in test runner, one migration at a time. + +.. WARNING:: + + This may leave your database in an inconsistent state; attempt this in non-production environments only! + +This is useful for testing the *next* migration in sequence (both forward & +backward) in a database under version control: + +.. code-block:: bash + + $ python keystone/common/sql/migrate_repo/manage.py test \ + --url=sqlite:///test.db \ + --repository=keystone/common/sql/migrate_repo/ + +This command references to a SQLite database (test.db) to be used. Depending on +the migration, this command alone does not make assertions as to the integrity +of your data during migration. + + +Writing Tests +============= + +To add tests covering all drivers, update the relevant base test class +(``test_backend.py``, ``test_legacy_compat.py``, and +``test_keystoneclient.py``). + +To add new drivers, subclass the ``test_backend.py`` (look towards +``test_backend_sql.py`` or ``test_backend_kvs.py`` for examples) and update the +configuration of the test class in ``setUp()``. + + +Further Testing +=============== + +devstack_ is the *best* way to quickly deploy Keystone with the rest of the +OpenStack universe and should be critical step in your development workflow! + +You may also be interested in either the +`OpenStack Continuous Integration Infrastructure`_ or the +`OpenStack Integration Testing Project`_. + +.. _devstack: http://devstack.org/ +.. _OpenStack Continuous Integration Infrastructure: http://ci.openstack.org +.. _OpenStack Integration Testing Project: https://github.com/openstack/tempest + + +LDAP Tests +========== + +LDAP has a fake backend that performs rudimentary operations. If you +are building more significant LDAP functionality, you should test against +a live LDAP server. Devstack has an option to set up a directory server for +Keystone to use. Add ldap to the ``ENABLED_SERVICES`` environment variable, +and set environment variables ``KEYSTONE_IDENTITY_BACKEND=ldap`` and +``KEYSTONE_CLEAR_LDAP=yes`` in your ``localrc`` file. + +The unit tests can be run against a live server with +``keystone/tests/test_ldap_livetest.py`` and +``keystone/tests/test_ldap_pool_livetest.py``. The default password is ``test`` +but if you have installed devstack with a different LDAP password, modify the +file ``keystone/tests/config_files/backend_liveldap.conf`` and +``keystone/tests/config_files/backend_pool_liveldap.conf`` to reflect your password. + +.. NOTE:: + To run the live tests you need to set the environment variable ``ENABLE_LDAP_LIVE_TEST`` + to a non-negative value. + + +"Work in progress" Tests +======================== + +Work in progress (WIP) tests are very useful in a variety of situations +including: + +* During a TDD process they can be used to add tests to a review while + they are not yet working and will not cause test failures. (They should + be removed before the final merge.) +* Often bug reports include small snippets of code to show broken + behaviors. Some of these can be converted into WIP tests that can later + be worked on by a developer. This allows us to take code that can be + used to catch bug regressions and commit it before any code is + written. + +The ``keystone.tests.util.wip`` decorator can be used to mark a test as +WIP. A WIP test will always be run. If the test fails then a TestSkipped +exception is raised because we expect the test to fail. We do not pass +the test in this case so that it doesn't count toward the number of +successfully run tests. If the test passes an AssertionError exception is +raised so that the developer knows they made the test pass. This is a +reminder to remove the decorator. + +The ``wip`` decorator requires that the author provides a message. This +message is important because it will tell other developers why this test +is marked as a work in progress. Reviewers will require that these +messages are descriptive and accurate. + +.. NOTE:: + The ``wip`` decorator is not a replacement for skipping tests. + +.. code-block:: python + + @wip('waiting on bug #000000') + def test(): + pass + + +Generating Updated Sample Config File +------------------------------------- + +Keystone's sample configuration file ``etc/keystone.conf.sample`` is automatically +generated based upon all of the options available within Keystone. These options +are sourced from the many files around Keystone as well as some external libraries. + +If new options are added, primarily located in ``keystone.common.config``, a new +sample configuration file needs to be generated. Generating a new sample configuration +to be included in a commit run: + +.. code-block:: bash + + $ tox -esample_config -r + +The tox command will place an updated sample config in ``etc/keystone.conf.sample``. + +If there is a new external library (e.g. ``oslo.messaging``) that utilizes the +``oslo.config`` package for configuration, it can be added to the list of libraries +found in ``tools/config/oslo.config.generator.rc``. + + +Translated responses +-------------------- + +The Keystone server can provide error responses translated into the language in +the ``Accept-Language`` header of the request. In order to test this in your +development environment, there's a couple of things you need to do. + +1. Build the message files. Run the following command in your keystone + directory: + +.. code-block:: bash + + $ python setup.py compile_catalog + +This will generate .mo files like keystone/locale/[lang]/LC_MESSAGES/[lang].mo + +2. When running Keystone, set the ``KEYSTONE_LOCALEDIR`` environment variable + to the keystone/locale directory. For example: + +.. code-block:: bash + + $ KEYSTONE_LOCALEDIR=/opt/stack/keystone/keystone/locale keystone-all + +Now you can get a translated error response: + +.. code-block:: bash + + $ curl -s -H "Accept-Language: zh" http://localhost:5000/notapath | python -mjson.tool + { + "error": { + "code": 404, + "message": "\u627e\u4e0d\u5230\u8cc7\u6e90\u3002", + "title": "Not Found" + } + } + + +Caching Layer +------------- + +The caching layer is designed to be applied to any ``manager`` object within Keystone +via the use of the ``on_arguments`` decorator provided in the ``keystone.common.cache`` +module. This decorator leverages `dogpile.cache`_ caching system to provide a flexible +caching backend. + +It is recommended that each of the managers have an independent toggle within the config +file to enable caching. The easiest method to utilize the toggle within the +configuration file is to define a ``caching`` boolean option within that manager's +configuration section (e.g. ``identity``). Once that option is defined you can +pass function to the ``on_arguments`` decorator with the named argument ``should_cache_fn``. +In the ``keystone.common.cache`` module, there is a function called ``should_cache_fn``, +which will provide a reference, to a function, that will consult the global cache +``enabled`` option as well as the specific manager's caching enable toggle. + + .. NOTE:: + If a section-specific boolean option is not defined in the config section specified when + calling ``should_cache_fn``, the returned function reference will default to enabling + caching for that ``manager``. + +Example use of cache and ``should_cache_fn`` (in this example, ``token`` is the manager): + +.. code-block:: python + + from keystone.common import cache + SHOULD_CACHE = cache.should_cache_fn('token') + + @cache.on_arguments(should_cache_fn=SHOULD_CACHE) + def cacheable_function(arg1, arg2, arg3): + ... + return some_value + +With the above example, each call to the ``cacheable_function`` would check to see if +the arguments passed to it matched a currently valid cached item. If the return value +was cached, the caching layer would return the cached value; if the return value was +not cached, the caching layer would call the function, pass the value to the ``SHOULD_CACHE`` +function reference, which would then determine if caching was globally enabled and enabled +for the ``token`` manager. If either caching toggle is disabled, the value is returned but +not cached. + +It is recommended that each of the managers have an independent configurable time-to-live (TTL). +If a configurable TTL has been defined for the manager configuration section, it is possible to +pass it to the ``cache.on_arguments`` decorator with the named-argument ``expiration_time``. For +consistency, it is recommended that this option be called ``cache_time`` and default to ``None``. +If the ``expiration_time`` argument passed to the decorator is set to ``None``, the expiration +time will be set to the global default (``expiration_time`` option in the ``[cache]`` +configuration section. + +Example of using a section specific ``cache_time`` (in this example, ``identity`` is the manager): + +.. code-block:: python + + from keystone.common import cache + SHOULD_CACHE = cache.should_cache_fn('identity') + + @cache.on_arguments(should_cache_fn=SHOULD_CACHE, + expiration_time=CONF.identity.cache_time) + def cachable_function(arg1, arg2, arg3): + ... + return some_value + +For cache invalidation, the ``on_arguments`` decorator will add an ``invalidate`` method +(attribute) to your decorated function. To invalidate the cache, you pass the same arguments +to the ``invalidate`` method as you would the normal function. + +Example (using the above cacheable_function): + +.. code-block:: python + + def invalidate_cache(arg1, arg2, arg3): + cacheable_function.invalidate(arg1, arg2, arg3) + +.. WARNING:: + The ``on_arguments`` decorator does not accept keyword-arguments/named arguments. An + exception will be raised if keyword arguments are passed to a caching-decorated function. + +.. NOTE:: + In all cases methods work the same as functions except if you are attempting to invalidate + the cache on a decorated bound-method, you need to pass ``self`` to the ``invalidate`` + method as the first argument before the arguments. + +.. _`dogpile.cache`: http://dogpilecache.readthedocs.org/ + + +dogpile.cache based Key-Value-Store (KVS) +----------------------------------------- +The ``dogpile.cache`` based KVS system has been designed to allow for flexible stores for the +backend of the KVS system. The implementation allows for the use of any normal ``dogpile.cache`` +cache backends to be used as a store. All interfacing to the KVS system happens via the +``KeyValueStore`` object located at ``keystone.common.kvs.KeyValueStore``. + +To utilize the KVS system an instantiation of the ``KeyValueStore`` class is needed. To acquire +a KeyValueStore instantiation use the ``keystone.common.kvs.get_key_value_store`` factory +function. This factory will either create a new ``KeyValueStore`` object or retrieve the +already instantiated ``KeyValueStore`` object by the name passed as an argument. The object must +be configured before use. The KVS object will only be retrievable with the +``get_key_value_store`` function while there is an active reference outside of the registry. +Once all references have been removed the object is gone (the registry uses a ``weakref`` to +match the object to the name). + +Example Instantiation and Configuration: + +.. code-block:: python + + kvs_store = kvs.get_key_value_store('TestKVSRegion') + kvs_store.configure('openstack.kvs.Memory', ...) + +Any keyword arguments passed to the configure method that are not defined as part of the +KeyValueStore object configuration are passed to the backend for further configuration (e.g. +memcached servers, lock_timeout, etc). + +The memcached backend uses the Keystone manager mechanism to support the use of any of the +provided memcached backends (``bmemcached``, ``pylibmc``, and basic ``memcached``). +By default the ``memcached`` backend is used. Currently the Memcache URLs come from the +``servers`` option in the ``[memcache]`` configuration section of the Keystone config. + +The following is an example showing how to configure the KVS system to use a +KeyValueStore object named "TestKVSRegion" and a specific Memcached driver: + +.. code-block:: python + + kvs_store = kvs.get_key_value_store('TestKVSRegion') + kvs_store.configure('openstack.kvs.Memcached', memcached_backend='Memcached') + +The memcached backend supports a mechanism to supply an explicit TTL (in seconds) to all keys +set via the KVS object. This is accomplished by passing the argument ``memcached_expire_time`` +as a keyword argument to the ``configure`` method. Passing the ``memcache_expire_time`` argument +will cause the ``time`` argument to be added to all ``set`` and ``set_multi`` calls performed by +the memcached client. ``memcached_expire_time`` is an argument exclusive to the memcached dogpile +backend, and will be ignored if passed to another backend: + +.. code-block:: python + + kvs_store.configure('openstack.kvs.Memcached', memcached_backend='Memcached', + memcached_expire_time=86400) + +If an explicit TTL is configured via the ``memcached_expire_time`` argument, it is possible to +exempt specific keys from receiving the TTL by passing the argument ``no_expiry_keys`` (list) +as a keyword argument to the ``configure`` method. ``no_expiry_keys`` should be supported by +all OpenStack-specific dogpile backends (memcached) that have the ability to set an explicit TTL: + +.. code-block:: python + + kvs_store.configure('openstack.kvs.Memcached', memcached_backend='Memcached', + memcached_expire_time=86400, no_expiry_keys=['key', 'second_key', ...]) + + +.. NOTE:: + For the non-expiring keys functionality to work, the backend must support the ability for + the region to set the key_mangler on it and have the attribute ``raw_no_expiry_keys``. + In most cases, support for setting the key_mangler on the backend is handled by allowing + the region object to set the ``key_mangler`` attribute on the backend. + + The ``raw_no_expiry_keys`` attribute is expected to be used to hold the values of the + keyword argument ``no_expiry_keys`` prior to hashing. It is the responsibility of the + backend to use these raw values to determine if a key should be exempt from expiring + and not set the TTL on the non-expiring keys when the ``set`` or ``set_multi`` methods are + called. + + Typically the key will be hashed by the region using its key_mangler method + before being passed to the backend to set the value in the KeyValueStore. This + means that in most cases, the backend will need to either pre-compute the hashed versions + of the keys (when the key_mangler is set) and store a cached copy, or hash each item in + the ``raw_no_expiry_keys`` attribute on each call to ``.set()`` and ``.set_multi()``. The + ``memcached`` backend handles this hashing and caching of the keys by utilizing an + ``@property`` method for the ``.key_mangler`` attribute on the backend and utilizing the + associated ``.settr()`` method to front-load the hashing work at attribute set time. + +Once a KVS object has been instantiated the method of interacting is the same as most memcache +implementations: + +.. code-block:: python + + kvs_store = kvs.get_key_value_store('TestKVSRegion') + kvs_store.configure(...) + # Set a Value + kvs_store.set(<Key>, <Value>) + # Retrieve a value: + retrieved_value = kvs_store.get(<key>) + # Delete a key/value pair: + kvs_store.delete(<key>) + # multi-get: + kvs_store.get_multi([<key>, <key>, ...]) + # multi-set: + kvs_store.set_multi(dict(<key>=<value>, <key>=<value>, ...)) + # multi-delete + kvs_store.delete_multi([<key>, <key>, ...]) + + +There is a global configuration option to be aware of (that can be set in the ``[kvs]`` section of +the Keystone configuration file): ``enable_key_mangler`` can be set top false, disabling the use of +key_manglers (modification of the key when saving to the backend to help prevent +collisions or exceeding key size limits with memcached). + +.. NOTE:: + The ``enable_key_mangler`` option in the ``[kvs]`` section of the Keystone configuration file + is not the same option (and does not affect the cache-layer key manglers) from the option in the + ``[cache]`` section of the configuration file. Similarly the ``[cache]`` section options + relating to key manglers has no bearing on the ``[kvs]`` objects. + +.. WARNING:: + Setting the ``enable_key_mangler`` option to False can have detrimental effects on the + KeyValueStore backend. It is recommended that this value is not set to False except for + debugging issues with the ``dogpile.cache`` backend itself. + +Any backends that are to be used with the ``KeyValueStore`` system need to be registered with +dogpile. For in-tree/provided backends, the registration should occur in +``keystone/common/kvs/__init__.py``. For backends that are developed out of tree, the location +should be added to the ``backends`` option in the ``[kvs]`` section of the Keystone configuration:: + + [kvs] + backends = backend_module1.backend_class1,backend_module2.backend_class2 + +All registered backends will receive the "short name" of "openstack.kvs.<class name>" for use in the +``configure`` method on the ``KeyValueStore`` object. The ``<class name>`` of a backend must be +globally unique. + +dogpile.cache based MongoDB (NoSQL) backend +-------------------------------------------- + +The ``dogpile.cache`` based MongoDB backend implementation allows for various MongoDB +configurations, e.g., standalone, a replica set, sharded replicas, with or without SSL, +use of TTL type collections, etc. + +Example of typical configuration for MongoDB backend: + +.. code-block:: python + + from dogpile.cache import region + + arguments = { + 'db_hosts': 'localhost:27017', + 'db_name': 'ks_cache', + 'cache_collection': 'cache', + 'username': 'test_user', + 'password': 'test_password', + + # optional arguments + 'son_manipulator': 'my_son_manipulator_impl' + } + + region.make_region().configure('keystone.cache.mongo', + arguments=arguments) + +The optional `son_manipulator` is used to manipulate custom data type while its saved in +or retrieved from MongoDB. If the dogpile cached values contain built-in data types and no +custom classes, then the provided implementation class is sufficient. For further details, refer +http://api.mongodb.org/python/current/examples/custom_type.html#automatic-encoding-and-decoding + +Similar to other backends, this backend can be added via Keystone configuration in +``keystone.conf``:: + + [cache] + # Global cache functionality toggle. + enabled = True + + # Referring to specific cache backend + backend = keystone.cache.mongo + + # Backend specific configuration arguments + backend_argument = db_hosts:localhost:27017 + backend_argument = db_name:ks_cache + backend_argument = cache_collection:cache + backend_argument = username:test_user + backend_argument = password:test_password + +This backend is registered in ``keystone.common.cache.core`` module. So, its usage +is similar to other dogpile caching backends as it implements the same dogpile APIs. + + +Building the Documentation +-------------------------- + +The documentation is generated with Sphinx using the tox command. To create HTML docs and man pages: + +.. code-block:: bash + + $ tox -e docs + +The results are in the docs/build/html and docs/build/man directories respectively. diff --git a/keystone-moon/doc/source/event_notifications.rst b/keystone-moon/doc/source/event_notifications.rst new file mode 100644 index 00000000..740986b1 --- /dev/null +++ b/keystone-moon/doc/source/event_notifications.rst @@ -0,0 +1,416 @@ + +.. + Copyright 2013 IBM Corp. + + 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. + +============================ +Keystone Event Notifications +============================ + +Keystone provides notifications about usage data so that 3rd party applications +can use the data for billing, monitoring, or quota purposes. This document +describes the current inclusions and exclusions for Keystone notifications. + +Keystone currently supports two notification formats: a Basic Notification, +and a Cloud Auditing Data Federation (`CADF`_) Notification. +The supported operations between the two types of notification formats are +documented below. + +Common Notification Structure +============================== + +Notifications generated by Keystone are generated in JSON format. An external +application can format them into ATOM format and publish them as a feed. +Currently, all notifications are immediate, meaning they are generated when a +specific event happens. Notifications all adhere to a specific top level +format: + +.. code-block:: javascript + + { + "event_type": "identity.<resource_type>.<operation>", + "message_id": "<message_id>", + "payload": {}, + "priority": "INFO", + "publisher_id": "identity.<hostname>", + "timestamp": "<timestamp>" + } + +Where ``<resource_type>`` is a Keystone resource, such as user or project, and +``<operation>`` is a Keystone operation, such as created, deleted. + +The key differences between the two notification formats (Basic and CADF), lie +within the ``payload`` portion of the notification. + +The ``priority`` of the notification being sent is not configurable through +the Keystone configuration file. This value is defaulted to INFO for all +notifications sent in Keystone's case. + +Basic Notifications +=================== + +All basic notifications contain a limited amount of information, specifically, +just the resource type, operation, and resource id. + +The ``payload`` portion of a Basic Notification is a single key-value pair. + +.. code-block:: javascript + + { + "resource_info": <resource_id> + } + +Where ``<resource_id>`` is the unique identifier assigned to the +``resource_type`` that is undergoing the ``<operation>``. + +Supported Events +---------------- + +The following table displays the compatibility between resource types and +operations. + +======================== ================================= +resource type supported operations +======================== ================================= +group create, update, delete +project create, update, delete +role create, update, delete +domain create, update, delete +user create, update, delete +trust create, delete +region create, update, delete +endpoint create, update, delete +service create, update, delete +policy create, update, delete +======================== ================================= + +Note, ``trusts`` are an immutable resource, they do not support ``update`` +operations. + +Example Notification +-------------------- + +This is an example of a notification sent for a newly created user: + +.. code-block:: javascript + + { + "event_type": "identity.user.created", + "message_id": "0156ee79-b35f-4cef-ac37-d4a85f231c69", + "payload": { + "resource_info": "671da331c47d4e29bb6ea1d270154ec3" + }, + "priority": "INFO", + "publisher_id": "identity.host1234", + "timestamp": "2013-08-29 19:03:45.960280" + } + +If the operation fails, the notification won't be sent, and no special error +notification will be sent. Information about the error is handled through +normal exception paths. + +Auditing with CADF +================== + +Keystone uses the `PyCADF`_ library to emit CADF notifications, these events +adhere to the DMTF `CADF`_ specification. This standard provides auditing +capabilities for compliance with security, operational, and business processes +and supports normalized and categorized event data for federation and +aggregation. + +.. _PyCADF: http://docs.openstack.org/developer/pycadf +.. _CADF: http://www.dmtf.org/standards/cadf + +CADF notifications include additional context data around the ``resource``, +the ``action`` and the ``initiator``. + +CADF notifications may be emitted by changing the ``notification_format`` to +``cadf`` in the configuration file. + +The ``payload`` portion of a CADF Notification is a CADF ``event``, which +is represented as a JSON dictionary. For example: + +.. code-block:: javascript + + { + "typeURI": "http://schemas.dmtf.org/cloud/audit/1.0/event", + "initiator": { + "typeURI": "service/security/account/user", + "host": { + "agent": "curl/7.22.0(x86_64-pc-linux-gnu)", + "address": "127.0.0.1" + }, + "id": "<initiator_id>" + }, + "target": { + "typeURI": "<target_uri>", + "id": "openstack:1c2fc591-facb-4479-a327-520dade1ea15" + }, + "observer": { + "typeURI": "service/security", + "id": "openstack:3d4a50a9-2b59-438b-bf19-c231f9c7625a" + }, + "eventType": "activity", + "eventTime": "2014-02-14T01:20:47.932842+00:00", + "action": "<action>", + "outcome": "success", + "id": "openstack:f5352d7b-bee6-4c22-8213-450e7b646e9f", + } + +Where the following are defined: + +* ``<initiator_id>``: ID of the user that performed the operation +* ``<target_uri>``: CADF specific target URI, (i.e.: data/security/project) +* ``<action>``: The action being performed, typically: + ``<operation>``. ``<resource_type>`` + +Additionally there may be extra keys present depending on the operation being +performed, these will be discussed below. + +Note, the ``eventType`` property of the CADF payload is different from the +``event_type`` property of a notifications. The former (``eventType``) is a +CADF keyword which designates the type of event that is being measured, this +can be: `activity`, `monitor` or `control`. Whereas the latter +(``event_type``) is described in previous sections as: +`identity.<resource_type>.<operation>` + +Supported Events +---------------- + +The following table displays the compatibility between resource types and +operations. + +====================== ============================= ============================= +resource type supported operations typeURI +====================== ============================= ============================= +group create, update, delete data/security/group +project create, update, delete data/security/project +role create, update, delete data/security/role +domain create, update, delete data/security/domain +user create, update, delete data/security/account/user +trust create, delete data/security/trust +region create, update, delete data/security/region +endpoint create, update, delete data/security/endpoint +service create, update, delete data/security/service +policy create, update, delete data/security/policy +role assignment add, remove data/security/account/user +None authenticate data/security/account/user +====================== ============================= ============================= + +Example Notification - Project Create +------------------------------------- + +The following is an example of a notification that is sent when a project is +created. This example can be applied for any ``create``, ``update`` or +``delete`` event that is seen in the table above. The ``<action>`` and +``typeURI`` fields will be change. + +The difference to note is the inclusion of the ``resource_info`` field which +contains the ``<resource_id>`` that is undergoing the operation. Thus creating +a common element between the CADF and Basic notification formats. + +.. code-block:: javascript + + { + "event_type": "identity.project.created", + "message_id": "0156ee79-b35f-4cef-ac37-d4a85f231c69", + "payload": { + "typeURI": "http://schemas.dmtf.org/cloud/audit/1.0/event", + "initiator": { + "typeURI": "service/security/account/user", + "host": { + "agent": "curl/7.22.0(x86_64-pc-linux-gnu)", + "address": "127.0.0.1" + }, + "id": "c9f76d3c31e142af9291de2935bde98a" + }, + "target": { + "typeURI": "data/security/project", + "id": "openstack:1c2fc591-facb-4479-a327-520dade1ea15" + }, + "observer": { + "typeURI": "service/security", + "id": "openstack:3d4a50a9-2b59-438b-bf19-c231f9c7625a" + }, + "eventType": "activity", + "eventTime": "2014-02-14T01:20:47.932842+00:00", + "action": "created.project", + "outcome": "success", + "id": "openstack:f5352d7b-bee6-4c22-8213-450e7b646e9f", + "resource_info": "671da331c47d4e29bb6ea1d270154ec3" + } + "priority": "INFO", + "publisher_id": "identity.host1234", + "timestamp": "2013-08-29 19:03:45.960280" + } + +Example Notification - Authentication +------------------------------------- + +The following is an example of a notification that is sent when a user +authenticates with Keystone. + +Note that this notification will be emitted if a user successfully +authenticates, and when a user fails to authenticate. + +.. code-block:: javascript + + { + "event_type": "identity.authenticate", + "message_id": "1371a590-d5fd-448f-b3bb-a14dead6f4cb", + "payload": { + "typeURI": "http://schemas.dmtf.org/cloud/audit/1.0/event", + "initiator": { + "typeURI": "service/security/account/user", + "host": { + "agent": "curl/7.22.0(x86_64-pc-linux-gnu)", + "address": "127.0.0.1" + }, + "id": "c9f76d3c31e142af9291de2935bde98a" + }, + "target": { + "typeURI": "service/security/account/user", + "id": "openstack:1c2fc591-facb-4479-a327-520dade1ea15" + }, + "observer": { + "typeURI": "service/security", + "id": "openstack:3d4a50a9-2b59-438b-bf19-c231f9c7625a" + }, + "eventType": "activity", + "eventTime": "2014-02-14T01:20:47.932842+00:00", + "action": "authenticate", + "outcome": "success", + "id": "openstack:f5352d7b-bee6-4c22-8213-450e7b646e9f" + }, + "priority": "INFO", + "publisher_id": "identity.host1234", + "timestamp": "2014-02-14T01:20:47.932842" + } + +Example Notification - Federated Authentication +----------------------------------------------- + +The following is an example of a notification that is sent when a user +authenticates with Keystone via Federation. + +This example is similar to the one seen above, however the ``initiator`` +portion of the ``payload`` contains a new ``credential`` section. + +.. code-block:: javascript + + { + "event_type": "identity.authenticate", + "message_id": "1371a590-d5fd-448f-b3bb-a14dead6f4cb", + "payload": { + "typeURI": "http://schemas.dmtf.org/cloud/audit/1.0/event", + "initiator": { + "credential": { + "type": "http://docs.oasis-open.org/security/saml/v2.0", + "token": "671da331c47d4e29bb6ea1d270154ec3", + "identity_provider": "ACME", + "user": "c9f76d3c31e142af9291de2935bde98a", + "groups": [ + "developers" + ] + }, + "typeURI": "service/security/account/user", + "host": { + "agent": "curl/7.22.0(x86_64-pc-linux-gnu)", + "address": "127.0.0.1" + }, + "id": "c9f76d3c31e142af9291de2935bde98a" + }, + "target": { + "typeURI": "service/security/account/user", + "id": "openstack:1c2fc591-facb-4479-a327-520dade1ea15" + }, + "observer": { + "typeURI": "service/security", + "id": "openstack:3d4a50a9-2b59-438b-bf19-c231f9c7625a" + }, + "eventType": "activity", + "eventTime": "2014-02-14T01:20:47.932842+00:00", + "action": "authenticate", + "outcome": "success", + "id": "openstack:f5352d7b-bee6-4c22-8213-450e7b646e9f" + }, + "priority": "INFO", + "publisher_id": "identity.host1234", + "timestamp": "2014-02-14T01:20:47.932842" + } + +Example Notification - Role Assignment +-------------------------------------- + +The following is an example of a notification that is sent when a role is +granted or revoked to a project or domain, for a user or group. + +It is important to note that this type of notification has many new keys +that convey the necessary information. Expect the following in the ``payload``: +``role``, ``inherited_to_project``, ``project`` or ``domain``, ``user`` or +``group``. With the exception of ``inherited_to_project``, each will represent +the unique identifier of the resource type. + +.. code-block:: javascript + + { + "event_type": "identity.created.role_assignment", + "message_id": "a5901371-d5fd-b3bb-448f-a14dead6f4cb", + "payload": { + "typeURI": "http://schemas.dmtf.org/cloud/audit/1.0/event", + "initiator": { + "typeURI": "service/security/account/user", + "host": { + "agent": "curl/7.22.0(x86_64-pc-linux-gnu)", + "address": "127.0.0.1" + }, + "id": "c9f76d3c31e142af9291de2935bde98a" + }, + "target": { + "typeURI": "service/security/account/user", + "id": "openstack:1c2fc591-facb-4479-a327-520dade1ea15" + }, + "observer": { + "typeURI": "service/security", + "id": "openstack:3d4a50a9-2b59-438b-bf19-c231f9c7625a" + }, + "eventType": "activity", + "eventTime": "2014-08-20T01:20:47.932842+00:00", + "role": "0e6b990380154a2599ce6b6e91548a68", + "project": "24bdcff1aab8474895dbaac509793de1", + "inherited_to_projects": false, + "group": "c1e22dc67cbd469ea0e33bf428fe597a", + "action": "created.role_assignment", + "outcome": "success", + "id": "openstack:f5352d7b-bee6-4c22-8213-450e7b646e9f" + }, + "priority": "INFO", + "publisher_id": "identity.host1234", + "timestamp": "2014-08-20T01:20:47.932842" + } + +Recommendations for consumers +============================= + +One of the most important notifications that Keystone emits is for project +deletions (``event_type`` = ``identity.project.deleted``). This event should +indicate to the rest of OpenStack that all resources (such as virtual machines) +associated with the project should be deleted. + +Projects can also have update events (``event_type`` = +``identity.project.updated``), wherein the project has been disabled. Keystone +ensures this has an immediate impact on the accessibility of the project's +resources by revoking tokens with authorization on the project, but should +**not** have a direct impact on the projects resources (in other words, virtual +machines should **not** be deleted). diff --git a/keystone-moon/doc/source/extension_development.rst b/keystone-moon/doc/source/extension_development.rst new file mode 100644 index 00000000..a0248495 --- /dev/null +++ b/keystone-moon/doc/source/extension_development.rst @@ -0,0 +1,303 @@ +.. + 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. + +===================================== +Keystone Extensions Development Guide +===================================== + +General +======= + +This Extension Development Guide provides some mocked code to use as an +Extension code base in the ``keystone/contrib/example`` folder. + +- All Extensions must be created in the ``keystone/contrib`` folder. +- The new Extension code must be contained in a new folder under ``contrib``. +- Whenever possible an Extension should follow the following directory + structure convention:: + + keystone/contrib/ + └── my_extension +   ├── backends (optional) +   │  ├── __init__.py (mandatory) +   │  └── sql.py (optional) +   │  └── kvs.py (optional) +   ├── migrate_repo (optional) +   │  ├── __init__.py (mandatory) +   │  ├── migrate.cfg (mandatory) +   │  └── versions (mandatory) + │    ├── 001_create_tables.py (mandatory) + │    └── __init__.py (mandatory) +   ├── __init__.py (mandatory) +   ├── core.py (mandatory) +   ├── controllers.py (mandatory for API Extension) +   └── routers.py (mandatory for API Extension) + +- If the Extension implements an API Extension the ``controllers.py`` and + ``routers.py`` must be present and correctly handle the API Extension + requests and responses. +- If the Extension implements backends a ``backends`` folder should exist. + Backends are defined to store data persistently and can use a variety of + technologies. Please see the Backends section in this document for more info. +- If the Extension adds data structures, then a ``migrate_repo`` folder should + exist. +- If configuration changes are required/introduced in the + ``keystone.conf.sample`` file, these should be kept disabled as default and + have their own section. +- If configuration changes are required/introduced in the + ``keystone-paste.ini``, the new filter must be declared. +- The module may register to listen to events by declaring the corresponding + callbacks in the ``core.py`` file. +- The new extension should be disabled by default (it should not affect the + default application pipelines). + +Modifying the `keystone.conf.sample` File +========================================= + +In the case an Extension needs to change the ``keystone.conf.sample`` file, it +must follow the config file conventions and introduce a dedicated section. + +Example:: + + [example] + driver = keystone.contrib.example.backends.sql.mySQLClass + + [my_other_extension] + extension_flag = False + +The Extension parameters expressed should be commented out since, by default, +extensions are disabled. + +Example:: + + [example] + #driver = keystone.contrib.example.backends.sql.mySQLClass + + [my_other_extension] + #extension_flag = False + +In case the Extension is overriding or re-implementing an existing portion of +Keystone, the required change should be commented in the ``configuration.rst`` +but not placed in the `keystone.conf.sample` file to avoid unnecessary +confusion. + +Modifying the ``keystone-paste.ini`` File +========================================= + +In the case an Extension is augmenting a pipeline introducing a new ``filter`` +and/or APIs in the ``OS`` namespace, a corresponding ``filter:`` section is +necessary to be introduced in the ``keystone-paste.ini`` file. The Extension +should declare the filter factory constructor in the ``ini`` file. + +Example:: + + [filter:example] + paste.filter_factory = keystone.contrib.example.routers:ExampleRouter. + factory + +The ``filter`` must not be placed in the ``pipeline`` and treated as optional. +How to add the extension in the pipeline should be specified in detail in the +``configuration.rst`` file. + +Package Constructor File +======================== + +The ``__init__.py`` file represents the package constructor. Extension needs to +import what is necessary from the ``core.py`` module. + +Example: + +.. code-block:: python + + from keystone.contrib.example.core import * + +Core +==== + +The ``core.py`` file represents the main module defining the data structure and +interface. In the ``Model View Control`` (MVC) model it represents the +``Model`` part and it delegates to the ``Backends`` the data layer +implementation. + +In case the ``core.py`` file contains a ``Manager`` and a ``Driver`` it must +provide the dependency injections for the ``Controllers`` and/or other modules +using the ``Manager``. A good practice is to call the dependency +``extension_name_api``. + +Example: + +.. code-block:: python + + @dependency.provider('example_api') + class Manager(manager.Manager): + +Routers +======= + +``routers.py`` have the objective of routing the HTTP requests and direct them to +the correct method within the ``Controllers``. Extension routers are extending +the ``wsgi.ExtensionRouter``. + +Example: + +.. code-block:: python + + from keystone.common import wsgi + from keystone.contrib.example import controllers + + + class ExampleRouter(wsgi.ExtensionRouter): + + PATH_PREFIX = '/OS-EXAMPLE' + + def add_routes(self, mapper): + example_controller = controllers.ExampleV3Controller() + mapper.connect(self.PATH_PREFIX + '/example', + controller=example_controller, + action='do_something', + conditions=dict(method=['GET'])) + +Controllers +=========== + +``controllers.py`` have the objective of handing requests and implement the +Extension logic. Controllers are consumers of 'Managers' API and must have all +the dependency injections required. ``Controllers`` are extending the +``V3Controller`` class. + +Example: + +.. code-block:: python + + @dependency.requires('identity_api', 'example_api') + class ExampleV3Controller(controller.V3Controller): + pass + +Backends +======== + +The ``backends`` folder provides the model implementations for the different +backends supported by the Extension. See General above for an example directory +structure. + +If a SQL backend is provided, in the ``sql.py`` backend implementation it is +mandatory to define the new table(s) that the Extension introduces and the +attributes they are composed of. + +For more information on backends, refer to the `Keystone Architecture +<http://docs.openstack.org/developer/keystone/architecture.html>`_ +documentation. + +Example: + +.. code-block:: python + + class ExampleSQLBackend(sql.ModelBase, sql.DictBase): + """example table description.""" + __tablename__ = 'example_table' + attributes = ['id', 'type', 'extra'] + + example_id = sql.Column(sql.String(64), + primary_key=True, + nullable=False) + ... + +SQL Migration Repository +======================== + +In case the Extension is adding SQL data structures, these must be stored in +separate tables and must not be included in the ``migrate_repo`` of the core +Keystone. Please refer to the ``migrate.cfg`` file to configure the Extension +repository. + +In order to create the Extension tables and their attributes, a ``db_sync`` +command must be executed. + +Example: + +.. code-block:: bash + + $ ./bin/keystone-manage db_sync --extension example + +Event Callbacks +--------------- + +Extensions may provide callbacks to Keystone (Identity) events. +Extensions must provide the list of events of interest and the corresponding +callbacks. Events are issued upon successful creation, modification, and +deletion of the following Keystone resources: + +- ``group`` +- ``project`` +- ``role`` +- ``user`` + +The extension's ``Manager`` class must contain the +``event_callbacks`` attribute. It is a dictionary listing as keys +those events that are of interest and the values should be the respective +callbacks. Event callback registration is done via the +dependency injection mechanism. During dependency provider registration, the +``dependency.provider`` decorator looks for the ``event_callbacks`` +class attribute. If it exists the event callbacks are registered +accordingly. In order to enable event callbacks, the extension's ``Manager`` +class must also be a dependency provider. + +Example: + +.. code-block:: python + + # Since this is a dependency provider. Any code module using this or any + # other dependency provider (uses the dependency.provider decorator) + # will be enabled for the attribute based notification + + @dependency.provider('example_api') + class ExampleManager(manager.Manager): + """Example Manager. + + See :mod:`keystone.common.manager.Manager` for more details on + how this dynamically calls the backend. + + """ + + def __init__(self): + self.event_callbacks = { + # Here we add the event_callbacks class attribute that + # calls project_deleted_callback when a project is deleted. + 'deleted': { + 'project': [ + self.project_deleted_callback]}} + super(ExampleManager, self).__init__( + 'keystone.contrib.example.core.ExampleDriver') + + def project_deleted_callback(self, context, message): + # cleanup data related to the deleted project here + +A callback must accept the following parameters: + +- ``service`` - the service information (e.g. identity) +- ``resource_type`` - the resource type (e.g. project) +- ``operation`` - the operation (updated, created, deleted) +- ``payload`` - the actual payload info of the resource that was acted on + +Current callback operations: + +- ``created`` +- ``deleted`` +- ``updated`` + +Example: + +.. code-block:: python + + def project_deleted_callback(self, service, resource_type, operation, + payload): diff --git a/keystone-moon/doc/source/extensions.rst b/keystone-moon/doc/source/extensions.rst new file mode 100644 index 00000000..f3bade9b --- /dev/null +++ b/keystone-moon/doc/source/extensions.rst @@ -0,0 +1,161 @@ +.. + 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. + +========== +Extensions +========== + +Status +====== + +An extension may be considered ``stable``, ``experimental`` or ``out-of-tree``. + +* A `stable` status indicates that an extension is fully supported by the + OpenStack Identity team. + +* An `experimental` status indicates that although the intention is to keep + the API unchanged, we reserve the right to change it up until the point that + it is deemed `stable`. + +* An `out-of-tree` status indicates that no formal support will be provided. + +Graduation Process +================== + +By default, major new functionality that is proposed to be in-tree will start +off in `experimental` status. Typically it would take at minimum of one cycle +to transition from `experimental` to `stable`, although in special cases this +might happened within a cycle. + +Removal Process +=============== + +It is not intended that functionality should stay in experimental for a long +period, functionality that stays `experimental` for more than **two** releases +would be expected to make a transition to either `stable` or `out-of-tree`. + +Current Extensions +================== + +------------------ +Endpoint Filtering +------------------ + +The Endpoint Filtering extension enables creation of ad-hoc catalogs for each +project-scoped token request. + +.. NOTE:: Support status for Endpoint Filtering + + *Experimental* (Icehouse, Juno) + *Stable* (Kilo) + +.. toctree:: + :maxdepth: 1 + + extensions/endpoint_filter.rst + +* `API Specification for Endpoint Filtering <http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3-os-ep-filter-ext.html>`__ + +--------------- +Endpoint Policy +--------------- + +The Endpoint Policy extension provides associations between service endpoints +and policies that are already stored in the Identity server and referenced by +a policy ID. + +.. NOTE:: Support status for Endpoint Policy + + *Experimental* (Juno) + *Stable* (Kilo) + +.. toctree:: + :maxdepth: 1 + + extensions/endpoint_policy.rst + +* `API Specification for Endpoint Policy <http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3-os-endpoint-policy.html>`__ + +---------- +Federation +---------- + +The Federation extension provides the ability for users to manage Identity +Providers (IdPs) and establish a set of rules to map federation protocol +attributes to Identity API attributes. + +.. NOTE:: Support status for Federation + + *Experimental* (Icehouse, Juno) + *Stable* (Kilo) + +.. toctree:: + :maxdepth: 1 + + extensions/federation.rst + +* `API Specification for Federation <http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3-os-federation-ext.html>`__ + +------- +Inherit +------- + +The Inherit extension provides the ability for projects to inherit role +assignments from their owning domain, or from projects higher in the +hierarchy. + +.. NOTE:: Support status for Inherit + + *Experimental* (Havava, Icehouse) + *Stable* (Juno) + +* `API Specification for Inherit <http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3-os-inherit-ext.html>`__ + +---------- +OAuth 1.0a +---------- + +The OAuth 1.0a extension provides the ability for Identity users to delegate +roles to third party consumers via the OAuth 1.0a specification. + +.. NOTE:: Support status for OAuth 1.0a + + *Experimental* (Havana, Icehouse) + *Stable* (Juno) + +.. toctree:: + :maxdepth: 1 + + extensions/oauth1.rst + +* `API Specification for OAuth 1.0a <http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3-os-oauth1-ext.html>`__ + +----------------- +Revocation Events +----------------- + +The Revocation Events extension provides a list of token revocations. Each +event expresses a set of criteria which describes a set of tokens that are +no longer valid. + +.. NOTE:: Support status for Revocation Events + + *Experimental* (Juno) + *Stable* (Kilo) + +.. toctree:: + :maxdepth: 1 + + extensions/revoke.rst + +* `API Specification for Revocation Events <http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3-os-revoke-ext.html>`__ diff --git a/keystone-moon/doc/source/extensions/endpoint_filter.rst b/keystone-moon/doc/source/extensions/endpoint_filter.rst new file mode 100644 index 00000000..66198503 --- /dev/null +++ b/keystone-moon/doc/source/extensions/endpoint_filter.rst @@ -0,0 +1,44 @@ +.. + Copyright 2011-2013 OpenStack, Foundation + 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. + +====================================== +Enabling the Endpoint Filter Extension +====================================== + +To enable the endpoint filter extension: + +1. Add the endpoint filter extension catalog driver to the ``[catalog]`` section + in ``keystone.conf``. For example:: + + [catalog] + driver = keystone.contrib.endpoint_filter.backends.catalog_sql.EndpointFilterCatalog + +2. Add the ``endpoint_filter_extension`` filter to the ``api_v3`` pipeline in + ``keystone-paste.ini``. This must be added after ``json_body`` and before + the last entry in the pipeline. For example:: + + [pipeline:api_v3] + pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth json_body ec2_extension_v3 s3_extension simple_cert_extension revoke_extension endpoint_filter_extension service_v3 + +3. Create the endpoint filter extension tables if using the provided sql backend. For example:: + + ./bin/keystone-manage db_sync --extension endpoint_filter + +4. Optionally, change ``return_all_endpoints_if_no_filter`` the ``[endpoint_filter]`` section + in ``keystone.conf`` to return an empty catalog if no associations are made. For example:: + + [endpoint_filter] + return_all_endpoints_if_no_filter = False diff --git a/keystone-moon/doc/source/extensions/endpoint_policy.rst b/keystone-moon/doc/source/extensions/endpoint_policy.rst new file mode 100644 index 00000000..86ff2264 --- /dev/null +++ b/keystone-moon/doc/source/extensions/endpoint_policy.rst @@ -0,0 +1,35 @@ +.. + 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. + +====================================== +Enabling the Endpoint Policy Extension +====================================== + +To enable the endpoint policy extension: + +1. Optionally, add the endpoint policy extension driver to the + ``[endpoint_policy]`` section in ``keystone.conf``. For example:: + + [endpoint_policy] + driver = keystone.contrib.endpoint_policy.backends.sql.EndpointPolicy + +2. Add the ``endpoint_policy_extension`` policy to the ``api_v3`` pipeline in + ``keystone-paste.ini``. This must be added after ``json_body`` and before + the last entry in the pipeline. For example:: + + [pipeline:api_v3] + pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth json_body ec2_extension_v3 s3_extension simple_cert_extension revoke_extension service_v3 endpoint_policy_extension service_v3 + +3. Create the endpoint policy extension tables if using the provided SQL backend. For example:: + + ./bin/keystone-manage db_sync --extension endpoint_policy diff --git a/keystone-moon/doc/source/extensions/federation.rst b/keystone-moon/doc/source/extensions/federation.rst new file mode 100644 index 00000000..f1b5baa9 --- /dev/null +++ b/keystone-moon/doc/source/extensions/federation.rst @@ -0,0 +1,66 @@ +.. + Copyright 2014 OpenStack, Foundation + 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. + +================================== +Enabling the Federation Extension +================================== + +To enable the federation extension: + +1. Add the federation extension driver to the ``[federation]`` section in + ``keystone.conf``. For example:: + + [federation] + driver = keystone.contrib.federation.backends.sql.Federation + +2. Add the ``saml2`` and/or ``oidc`` authentication methods to the ``[auth]`` + section in ``keystone.conf``:: + + [auth] + methods = external,password,token,saml2,oidc + saml2 = keystone.auth.plugins.mapped.Mapped + oidc = keystone.auth.plugins.mapped.Mapped + +.. NOTE:: + The ``external`` method should be dropped to avoid any interference with + some Apache + Shibboleth SP setups, where a ``REMOTE_USER`` env variable is + always set, even as an empty value. + +3. Add the ``federation_extension`` middleware to the ``api_v3`` pipeline in + ``keystone-paste.ini``. This must be added after ``json_body`` and before + the last entry in the pipeline. For example:: + + [pipeline:api_v3] + pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth json_body ec2_extension_v3 s3_extension simple_cert_extension revoke_extension federation_extension service_v3 + +4. Create the federation extension tables if using the provided SQL backend. + For example:: + + ./bin/keystone-manage db_sync --extension federation + +5. As of the Juno release, multiple Keystone deployments can now be federated. + To do so, the `pysaml2 <https://pypi.python.org/pypi/pysaml2>`_ library is + required. Since OS-FEDERATION is an extension, ``pysaml2`` is not installed + by default, it must be installed manually. For example:: + + pip install --upgrade $(grep pysaml2 test-requirements.txt) + + Also, the `xmlsec1` command line tool is needed to sign the SAML assertions + generated by the Keystone Identity Provider: + + .. code-block:: bash + + $ apt-get install xmlsec1 diff --git a/keystone-moon/doc/source/extensions/moon.rst b/keystone-moon/doc/source/extensions/moon.rst new file mode 100644 index 00000000..fc862675 --- /dev/null +++ b/keystone-moon/doc/source/extensions/moon.rst @@ -0,0 +1,145 @@ +.. + Copyright 2015 Orange + 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. + +============ +Moon backend +============ + +Before doing anything, you must test your installation and check that your infrastructure is working. +For example, check that you can create new virtual machines with admin and demo login. + +Configuration +------------- + +Moon is a contribute backend so you have to enable it by modifying /etc/keystone/keystone-paste.ini, like this: + +.. code-block:: ini + + [filter:moon] + paste.filter_factory = keystone.contrib.moon.routers:Admin.factory + + ... + + [pipeline:public_api] + # The last item in this pipeline must be public_service or an equivalent + # application. It cannot be a filter. + pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth json_body ec2_extension user_crud_extension moon public_service + + [pipeline:admin_api] + # The last item in this pipeline must be admin_service or an equivalent + # application. It cannot be a filter. + pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth json_body ec2_extension s3_extension crud_extension moon admin_service + + [pipeline:api_v3] + # The last item in this pipeline must be service_v3 or an equivalent + # application. It cannot be a filter. + pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth json_body ec2_extension_v3 s3_extension simple_cert_extension revoke_extension moon service_v3 + + ... + +You must modify /etc/keystone/keystone.conf as you need (see at the end of the file) and copy the following directories: + +.. code-block:: sh + + cp -R /opt/stack/keystone/examples/moon/policies/ /etc/keystone/ + cp -R /opt/stack/keystone/examples/moon/super_extension/ /etc/keystone/ + +You can now update the Keystone database and create the directory for logs and restart the Keystone service: + +.. code-block:: sh + + cd /opt/stack/keystone + ./bin/keystone-manage db_sync --extension moon + sudo mkdir /var/log/moon/ + sudo chown vagrant /var/log/moon/ + sudo service apache2 restart + +You have to install our version of keystonemiddleware https://github.com/rebirthmonkey/keystonemiddleware : + +.. code-block:: sh + + cd + git clone https://github.com/rebirthmonkey/keystonemiddleware.git + cd keystonemiddleware + sudo python setup.py install + +At this time, the only method to configure Moon is to use the python-moonclient which is a console based client: + +.. code-block:: sh + + cd + git clone https://github.com/rebirthmonkey/moonclient.git + cd moonclient + sudo python setup.py install + +If afterwards, you have some problem restarting nova-api, try removing the package python-six: + +.. code-block:: sh + + sudo apt-get remove python-six + + +Nova must be configured to send request to Keystone, you have to modify /etc/nova/api-paste.ini : + +.. code-block:: ini + + ... + + [composite:openstack_compute_api_v2] + use = call:nova.api.auth:pipeline_factory + noauth = compute_req_id faultwrap sizelimit noauth ratelimit osapi_compute_app_v2 + noauth2 = compute_req_id faultwrap sizelimit noauth2 ratelimit osapi_compute_app_v2 + keystone = compute_req_id faultwrap sizelimit authtoken keystonecontext moon ratelimit osapi_compute_app_v2 + keystone_nolimit = compute_req_id faultwrap sizelimit authtoken keystonecontext moon osapi_compute_app_v2 + + [composite:openstack_compute_api_v21] + use = call:nova.api.auth:pipeline_factory_v21 + noauth = compute_req_id faultwrap sizelimit noauth osapi_compute_app_v21 + noauth2 = compute_req_id faultwrap sizelimit noauth2 osapi_compute_app_v21 + keystone = compute_req_id faultwrap sizelimit authtoken keystonecontext moon osapi_compute_app_v21 + + [composite:openstack_compute_api_v3] + use = call:nova.api.auth:pipeline_factory_v21 + noauth = request_id faultwrap sizelimit noauth_v3 osapi_compute_app_v3 + noauth2 = request_id faultwrap sizelimit noauth_v3 osapi_compute_app_v3 + keystone = request_id faultwrap sizelimit authtoken keystonecontext moon osapi_compute_app_v3 + + ... + + [filter:moon] + paste.filter_factory = keystonemiddleware.authz:filter_factory + +If Swift is also installed, you have to configured it, in /etc/swift/proxy-server.conf : + +.. code-block:: ini + + ... + + [pipeline:main] + pipeline = catch_errors gatekeeper healthcheck proxy-logging cache container_sync bulk tempurl ratelimit crossdomain authtoken keystoneauth tempauth formpost staticweb container-quotas account-quotas slo dlo proxy-logging moon proxy-server + + ... + + [filter:moon] + paste.filter_factory = keystonemiddleware.authz:filter_factory + +Nova and Swift must be restarted after that, depending on your configuration, you will have to use 'screen' (if using devstack) +or 'service' on those daemons : nova-api and swift-proxy + +Usage +----- + +TODO
\ No newline at end of file diff --git a/keystone-moon/doc/source/extensions/moon_api.rst b/keystone-moon/doc/source/extensions/moon_api.rst new file mode 100644 index 00000000..1f7ad10b --- /dev/null +++ b/keystone-moon/doc/source/extensions/moon_api.rst @@ -0,0 +1,628 @@ +Moon API +======== + +Here are Moon API with some examples of posted data and returned data. + +Intra-Extension API +------------------- + +Authz +~~~~~ + +* ``GET /OS-MOON/authz/{tenant_id}/{subject_id}/{object_id}/{action_id}`` + +.. code-block:: json + + return = { + "authz": "OK/KO/OutOfScope", + "tenant_id": "tenant_id", + "subject_id": "subject_id", + "object_id": "object_id", + "action_id": "action_id" + } + +Intra_Extension +~~~~~~~~~~~~~~~ + +* ``GET /OS-MOON/authz_policies`` + +.. code-block:: json + + return = { + "authz_policies": ["policy_name1", "policy_name2"] + } + +* ``GET /OS-MOON/intra_extensions`` + +.. code-block:: json + + return = { + "intra_extensions": ["ie_uuid1", "ie_uuid2"] + } + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}`` + +.. code-block:: json + + return = { + "intra_extensions": { + "id": "uuid1", + "description": "", + "tenant": "tenant_uuid", + "model": "", + "genre": "", + "authz": {}, + "admin": {} + } + } + +* ``POST /OS-MOON/intra_extensions`` + +.. code-block:: json + + post = { + "name" : "", + "policymodel": "", + "description": "" + } + return = { + "id": "uuid1", + "description": "", + "tenant": "tenant_uuid", + "model": "", + "genre": "", + "authz": {}, + "admin": {} + } + +* ``DELETE /OS-MOON/intra_extensions/{intra_extensions_id}`` + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/tenant`` + +.. code-block:: json + + return = { + "tenant": "tenant_id" + } + +* ``POST /OS-MOON/intra_extensions/{intra_extensions_id}/tenant`` + +.. code-block:: json + + post = { + "tenant_id": "tenant_id" + } + return = { + "tenant": "tenant_id" + } + +* ``DELETE /OS-MOON/intra_extensions/{intra_extensions_id}/tenant/{tenant_id}`` + +Perimeter +~~~~~~~~~ + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/subjects`` + +.. code-block:: json + + return = { + "subjects": ["sub_uuid1", "sub_uuid2"] + } + +* ``POST /OS-MOON/intra_extensions/{intra_extensions_id}/subjects`` + +.. code-block:: json + + post = { + "subject_id" : "" + } + return = { + "subjects": ["sub_uuid1", "sub_uuid2"] + } + +* ``DELETE /OS-MOON/intra_extensions/{intra_extensions_id}/subject/{subject_id}`` + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/objects`` + +.. code-block:: json + + return = { + "objects": ["obj_uuid1", "obj_uuid2"] + } + +* ``POST /OS-MOON/intra_extensions/{intra_extensions_id}/objects`` + +.. code-block:: json + + post = { + "object_id" : "" + } + return = { + "objects": ["obj_uuid1", "obj_uuid2"] + } + +* ``DELETE /OS-MOON/intra_extensions/{intra_extensions_id}/object/{object_id}`` + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/actions`` + +.. code-block:: json + + return = { + "actions": ["act_uuid1", "act_uuid2"] + } + +* ``POST /OS-MOON/intra_extensions/{intra_extensions_id}/actions`` + +.. code-block:: json + + post = { + "action_id" : "" + } + return = { + "actions": ["act_uuid1", "act_uuid2"] + } + +* ``DELETE /OS-MOON/intra_extensions/{intra_extensions_id}/actions/{action_id}`` + +Assignment +~~~~~~~~~~ + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/subject_assignments`` + +.. code-block:: json + + return = { + "subject_assignments": { + "subject_security_level":{ + "user1": ["low"], + "user2": ["medium"], + "user3": ["high"] + } + } + +* ``POST /OS-MOON/intra_extensions/{intra_extensions_id}/subject_assignments`` + +.. code-block:: json + + post = { + "subject_id" : "", + "subject_category_id" : "", + "subject_category_scope_id" : "" + } + return = { + "subject_assignments": { + "subject_security_level":{ + "user1": ["low"], + "user2": ["medium"], + "user3": ["high"] + } + } + +* ``DELETE /OS-MOON/intra_extensions/{intra_extensions_id}/subject_assignments/{subject_category}/{subject_id}/{subject_scope}`` + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/object_assignments`` + +.. code-block:: json + + return = { + "object_assignments": { + "object_security_level":{ + "vm1": ["low"], + "vm2": ["medium"], + "vm3": ["high"] + } + } + +* ``POST /OS-MOON/intra_extensions/{intra_extensions_id}/object_assignments`` + +.. code-block:: json + + post = { + "object_id" : "", + "object_category_id" : "", + "object_category_scope_id" : "" + } + return = { + "object_assignments": { + "object_security_level":{ + "vm1": ["low"], + "vm2": ["medium"], + "vm3": ["high"] + } + } + +* ``DELETE /OS-MOON/intra_extensions/{intra_extensions_id}/object_assignments/{object_category}/{object_id}/{object_scope}`` + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/action_assignments`` + +.. code-block:: json + + return = { + "action_assignments": { + "computing_action":{ + "pause": ["vm_admin"], + "unpause": ["vm_admin"], + "start": ["vm_admin"], + "stop": ["vm_admin"] + } + } + +* ``POST /OS-MOON/intra_extensions/{intra_extensions_id}/action_assignments`` + +.. code-block:: json + + post = { + "action_id" : "", + "action_category_id" : "", + "action_category_scope_id" : "" + } + return = { + "action_assignments": { + "computing_action":{ + "pause": ["vm_admin"], + "unpause": ["vm_admin"], + "start": ["vm_admin"], + "stop": ["vm_admin"] + } + } + +* ``DELETE /OS-MOON/intra_extensions/{intra_extensions_id}/action_assignments/{action_category}/{action_id}/{action_scope}`` + +Metadata +~~~~~~~~ + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/subject_categories`` + +.. code-block:: json + + return = { + "subject_categories": [ "subject_security_level" ] + } + +* ``POST /OS-MOON/intra_extensions/{intra_extensions_id}/subject_categories`` + +.. code-block:: json + + post = { + "subject_category_id" : "" + } + return = { + "subject_categories": [ "subject_security_level" ] + } + +* ``DELETE /OS-MOON/intra_extensions/{intra_extensions_id}/subject_categories/{subject_category_id}`` + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/object_categories`` + +.. code-block:: json + + return = { + "object_categories": [ "object_security_level" ] + } + +* ``POST /OS-MOON/intra_extensions/{intra_extensions_id}/object_categories`` + +.. code-block:: json + + post = { + "object_category_id" : "" + } + return = { + "object_categories": [ "object_security_level" ] + } + +* ``DELETE /OS-MOON/intra_extensions/{intra_extensions_id}/object_categories/{object_category_id}`` + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/action_categories`` + +.. code-block:: json + + return = { + "action_categories": [ "computing_action" ] + } + + +* ``POST /OS-MOON/intra_extensions/{intra_extensions_id}/action_categories`` + +.. code-block:: json + + post = { + "action_category_id" : "" + } + return = { + "action_categories": [ "computing_action" ] + } + +* ``DELETE /OS-MOON/intra_extensions/{intra_extensions_id}/action_categories/{action_category_id}`` + +Scope +~~~~~ + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/subject_category_scope`` + +.. code-block:: json + + return = { + "subject_security_level": [ "high", "medium", "low" ] + } + +* ``POST /OS-MOON/intra_extensions/{intra_extensions_id}/subject_category_scope`` + +.. code-block:: json + + post = { + "subject_category_id" : "", + "subject_category_scope_id" : "" + } + return = { + "subject_security_level": [ "high", "medium", "low" ] + } + +* ``DELETE /OS-MOON/intra_extensions/{intra_extensions_id}/subject_category_scope/{subject_category}/{subject_scope}`` + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/object_category_scope`` + +.. code-block:: json + + return = { + "object_security_level": [ "high", "medium", "low" ] + } + +* ``POST /OS-MOON/intra_extensions/{intra_extensions_id}/object_category_scope`` + +.. code-block:: json + + post = { + "object_category_id" : "", + "object_category_scope_id" : "" + } + return = { + "object_security_level": [ "high", "medium", "low" ] + } + +* ``DELETE /OS-MOON/intra_extensions/{intra_extensions_id}/object_category_scope/{object_category}/{object_scope}`` + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/action_category_scope`` + +.. code-block:: json + + return = { + "computing_action": [ "vm_admin", "vm_access" ] + } + +* ``POST /OS-MOON/intra_extensions/{intra_extensions_id}/action_category_scope`` + +.. code-block:: json + + post = { + "action_id" : "", + "action_category_id" : "", + "action_category_scope_id" : "" + } + return = { + "computing_action": [ "vm_admin", "vm_access" ] + } + +* ``DELETE /OS-MOON/intra_extensions/{intra_extensions_id}/action_category_scope/{action_category}/{action_scope}`` + +Metarule +~~~~~~~~ + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/aggregation_algorithms`` + +.. code-block:: json + + return = { + "aggregation_algorithms": [ "and_true_aggregation", "..."] + } + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/aggregation_algorithm`` + +.. code-block:: json + + return = { + "aggregation_algorithm": "and_true_aggregation" + } + +* ``POST /OS-MOON/intra_extensions/{intra_extensions_id}/aggregation_algorithm`` + +.. code-block:: json + + post = { + "aggregation": "and_true_aggregation" + } + return = { + "aggregation_algorithm": "and_true_aggregation" + } + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/sub_meta_rule`` + +.. code-block:: json + + return = { + "sub_meta_rule": { + "subject_categories": ["role"], + "action_categories": ["ie_action"], + "object_categories": ["id"], + "relation": "relation_super" + } + } + +* ``POST /OS-MOON/intra_extensions/{intra_extensions_id}/sub_meta_rule`` + +.. code-block:: json + + post = { + "relation_super": { + "subject_categories": ["role"], + "action_categories": ["ie_action"], + "object_categories": ["id"], + } + } + return = { + "sub_meta_rule": { + "subject_categories": ["role"], + "action_categories": ["ie_action"], + "object_categories": ["id"], + "relation": "relation_super" + } + } + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/sub_meta_rule_relations`` + +.. code-block:: json + + return = { + "sub_meta_rule_relations": ["relation_super", ] + } + +Rules +~~~~~ + +* ``GET /OS-MOON/intra_extensions/{intra_extensions_id}/sub_rules`` + +.. code-block:: json + + return = { + "sub_rules": { + "relation_super": [ + ["high", "vm_admin", "medium"], + ["high", "vm_admin", "low"], + ["medium", "vm_admin", "low"], + ["high", "vm_access", "high"], + ["high", "vm_access", "medium"], + ["high", "vm_access", "low"], + ["medium", "vm_access", "medium"], + ["medium", "vm_access", "low"], + ["low", "vm_access", "low"] + ] + } + } + +* ``POST /OS-MOON/intra_extensions/{intra_extensions_id}/sub_rules`` + +.. code-block:: json + + post = { + "rules": ["admin", "vm_admin", "servers"], + "relation": "relation_super" + } + +* ``DELETE /OS-MOON/intra_extensions/{intra_extensions_id}/sub_rules/{relation_name}/{rule}`` + + +Tenant mapping API +------------------ + +* ``GET /OS-MOON/tenants`` + +.. code-block:: json + + return = { + "tenant": { + "uuid1": { + "name": "tenant1", + "authz": "intra_extension_uuid1", + "admin": "intra_extension_uuid2" + }, + "uuid2": { + "name": "tenant2", + "authz": "intra_extension_uuid1", + "admin": "intra_extension_uuid2" + } + } + } + +* ``GET /OS-MOON/tenant/{tenant_uuid}`` + +.. code-block:: json + + return = { + "tenant": { + "uuid": { + "name": "tenant1", + "authz": "intra_extension_uuid1", + "admin": "intra_extension_uuid2" + } + } + } + +* ``POST /OS-MOON/tenant`` + +.. code-block:: json + + post = { + "id": "uuid", + "name": "tenant1", + "authz": "intra_extension_uuid1", + "admin": "intra_extension_uuid2" + } + return = { + "tenant": { + "uuid": { + "name": "tenant1", + "authz": "intra_extension_uuid1", + "admin": "intra_extension_uuid2" + } + } + } + +* ``DELETE /OS-MOON/tenant/{tenant_uuid}/{intra_extension_uuid}`` + +.. code-block:: json + + return = {} + +Logs API +-------- + +* ``GET /OS-MOON/logs`` + +InterExtension API +------------------ + +* ``GET /OS-MOON/inter_extensions`` + +.. code-block:: json + + return = { + "inter_extensions": ["ie_uuid1", "ie_uuid2"] + } + +* ``GET /OS-MOON/inter_extensions/{inter_extensions_id}`` + +.. code-block:: json + + return = { + "inter_extensions": { + "id": "uuid1", + "description": "", + "requesting_intra_extension_uuid": "uuid1", + "requested_intra_extension_uuid": "uuid2", + "genre": "trust_OR_coordinate", + "virtual_entity_uuid": "ve_uuid1" + } + } + +* ``POST /OS-MOON/inter_extensions`` + +.. code-block:: json + + post = { + "description": "", + "requesting_intra_extension_uuid": uuid1, + "requested_intra_extension_uuid": uuid2, + "genre": "trust_OR_coordinate", + "virtual_entity_uuid": "ve_uuid1" + } + return = { + "id": "uuid1", + "description": "", + "requesting_intra_extension_uuid": uuid1, + "requested_intra_extension_uuid": uuid2, + "genre": "trust_OR_coordinate", + "virtual_entity_uuid": "ve_uuid1" + } + +* ``DELETE /OS-MOON/inter_extensions/{inter_extensions_id}`` + diff --git a/keystone-moon/doc/source/extensions/oauth1.rst b/keystone-moon/doc/source/extensions/oauth1.rst new file mode 100644 index 00000000..c89ee126 --- /dev/null +++ b/keystone-moon/doc/source/extensions/oauth1.rst @@ -0,0 +1,50 @@ +.. + Copyright 2011-2013 OpenStack, Foundation + 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. + +============================= +Enabling the OAuth1 Extension +============================= + +To enable the OAuth1 extension: + +1. Optionally, add the oauth1 extension driver to the ``[oauth1]`` section in ``keystone.conf``. For example:: + + [oauth1] + driver = keystone.contrib.oauth1.backends.sql.OAuth1 + +2. Add the ``oauth1`` authentication method to the ``[auth]`` section in ``keystone.conf``:: + + [auth] + methods = external,password,token,oauth1 + oauth1 = keystone.auth.plugins.oauth1.OAuth + +3. Add the ``oauth1_extension`` filter to the ``api_v3`` pipeline in + ``keystone-paste.ini``. This must be added after ``json_body`` and before + the last entry in the pipeline. For example:: + + [pipeline:api_v3] + pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth json_body ec2_extension_v3 s3_extension simple_cert_extension revoke_extension oauth1_extension service_v3 + +4. Create the OAuth1 extension tables if using the provided SQL backend. For example:: + + ./bin/keystone-manage db_sync --extension oauth1 + +5. Optionally, if deploying under an HTTPD server (i.e. Apache), set the + `WSGIPassAuthorization` to allow the OAuth Authorization headers to + pass through `mod_wsgi`. For example, add the following to the Keystone + virtual host file:: + + WSGIPassAuthorization On diff --git a/keystone-moon/doc/source/extensions/openidc.rst b/keystone-moon/doc/source/extensions/openidc.rst new file mode 100644 index 00000000..f515309e --- /dev/null +++ b/keystone-moon/doc/source/extensions/openidc.rst @@ -0,0 +1,93 @@ +:orphan: + +.. + 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. + +==================== +Setup OpenID Connect +==================== + +Configuring mod_auth_openidc +============================ + +Federate Keystone (SP) and an external IdP using OpenID Connect (`mod_auth_openidc`_) + +.. _`mod_auth_openidc`: https://github.com/pingidentity/mod_auth_openidc + +To install `mod_auth_openidc` on Ubuntu, perform the following: + +.. code-block:: bash + + sudo apt-get install libapache2-mod-auth-openidc + +Note that this module is not available on Fedora/CentOS/Red Hat. + +In the keystone Apache site file, add the following as a top level option, to +load the `mod_auth_openidc` module: + +.. code-block:: xml + + LoadModule auth_openidc_module /usr/lib/apache2/modules/mod_auth_openidc.so + +Also within the same file, locate the virtual host entry and add the following +entries for OpenID Connect: + +.. code-block:: xml + + <VirtualHost *:5000> + + ... + + OIDCClaimPrefix "OIDC-" + OIDCResponseType "id_token" + OIDCScope "openid email profile" + OIDCProviderMetadataURL <url_of_provider_metadata> + OIDCClientID <openid_client_id> + OIDCClientSecret <openid_client_secret> + OIDCCryptoPassphrase openstack + OIDCRedirectURI http://localhost:5000/v3/OS-FEDERATION/identity_providers/<idp_id>/protocols/oidc/auth/redirect + + <LocationMatch /v3/OS-FEDERATION/identity_providers/.*?/protocols/oidc/auth> + AuthType openid-connect + Require valid-user + LogLevel debug + </LocationMatch> + </VirtualHost> + +Note an example of an `OIDCProviderMetadataURL` instance is: https://accounts.google.com/.well-known/openid-configuration +If not using `OIDCProviderMetadataURL`, then the following attributes +must be specified: `OIDCProviderIssuer`, `OIDCProviderAuthorizationEndpoint`, +`OIDCProviderTokenEndpoint`, `OIDCProviderTokenEndpointAuth`, +`OIDCProviderUserInfoEndpoint`, and `OIDCProviderJwksUri` + +Note, if using a mod_wsgi version less than 4.3.0, then the `OIDCClaimPrefix` +must be specified to have only alphanumerics or a dash ("-"). This is because +mod_wsgi blocks headers that do not fit this criteria. See http://modwsgi.readthedocs.org/en/latest/release-notes/version-4.3.0.html#bugs-fixed +for more details + +Once you are done, restart your Apache daemon: + +.. code-block:: bash + + $ service apache2 restart + +Tips +==== + +1. When creating a mapping, note that the 'remote' attributes will be prefixed, + with `HTTP_`, so for instance, if you set OIDCClaimPrefix to `OIDC-`, then a + typical remote value to check for is: `HTTP_OIDC_ISS`. + +2. Don't forget to add oidc as an [auth] plugin in keystone.conf, see `Step 2`_ + +.. _`Step 2`: federation.html
\ No newline at end of file diff --git a/keystone-moon/doc/source/extensions/revoke.rst b/keystone-moon/doc/source/extensions/revoke.rst new file mode 100644 index 00000000..e8a25ce9 --- /dev/null +++ b/keystone-moon/doc/source/extensions/revoke.rst @@ -0,0 +1,45 @@ + .. + 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. + +================================= +Enabling the Revocation Extension +================================= + +.. NOTE:: + + As of the Juno release, the example configuration files will have the + ``OS-REVOKE`` extension enabled by default, thus it is not necessary to + perform steps 1 and 2. + Also, for new installations, the revocation extension tables are already + migrated, thus it is not necessary to perform steps 3. + +1. Optionally, add the revoke extension driver to the ``[revoke]`` section + in ``keystone.conf``. For example:: + + [revoke] + driver = keystone.contrib.revoke.backends.sql.Revoke + +2. Add the required ``filter`` to the ``pipeline`` in ``keystone-paste.ini``. + This must be added after ``json_body`` and before the last entry in the + pipeline. For example:: + + [filter:revoke_extension] + paste.filter_factory = keystone.contrib.revoke.routers:RevokeExtension.factory + + [pipeline:api_v3] + pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth json_body ec2_extension_v3 s3_extension simple_cert_extension revoke_extension service_v3 + +3. Create the revocation extension tables if using the provided SQL backend. + For example:: + + ./bin/keystone-manage db_sync --extension revoke diff --git a/keystone-moon/doc/source/extensions/shibboleth.rst b/keystone-moon/doc/source/extensions/shibboleth.rst new file mode 100644 index 00000000..d67cfa1a --- /dev/null +++ b/keystone-moon/doc/source/extensions/shibboleth.rst @@ -0,0 +1,279 @@ +:orphan: + +.. + 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. + +================ +Setup Shibboleth +================ + +Configure Apache HTTPD for mod_shibboleth +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Follow the steps outlined at: `Running Keystone in HTTPD`_. + +.. _`Running Keystone in HTTPD`: ../apache-httpd.html + +You'll also need to install `Shibboleth <https://wiki.shibboleth.net/confluence/display/SHIB2/Home>`_, for +example: + +.. code-block:: bash + + $ apt-get install libapache2-mod-shib2 + +Configure your Keystone virtual host and adjust the config to properly handle SAML2 workflow: + +Add *WSGIScriptAlias* directive to your vhost configuration:: + + WSGIScriptAliasMatch ^(/v3/OS-FEDERATION/identity_providers/.*?/protocols/.*?/auth)$ /var/www/keystone/main/$1 + +Make sure the *wsgi-keystone.conf* contains a *<Location>* directive for the Shibboleth module and +a *<Location>* directive for each identity provider:: + + <Location /Shibboleth.sso> + SetHandler shib + </Location> + + <Location /v3/OS-FEDERATION/identity_providers/idp_1/protocols/saml2/auth> + ShibRequestSetting requireSession 1 + ShibRequestSetting applicationId idp_1 + AuthType shibboleth + ShibRequireAll On + ShibRequireSession On + ShibExportAssertion Off + Require valid-user + </Location> + +.. NOTE:: + * ``saml2`` may be different in your deployment, but do not use a wildcard value. + Otherwise *every* federated protocol will be handled by Shibboleth. + * ``idp_1`` has to be replaced with the name associated with the idp in Keystone. + The same name is used inside the shibboleth2.xml configuration file but they could + be different. + * The ``ShibRequireSession`` and ``ShibRequireAll`` rules are invalid in + Apache 2.4+ and should be dropped in that specific setup. + * You are advised to carefully examine `Shibboleth Apache configuration + documentation + <https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPApacheConfig>`_ + +Enable the Keystone virtual host, for example: + +.. code-block:: bash + + $ a2ensite wsgi-keystone.conf + +Enable the ``ssl`` and ``shib2`` modules, for example: + +.. code-block:: bash + + $ a2enmod ssl + $ a2enmod shib2 + +Restart Apache, for example: + +.. code-block:: bash + + $ service apache2 restart + +Configuring shibboleth2.xml +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once you have your Keystone vhost (virtual host) ready, it's then time to +configure Shibboleth and upload your Metadata to the Identity Provider. + +If new certificates are required, they can be easily created by executing: + +.. code-block:: bash + + $ shib-keygen -y <number of years> + +The newly created file will be stored under ``/etc/shibboleth/sp-key.pem`` + +You should fetch your Service Provider's Metadata file. Typically this can be +achieved by simply fetching a Metadata file, for example: + +.. code-block:: bash + + $ wget --no-check-certificate -O <name of the file> https://service.example.org/Shibboleth.sso/Metadata + +Upload your Service Provider's Metadata file to your Identity Provider. +This step depends on your Identity Provider choice and is not covered here. + +Configure your Service Provider by editing ``/etc/shibboleth/shibboleth2.xml`` +file. You are advised to examine `Shibboleth Service Provider Configuration documentation <https://wiki.shibboleth.net/confluence/display/SHIB2/Configuration>`_ + +An example of your ``/etc/shibboleth/shibboleth2.xml`` may look like +(The example shown below is for reference only, not to be used in a production +environment): + +.. code-block:: xml + + <!-- + File configuration courtesy of http://testshib.org + + More information: + https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPConfiguration + --> + + <SPConfig xmlns="urn:mace:shibboleth:2.0:native:sp:config" + xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" clockSkew="1800 "> + + <!-- The entityID is the name TestShib made for your SP. --> + <ApplicationDefaults entityID="https://<yourhosthere>/shibboleth"> + + <!-- + You should use secure cookies if at all possible. + See cookieProps in this Wiki article. + --> + <!-- https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPSessions --> + <Sessions lifetime="28800" timeout="3600" checkAddress="false" + relayState="ss:mem" handlerSSL="false"> + + <!-- Triggers a login request directly to the TestShib IdP. --> + <!-- https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPServiceSSO --> + <SSO entityID="https://<idp-url>/idp/shibboleth" ECP="true"> + SAML2 SAML1 + </SSO> + + <!-- SAML and local-only logout. --> + <!-- https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPServiceLogout --> + <Logout>SAML2 Local</Logout> + + <!-- + Handlers allow you to interact with the SP and gather + more information. Try them out! + Attribute value s received by the SP through SAML + will be visible at: + http://<yourhosthere>/Shibboleth.sso/Session + --> + + <!-- + Extension service that generates "approximate" metadata + based on SP configuration. + --> + <Handler type="MetadataGenerator" Location="/Metadata" + signing="false"/> + + <!-- Status reporting service. --> + <Handler type="Status" Location="/Status" + acl="127.0.0.1"/> + + <!-- Session diagnostic service. --> + <Handler type="Session" Location="/Session" + showAttributeValues="true"/> + <!-- JSON feed of discovery information. --> + <Handler type="DiscoveryFeed" Location="/DiscoFeed"/> + </Sessions> + + <!-- + Error pages to display to yourself if + something goes horribly wrong. + --> + <Errors supportContact ="<admin_email_address>" + logoLocation="/shibboleth-sp/logo.jpg" + styleSheet="/shibboleth-sp/main.css"/> + + <!-- + Loads and trusts a metadata file that describes only one IdP + and how to communicate with it. + --> + <MetadataProvider type="XML" uri="<idp-metadata-file>" + backingFilePath="<local idp metadata>" + reloadInterval="180000" /> + + <!-- Attribute and trust options you shouldn't need to change. --> + <AttributeExtractor type="XML" validate="true" + path="attribute-map.xml"/> + <AttributeResolver type="Query" subjectMatch="true"/> + <AttributeFilter type="XML" validate="true" + path="attribute-policy.xml"/> + + <!-- + Your SP generated these credentials. + They're used to talk to IdP's. + --> + <CredentialResolver type="File" key="sp-key.pem" + certificate="sp-cert.pem"/> + + <ApplicationOverride id="idp_1" entityID="https://<yourhosthere>/shibboleth"> + <Sessions lifetime="28800" timeout="3600" checkAddress="false" + relayState="ss:mem" handlerSSL="false"> + + <!-- Triggers a login request directly to the TestShib IdP. --> + <SSO entityID="https://<idp_1-url>/idp/shibboleth" ECP="true"> + SAML2 SAML1 + </SSO> + + <Logout>SAML2 Local</Logout> + </Sessions> + + <MetadataProvider type="XML" uri="<idp_1-metadata-file>" + backingFilePath="<local idp_1 metadata>" + reloadInterval="180000" /> + + </ApplicationOverride> + + <ApplicationOverride id="idp_2" entityID="https://<yourhosthere>/shibboleth"> + <Sessions lifetime="28800" timeout="3600" checkAddress="false" + relayState="ss:mem" handlerSSL="false"> + + <!-- Triggers a login request directly to the TestShib IdP. --> + <SSO entityID="https://<idp_2-url>/idp/shibboleth" ECP="true"> + SAML2 SAML1 + </SSO> + + <Logout>SAML2 Local</Logout> + </Sessions> + + <MetadataProvider type="XML" uri="<idp_2-metadata-file>" + backingFilePath="<local idp_2 metadata>" + reloadInterval="180000" /> + + </ApplicationOverride> + + </ApplicationDefaults> + + <!-- + Security policies you shouldn't change unless you + know what you're doing. + --> + <SecurityPolicyProvider type="XML" validate="true" + path="security-policy.xml"/> + + <!-- + Low-level configuration about protocols and bindings + available for use. + --> + <ProtocolProvider type="XML" validate="true" reloadChanges="false" + path="protocols.xml"/> + + </SPConfig> + +Keystone enforces `external authentication`_ when the ``REMOTE_USER`` +environment variable is present so make sure Shibboleth doesn't set the +``REMOTE_USER`` environment variable. To do so, scan through the +``/etc/shibboleth/shibboleth2.xml`` configuration file and remove the +``REMOTE_USER`` directives. + +Examine your attributes map file ``/etc/shibboleth/attributes-map.xml`` and adjust +your requirements if needed. For more information see +`attributes documentation <https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPAddAttribute>`_ + +Once you are done, restart your Shibboleth daemon: + +.. _`external authentication`: ../external-auth.html + +.. code-block:: bash + + $ service shibd restart + $ service apache2 restart diff --git a/keystone-moon/doc/source/external-auth.rst b/keystone-moon/doc/source/external-auth.rst new file mode 100644 index 00000000..5f3c9af8 --- /dev/null +++ b/keystone-moon/doc/source/external-auth.rst @@ -0,0 +1,155 @@ +=========================================== +Using external authentication with Keystone +=========================================== +.. _external-auth: + +When Keystone is executed in a web server like :doc:`Apache HTTPD +<apache-httpd>` it is possible to use external authentication methods different +from the authentication provided by the identity store backend or the different +authentication plugins. For example, this makes possible to use an SQL identity +backend together with, X.509 authentication or Kerberos, for example, instead +of using the username and password combination. + +When a web server is in charge of authentication, it is normally possible to +set the ``REMOTE_USER`` environment variable so that it can be used in the +underlying application. Keystone can be configured to use that environment +variable if set, so that the authentication is handled by the web server. + +Configuration +============= + +In Identity API v2, there is no way to disable external authentication. In +order to activate the external authentication mechanism for Identity API v3, +the ``external`` method must be in the list of enabled authentication methods. +By default it is enabled, so if you don't want to use external authentication, +remove it from the ``methods`` option in the ``auth`` section. + +To configure the plugin that should be used set the ``external`` option again +in the ``auth`` section. There are two external authentication method plugins +provided by Keystone: + +* ``keystone.auth.plugins.external.Default``: This plugin won't take into + account the domain information that the external authentication method may + pass down to Keystone and will always use the configured default domain. The + ``REMOTE_USER`` variable is the username. + +* ``keystone.auth.plugins.external.Domain``: This plugin expects that the + ``REMOTE_DOMAIN`` variable contains the domain for the user. If this variable + is not present, the configured default domain will be used. The + ``REMOTE_USER`` variable is the username. + +Using HTTPD authentication +========================== + +Web servers like Apache HTTP support many methods of authentication. Keystone +can profit from this feature and let the authentication be done in the web +server, that will pass down the authenticated user to Keystone using the +``REMOTE_USER`` environment variable. This user must exist in advance in the +identity backend to get a token from the controller. + +To use this method, Keystone should be running on :doc:`HTTPD <apache-httpd>`. + +X.509 example +------------- + +The following snippet for the Apache conf will authenticate the user based on +a valid X.509 certificate from a known CA:: + + <VirtualHost _default_:5000> + SSLEngine on + SSLCertificateFile /etc/ssl/certs/ssl.cert + SSLCertificateKeyFile /etc/ssl/private/ssl.key + + SSLCACertificatePath /etc/ssl/allowed_cas + SSLCARevocationPath /etc/ssl/allowed_cas + SSLUserName SSL_CLIENT_S_DN_CN + SSLVerifyClient require + SSLVerifyDepth 10 + + (...) + </VirtualHost> + +Developing a WSGI middleware for authentication +=============================================== + +In addition to the method described above, it is possible to implement other +custom authentication mechanisms using the ``REMOTE_USER`` WSGI environment +variable. + +.. ATTENTION:: + + Please note that even if it is possible to develop a custom authentication + module, it is preferable to use the modules in the HTTPD server. Such + authentication modules in webservers like Apache have normally undergone + years of development and use in production systems and are actively + maintained upstream. Developing a custom authentication module that + implements the same authentication as an existing Apache module likely + introduces a higher security risk. + +If you find you must implement a custom authentication mechanism, you will need +to develop a custom WSGI middleware pipeline component. This middleware should +set the environment variable ``REMOTE_USER`` to the authenticated username. +Keystone then will assume that the user has been already authenticated upstream +and will not try to authenticate it. However, as with HTTPD authentication, the +user must exist in advance in the identity backend so that a proper token can +be issued. + +Your code should set the ``REMOTE_USER`` if the user is properly authenticated, +following the semantics below: + +.. code-block:: python + + from keystone.common import wsgi + from keystone import exception + + class MyMiddlewareAuth(wsgi.Middleware): + def __init__(self, *args, **kwargs): + super(MyMiddlewareAuth, self).__init__(*args, **kwargs) + + def process_request(self, request): + if request.environ.get('REMOTE_USER', None) is not None: + # Assume that it is authenticated upstream + return self.application + + if not self.is_auth_applicable(request): + # Not applicable + return self.application + + username = self.do_auth(request) + if username is not None: + # User is authenticated + request.environ['REMOTE_USER'] = username + else: + # User is not authenticated, render exception + raise exception.Unauthorized("Invalid user") + + +Pipeline configuration +---------------------- + +Once you have your WSGI middleware component developed you have to add it to +your pipeline. The first step is to add the middleware to your configuration +file. Assuming that your middleware module is +``keystone.middleware.MyMiddlewareAuth``, you can configure it in your +``keystone-paste.ini`` as:: + + [filter:my_auth] + paste.filter_factory = keystone.middleware.MyMiddlewareAuth.factory + +The second step is to add your middleware to the pipeline. The exact place +where you should place it will depend on your code (i.e. if you need for +example that the request body is converted from JSON before perform the +authentication you should place it after the ``json_body`` filter) but it +should be set before the ``public_service`` (for the ``public_api`` pipeline) +or ``admin_service`` (for the ``admin_api`` pipeline), since they consume +authentication. + +For example, if the original pipeline looks like this:: + + [pipeline:public_api] + pipeline = url_normalize token_auth admin_token_auth json_body debug ec2_extension user_crud_extension public_service + +Your modified pipeline might then look like this:: + + [pipeline:public_api] + pipeline = url_normalize token_auth admin_token_auth json_body my_auth debug ec2_extension user_crud_extension public_service diff --git a/keystone-moon/doc/source/http-api.rst b/keystone-moon/doc/source/http-api.rst new file mode 100644 index 00000000..a104ce3f --- /dev/null +++ b/keystone-moon/doc/source/http-api.rst @@ -0,0 +1,227 @@ +.. + 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. + +======== +HTTP API +======== + +Specifications +============== + +Keystone implements two major HTTP API versions, along with several API +extensions that build on top of each core API. The two APIs are specified as +`Identity API v2.0`_ and `Identity API v3`_. Each API is specified by a single +source of truth to avoid conflicts between documentation and implementation. +The original source of truth for the v2.0 API is defined by a set of WADL and +XSD files. The original source of truth for the v3 API is defined by +documentation. + +.. _`Identity API v2.0`: https://github.com/openstack/identity-api/tree/master/v2.0/src +.. _`Identity API v3`: https://github.com/openstack/identity-api/tree/master/v3/src/markdown + +History +======= + +You're probably wondering why Keystone does not implement a "v1" API. As a +matter of fact, one exists, but it actually predates OpenStack. The v1.x API +was an extremely small API documented and implemented by Rackspace for their +early public cloud products. + +With the advent of OpenStack, Keystone served to provide a superset of the +authentication and multi-tenant authorization models already implemented by +Rackspace's public cloud, Nova, and Swift. Thus, Identity API v2.0 was +introduced. + +Identity API v3 was established to introduce namespacing for users and projects +by using "domains" as a higher-level container for more flexible identity +management and fixed a security issue in the v2.0 API (bearer tokens appearing +in URLs). + +Should I use v2.0 or v3? +======================== + +Identity API v3. + +Identity API v3 is a superset of all the functionality available in v2.0 and +several of its extensions, and provides a much more consistent developer +experience to boot. We're also on the road to deprecating, and ultimately +reducing (or dropping) support for, Identity API v2.0. + +How do I migrate from v2.0 to v3? +================================= + +I am a deployer +--------------- + +You'll need to ensure the v3 API is included in your Paste pipeline, usually +``etc/keystone-paste.ini``. Our `latest sample configuration`_ includes the v3 +application pipeline. + +First define a v3 application, which refers to the v3 application factory +method: + +.. code-block:: ini + + [app:service_v3] + paste.app_factory = keystone.service:v3_app_factory + +Then define a v3 pipeline, which terminates with the v3 application you defined +above: + +.. code-block:: ini + + [app:app_v3] + pipeline = ... service_v3 + +Replace "..." with whatever middleware you'd like to run in front of the API +service. Our `latest sample configuration`_ documents our tested +recommendations, but your requirements may vary. + +Finally, include the v3 pipeline in at least one ``composite`` application (but +usually both ``[composite:main]`` and ``[composite:admin]``), for example: + +.. code-block:: ini + + [composite:main] + use = egg:Paste#urlmap + /v3 = api_v3 + ... + +Once your pipeline is configured to expose both v2.0 and v3, you need to ensure +that you've configured your service catalog in Keystone correctly. The +simplest, and most ideal, configuration would expose one identity with +unversioned endpoints (note the lack of ``/v2.0/`` or ``/v3/`` in these URLs): + +- Service (type: ``identity``) + + - Endpoint (interface: ``public``, URL: ``http://identity:5000/``) + - Endpoint (interface: ``admin``, URL: ``http://identity:35357/``) + +If you were to perform a ``GET`` against either of these endpoints, you would +be greeted by an ``HTTP/1.1 300 Multiple Choices`` response, which newer +Keystone clients can use to automatically detect available API versions. + +.. code-block:: bash + + $ curl -i http://identity:35357/ + HTTP/1.1 300 Multiple Choices + Vary: X-Auth-Token + Content-Type: application/json + Content-Length: 755 + Date: Tue, 10 Jun 2014 14:22:26 GMT + + {"versions": {"values": [ ... ]}} + +With unversioned ``identity`` endpoints in the service catalog, you should be +able to `authenticate with keystoneclient`_ successfully. + +.. _`latest sample configuration`: https://github.com/openstack/keystone/blob/master/etc/keystone-paste.ini +.. _`authenticate with keystoneclient`: http://docs.openstack.org/developer/python-keystoneclient/using-api-v3.html#authenticating + +I have a Python client +---------------------- + +The Keystone community provides first-class support for Python API consumers +via our client library, `python-keystoneclient`_. If you're not currently using +this library, you should, as it is intended to expose all of our HTTP API +functionality. If we're missing something you're looking for, please +contribute! + +Adopting `python-keystoneclient`_ should be the easiest way to migrate to +Identity API v3. + +.. _`python-keystoneclient`: https://pypi.python.org/pypi/python-keystoneclient/ + +I have a non-Python client +-------------------------- + +You'll likely need to heavily reference our `API documentation`_ to port your +application to Identity API v3. + +.. _`API documentation`: https://github.com/openstack/identity-api/blob/master/v3/src/markdown/identity-api-v3.md + +The most common operation would be password-based authentication including a +tenant name (i.e. project name) to specify an authorization scope. In Identity +API v2.0, this would be a request to ``POST /v2.0/tokens``: + +.. code-block:: javascript + + { + "auth": { + "passwordCredentials": { + "password": "my-password", + "username": "my-username" + }, + "tenantName": "project-x" + } + } + +And you would get back a JSON blob with an ``access`` -> ``token`` -> ``id`` +that you could pass to another web service as your ``X-Auth-Token`` header +value. + +In Identity API v3, an equivalent request would be to ``POST /v3/auth/tokens``: + +.. code-block:: javascript + + { + "auth": { + "identity": { + "methods": [ + "password" + ], + "password": { + "user": { + "domain": { + "id": "default" + }, + "name": "my-username", + "password": "my-password" + } + } + }, + "scope": { + "project": { + "domain": { + "id": "default" + }, + "name": "project-x" + } + } + } + } + +Note a few key differences when compared to the v2.0 API: + +- A "tenant" in v2.0 became a "project" in v3. +- The authentication method (``password``) is explicitly identified. +- Both the user name (``my-username``) and project name (``project-x``) are + namespaced by an owning domain (where ``id`` = ``default``). The "default" + domain exists by default in Keystone, and automatically owns the namespace + exposed by Identity API v2.0. Alternatively, you may reference users and + projects that exist outside the namespace of the default domain, which are + thus inaccessible to the v2.0 API. +- In v3, your token is returned to you in an ``X-Subject-Token`` header, + instead of as part of the request body. You should still authenticate + yourself to other services using the ``X-Auth-Token`` header. + + +HTTP/1.1 Chunked Encoding +========================= +.. WARNING:: + + Running Keystone under HTTPD in the recommended (and tested) configuration does not support + the use of ``Transfer-Encoding: chunked``. This is due to a limitation with the WSGI spec + and the implementation used by ``mod_wsgi``. Support for chunked encoding under ``eventlet`` + may or may not continue. It is recommended that all clients assume Keystone will not support + ``Transfer-Encoding: chunked``. diff --git a/keystone-moon/doc/source/index.rst b/keystone-moon/doc/source/index.rst new file mode 100644 index 00000000..48129a80 --- /dev/null +++ b/keystone-moon/doc/source/index.rst @@ -0,0 +1,97 @@ +.. + Copyright 2011-2012 OpenStack Foundation + 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. + +==================================================== +Welcome to Keystone, the OpenStack Identity Service! +==================================================== + +Keystone is an OpenStack project that provides Identity, Token, Catalog and +Policy services for use specifically by projects in the OpenStack family. +It implements `OpenStack's Identity API`_. + +This document describes Keystone for contributors of the project, and assumes +that you are already familiar with Keystone from an `end-user perspective`_. + +.. _`OpenStack's Identity API`: http://specs.openstack.org/openstack/keystone-specs/ +.. _`end-user perspective`: http://docs.openstack.org/ + +This documentation is generated by the Sphinx toolkit and lives in the source +tree. Also see the :doc:`community` page for other ways to interact with the +community. + +Related Identity Projects +========================= + +In addition to creating OpenStack's Identity Service, the Keystone team also +provides a `WSGI middleware`_, as well as `Python client library`_. + +.. _`WSGI middleware`: http://docs.openstack.org/developer/keystonemiddleware/ +.. _`Python client library`: http://docs.openstack.org/developer/python-keystoneclient/ + +Getting Started +=============== + +.. toctree:: + :maxdepth: 1 + + setup + installing + configuration + configure_federation + configuringservices + extensions + key_terms + community + +Man Pages +========= + +.. toctree:: + :maxdepth: 1 + + man/keystone-all + man/keystone-manage + +Developers Documentation +======================== +.. toctree:: + :maxdepth: 1 + + developing + architecture + middlewarearchitecture + http-api + api_curl_examples + cli_examples + apache-httpd + external-auth + event_notifications + extension_development + +Code Documentation +================== +.. toctree:: + :maxdepth: 1 + + api/modules + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/keystone-moon/doc/source/installing.rst b/keystone-moon/doc/source/installing.rst new file mode 100644 index 00000000..0492da7b --- /dev/null +++ b/keystone-moon/doc/source/installing.rst @@ -0,0 +1,125 @@ +.. + Copyright 2012 OpenStack Foundation + Copyright 2012 Nebula, Inc + 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. + +=================== +Installing Keystone +=================== + +This document describes how to install Keystone in order to use it. If you are +intending to develop on or with Keystone, please read :doc:`developing` and +:doc:`setup`. + +Installing from Source +---------------------- + +The source install instructions specifically avoid using platform specific +packages, instead using the source for the code and the Python Package Index +(PyPi_). + +.. _PyPi: http://pypi.python.org/pypi + +It's expected that your system already has python_, pip_, and git_ available. + +.. _python: http://www.python.org +.. _pip: http://www.pip-installer.org/en/latest/installing.html +.. _git: http://git-scm.com/ + +Clone the Keystone repository: + +.. code-block:: bash + + $ git clone http://github.com/openstack/keystone.git + $ cd keystone + +Install the Keystone web service: + +.. code-block:: bash + + $ python setup.py install + +You should have all the pieces you need to run Keystone installed on your +system. The following commands should be available on the command-line path: + +* ``keystone`` the Keystone client, used to interact with Keystone +* ``keystone-manage`` used to bootstrap Keystone data +* ``keystone-all`` used to run the Keystone services + +You will find sample configuration files in ``etc/``: + +* ``keystone.conf`` +* ``keystone-paste.ini`` +* ``logging.conf`` +* ``policy.json`` +* ``default_catalog.templates`` + +From here, refer to :doc:`configuration` to choose which backend drivers to +enable and use. Once configured, you should be able to run Keystone by issuing +the command: + +.. code-block:: bash + + $ keystone-all + +By default, this will show logging on the console from which it was started. +Once started, you can initialize data in Keystone for use with the rest of +OpenStack, as described in :doc:`configuringservices`. + +An excellent reference implementation of setting up Keystone is DEVSTACK_, +most commonly used for development and testing setup of not only Keystone, +but all of the core OpenStack projects. + +.. _DEVSTACK: http://devstack.org/ + +The script with the latest examples of initializing data in Keystone is a +bash script called keystone_data.sh_ + +.. _keystone_data.sh: https://github.com/openstack-dev/devstack/blob/master/files/keystone_data.sh + +Installing from packages: Ubuntu +-------------------------------- + +Ubuntu is providing packages for Keystone for Precise. To install keystone +on Ubuntu: + +.. code-block:: bash + + $ sudo apt-get install keystone + +In using Ubuntu's packages, the packages will set up a user account for +the Keystone service (`keystone`), and place default configurations in +``/etc/keystone``. The Debian installer will also ask you about configuration +options for setting up and running Keystone. As of this writing, the defaults +for Keystone backends are all SQL based, stored locally in a SQLite. + +Once installed, you still need to initialize data in Keystone, which you can +find described in :doc:`configuringservices`. + +Installing from packages: Fedora +-------------------------------- + +Installing Keystone with Fedora 17 is documented at +http://fedoraproject.org/wiki/Getting_started_with_OpenStack_on_Fedora_17. + +To install the packages: + +.. code-block:: bash + + $ sudo yum install --enablerepo=updates-testing openstack-keystone + +Once installed, you can configure Keystone based on the instructions at: + +http://fedoraproject.org/wiki/Getting_started_with_OpenStack_on_Fedora_17#Configuring_Keystone_for_authentication diff --git a/keystone-moon/doc/source/key_terms.rst b/keystone-moon/doc/source/key_terms.rst new file mode 100644 index 00000000..93aec532 --- /dev/null +++ b/keystone-moon/doc/source/key_terms.rst @@ -0,0 +1,185 @@ +========= +Key Terms +========= + +This document describes the different resource types that are available in +OpenStack's Identity Service. + +Identity +======== + +The Identity portion of keystone includes ``Users`` and ``Groups``, and may be +backed by SQL or more commonly LDAP. + +Users +----- + +``Users`` represent an individual API consumer. A user itself must be owned by +a specific domain, and hence all user names are **not** globally unique, but +only unique to their domain. + +Groups +------ + +``Groups`` are a container representing a collection of users. A group itself +must be owned by a specific domain, and hence all group names are **not** +globally unique, but only unique to their domain. + +Resources +========= + +The Identity portion of keystone includes ``Projects`` and ``Domains``, and +are commonly stored in an SQL backend. + +Projects (Tenants) +------------------ + +``Projects`` (known as Tenants in v2.0) represent the base unit of +``ownership`` in OpenStack, in that all resources in OpenStack should be owned +by a specific project. +A project itself must be owned by a specific domain, and hence all project +names are **not** globally unique, but unique to their domain. +If the domain for a project is not specified, then it is added to the default +domain. + +Domains +------- + +``Domains`` are a high-level container for projects, users and groups. Each is +owned by exactly one domain. Each domain defines a namespace where certain an +API-visible name attribute exists. keystone provides a default domain, aptly +named 'Default'. + +In the Identity v3 API, the uniqueness of attributes is as follows: + +- Domain Name. Globally unique across all domains. + +- Role Name. Globally unique across all domains. + +- User Name. Unique within the owning domain. + +- Project Name. Unique within the owning domain. + +- Group Name. Unique within the owning domain. + +Due to their container architecture, domains may be used as a way to delegate +management of OpenStack resources. A user in a domain may still access +resources in another domain, if an appropriate assignment is granted. + + +Assignment +========== + +Roles +----- + +``Roles`` dictate the level of authorization the end user can obtain. Roles +can be granted at either the domain or project level. Role can be assigned to +the individual user or at the group level. Role names are globally unique. + +Role Assignments +---------------- + +A 3-tuple that has a ``Role``, a ``Resource`` and an ``Identity``. + +What's needed to Authenticate? +============================== + +Two pieces of information are required to authenticate with keystone, a +bit of ``Resource`` information and a bit of ``Identity``. + +Take the following call POST data for instance: + +.. code-block:: javascript + + { + "auth": { + "identity": { + "methods": [ + "password" + ], + "password": { + "user": { + "id": "0ca8f6", + "password": "secretsecret" + } + } + }, + "scope": { + "project": { + "id": "263fd9" + } + } + } + } + +The user (ID of 0ca8f6) is attempting to retrieve a token that is scoped to +project (ID of 263fd9). + +To perform the same call with names instead of IDs, we now need to supply +information about the domain. This is because usernames are only unique within +a given domain, but user IDs are supposed to be unique across the deployment. +Thus, the auth request looks like the following: + +.. code-block:: javascript + + { + "auth": { + "identity": { + "methods": [ + "password" + ], + "password": { + "user": { + "domain": { + "name": "acme" + } + "name": "userA", + "password": "secretsecret" + } + } + }, + "scope": { + "project": { + "domain": { + "id": "1789d1" + }, + "name": "project-x" + } + } + } + } + +For both the user and the project portion, we must supply either a domain ID +or a domain name, in order to properly determine the correct user and project. + +Alternatively, if we wanted to represent this as environment variables for a +command line, it would be: + +.. code-block:: bash + + $ export OS_PROJECT_DOMAIN_ID=1789d1 + $ export OS_USER_DOMAIN_NAME=acme + $ export OS_USERNAME=userA + $ export OS_PASSWORD=secretsecret + $ export OS_PROJECT_NAME=project-x + +Note that the project the user it attempting to access must be in the same +domain as the user. + +What is Scope? +============== + +Scope is an overloaded term. + +In reference to authenticating, as seen above, scope refers to the portion +of the POST data that dictates what ``Resource`` (project or domain) the user +wants to access. + +In reference to tokens, scope refers to the effectiveness of a token, +i.e.: a `project-scoped` token is only useful on the project it was initially +granted for. A `domain-scoped` token may be used to perform domain-related +function. + +In reference to users, groups, and projects, scope often refers to the domain +that the entity is owned by. i.e.: a user in domain X is scoped to domain X. diff --git a/keystone-moon/doc/source/man/keystone-all.rst b/keystone-moon/doc/source/man/keystone-all.rst new file mode 100644 index 00000000..328b0c4e --- /dev/null +++ b/keystone-moon/doc/source/man/keystone-all.rst @@ -0,0 +1,112 @@ +============ +keystone-all +============ + +------------------------ +Keystone Startup Command +------------------------ + +:Author: openstack@lists.openstack.org +:Date: 2014-10-16 +:Copyright: OpenStack Foundation +:Version: 2014.2 +:Manual section: 1 +:Manual group: cloud computing + +SYNOPSIS +======== + +:: + + keystone-all [-h] [--config-dir DIR] [--config-file PATH] [--debug] + [--log-config-append PATH] [--log-date-format DATE_FORMAT] + [--log-dir LOG_DIR] [--log-file PATH] + [--log-format FORMAT] [--nodebug] [--nostandard-threads] + [--nouse-syslog] [--nouse-syslog-rfc-format] [--noverbose] + [--pydev-debug-host PYDEV_DEBUG_HOST] + [--pydev-debug-port PYDEV_DEBUG_PORT] [--standard-threads] + [--syslog-log-facility SYSLOG_LOG_FACILITY] [--use-syslog] + [--use-syslog-rfc-format] [--verbose] [--version] + +DESCRIPTION +=========== + +keystone-all starts both the service and administrative APIs in a single +process to provide catalog, authorization, and authentication services for +OpenStack. + +OPTIONS +======= + + -h, --help show this help message and exit + --config-dir DIR Path to a config directory to pull \*.conf files from. + This file set is sorted, so as to provide a + predictable parse order if individual options are + over-ridden. The set is parsed after the file(s) + specified via previous --config-file, arguments hence + over-ridden options in the directory take precedence. + --config-file PATH Path to a config file to use. Multiple config files + can be specified, with values in later files taking + precedence. The default files used are: None. + --debug, -d Print debugging output (set logging level to DEBUG + instead of default WARNING level). + --log-config-append PATH, --log_config PATH + The name of a logging configuration file. This file is + appended to any existing logging configuration files. + For details about logging configuration files, see the + Python logging module documentation. + --log-date-format DATE_FORMAT + Format string for %(asctime)s in log records. Default: + None . + --log-dir LOG_DIR, --logdir LOG_DIR + (Optional) The base directory used for relative --log- + file paths. + --log-file PATH, --logfile PATH + (Optional) Name of log file to output to. If no + default is set, logging will go to stdout. + --log-format FORMAT DEPRECATED. A logging.Formatter log message format + string which may use any of the available + logging.LogRecord attributes. This option is + deprecated. Please use logging_context_format_string + and logging_default_format_string instead. + --nodebug The inverse of --debug + --nostandard-threads The inverse of --standard-threads + --nouse-syslog The inverse of --use-syslog + --nouse-syslog-rfc-format + The inverse of --use-syslog-rfc-format + --noverbose The inverse of --verbose + --pydev-debug-host PYDEV_DEBUG_HOST + Host to connect to for remote debugger. + --pydev-debug-port PYDEV_DEBUG_PORT + Port to connect to for remote debugger. + --standard-threads Do not monkey-patch threading system modules. + --syslog-log-facility SYSLOG_LOG_FACILITY + Syslog facility to receive log lines. + --use-syslog Use syslog for logging. Existing syslog format is + DEPRECATED during I, and will change in J to honor + RFC5424. + --use-syslog-rfc-format + (Optional) Enables or disables syslog rfc5424 format + for logging. If enabled, prefixes the MSG part of the + syslog message with APP-NAME (RFC5424). The format + without the APP-NAME is deprecated in I, and will be + removed in J. + --verbose, -v Print more verbose output (set logging level to INFO + instead of default WARNING level). + --version show program's version number and exit + +FILES +===== + +None + +SEE ALSO +======== + +* `OpenStack Keystone <http://keystone.openstack.org>`__ + +SOURCE +====== + +* Keystone source is managed in GitHub `Keystone <http://github.com/openstack/keystone>`__ +* Keystone bugs are managed at Launchpad `Keystone <https://bugs.launchpad.net/keystone>`__ diff --git a/keystone-moon/doc/source/man/keystone-manage.rst b/keystone-moon/doc/source/man/keystone-manage.rst new file mode 100644 index 00000000..b2ea3924 --- /dev/null +++ b/keystone-moon/doc/source/man/keystone-manage.rst @@ -0,0 +1,125 @@ +=============== +keystone-manage +=============== + +--------------------------- +Keystone Management Utility +--------------------------- + +:Author: openstack@lists.openstack.org +:Date: 2014-10-16 +:Copyright: OpenStack Foundation +:Version: 2014.2 +:Manual section: 1 +:Manual group: cloud computing + +SYNOPSIS +======== + + keystone-manage [options] + +DESCRIPTION +=========== + +``keystone-manage`` is the command line tool which interacts with the Keystone +service to initialize and update data within Keystone. Generally, +``keystone-manage`` is only used for operations that cannot be accomplished +with the HTTP API, such data import/export and database migrations. + +USAGE +===== + + ``keystone-manage [options] action [additional args]`` + +General keystone-manage options: +-------------------------------- + +* ``--help`` : display verbose help output. + +Invoking ``keystone-manage`` by itself will give you some usage information. + +Available commands: + +* ``db_sync``: Sync the database. +* ``db_version``: Print the current migration version of the database. +* ``mapping_purge``: Purge the identity mapping table. +* ``pki_setup``: Initialize the certificates used to sign tokens. +* ``saml_idp_metadata``: Generate identity provider metadata. +* ``ssl_setup``: Generate certificates for SSL. +* ``token_flush``: Purge expired tokens. + +OPTIONS +======= + + -h, --help show this help message and exit + --config-dir DIR Path to a config directory to pull \*.conf files from. + This file set is sorted, so as to provide a + predictable parse order if individual options are + over-ridden. The set is parsed after the file(s) + specified via previous --config-file, arguments hence + over-ridden options in the directory take precedence. + --config-file PATH Path to a config file to use. Multiple config files + can be specified, with values in later files taking + precedence. The default files used are: None. + --debug, -d Print debugging output (set logging level to DEBUG + instead of default WARNING level). + --log-config-append PATH, --log_config PATH + The name of a logging configuration file. This file is + appended to any existing logging configuration files. + For details about logging configuration files, see the + Python logging module documentation. + --log-date-format DATE_FORMAT + Format string for %(asctime)s in log records. Default: + None . + --log-dir LOG_DIR, --logdir LOG_DIR + (Optional) The base directory used for relative --log- + file paths. + --log-file PATH, --logfile PATH + (Optional) Name of log file to output to. If no + default is set, logging will go to stdout. + --log-format FORMAT DEPRECATED. A logging.Formatter log message format + string which may use any of the available + logging.LogRecord attributes. This option is + deprecated. Please use logging_context_format_string + and logging_default_format_string instead. + --nodebug The inverse of --debug + --nostandard-threads The inverse of --standard-threads + --nouse-syslog The inverse of --use-syslog + --nouse-syslog-rfc-format + The inverse of --use-syslog-rfc-format + --noverbose The inverse of --verbose + --pydev-debug-host PYDEV_DEBUG_HOST + Host to connect to for remote debugger. + --pydev-debug-port PYDEV_DEBUG_PORT + Port to connect to for remote debugger. + --standard-threads Do not monkey-patch threading system modules. + --syslog-log-facility SYSLOG_LOG_FACILITY + Syslog facility to receive log lines. + --use-syslog Use syslog for logging. Existing syslog format is + DEPRECATED during I, and will change in J to honor + RFC5424. + --use-syslog-rfc-format + (Optional) Enables or disables syslog rfc5424 format + for logging. If enabled, prefixes the MSG part of the + syslog message with APP-NAME (RFC5424). The format + without the APP-NAME is deprecated in I, and will be + removed in J. + --verbose, -v Print more verbose output (set logging level to INFO + instead of default WARNING level). + --version show program's version number and exit + +FILES +===== + +None + +SEE ALSO +======== + +* `OpenStack Keystone <http://keystone.openstack.org>`__ + +SOURCE +====== + +* Keystone is sourced in GitHub `Keystone <http://github.com/openstack/keystone>`__ +* Keystone bugs are managed at Launchpad `Keystone <https://bugs.launchpad.net/keystone>`__ diff --git a/keystone-moon/doc/source/middlewarearchitecture.rst b/keystone-moon/doc/source/middlewarearchitecture.rst new file mode 100644 index 00000000..7b958510 --- /dev/null +++ b/keystone-moon/doc/source/middlewarearchitecture.rst @@ -0,0 +1,34 @@ +.. + Copyright 2011-2012 OpenStack Foundation + 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 mechanism, the OpenStack project can plug in +to existing authentication and authorization systems in use by existing +environments. + +The auth_token middleware is no longer hosted in Keystone and has moved to the +keystonemiddleware project. The `documentation regarding authentication +middleware`_ can be found there. + +.. _`documentation regarding authentication middleware`: http://docs.openstack.org/developer/keystonemiddleware/middlewarearchitecture.html diff --git a/keystone-moon/doc/source/setup.rst b/keystone-moon/doc/source/setup.rst new file mode 100644 index 00000000..f919dccc --- /dev/null +++ b/keystone-moon/doc/source/setup.rst @@ -0,0 +1,175 @@ +.. + Copyright 2011-2012 OpenStack Foundation + 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. + +============================================= +Setting up a Keystone development environment +============================================= + +This document describes getting the source from keystone's `GitHub repository`_ +for development purposes. + +To install Keystone from packaging, refer instead to Keystone's `User +Documentation`_. + +.. _`GitHub Repository`: http://github.com/openstack/keystone +.. _`User Documentation`: http://docs.openstack.org/ + +Prerequisites +============= + +This document assumes you are using: + +- Ubuntu, Fedora or openSUSE (SLE) +- `Python 2.7`_ + +.. _`Python 2.7`: http://www.python.org/ + +And that you have the following tools available on your system: + +- git_ +- setuptools_ +- pip_ +- msgfmt (part of the gettext package) +- virtualenv_ + +**Reminder**: If you're successfully using a different platform, or a +different version of the above, please document your configuration here! + +.. _git: http://git-scm.com/ +.. _setuptools: http://pypi.python.org/pypi/setuptools + +Getting the latest code +======================= + +Make a clone of the code from our `Github repository`: + +.. code-block:: bash + + $ git clone https://github.com/openstack/keystone.git + +When that is complete, you can: + +.. code-block:: bash + + $ cd keystone + +Installing dependencies +======================= + +Keystone maintains two lists of dependencies:: + + requirements.txt + test-requirements.txt + +The first is the list of dependencies needed for running keystone, the second list includes dependencies used for active development and testing of Keystone itself. + +These dependencies can be installed from PyPi_ using the Python tool pip_. + +.. _PyPi: http://pypi.python.org/ +.. _pip: http://pypi.python.org/pypi/pip + +However, your system *may* need additional dependencies that `pip` (and by +extension, PyPi) cannot satisfy. These dependencies should be installed +prior to using `pip`, and the installation method may vary depending on +your platform. + +Ubuntu 12.04: + +.. code-block:: bash + + $ sudo apt-get install python-dev libxml2-dev libxslt1-dev libsasl2-dev libsqlite3-dev libssl-dev libldap2-dev libffi-dev + + +Fedora 19+: + +.. code-block:: bash + + $ sudo yum install python-sqlite2 python-lxml python-greenlet-devel python-ldap sqlite-devel openldap-devel python-devel libxslt-devel openssl-devel + +openSUSE 13.2 (SLE 12): + +.. code-block:: bash + + $ sudo zypper install libxslt-devel openldap2-devel libopenssl-devel python-devel python-greenlet-devel python-ldap python-lxml python-pysqlite sqlite3-devel + +PyPi Packages and VirtualEnv +---------------------------- + +We recommend establishing a virtualenv to run Keystone within. virtualenv +limits the Python environment to just what you're installing as dependencies, +useful to keep a clean environment for working on Keystone. The tools directory +in Keystone has a script already created to make this very simple: + +.. code-block:: bash + + $ python tools/install_venv.py + +This will create a local virtual environment in the directory ``.venv``. +Once created, you can activate this virtualenv for your current shell using: + +.. code-block:: bash + + $ source .venv/bin/activate + +The virtual environment can be disabled using the command: + +.. code-block:: bash + + $ deactivate + +You can also use ``tools\with_venv.sh`` to prefix commands so that they run +within the virtual environment. For more information on virtual environments, +see virtualenv_. + +.. _virtualenv: http://www.virtualenv.org/ + +If you want to run Keystone outside of a virtualenv, you can install the +dependencies directly into your system from the requires files: + +.. code-block:: bash + + # Install the dependencies for running keystone + $ pip install -r requirements.txt + + # Install the dependencies for developing, testing, and running keystone + $ pip install -r test-requirements.txt + + # Use 'python setup.py' to link Keystone into Python's site-packages + $ python setup.py develop + + +Verifying Keystone is set up +============================ + +Once set up, either directly or within a virtualenv, you should be able to +invoke Python and import the libraries. If you're using a virtualenv, don't +forget to activate it: + +.. code-block:: bash + + $ source .venv/bin/activate + $ python + +You should then be able to `import keystone` from your Python shell +without issue: + +.. code-block:: python + + >>> import keystone + >>> + +If you can import Keystone successfully, you should be ready to move on to +:doc:`developing`. |