> ## Documentation Index
> Fetch the complete documentation index at: https://devlookout.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Hosted installation and release publishing

> Operate the account-bound bootstrap and publish immutable Lookout releases.

> For the complete documentation index, see [llms.txt](https://devlookout.com/llms.txt). Markdown versions are available by appending `.md` to page URLs.

The public entry point should serve the generated `lookout-install.sh` byte-for-byte:

```sh theme={null}
(
  umask 077
  token_file=$(mktemp "${TMPDIR:-/tmp}/lookout-setup-token.XXXXXX")
  trap 'rm -f "$token_file"' EXIT HUP INT TERM
  printf '%s\n' 'SETUP_TOKEN' > "$token_file"
  curl -fsSL https://app.devlookout.com/install.sh | env LOOKOUT_SETUP_TOKEN_FILE="$token_file" sh
)
```

The authenticated Setup page embeds a short-lived single-use token in one command intended for the current blank agent terminal. The bootstrap accepts no arguments and requires only `LOOKOUT_SETUP_TOKEN_FILE`. Before downloading the release it posts the token through a bounded JSON request body to the setup connection endpoint, allowing the browser to display `Connected` immediately without consuming the claim token. `install/onboard.sh` then reads and removes the owner-only token file, performs parallel authoritative provider inventory from the orchestration host, deterministically selects a central Linux VM, consumes the token once, and binds the deployment identity and exact discovered scope to the authenticated account. The orchestration host is not added to the target scope. The returned scope is staged in an owner-only file and `install/fleet.js` loads only those VMs. It never expands the scope through Tailscale, neighbor discovery, or network scanning.

The installer proves possession of the local Ed25519 deployment identity and stages the deployment-only console credential. Access probes run in isolated workers with bounded parallelism. Provider-native access is attempted before OpenSSH, and failed account-level native methods are not retried for every SSH username or command. Every target downloads the pinned release directly, so the orchestration host does not recompress or relay the artifact. The installer validates signed heartbeats, removes temporary authorization and staging files, reports completion, and preserves automatic browser redirect. The setup token must never appear in a URL, process argument, cloud-init data, or logs.

Central heartbeat recovery uses `LOOKOUT_CENTRAL_HEARTBEAT_TIMEOUT_MS`, defaulting to five minutes. Configure `LOOKOUT_RESEND_API_KEY` and `LOOKOUT_RECOVERY_EMAIL_FROM` on the hosted service to deliver recovery email. Dashboard notification and recovery-token generation remain active even when email delivery is not configured.

## Publishing

A `vMAJOR.MINOR.PATCH` tag runs `.github/workflows/release.yml`. Configure the repository variable `LOOKOUT_PUBLIC_RELEASE_BASE_URL` to the HTTPS public distribution prefix (for example `https://releases.lookout.security`). The workflow requires an annotated tag whose signature GitHub reports as verified, tests the exact commit, creates a reproducible archive, records its SHA-256 digest, renders a bootstrap that pins that version and public URL, creates a GitHub release, and emits GitHub build-provenance attestations. Release creation is intentionally non-overwriting: re-running an already-published tag fails rather than replacing assets. Enable GitHub's immutable-releases setting and a protected tag rule for `v*` on the production repository; the workflow alone cannot prevent an administrator from manually replacing an asset or tag.

The hosting/CDN deployment must copy `lookout-install.sh` and its referenced archive to public distribution storage without modifying them, serve them only over HTTPS, use an atomic object replacement, and retain the previous objects for rollback. The application repository may remain private; a private GitHub release URL itself cannot be the anonymous target. Promotion to the short URL is a separate, auditable deployment step so creating a release cannot silently change the public installer. Configure the CDN to prevent content transformation and return `Content-Type: text/x-shellscript; charset=utf-8` plus `X-Content-Type-Options: nosniff`.

The checksum embedded in the bootstrap prevents a changed or partial archive from executing. TLS authenticates the small bootstrap itself, while GitHub's signed artifact attestation provides independently verifiable provenance at promotion and audit time. The release includes production dependencies and a Node.js runtime. Every target verifies the same pinned checksum, extracts to a staging directory, atomically swaps the active release, and restarts the service. Target VMs do not download Node.js or run npm. Release construction rejects symlinks and submodules, and the target rejects absolute or parent-traversing archive members before extraction.

For a release, first update `package.json` and its lockfile to the same semantic version, commit, and create a signed tag:

```sh theme={null}
git tag -s v0.2.0
git push origin v0.2.0
```

Before promoting the generated script, verify its attestation and test it against a disposable Linux VM. The CDN/service configuration and DNS for the real `get.lookout…` domain live outside this repository and must be provisioned before the short command can work.
