openstack-manuals/doc/admin-guide-cloud/ch_identity_mgmt.xml

321 lines
16 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="5.0"
xml:id="ch-identity-mgmt-config">
<title>Identity management</title>
<para>OpenStack Identity, code-named keystone, is the
default identity management system for OpenStack. After you
install Identity, you configure it through the
<filename>etc/keystone.conf</filename> configuration file and,
possibly, a separate logging configuration file. You initialize
data into Identity by using the
<command>keystone</command> command-line client.</para>
<section xml:id="keystone-admin-concepts">
<title>Identity concepts</title>
<xi:include
href="../common/section_keystone-concepts-user-management.xml"/>
<xi:include
href="../common/section_keystone-concepts-service-management.xml"/>
<xi:include
href="../common/section_keystone-concepts-group-management.xml"/>
<xi:include
href="../common/section_keystone-concepts-domain-management.xml"/>
</section>
<xi:include href="../common/section_keystone_certificates-for-pki.xml"/>
<xi:include href="../common/section_keystone-ssl-config.xml"/>
<xi:include href="../common/section_keystone-external-auth.xml"/>
<xi:include href="../common/section_keystone_config_ldap.xml"/>
<xi:include href="identity/section_keystone-token-binding.xml"/>
<xi:include href="identity/section_caching-layer.xml"/>
<section xml:id="user-crud">
<title>User CRUD</title>
<para>Identity provides a user CRUD filter that can
be added to the public_api pipeline. This user CRUD filter
enables users to use a HTTP PATCH to change their own password.
To enable this extension you should define a
<literal>user_crud_extension</literal> filter, insert it after
the <literal>*_body</literal> middleware and before the
<literal>public_service</literal> application in the
public_api WSGI pipeline in <filename>keystone.conf</filename>.
For example:</para>
<programlisting language="ini"><?db-font-size 75%?>[filter:user_crud_extension]
paste.filter_factory = keystone.contrib.user_crud:CrudExtension.factory
[pipeline:public_api]
pipeline = stats_monitoring url_normalize token_auth admin_token_auth xml_body json_body debug ec2_extension user_crud_extension public_service</programlisting>
<para>Each user can then change their own password with a HTTP PATCH:</para>
<screen><prompt>$</prompt> <userinput>curl -X PATCH http://localhost:5000/v2.0/OS-KSCRUD/users/<replaceable>USERID</replaceable> -H &quot;Content-type: application/json&quot; \
-H &quot;X_Auth_Token: <replaceable>AUTHTOKENID</replaceable>&quot; -d '{&quot;user&quot;: {&quot;password&quot;: &quot;ABCD&quot;, &quot;original_password&quot;: &quot;DCBA&quot;}}'</userinput></screen>
<para>In addition to changing their password, all current
tokens for the user are deleted (if the back end is KVS or SQL).</para>
<note><para>Only use a KVS back end for tokens when testing.</para></note>
</section>
<section xml:id="keystone-logging">
<title>Logging</title>
<para>You configure logging externally to the rest of Identity. The file specifying the logging configuration is in the
<literal>[DEFAULT]</literal> section of the
<filename>keystone.conf</filename> file under
<literal>log_config</literal>. To route logging through
syslog, set <literal>use_syslog=true</literal> option in the
<literal>[DEFAULT]</literal> section.</para>
<para>A sample logging file is available with the project in the
<filename>etc/logging.conf.sample</filename> directory. Like
other OpenStack projects, Identity uses the Python
logging module, which includes extensive configuration options
that let you define the output levels and formats.</para>
<para>Review the <filename>etc/keystone.conf</filename> sample
configuration files that are distributed with the Identity
Service. For example, each server application has its own
configuration file.</para>
<para>For services that have separate paste-deploy
<filename>.ini</filename> files, you can configure
<literal>auth_token</literal> middleware in the
<literal>[keystone_authtoken]</literal> section in the main
configuration file, such as <filename>nova.conf</filename>. For
example in Compute, you can remove the middleware parameters
from <filename>api-paste.ini</filename>, as follows:</para>
<programlisting language="ini"><?db-font-size 75%?>[filter:authtoken]
paste.filter_factory =
keystoneclient.middleware.auth_token:filter_factory</programlisting>
<para>Set these values in the <filename>nova.conf</filename>
file:</para>
<programlisting language="ini"><?db-font-size 75%?>[DEFAULT]
...
auth_strategy=keystone
[keystone_authtoken]
auth_host = 127.0.0.1
auth_port = 35357
auth_protocol = http
auth_uri = http://127.0.0.1:5000/
admin_user = admin
admin_password = SuperSekretPassword
admin_tenant_name = service</programlisting>
<note>
<para>Middleware parameters in paste config take priority. You
must remove them to use values in the
<literal>[keystone_authtoken]</literal> section.</para>
</note>
</section>
<section xml:id="monitoring">
<title>Monitoring</title>
<para>Identity provides some basic request and response
monitoring statistics out of the box.</para>
<para>Enable data collection by defining a
<literal>stats_monitoring</literal> filter and including it at
the beginning of any desired WSGI pipelines:</para>
<programlisting language="ini"><?db-font-size 75%?>[filter:stats_monitoring]
paste.filter_factory = keystone.contrib.stats:StatsMiddleware.factory
[pipeline:public_api]
pipeline = stats_monitoring [...] public_service</programlisting>
<para>Enable the reporting of collected data by defining a
<literal>stats_reporting</literal> filter and including it
near the end of your <literal>admin_api</literal> WSGI pipeline
(After <literal>*_body</literal> middleware and before
<literal>*_extension</literal> filters is recommended):</para>
<programlisting language="ini"><?db-font-size 75%?>[filter:stats_reporting]
paste.filter_factory = keystone.contrib.stats:StatsExtension.factory
[pipeline:admin_api]
pipeline = [...] json_body stats_reporting ec2_extension [...] admin_service</programlisting>
<para>Query the admin API for statistics using:</para>
<screen><prompt>$</prompt> <userinput>curl -H 'X-Auth-Token: ADMIN' http://localhost:35357/v2.0/OS-STATS/stats</userinput></screen>
<para>Reset collected data using:</para>
<screen><prompt>$</prompt> <userinput>curl -H 'X-Auth-Token: ADMIN' -X DELETE \
http://localhost:35357/v2.0/OS-STATS/stats</userinput></screen>
</section>
<section xml:id="running-keystone">
<title>Start the Identity services</title>
<para>To start the services for Identity, run the
following command:</para>
<screen><prompt>$</prompt> <userinput>keystone-all</userinput></screen>
<para>This command starts two wsgi.Server instances configured by
the <filename>keystone.conf</filename> file as described
previously. One of these wsgi servers is
<literal>admin</literal> (the administration API) and the
other is <literal>main</literal> (the primary/public API
interface). Both run in a single process.</para>
</section>
<section xml:id="example-usage">
<title>Example usage</title>
<para>The <literal>keystone</literal> client is set up to expect
commands in the general form of <literal>keystone</literal>
<literal>command</literal>
<literal>argument</literal>, followed by flag-like keyword
arguments to provide additional (often optional) information.
For example, the command <literal>user-list</literal> and
<literal>tenant-create</literal> can be invoked as
follows:</para>
<programlisting language="bash"><?db-font-size 65%?># Using token auth env variables
export OS_SERVICE_ENDPOINT=http://127.0.0.1:5000/v2.0/
export OS_SERVICE_TOKEN=secrete_token
keystone user-list
keystone tenant-create --name=demo
# Using token auth flags
keystone --os-token=secrete --os-endpoint=http://127.0.0.1:5000/v2.0/ user-list
keystone --os-token=secrete --os-endpoint=http://127.0.0.1:5000/v2.0/ tenant-create --name=demo
# Using user + password + tenant_name env variables
export OS_USERNAME=admin
export OS_PASSWORD=secrete
export OS_TENANT_NAME=admin
keystone user-list
keystone tenant-create --name=demo
# Using user + password + tenant_name flags
keystone --username=admin --password=secrete --tenant_name=admin user-list
keystone --username=admin --password=secrete --tenant_name=admin tenant-create --name=demo</programlisting>
</section>
<section xml:id="auth-token-middleware-with-username-and-password">
<title>Authentication middleware with user name and
password</title>
<para>You can also configure Identity authentication
middleware using the <option>admin_user</option> and
<option>admin_password</option> options. When using the
<option>admin_user</option> and
<option>admin_password</option> options the
<option>admin_token</option> parameter is optional. If
<option>admin_token</option> is specified, it is used only if
the specified token is still valid.</para>
<para>For services that have a separate paste-deploy .ini file,
you can configure the authentication middleware in the
<literal>[keystone_authtoken]</literal> section of the main
configuration file, such as <filename>nova.conf</filename>. In
Compute, for example, you can remove the middleware parameters
from <filename>api-paste.ini</filename>, as follows:</para>
<programlisting language="ini"><?db-font-size 75%?>[filter:authtoken]
paste.filter_factory =
keystoneclient.middleware.auth_token:filter_factory</programlisting>
<para>And set the following values in
<filename>nova.conf</filename> as follows:</para>
<programlisting language="ini"><?db-font-size 75%?>[DEFAULT]
...
auth_strategy=keystone
[keystone_authtoken]
auth_host = 127.0.0.1
auth_port = 35357
auth_protocol = http
auth_uri = http://127.0.0.1:5000/
admin_user = admin
admin_password = SuperSekretPassword
admin_tenant_name = service</programlisting>
<note>
<para>The middleware parameters in the paste config take
priority. You must remove them to use the values in the
[keystone_authtoken] section.</para>
</note>
<para>This sample paste config filter makes use of the
<option>admin_user</option> and
<option>admin_password</option> options:</para>
<programlisting language="ini"><?db-font-size 75%?>[filter:authtoken]
paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory
service_port = 5000
service_host = 127.0.0.1
auth_port = 35357
auth_host = 127.0.0.1
auth_token = 012345SECRET99TOKEN012345
admin_user = admin
admin_password = keystone123</programlisting>
<note>
<para>Using this option requires an admin tenant/role
relationship. The admin user is granted access to the admin
role on the admin tenant.</para>
</note>
</section>
<section xml:id="identity-service-api-protection-with-role-based-access-control">
<title>Identity API protection with role-based access control (RBAC)
</title>
<para>Like most OpenStack projects, Identity supports the protection of
its APIs by defining policy rules based on an RBAC approach. Identity
stores a reference to a policy JSON file in the main Identity
configuration file, <filename>keystone.conf</filename>. Typically this
file is named <filename>policy.json</filename>, and it contains the rules
for which roles have access to certain actions in defined services.</para>
<para>Each Identity API v3 call has a line in the policy file that dictates which
level of governance of access applies.</para>
<programlisting language="ini"><replaceable>API_NAME</replaceable>: <replaceable>RULE_STATEMENT</replaceable> or <replaceable>MATCH_STATEMENT</replaceable></programlisting>
<para>Where:</para>
<para><code><replaceable>RULE_STATEMENT</replaceable></code> can contain <code><replaceable>RULE_STATEMENT</replaceable></code> or <code><replaceable>MATCH_STATEMENT</replaceable></code>.</para>
<para><code><replaceable>MATCH_STATEMENT</replaceable></code> 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:</para>
<programlisting language="ini">"identity:create_user": [["role:admin", "domain_id:%(user.domain_id)s"]]</programlisting>
<para>Indicates that to create a user, you must have the admin role in your token and
the <literal>domain_id</literal> in your token (which implies this must be a domain-scoped token)
must match the <literal>domain_id</literal> in the user object that 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 that you use must be scoped to that
domain.</para>
<para>Each component of a match statement uses this format:</para>
<programlisting language="ini"><replaceable>ATTRIB_FROM_TOKEN</replaceable>:<replaceable>CONSTANT</replaceable> or <replaceable>ATTRIB_RELATED_TO_API_CALL</replaceable></programlisting>
<para>The Identity service expects these attributes:</para>
<para>Attributes from token: <literal>user_id</literal>, the <literal>domain_id</literal> or <literal>project_id</literal> depending on
the scope, and the list of roles you have within that scope.</para>
<para>Attributes related to API call: Any parameters passed into the API call
are available, along with any filters specified in the query string. You
reference attributes of objects passed with an object.attribute syntax
(such as, <literal>user.domain_id</literal>). The target objects of an API are
also available using a target.object.attribute syntax. For
instance:</para>
<programlisting language="ini">"identity:delete_user": [["role:admin", "domain_id:%(target.user.domain_id)s"]]</programlisting>
<para>would ensure that Identity only deletes the user object in the same
domain as the provided token.</para>
<para>Every target object has an `id` and a `name` available as
`target.<replaceable>OBJECT</replaceable>.id` and `target.<replaceable>OBJECT</replaceable>.name`. Identity
retrieves other attributes from the database, and the attributes vary
between object types. The Identity service filters out some database
fields, such as user passwords.</para>
<para>List of object attributes:</para>
<programlisting language="ini">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</programlisting>
<para>The default <filename>policy.json</filename> file supplied provides a
somewhat basic example of API protection, and does not assume any
particular use of domains. Refer to
<filename>policy.v3cloudsample.json</filename> as an example of
multi-domain configuration installations where a cloud provider wants to
delegate administration of the contents of a domain to a particular admin
domain. 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.</para>
<para>A clean installation could start with the standard policy file, to allow
creation of the admin_domain with the first users within it. You could
then obtain the domain_id of the admin domain, paste the ID into a
modified version of <filename>policy.v3cloudsample.json</filename>, and
then enable it as the main policy file.</para>
</section>
<?hard-pagebreak?>
<xi:include href="../common/section_identity-troubleshooting.xml"/>
</chapter>