OpenStack Toronto Meetup - FebruaryKeystone 101
Steve MartinelliSoftware Developer, IBMKeystone CoreTwitter: @stevebot
Agenda
● Who is this guy and what does he do?● Keystone 101
o Main uses of Keystoneo Identity API v2 vs Identity API v3o Token formatso Token APIso Identity Backendso Keystone Middlewareo Keystone Clients
● IBM’s involvement in OpenStack● Q & (possibly) A
● Joined what is now the IBM Open Technologies team in December 2012. Primarily focused on contributing code to upstream projects and being good members of the OpenStack community.
● I’m primarily focused in Keystone (Identity program) and OpenStackClient (Command Line). Core reviewer in four projects: keystone, python-openstackclient, oslo.policy, pycadf.
● I’ve also contributed to a few other projects: devstack, infra, ceilometer, oslo.*, and most of the *-specs repositories. If you see something in need of fixing, push up a patch.
My typical day…● TODO: open source, code review/gerrit, tests required, mailing list / IRC, blueprint/spec
process, gate status, bug fixes/dev
Who is this guy and what does he do?
● Get a tokeno Token required to access other resources/serviceso Contains the user's roles on the project
● Get the service catalogo URL to the other service
● Returned by POST /v3/auth/tokens
Uses of Identity API – As a user
Uses of Identity API – As an admin● Define
○ Users, Groups○ Projects○ Roles○ Roles for users on projects○ Services, endpoints for services
● Validate a token○ auth_token middleware
✓ Works with V2 and V3 tokens✓ Works with PKI and UUID tokens✓ Revocation list✓ Extracts roles, other info from token
○ Supplied by keystonemiddleware package● Discover other service endpoints● Get a trust to impersonate user
Uses of Identity API – As a service
Keystone APIs are hosted here: http://specs.openstack.org/openstack/keystone-specs/
{ "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:35357/v2.0", "region": "RegionOne", "internalURL": " http: //cdn.admin-nets.local:5000/v2.0 ", "publicURL": " http: //cdn.admin-nets.local:5000/v2.0 " } ], "type": “identity", "name": “keystone" } ]}
Sample Service Catalog
Identity API● Identity API is a standard, it now has v2 and v3● Anyone could implement the Identity API, Keystone is one example● There is no Keystone V2 or Keystone V3 or a way to upgrade from one to the other!
Identity API v2● Public API
○ Port 5000 (http://localhost:5000/v2.0)○ Get tokens, List tenants, very limited
● Admin API, most other Keystone operations, they are admin only○ (http://localhost:35357/v2.0)
Identity API v3● Full support for Identity API v2● Renamed “tenants” to “projects”● Token IDs are not in the URL for security, they are in X-Subject-Token header
Keystone● Both “admin” 35357 and “public” 5000 ports● Protected by RBAC (policy.json)● Grizzly supports Identity API V3.0, Havana has V3.1, IceHouse is V3.2
Identity API v2 vs Identity API v3 vs Keystone
● Users exist in a backend (SQL/LDAP/Other).● AuthN: The user authenticates by providing user id and password.● AuthZ: The user should have a role on a project.● Keystone returns a token with that is scoped to the role and project.● The user will pass this token around to the other OpenStack services.
Keystone Classic AuthN/AuthZ flow
Nova
SwiftKeystone
Auth Plugins: https://github.com/openstack/keystone/tree/master/keystone/auth/plugins Auth Controller: https://github.com/openstack/keystone/blob/master/keystone/auth/controllers.py
● UUID○ Looks like a 32 character string: 468da447bd1c4821bbc5def0498fd441○ Pros:
✓ Better user experience✓ No problem with token length
○ Cons:✓ Goes back to Keystone server for validation
○ How the Provider creates an ID:
Token Formats
Common Provider: https://github.com/openstack/keystone/blob/master/keystone/token/providers/common.py UUID Provider: https://github.com/openstack/keystone/blob/master/keystone/token/providers/uuid.py Token Model: https://github.com/openstack/keystone/blob/master/keystone/models/token_model.py
● PKI○ Looks like:
MIIDsAYJKoZIhvcNAQcCoIIDoTCCA50CAQExCTAHBgUrDgMCGjCCAokGCSqGSIb3DQEHAaCCAnoEggJ2ew0KICAgICJhY2QogICAgICAgI...EBMFwwVzELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVVuc2V0MQ4wDAYDVQQHEwVVbnNldDEOMAwGA1UEChM7r0iosFscpnfCuc8jGMobyfApz/dZqJnsk4lt1ahlNTpXQeVFxNK/ydKL+tzEjg
○ Pros:✓ Does not go back to Keystone for validation
○ Cons:✓ Complex to setup✓ Several problems with length - had caused issues with swift and horizon
○ How the Provider creates an ID:
Token Formats
Common Provider: https://github.com/openstack/keystone/blob/master/keystone/token/providers/common.py PKI Provider: https://github.com/openstack/keystone/blob/master/keystone/token/providers/pki.py Token Model: https://github.com/openstack/keystone/blob/master/keystone/models/token_model.py
● PKIz○ Compressed version of PKI○ Looks similar to PKI, but slightly shorter○ How the Provider creates an ID:
Token Formats
Common Provider: https://github.com/openstack/keystone/blob/master/keystone/token/providers/common.py PKIz Provider: https://github.com/openstack/keystone/blob/master/keystone/token/providers/pkiz.py Token Model: https://github.com/openstack/keystone/blob/master/keystone/models/token_model.py
● KLWT (Keystone Lightweight Token)○ New in Kilo!! The code isn’t even merged yet, but it should be by feature freeze.○ Doesn’t actually store tokens in any database!○ The token consists of a bunch of data that is signed and hashed:
Data is: (user_id, scope_id, issued_at, *expires_at*, audit_ids)○ Token Format prefix: KLWT00 for regular token, KLWT01 for trusts, etc.○ Keystone middleware must be updated to provide the ability to decrypt the token
To be implemented
Token Formats
Common Provider: https://github.com/openstack/keystone/blob/master/keystone/token/providers/common.py Token Model: https://github.com/openstack/keystone/blob/master/keystone/models/token_model.py
● /v3/auth/tokens○ POST – authenticate to get a token○ GET – validate a token○ HEAD – validate a token (no data)○ DELETE – invalidate a token
Request endpoint and HTTP method: POST http://localhost:5000/v3/auth/tokensRequest body:{ "auth": { "identity": { "methods": ["password"], "password": { "user": { "name": "admin", "domain": { "id": "default" }, "password": "adminpassword" } } }, "scope": { "project": { "name": "demo", "domain": { "id": "default" } } } }}
Token APIs and Request
<< Methods describes the authentication plugin that is being used. Aside from password, other valid options are `token`, `external`, and a few other experimental ones.
<< Scope describes the what the user wants the returned token to be valid on. Scopes can be a project or domain.
Scope can be one of the following:1) Project ID 2) Domain ID 3) Project Name + Domain ID 4) Project Name + Domain Name
{ "token": { "methods": [ "password" ], "roles": [{ "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:5000/v2.0", "region": "RegionOne", "interface": "public", "id": "ef303187fc8d41668f25199c298396a5"} ], "type": "identity", "id": "bd73972c0e14fb69bae8ff76e112a90", "name": "keystone" } ], "user": { "domain": { "id": "default", "name": "Default" }, "id": "3ec3164f750146be97f21559ee4d9c51", "name": "admin" }, "issued_at": "201406-10T20:55:16.806027Z" }}
Analyzing the token response
Keystone returns the ID of the Token in the X-Subject-Token header, and the token content in the body.
<< Roles represents the roles that the user has on the resource. << Project represents the resource the user has a role on. From the scope in the request.
<< Catalog describes the different services a user may access, and their various endpoints.
Services may be: compute, identity, image, orchestration, etc.
<< User represents the user that was issued the token.
● Users are managed by Keystone● Settings for connecting to a database are handled in Keystone’s config file● Essentially, Keystone is acting as an Identity Provider● Pros:
o Easy to setupo Easier management of users and groups
● Cons:o Keystone shouldn’t be an Identity Providero Weak password support
✓ No password rotation✓ No password recovery
o Most enterprises have an LDAP they want to useo Yet another username and password users must remember
Identity Backends - SQL
SQL Backend: https://github.com/openstack/keystone/blob/master/keystone/identity/backends/sql.py
● Keystone accessing LDAP should be act just like any other application● Keystone operations performed on LDAP
○ User/Group lookup (search)○ Authentication of users (bind)
● What rights does Keystone need in LDAP?○ Read access to user/group attributes defined in keystone.conf○ Unprivileged account or anonymous is preferable○ Access to password hashes is not needed
Identity Backends - LDAP - Basics
* awesome diagrams provided by nkinder
LDAP Backend: https://github.com/openstack/keystone/blob/master/keystone/identity/backends/ldap.py
Configured Keystone to use our Internal LDAP, and I was able to authenticating with username
[email protected] and my own intranet password.
Listing users in a group:steve:keystone$ openstack user list --group openstackers+-----------+--------------------------------+| ID | Name |+-----------+--------------------------------+| 111111111 | [email protected] || 222222222 | [email protected] || 333333333 | [email protected] || 123456789 | [email protected] |
Listing groups a user belongs to:steve:keystone$ openstack group list --user 123456789+-----------+--------------------------------+| ID | Name |+-----------+--------------------------------+| 444444444 | vpn-users || 555555555 | openstackers || 666666666 | softwaregroup_canada |
*Slight changes made to names/emails/ids
Identity Backends - LDAP - Example
● A common authentication protocol in use between the OpenStack projects.o Added to the paste pipeline of other projects
Keystone Auth Token Middleware
Middleware example config: http://docs.openstack.org/developer/keystonemiddleware/middlewarearchitecture.html#configurationMiddleware __call__: https://github.com/openstack/keystonemiddleware/blob/master/keystonemiddleware/auth_token.py#L783Middleware validate: https://github.com/openstack/keystonemiddleware/blob/master/keystonemiddleware/auth_token.py#L929
● KeystoneClient (python-keystoneclient)○ Essentially two parts: a library, and a command line○ The library supports V2 & V3 API
Modules can be imported and used like any other python library.○ KeystoneClient’s CLI supports only Identity V2
● OpenStackClient (python-openstackclient)○ Strictly a command line, supports Identity V2 and V3○ Leverages the libraries that KeystoneClient supports○ Also supports Nova/Glance/Cinder/Swift/etc…○ Community direction is to create a common CLI.
Keystone Clients
OpenStackClient: http://docs.openstack.org/developer/python-openstackclient/KeystonClient vs OpenStackClient: https://github.com/openstack/keystone/blob/master/doc/source/cli_examples.rst
Questions?… and hopefully some answers
Backup slides
● Users○ id, name, description, enabled, mail○ Enabled attribute can be emulated via group membership
● Groups○ id, name, description, member○ id and name are both considered to be unique
● inetOrgPerson (User) example○ dn: uid=someuser,cn=users,dc=example,dc=com○ objectclass: inetorgperson○ uid: someuser (<---- id, name)○ cn: Some User○ mail: [email protected] (<---- mail)
● Group example○ dn: cn=Some Group,cn=users,dc=example,dc=com○ objectclass: group○ cn: Some User (<---- id, name)○ description: Some Group (<---- description)○ member: <user DN> (<---- member)
Identity Backends - LDAP - Attributes
LDAP Seach function: https://github.com/openstack/keystone/blob/master/keystone/common/ldap/core.py#L916-L943
● Domains are a grouping of users, groups, and project● Now able to configure more than one LDAP backend● Configure one LDAP per domains
○ Set domain_specific_drivers_enabled = true○ Domain specific partial config files are placed in:
/etc/keystone/domains/keystone.<domain>.conf
Identity Backends - LDAP - Enhancements
* awesome diagrams provided by nkinder
LDAP Mapping: https://github.com/openstack/keystone/blob/master/keystone/identity/mapping_backends/sql.py#L23-L25
● Keystone has generic federation capabilities, which allows for external users to be recognized
● Users are not persisted in Keystone, but are created on the fly from external user information provided by a trusted identity provider
● Use-cases○ Existing internal IdP, Single Sign On○ Inaccessible LDAP identity source○ Non-LDAP identity source
● Currently support the following federation protocols:o SAML 2.0o OpenID Connect
Federation
OS-FEDERATION API: http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3-os-federation-ext.html
● Identity Provider (IdP)○ Trusted provider of identity information
● Service Provider (SP)○ Service that consumes identity information (Keystone)
● Assertion○ Trusted representation of identity attributes issued by IdP for consumption by SP
● Using the SAML protocol an Assertion represents identity attributes, whereas the OpenID Connect protocol has Claims.
Federation - Concepts
* awesome diagrams provided by nkinder
Docs for configuring federation: http://docs.openstack.org/developer/keystone/configure_federation.html
● Groups are created in Keystone's identity backend for the purpose of role assignment○ Mapping establishes group membership
● Federation specific auth URL is used to obtain an unscoped token○ Simply identifies user and groups
● Unscoped federation token is used to obtain a scoped token○ Contains group assigned roles
Federation
* awesome diagrams provided by nkinder
Mapping function: https://github.com/openstack/keystone/blob/master/keystone/contrib/federation/utils.py#L145-L230
Recommended