Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
11501ec
image declare OpenSSH dependency
Deadbytes101 Jul 7, 2026
fe61a3e
ci add alpha8 physical findings applicator
Deadbytes101 Jul 7, 2026
0a0fe4f
tool add deterministic alpha8 source patch
Deadbytes101 Jul 7, 2026
d9cd9e3
ci trigger alpha8 source application
Deadbytes101 Jul 7, 2026
739d8a5
runtime render exact miner policy
Deadbytes101 Jul 7, 2026
bed746a
runtime add miner render authority
Deadbytes101 Jul 7, 2026
493cc71
miner override runtime render config
Deadbytes101 Jul 7, 2026
3c4e19a
runtime render wait for committed revision
Deadbytes101 Jul 7, 2026
8eef195
miner gate rendered runtime truth
Deadbytes101 Jul 7, 2026
d8d5050
image wire runtime authority and user CLI
Deadbytes101 Jul 7, 2026
ab2baf5
remote access report listener truth
Deadbytes101 Jul 7, 2026
2a20d15
remote access add truth service
Deadbytes101 Jul 7, 2026
a6f491d
remote access add observer unit
Deadbytes101 Jul 7, 2026
1b09751
ssh pull remote truth observer
Deadbytes101 Jul 7, 2026
80065d0
remove unused workflow
Deadbytes101 Jul 7, 2026
73a3020
remove unused source applicator
Deadbytes101 Jul 7, 2026
3627b76
miner render before runtime gate
Deadbytes101 Jul 7, 2026
de4389d
runtime render remain active
Deadbytes101 Jul 7, 2026
b5a60db
test alpha8 runtime authority
Deadbytes101 Jul 7, 2026
efec3e7
test alpha8 runtime authority in workspace verify
Deadbytes101 Jul 7, 2026
6358035
test remote listener truth in alpha8 gate
Deadbytes101 Jul 7, 2026
972b90e
test alpha8 appliance wiring
Deadbytes101 Jul 7, 2026
24c4f0c
format alpha8 runtime test
Deadbytes101 Jul 7, 2026
4fee061
remove duplicate remote access unit
Deadbytes101 Jul 7, 2026
627bef1
release stage alpha8 appliance candidate
Deadbytes101 Jul 7, 2026
c1ca514
alpha8 hotfix enable SSH password login
Deadbytes101 Jul 7, 2026
105d391
verify alpha8 SSH hotfix policy
Deadbytes101 Jul 7, 2026
2a49c77
gate alpha8 rebuild on hotfix verification
Deadbytes101 Jul 7, 2026
83ecd6e
alpha8 hotfix normalize SSH policy line endings
Deadbytes101 Jul 7, 2026
98ed5bd
alpha8 hotfix preserve Cargo path in builder
Deadbytes101 Jul 7, 2026
e76734d
alpha8 hotfix verify builder Cargo path
Deadbytes101 Jul 7, 2026
8b6068c
alpha8 hotfix reuse builder package layer
Deadbytes101 Jul 7, 2026
0b77a5f
alpha8 hotfix verify recovery credential outcome
Deadbytes101 Jul 7, 2026
3dd0db9
alpha8 hotfix clear false recovery failure
Deadbytes101 Jul 7, 2026
827916f
alpha8 hotfix make recovery gate testable
Deadbytes101 Jul 7, 2026
93de25e
test alpha8 recovery false-failure hotfix
Deadbytes101 Jul 7, 2026
5e00b35
alpha8 hotfix verify recovery access outcome gate
Deadbytes101 Jul 7, 2026
a6dd9ec
format alpha8 recovery gate test
Deadbytes101 Jul 7, 2026
3024868
format alpha8 recovery gate fixture exactly
Deadbytes101 Jul 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion build/usb/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,11 @@ RUN apt-get update \
ripgrep rsync squashfs-tools syslinux-common syslinux-utils udev uuid-runtime xorriso zstd \
&& rm -rf /var/lib/apt/lists/*

ENV PATH="/usr/local/cargo/bin:/usr/local/rustup/bin:${PATH}"

RUN command -v cargo \
&& cargo --version \
&& rustc --version

WORKDIR /source
ENTRYPOINT ["./scripts/build-usb-image.sh"]
ENTRYPOINT ["/bin/bash", "-c", "python3 ./scripts/check-alpha8-ssh-hotfix.py && exec ./scripts/build-usb-image.sh"]
9 changes: 6 additions & 3 deletions build/usb/hooks/010-rigos.chroot
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ useradd --system --home-dir /var/lib/rigos --shell /usr/sbin/nologin --user-grou
useradd --create-home --shell /bin/bash --groups sudo rigosadmin
passwd --lock rigosadmin
install -d -o rigos -g rigos -m 0750 /var/lib/rigos
install -d -m 0755 /usr/lib/rigos
install -d -m 0755 /usr/lib/rigos /usr/local/bin
ln -sfn /usr/lib/rigos/rigosd /usr/local/bin/rigosd
ln -sfn /usr/lib/rigos/rigosctl /usr/local/bin/rigosctl
systemd-tmpfiles --create /usr/lib/tmpfiles.d/rigos.conf

chmod 0755 /usr/local/sbin/rigos-firstboot /usr/local/sbin/rigos-recovery-access /usr/local/sbin/rigos-state-orchestrate /usr/lib/rigos/rigos-miner-gate /usr/lib/rigos/rigos-state-init /usr/lib/rigos/rigos-state-ready /usr/lib/rigos/rigos-config /usr/lib/rigos/rigos-performance /usr/lib/rigos/rigos-lifecycle-cycles /usr/lib/rigos/rigos-identity-seed /usr/lib/rigos/xmrig
systemctl enable NetworkManager.service rigos-state.service rigos-recovery-access.service rigos-state-ready.service rigos-profile-apply.service rigos-hugepages.service rigos-firstboot.service rigos-miner.service tmp.mount
chmod 0755 /usr/local/sbin/rigos-firstboot /usr/local/sbin/rigos-recovery-access /usr/local/sbin/rigos-state-orchestrate /usr/lib/rigos/rigos-miner-gate /usr/lib/rigos/rigos-runtime-render /usr/lib/rigos/rigos-runtime-gate /usr/lib/rigos/rigos-state-init /usr/lib/rigos/rigos-state-ready /usr/lib/rigos/rigos-config /usr/lib/rigos/rigos-performance /usr/lib/rigos/rigos-lifecycle-cycles /usr/lib/rigos/rigos-identity-seed /usr/lib/rigos/xmrig
systemctl enable NetworkManager.service ssh.service rigos-state.service rigos-recovery-access.service rigos-state-ready.service rigos-profile-apply.service rigos-runtime-render.service rigos-hugepages.service rigos-firstboot.service rigos-miner.service tmp.mount
systemctl disable ssh.socket 2>/dev/null || true
systemctl disable apt-daily.timer apt-daily-upgrade.timer logrotate.timer fstrim.timer 2>/dev/null || true
systemctl disable systemd-journald-audit.socket 2>/dev/null || true

Expand Down
12 changes: 12 additions & 0 deletions build/usb/includes.chroot/etc/ssh/sshd_config.d/00-rigos.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
PasswordAuthentication yes
KbdInteractiveAuthentication no
UsePAM yes
AuthenticationMethods any
PubkeyAuthentication yes
PermitRootLogin no
AllowUsers rigosadmin
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no
PermitTunnel no
GatewayPorts no
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[Unit]
After=rigos-runtime-render.service
Requires=rigos-runtime-render.service
ConditionPathExists=
ConditionPathExists=/var/lib/rigos/current

[Service]
ExecCondition=+/usr/lib/rigos/rigos-runtime-render
ExecCondition=/usr/lib/rigos/rigos-runtime-gate
ExecStart=
ExecStart=/usr/lib/rigos/xmrig --config=/run/rigos/xmrig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
Description=Establish local RIGOS recovery access
After=rigos-state.service
Wants=rigos-state.service
Before=rigos-state-ready.service rigos-firstboot.service getty@tty1.service
Before=rigos-state-ready.service rigos-firstboot.service getty@tty1.service ssh.service

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/rigos-recovery-access
SuccessExitStatus=1
ExecStartPost=/usr/bin/python3 /usr/lib/rigos/rigos-recovery-access-verify
StandardInput=tty
StandardOutput=tty
StandardError=tty
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Unit]
Description=Observe RIGOS SSH listener truth
After=network-online.target ssh.service rigos-recovery-access.service
Wants=network-online.target
Requires=ssh.service rigos-recovery-access.service

[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /usr/lib/rigos/rigos-remote-access-probe
RemainAfterExit=yes
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[Unit]
Description=Render RIGOS runtime miner configuration
After=rigos-state-ready.service rigos-profile-apply.service
Requires=rigos-state-ready.service rigos-profile-apply.service
Before=rigos-hugepages.service rigos-miner.service
ConditionPathExists=/var/lib/rigos/current

[Service]
Type=oneshot
ExecStart=/usr/lib/rigos/rigos-runtime-render
NoNewPrivileges=yes
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=strict
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
RestrictAddressFamilies=AF_UNIX
RestrictNamespaces=yes
LockPersonality=yes
ReadWritePaths=/run/rigos

[Install]
WantedBy=multi-user.target
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[Service]
RemainAfterExit=yes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[Unit]
After=rigos-recovery-access.service
Wants=rigos-remote-access-observe.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/python3
import json
import os
import sys
from pathlib import Path

RUNTIME = Path(os.environ.get("RIGOS_RUNTIME_PATH", "/run/rigos"))
BOOT_ID = Path(os.environ.get("RIGOS_BOOT_ID_PATH", "/proc/sys/kernel/random/boot_id"))
STATUS = RUNTIME / "recovery-access-status.json"
MAX_STATUS_BYTES = 64 * 1024


def emit(outcome: str, reason: str | None = None) -> None:
value = {
"schema": "rigos.recovery-access-gate/v1",
"outcome": outcome,
"reason": reason,
}
print(json.dumps(value, sort_keys=True), file=sys.stdout if outcome == "allowed" else sys.stderr)


def deny(reason: str) -> int:
emit("denied", reason)
return 2


def main() -> int:
try:
boot_id = BOOT_ID.read_text(encoding="ascii").strip()
raw = STATUS.read_bytes()
if not boot_id or not raw or len(raw) > MAX_STATUS_BYTES:
return deny("recovery_status_unreadable")
status = json.loads(raw)
except (OSError, UnicodeError, json.JSONDecodeError):
return deny("recovery_status_unreadable")

if not isinstance(status, dict):
return deny("recovery_status_invalid")
if status.get("schema") != "rigos.recovery-access-status/v1":
return deny("recovery_schema_mismatch")
if status.get("boot_id") != boot_id:
return deny("recovery_status_stale")
if status.get("local_console_access") is not True:
return deny("local_credential_unavailable")
if status.get("credential_persisted") is not True:
return deny("credential_not_persisted")
if status.get("credential_action") not in ("existing", "created", "restored"):
return deny("credential_action_invalid")

emit("allowed")
return 0


if __name__ == "__main__":
raise SystemExit(main())
99 changes: 99 additions & 0 deletions build/usb/includes.chroot/usr/lib/rigos/rigos-remote-access-probe
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/python3
import json
import os
import subprocess
import tempfile
from pathlib import Path

RUNTIME = Path("/run/rigos")
STATUS = RUNTIME / "recovery-access-status.json"
BOOT_ID = Path("/proc/sys/kernel/random/boot_id")
SSH_PORT = 22


def unit_state(action: str, unit: str) -> bool:
return subprocess.run(
["/usr/bin/systemctl", action, "--quiet", unit],
check=False,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
).returncode == 0


def has_listener(path: Path, port: int) -> bool:
try:
lines = path.read_text(encoding="ascii").splitlines()[1:]
except OSError:
return False
for line in lines:
fields = line.split()
if len(fields) < 4 or fields[3] != "0A":
continue
try:
observed = int(fields[1].rsplit(":", 1)[1], 16)
except (IndexError, ValueError):
continue
if observed == port:
return True
return False


def fsync_directory(path: Path) -> None:
descriptor = os.open(path, os.O_RDONLY | os.O_DIRECTORY)
try:
os.fsync(descriptor)
finally:
os.close(descriptor)


def main() -> int:
boot_id = BOOT_ID.read_text(encoding="ascii").strip()
status = json.loads(STATUS.read_text(encoding="utf-8"))
if status.get("boot_id") != boot_id:
raise RuntimeError("recovery access status belongs to another boot")
enabled = unit_state("is-enabled", "ssh.service")
active = unit_state("is-active", "ssh.service")
ipv4 = has_listener(Path("/proc/net/tcp"), SSH_PORT)
ipv6 = has_listener(Path("/proc/net/tcp6"), SSH_PORT)
listening = ipv4 or ipv6
if enabled and active and listening:
remote_access = "active"
elif enabled and not listening:
remote_access = "enabled_no_listener"
elif listening and not active:
remote_access = "listener_without_service"
else:
remote_access = "inactive"
operational = (
status.get("state_outcome") == "ready"
and status.get("local_console_access") is True
and remote_access == "active"
)
status.update(
{
"mode": "operational" if operational else "recovery",
"remote_access": remote_access,
"remote_protocol": "ssh",
"remote_port": SSH_PORT,
"ssh_service_enabled": enabled,
"ssh_service_active": active,
"ssh_listener_ipv4": ipv4,
"ssh_listener_ipv6": ipv6,
}
)
with tempfile.NamedTemporaryFile(
mode="w", encoding="utf-8", dir=RUNTIME, prefix=".recovery-access-", delete=False
) as stream:
json.dump(status, stream, sort_keys=True)
stream.write("\n")
stream.flush()
os.fsync(stream.fileno())
temporary = Path(stream.name)
temporary.chmod(0o644)
os.replace(temporary, STATUS)
fsync_directory(RUNTIME)
return 0 if operational else 1


if __name__ == "__main__":
raise SystemExit(main())
66 changes: 66 additions & 0 deletions build/usb/includes.chroot/usr/lib/rigos/rigos-runtime-gate
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/python3
import argparse
import json
import sys
from pathlib import Path

MAX_JSON_BYTES = 2 * 1024 * 1024


def emit(outcome: str, reason: str | None = None) -> None:
value = {
"schema": "rigos.runtime-gate/v1",
"outcome": outcome,
"reason": reason,
}
print(json.dumps(value, sort_keys=True), file=sys.stdout if outcome == "allowed" else sys.stderr)


def read_object(path: Path) -> dict:
raw = path.read_bytes()
if len(raw) > MAX_JSON_BYTES:
raise ValueError("JSON exceeds size limit")
value = json.loads(raw)
if not isinstance(value, dict):
raise ValueError("JSON root is not an object")
return value


def deny(reason: str) -> int:
emit("denied", reason)
return 2


def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--state", type=Path, default=Path("/var/lib/rigos"))
parser.add_argument("--runtime", type=Path, default=Path("/run/rigos"))
args = parser.parse_args()
try:
revision = (args.state / "current").resolve(strict=True).name
status = read_object(args.runtime / "runtime-config-status.json")
config = read_object(args.runtime / "xmrig.json")
except (OSError, ValueError, json.JSONDecodeError):
return deny("runtime_truth_unreadable")
if status.get("schema") != "rigos.runtime-config-status/v1" or status.get("outcome") != "ready":
return deny("runtime_status_invalid")
if status.get("revision") != revision:
return deny("runtime_revision_stale")
pools = config.get("pools")
cpu = config.get("cpu")
if not isinstance(pools, list) or not pools or not isinstance(cpu, dict):
return deny("runtime_config_invalid")
exact_threads = status.get("exact_threads")
profile = status.get("profile")
if exact_threads is not None:
if not isinstance(exact_threads, int) or exact_threads < 1 or not isinstance(profile, str):
return deny("runtime_thread_truth_invalid")
entries = cpu.get(profile)
if not isinstance(entries, list) or len(entries) != exact_threads:
return deny("runtime_thread_profile_mismatch")
emit("allowed")
return 0


if __name__ == "__main__":
raise SystemExit(main())
Loading