Files
archy/docs/release-verifier-appointment.md
T

5.6 KiB

Production publication verifier appointment

publish-release-assets.sh authenticates both OTA and ISO declarations through release_payload.py production / production-iso, before publisher API access. The staged candidate is never executed. There is no unsigned publication mode. native is only an ELF-format check, and unsigned manifest preparation is only staging; neither establishes build provenance or publication authorization. Unsigned UAT continues through build-iso-uat.py and docs/unsigned-uat-iso.md; its receipts cannot satisfy the production gate.

Operator inputs (prepare later, independently of candidate JSON)

The only appointment path is /etc/archipelago/release-publication/appointment.json. No environment variable or CLI option overrides it. An authorized root operator must install the reviewed appointment, verifier, build receipts and underlying build evidence into protected custody. Every ancestor must be root-owned and not group/other writable; every file must be root-owned, regular, read-only (0444 or 0555), with no symlink anywhere in its path. /tmp, user home directories and candidate checkout custody fail. This tool neither creates appointments nor promotes a candidate to authority.

Required reviewed inputs:

  1. An independent, already production-verified native verifier, its exact SHA256 and original source/build evidence. The existing installed native from accepted source c32a925647eab63ba0f1cac7e6bd135b857d5b7b is a possible operator input, not implicitly appointed by this patch. Obtain its exact hash, source tree, Cargo.lock digest, version, build command and production-root configuration from its retained build/acceptance record. Do not infer these from a filename, a successful exit, a new candidate, or an installed path.
  2. The candidate's actual clean-build receipt and frozen build evidence, including exact ELF SHA256, full commit and tree IDs, Cargo.lock SHA256, version, target, release profile, actual build command and proof that no test root override was used. Record source cleanliness at build time and retain the input inventory/log. Do not retrospectively label arbitrary ELF bytes with the checkout's current commit. The root operator reviews that evidence before appointing its receipt hash. Missing evidence blocks production publication.
  3. A clean checkout at that exact commit/tree, with matching backend/frontend versions and annotated vVERSION tag, reviewed mirror parity, and separately authorized production-signed OTA and ISO declarations. No private key or seed is needed by the verifier or appointment.

Use full lowercase hashes below; angle-bracket values are required operator inputs, not runnable defaults. Paths can differ except for the fixed appointment path. Recommended custody is the same root-owned directory.

Each build receipt (one for the independent verifier, one for the candidate):

{
  "schema": "archipelago-production-build-v1",
  "clean": true,
  "source_commit": "<40 hex actual build commit>",
  "source_tree": "<40 hex actual build tree>",
  "cargo_lock_sha256": "<64 hex actual core/Cargo.lock hash>",
  "backend_sha256": "<64 hex actual ELF hash>",
  "version": "<actual version>",
  "target": "x86_64-unknown-linux-gnu",
  "build_profile": "release",
  "build_command": "<actual recorded build command>",
  "test_root_override": false,
  "release_root": "did:key:z6Mkfu5LT8d4DjETtrkATvHh9Dvcbnr7zBCUwfau8Sw7DLWT",
  "evidence": {
    "path": "/etc/archipelago/release-publication/<verifier-or-candidate>-build-evidence.json",
    "sha256": "<64 hex frozen evidence bytes>"
  }
}

The evidence is retained independently reviewed build output, not a signature made by the candidate. Its format is retained as produced; the gate pins its bytes, while operator appointment is the authority for its provenance. This is an operator-appointed build record, not a claim of independently reproduced builds.

Appointment:

{
  "schema": "archipelago-release-appointment-v1",
  "release_root": "did:key:z6Mkfu5LT8d4DjETtrkATvHh9Dvcbnr7zBCUwfau8Sw7DLWT",
  "verifier": {
    "path": "/etc/archipelago/release-publication/production-verifier",
    "sha256": "<64 hex independently accepted verifier hash>",
    "build_receipt": {
      "path": "/etc/archipelago/release-publication/verifier-build.json",
      "sha256": "<64 hex verifier receipt bytes>"
    }
  },
  "releases": {
    "<VERSION>": {
      "path": "/etc/archipelago/release-publication/candidate-build.json",
      "sha256": "<64 hex candidate receipt bytes>"
    }
  }
}

After operator setup, the local, read-only gates are:

python3 -B scripts/release_payload.py build --version VERSION --backend /absolute/path/to/archipelago
python3 -B scripts/release_payload.py production /absolute/path/to/manifest.json --version VERSION --backend /absolute/path/to/archipelago
python3 -B scripts/release_payload.py production-iso /absolute/path/to/image.iso.sha256.json --version VERSION --backend /absolute/path/to/archipelago

These commands do not sign, install, upload or appoint. production-iso verifies the signature; the publisher separately checks ISO artifact name, hash, size and checksum file before API access. The verifier and document are executed/read from sealed memfds, with loader-injection environment variables excluded, so changing their original path after validation cannot change the cryptographic decision. The independently appointed verifier must differ from the candidate bytes.

Publication remains a separately authorized operation. Source/fixture success does not qualify a new production artifact, installed cutover or operator UAT.