Configure ADMIN_SECRETS IPv6 whitelist for dashboard access control #11
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Parent: #8
Context
hero_codescalers TCP connections are gated by an IPv6 whitelist stored in hero_proc secrets under the key
ADMIN_SECRETS. This needs to be configured so only trusted admin users (e.g. over Mycelium) can reach the dashboard. Unix-socket calls are always trusted and bypass this.What to do
ADMIN_SECRETSkey400::/7)Relevant paths
hero_codescalers/crates/hero_codescalers_ui/— Axum web dashboard, where the IPv6 whitelist check should be enforcedhero_proc/crates/hero_proc_server/— secrets storage$HERO_SOCKET_DIR/hero_codescalers_server<N>/Acceptance Criteria
ADMIN_SECRETS whitelist verified — design works as documented
Setup applied on kristof4 (root context)
The four entries are each kristof box's mycelium TUN IP:
543:66c5:6430:8f31:5293:1ad9:694a:70f358b:c3be:cf70:4826:765a:2c6d:6c8d:a5e24a0:6976:8fa7:efc:9abc:c9c0:a338:f224c0:b29a:2940:5d2:42e4:4a63:7002:1ac0Verification matrix
/root/hero/var/sockets/hero_router/ui.sock[kristof4-host]:9988/healthfrom kristof4 mahmoud[kristof4-host]:9988/healthfrom kristof3 mahmoud[kristof4-host]:9988/hero_codescalers_server/ui/from kristof3Important architectural finding
The whitelist enforces against the TCP source IP at the accept loop. For cross-host mycelium connections the source IP that hero_router sees is the ORIGIN HOST's mycelium TUN address — not the calling user's bridge IP. This is because outgoing connections from a host go through that host's mycelium daemon, and the kernel's source-address selection picks the host TUN address.
For the on-host case (a kristof4 user reaching kristof4's own mycelium IP), Linux routes via
lowith source = host TUN IP. So all on-host users share the same source IP from the gate's perspective.Practical consequence — ADMIN_SECRETS is a list of admin hosts, not admin users. Per-user gating on the same host must use UDS (filesystem perms), not the TCP whitelist.
Pre-conditions that needed to be met (worth flagging)
hero_routerhas to be on a real mycelium IP, not127.0.0.1. The defaultservice_router start --rootauto-detects via~/hero/cfg/hero_cfg.toml [mycelium].ipv6_addressfirst, thenip -6 addrfor/7 mycelium-range global. On kristof4 the cfg file was empty, so the ip-scan fallback found the mycelium TUN address.hero_routerbinary must have theaccess.rsmodule (the per-host gate). Older binaries don't enforce — verify withgit logon the source clone or by testing.service_router start --root --reset).Coverage on the issue checklist
Notes / follow-ups
hero_router/src/access.rs+acceptloop inmain.rs:453). Same module is mirrored in hero_codescalers_ui (admin_secrets.rs) for the alternative path of codescalers exposing its own TCP listener.admin_secrets::saveto reject non-400::/7addresses was suggested in the analysis. Not done yet — easy follow-up if/when desired.secret_refreshSIGUSR1 / RPC call would help if we want immediate propagation; out of scope for this issue.Closed — verified, no code change required
ADMIN_SECRETSis set on kristof4 root's hero_proc secret store with the four kristof host TUN IPs. The gate athero_router/src/access.rsenforces against the TCP source IP at the accept loop (main.rs:453); UDS paths bypass it entirely.hero_router/ui.sock[kristof4-host]:9988/healthfrom kristof4 mahmoudImportant architectural finding: the whitelist enforces against the TCP source IP at accept time. For cross-host mycelium connections the source is the origin host TUN, not the calling user's bridge IP — so
ADMIN_SECRETSis a list of admin hosts, not admin users. Per-user gating on the same host needs UDS (filesystem perms), not the TCP whitelist.Pre-conditions worth flagging for ops:
hero_routermust be on a real mycelium IP, not127.0.0.1. The defaultservice_router start --rootauto-detects via~/hero/cfg/hero_cfg.toml [mycelium].ipv6_addressfirst, thenip -6 addrfor/7mycelium-range global.hero_routerbinary must include theaccess.rsmodule (the per-host gate). Older binaries don't enforce — verify withgit logor by testing.--resetto force immediate propagation ofADMIN_SECRETSchanges.Optional follow-up: tighten
admin_secrets::saveto reject non-400::/7addresses. Not done — easy to add later if desired.