> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aiaxoniq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Install on Linux

> Install the zero-code agent as a systemd service: preflight the host, install, verify, upgrade and remove — including the check that blocks a silent failure.

The agent runs as one systemd service per host, observing every process on it.

<Warning>
  **Availability.** The zero-code agent is an early-access distribution. It is
  installable, upgradable and tested, and it is **not yet an integrated part of
  the product**: there is no dashboard page for it, no in-product installer and
  no self-service download. Ask your account contact for access.

  Its telemetry, once flowing, is ordinary OTLP and needs nothing special —
  it appears in Services, Traces and Metrics exactly like SDK telemetry does.
  That is the design rather than a shortcut.
</Warning>

<Info>
  **Before you start, you need two values.**

  1. **Your base endpoint** — shown on **Get Started** in the dashboard. These
     pages write it as `$OIQ_ENDPOINT`.
  2. **A license key** — created in **Settings → License Keys**, starting
     `oiq_`. Requires the Admin role. See
     [Create a license key](/get-started/license-keys). These pages write it as
     `$OIQ_LICENSE_KEY`.

  Export both before running anything below:

  ```bash theme={null}
  export OIQ_ENDPOINT="https://app.aiaxoniq.com/otlp"   # or your own
  export OIQ_LICENSE_KEY="oiq_..."
  ```
</Info>

<Info>
  **Give the endpoint as a base URL** — not a signal path. The tooling refuses
  `.../v1/traces` outright rather than letting it fail later as a confusing
  404 at ingest.
</Info>

## 1. Check the host first

<Steps>
  <Step title="Run preflight">
    ```bash theme={null}
    ./bin/oiq-zerocode-preflight
    ```

    It reads only. It installs nothing, sends nothing, and loads no eBPF
    program — it is safe to run on production.
  </Step>

  <Step title="Read the result">
    A host that passes looks like this:

    ```text theme={null}
      ✓ operating system             Ubuntu 22.04.5 LTS
      ✓ kernel version               6.8.0-47-generic (need 5.8+)
      ✓ BTF (CO-RE)                  /sys/kernel/btf/vmlinux present
      ✓ architecture                 x86_64 → linux-amd64
      ⚠ capabilities (profile A)     not held by this shell
                                     — the installer grants them
      · perf_event_paranoid          4 — not required by profile A

      → This host is supported. (1 warning(s) — none block installation.)
    ```
  </Step>
</Steps>

<Warning>
  **A `⚠` never blocks; a `✗` always does.** The capability warning describes
  your *current shell*, and the installer grants capabilities through `setcap`
  and systemd. Do not chase it.

  The one you must not override is this, on the same host, for the default
  profile:

  ```text theme={null}
    ✗ perf_event_paranoid          4 — profile B attaches kprobes and WILL
                                   silently collect nothing.
  ```

  The agent would start, hold every capability, pass its own checks, report
  healthy and collect nothing at all. Fix it on the host:

  ```bash theme={null}
  sudo sysctl -w kernel.perf_event_paranoid=1
  echo 'kernel.perf_event_paranoid=1' | sudo tee /etc/sysctl.d/99-aiaxoniq.conf
  ```
</Warning>

Preflight also emits machine-readable output for a CI gate — the human report
goes to stderr, so this composes cleanly:

```bash theme={null}
./bin/oiq-zerocode-preflight --format json | jq '.supported'
```

## 2. Preview, then install

```bash theme={null}
./install/install.sh --endpoint "$OIQ_ENDPOINT" --dry-run
```

`--dry-run` prints exactly what would happen and changes nothing. When you are
satisfied:

```bash theme={null}
export OIQ_LICENSE_KEY='oiq_...'
sudo -E ./install/install.sh --endpoint "$OIQ_ENDPOINT"
```

<Warning>
  **`sudo -E` is not optional.** It preserves `OIQ_LICENSE_KEY` across the
  privilege change. Without it the installer writes a placeholder and tells you
  so — the agent then installs cleanly and every export is rejected with `401`.

  The key is read from the environment rather than passed as a flag so that it
  does not land in your shell history or in `ps` output.
</Warning>

### What the installer does

<Steps>
  <Step title="Runs preflight">
    Skippable with `--skip-preflight`, which you should not use.
  </Step>

  <Step title="Downloads the upstream agent and verifies its SHA-256">
    Against the checksums shipped with the distribution. **A mismatch is fatal
    and there is no skip flag.**
  </Step>

  <Step title="Installs the binary and applies the capability profile">
    Using `setcap`, plus the systemd unit's ambient capabilities.
  </Step>

  <Step title="Generates the configuration and the credential file">
    Configuration at mode `0644`; endpoint and key at mode `0600`.
  </Step>

  <Step title="Writes and starts the service" />
</Steps>

### What lands on disk

```text theme={null}
/usr/local/bin/obi                          upstream binary, unmodified
/etc/aiaxoniq-zerocode/config.yaml          agent configuration      (0644)
/etc/aiaxoniq-zerocode/agent.env            endpoint + license key   (0600)
/etc/systemd/system/aiaxoniq-zerocode.service
/var/log/aiaxoniq-zerocode/
```

### Options

```text theme={null}
--profile A|B|C       capability profile (default B)
--allow-sys-admin     add CAP_SYS_ADMIN to profile C (near-root)
--force-config        overwrite an existing config.yaml / agent.env
--no-start            install without starting
--dry-run             print what would happen; change nothing
```

See [Capability profiles](/zero-code/profiles) before changing `--profile`.

## 3. Confirm it is running

```bash theme={null}
systemctl status aiaxoniq-zerocode
journalctl -u aiaxoniq-zerocode -f
```

Then confirm data is actually arriving — a running agent is not the same as a
working one. See [Verification](/zero-code/verification).

## Upgrading

Re-run the installer. **Upgrades happen in place and preserve your
configuration**: `config.yaml` and `agent.env` are kept unless you pass
`--force-config`. An installer that silently discarded tuned route patterns on
upgrade would be a defect.

<Note>
  **The systemd unit is always regenerated**, because it encodes the capability
  profile. A stale unit would leave the agent running at the old privilege
  level while you believed you had changed it — which is the failure you would
  least want to be silent.

  Run the audit tool after any upgrade to confirm the privilege you actually
  have.
</Note>

## Removing

```bash theme={null}
sudo ./install/uninstall.sh            # keeps config and key
sudo ./install/uninstall.sh --purge    # removes them too
```

Nothing is left in the kernel either way — eBPF programs are released when the
process exits. No reboot, no module to unload.

## If something is wrong

<AccordionGroup>
  <Accordion title="It refuses to start: capabilities are required" icon="ban">
    Capability enforcement is doing its job — the agent refuses to attach
    partially and then report nothing. The message names exactly what is
    missing.

    The usual cause is `setcap` failing on a filesystem without extended
    attribute support. systemd's ambient capabilities still grant them, so
    check the unit is the thing actually starting the process.
  </Accordion>

  <Accordion title="It runs, but no telemetry arrives" icon="ghost">
    In order of likelihood: `perf_event_paranoid` above 1, then a rejected
    license key showing as `401` in the log. Both, with the commands to confirm
    each, are on [Troubleshooting](/zero-code/troubleshooting).
  </Accordion>

  <Accordion title="Metric volume is higher than expected" icon="chart-line">
    Route unification is on by default, but your own explicit route patterns
    always beat the heuristic. See
    [Troubleshooting](/zero-code/troubleshooting).
  </Accordion>
</AccordionGroup>

## Next

<CardGroup cols={3}>
  <Card title="Verification" icon="circle-check" href="/zero-code/verification">
    Confirm data is arriving, and rule out the silent failure.
  </Card>

  <Card title="Capability profiles" icon="layer-group" href="/zero-code/profiles">
    What `--profile` actually changes.
  </Card>

  <Card title="Troubleshooting" icon="triangle-exclamation" href="/zero-code/troubleshooting">
    Symptom to cause to fix.
  </Card>
</CardGroup>
