171 lines
9.9 KiB
Markdown
171 lines
9.9 KiB
Markdown
# Installer provenance
|
|
|
|
Reviewed on 2026-08-27. `installers.conf` is data, not a shell fragment: the
|
|
installer reads it only with `load_installer_provenance`. Its versions, URLs,
|
|
SHA-256 values, byte limits, and complete primary fingerprints are reviewed
|
|
inputs. No installer path may substitute a `latest` URL or execute fetched
|
|
content before the applicable verification succeeds.
|
|
|
|
## Key retrieval and verification
|
|
|
|
Each command below was run in a private temporary directory on 2026-08-27.
|
|
The resulting armored public key is vendored under `keys/`; each output was
|
|
checked with the listed complete primary fingerprint before it was committed.
|
|
|
|
| Key | Source URL | Expected primary fingerprint | Verification command |
|
|
| --- | --- | --- | --- |
|
|
| Terra 44 | `https://repos.fyralabs.com/terra44/key.asc` | `AE09157A4DE88B497EA1D5D300CDAB43DE226D6F` | `gpg --batch --with-colons --import-options show-only --import terra44.asc \| awk -F: '$1 == "fpr" { print $10; exit }'` |
|
|
| Anthropic Claude Code | `https://downloads.claude.ai/keys/claude-code.asc` | `31DDDE24DDFAB679F42D7BD2BAA929FF1A7ECACE` | `gpg --batch --with-colons --import-options show-only --import claude-code.asc \| awk -F: '$1 == "fpr" { print $10; exit }'` |
|
|
| Bun releases | `https://keys.openpgp.org/vks/v1/by-fingerprint/F3DCC08A8572C0749B3E18888EAB4D40A7B22B59` | `F3DCC08A8572C0749B3E18888EAB4D40A7B22B59` | `gpg --batch --with-colons --import-options show-only --import bun.asc \| awk -F: '$1 == "fpr" { print $10; exit }'` |
|
|
| RPM Fusion free | `https://download1.rpmfusion.org/free/fedora/RPM-GPG-KEY-rpmfusion-free-fedora-2020` | `E9A491A3DE247814E7E067EAE06F8ECDD651FF2E` | `gpg --batch --with-colons --import-options show-only --import rpmfusion-free.asc \| awk -F: '$1 == "fpr" { print $10; exit }'` |
|
|
| RPM Fusion nonfree | `https://download1.rpmfusion.org/nonfree/fedora/RPM-GPG-KEY-rpmfusion-nonfree-fedora-2020` | `79BDB88F9BBF73910FD4095B6A2AF96194843C65` | `gpg --batch --with-colons --import-options show-only --import rpmfusion-nonfree.asc \| awk -F: '$1 == "fpr" { print $10; exit }'` |
|
|
| lionheartp/Hyprland COPR | `https://download.copr.fedorainfracloud.org/results/lionheartp/Hyprland/pubkey.gpg` | `97E23476C89635135407C7D5E9BA41342C4B2995` | `gpg --batch --with-colons --import-options show-only --import hyprland-copr.asc \| awk -F: '$1 == "fpr" { print $10; exit }'` |
|
|
| Flathub | `https://flathub.org/repo/flathub.flatpakrepo` | `6E5C05D979C76DAF93C081354184DD4D907A7CAE` | `awk -F= '/^GPGKey=/{print $2}' flathub.flatpakrepo \| base64 --decode \| gpg --batch --with-colons --import-options show-only --import \| awk -F: '$1 == "fpr" { print $10; exit }'` |
|
|
| Claude Desktop Extra | `https://patrickjaja.github.io/claude-desktop-extra/gpg-key.asc` | `825A7D15D78BABE45646D5DF382409F597908867` | `gpg --batch --with-colons --import-options show-only --import claude-desktop.asc \| awk -F: '$1 == "fpr" { print $10; exit }'` |
|
|
|
|
The retrieval command for every direct key was:
|
|
|
|
```bash
|
|
curl --fail --location --connect-timeout 10 --max-time 60 --output KEY.asc SOURCE_URL
|
|
```
|
|
|
|
## Reviewed publisher records and artifact locations
|
|
|
|
The key sources above are supported by these publisher-controlled records:
|
|
|
|
- `https://github.com/terrapkg/packages/blob/frawhide/README.md`
|
|
- `https://github.com/terrapkg/packages/discussions/7736`
|
|
- `https://code.claude.com/docs/en/setup`
|
|
- `https://github.com/oven-sh/bun/releases/tag/bun-v1.4.0`
|
|
- `https://github.com/oven-sh/bun/blob/main/dockerhub/distroless/Dockerfile`
|
|
- `https://github.com/nodejs/node/releases/tag/v24.20.0`
|
|
- `https://github.com/nodejs/node/blob/main/README.md`
|
|
- `https://github.com/openai/codex/releases/tag/rust-v0.150.1`
|
|
- `https://github.com/openai/codex/blob/main/.github/workflows/rust-release.yml`
|
|
- `https://github.com/rustdesk/rustdesk/releases/tag/1.4.9`
|
|
|
|
The reviewed immutable artifact and repository URLs are:
|
|
|
|
- `https://github.com/oven-sh/bun/releases/download/bun-v1.4.0/bun-linux-x64.zip`
|
|
- `https://github.com/oven-sh/bun/releases/download/bun-v1.4.0/bun-linux-aarch64.zip`
|
|
- `https://nodejs.org/dist/v24.20.0/node-v24.20.0-linux-x64.tar.xz`
|
|
- `https://nodejs.org/dist/v24.20.0/node-v24.20.0-linux-arm64.tar.xz`
|
|
- `https://github.com/openai/codex/releases/download/rust-v0.150.1/codex-package-x86_64-unknown-linux-musl.tar.gz`
|
|
- `https://github.com/openai/codex/releases/download/rust-v0.150.1/codex-package-aarch64-unknown-linux-musl.tar.gz`
|
|
- `https://github.com/rustdesk/rustdesk/releases/download/1.4.9/rustdesk-1.4.9-0.x86_64.rpm`
|
|
- `https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-44.noarch.rpm`
|
|
- `https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-44.noarch.rpm`
|
|
- `https://repos.fyralabs.com/terra44`
|
|
- `https://download.copr.fedorainfracloud.org/results/lionheartp/Hyprland/fedora-$releasever-$basearch/`
|
|
- `https://downloads.claude.ai/claude-code/rpm/stable`
|
|
- `https://patrickjaja.github.io/claude-desktop-extra/rpm/`
|
|
|
|
Artifact digests were checked with `sha256sum ARTIFACT` against the lowercase
|
|
64-hex values in `installers.conf`; all runtime downloads also enforce the
|
|
recorded byte limit before atomic replacement.
|
|
|
|
The `*_BINARY_SHA256` values are the SHA-256 digests of the exact executable
|
|
bytes selected from each verified runtime archive. They were derived without
|
|
executing the artifacts: `tar -xO` selected Node's `bin/node` and Codex's
|
|
`bin/codex`, while `unzip -p` selected Bun's `bun`. Runtime version directories
|
|
record both the reviewed archive digest and this reviewed installed-byte digest
|
|
in `.panama-provenance`; later runs require the receipt and re-hash the installed
|
|
binary before treating an existing directory as trusted.
|
|
|
|
## Panama bootstrap
|
|
|
|
The public desktop and server commands use the same committed `boot` blob:
|
|
|
|
```text
|
|
commit 0d1841cf86975d52485c94c0caa5d1b67e5c54a1
|
|
SHA-256 fd8dcd70d1266da109972df346e3d85d1037f6f6e1942b0157064412ab892372
|
|
URL https://git.gbrown.org/gib/Panama/raw/commit/0d1841cf86975d52485c94c0caa5d1b67e5c54a1/boot
|
|
```
|
|
|
|
The digest was derived from the committed blob with:
|
|
|
|
```bash
|
|
git show 0d1841cf86975d52485c94c0caa5d1b67e5c54a1:boot | sha256sum
|
|
```
|
|
|
|
That implementation commit contains only `boot` and its boot/root-server
|
|
contracts. The following documentation commit records the pin and does not
|
|
contribute bytes to it. Rotate the bootstrap pin only through the same two-step
|
|
sequence: commit the boot implementation first, derive its committed blob
|
|
digest, then update the command and this ledger in a second commit.
|
|
|
|
## Rotation policy
|
|
|
|
Do not replace a key on an automated update. A key rotation is a reviewed
|
|
repository change: obtain the new key from the publisher record, independently
|
|
confirm its complete primary fingerprint, update the vendored key and
|
|
`installers.conf` together, refresh this retrieval record, and add a focused
|
|
contract case if the verification behavior changes. Until that review lands,
|
|
verification fails closed and preserves any known-good destination.
|
|
|
|
## Container-only Terra 44 signed-bootstrap proof
|
|
|
|
On 2026-08-27, a single disposable rootless Podman container proved the Terra
|
|
bootstrap path without changing the host package database, host keyring, or
|
|
host repository files. Podman reported `rootless=true`, `runtime=crun`, and a
|
|
user graph root. The fresh image was
|
|
`registry.fedoraproject.org/fedora@sha256:62f199d1eb34170a7bb2277485676d89c0e91aae4086151c4043062cce51c77c`
|
|
(`sha256:87d8a4a90c0457689db68624cac1026fb2201cbdc1e99cc5455a8f8876118498`).
|
|
The container (`5fc8fa42bb85afb3b57b336ca29b58a32fad50d460583329a4e910cc29fb4d2d`)
|
|
had no mounts and was removed automatically after `podman stop`.
|
|
|
|
Before copying the only host file admitted to the container,
|
|
`keys/terra44.asc`, this exact host check reported the complete primary
|
|
fingerprint `AE09157A4DE88B497EA1D5D300CDAB43DE226D6F`:
|
|
|
|
```bash
|
|
gpg --batch --with-colons --import-options show-only --import setup/provenance/keys/terra44.asc \
|
|
| awk -F: '$1 == "fpr" { print $10; exit }'
|
|
```
|
|
|
|
Its SHA-256 was
|
|
`3febbaadfa43509c22edc440d58c970705e502cdd0f347a75d5005562fd6b3d8`.
|
|
The container commands were:
|
|
|
|
```bash
|
|
podman create --name panama-terra-proof-20260827 --rm --pull=always \
|
|
registry.fedoraproject.org/fedora:44 sleep infinity
|
|
podman cp setup/provenance/keys/terra44.asc \
|
|
panama-terra-proof-20260827:/tmp/terra44.asc
|
|
podman start panama-terra-proof-20260827
|
|
podman exec panama-terra-proof-20260827 /bin/bash -lc '
|
|
sha256sum /tmp/terra44.asc
|
|
install -Dm0644 /tmp/terra44.asc /etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama
|
|
dnf install -y --repofrompath terra,https://repos.fyralabs.com/terra44 \
|
|
--setopt=terra.pkg_gpgcheck=1 \
|
|
--setopt=terra.repo_gpgcheck=1 \
|
|
--setopt=terra.gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama \
|
|
terra-release
|
|
'
|
|
```
|
|
|
|
Inside the container the copied and installed key both had the recorded
|
|
SHA-256 before and after installation. `terra-release-44-9.noarch` was
|
|
installed. Its effective `terra` configuration reported `gpgcheck = 1`,
|
|
`pkg_gpgcheck = 1`, and `repo_gpgcheck = 1`; no GPG-bypass option was used.
|
|
The package's own `/etc/yum.repos.d/terra.repo` uses its Terra metalink and
|
|
`RPM-GPG-KEY-terra44`. That differs from Panama's deliberately staged local
|
|
key/base-URL file in `install-packages`, which replaces the release-generated
|
|
file only after this verified bootstrap step.
|
|
|
|
Although the command runner returned after 30 seconds while DNF was still
|
|
loading metadata, Podman's retained event log records the exact command's
|
|
completion. This read-only recovery command was run after container removal:
|
|
|
|
```bash
|
|
podman events --since '2026-08-27T10:55:00-04:00' --until '2026-08-27T11:02:00-04:00' \
|
|
--filter container=5fc8fa42bb85afb3b57b336ca29b58a32fad50d460583329a4e910cc29fb4d2d \
|
|
--format json
|
|
```
|
|
|
|
The first `exec` event, at `timeNano=1787842633591543881`, is the documented
|
|
key-install and DNF command. Its matching first `exec_died` event, at
|
|
`timeNano=1787842671276003275`, records `ContainerExitCode:0`. The
|
|
same-container post-check independently confirmed the installed package and
|
|
effective signature settings above; no retry or second container was used.
|