# Kabeen Server Agent

Kabeen Server Agent is the Kabeen infrastructure monitoring agent. It runs as a privileged background service on Linux, macOS, and Windows, collecting host configuration and system metrics and forwarding them over gRPC/TLS to the Kabeen backend.

The internal project name is **komet** (used in repository names, Rust crate identifiers, etc.).

This document describes installation, configuration, health verification, mass deployment, and day-to-day operations of the **Kabeen Server Agent** on:

- **Windows** (≥ Windows Server 2016 / Windows 10, x86_64 and arm64) — **MSI** installer
- **Linux Debian / Ubuntu** — **`.deb`** package
- **Linux Red Hat / RHEL / Rocky / Alma / CentOS Stream / Oracle Linux** — **`.rpm`** package

The agent runs as a privileged system service. It collects host configuration and system metrics, then transmits this data to the **Kabeen** platform over gRPC on TLS.

> The detailed install and operational procedures below cover **Windows and Linux**. macOS is supported (see the runtime-layout and service-registration tables for its paths), but its step-by-step procedures are out of scope for this guide.

---

## Table of contents

1. [Overview](#1-overview)
2. [Download](#2-download)
3. [Operational architecture](#3-operational-architecture)
4. [Prerequisites](#4-prerequisites)
5. [Runtime layout](#5-runtime-layout)
6. [Service registration](#6-service-registration)
7. [Installation on Windows](#7-installation-on-windows)
8. [Installation on Debian/Ubuntu (`.deb`)](#8-installation-on-debianubuntu-deb)
9. [Installation on Red Hat / derivatives (`.rpm`)](#9-installation-on-red-hat--derivatives-rpm)
10. [Agent configuration](#10-agent-configuration)
11. [Kapsul integration (migration at startup)](#11-kapsul-integration-migration-at-startup)
12. [Health verification](#12-health-verification)
13. [Mass deployment](#13-mass-deployment)
    - [13.1 Windows — GPO](#131-windows--gpo-group-policy)
    - [13.2 Windows — Microsoft Intune](#132-windows--microsoft-intune)
    - [13.3 Linux — Ansible / Puppet / SCCM Linux / internal repositories](#133-linux--ansible--puppet--sccm-linux--internal-repositories)
14. [Updates](#14-updates)
15. [Uninstallation](#15-uninstallation)
16. [Troubleshooting](#16-troubleshooting)
17. [Building from source](#17-building-from-source)
18. [Appendices](#18-appendices)

---

## 1. Overview

| Characteristic            | Value                                                                   |
|---------------------------|-------------------------------------------------------------------------|
| Product name              | Kabeen Server Agent                                                     |
| Binary name               | `kabeen-server-agent` (Linux/macOS) / `kabeen-server-agent.exe` (Windows) |
| Windows service name      | `KabeenServerAgent` (label: *Kabeen Server Agent*)                     |
| Linux systemd unit        | `kabeen-server-agent.service`                                           |
| LaunchDaemon identifier   | `io.kabeen.server-agent` (macOS, out of scope for this document)        |
| Run-as account            | `LocalSystem` (Windows MSI) or `root` (Linux)                           |
| Transport protocol        | gRPC over TLS 1.2+                                                      |
| Default endpoint          | `https://intake.kabeen.io:443`                                          |
| Configuration format      | TOML                                                                    |
| Supervisor tick           | 10 s (re-reads `config.toml` and restarts tasks if it changed)          |

### Collected data

The agent periodically emits the following reports to the Kabeen backend:

- **Configuration** of the host (hardware, OS, network interfaces, mounted disks…).
- **Metrics**: CPU usage, memory, disks, system load.
- **Installed programs** (RPC `AddInstalledPrograms`).
- **Running processes** (RPC `AddRunningProcesses`).
- **Diagnostics** (RPC `AddDiagnosticReport`): condensed health report.
- **Heartbeat** and **HealthCheck** to the backend.

> **Note:** the inventory RPCs (programs, processes, diagnostics) are
> tolerant: if the backend returns `Unimplemented`, the agent treats the send
> as a success and does not retry (backward compatibility).

---

## 2. Download

Stable URLs that always resolve to the most recent release:

| Platform               | Latest URL                                                                                            |
|------------------------|-------------------------------------------------------------------------------------------------------|
| Linux deb (amd64)      | https://app.kabeen.io/download/packages/server/latest/kabeen-server-agent_amd64.deb                   |
| Linux deb (arm64)      | https://app.kabeen.io/download/packages/server/latest/kabeen-server-agent_arm64.deb                   |
| Linux rpm (x86_64)     | https://app.kabeen.io/download/packages/server/latest/kabeen-server-agent.x86_64.rpm                  |
| Linux rpm (aarch64)    | https://app.kabeen.io/download/packages/server/latest/kabeen-server-agent.aarch64.rpm                 |
| macOS pkg              | https://app.kabeen.io/download/packages/server/latest/Kabeen-Server-Agent.pkg                         |
| Windows MSI (x86_64)   | https://app.kabeen.io/download/packages/server/latest/kabeen-server-agent-x86_64.msi                  |
| Windows MSI (aarch64)  | https://app.kabeen.io/download/packages/server/latest/kabeen-server-agent-aarch64.msi                 |

Pinned versions remain available next to the `latest/` directory under `https://app.kabeen.io/download/packages/server/`, and every tagged release is also published to [GitHub Releases](https://github.com/kbine/komet/releases).

---

## 3. Operational architecture

```
        ┌──────────────────────────────────────────────────────────┐
        │                   Kabeen Server Agent                    │
        │                                                          │
        │  ┌────────────┐    mpsc    ┌──────────┐    gRPC/TLS      │
        │  │ Collectors │ ─────────► │ Senders  │ ───────────────► │── ►  intake.kabeen.io:443
        │  └────────────┘            └──────────┘                  │
        │        ▲                         ▲                       │
        │        │                         │                       │
        │        │      ┌──────────┐       │                       │
        │        └──────│ Settings │───────┘                       │
        │               │ (TOML)   │                               │
        │               └──────────┘                               │
        │                                                          │
        │  System service (systemd / Windows SCM / launchd)        │
        └──────────────────────────────────────────────────────────┘
```

- **Supervisor loop** (`TaskManager`): 10 s tick. It reads `config.toml`,
  verifies that the `api_key` is valid (at least 16 characters, no obvious
  placeholder such as `changeme`, `your_key_here`, etc.), then starts or
  restarts all tasks.
- **Collect/send split**: each family (configuration, metrics, programs,
  processes, diagnostics) has a collector and a sender connected by `mpsc`.
- **Cooperative shutdown**: a `broadcast` channel propagates the stop signal
  to all tasks when the service receives `SIGTERM` (Linux/macOS) or the
  SCM *Stop* event (Windows).
- **Platform code** isolated via `#[cfg(target_os = …)]` (no runtime dispatch).

---

## 4. Prerequisites

### Network

The agent must be able to establish an **outbound** connection:

| Destination                    | Port    | Protocol  | Usage           |
|--------------------------------|---------|-----------|-----------------|
| `intake.kabeen.io`             | 443/TCP | HTTPS/gRPC| Production      |

No inbound connection is required. The agent does not publish any port.

> **Important — strict TLS:** the agent explicitly rejects `http://` and,
> in *release* builds, only allows hosts under `kabeen.io`. If you use a TLS
> inspection proxy, the trusted root certificate must be present in the system
> store (Linux: `ca-certificates`; Windows: **Trusted Root Certification
> Authorities** store).

> **Enterprise proxy (Zscaler, Squid, …):** see § 10.6. The agent supports an
> explicit proxy (HTTP CONNECT) via the `proxy` field of `config.toml`, and
> transparent mode as long as the inspection CA is in the OS trust store.

### System

| OS       | Minimum versions                                                 | Package dependencies                              |
|----------|------------------------------------------------------------------|---------------------------------------------------|
| Debian   | Debian 11 (Bullseye), Ubuntu 20.04 LTS                           | `iproute2`, `libc6 (>= 2.31)` (resolved by dpkg)  |
| RHEL     | RHEL 8 / 9, Rocky 8/9, AlmaLinux 8/9, CentOS Stream 8/9, Oracle 8/9 | `iproute`, `systemd` (resolved by rpm)         |
| Windows  | Windows Server 2016+, Windows 10/11                              | None (static binary)                              |

The Linux packages require **systemd** as the init manager.

### Privileges

Installation and execution of the service require administrator privileges:

- Linux: `root` (or `sudo`).
- Windows: an account that is a member of **local Administrators**, running
  the installer as administrator.

---

## 5. Runtime layout

| OS      | Binary                                                       | Configuration                                        | State                                                      | Logs                                                                  |
|---------|--------------------------------------------------------------|------------------------------------------------------|------------------------------------------------------------|-----------------------------------------------------------------------|
| Linux   | `/usr/local/bin/kabeen-server-agent`                         | `/etc/kabeen-server-agent/config.toml`               | `/var/lib/kabeen-server-agent/`                            | `/var/log/kabeen-server-agent/kabeen-server-agent.log` (+ journald)   |
| macOS   | `/usr/local/bin/kabeen-server-agent`                         | `/etc/kabeen-server-agent/config.toml`               | `/Library/Application Support/Kabeen Server Agent/`        | `/var/log/kabeen-server-agent/kabeen-server-agent.log`                |
| Windows | `C:\Program Files\Kabeen\Server Agent\kabeen-server-agent.exe` | `C:\ProgramData\Kabeen\Server Agent\config.toml`   | `C:\ProgramData\Kabeen\Server Agent\`                      | `C:\ProgramData\Kabeen\Server Agent\logs\kabeen-server-agent.log`     |

The agent creates its data and log directories at first boot if they are missing, then waits for a valid `config.toml` (containing at least `api_key = "…"`) before contacting the backend.

---

## 6. Service registration

Each installer registers the agent as the native OS service:

- **Linux** (`.deb` / `.rpm`) — systemd unit `kabeen-server-agent.service`.
- **macOS** (`.pkg`) — launchd `LaunchDaemon` `io.kabeen.server-agent`.
- **Windows** (`.msi`) — Windows service **KabeenServerAgent** displayed as **Kabeen Server Agent** under `LocalSystem`.

---

## 7. Installation on Windows

The official installer is a signed **MSI**, generated by `cargo-wix`. It
supports **x86_64** (`x64`) and **aarch64** (`arm64`).

### 7.1 Interactive installation (UI)

1. Get the MSI matching the target architecture:
   - `kabeen-server-agent-<version>-x86_64.msi`
   - `kabeen-server-agent-<version>-aarch64.msi`
2. Double-click the file; accept the UAC elevation.
3. Read and accept the Kabeen **End-User License Agreement** (EULA).
4. On the **Kabeen API key** screen, paste your API key if you have it on
   hand (otherwise leave it empty — you can write it into `config.toml`
   later). The key entered is written immediately into the configuration
   file; the agent will pick it up on the next supervisor tick.
5. Click **Install**. The installer:
   - copies the binary to `C:\Program Files\Kabeen\Server Agent\kabeen-server-agent.exe`,
   - creates the folder `C:\ProgramData\Kabeen\Server Agent\` (marked *Permanent*
     to preserve the configuration on uninstall),
   - if an `APIKEY` was entered: writes `C:\ProgramData\Kabeen\Server Agent\config.toml`
     with `api_key = "<value>"` and restricts its ACL (SYSTEM + Administrators
     write, `NT SERVICE\KabeenServerAgent` read),
   - registers the Windows service **KabeenServerAgent** under the
     `LocalSystem` account with automatic startup,
   - starts the service immediately.

> If the API key was not entered at install time, the agent will loop on
> "Configuration is incomplete" until you manually write `config.toml`. See
> [Agent configuration](#10-agent-configuration).

### 7.2 Silent installation (CLI)

```powershell
# Elevate PowerShell as Administrator, then:
msiexec /i "kabeen-server-agent-0.2.3-x86_64.msi" /qn /norestart APIKEY="YOUR_KABEEN_APIKEY" /l*v "C:\Windows\Temp\kabeen-server-agent-install.log"
```

Useful options:

| Option              | Effect                                                               |
|---------------------|----------------------------------------------------------------------|
| `/qn`               | No UI (fully silent)                                                 |
| `/qb`               | Progress bar only                                                   |
| `/norestart`        | No automatic restart (never needed here)                            |
| `/l*v <path>`       | Verbose MSI log (useful for support)                                |
| `APIKEY="<value>"`  | Pre-fills `config.toml` with the provided key. Optional.            |

**Exit code 0 = success.** Any other code should be logged via `/l*v`.

> For mass deployment (Intune, GPO, SCCM), pass `APIKEY=…` on the `msiexec`
> command line instead of writing `config.toml` afterward. The property is
> marked `Secure` and does not appear in clear text in the standard MSI log
> (but may appear in `/l*v` logs — protect those files accordingly).

### 7.3 Installation via the provided PowerShell script (alternative method)

The repository provides `deploy/install-kabeen-server-agent-service.ps1`, which
can be used if you deploy the binary alone (e.g. from a network share, without
the MSI). This script registers the service under the virtual account
**`NT SERVICE\KabeenServerAgent`** instead of `LocalSystem`, which reduces the
attack surface.

```powershell
# Drop kabeen-server-agent.exe into C:\Program Files\Kabeen\Server Agent\
# then:
.\install-kabeen-server-agent-service.ps1 -Action install
.\install-kabeen-server-agent-service.ps1 -Action start
.\install-kabeen-server-agent-service.ps1 -Action status
```

> **Choose before deployment:** either the MSI (`LocalSystem`, standard path)
> or the PowerShell script (`NT SERVICE\KabeenServerAgent`, restricted virtual
> account). Do not mix the two on the same machine.

### 7.4 Locations

| Item           | Path                                                               |
|----------------|---------------------------------------------------------------------|
| Binary         | `C:\Program Files\Kabeen\Server Agent\kabeen-server-agent.exe`      |
| Configuration  | `C:\ProgramData\Kabeen\Server Agent\config.toml`                    |
| Agent state    | `C:\ProgramData\Kabeen\Server Agent\agent-state.toml`               |
| Logs           | `C:\ProgramData\Kabeen\Server Agent\logs\kabeen-server-agent.log`   |

ACLs applied to the `C:\ProgramData\Kabeen\Server Agent` folder:

- `SYSTEM`: Full control (inherited)
- `Administrators`: Full control (inherited)
- `NT SERVICE\KabeenServerAgent`: Modify (inherited, only with the PowerShell
  script)
- No *Users* / *Authenticated Users* entry — the files (notably
  `config.toml`) are **not** readable by unprivileged users.

---

## 8. Installation on Debian/Ubuntu (`.deb`)

### 8.1 Manual installation

```bash
# As root or via sudo
sudo apt-get update
sudo apt-get install ./kabeen-server-agent_0.1.0_amd64.deb
# (arm64 architecture: ./kabeen-server-agent_0.1.0_arm64.deb)
```

`apt-get install ./file.deb` is preferable to `dpkg -i` because it
automatically resolves dependencies (`iproute2`, `libc6 ≥ 2.31`).

The post-installer (`packaging/deb/postinst`):

1. Creates the directories:
   - `/etc/kabeen-server-agent/` (mode `0700`, owner `root`)
   - `/var/lib/kabeen-server-agent/` (mode `0700`, owner `root`)
   - `/var/log/kabeen-server-agent/` (mode `0755`, owner `root`)
2. Creates a blank `config.toml` in mode `0600` if none exists:
   ```toml
   # Kabeen Server Agent Configuration
   api_key = ""
   # endpoint = "https://intake.kabeen.io:443"
   ```
3. Reloads systemd, enables the `kabeen-server-agent.service` unit and starts it.

### 8.2 Immediate verification

```bash
sudo systemctl status kabeen-server-agent.service
sudo journalctl -u kabeen-server-agent.service -n 50 --no-pager
```

As long as `api_key` is empty, the agent loops with:
```
Configuration is incomplete (api_key is empty). Waiting...
```
This is expected. See the [Agent configuration](#10-agent-configuration) section.

### 8.3 Signature verification (signed packages)

Officially distributed packages are signed with `debsigs`. To validate:

```bash
sudo apt-get install debsig-verify
# Import the Kabeen public key into /usr/share/debsig/keyrings/<KEY_ID>/
debsig-verify kabeen-server-agent_0.1.0_amd64.deb
```

### 8.4 Locations

| Item           | Path                                                               |
|----------------|---------------------------------------------------------------------|
| Binary         | `/usr/local/bin/kabeen-server-agent`                                |
| systemd unit   | `/lib/systemd/system/kabeen-server-agent.service`                   |
| Configuration  | `/etc/kabeen-server-agent/config.toml` (mode `0600`)                |
| State          | `/var/lib/kabeen-server-agent/agent-state.toml`                     |
| Logs           | `/var/log/kabeen-server-agent/kabeen-server-agent.log` + `journald` |

---

## 9. Installation on Red Hat / derivatives (`.rpm`)

### 9.1 Manual installation

```bash
sudo dnf install ./kabeen-server-agent-0.1.0-1.x86_64.rpm
# or, on distributions without dnf:
sudo yum install ./kabeen-server-agent-0.1.0-1.x86_64.rpm
```

The `%post` scriptlet (`packaging/rpm/post-install.sh`) performs the same
operations as on Debian: directory creation, generation of a blank
`config.toml`, `systemctl enable --now`.

### 9.2 Immediate verification

```bash
sudo systemctl status kabeen-server-agent.service
sudo journalctl -u kabeen-server-agent.service -n 50 --no-pager
```

### 9.3 Signature verification

```bash
# Import the Kabeen public key
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-kabeen
# Verify the signature
rpm --checksig kabeen-server-agent-0.1.0-1.x86_64.rpm
# Expected output: "... Header V4 ... OK", "Payload V4 ... OK"
```

### 9.4 SELinux

On RHEL/Rocky/Alma with SELinux in *enforcing* mode (the default), the
service runs in the `unconfined_service_t` context via systemd. No custom
SELinux policy is required for routine operations (reading `/proc`, `/sys`,
writing to `/var/log/kabeen-server-agent`, outbound 443/TCP connection).

If you observe SELinux denials, capture them:

```bash
sudo ausearch -m AVC -ts recent | grep kabeen-server-agent
```

and forward the `AVC` entries to Kabeen support.

### 9.5 Locations

Identical to Debian (see § 8.4).

---

## 10. Agent configuration

The `config.toml` file is the **only** source of runtime configuration. It is
re-read automatically every 10 seconds by the supervisor; it is **not
necessary to restart the service** after modifying it.

### 10.1 Minimal format

```toml
api_key = "YOUR_KABEEN_API_KEY"
```

### 10.2 Full format

```toml
api_key  = "YOUR_KABEEN_API_KEY"
# Optional — useful only for pre-production environments.
# Must be HTTPS and under a subdomain of kabeen.io.
# endpoint = "https://intake.dev.kabeen.io"
# Optional — enterprise proxy (HTTP CONNECT). See § 10.6.
# proxy = "http://proxy.corp.example:8080"
```

If `endpoint` is omitted the compiled-in default (`https://intake.kabeen.io`) is used.

### 10.3 Validation constraints

| Field      | Constraint                                                                                       |
|------------|--------------------------------------------------------------------------------------------------|
| `api_key`  | ≥ 16 characters; must not be an obvious placeholder (`changeme`, `your_key_here`, `xxx`, `todo`, `placeholder`, `replace_me`). |
| `endpoint` | Must start with `https://`. In release builds, the host must be `kabeen.io` or a subdomain, or a Cloud Run service of the Kabeen GCP test project (`*-560939028376.europe-west9.run.app`). Debug builds skip this check to allow local or staging endpoints. |
| `proxy`    | `http://` or `https://` scheme. Explicit port **required**. No `user:pwd@` (proxy auth not supported). |

An invalid `api_key` or a rejected endpoint produces the message:

```
Configuration is incomplete (api_key is empty). Waiting...
```

or a failure to create the gRPC client, without crashing: the agent will
retry on the next tick.

### 10.4 File permissions

| OS      | Owner               | Mode  |
|---------|---------------------|-------|
| Linux   | `root:root`         | `0600`|
| Windows | `SYSTEM` + `Administrators` (RW), `NT SERVICE\KabeenServerAgent` (R) | ACL via `icacls` |

Do not loosen these permissions: the file contains an API key in clear text.

### 10.5 Recommended key-injection procedure

**Linux:**
```bash
sudo install -m 600 -o root -g root /dev/stdin /etc/kabeen-server-agent/config.toml <<'EOF'
api_key = "YOUR_API_KEY"
EOF
# No restart needed: the supervisor picks it up on the next tick.
```

**Windows (admin PowerShell):**
```powershell
$config = @"
api_key = "YOUR_API_KEY"
"@
$path = "C:\ProgramData\Kabeen\Server Agent\config.toml"
$config | Set-Content -Path $path -Encoding UTF8 -Force
icacls $path /inheritance:r `
    /grant "SYSTEM:(F)" `
    /grant "Administrators:(F)" `
    /grant "NT SERVICE\KabeenServerAgent:(R)" | Out-Null
```

### 10.6 Egress through an enterprise proxy (Zscaler, Squid, …)

Two operating modes are supported depending on your proxy's network
deployment.

#### 10.6.1 Transparent mode (network interception, TLS MITM)

This is the default mode of Zscaler ZIA / ZTNA when traffic is routed at the
network level (PAC delivered by GPO, Zscaler Client Connector tunnel, or
iptables redirection). **No `proxy` configuration on the agent side is
required.**

The only requirement: the **inspection root certificate** must be present in
the OS trust store. The agent uses `rustls-native-certs`, which reads this
store at startup.

**Linux (Debian/Ubuntu):**
```bash
sudo cp zscaler-root.crt /usr/local/share/ca-certificates/zscaler-root.crt
sudo update-ca-certificates
sudo systemctl restart kabeen-server-agent.service
```

**Linux (RHEL/Rocky/Alma):**
```bash
sudo cp zscaler-root.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust
sudo systemctl restart kabeen-server-agent.service
```

**Windows (admin PowerShell):**
```powershell
Import-Certificate -FilePath C:\Temp\zscaler-root.cer `
    -CertStoreLocation Cert:\LocalMachine\Root
Restart-Service KabeenServerAgent
```

> The restart is only needed to make the agent re-read the trust store — it
> does not reload it on the fly.

#### 10.6.2 Explicit mode (HTTP CONNECT to `proxy:port`)

To be used when the proxy is configured explicitly (no transparent routing).
The agent then opens a TCP connection to the proxy, sends an
`HTTP CONNECT intake.kabeen.io:443` request, then negotiates end-to-end TLS
inside the established tunnel.

```toml
api_key = "YOUR_API_KEY"
proxy   = "http://proxy.corp.example:8080"
```

**Constraints of the `proxy` field**:

| Rule                          | Valid example                   | Rejected example              |
|-------------------------------|---------------------------------|-------------------------------|
| `http://` or `https://` scheme| `http://proxy.corp:8080`        | `socks5://proxy.corp:1080`    |
| **Explicit** port             | `http://proxy.corp:8080`        | `http://proxy.corp`           |
| No inline credentials         | `http://proxy.corp:8080`        | `http://user:pwd@proxy:8080`  |

**Current limitations** (not supported):

- Proxy authentication (Basic, NTLM, Kerberos).
- PAC / WPAD auto-configuration.
- SOCKS5 proxies.

If your enterprise proxy requires authentication, two workarounds:

1. create an **authentication bypass rule** on the proxy for the source IP or
   for the destination `intake.kabeen.io`;
2. deploy a **local unauthenticated auxiliary proxy** that relays to the
   enterprise proxy (squid with `cache_peer` + `login=`).

#### 10.6.3 Via environment variables (`HTTPS_PROXY` / `NO_PROXY`)

In the absence of the `proxy` field in `config.toml`, the agent honors the
standard environment variables. The `config.toml` field stays authoritative:
if present, the environment is ignored, and so is `NO_PROXY`.

| Variable                       | Role                                                                  |
|--------------------------------|-----------------------------------------------------------------------|
| `HTTPS_PROXY` / `https_proxy`  | Proxy for HTTPS targets (the Kabeen endpoint)                        |
| `HTTP_PROXY` / `http_proxy`    | Fallback if `HTTPS_PROXY` is absent                                  |
| `NO_PROXY` / `no_proxy`        | List of domains/IPs to reach directly (applies to the env only)      |

Details:

- Both uppercase and lowercase variants are accepted.
- The **port may be omitted** in the env variable (`80` for `http://`, `443`
  for `https://` are assumed).
- **`NO_PROXY` format**: comma-separated list. For each entry, exact match OR
  suffix. `kabeen.io` and `.kabeen.io` both match `intake.kabeen.io`. The
  value `*` disables the proxy everywhere.

**Linux (systemd):**

```bash
sudo systemctl edit kabeen-server-agent.service
```

Add (the drop-in creates `/etc/systemd/system/kabeen-server-agent.service.d/override.conf`):

```ini
[Service]
Environment=HTTPS_PROXY=http://proxy.corp:8080
Environment=NO_PROXY=.internal,localhost,127.0.0.1
```

Then:

```bash
sudo systemctl daemon-reload
sudo systemctl restart kabeen-server-agent.service
```

**Windows (admin PowerShell):**

```powershell
[Environment]::SetEnvironmentVariable('HTTPS_PROXY', 'http://proxy.corp:8080', 'Machine')
[Environment]::SetEnvironmentVariable('NO_PROXY',    '.internal,localhost,127.0.0.1', 'Machine')
Restart-Service KabeenServerAgent
```

> You must use the **`Machine`** scope: `User` variables are not visible to
> services running under `LocalSystem` or under a virtual account
> `NT SERVICE\…`.

**Verification in the logs**:

```
[proxy] using env HTTPS_PROXY=http://proxy.corp:8080
Connected to Kabeen endpoint: https://intake.kabeen.io via proxy http://proxy.corp:8080
```

or, if `NO_PROXY` matches:

```
[proxy] target host 'intake.kabeen.io' matches NO_PROXY='.kabeen.io', going direct
Connected to Kabeen endpoint: https://intake.kabeen.io
```

#### 10.6.4 Quick verification

After writing `proxy = …`, the supervisor takes the change into account on the
next tick (≤ 10 s). Inspect the logs:

```bash
sudo journalctl -u kabeen-server-agent.service -f
```

Expected lines:

```
Configuration changed, restarting tasks.
Connected to Kabeen endpoint: https://intake.kabeen.io via proxy http://proxy.corp.example:8080
All tasks running. Agent is operational.
```

Typical errors (to correlate with the proxy logs):

| Agent message                                              | Probable cause                                |
|------------------------------------------------------------|-----------------------------------------------|
| `proxy CONNECT failed for … — 'HTTP/1.1 407 …'`            | The proxy requires auth (not supported)       |
| `proxy CONNECT failed for … — 'HTTP/1.1 403 …'`            | Proxy rule blocking the destination           |
| `proxy CONNECT failed for … — 'HTTP/1.1 502 …'`            | The proxy cannot reach `intake.kabeen.io`     |
| `Failed to create KabeenClient: … Connection refused`      | Proxy host/port unreachable                   |
| `Proxy '…' must specify a port explicitly`                 | Malformed `proxy` field: add `:port`          |

### 10.7 Network usage capture (enabled by default)

```toml
api_key       = "your-api-key"
network_usage = false   # set to false to opt out; enabled when omitted
```

When enabled, the agent continuously captures per-flow network usage (protocol,
endpoints, byte/packet counters, owning process, resolved remote hostname) and
ships flow records to the backend in batches. Capture is enabled by default;
set `network_usage = false` to opt out if the data volume or the payload
(remote hosts, process command lines, users) is a concern.

- **Windows** — uses an ETW kernel session (Kernel-Network, Kernel-Process,
  DNS-Client, Schannel, WinINet, WinHTTP). Requires elevation; the packaged
  service (LocalSystem) qualifies. An unelevated `--console` run logs a warning
  and the rest of the agent keeps working.
- **Linux** — polls the kernel socket tables via netlink `sock_diag` every 5 s
  and attributes sockets to processes through `/proc`. Flows shorter than one
  poll interval are not observed; UDP flows carry no byte counters. Remote
  hostnames come from reverse DNS.
- **macOS** — not implemented yet; the flag is accepted but no flows are
  captured.

Toggling the flag takes effect within ~10 s (the supervisor restarts tasks on
any config change). If the backend does not implement the `NetworkManagement`
service yet, the agent logs a single warning and drops flow batches silently.

---

## 11. Kapsul integration (migration at startup)

If **Kapsul** (the previous Kabeen agent) is already installed on the machine,
the Kabeen Server Agent **automatically imports** its configuration on the
**very first startup**.

### 11.1 What is migrated

| Kapsul item                    | Komet destination                                          |
|--------------------------------|------------------------------------------------------------|
| `kbine.apiKey` field           | `api_key` in `config.toml`                                 |
| `agentUUID` field              | `agent_id` in `agent-state.toml`                           |

> Tickets / metrics / history stored on the Kapsul side are **not** migrated.
> Only the agent's identity elements are carried over to preserve the
> machine's identity in the Kabeen backend.

### 11.2 Locations read

| OS      | Kapsul file read                                           |
|---------|------------------------------------------------------------|
| Windows | `C:\Program Files (x86)\Kapsul\application.conf`           |
| Linux   | `/etc/kapsul/application.conf`                             |
| macOS   | *(not supported — Kapsul never existed on macOS)*          |

### 11.3 Strict migration conditions

The import writes into the new configuration **only if**:

1. The `kbine.apiKey` key exists in `application.conf` **and** is at least 16
   characters long.
2. The target `config.toml` **does not already** have a non-empty `api_key`.
3. For the `agentUUID`: it is parseable as a UUID **and** `agent-state.toml`
   does not already exist.

This means a prior manual configuration of the Kabeen Server Agent is
**never** overwritten.

### 11.4 Idempotency marker

After the first attempt — **whether it succeeded or not** — a zero-byte file
`kapsul-migration-checked` is created in the data directory:

| OS      | Marker path                                                            |
|---------|-------------------------------------------------------------------------|
| Linux   | `/var/lib/kabeen-server-agent/kapsul-migration-checked`                 |
| Windows | `C:\ProgramData\Kabeen\Server Agent\kapsul-migration-checked`           |

As long as this marker exists, **no new attempt is made**, even if Kapsul is
later installed or reinstalled. To force a new migration (e.g. after a full
reset):

```bash
# Linux
sudo rm /var/lib/kabeen-server-agent/kapsul-migration-checked
sudo systemctl restart kabeen-server-agent.service
```

```powershell
# Windows
Remove-Item "C:\ProgramData\Kabeen\Server Agent\kapsul-migration-checked"
Restart-Service KabeenServerAgent
```

### 11.5 Kapsul / Kabeen Server Agent coexistence

During the migration phase, you may temporarily leave both agents installed.
**Recommendation:**

1. Install the Kabeen Server Agent (let the migration happen).
2. Verify in the Kabeen console that the machine reports under the same
   `agent_id` as before.
3. Uninstall Kapsul once the report is confirmed:
   - **Windows**: `Programs and Features` → uninstall *Kapsul*.
   - **Linux**: according to the original deployment method (`apt remove
     kapsul`, uninstall script provided by Kabeen, etc.).

### 11.6 Verifying the migration

Inspect the log on the first startup:

```bash
# Linux
sudo journalctl -u kabeen-server-agent.service | grep -i kapsul
```

Expected lines:
```
[Kapsul migration] Found Kapsul config at "/etc/kapsul/application.conf"
[Kapsul migration] Imported api_key into config.toml
[Kapsul migration] Imported agent_id into agent-state.toml
```

If Kapsul is absent:
```
[Kapsul migration] No Kapsul config found — nothing to import
```

---

## 12. Health verification

Five checks to run in order. All must be green to consider the agent
operational.

### 12.1 Is the service running?

**Linux:**
```bash
sudo systemctl is-active kabeen-server-agent.service     # → active
sudo systemctl is-enabled kabeen-server-agent.service    # → enabled
sudo systemctl status kabeen-server-agent.service
```

**Windows (admin PowerShell):**
```powershell
Get-Service -Name KabeenServerAgent
# Status must be Running, StartType Automatic
sc.exe qc KabeenServerAgent
```

### 12.2 Is the binary the expected one?

**Linux:**
```bash
/usr/local/bin/kabeen-server-agent --version 2>/dev/null || \
    dpkg -s kabeen-server-agent 2>/dev/null | grep '^Version:' || \
    rpm -q kabeen-server-agent
```

**Windows:**
```powershell
(Get-Item "C:\Program Files\Kabeen\Server Agent\kabeen-server-agent.exe").VersionInfo
Get-AuthenticodeSignature "C:\Program Files\Kabeen\Server Agent\kabeen-server-agent.exe"
# Status must be "Valid", SignerCertificate in the name of Kabeen.
```

### 12.3 Is the configuration valid?

```bash
# Linux
sudo cat /etc/kabeen-server-agent/config.toml
sudo stat -c '%a %U:%G' /etc/kabeen-server-agent/config.toml
# expected: 600 root:root
```

```powershell
# Windows
Get-Content "C:\ProgramData\Kabeen\Server Agent\config.toml"
icacls   "C:\ProgramData\Kabeen\Server Agent\config.toml"
```

### 12.4 Do the logs show registration?

```bash
# Linux — file
sudo tail -f /var/log/kabeen-server-agent/kabeen-server-agent.log
# Linux — journald
sudo journalctl -u kabeen-server-agent.service -f
```

```powershell
# Windows
Get-Content "C:\ProgramData\Kabeen\Server Agent\logs\kabeen-server-agent.log" -Tail 50 -Wait
```

Key lines to observe after injecting a valid `api_key`:

```
=== Kabeen Server Agent v0.1.0 starting ===
Endpoint: https://intake.kabeen.io
Configuration is complete. Spawning tasks...
Connected to Kabeen endpoint: https://intake.kabeen.io
All tasks running. Agent is operational.
```

Conversely, a typical blockage:

| Message                                                | Diagnosis                                         |
|--------------------------------------------------------|---------------------------------------------------|
| `Configuration is incomplete (api_key is empty)`       | `api_key` missing or empty → § 10                 |
| `Cannot read configuration at …`                       | File missing or incorrect permissions             |
| `Failed to create KabeenClient: …`                     | Endpoint unreachable / TLS / DNS                  |
| `register_or_renew failed: …`                          | API key invalid on the backend side               |

### 12.5 Does the machine report in the Kabeen console?

Log in to your Kabeen console and verify that:

- the machine appears in the host list,
- the **heartbeat** is recent (< 2 min),
- the **configuration** and **metrics** reports are present.

> In case of migration from Kapsul, the machine must keep the same identifier
> as before — that is precisely the purpose of migrating the `agentUUID`.

### 12.6 Network connectivity (quick test)

```bash
# Linux
curl -v https://intake.kabeen.io 2>&1 | head -20
# Expected HTTP/2 code: 200 or 404 (the endpoint is gRPC, not REST — we just test the TLS handshake)
```

```powershell
# Windows
Test-NetConnection -ComputerName intake.kabeen.io -Port 443
```

---

## 13. Mass deployment

### 13.1 Windows — GPO (Group Policy)

Two recommended approaches, in order of robustness.

#### 13.1.1 MSI deployment via *Software Installation*

1. **Prepare an SMB share** readable by all target machines (`Authenticated
   Users` read access is enough, no write needed):
   ```
   \\fileserver.corp\software$\Kabeen\kabeen-server-agent-0.1.0-x86_64.msi
   ```
2. **GPMC** → *Computer Configuration* → *Policies* → *Software Settings*
   → *Software installation* → right-click → *New* → *Package…*
3. Select the MSI **via the UNC path** (not a local path).
4. Choose **Assigned**.
5. Link the GPO to the OU containing the target servers.
6. Force application on a test machine:
   ```powershell
   gpupdate /force
   # The MSI is installed at the next reboot (pre-logon, machine context).
   ```

> **Limitation:** this mechanism does not allow passing custom MST transforms
> without preparation. To push the `api_key`, see step 13.1.3.

#### 13.1.2 MSI deployment via GPO scheduled task + script

More flexible, and the only way to couple installation + configuration in one
step.

Create in the GPO an **Immediate Scheduled Task** (*Computer Configuration*
→ *Preferences* → *Control Panel Settings* → *Scheduled Tasks* → *New* →
*Immediate Task (At least Windows 7)*) with:

- **User**: `NT AUTHORITY\System`
- **Run with highest privileges**: ✓
- **Action**: `Start a program`
  - Program: `powershell.exe`
  - Arguments:
    ```
    -NoProfile -ExecutionPolicy Bypass -File "\\fileserver.corp\software$\Kabeen\install.ps1"
    ```

Contents of `install.ps1` (to adapt, to sign if your GPOs require it):

```powershell
$ErrorActionPreference = 'Stop'
$msi      = '\\fileserver.corp\software$\Kabeen\kabeen-server-agent-0.1.0-x86_64.msi'
$marker   = 'C:\ProgramData\Kabeen\Server Agent\.gpo-installed'
$apiKey   = '<API_KEY_INJECTED_FROM_GPO_OR_KEYVAULT>'

if (Test-Path $marker) { exit 0 }   # already installed by GPO

# 1. Silent installation
Start-Process msiexec.exe -ArgumentList @(
    '/i', "`"$msi`"", '/qn', '/norestart',
    '/l*v', 'C:\Windows\Temp\kabeen-server-agent-install.log'
) -Wait -NoNewWindow

# 2. Configuration
$cfgDir = 'C:\ProgramData\Kabeen\Server Agent'
$cfg    = Join-Path $cfgDir 'config.toml'
"api_key = `"$apiKey`"" | Set-Content $cfg -Encoding UTF8
icacls $cfg /inheritance:r `
    /grant 'SYSTEM:(F)' `
    /grant 'Administrators:(F)' `
    /grant 'NT SERVICE\KabeenServerAgent:(R)' | Out-Null

# 3. Idempotency marker
New-Item -ItemType File -Path $marker -Force | Out-Null
```

> **Security of the `api_key` in the GPO:** **never** store it in clear text
> in the script. Prefer:
> - retrieval via an authenticated internal API (Azure Key Vault, HashiCorp
>   Vault, SCCM secret);
> - or a *Files* GPO dropping an encrypted `config.toml` that the script
>   decrypts via DPAPI `LocalMachine`.

#### 13.1.3 Configuration without installation (already-installed machines)

To push/update only the `api_key` on an already-equipped fleet, use *Computer
Configuration* → *Preferences* → *Windows Settings* → *Files* with:

- Source: a central `config.toml` protected by ACL (read by
  `Domain Computers`).
- Destination: `C:\ProgramData\Kabeen\Server Agent\config.toml`
- Action: `Replace` or `Update`

The agent will detect the new configuration on the next tick (≤ 10 s), without
a restart.

### 13.2 Windows — Microsoft Intune

#### 13.2.1 *Line-of-Business* application (MSI)

1. **Microsoft Intune admin center** → *Apps* → *Windows* → *Add* → *Line-of-business app*.
2. Upload the MSI.
3. Fill in:
   - *Name*: Kabeen Server Agent
   - *Publisher*: Kabeen
   - *Command-line arguments*: `/qn /norestart`
   - *Install behavior*: System
4. Assign the app to an Azure AD group of **Devices** (not users; the
   installation runs in system context).
5. *Detection rule*: MSI (auto, based on the `UpgradeCode`
   `B1F2A3E4-5D6C-4788-9A0B-1C2D3E4F5A6B`).

#### 13.2.2 Win32 application (`.intunewin`) with configuration

Recommended if you want to install **and** configure in one step.

1. Prepare a source folder containing:
   ```
   source/
     ├── kabeen-server-agent-0.1.0-x86_64.msi
     └── install.ps1
   ```
2. Package with `IntuneWinAppUtil.exe`:
   ```powershell
   IntuneWinAppUtil.exe -c .\source -s install.ps1 -o .\out
   ```
3. **Intune admin center** → *Apps* → *Windows* → *Add* → *Windows app (Win32)*.
4. Upload the `.intunewin`. Key fields:
   - *Install command*: `powershell.exe -NoProfile -ExecutionPolicy Bypass -File install.ps1`
   - *Uninstall command*: `msiexec /x {B1F2A3E4-5D6C-4788-9A0B-1C2D3E4F5A6B} /qn`
   - *Install behavior*: System
   - *Device restart behavior*: No specific action
5. *Requirements*: Windows 10 1809+, x64/arm64.
6. *Detection rule* (at least one of):
   - **MSI**: product code from the MSI.
   - **File**: presence of
     `C:\Program Files\Kabeen\Server Agent\kabeen-server-agent.exe`
     (with a *string version* ≥ 0.1.0).
   - **Registry**: key `HKLM\SYSTEM\CurrentControlSet\Services\KabeenServerAgent`.
7. *Assignments*: required device group.

#### 13.2.3 Distributing the `api_key` via Intune

Three possible patterns, from simplest to safest:

| Pattern                          | Key storage                 | Notes                                      |
|----------------------------------|-----------------------------|--------------------------------------------|
| Argument of the `install.ps1` script | In the `.intunewin`     | Simple, but key visible in the package     |
| *Custom OMA-URI* configuration profile | In Intune (encrypted at rest) | Push a file via the `./Device/Vendor/MSFT/EnterpriseDesktopAppManagement` CSP or a Win32 PowerShell script that calls MS Graph |
| On-the-fly retrieval             | Azure Key Vault / homemade API | The safest; install.ps1 retrieves the key via the device's managed identity |

### 13.3 Linux — Ansible / Puppet / SCCM Linux / internal repositories

#### 13.3.1 Internal APT/YUM repository

This is the **recommended** method for Linux fleets. It allows transparent
updates via `apt-get upgrade` / `dnf upgrade`.

**On the repository server side:**
- Publish the signed `.deb` packages in an APT repository (`reprepro`, `aptly`,
  `Sonatype Nexus`, `JFrog Artifactory`).
- Publish the signed `.rpm` packages in a YUM/DNF repository (`createrepo_c`,
  `Pulp`, `Nexus`, `Artifactory`).

**On the client side (template to apply via Ansible/Puppet):**

```bash
# Debian/Ubuntu
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://repo.corp/kabeen/gpg | sudo tee /etc/apt/keyrings/kabeen.asc > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/kabeen.asc] https://repo.corp/kabeen/deb stable main" | \
    sudo tee /etc/apt/sources.list.d/kabeen.list
sudo apt-get update
sudo apt-get install -y kabeen-server-agent
```

```bash
# RHEL/Rocky/Alma
sudo tee /etc/yum.repos.d/kabeen.repo <<'EOF'
[kabeen]
name=Kabeen
baseurl=https://repo.corp/kabeen/rpm/$basearch
enabled=1
gpgcheck=1
gpgkey=https://repo.corp/kabeen/gpg
EOF
sudo dnf install -y kabeen-server-agent
```

#### 13.3.2 Minimal Ansible role

```yaml
# roles/kabeen-server-agent/tasks/main.yml
- name: Install kabeen-server-agent (Debian)
  ansible.builtin.apt:
    name: kabeen-server-agent
    state: present
    update_cache: true
  when: ansible_os_family == 'Debian'

- name: Install kabeen-server-agent (RedHat)
  ansible.builtin.dnf:
    name: kabeen-server-agent
    state: present
  when: ansible_os_family == 'RedHat'

- name: Deploy the configuration
  ansible.builtin.copy:
    dest: /etc/kabeen-server-agent/config.toml
    owner: root
    group: root
    mode: '0600'
    content: |
      api_key = "{{ kabeen_api_key }}"
  notify: restart kabeen-server-agent     # optional — the supervisor reloads on its own

- name: Ensure the service is active
  ansible.builtin.systemd:
    name: kabeen-server-agent.service
    enabled: true
    state: started
    daemon_reload: true
```

**Inventory:** store `kabeen_api_key` in `ansible-vault` or an external vault;
never commit it in clear text.

#### 13.3.3 Puppet module (excerpt)

```puppet
class kabeen_server_agent (
  String $api_key,
) {
  package { 'kabeen-server-agent':
    ensure => installed,
  }

  file { '/etc/kabeen-server-agent/config.toml':
    ensure  => file,
    owner   => 'root',
    group   => 'root',
    mode    => '0600',
    content => "api_key = \"${api_key}\"\n",
    require => Package['kabeen-server-agent'],
  }

  service { 'kabeen-server-agent':
    ensure    => running,
    enable    => true,
    require   => Package['kabeen-server-agent'],
  }
}
```

---

## 14. Updates

### 14.1 Linux

```bash
# Debian/Ubuntu
sudo apt-get update && sudo apt-get install --only-upgrade kabeen-server-agent

# RedHat/Rocky/Alma
sudo dnf upgrade kabeen-server-agent
```

The scriptlets run `systemctl try-restart kabeen-server-agent.service`: the
service restarts if it was already active, otherwise it stays in its previous
state (the admin may have chosen to disable it). The existing configuration is
**preserved**.

### 14.2 Windows

The MSI is built with a stable `UpgradeCode`
(`B1F2A3E4-5D6C-4788-9A0B-1C2D3E4F5A6B`) and `MajorUpgrade` scheduled
*afterInstallInitialize*. To update:

```powershell
msiexec /i "kabeen-server-agent-0.1.1-x86_64.msi" /qn /norestart
```

The MSI:
- detects the existing installation,
- stops the service,
- replaces the binary,
- restarts the service,
- **keeps** `config.toml` and `agent-state.toml` (the `KometDataDir` component
  is marked `Permanent='yes'`).

**Downgrades** are blocked and return an explicit error.

---

## 15. Uninstallation

### 15.1 Linux

```bash
# Debian/Ubuntu — keeps the configuration
sudo apt-get remove kabeen-server-agent

# Debian/Ubuntu — full purge (configuration + state + logs)
sudo apt-get purge kabeen-server-agent
sudo rm -rf /var/lib/kabeen-server-agent /var/log/kabeen-server-agent

# RedHat/Rocky/Alma
sudo dnf remove kabeen-server-agent
# The directories created by the scriptlet are not removed by default:
sudo rm -rf /etc/kabeen-server-agent /var/lib/kabeen-server-agent /var/log/kabeen-server-agent
```

### 15.2 Windows

```powershell
# Via the product code
msiexec /x {B1F2A3E4-5D6C-4788-9A0B-1C2D3E4F5A6B} /qn /norestart

# Or via WMI
Get-CimInstance Win32_Product -Filter "Name='Kabeen Server Agent'" | `
    Invoke-CimMethod -MethodName Uninstall

# If installed via the PowerShell script (without MSI)
.\install-kabeen-server-agent-service.ps1 -Action uninstall
```

The `C:\ProgramData\Kabeen\Server Agent\` folder is marked *Permanent*: it is
**preserved** by the uninstall to keep the configuration in case of a future
reinstall. For a full cleanup:

```powershell
Remove-Item "C:\ProgramData\Kabeen\Server Agent" -Recurse -Force
```

---

## 16. Troubleshooting

### 16.1 The service does not start

| Symptom                                       | Action                                                                  |
|-----------------------------------------------|-------------------------------------------------------------------------|
| `systemctl status`: *failed*                  | `journalctl -u kabeen-server-agent -n 200`                              |
| Windows: *Error 1053* (does not respond in time) | Inspect `C:\ProgramData\Kabeen\Server Agent\logs\kabeen-server-agent.log` |
| Immediate crash with *cannot read TLS roots*  | Install / repair `ca-certificates` (Linux) or the root CAs (Windows)    |
| "Configuration is incomplete" loop            | Check `api_key` ≥ 16 characters and not a placeholder                   |

### 16.2 Data does not report despite a *Running* service

1. Check connectivity (§ 12.6).
2. Check the logs for `Failed to create KabeenClient`, `register_or_renew
   failed`, `Connection refused`, `tls handshake` messages.
3. Check the system date (a drift > 5 min breaks TLS).
4. Check that the outbound firewall allows 443/TCP to `intake.kabeen.io`.
5. In an environment with a TLS inspection proxy, import the enterprise CA
   into the system store.

### 16.3 Permission denied on the configuration file

```bash
# Linux — restore
sudo chown root:root /etc/kabeen-server-agent/config.toml
sudo chmod 600       /etc/kabeen-server-agent/config.toml
```

```powershell
# Windows — restore
icacls "C:\ProgramData\Kabeen\Server Agent\config.toml" /inheritance:r `
    /grant 'SYSTEM:(F)' /grant 'Administrators:(F)' `
    /grant 'NT SERVICE\KabeenServerAgent:(R)'
```

### 16.4 Console mode (Windows, interactive debug)

To run the agent by hand, outside the SCM (useful for diagnostics):

```powershell
# Stop the service first
Stop-Service KabeenServerAgent
& "C:\Program Files\Kabeen\Server Agent\kabeen-server-agent.exe" --console
# Ctrl+C to stop, then Start-Service KabeenServerAgent
```

### 16.5 Force a clean restart

```bash
# Linux
sudo systemctl restart kabeen-server-agent.service
```

```powershell
# Windows
Restart-Service KabeenServerAgent
```

### 16.6 No migration from Kapsul detected

See § 11.6. The `kapsul-migration-checked` marker can be deleted to force a
new attempt; while doing so, verify that the Kapsul `application.conf` is
indeed readable by root and contains a line of the form `kbine.apiKey = "…"`.

### 16.7 Reset the agent identity

If you need to force a new registration (cloned machine, corrupted identity):

```bash
# Linux
sudo systemctl stop kabeen-server-agent.service
sudo rm /var/lib/kabeen-server-agent/agent-state.toml
sudo systemctl start kabeen-server-agent.service
```

```powershell
# Windows
Stop-Service KabeenServerAgent
Remove-Item "C:\ProgramData\Kabeen\Server Agent\agent-state.toml"
Start-Service KabeenServerAgent
```

> ⚠️ This generates a **new** `agent_id` on the Kabeen backend — the machine
> will appear as a new host. Use only when appropriate.

---

## 17. Building from source

```
cargo build --release
```

The build emits a single `kabeen-server-agent` binary. See `packaging/` and `.github/workflows/release.yml` for the per-OS installer pipeline.

---

## 18. Appendices

### 18.1 Recognized environment variables

| Variable           | Effect                                                                  |
|--------------------|-------------------------------------------------------------------------|
| `KABEEN_DATA_DIR`  | Overrides the data directory. Useful for IDE/local runs without `root`. Do **not** set in production. |

### 18.2 Path recap table

| Item           | Linux                                                  | Windows                                                          |
|----------------|--------------------------------------------------------|------------------------------------------------------------------|
| Binary         | `/usr/local/bin/kabeen-server-agent`                   | `C:\Program Files\Kabeen\Server Agent\kabeen-server-agent.exe`   |
| Configuration  | `/etc/kabeen-server-agent/config.toml`                 | `C:\ProgramData\Kabeen\Server Agent\config.toml`                 |
| State          | `/var/lib/kabeen-server-agent/agent-state.toml`        | `C:\ProgramData\Kabeen\Server Agent\agent-state.toml`            |
| Kapsul marker  | `/var/lib/kabeen-server-agent/kapsul-migration-checked`| `C:\ProgramData\Kabeen\Server Agent\kapsul-migration-checked`    |
| Logs           | `/var/log/kabeen-server-agent/kabeen-server-agent.log` | `C:\ProgramData\Kabeen\Server Agent\logs\kabeen-server-agent.log`|
| Service unit   | `/lib/systemd/system/kabeen-server-agent.service`      | SCM service `KabeenServerAgent`                                 |

### 18.3 Operational commands to remember

```bash
# Linux
sudo systemctl {start|stop|restart|status} kabeen-server-agent.service
sudo systemctl {enable|disable} kabeen-server-agent.service
sudo journalctl -u kabeen-server-agent.service -f
sudo tail -f /var/log/kabeen-server-agent/kabeen-server-agent.log
```

```powershell
# Windows
Get-Service KabeenServerAgent
Start-Service / Stop-Service / Restart-Service KabeenServerAgent
sc.exe qc KabeenServerAgent
Get-Content "C:\ProgramData\Kabeen\Server Agent\logs\kabeen-server-agent.log" -Tail 100 -Wait
```

### 18.4 Common MSI return codes

| Code   | Meaning                                                                |
|--------|------------------------------------------------------------------------|
| 0      | Success                                                                |
| 1602   | User cancellation (does not happen with `/qn`)                         |
| 1603   | Fatal installation error — consult the `/l*v` log                      |
| 1618   | Another MSI installation is already in progress                        |
| 1641   | Success, restart initiated (never triggered by this installer)         |
| 3010   | Success, restart required (never triggered by this installer)          |

### 18.5 Security — operational best practices

- **Never** put the `api_key` in a Git repository.
- Restrict read access to `config.toml` (`0600` on Linux, the provided Windows
  ACL). Do not `chmod 644` or `icacls /reset`.
- For mass deployments: inject the key via a vault (Vault, Key Vault,
  CyberArk…) rather than in a clear-text script.
- Keep the packages/MSI signed; verify the signature before installation
  (§ 8.3, § 9.3, § 12.2).
- Monitor API key rotation in the Kabeen console; an updated `config.toml` is
  taken into account in ≤ 10 s without a restart.
- Let **systemd / Windows SCM** automatically restart the service on crash
  (native configuration already in place: `Restart=always`,
  `sc.exe failure … restart/60000/restart/60000/restart/60000`).

---

*Document maintained by the Kabeen team. For any feedback:
`support@kabeen.io`.*
