Skip to content
Login

Agent

The agent is one long-running process per machine that serves every endpoint you declare in the dashboard. Add, edit, or remove an endpoint at hle.world/dashboard and the agent converges within seconds — no restart, no SSH, no process per tunnel.

hle tunnel createhle agent
Tunnels per processonemany
Configured inthe command linethe dashboard
Changing a tunnelrestart the commandtakes effect in seconds
CredentialAPI key (hle_…)agent token (hle_…, scoped to tunnels)

Use hle tunnel create for a quick one-off share. Use the agent for anything you want to keep running.

An endpoint’s target is any URL the agent can reach — not just services on its own machine, but anything on its network.

FirepuncherReach any TCP port the agent can see — SSH, Postgres, RDP — with no port open anywhere
Service discoveryThe agent inventories your Kubernetes Services and Docker containers so you can expose one in a click
Traffic & metricsOne chart and one metric strip for the agent, each endpoint, and every forward

The installer sets up the client, enrolls the machine, and installs a background service — in one command:

Terminal window
curl -fsSL https://get.hle.world | sh -s -- --agent

It prompts for the agent token. To get one, go to Connections → Agents → New in the dashboard and copy the hle_… value. It is shown only once.

The dialog then shows the commands to run on the machine: the installer (curl -fsSL https://get.hle.world | sh), hle agent enroll <token>, and hle agent run.

For unattended installs (cloud-init, Ansible, CI), pass the token instead:

Terminal window
curl -fsSL https://get.hle.world | sh -s -- --agent --token hle_xxxxx
FlagEffect
--agentEnroll the machine and install the agent service
--token <hle_…>Provide the token non-interactively (implies --agent)
--no-serviceEnroll only — don’t install a service
--reinstallForce a from-scratch rebuild instead of upgrading in place
--userPer-user service (no sudo)
--systemSystem-wide service, starts at boot (needs sudo)
--version <v>Pin a specific hle-client version

Without --user or --system the scope is auto-detected: running as root installs a system service, otherwise a per-user one. A per-user service on Linux only survives logout and reboot with lingering enabled (see Per-user services and logout), so on a headless box pass --system:

Terminal window
curl -fsSL https://get.hle.world | sh -s -- --agent --system

As a normal user it asks for your sudo password to install the service; the service still runs as you and reads your token.

If you already have the client installed:

Terminal window
hle agent enroll # prompts for the token
hle daemon install agent # install + start the background service

In a script, pipe the token in with --stdin instead of passing it as an argument, so it stays out of the process list and shell history:

Terminal window
printf '%s\n' "$HLE_AGENT_TOKEN" | hle agent enroll --stdin

Or run it in the foreground to watch what it does:

Terminal window
hle agent run

Everything else happens in the dashboard, under Connections → Agents → your agent → Endpoints. Each endpoint has:

  • Label — used in the public hostname (e.g. ha → ha-x7k.hle.world)
  • Local URL — where the agent should forward to (e.g. http://localhost:8123)
  • Domain — the base domain, or one of your custom zones
  • Auth — SSO or open

A typical homelab agent:

LabelLocal URLPublic URLAuth
hahttp://homeassistant:8123ha-x7k.hle.worldSSO
jellyhttp://nas:8096jelly.example.comSSO
githttp://git:3000git-x7k.hle.worldSSO
Terminal window
hle daemon status agent # is it running?
hle daemon uninstall agent # stop, disable, and remove it

Under the hood this is a systemd unit (hle-agent.service) on Linux and a launchd job (world.hle.agent) on macOS. Read the logs with:

Dashboard Agents screen: an online agent with its tunnels, an Add tunnel form and the Updates panel

Terminal window
# Linux, system service
sudo journalctl -u hle-agent -f
# Linux, per-user service
journalctl --user -u hle-agent -f
# macOS
tail -f ~/Library/Logs/hle/agent.log
Terminal window
hle update

It upgrades the client, rebuilds the service against it and restarts it. Say yes when it offers the restart, or the agent keeps running the previous release while hle version reports the new one.

To look before you leap, or to pin a version:

Terminal window
hle update --check
hle update --version 2611.3

Re-running the install script upgrades in place too — it detects the existing install and hands off to hle update:

Terminal window
curl -fsSL https://get.hle.world | sh -s -- --agent

On an enrolled machine it keeps the existing agent token, so --agent needs no new one. Pass --reinstall to force the old from-scratch build instead:

Terminal window
curl -fsSL https://get.hle.world | sh -s -- --agent --reinstall

The installer falls back to that rebuild on its own if the in-place upgrade fails.

If the agent is reachable only through a tunnel it carries — a firewall, a remote box with no other way in — note that restarting it drops your own connection for a second or two. The restart is detached from your shell so the agent still comes back if the session dies with it.

A per-user systemd service stops when you log out unless lingering is enabled:

Terminal window
sudo loginctl enable-linger $USER

A system service (--system) has no such caveat — prefer it on a headless box.

hle agent enroll writes the token to ~/.config/hle/agent.toml with mode 0600. It is never written into the service definition, so the unit file is safe to read, back up, or commit as a template.

A system service runs as a specific user (--run-as, defaulting to whoever ran the install) and reads that user’s agent.toml. If you enroll as one user and install the service as another, the agent won’t find the token — enroll as the same user, or set HLE_AGENT_TOKEN in the unit’s environment.

You can also supply the token entirely by environment variable, which is what the container images do:

Terminal window
export HLE_AGENT_TOKEN=hle_xxxxx
hle agent run

Connections → Agents → your agent → Rotate token replaces the credential on the same agent — its endpoints, forward rules and settings are untouched.

By default the agent and its tunnels disconnect at once and stay offline until the new token is installed, so a leaked token loses the session it already has. Tick Keep the agent connected until it restarts for a routine swap: the agent keeps running, and only its next reconnect needs the new token. Either way, install the new token on the machine and restart the service. Run enroll as the user who installed the agent: no sudo, because a pipx install puts hle in that user’s ~/.local/bin, outside sudo’s search path.

Terminal window
printf '%s' '<TOKEN>' | hle agent enroll --stdin --force
sudo systemctl restart hle-agent

For a user-level service (systemctl --user is-active hle-agent prints active), restart it with systemctl --user restart hle-agent instead. For an agent installed as root, run the enroll as root: printf '%s' '<TOKEN>' | sudo -i /root/.local/bin/hle agent enroll --stdin --force.

A legacy hlea_… token (an agent created before server v2609.2) is badged Legacy token, rotate it and moves onto a scoped hle_… key the same way.

Docker and Home Assistant installs paste the token into their configuration (HLE_AGENT_TOKEN, or the add-on’s agent_token) instead of running hle agent enroll.

Tokens can’t be retrieved after creation. To remove the saved token from a machine:

Terminal window
hle agent logout
  • Docker — HLE_AGENT_TOKEN with the agent profile
  • Home Assistant — the agent_token add-on option
  • Proxmox — one agent per node or LXC

The agent shows offline in the dashboard. Check the service is running (hle daemon status agent) and look at the logs. The agent needs outbound HTTPS to hle.world:443; it never accepts inbound connections.

An endpoint shows an error. The agent could reach the server but not your local service. Verify the local URL from the machine running the agent — inside a container, localhost is the container, not the host.

“No agent token” on service start. The service is running as a user without ~/.config/hle/agent.toml. See Where the token lives.

A “Duplicate” badge, or “Another machine is using this agent’s token”. Two copies are running on one token. They take every tunnel off each other roughly once a second, so the agent reports online the whole time while nothing it serves ever settles.

Run hle daemon list on each machine to find the copy you did not mean to run. The usual cause is a foreground hle agent run left alongside the service — often on the same machine, which is why the warning can name the host you are already on. If both machines should be agents, enrol the second one separately from the dashboard rather than copying the token.

The warning clears itself 15 minutes after the last refused connection. It does not need dismissing: while the duplicate is running the attempts never stop for long, so a quarter of an hour of silence means it has been stopped. Each refusal is also recorded under the agent’s connection events, which stay after the banner goes.