# Run the edge agent

This guide is for the person who runs the **Axiad edge agent** on a host inside your
network — usually someone on your IT or infrastructure team. Your Mesh administrator
will send you a **one-time enrollment token** and a **command** to run.

> **note**
If you manage connectors in the Mesh dashboard instead, see
**[Set up an on-prem connector](./set-up-on-prem-connector.md)**.

## What the edge agent is

The edge agent is a small container you run on a host inside your network. It lets
Mesh collect from internal systems that aren't reachable from the internet. It
connects **out** to Mesh over HTTPS and keeps a secure channel open — it never
accepts inbound connections, so you don't open any firewall ports for it.

## Before you begin

You'll need:

- A **Linux host** inside your network with **Docker** (or a compatible container
  runtime) installed.
- **Outbound HTTPS (443)** from that host to Mesh. **No inbound ports.**
- Network reachability from that host to the internal systems you want Mesh to
  collect from.
- From your Mesh administrator: the **one-time enrollment token** and the **run
  command**.

> **warning**
The enrollment token is valid for a short time and can be used **only once**. Run the
command soon after you receive it. If it expires, ask your administrator to issue a
new one.

## Step 1 — Prepare the data directory

The agent runs as a **non-root user** (uid `65532`) and keeps a little state on disk,
so create its data directory and give it ownership. The command from your
administrator includes these two lines:

```bash
sudo mkdir -p /var/lib/axiad-edge
sudo chown 65532:65532 /var/lib/axiad-edge
```

> **warning**
If you skip this, the container fails to start with an error like
`mkdir .../store: permission denied`.

## Step 2 — Pull and run the agent

Run the command your administrator gave you. Your token and the exact image version
are filled in for you; it looks like this:

```bash
docker pull axiadciregistry.azurecr.io/mesh-edge-agent:<version>

docker run -d --name axiad-edge-agent --restart unless-stopped \
  -e ENROLL_TOKEN='<your-one-time-token>' \
  -e MESH_SSRF_ALLOW_PRIVATE=1 \
  -v /var/lib/axiad-edge:/var/lib/mesh-edge \
  axiadciregistry.azurecr.io/mesh-edge-agent:<version>
```

What the parts mean:

- **`ENROLL_TOKEN`** — your one-time enrollment token. The agent uses it once to
  enroll, then keeps its own identity, so you won't need it again. The token also
  tells the agent where Mesh is — there's nothing else to configure.
- **`MESH_SSRF_ALLOW_PRIVATE=1`** — lets the agent reach systems on your private
  network. Leave it in if any target is internal (the usual case); you can omit it if
  every target is publicly reachable.
- **`-v /var/lib/axiad-edge:/var/lib/mesh-edge`** — gives the agent the data directory
  you prepared in Step 1.
- **`--restart unless-stopped`** — brings the agent back automatically after a
  reboot.

## Step 3 — Verify it enrolled and connected

Watch the logs:

```bash
docker logs -f axiad-edge-agent
```

Look for these lines, in order:

- **`enroll: success`** — the agent registered with Mesh.
- **`connect: gateway stream open`** — the secure channel is up.
- **`heartbeat: initial tick sent`** — it has checked in and is healthy.

You can also ask the agent directly:

```bash
docker exec axiad-edge-agent agent status
```

- Enrolled: `agent kid=... issued_at=... not_after=...` (the `not_after` value is when
  its certificate expires — renewal is automatic).
- Not yet enrolled: `agent: not enrolled`.

Once it's up, let your administrator know — the agent will show **Enrolled** in the
Mesh dashboard.

## Keeping it running

- **Restart:** `docker restart axiad-edge-agent`. The agent reuses its stored identity
  and reconnects — no new token needed.
- **Stop:** `docker stop axiad-edge-agent`. It shuts down cleanly
  (`boot: shutdown complete`) and won't start again until you tell it to.
- **After a host reboot:** `--restart unless-stopped` starts it automatically.
- **Certificate renewal:** handled automatically while the agent is running — nothing
  for you to do.
- **Decommission:** if your administrator decommissions the agent in Mesh, it shuts
  itself down and won't reconnect. To retire a host yourself, stop and remove the
  container (`docker rm -f axiad-edge-agent`) and delete `/var/lib/axiad-edge`.

## Behind a proxy

If the host reaches the internet through an HTTP proxy, pass it to the container the
usual Docker way, for example by adding `-e HTTPS_PROXY=http://proxy.example.com:8080` to
the `docker run` command.

## Troubleshooting

| Symptom | Fix |
| --- | --- |
| Container exits immediately; logs show `mkdir .../store: permission denied` | The data directory isn't owned by uid `65532`. Re-run the `chown` from Step 1. |
| Logs show `enroll: ENROLL_TOKEN expired` or `enroll: ENROLL_TOKEN required...` | The token expired or wasn't passed. Ask your administrator to issue a new one and re-run. |
| You never see `connect: gateway stream open` | The host can't reach Mesh outbound on 443. Check your egress firewall and DNS. |
| A connector test can't reach an internal system | Confirm the host can reach that system, and that `MESH_SSRF_ALLOW_PRIVATE=1` is set. |

> **tip**
For more detail while diagnosing, add `-e MESH_LOG_LEVEL=debug` to the `docker run`
command.

## Verify

- `docker logs` shows `enroll: success` and `connect: gateway stream open`.
- `docker exec axiad-edge-agent agent status` shows `agent kid=...`.
- Your administrator sees the agent as **Enrolled** in Mesh.
