Documentation · The Lagstyr handbook
Installing Lagstyr
The host consumes an immutable release and lagstyr-install-kit.tar.gz. It does not clone the
repository, compile binaries or resolve Python dependencies at runtime. The kit’s
infra/install/README.md is the detailed command reference. Use the release and platform checks in
Planning an installation before these steps.
Commands here assume a root Bash session on the fresh supported host. Replace vX.Y.Z and every
example customer value with reviewed installation inputs. They describe the installation procedure;
the current currentRelease: none policy prevents a supported production install.
Prepare the customer contract and secrets
Start from the kit’s infra/install/customer.example.json and validate against its
infra/install/config.schema.json. Keep schemaVersion: 1. Supply your installation identity,
isolation boundaries, operating package, exact release tag, DNS/TLS, PostgreSQL files, S3-compatible
storage, backup destinations, identity settings, privacy inventory, capacity and service lists.
Each declared endpoint is the exact health/contract probe URL that must return a successful
response. Each requiredVariables entry must exist and be non-empty in the named environment
file. Prepare private, root-owned files with only the consuming service’s group access. The JSON
contains paths and configuration; credential values belong in the secret store and environment
files. See Securing your installation.
Supply the owner/migrator, confined kernel and per-workload database identities; the runtime DML key; operator bootstrap credentials; the configured OIDC client; scoped object-store credentials; and working offsite backup and monitoring bindings. Install only the public age backup recipient. Escrow its private identity separately before the first encrypted snapshot.
Customer-lane OAuth is optional and takes effect only when services.rustWorkers enables
integration-token-broker. Then set connectors.integrationOAuth: tokenSealingKeyFile and
tokenDeliveryKeyFile each name a root-owned 0400/0600 file holding 64 lowercase hex characters,
and the two keys must differ. clientSecretCredentials maps a credential name (^[a-z0-9-]{1,64}$)
to each OAuth client secret file. Preflight refuses equal or malformed keys, a disabled console and a
missing or non-HTTPS CONSOLE_PUBLIC_ORIGIN in the identity environment, because every provider
redirect returns to CONSOLE_PUBLIC_ORIGIN followed by /integration-oauth/callback. The unit
wiring binds the sealing key and client secrets to the broker alone and the delivery key to the
kernel and broker alone. Mint the broker’s machine credential, grant its integration_token_broker
role, admit its egress to the token and revocation hosts your releases declare, and escrow both
keys beside the age identity. Connecting a provider is later operator work; see
Building and commissioning integrations.
Choose a founding governance.authorityProfile decision: the exact pinned
starter_operational_obligations@1 template, or intentionally_inert. Keep console.sourceId at
the schema-pinned value. Starter adoption selects a bounded operational-obligation authority
profile; deliberate inertness brings up infrastructure with governed business proposals unavailable.
Download and verify before executing
Store a read-scoped release token as GH_TOKEN in root-owned mode-0600
/etc/lagstyr/deploy.env. Run the bootstrap in a private root-owned directory and check GitHub’s
server-recorded asset digest before extracting or executing the downloaded kit:
set -euo pipefail
umask 077
set -a
. /etc/lagstyr/deploy.env
set +a
tag=vX.Y.Z
work="$(mktemp -d /var/lib/lagstyr-bootstrap.XXXXXX)"
gh release download "$tag" --repo lagstyr/lagstyr \
--pattern lagstyr-install-kit.tar.gz --dir "$work"
server_digest="$(gh api "repos/lagstyr/lagstyr/releases/tags/$tag" \
--jq '.assets[] | select(.name == "lagstyr-install-kit.tar.gz") | .digest')"
[[ "$server_digest" =~ ^sha256:([0-9a-f]{64})$ ]]
printf '%s %s\n' "${BASH_REMATCH[1]}" "$work/lagstyr-install-kit.tar.gz" | sha256sum -c -
while IFS= read -r member; do
case "$member" in lagstyr-install-kit|lagstyr-install-kit/*) ;; *) exit 1 ;; esac
done < <(tar -tzf "$work/lagstyr-install-kit.tar.gz")
tar -xzf "$work/lagstyr-install-kit.tar.gz" -C "$work" \
--no-same-owner --no-same-permissions
GitHub Release authority, the asset digest and the read token form this bootstrap trust root. The pull-deploy verifier independently checks the complete release’s tag/commit binding, artifact manifest, digests, publisher attestations, provenance, SBOM and version agreement before staging. The bootstrap digest check alone is not that complete verification.
Provision the host foundation
The kit includes nix/nixos-module.nix. For a module-managed host, preserve the verified kit at a
persistent root-readable path and import the module into your host configuration:
{
imports = [ /etc/nixos/lagstyr-install-kit/nix/nixos-module.nix ];
services.lagstyr = {
enable = true;
configurationFile = /etc/nixos/lagstyr-customer.json;
releaseTag = "vX.Y.Z";
rustWorkers = [ "erasure-worker" "embedder" "render-report" ];
pythonWorkers = [ "document_indexer" "extractor" ];
activateRuntime = false;
};
}
These worker lists match the example only; yours must exactly match the customer JSON. First
run nixos-rebuild switch with activateRuntime=false to provision the foundation without
starting an absent release. The module supplies PostgreSQL, extensions, users, units, timers and
configuration wiring. This rebuild does not replace release verification and activation.
A worker that belongs to an optional pack refuses to start unless that pack is activated, and preflight fails while it remains in the configured service lists. Either activate the pack, which is a governed decision like the rest of customer setup, or leave the worker out.
Runtime-role provisioning authenticates as the real kernel and inventory-selected workload logins, then attempts hostile catalogue, trigger, ownership, role-escalation and public-schema operations in rollback-bounded sessions. Installation stops if any attempt succeeds. Retain the successful confinement proof with the acceptance record; reading role grants from the catalogue is not an equivalent test.
Install and retain the acceptance record
For the fresh-host second-operator exercise, use the evidence wrapper from the same verified kit:
"$work/lagstyr-install-kit/infra/install/second-operator-exercise.sh" \
--config /etc/nixos/lagstyr-customer.json --tag "$tag" \
--evidence-dir "/var/lib/lagstyr-evidence/G3-$tag" \
--operator "Second operator" --host-id "sanitized-fresh-host-id" \
--bootstrap-archive "$work/lagstyr-install-kit.tar.gz" \
--attest-no-source-checkout
The underlying installer is infra/install/install.sh --config FILE --tag TAG. It runs static
preflight, installs the operator kit and wiring, then uses the snapshot-first pull-deploy path.
The first staged loopback kernel authenticates the operator and records the reviewed founding
decision atomically. The temporary founding authority closes permanently.
Status 75 means a resumable pause. Retain the evidence directory and rerun the exact command after the reported condition is satisfied; do not discard attempts or bypass cooling controls. Clean starter adoption has no mandatory cooling pause. Other failures require diagnosis before retry. Raw exercise evidence is private; review the as-built exports before sharing them.
After successful first activation, set activateRuntime=true and rebuild to make runtime
enablement declarative. Confirm the active tag, passing preflight, configured units and smoke
results before starting customer setup.
Complete customer setup
Activation creates the founding decision and its bounded installation records. Later organisation, people, source and authority data come from an installation-authored setup manifest:
lagstyr-setup-bootstrap --manifest /secure/config/setup.json plan
lagstyr-setup-bootstrap --manifest /secure/config/setup.json status
The run --operator-email EMAIL phase proposes and approves the selected facts using the ordinary
governed path. Supply LAGSTYR_KERNEL_URL, LAGSTYR_OPERATOR_KEY and, for run,
LAGSTYR_OPERATOR_PASSWORD through the documented private environment. Additional
skills must first be selected by a reviewed profile revision. Retain the manifest and bootstrap
ledger; include the manifest in the encrypted lifecycle export.
Run setup diagnostics from the activated kit:
/opt/lagstyr/current/install-kit/infra/install/preflight.sh --mode setup \
--config /etc/lagstyr/install.json --report /var/lib/lagstyr/preflight/setup.json
A fresh installation is expected to have incomplete setup. This mode is a to-do list and does not gate infrastructure activation. Commission integrations and agents separately before admitting business work.