
An Incus cluster does not have to serve a single team: it can host several isolated tenants, each with its own instances, its own VPC, its own quotas and its own access. All of it rests on projects, the equivalent of accounts on a public cloud. This guide shows how to create a tenant, give it quotas that are genuinely enforced, issue it a credential confined to its perimeter, and peer two OVN VPCs across tenants. It ends with an honest assessment of what is not there yet. Advanced audience, private cloud oriented.
What you will learn
- Use a project as an isolated tenant.
- Set quotas and check that they really block.
- Issue a scoped credential (the equivalent of an access key) and revoke it.
- Peer two VPCs belonging to different tenants.
Prerequisites
- A working OVN network: see OVN in Incus.
- An existing uplink (named
UPLINKhere).
The project is the tenant
A project isolates its instances, networks, profiles and volumes. You enable features.networks so that it carries its own VPC:
incus project create tenant-b -c features.networks=trueEach tenant then creates its own OVN network, its instances and its ACLs, without seeing those of the others.
Setting quotas, and checking that they hold
Quotas bound what a tenant consumes. You set them on the project:
incus project set tenant-b \ limits.cpu=4 limits.memory=8GiB limits.instances=5 \ restricted=true restricted.networks.uplinks=UPLINKA quota is only worth something if it is enforced. You verify that by exceeding it on purpose. With limits.instances=2, the third instance is refused:
incus launch images:debian/13 c3 --network vpc-b --storage ceph-rbd --project tenant-bError: Failed instance creation: Reached maximum number of instances in project "tenant-b"The message leaves no room for doubt: Incus quotas really do block.
Issuing a scoped credential
Each user receives their own certificate, restricted to their project. The operator issues a token (the equivalent of an access key):
incus config trust add alice --projects tenant-b --restrictedClient alice certificate add token:eyJjbGllbnRfbmFtZSI6ImFsaWNlIi...The user adds that token to their own configuration, which generates their certificate, automatically confined:
incus remote add mycloud eyJjbGll... # in the user's own configincus project list mycloud: # they only see tenant-bThey see nothing of the other tenants, and listing the default project comes back empty. To cut access off, you revoke the certificate the way you would disable a key:
incus config trust remove <fingerprint>Peering two VPCs across tenants
By default, two OVN VPCs belonging to different tenants are isolated: they cannot see each other. To connect them, you create a peering, which has to be established on both sides (a mutual relationship):
incus network peer create vpc0 to-tenantb tenant-b/vpc-b --project defaultincus network peer create vpc-b to-default default/vpc0 --project tenant-bOnce both halves are in place, the state moves to CREATED and traffic routes directly between the two VPCs, without going back through the uplink. One notable point: ACLs stay enforced across the peering. A tenant can reach another tenant's web tier (if allowed), but not its database if an ACL blocks it. That is the behaviour of VPC Peering combined with Security Groups.
What is not there yet (let us be honest)
This model covers the essentials of a private cloud operated by the infrastructure team. Two limits are worth knowing:
- No fine-grained per-resource RBAC without an extra building block: trust certificates grant access at project level, not "read only on this network". Fine granularity does exist, through OpenFGA, which the Incus documentation describes as a first-class authorization method (
authorization.openfga.*options, with the model generated by Incus). The cost is therefore not availability but operations: you have to run your own OpenFGA server and explicitly route the relevant clients to it, otherwise enabling it changes nothing. - No self-service portal: the user does not manage their resources from a console of their own the way they would on a public cloud. Everything is driven through the CLI and the API (often via Terraform). The multi-tenant portal remains a layer to build on top.
For a company private cloud driven by IaC, this is enough. For a self-service public cloud, that layer is missing.
Key points
- A project equals an isolated tenant;
features.networksgives it its own VPC. - Quotas (
limits.*) are enforced: going over the limit is refused. - A scoped credential (
config trust add --projects --restricted) confines the user to their project; revoking it cuts access. - Peering connects two VPCs (mutually), and ACLs stay enforced across it.
- Fine-grained RBAC needs an OpenFGA server of your own; the self-service portal is still missing entirely.