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

66 lines
3.4 KiB
Markdown

# 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).