HailBytes SAT Tutorial

MSSP Multi-Tenancy & White-Label

Run HailBytes SAT as a managed security service: one organization per client, isolated data, seat caps, and a compliance readout you send to each client under your own brand.

Read this first: which deployment shape you are in

One instance carries multiple client organizations when the MSSP operates the platform, with row-level data isolation, per-client sending identities, and per-client hostnames. Clients that require their own branding, their own identity provider, or self-service administration need a dedicated instance.

That is a hard line, not a configuration preference. Branding is one instance-wide record and single sign-on allows one configuration per provider per instance, so a shared instance can only ever wear one brand and answer to one identity provider — yours. This tutorial covers the shape that works today: your team drives the platform and your clients receive reports. An earlier version of this page taught per-client branding and per-client identity providers on a shared instance; that was wrong and has been removed.

Architecture

A single HailBytes SAT instance hosts many organizations. An organization is a data boundary: users, groups, campaigns, training and results are scoped to it, and that scoping is enforced in the query layer and covered by tests. Your staff cross between organizations through membership in more than one, or through an audited Impersonate action.

  • Isolated per organization: users, groups, campaigns, training assignments, results.
  • Configurable per organization: a seat cap (max_users).
  • Configurable per client: the sending identity (SMTP sending profile) and a custom hostname, so mail and links carry the right domain for each client.
  • Instance-wide, not per organization: branding, the single-sign-on configuration, the SCIM endpoint, and the audit log. All four are yours as the operator.

How many organizations one instance carries is a throughput question, so size the instance for the campaign volume you are actually driving rather than a client count — see pricing for the size ladder. We do not publish an organizations-per-instance figure: we have no measured basis for one, and the number that used to appear here was extrapolated rather than tested.

Step 1: Create a Client Organization

The organizations API requires the modify_system permission. That is deliberate for the shape described above — organizations are created by your operations team. It also means a client administrator cannot create organizations or invite their own users; if a client needs that, they need their own instance.

POST /api/organizations/
{
  "name":      "Northwind Trading",
  "slug":      "northwind",
  "contact":   "[email protected]",
  "max_users": 250,
  "is_active": true
}
# 201 Created, returns the organization including its id

Step 2: Set the Instance Branding to Your Firm

Branding is a single record for the whole instance. Set it once, to your own brand — that is the white-label story: every screen, every report and every outbound email carries your firm rather than HailBytes.

PUT /api/branding
{
  "organization_name": "Example MSSP Security",
  "primary_color":     "#0F4C81",
  "secondary_color":   "#1A2832",
  "email_from_name":   "Example MSSP Security",
  "support_email":     "[email protected]"
}

PUT /api/branding/logo            # multipart upload
PUT /api/branding/favicon         # multipart upload

Public assets are served at /api/branding/logo/view and /api/branding/favicon/view, and the login page renders them before authentication. There is no per-organization override: a second client cannot be given a second brand on the same instance. Where a client contract requires their own logo on the portal, deploy them a dedicated instance and brand that one to them.

Step 3: Add Members & Scope Groups

POST /api/organizations/{id}/members
{
  "user_id": 42
}

# 200 OK        assigned
# 409 Conflict  the organization is at its max_users seat cap
# 404 Not Found the org does not exist, or is outside your tenant boundary

Your own staff can be members of many organizations; a client's people belong to one. Raise max_users on the organization record to admit more users after a 409.

Step 4: Provision from Your Identity Provider (Optional)

SCIM 2.0 provisioning maps SCIM groups onto HailBytes SAT organizations, so pushing a group from your directory creates or updates the matching client organization and its membership. The endpoint is instance-wide: connect your Entra ID or Okta tenant to it, not each client's. A client IdP connected to a shared instance would see every organization on it, so per-client directory integration belongs on a dedicated instance.

Step 5: Single Sign-On — One Provider per Instance

SAML and OIDC single sign-on is configured once per provider for the whole instance — one Entra ID configuration, one Google configuration. Use it for your own operators. There is no per-organization identity provider, and no host-based provider selection, so a client that insists on authenticating its users against its own directory needs a dedicated instance.

Step 6: Send Per-Organization Compliance Reports

This is the client-facing deliverable in the MSSP-operated shape. The per-organization compliance card is genuinely org-scoped, and it is the artefact behind the consortium pattern of one instance serving many member institutions.

for org_id in $(curl -s -H "Authorization: Bearer $KEY" \
                  https://sat-mssp.example.com:3333/api/organizations/ \
                | jq -r '.[].id'); do
  curl -H "Authorization: Bearer $KEY" \
       "https://sat-mssp.example.com:3333/api/training/organizations/$org_id/compliance.csv" \
       -o "compliance-$org_id-$(date +%Y-%m).csv"
done

The instance-wide executive report at /api/reports/executive takes since and format=html|json|csv. It is scoped to the calling account and rendered in the instance branding — it does not take an org_id, so treat it as your internal or portfolio-level readout and build the per-client document from the compliance CSV above plus your own report template.

Audit & Impersonation

Staff who need to act inside a client organization use Impersonate. Every impersonation is written to the audit log with the staff member's identity and the target account, queryable via /api/audit?event_type=impersonation. Note that the audit log is instance-wide rather than partitioned by organization, which is another reason a client wanting direct read access to their own audit trail should be on a dedicated instance.

Next Steps

SAML / OIDC SSO

Configure single sign-on for your own operator accounts.

View Tutorial →

SCIM 2.0 Provisioning

Auto-create and deactivate users from your directory.

View Tutorial →

Related Tutorials

Get the Free HailBytes SAT Getting Started Guide

A 7-part email series covering everything from your first deployment to advanced configuration and real-world workflows. One email per day, no spam.