# wazuh-agent-enrollment

Companion files for the lesson **Wazuh Agent Enrolment Explained**:
<https://maheshtata.com/wazuh/wazuh-agent-enrollment/>

Tested against: Wazuh 5.0.0-beta5, official single-node Docker stack, Ubuntu 24.04,
lab-verified 23 September 2026 for the Linux password route. The macOS paths and the
manager-API route were not exercised; treat those values as a starting point.

## Files

| File | What it is |
| --- | --- |
| `agent-enrollment.fragment.xml` | The agent-configuration enrolment route. Partial `<agent>` block covering manager endpoint, TLS and the full documented `<enrollment>` option set, with the ignored 4.x options called out. |
| `enroll-via-api.sh` | The manager-API enrolment route. Authenticates, creates the group, enrols the agent, assigns the group, and prints the key with the import command for each platform. |

## The two routes, and when to use which

**Agent configuration** (`agent-enrollment.fragment.xml`). The agent requests
its own key at first start. Automate this one: no key ever passes through a
human's hands. The endpoint needs the enrolment password.

**Manager API** (`enroll-via-api.sh`). You request the key centrally and import
it on the endpoint. Use this when the endpoint must never hold the enrolment
password, or when the key has to exist before the host does.

## Usage

```bash
MANAGER=10.0.0.2 \
API_USER=wazuh \
API_PASSWORD='...' \
AGENT_NAME=mac-design-04 \
AGENT_GROUP=macos-laptops \
  ./enroll-via-api.sh
```

## Rules that bite

1. **Groups must exist on the manager before the handshake.** An unknown group
   in `<enrollment><groups>` gets the enrolment rejected. There is no fallback
   to `default` and no checksum-based group guessing in 5.0. Verified strings:
   agent `ERROR: Enrollment rejected by the manager: invalid request. Invalid
   Group(s) Name(s)`, manager `wazuh-manager-authd: ERROR: Invalid group:
   <name>`. A wrong password instead gives `ERROR: Enrollment rejected by the
   manager: invalid or missing authentication. Invalid client authentication`,
   with nothing in the manager log. Either way the agent stays `pending`.
2. **Agent names must be unique.** Without `<agent_name>` the hostname is used,
   so every clone of an image collides.
3. **Clocks must be roughly in sync.** The bearer token lives 60 seconds with
   30 seconds of tolerated skew. Drift shows up as a generic `401`.
4. **Uninstalling does not deregister.** Remove the record separately through
   the dashboard or `DELETE /agents`.
5. `curl -k` in the script skips certificate verification. Remove it once the
   manager API presents a certificate the calling host trusts.

## Ports

| Port | Used for |
| --- | --- |
| 1517/TCP | Wazuh 5.0 agent enrolment and all later communication (HTTPS) |
| 55000/TCP | Manager API, including the API enrolment route |
| 1514, 1515/TCP | Legacy channel for Wazuh 4.x agents. Verified on 5.0.0-beta5: enabled in the shipped manager configuration, so a stock manager listens on 1514 1515 1516 1517 55000 |
