Multi-Tenancy
A single cluster-mode install can serve many tenants at once. Each tenant is an Organization — a real row in hyve-api’s own datastore (Postgres or SQLite, see internal/orgdb), not a Kubernetes object — paired with its own Kubernetes namespace and RBAC scaffolding. No separate Helm release per tenant, no separate controller+API pod pair to operate and upgrade for each one.
Creating, renaming, and deleting organizations
hyve organization create acmeSuperadmin-only, and deliberately narrow: it turns a name into a real tenant — its own namespace, its own hyve-access-admin/hyve-access-readonly ServiceAccount+RoleBinding scaffolding (the same RBAC a one-install-per-tenant deployment gets from the Helm chart at install time, created programmatically here instead), and its own datastore record — and nothing more. Every organization also gets one default environment automatically — a named scope within it (staging, production, …) that clusters are created in; see hyve environment.
Creating it grants no one access. Add its first member from the web console’s Users page while viewing it (or POST /api/accounts) — a new user gets a password and is emailed about their account; an existing user from another organization is just added, keeping their own login. From inside the hyve-api pod there’s also:
hyve cluster-config api create-user alice --role admin --namespace acmeAn organization’s name can be changed later — its Kubernetes namespace, the thing every binding/RBAC/reconciling-cluster lookup actually keys on, never can, so this is purely a relabel:
hyve organization migrate --help # renaming happens via the same PATCH /organizations/{name} as migration — see belowNames must stay unique, and the same two names creation reserves stay reserved for renaming too: hyve-system (the control plane’s own namespace) and any casing/spacing of control plane.
Deleting one is equally direct:
hyve organization delete acmeThis marks the row for deletion and issues a standard Kubernetes namespace delete — Kubernetes’ own native cascade tears down everything inside it and then the namespace itself, no hyve-specific finalizer or out-of-band controller confirmation gates that removal. Deletion behaves the same way here as everywhere else in the application.
Reconciling clusters: where a tenant’s resources actually live
By default, an organization’s ClusterDefinition/Template/Workflow/Resource objects (and its own HyveConfig) live in its namespace on the control plane’s own home cluster, right alongside every other tenant’s. hyve-controller reconciles every such organization alongside the control plane — the Helm chart turns this on for api.multiTenant.enabled with api.db.driver: postgres (the controller reads the organization list from the same database, and picks up new organizations by restarting itself within about 30 seconds). A reconciling cluster lets one organization’s resources live on a different, dedicated physical Kubernetes cluster instead — useful for isolating a noisy or sensitive tenant, or for a hosted offering that never wants tenant workloads anywhere near its own control-plane infrastructure.
An organization can keep several clusters stored and switch between them by name — no re-entering a kubeconfig each time. This is self-service, reachable by the organization’s own admin:
hyve reconciling-cluster add k3s --kubeconfig-file ~/k3s.yamlhyve reconciling-cluster add civo --kubeconfig-file ~/civo.yamlhyve reconciling-cluster use civo # copies every resource over, then switcheshyve reconciling-cluster use --home # back to the control plane's own home clusterThe web console’s Reconciling cluster page does the same, and shows each cluster’s server endpoint, Kubernetes version, and live reachability. Cluster names are unique per organization, so two organizations can each have a prod. Switching locks the organization (423 Locked) while the copy runs; a failed copy leaves it where it was.
A superadmin can also register clusters in an install-wide pool and assign one to an organization directly:
hyve reconciling-cluster pool add cell-a --kubeconfig-file ./cell-a.yamlhyve organization migrate acme --reconciling-cluster cell-a--require-reconciling-cluster
A hosted/managed install can refuse to let any organization other than the control plane’s own ever land on (or migrate back to) the shared home cluster at all:
hyve cluster-config api run --require-reconciling-cluster ...Every organization must then be given an explicit reconciling cluster at creation, and can never migrate back to "" (home) later — a hard operator guarantee that tenant workloads never touch the infrastructure the control plane itself runs on.
One account, many organizations
A user is one account — a username, an email, and a password, all unique across the install — with a membership in each organization they belong to, each with its own role. Adding someone to a second organization adds a membership, not a second account or password.
Logging in names no organization:
hyve context login --api-url https://hyve-api.example.comWhich organization a command acts in is picked per request, and checked against your memberships every time:
hyve organization list # the organizations you can access, and your role in eachhyve organization use acme # remembered on the active contexthyve cluster list --org widget # or for a single commandIn the web console, the same choice is the Viewing picker, which lists only your organizations (and hides itself when there’s just one). With nothing picked, hyve-api uses your only organization — the first one, if you belong to several — or, for a superadmin, the control plane. Organization names are resolved server-side, so a renamed organization keeps working under its new name, and under its namespace.
The control plane’s own organization (hyve-system) appears once, as Control plane.
The superadmin role
Above the namespace-scoped admin/read-only roles sits one intentionally cluster-scoped tier: superadmin. It exists for a small, fixed set of things:
- Create, rename, or delete a tenant organization.
- Manage the install-wide reconciling-cluster pool and assign pool clusters to organizations (an organization’s own clusters, above, need no
superadminat all). - Act in any organization, member or not (picked like any other —
hyve organization use,--org, or the console’s Viewing picker), always assuperadmin.
It’s never the default role, and no tenant admin can grant it to themselves. A user’s email and password are shared by all their organizations, so an organization’s admin can change them only for someone who belongs to that organization alone — see Access Control for the full role model.
The host cluster
hyve-controller/hyve-api run on some cluster — the host. It’s represented as a ClusterDefinition marked spec.access.method: primary, in one of two ways:
-
No
spec.driver(the zero-config default). The cluster already exists by definition, so hyve never creates, deletes, or scales it — it only reconciles itsspec.resources.hyve cluster auth <name>gets a kubeconfig minted by hyve-api itself: a short-lived token for a dedicatedcluster-admin-bound ServiceAccount (hyve-host-admin), superadmin only, since the host carries every tenant’s control plane.apiVersion: hyve.io/v1alpha1kind: ClusterDefinitionmetadata: {name: host, namespace: hyve-system}spec: {access: {method: primary}} -
With a real
spec.driver. Hyve provisions and authenticates to the host through that driver exactly like any other cluster — the pattern for a host cluster hyve itself created (for example from a template, locally or in a pipeline).primaryis then only a markerhyve migrate clusteruses to find the current host.
See Cluster Patterns for creating a host cluster locally or from a pipeline.
The host as other organizations’ management cluster
A module with a management cluster (such as a Cluster API module — see Modules) can name the host. Clusters in the control plane can always do that; clusters in other organizations on the home cluster can only once a superadmin allows it — Organizations may use the host cluster in the control plane’s Settings (HyveConfig.spec.organizationsMayUseHostCluster). Off by default: the module then gets the host’s cluster-admin kubeconfig, and organizations choose their own modules, so only allow it when every organization is trusted with that.
Moving tenants and hosts: hyve migrate
hyve migrate cluster understands this model directly via --namespace, working alongside (not instead of) hyve organization migrate above:
- A tenant namespace scopes the migration to just that tenant — split one tenant onto its own dedicated cluster while the source keeps running for everyone else.
hyve-system(the default) migrates everything — every organization, plus the control plane’s own objects.