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
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
66 lines
3.4 KiB
Markdown
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).
|