Docs / Reference
Verify what you run
Check the installer download, verify the system image and its SBOM with cosign, and know what rime update checks and what it does not.
On this page 6 sections
The installer download
The published installer is apex-os-netinstall-x86_64.iso (APEX-OS v2.1.0),
1,902,344,192 bytes, SHA-256
7208b6fd5c2641e3e1bb035eac0d1c642f4f7eda85b1ba3295993b8ec0227248.
sha256sum -c apex-os-netinstall-x86_64.iso.sha256
The ISO is not signed. The checksum sits on the same release page as the file, so it proves the download is complete and uncorrupted, not who made it.
You can check what the ISO installs. It downloads the system image by digest,
sha256:148f57de20e1db04ee672037791d10d6d6d02a188784b6f213255c7d50153a92, pinned
in the registry as ghcr.io/andrenijman/apex-os:netinstall-v2.1.0. The
workflow that gives a release image that permanent tag checks its signature
first. You can check the signature yourself:
cosign verify ghcr.io/andrenijman/apex-os:netinstall-v2.1.0 \
--certificate-identity-regexp '^https://github\.com/AndreNijman/(apex|rime)-os/\.github/workflows/build-image\.yml@' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
The system image
Every Rime image is signed by CI with cosign, keyless, under a GitHub Actions identity. CI verifies its own signature and attestation before it moves any tag. Since the rename, that identity is:
https://github.com/AndreNijman/rime-os/.github/workflows/build-image.yml@refs/heads/main
Images built before the rename were signed as AndreNijman/apex-os. Current
Rime clients accept both.
On your machine
rime trust # what was checked when the booted image arrived, and what the next update will check
rime trust --verify # does the registry hold a signature and an SBOM attestation for the image I am running?
rime trust --gate # would the next update be accepted? exits 1 if it would be refused
None of these needs root. Plain rime trust reads local files only. --verify
and --gate ask the registry, and a registry that cannot be reached is reported
as unavailable, never as unsigned. Add --json for a program.
--verify and --gate answer different questions. The tag your machine follows
moves on every build, so the image you run and the image you would update to are
usually different. Only the next one can be refused, so that is the one the
gate checks.
With cosign, from any computer
cosign is not installed on Rime, and Fedora does not package it. Run it on a computer that has it:
cosign verify ghcr.io/andrenijman/rime-os:rime \
--certificate-identity https://github.com/AndreNijman/rime-os/.github/workflows/build-image.yml@refs/heads/main \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
The same image is also published, and signed, as
ghcr.io/andrenijman/apex-os:apex and under the other tags. To check the exact
image a machine runs, use its digest (ghcr.io/andrenijman/rime-os@sha256:…)
in place of the tag.
The SBOM attestation
Every build attaches a software bill of materials as a signed attestation. It is an SPDX document listing every package in the image (9,830 in a recent build), with name, version, purl and CPE identifiers: the RPMs, the npm trees inside the bundled Claude and ChatGPT desktop apps, and the Go and Rust modules inside binaries. It is signed by the same identity as the image and recorded in the public Sigstore transparency log; the build fails if no log entry is made.
It is a flat package list. It carries no file inventory and no dependency graph, because the full document is too large for the transparency log.
To read it:
cosign verify-attestation \
ghcr.io/andrenijman/rime-os@sha256:... \
--type spdxjson \
--certificate-identity-regexp '^https://github\.com/AndreNijman/(apex|rime)-os/\.github/workflows/build-image\.yml@' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
| jq -r '.payload | @base64d | fromjson | .predicate.packages[] | "\(.name) \(.versionInfo)"'
For the full file-level document with the dependency graph, generate it from the public image yourself. It needs about 16 GB of memory and fifteen minutes:
syft "registry:ghcr.io/andrenijman/rime-os@sha256:..." -o spdx-json
What rime update checks
Before it deploys anything, rime update verifies the image the registry serves
now. All of these must hold:
- the signature payload’s hash matches the digest that named it;
- the ECDSA signature verifies over that payload, with the key in the signing certificate;
- the certificate chains to the Sigstore root pinned in the image, at
/usr/share/rime-os/trust/fulcio-root.pem, not to a root the signature supplied; - the certificate names the expected identity, issued by GitHub’s token endpoint;
- the signed payload names this digest and this repository.
It also checks for the SBOM attestation (the provenance setting).
What it does not check
- The transparency log. Your machine does not check the Rekor entry, and
every report says “the transparency log was not checked”. It verifies the
certificate chain at the certificate’s own start time instead. This is the
posture of
cosign verify --insecure-ignore-tlog. To check the log, run cosign as shown above. - Anything bootc pulls on its own. The containers policy that bootc reads
accepts any image. Only
rime updateapplies the check; runningbootc upgradeyourself skips it. - The kernel at run time. Secure Boot on Rime covers the boot chain: shim, GRUB, and a kernel signed with Rime’s own key, which you enrol during the install. The kernel does not enforce module signatures and does not enter lockdown under Secure Boot.
The verification uses skopeo and openssl, which the image carries.
Changing what is enforced
The image’s defaults are signature=enforce and provenance=warn. To change
one on your machine, write only that key to /etc/rime/trust.conf; it wins over
the image’s default for that key. For example, to refuse any update whose SBOM
attestation is missing as well as one whose signature fails:
printf 'provenance=enforce\n' | sudo tee /etc/rime/trust.conf
tee replaces the file, so include every key you want to keep.
A value other than enforce, warn or off is ignored with a note naming the
file and line, so a typo never turns the check off. An unreadable file falls
back to the defaults. The full decision table is on
Updating.
On a machine installed from the v2.1.0 ISO
Until its first update, such a machine runs an older APEX-OS image. The same
commands start with apex (apex trust --gate), the settings file is
/etc/apex/trust.conf, and the client trusts only the old apex-os signer.
Install Rime covers the first update.