PSA/ee/appliance/docs/registration-install-flow.md
Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

3.4 KiB

Appliance registration → install flow

An on-prem appliance gets its identity before it boots: the customer registers, the alga-license control plane mints a tenant in the global registry and a one-time install code, and the appliance redeems that code at first-boot setup to come up already bound to its tenant. The ISO is generic — the install code is the only per-customer artifact.

The path a customer takes

  1. Register (nm-store). The customer submits company, contact, and edition. nm-store calls alga-license POST /register-tenant, which creates the tenant_registry row, mints a one-time install code carrying the new tenant_id (plus an entitlement for paid editions), and returns a presigned, time-boxed ISO download link. The install code and link are emailed to the contact.
  2. Download the generic appliance ISO from the presigned link.
  3. Install. On the first-boot setup screen the operator enters the install code (and sets the admin password). The appliance redeems the code and comes up under the registry-minted tenant.
  4. Reinstall (if needed). Install codes are single-use. To rebuild an appliance, re-issue a fresh code for the same tenant (below).

What happens at install (under the hood)

The host-service setup engine (ee/appliance/host-service/setup-engine.mjs, via install-code.mjs) redeems the code against ALGA_LICENSE_SERVICE_URL/register, which returns the tenant_id, the edition, and — for paid editions — the first license JWT, a per-appliance credential, and the check-in URL. Those flow into two Secrets the in-cluster bootstrap consumes:

  • appliance-initial-tenant gains INITIAL_TENANT_ID. The bootstrap (helm/templates/appliance-bootstrap-configmap.yaml) runs create-tenant, which adopts that id instead of generating one, so the appliance's local tenant row is the registry tenant. (No install code → create-tenant generates a id as before; nothing else changes.)
  • appliance-license-seed carries the edition + (paid) license token + connected credential/check-in URL. The bootstrap seeds license_state from it: essentials runs at the essentials tier with no token; paid is licensed from first boot and refreshes daily via check-in.

A bad, expired, or already-used code — or an unreachable license service — blocks the install with a clear message; the appliance never silently self-generates a tenant.

Re-issuing an install code (reinstall recovery)

Because codes are single-use (and consumed when the install applies them), a reinstall needs a fresh one for the same tenant. Re-issue resolves the tenant by contact email or tenant_id, revokes any still-unclaimed codes, and mints a new code + presigned link bound to the same tenant_id (re-attaching the paid entitlement). The rebuilt appliance comes back under its original identity.

Service endpoint: POST /install-codes/reissue on alga-license (service-authed), surfaced through the nm-store portal.

Operator notes

  • The install code is the per-customer gate; the ISO itself is generic and not secret. The download link is presigned (registration-gated + time-boxed), not public.
  • The admin password is set at install — it never travels through registration or email.
  • A failed install after the code is applied needs a re-issued code (the original is already consumed).