Skip to main content
Version: 2.0

Multi-Tenancy

KubeOpera is multi-tenant from the ground up. One or more host clusters run the platform, and each customer — a tenant — gets isolated environments called CloudSpaces, each backed by a vCluster: a complete Kubernetes control plane running inside the host cluster.

This page explains how tenants are separated at every layer, and what happens when a new customer signs up.

Roles​

Every user has one of two roles. The role travels in the user's token and decides what they see and can do.

Platform administrator (super_admin)Tenant user (customer)
ScopeThe whole platform: host clusters, all tenants, platform services.Their own tenant's CloudSpaces and apps.
DashboardCluster monitoring, node pools, incidents, pipelines, analytics, security.CloudSpaces, app health, pipelines, monitoring and AI advice.
AI ChatEvery tool across the platform.Tools scoped to their own tenant: app profiles, advice, live metrics, cost and incidents for their apps.
How it's assignedCreated at installation or granted by another administrator.Given to every new sign-up.
Home page/dashboard/home

Within a tenant, role-based access control lets you give team members finer-grained permissions.

CloudSpaces​

A CloudSpace is a vCluster in its own host namespace (vcluster-<name>). It has its own API server, etcd and scheduler, while sharing the host cluster's worker nodes.

Host cluster
├── kubeopera-system/ ← platform controllers (tenant-controller, …)
├── kubeopera-core/ ← platform services (kubeopera-api, auth-service, …)
├── vcluster-alice-default/ ← Alice's CloudSpace
│ ├── vCluster control plane
│ ├── Alice's app advisor
│ └── Alice's apps
└── vcluster-bob-default/ ← Bob's CloudSpace, fully isolated from Alice's
├── vCluster control plane
├── Bob's app advisor
└── Bob's apps

Every new tenant gets a default CloudSpace automatically and can create more — for example, separate staging and production spaces. See CloudSpaces.

How isolation works​

LayerHow tenants are kept apart
KubernetesEach CloudSpace is a separate control plane. A tenant's Pods, Services, Secrets and Ingresses exist only in their vCluster; host namespaces are separate.
ComputeWorkloads share host nodes, but every CloudSpace has a CPU and memory quota covering both its control plane and its workloads.
DataTenant-owned records carry a tenant_id. Every query is filtered by the tenant in the caller's token — never by an ID the client sends.
APIAuthentication middleware reads tenant_id and user_type from the token and scopes every request.
AIThe chat's tools are filtered by role, and each tool re-checks that the requested resource belongs to the caller's tenant. Each CloudSpace runs its own App Advisor instance.
ImagesEach tenant's built images live in an isolated area of the built-in registry.

Token claims​

auth-service adds two claims to every token:

ClaimValue
user_typesuper_admin or customer, derived from the user's roles at sign-in.
tenant_idThe tenant's ID. Empty for platform administrators.

Onboarding a new tenant​

When someone signs up and verifies their email, KubeOpera provisions their tenant automatically:

1. Dashboard  →  POST /api/kubeopera/onboarding/provision
2. kubeopera-api creates the CloudSpace record (status: provisioning)
and marks it as the user's default
3. kubeopera-api creates a Tenant resource in the host cluster
4. tenant-controller reconciles it:
Pending → Provisioning → InstallingFlux → Ready
• installs the vCluster
• waits for it to become ready
• stores its kubeconfig as kubeopera-system/tenant-<id>-kubeconfig
• installs Flux and the tenant's App Advisor inside the vCluster
• applies the tenant's quotas
• marks the CloudSpace active
5. The user's next token carries tenant_id and they land on /home

What the new user sees​

The /onboarding page drives this with a short, three-step experience:

  1. Setting up your space — provisioning starts automatically.
  2. Your space is ready — the CloudSpace name is shown when it's done.
  3. Get started — the user is taken to /home.

The user can start exploring while provisioning finishes in the background; the CloudSpace's status on /cloudspaces moves from provisioning to active.

When provisioning fails​

If provisioning fails — a network error or an install timeout — the Tenant's phase becomes Failed and the reason is shown on the CloudSpace. tenant-controller retries automatically with backoff. Administrators can also retry immediately from Settings → Tenants → Retry provisioning, or with kubectl:

kubectl patch tenant alice-default \
--type merge \
-p '{"status":{"phase":"Pending"}}' \
-n kubeopera-system

Next steps​