[转]Setting Keystone v3 domains
http://www.florentflament.com/blog/setting-keystone-v3-domains.html
The Openstack Identity v3 API, provided by Keystone, offers features that were lacking in the previous version. Among these features, it introduces the concept of domains, allowing isolation of projects and users. For instance, an administrator allowed to create projects and users in a given domain, may not have any right in another one. While these features look very exciting, some configuration needs to be done to have a working identity v3 service with domains properly set.
Keystone API protection section of the developer's doc provides hints about how to set-up a multi-domain installation. Starting from there, I describe the full steps to have a multi-domain setup running, by using curl
to send http requests and jq
to parse the json answers.
Setting an admin domain and a cloud admin
First, we have to start on a fresh non multi-domain installation with the default policy file.
-
With the
admin
user we can create theadmin_domain
.ADMIN_TOKEN=$(\ curl http://localhost:5000/v3/auth/tokens \ -s \ -i \ -H "Content-Type: application/json" \ -d ' { "auth": { "identity": { "methods": [ "password" ], "password": { "user": { "domain": { "name": "Default" }, "name": "admin", "password": "password" } } }, "scope": { "project": { "domain": { "name": "Default" }, "name": "admin" } } } }' | grep ^X-Subject-Token: | awk '{print $2}' ) ID_ADMIN_DOMAIN=$(\ curl http://localhost:5000/v3/domains \ -s \ -H "X-Auth-Token: $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d ' { "domain": { "enabled": true, "name": "admin_domain" } }' | jq .domain.id | tr -d '"' ) echo "ID of domain cloud: $ID_ADMIN_DOMAIN"
-
Then we can create our
cloud_admin
user, within theadmin_domain
domain.ID_CLOUD_ADMIN=$(\ curl http://localhost:5000/v3/users \ -s \ -H "X-Auth-Token: $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d " { \"user\": { \"description\": \"Cloud administrator\", \"domain_id\": \"$ID_ADMIN_DOMAIN\", \"enabled\": true, \"name\": \"cloud_admin\", \"password\": \"password\" } }" | jq .user.id | tr -d '"' ) echo "ID of user cloud_admin: $ID_CLOUD_ADMIN"
-
And we grant to our user
cloud_admin
theadmin
role on domainadmin_domain
.ADMIN_ROLE_ID=$(\ curl http://localhost:5000/v3/roles?name=admin \ -s \ -H "X-Auth-Token: $ADMIN_TOKEN" \ | jq .roles[0].id | tr -d '"' ) curl -X PUT http://localhost:5000/v3/domains/${ID_ADMIN_DOMAIN}/users/${ID_CLOUD_ADMIN}/roles/${ADMIN_ROLE_ID} \ -s \ -i \ -H "X-Auth-Token: $ADMIN_TOKEN" \ -H "Content-Type: application/json" curl http://localhost:5000/v3/domains/${ID_ADMIN_DOMAIN}/users/${ID_CLOUD_ADMIN}/roles\ -s \ -H "X-Auth-Token: $ADMIN_TOKEN" | jq .roles
-
Once the
admin_domain
has been created with itscloud_admin
user, we can enforce a domain based policy. In order to do that, we have to copy the policy.v3cloudsample.json file over our former/etc/keystone/policy.json
, while replacing the stringadmin_domain_id
by the ID of theadmin_domain
we just created. Locate thepolicy.v3cloudsample.json
file into theetc
directory of Keystone's source.sed s/admin_domain_id/${ID_ADMIN_DOMAIN}/ \ < policy.v3cloudsample.json \ > /etc/keystone/policy.json
Warning, current version (commit 19620076f587f925c5d2fa59780c1a80dde15db2) of policy.v3cloudsample.json doesn't allow cloud_admin
to manage users in other domains than its own (see bug 1267187). Until the patch is merged, I suggest using this policy.c3cloudsample.json under review.
Creating domains and admins
From now on, the admin
user can only manage projects and users in the Default
domain. To create other domains we will have to authenticate with the cloud_admin
user created above.
-
Getting a token scoped on the
admin_domain
, for usercloud_admin
.CLOUD_ADMIN_TOKEN=$(\ curl http://localhost:5000/v3/auth/tokens \ -s \ -i \ -H "Content-Type: application/json" \ -d ' { "auth": { "identity": { "methods": [ "password" ], "password": { "user": { "domain": { "name": "admin_domain" }, "name": "cloud_admin", "password": "password" } } }, "scope": { "domain": { "name": "admin_domain" } } } }' | grep ^X-Subject-Token: | awk '{print $2}' )
-
Creating domains
dom1
anddom2
.ID_DOM1=$(\ curl http://localhost:5000/v3/domains \ -s \ -H "X-Auth-Token: $CLOUD_ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d ' { "domain": { "enabled": true, "name": "dom1" } }' | jq .domain.id | tr -d '"') echo "ID of dom1: $ID_DOM1" ID_DOM2=$(\ curl http://localhost:5000/v3/domains \ -s \ -H "X-Auth-Token: $CLOUD_ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d ' { "domain": { "enabled": true, "name": "dom2" } }' | jq .domain.id | tr -d '"') echo "ID of dom2: $ID_DOM2"
-
Now we will create a user
adm1
in domaindom1
.ID_ADM1=$(\ curl http://localhost:5000/v3/users \ -s \ -H "X-Auth-Token: $CLOUD_ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d " { \"user\": { \"description\": \"Administrator of domain dom1\", \"domain_id\": \"$ID_DOM1\", \"enabled\": true, \"name\": \"adm1\", \"password\": \"password\" } }" | jq .user.id | tr -d '"') echo "ID of user adm1: $ID_ADM1"
-
We will also grant the
admin
role on domaindom1
to thisadm1
user.curl -X PUT http://localhost:5000/v3/domains/${ID_DOM1}/users/${ID_ADM1}/roles/${ADMIN_ROLE_ID} \ -s \ -i \ -H "X-Auth-Token: $CLOUD_ADMIN_TOKEN" \ -H "Content-Type: application/json" curl http://localhost:5000/v3/domains/${ID_DOM1}/users/${ID_ADM1}/roles \ -s \ -H "X-Auth-Token: $CLOUD_ADMIN_TOKEN" | jq .roles
Creating projects and users
The adm1
user can now fully manage domain dom1
. He is allowed to manage as many projects and users as he wishes within dom1
, while not being able to access resources of domain dom2
.
-
Now we authenticate as user
adm1
with a scope ondom1
.ADM1_TOKEN=$(\ curl http://localhost:5000/v3/auth/tokens \ -s \ -i \ -H "Content-Type: application/json" \ -d ' { "auth": { "identity": { "methods": [ "password" ], "password": { "user": { "domain": { "name": "dom1" }, "name": "adm1", "password": "password" } } }, "scope": { "domain": { "name": "dom1" } } } }' | grep ^X-Subject-Token: | awk '{print $2}' )
-
We create a project
prj1
in domaindom1
.ID_PRJ1=$(\ curl http://localhost:5000/v3/projects \ -s \ -H "X-Auth-Token: $ADM1_TOKEN" \ -H "Content-Type: application/json" \ -d " { \"project\": { \"enabled\": true, \"domain_id\": \"$ID_DOM1\", \"name\": \"prj1\" }\ }" | jq .project.id | tr -d '"' ) echo "ID of prj1: $ID_PRJ1"
-
When trying and creating a project in domain
dom2
, it fails.curl http://localhost:5000/v3/projects \ -s \ -H "X-Auth-Token: $ADM1_TOKEN" \ -H "Content-Type: application/json" \ -d " { \"project\": { \"enabled\": true, \"domain_id\": \"$ID_DOM2\", \"name\": \"prj2\" }\ }" | jq .
-
Creating a standard user
usr1
in domaindom1
, with default projectprj1
.ID_USR1=$(\ curl http://localhost:5000/v3/users \ -s \ -H "X-Auth-Token: $ADM1_TOKEN" \ -H "Content-Type: application/json" \ -d " { \"user\": { \"default_project_id\": \"$ID_PRJ1\", \"description\": \"Just a user of dom1\", \"domain_id\": \"$ID_DOM1\", \"enabled\": true, \"name\": \"usr1\", \"password\": \"password\" } }" | jq .user.id | tr -d '"' ) echo "ID of user usr1: $ID_USR1"
-
Granting
Member
role to userusr1
on projectprj1
.MEMBER_ROLE_ID=$(\ curl http://localhost:5000/v3/roles?name=Member \ -s \ -H "X-Auth-Token: $ADM1_TOKEN" \ | jq .roles[0].id | tr -d '"' ) curl -X PUT http://localhost:5000/v3/projects/${ID_PRJ1}/users/${ID_USR1}/roles/${MEMBER_ROLE_ID} \ -s \ -i \ -H "X-Auth-Token: $ADM1_TOKEN" \ -H "Content-Type: application/json" curl http://localhost:5000/v3/projects/${ID_PRJ1}/users/${ID_USR1}/roles \ -s \ -H "X-Auth-Token: $ADM1_TOKEN" | jq .roles
The domain administrator adm1
ended up creating a project prj1
and a user usr1
member of the project. usr1
can now get a token scoped onprj1
and manage resources into this project.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现