# Install trust artifacts
## Goal
Install the `law` runtime and the canon packages it executes from pinned,
checkable artifacts, so that every byte on the deployment host traces back
to a version and a hash the operator chose.
## Scope
Component `law` CLI, tool `0.1.1`, semantics `law.core/0.2` (as printed by
`law version`). Scenario: first install on a deployment host, or replacing
an install whose provenance is unknown. All names, versions, key ids, and
hashes below are synthetic examples.
## Applies to
| Branch | Coverage in this article |
|---|---|
| MCP + `law serve` | both servers ship from the same pinned supply; the install, hash, signature, and toolchain procedure below feeds both branches |
## Prerequisites
- A host with one supported install route (see [Install](/cli/install/)):
npm (`@arxo/cli`), Homebrew (`arxohq/tap/law`), the install script,
APT (`arxo-law`), or a GitHub Releases archive.
- The pinned release identifier your change record names (created-example:
`law 0.1.1`, binary hash
`sha256:78dea06ce928547e87bd9875a2556cc663def37cbb78c8b04aa0da57839c95d7`).
- The publisher public keys your policy trusts (created-example key ids;
format and trust wiring are real: `--trust`, `trustedKeys`).
## Steps
1. Fetch the artifact only from the pinned supply route. For the archive
route, download the archive together with its adjacent `.sha256` file
(real: every release archive ships with one).
2. Check the archive bytes against the `.sha256` file before unpacking
(operator-policy-example command using the OS tool):
`sha256sum -c law-0.1.1-linux-x64.tar.gz.sha256`.
3. Install, then print identity:
`law version` and `law version --json`.
4. Resolve canon dependencies into the project with `law install`
(real flags: `--project
`, `--registry `,
`--offline`, `--dry-run`, `--recover`, `--json`), then record
`law.toml` + `law.lock` as the pinned dependency closure.
5. For each `.arxo` container you deploy, run
`law inspect --verify --trust …`
(real flags; `--trust` is repeatable). Trusted keys may also come
from user/project configuration `trustedKeys` (real, read from the
project or the nearest `law.toml`).
6. Pin the toolchain that built from source, if you build rather than
install: the toolchain file (`rust-toolchain.toml`) and the
dependency lockfile (`Cargo.lock`) under the engine workspace are
the real pin files — record their revisions in the change record.
Each file also exists in the matching service workspaces
(MCP host, HTTP service).
## Expected result
- `law version` prints the tool line, the semantics line, and the binary
hash line; `law version --json` prints the same as fields `tool`,
`semantics`, `std`, `binaryHash` (all real field names).
- `law inspect … --verify` prints per-file hashes, `integrity`, and a
`signature` status line followed by one line per attestation
(` trusted|not in --trust — signature valid|INVALID…`).
- Exit code `0` on every check above.
## Result check
Compare the printed `tool` + `binaryHash` against the pinned values from
Prerequisites character for character; compare each container's `contentHash`
and signature key ids against the release manifest. Any mismatch is a
failed install, not a warning to waive.
## Failures and diagnostics
- `bad attestation in the archive` (refusal): at least one signature is
cryptographically invalid. Implementation behavior: a bad signature is
always a refusal, with or without `--trust`. Re-fetch from the pinned
route; do not install.
- `no signature from a --trust or trustedKeys key` (refusal): the archive
verified structurally but no attestation chains to your trusted keys.
Implementation behavior: this refusal happens only when the trusted-key
list is non-empty. Either the artifact is not yours to trust, or the
key list is wrong — determine which before proceeding.
- `LPK-E0101` unknown parameter: the flag you typed does not exist on that
subcommand (for example `--help` on `install`). Re-read `law --help`.
- Hash mismatch on the archive: treat the bytes as untrusted and re-fetch;
never install mismatched bytes and note the incident.
## Signature presence versus mandatory-verification policy
These are two different things; do not conflate them:
- Signature presence (implementation behavior): `.arxo` containers may
carry publisher/executor attestations (`law sign --key
[--role publisher|executor]`); `law inspect --verify` reports
each attestation's validity. A bad signature always refuses.
- Mandatory verification (operator-policy-example, not a default): the rule
"this host installs only containers with a valid signature from key set
K" is enforced by always passing `--trust` (or configuring
`trustedKeys`) and refusing to proceed on the `no signature from…`
refusal. The tool default without `--trust` still rejects bad
signatures but does not require any signature. If your policy demands
mandatory verification, encode it in your install runbook and audit for
bare `unpack`/`inspect` runs without `--trust`.
## Support boundaries
- Supported: hash and signature checks described above on released
artifacts; Ed25519 keys made by `law key new --out ` (real: the
secret lives only in that file, mode `0600`).
- Reference setting: the key ids, versions, and hashes in this article are
created-examples — substitute your release record.
- Out of scope: OS-level hardening, key-ceremony design, and registry
server operation are operator responsibilities, not tool behavior.
## Next step
For hosts without network access, continue with
[Offline and restricted-network operation](/operate/offline-restricted-network/); otherwise record the installed
versions and hashes and proceed to staging your first world.