Skip to Content
DocsControl PanelMSP & Multi-Tenancy

MSP & Multi-Tenancy

The Control Panel includes full multi-tenancy support for Managed Service Providers (MSPs). You can create and manage clients, set resource quotas, generate per-client billing reports, customize branding for each client, and curate client-specific app catalogs.

Client Management

Creating a Client

  1. Navigate to MSP > Clients from the sidebar
  2. Click Add Client
  3. Enter the client details:
    • Company name — the client’s business name
    • Contact email — primary contact for the client
    • Plan — the licensing plan for this client
  4. Configure resource quotas (see below)
  5. Click Create

The client appears in the client list and can have instances, users, and branding assigned to it.

Client List

Settings → MSP lists your customers. Every row is computed by the Control Center:

ColumnWhere it comes from
NodesNodes linked to the customer (on the node page: ⋯ → Link to client)
UsersThe customer’s portal users, plus the members of its client workspace when the customer belongs to one
MRRThe latest billing report for a period that ended in the last two months. Without one, an estimate: nodes × $10, shown with a ~
HealthHealthy; N offline when some of its nodes are offline (or the customer is suspended); Down when all of them are

Click a customer for its details, quotas, billing reports and app catalog.

Resource Quotas

Each client can have resource quotas that limit their usage within the Control Panel. Quotas prevent any single client from consuming excessive resources.

Available Quotas

QuotaDescription
max_serversMaximum number of Cloud OS instances the client can register
max_usersMaximum number of user accounts for the client
max_apps_per_serverMaximum number of applications per server
storage_quota_gbMaximum total storage across all instances in gigabytes

Setting Quotas

  1. Open the client detail page
  2. Navigate to the Quotas tab
  3. Set the desired limits for each quota
  4. Click Save

When a client reaches a quota limit, new resources of that type cannot be added until existing resources are removed or the quota is increased.

Quota enforcement is checked at the time of resource creation. Existing resources are not removed if a quota is lowered below current usage, but no new resources can be added until usage falls below the new limit.

Per-Client Billing Reports

The Control Panel generates billing reports for each client based on their resource usage and hosting costs.

Report Contents

  • Server count — nodes linked to the customer at the end of the period (billed at $10 per node)
  • Hosting costs — costs from provisioned servers (Hetzner Cloud, DigitalOcean)
  • License fees — based on the client’s plan and instance count
  • Total monthly cost — aggregated billing amount

Generating Reports

  1. Navigate to MSP > Billing
  2. Select the client and the billing period
  3. Click Generate Report
  4. Export the report as PDF or CSV

Reports can be generated for individual clients or as a summary across all clients.

White-Label Branding

The Control Panel supports white-label branding so that each client sees a customized interface with their own company identity.

Branding Options

SettingDescription
logo_urlURL to the client’s logo image
favicon_urlURL to the client’s favicon
company_nameCompany name displayed in the header and title
primary_colorPrimary brand color (hex value)
secondary_colorSecondary brand color (hex value)
accent_colorAccent color for highlights and buttons (hex value)
custom_domainCustom domain for the client’s Control Panel access
custom_cssAdditional CSS for advanced customization

Configuring Branding

  1. Open the client detail page
  2. Navigate to the Branding tab
  3. Upload a logo and favicon, or provide URLs
  4. Set the color scheme
  5. Optionally configure a custom domain
  6. Add custom CSS if needed
  7. Click Save

The branding changes take effect immediately for users belonging to that client.

Custom domain and TLS

Save the domain first (for example portal.acmehosting.io). Settings → Branding then shows the records to add at the customer’s DNS provider. Either one proves the domain:

RecordNameValue
CNAMEthe domainthe Control Center’s host (shown on the page)
TXT_quazzar-verify.<domain>quazzar-verify=<token> (shown on the page)

Click Recheck after adding it. The domain row shows where it stands:

StatusMeaning
TLS pending DNSNeither record is in place yet
Issuing TLSDNS is verified; the certificate is issued on the first HTTPS request to the domain
TLS ✓A valid certificate is served, with its issuer and expiry date. It turns amber 14 days before expiry
TLS errorDNS was verified more than a day ago and no valid certificate is served yet, or the certificate expired

Certificates are issued by the Control Center’s reverse proxy (on-demand TLS), not by the Control Center itself, so the status is observed from outside: the check connects to the domain over HTTPS and reads the certificate it gets. Changing the domain starts verification over with a new token.

Custom CSS

The custom_css field accepts arbitrary CSS that is injected into the Control Panel frontend for the client’s users. This allows fine-grained visual customization beyond the color settings.

Example use cases for custom CSS:

  • Hiding specific navigation items
  • Adjusting font sizes or families
  • Customizing the login page layout

Client App Catalogs

Each client can have a curated app catalog that controls which applications are available to their instances.

How App Catalogs Work

By default, clients have access to the full Cloud OS app template library. You can restrict this by creating a custom catalog:

  1. Open the client detail page
  2. Navigate to the App Catalog tab
  3. Toggle individual apps on or off
  4. Click Save

Only apps enabled in the client’s catalog will be available for installation on their Cloud OS instances.

This feature is useful for:

  • Restricting clients to approved applications only
  • Offering different app tiers based on the client’s plan
  • Preventing installation of resource-heavy apps on clients with small quotas

Tenant Isolation

Each client’s data is isolated at the database level using a TenantID. Every API request is scoped to the authenticated user’s tenant, ensuring that clients cannot access each other’s instances, users, or configuration.

The JWT token includes the TenantID claim, which the backend uses to filter all queries to the correct tenant.

API

MethodPathDescription
GET/api/msp/clientsCustomers with nodes, nodes_online, users, mrr_cents, mrr_source (billing_report | estimate) and health (ok | degraded | down)
GET/PUT/api/msp/branding/{clientID}Branding
GET/api/msp/branding/{clientID}/domain-statusCustom domain: DNS records to add, dns_verified, tls_status (none | pending_dns | issuing | active | error), tls_issuer, tls_expires_at, checked_at, error
POST/api/msp/branding/{clientID}/domain-status/recheckCheck DNS and TLS now

Next Steps