Skip to main content

Tenancy: single vs multi

The deployment shape — single-tenancy vs multi-tenancy — is declared by the active license, not by an env var. Same codebase, two faces, one source of truth.

TL;DR​

  • single tenancy — one customer org. The system auto-creates the default org + adds the local cluster as that org's edge on first license install. Admin/public pages (Public Edges / Global Marketplace / Public Registries) hide.
  • multi tenancy — operator creates organizations through the UI. Admin/public pages surface when the corresponding MaxPublic* license cap is positive.

The distinction lives in the license's Binding.Tenancy field — "single" or "multi".

Why two shapes​

DT Edge Platform serves two distinct customer types:

  • One customer who needs an ops console. Their team installs apps on a single (or small number) of clusters they own. Don't need orgs. Don't publish to a marketplace. Just want a UI around helm + observability + alarms.
  • A SaaS operator running DT Edge Platform for many customer orgs. Multiple isolated tenants, each with their own edges + registries + marketplace + members. Public/admin surfaces optional based on contract.

Same product, same code path, two shapes. Sales / contracts decide which one a license is good for.

What changes between the two​

The non-obvious thing: most of the product is identical. The core flow (install an app on an edge, manage releases, monitor with alarms) doesn't care about tenancy. What differs is the admin surface area.

SurfaceSingleMulti
Sidebar → Organizationshidden (only one exists)visible
Sidebar → Public Edges (admin)hiddenvisible if MaxPublicEdges > 0
Sidebar → Global Registrieshiddenvisible if MaxPublicRegistries > 0
Sidebar → Global Marketplacehiddenvisible if MaxPublicMarketplacePackages > 0
First-run experiencedashboard with the local edge ready to go"create your first org" walkthrough
Org-scoped features (helm, alarms, audit log, ...)identicalidentical

Why license-driven and not env-driven​

There used to be a MODE=single|platform env var that did the same thing. We dropped it. Reasons:

  1. Two sources of truth. Operators sometimes set MODE=single for a license whose tenancy field said multi, or vice versa. There was no way to detect that mismatch from the running system; the UI showed one shape, the contract said another.
  2. The contract should drive the shape. A customer paid for "single-tenant up to 25 nodes". The license already encodes that. Having the deployment also need a separate env var was redundant and error-prone.
  3. Tenancy swap should be a contract event. When a customer upgrades from single to multi, that's a re-issued license (with new caps). It shouldn't require a helm upgrade as well.

So today: one artifact (the license), one source of truth, no env var to misconfigure.

The trade-off: pre-license boot has clear semantics now — UI shows a "License Required" landing page, the API refuses mutations. There's no "we're in single mode but no license loaded" ambiguity.

What "the local cluster" means in single tenancy​

When a single-tenancy license is uploaded, DT Edge Platform calls bootstrap.EnsureSingleTenancy:

  1. Creates a default org named after the license's customer name
  2. Adds the cluster DT Edge Platform is running in as that org's edge instance — the kubeconfig comes from rest.InClusterConfig() which works inside any k8s pod
  3. Grants the super-admin org:admin on the default org

Idempotent — license renewal is a no-op for the bootstrap (the org + edge are already there).

The local cluster is just like any other edge. You can register other edges alongside it (same org), install apps on either, remove the local one if you ever migrate DT Edge Platform somewhere else.

Switching tenancy​

Re-issue the license with a different Binding.Tenancy value and upload it. Effects:

  • single → multi — admin/public pages start surfacing per the new license's MaxPublic* caps. Existing default org + local edge stay in place; you can keep them or replace them.
  • multi → single — admin/public pages hide. Existing orgs stay in the database; the bootstrap is idempotent and doesn't delete anything. Typically you only do this when consolidating to one org anyway.

It's rare; usually reflects a contract change.

What stays multi-tenant in single tenancy​

The codebase is fundamentally multi-tenant. Single tenancy is a special case of multi tenancy where N=1.

That means:

  • Every row still has org_id. The default org is just one of (potentially) many.
  • Casbin still runs. The default org has its own roles, members, permissions.
  • Admin / super-admin distinction still exists. The super-admin isn't automatically a member of the default org — they get an explicit org:admin grant during bootstrap.

If a single-tenancy install ever needs to "grow into" multi-tenancy (e.g. a small team becomes a SaaS), it's a license re-issue + uploading the new JWT. No data migration.

See also​