Step 5's last piece: relay upgrades (RL-29), plus the downstream showing a relay that's older than itself (RL-28).
Signed releases
crates/relay-proto/src/release.rs defines the signature file inbuxa-relay-<target>.sig. It has four lines (inbuxa-relay release 1, version, target such as x86_64-linux-musl, and sha256), then signature: Ed25519 over those four lines, in base64url.
The release keys' public halves are compiled in as RELEASE_KEYS. It's empty for now, so every upgrade is refused (see below).
It also has SemVer ordering, so 27.1.0-rc.5 comes before 27.1.0.
tools/release/sign-relay.sh KEY.pem BINARY VERSION TARGET writes BINARY.sig. It needs only openssl and coreutils. A test checks the script's output against the Rust verifier.
It refuses an upgrade in a container image (INBUXA_RELAY_CONTAINER, so selfUpgrade: false), while another upgrade is on its way, for a bad signature, for another target, and for a version that isn't newer.
Otherwise it:
writes the new binary beside its own;
runs it with --version, which must name the signed version within 10 s;
keeps the old binary as inbuxa-relay.previous and renames the new one into place;
records relay.upgraded, or relay.upgrade-refused with the reason;
answers, then exits with 75 (EX_TEMPFAIL) so its supervisor restarts it.
Server (inbuxa:Relay)
An update with upgrade: {blobId, signature} must be sent on its own.
The server reads the blob with the caller's access, checks the signature, then uploads the binary over this node's link (Sender::upgrade) and calls Relay/upgrade.
If this node has no link to the relay, the update is refused with forbidden.
The relay's refusal comes back as invalidProperties on upgrade.
olderThanServer (server-set): true when any link last heard an older relayVersion than this server's, null before any link has reported.
Tests
Relay end-to-end test, over the real link: a forged signature, an older version, another target and an unreadable file are each refused and leave the binary unchanged (RL-T16). A good release goes in, the old one is kept, the run loop is told to exit, and a second upgrade is refused.
Unit tests:
a binary that reports another version is never put in place;
signature parsing and tampering are caught;
version ordering is right.
relay_tests: an upgrade on create, a malformed one, one sent with other properties, an unknown blob, an unreadable file, and a signature by no release key are each refused before any relay sees them. olderThanServer is null before any link has reported.
relay_link_tests: a linked relay from this build has olderThanServer: false.
Run locally: relay crate 28 tests; relay-proto, features and fork tools all pass; relay_tests (2 s) and relay_link_tests (39 s); fmt, clippy (no new warnings in the changed files), the fork checks, and the expr-schema check.
Not in this PR, for step 6 (packaging)
The release key itself.
Signing in publish.yml.
A relay service unit with a restart policy.
Until the key exists, every build refuses every upgrade, which is the safe default.
Console: inbuxa-admin PR to follow (Upgrade dialog and the older-version line).
Step 5's last piece: relay upgrades (RL-29), plus the downstream showing a relay that's older than itself (RL-28).
**Signed releases**
- `crates/relay-proto/src/release.rs` defines the signature file `inbuxa-relay-<target>.sig`. It has four lines (`inbuxa-relay release 1`, `version`, `target` such as `x86_64-linux-musl`, and `sha256`), then `signature`: Ed25519 over those four lines, in base64url.
- The release keys' public halves are compiled in as `RELEASE_KEYS`. It's empty for now, so every upgrade is refused (see below).
- It also has SemVer ordering, so `27.1.0-rc.5` comes before `27.1.0`.
- `tools/release/sign-relay.sh KEY.pem BINARY VERSION TARGET` writes `BINARY.sig`. It needs only openssl and coreutils. A test checks the script's output against the Rust verifier.
**Relay** (`crates/relay/src/upgrade.rs`, `Relay/upgrade {blobId, signature}`)
- It refuses an upgrade in a container image (`INBUXA_RELAY_CONTAINER`, so `selfUpgrade: false`), while another upgrade is on its way, for a bad signature, for another target, and for a version that isn't newer.
- Otherwise it:
- writes the new binary beside its own;
- runs it with `--version`, which must name the signed version within 10 s;
- keeps the old binary as `inbuxa-relay.previous` and renames the new one into place;
- records `relay.upgraded`, or `relay.upgrade-refused` with the reason;
- answers, then exits with 75 (EX_TEMPFAIL) so its supervisor restarts it.
**Server** (`inbuxa:Relay`)
- An update with `upgrade: {blobId, signature}` must be sent on its own.
- The server reads the blob with the caller's access, checks the signature, then uploads the binary over this node's link (`Sender::upgrade`) and calls `Relay/upgrade`.
- If this node has no link to the relay, the update is refused with `forbidden`.
- The relay's refusal comes back as `invalidProperties` on `upgrade`.
- `olderThanServer` (server-set): true when any link last heard an older `relayVersion` than this server's, null before any link has reported.
**Tests**
- Relay end-to-end test, over the real link: a forged signature, an older version, another target and an unreadable file are each refused and leave the binary unchanged (RL-T16). A good release goes in, the old one is kept, the run loop is told to exit, and a second upgrade is refused.
- Unit tests:
- a binary that reports another version is never put in place;
- signature parsing and tampering are caught;
- version ordering is right.
- `relay_tests`: an upgrade on create, a malformed one, one sent with other properties, an unknown blob, an unreadable file, and a signature by no release key are each refused before any relay sees them. `olderThanServer` is null before any link has reported.
- `relay_link_tests`: a linked relay from this build has `olderThanServer: false`.
- Run locally: relay crate 28 tests; relay-proto, features and fork tools all pass; `relay_tests` (2 s) and `relay_link_tests` (39 s); fmt, clippy (no new warnings in the changed files), the fork checks, and the expr-schema check.
**Not in this PR, for step 6 (packaging)**
- The release key itself.
- Signing in `publish.yml`.
- A relay service unit with a restart policy.
Until the key exists, every build refuses every upgrade, which is the safe default.
Console: inbuxa-admin PR to follow (Upgrade dialog and the older-version line).
A relay release binary comes with a signature file: version, target and
SHA-256, signed with Ed25519 by the inbuxa release key, whose public half
is compiled into relay-proto. tools/release/sign-relay.sh makes the file
with openssl.
inbuxa:Relay/set takes an update with upgrade: {blobId, signature}. The
server checks the signature, uploads the binary over this node's link and
calls Relay/upgrade. The relay refuses it in a container image, while
another upgrade is on its way, and for a bad signature, another target or
a version that isn't newer. Otherwise it runs the new binary's --version,
keeps the old one as inbuxa-relay.previous, swaps it in and exits with 75
for its supervisor to restart it.
inbuxa:Relay gains olderThanServer, from each link's last relay version.
No release key is set yet: that and signing in the release workflow come
with packaging (step 6), so for now every upgrade is refused.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Step 5's last piece: relay upgrades (RL-29), plus the downstream showing a relay that's older than itself (RL-28).
Signed releases
crates/relay-proto/src/release.rsdefines the signature fileinbuxa-relay-<target>.sig. It has four lines (inbuxa-relay release 1,version,targetsuch asx86_64-linux-musl, andsha256), thensignature: Ed25519 over those four lines, in base64url.RELEASE_KEYS. It's empty for now, so every upgrade is refused (see below).27.1.0-rc.5comes before27.1.0.tools/release/sign-relay.sh KEY.pem BINARY VERSION TARGETwritesBINARY.sig. It needs only openssl and coreutils. A test checks the script's output against the Rust verifier.Relay (
crates/relay/src/upgrade.rs,Relay/upgrade {blobId, signature})INBUXA_RELAY_CONTAINER, soselfUpgrade: false), while another upgrade is on its way, for a bad signature, for another target, and for a version that isn't newer.--version, which must name the signed version within 10 s;inbuxa-relay.previousand renames the new one into place;relay.upgraded, orrelay.upgrade-refusedwith the reason;Server (
inbuxa:Relay)upgrade: {blobId, signature}must be sent on its own.Sender::upgrade) and callsRelay/upgrade.forbidden.invalidPropertiesonupgrade.olderThanServer(server-set): true when any link last heard an olderrelayVersionthan this server's, null before any link has reported.Tests
relay_tests: an upgrade on create, a malformed one, one sent with other properties, an unknown blob, an unreadable file, and a signature by no release key are each refused before any relay sees them.olderThanServeris null before any link has reported.relay_link_tests: a linked relay from this build hasolderThanServer: false.relay_tests(2 s) andrelay_link_tests(39 s); fmt, clippy (no new warnings in the changed files), the fork checks, and the expr-schema check.Not in this PR, for step 6 (packaging)
publish.yml.Until the key exists, every build refuses every upgrade, which is the safe default.
Console: inbuxa-admin PR to follow (Upgrade dialog and the older-version line).
A relay release binary comes with a signature file: version, target and SHA-256, signed with Ed25519 by the inbuxa release key, whose public half is compiled into relay-proto. tools/release/sign-relay.sh makes the file with openssl. inbuxa:Relay/set takes an update with upgrade: {blobId, signature}. The server checks the signature, uploads the binary over this node's link and calls Relay/upgrade. The relay refuses it in a container image, while another upgrade is on its way, and for a bad signature, another target or a version that isn't newer. Otherwise it runs the new binary's --version, keeps the old one as inbuxa-relay.previous, swaps it in and exits with 75 for its supervisor to restart it. inbuxa:Relay gains olderThanServer, from each link's last relay version. No release key is set yet: that and signing in the release workflow come with packaging (step 6), so for now every upgrade is refused.