Here’s my set up and the design decisions I’ve made so far. Since this code is not yet submitted for code review, there is a good chance that it will change prior to deployment. Users will be stored in a flat collection. ou=Users,$SUBTREE and be based on the standard LDAP objectClass inetOrgPerson which is defined in /etc/openldap/schema/inetorgperson.ldif. Currently, only two fields are used: cn and sn. cn is used for the bind call, and is the id field in the user object. Tenants are in a collection that is a peer to Users. Tenants are instancs of the groupOfNames object class defined in /etc/openldap/schema/core.ldif. Tenant membership is indicated by the presence of the User’s DN in the tenant’s members attribute. Roles are instances of the LDAP object class organizationalRole defined in /etc/openldap/schema/core.ldif. Role assignment is indicated by the presence of the User’s DN in the roleOccupant attribute. Configuration of LDAP for the Keystone server is provided by the [LDAP] stanza in the appropriate keystone.conf file. Here are the supported values url user password suffix use_dumb_member user_tree_dn tenant_tree_dn role_tree_dn And an example of what my config file looks like: 01 [ldap] 02 url = ldap://localhost 03 tree_dn = dc=younglogic,dc=com 04 user_tree_dn = dc=Users,dc=younglogic,dc=com 05 role_tree_dn = dc=Roles,dc=younglogic,dc=com 06 tenant_tree_dn = dc=Groups,dc=younglogic,dc=com 07 user = dc=Manager,dc=younglogic,dc=com 08 password = freeipa4all 09 backend_entities = ['Tenant', 'User', 'UserRoleAssociation', 'Role'] 10 suffix =cn=younglogic,cn=com 11 12 [identity] 13 driver = keystone.identity.backends.ldap.Identity Not all of these fields need to be specified. It is expected that the user will supply simply the suffix field, and not override the values of user_tree_dn,role_tree_dn, or tenant_tree_dn. backend_entities is not currently honored. It is expected that LDAP will instead either manage all of these or non e of them, with token management handled by a different backend provider. use_dumb_member is still honored from the previous incarnation, but has not been tested, nor do I understand the intention of this code. The unit tests for the LDAP code use a common code sournce with the other Identity management backends. To run just the LDAP unit tests, from the Keystone directory, run 1 python ./run_tests.py test_backend_ldap Additionally, the unit tests can be run against a live OpenLDAP server by running. 1 python ./run_tests.py _ldap_livetest All tests pass successfully on my development machine as of this posting. I’m running Fedora 16, which supports OpenLDAP. Specifically I am running openldap-servers-2.4.26-5.fc16.x86_64. To start the service, run 1 sudo service slapd start To configure the server, I use a file I call manager.ldif: 01 dn: olcDatabase={2}hdb,cn=config 02 changetype: modify 03 replace: olcSuffix 04 olcSuffix: dc=younglogic,dc=com 05 - 06 replace: olcRootDN 07 olcRootDN: dc=Manager,dc=younglogic,dc=com 08 - 09 add: olcRootPW 10 olcRootPW: {SSHA}lBDIdfwvZkITal0k9tdhiCUolxpf6anu You should modify the suffix for your organization. Execute the configuration with: 1 sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f ./manager.ldif And test that you can now do a simple bind to the localhost server. 1 ldapsearch -x -D "dc=Manager,dc=younglogic,dc=com" -H ldap://localhost -w freeipa4all -b ou=Groups,dc=younglogic,dc=com "(objectClass=*)" Now set up the subtree for Keystone. I use file I call org.ldif 01 dn: dc=younglogic,dc=com 02 dc: younglogic 03 objectClass: dcObject 04 objectClass: organizationalUnit 05 ou: younglogic 06 07 dn: ou=Groups,dc=younglogic,dc=com 08 objectClass: top 09 objectClass: organizationalUnit 10 ou: groups 11 12 dn: ou=Users,dc=younglogic,dc=com 13 objectClass: top 14 objectClass: organizationalUnit 15 ou: users 16 17 dn: ou=Roles,dc=younglogic,dc=com 18 objectClass: top 19 objectClass: organizationalUnit 20 ou: users Technically, the Roles ou is not required. My original though was that this collection would contain the superset of roles possible for all of the Tenants. However, I have not implemented that. Current code is commited to Github I will update this link when the code is ready for review.