Create an OpenStack Project & User (Keystone)
Set up multi-tenancy in OpenStack with Keystone: create a project, add a user, assign roles, and apply quotas from the OpenStack CLI.
Keystone is the identity service that sits at the centre of every OpenStack cloud. Before anyone can launch an instance, attach a volume, or create a network, Keystone has to know who they are, which project they belong to, and what they are allowed to do. Getting this layer right is what turns a single cloud into a safely shared, multi-tenant platform.
This tutorial shows how to build a clean tenancy from scratch using the OpenStack CLI: a domain (optional), a project, a user, the right role assignments, and sensible quotas. It assumes you already have a working cloud โ for example one built by following our guide to installing OpenStack with OpenStack-Ansible.
Prerequisites
- A running OpenStack 2025.2 cloud and the
openstackclient installed. - Admin credentials โ an
openrcorclouds.yamlentry with theadminrole on the default domain. - A shell where you have sourced those admin credentials.
Confirm you are operating as an administrator before making any changes:
source ~/admin-openrc
openstack token issue
openstack project listUnderstanding the Keystone object model
Four concepts do most of the work. A domain is a top-level container for projects and users, used to separate organisations on a shared cloud. A project (historically called a tenant) owns resources and quotas. A user is an identity that authenticates. A role is a named set of permissions that you grant to a user on a specific project. Authorisation in OpenStack is the combination: this user has this role on this project.
Step 1: Create a domain (optional)
For a small cloud the built-in default domain is enough. If you are isolating separate customers or business units, create a domain per tenant so their users and projects never collide:
openstack domain create --description 'Acme GmbH tenant' acme
openstack domain listStep 2: Create a project
Create a project to hold the new tenant's resources. If you made a domain above, place the project inside it; otherwise omit --domain to use default.
openstack project create --domain acme \
--description 'Acme production workloads' acme-prod
openstack project show acme-prodStep 3: Create a user
Create a user, set its password, assign it to a primary project, and give it an email for recovery and notifications. In automation you would supply the password from a secret store rather than on the command line.
openstack user create --domain acme \
--project acme-prod \
--email alice@acme.example \
--password-prompt alice
openstack user show aliceStep 4: Assign roles
A freshly created user can authenticate but can do almost nothing until it holds a role on a project. The standard project-scoped role is member (with reader for read-only access and admin for full control). Grant Alice the member role on her project:
openstack role add --project acme-prod --user alice member
openstack role assignment list --user alice --namesIf a user genuinely needs administrative power โ use this sparingly โ grant the admin role instead. Roles are additive, so you can combine them as needed:
openstack role add --project acme-prod --user alice adminStep 5: Set project quotas
Quotas are how you stop one tenant from consuming the entire cloud. They are set per project and cover compute, networking, and storage independently. Start conservative; you can always raise them.
openstack quota set --cores 20 --ram 49152 --instances 10 acme-prod
openstack quota set --networks 5 --subnets 5 --routers 2 \
--floating-ips 5 --secgroups 10 acme-prod
openstack quota set --volumes 10 --gigabytes 500 acme-prodReview the effective limits for the project at any time:
openstack quota show acme-prodStep 6: Hand the user a working openrc
Give Alice a credentials file she can source. This is the project-scoped equivalent of the admin RC you used at the start:
cat > acme-openrc <<'EOF'
export OS_AUTH_URL=https://cloud.example.com:5000/v3
export OS_PROJECT_NAME=acme-prod
export OS_PROJECT_DOMAIN_NAME=acme
export OS_USERNAME=alice
export OS_USER_DOMAIN_NAME=acme
export OS_IDENTITY_API_VERSION=3
export OS_REGION_NAME=RegionOne
EOFWhen Alice sources this file and runs a command she will be prompted for her password, and every action will be scoped to acme-prod.
Verification
Confirm the whole chain works from the user's perspective. Source the new file, issue a token, and check that the scope matches the project you intended:
source acme-openrc
openstack token issue
openstack project show acme-prod -f value -c idCommon errors and troubleshooting
403 Forbidden / You are not authorized
The user authenticated but lacks a role on the project it is trying to use, or the token is scoped to the wrong project. Re-check the assignment with openstack role assignment list --user alice --names and confirm the OS_PROJECT_NAME and domain variables in the RC file.
Could not find user / domain
When you use custom domains, almost every command needs the domain made explicit. Add --domain acme to user and project commands, and set both OS_USER_DOMAIN_NAME and OS_PROJECT_DOMAIN_NAME in the RC file.
Quota exceeded later on
If launching an instance fails with a quota error, the project hit a limit. Inspect usage with openstack quota show acme-prod and raise the relevant value, or clean up unused resources.
Conclusion
You have built a complete tenancy: a project, a user, role-based access, and quotas that keep consumption in check. This is the foundation of safe multi-tenancy โ isolated, accountable, and sovereign per customer. With identity in place, the next step is to give the new user something to run by launching a first instance, and the OpenStack CLI basics guide is a handy companion for everyday operations.
Managing domains, roles, and quotas cleanly across many tenants is precisely the kind of governance clouditiv builds into its managed, digitally sovereign private cloud, where every tenant's identity and data stay isolated and resident in Germany.