Skip to content

refactor(installer): remove hardened (unprivileged hal0-api) mode; drop live-hello; fix ready-summary IPs#953

Merged
thinmintdev merged 1 commit into
mainfrom
refactor/installer-drop-hardened-mode
Jun 23, 2026
Merged

refactor(installer): remove hardened (unprivileged hal0-api) mode; drop live-hello; fix ready-summary IPs#953
thinmintdev merged 1 commit into
mainfrom
refactor/installer-drop-hardened-mode

Conversation

@thinmintdev

Copy link
Copy Markdown
Contributor

Summary

Removes hardened mode (the HAL0_USER != root path that ran hal0-api as an unprivileged service user) from the installer. hal0-api now always runs as root, so it can apply updates, write systemd drop-ins, and restart services directly — eliminating a class of operational breakage (hal0 update permission-denied, the memory extraction_slot drop-in failing to apply, the daemon unable to restart itself). Bundles two related installer-output cleanups.

1. Remove hardened (unprivileged hal0-api) mode

  • hal0-api.service base unit: User=${HAL0_USER}User=root.
  • Delete the 20-run-as-hal0.conf drop-in and its template (installer/systemd/hal0-api.service.d/).
  • Delete the HAL0_USER != root perms-flip block that recursively chowned /etc/hal0 + /var/lib/hal0 to the service user (kept only the non-hardening agent-dir seeding).
  • Drop the HAL0_USER env var, its --sudo re-exec passthrough, and its docs.
  • Upgrade path: an existing hardened box that re-runs the installer has its stale run-as-hal0 drop-in removed, reverting the unit cleanly to User=root.
  • Unchanged: agent isolation — the Hermes agent + gateway still run as hal0 via run-as-hal0.sh (that's #843 root-clobber protection, not hardened mode).

2. Remove the install-time "live hello"

Threw up a throwaway hello slot, loaded a model, and streamed a one-line greeting. On a fresh install (no model pulled) it just printed live hello skipped: no model pulled. Gone.

3. Fix the "hal0 is ready" summary

  • LAN IP filtering: discovery now skips container/virtual bridge interfaces (podman/cni/docker/veth/br-/flannel/virbr/...) by interface name, so noise like the podman 10.88.0.1 gateway no longer leaks into "Reach hal0 at" — and can no longer be picked as the primary HOST/dashboard URL.
  • Better next steps: lead with hal0 setup / hal0 model pull <id> (what a fresh box actually needs), add hal0 update, and a docs/logs footer.

⚠️ Security note (intentional, please weigh in)

hal0-api is open on the LAN with no built-in auth (ADR-0012). Running it as root means a compromise of that surface is root on the host. This is the project default (HAL0_USER defaulted to root); hardened mode was an opt-in that proved operationally fragile (no privileged-update seam was ever wired, so hal0 update couldn't write its own files). The slots already run as root podman containers regardless, so this changes only the API process's own privilege. Front :8080 with a reverse proxy / firewall on untrusted networks.

Out of scope (follow-up)

The now-dormant slot/agent privilege seam (hal0-slotctl + sudoers, container.py euid routing, src/hal0/install/perms.py) is dead code under root-only hal0-api but is left in place — removing it touches core slot management and deserves its own PR + slot testing.

Test plan

  • Fresh install on a clean box (installer/install.sh) — hal0-api comes up User=root; no 20-run-as-hal0.conf; services healthy. (Can't be fully exercised from an existing install — needs a clean box.)
  • Upgrade a previously-hardened box → stale drop-in removed, unit reverts to User=root.
  • hal0 update applies without permission errors.
  • "hal0 is ready" box shows only real LAN IPs (no 10.88.x), correct dashboard URL.
  • bash -n clean. (Already applied + verified live on CT105 + CT107: hal0-api as root, slots managed, hal0 memory graph enable --slot <x> returns written/restarted: true.)

🤖 Generated with Claude Code

…op live-hello; fix ready-summary IPs

hal0-api now always runs as root, so updates, systemd drop-in writes, and service restarts work directly — no privileged seam or perms workaround. Removes the HAL0_USER!=root path: the User substitution (now User=root), the 20-run-as-hal0.conf drop-in + template, and the /etc/hal0 + /var/lib/hal0 chown flip. Upgrading a previously-hardened box removes any stale run-as-hal0 drop-in to revert to User=root. Agent isolation (hermes/agents run as hal0 via run-as-hal0.sh) is unchanged.

Also: remove the install-time 'live hello' greeting (threw up a temp slot + streamed a chat; on a fresh box just printed 'skipped: no model pulled'). And fix the 'hal0 is ready' summary — filter LAN IPs by interface so container/bridge addrs (e.g. podman 10.88.0.1) stop leaking into 'Reach hal0 at' / becoming the primary HOST; lead next-steps with model pull + hal0 update + docs/logs footer.

Dormant slot/agent privilege seam (hal0-slotctl, container.py euid routing, perms.py) left in place; removing it is a follow-up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@thinmintdev thinmintdev merged commit 589c05f into main Jun 23, 2026
3 checks passed
bogdan-d pushed a commit to bogdan-d/hal0 that referenced this pull request Jun 23, 2026
… routing)

Follow-up to Hal0ai#953 (hardened mode removed). With hal0-api always root, the slot privilege seam is dead code. Removes: ContainerProvider._privileged() + the two euid!=0 branches (the root path is unchanged — behavior-preserving), the hal0-slotctl wrapper + sudoers + their install.sh writes (replaced with an upgrade cleanup that deletes any stale copies), the installer-route _privileged_systemctl_argv sudo fallback, and the now-obsolete seam test + conftest euid fixture.

Kept: src/hal0/install/perms.py (still used by 'hal0 doctor' for root-only + agent ownership auditing; stale seam doc updated) and the agent env seam (hal0-agentenv / run-as-hal0.sh — agents still run as hal0). perms.py's non-root branches are now unwired — a candidate for a later cleanup alongside doctor.

289 targeted tests pass (providers + perms + installer routes); ruff + bash -n clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
bogdan-d pushed a commit to bogdan-d/hal0 that referenced this pull request Jun 23, 2026
Bump version 0.8.0-beta.3 -> 0.8.1-beta.1 and add the CHANGELOG entry for the
installer/privilege simplification (Hal0ai#953, Hal0ai#954) + Hermes durable memory on by
default (Hal0ai#955: private:hermes + shared banks, agent-id hermes).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@thinmintdev thinmintdev deleted the refactor/installer-drop-hardened-mode branch June 23, 2026 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant