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

# Install Formal Endpoint on Linux

> Install the headless Formal Endpoint package on Debian and Ubuntu hosts

export const G = ({term, anchor, children}) => {
  const href = anchor ? `/docs/glossary/index#${anchor}` : `/docs/glossary/index`;
  return <a href={href} className="glossary-link" style={{
    textDecoration: "underline",
    textDecorationLine: "underline",
    textDecorationColor: "#6b7280",
    textDecorationThickness: "1px",
    textUnderlineOffset: "2px",
    color: "inherit",
    transition: "text-decoration-color 0.2s ease",
    borderBottom: "none"
  }} onMouseEnter={e => e.target.style.textDecorationColor = "#fff"} onMouseLeave={e => e.target.style.textDecorationColor = "#6b7280"}>
  {children || term}
</a>;
};

## Overview

Install the headless Formal Endpoint package on Debian or Ubuntu. The package
adds the `formal` CLI and a systemd user service that runs
`formal agent --headless`. Enable Transparent Mode to intercept host
traffic, including traffic from coding agents.

For Kubernetes, use the [Kubernetes egress sidecar](/docs/guides/client-apps/kubernetes-egress)
instead of this package.

## Prerequisites

* A Debian or Ubuntu host with `sudo` and systemd
* A Formal API key from [API Keys](https://app.formal.ai/api-keys)
* Outbound HTTPS to `static-assets.formalcloud.net` and `api.joinformal.com`

The package supports `amd64` and `arm64`.

## Install

<Steps>
  <Step title="Download and install the package">
    The latest package URL includes the host architecture:

    ```bash theme={"languages":{"custom":["/languages/cel.json","/languages/rego.json"]}}
    arch="$(dpkg --print-architecture)"
    curl --fail --silent --show-error --location \
      "https://static-assets.formalcloud.net/desktop-app/linux/formal-desktop-headless_latest_${arch}.deb" \
      --output /tmp/formal-desktop-headless.deb
    sudo apt-get update
    sudo apt-get install --yes /tmp/formal-desktop-headless.deb
    ```

    Pin a versioned package URL when your rollout requires a fixed version.

    **Verify:**

    ```bash theme={"languages":{"custom":["/languages/cel.json","/languages/rego.json"]}}
    command -v formal
    # Expected: /usr/bin/formal
    ```
  </Step>

  <Step title="Grant access to the local CA directory">
    The Endpoint writes its local CA to `/var/lib/formal/ca`. Your user must
    be able to write that directory:

    ```bash theme={"languages":{"custom":["/languages/cel.json","/languages/rego.json"]}}
    sudo chgrp "$(id -gn)" /var/lib/formal/ca
    sudo chmod 0775 /var/lib/formal/ca
    ```
  </Step>

  <Step title="Configure the API key and Transparent Mode">
    Create `~/.formal` and store the API key in `formal.env`. The user
    service loads that file on start.

    ```bash theme={"languages":{"custom":["/languages/cel.json","/languages/rego.json"]}}
    mkdir -p ~/.formal
    chmod 0700 ~/.formal
    printf 'FORMAL_API_KEY=<YOUR_API_KEY>\n' > ~/.formal/formal.env
    chmod 0600 ~/.formal/formal.env
    cat > ~/.formal/config.toml <<'EOF'
    [transparent_proxy]
    enable = true
    EOF
    ```

    Replace `<YOUR_API_KEY>` with a key from
    [API Keys](https://app.formal.ai/api-keys). See
    [Configuration](/docs/guides/client-apps/configuration) for other
    `config.toml` keys. To skip long-lived keys, use
    [OIDC](/docs/guides/client-apps/desktop-app#log-in-with-oidc).
  </Step>

  <Step title="Enable lingering and start the service">
    Lingering lets systemd start the user service without an interactive
    login. This is required on servers and VMs.

    ```bash theme={"languages":{"custom":["/languages/cel.json","/languages/rego.json"]}}
    sudo loginctl enable-linger "$(id -un)"
    export XDG_RUNTIME_DIR="/run/user/$(id -u)"
    systemctl --user daemon-reload
    systemctl --user enable --now formal.service
    ```

    **Verify:**

    ```bash theme={"languages":{"custom":["/languages/cel.json","/languages/rego.json"]}}
    XDG_RUNTIME_DIR="/run/user/$(id -u)" \
      systemctl --user is-active formal.service
    # Expected: active
    ```
  </Step>
</Steps>

## Verify

```bash theme={"languages":{"custom":["/languages/cel.json","/languages/rego.json"]}}
formal auth whoami
formal transparent-proxy status
```

`formal auth whoami` should show the user that owns the API key. The
Transparent Mode status should be enabled.

Write [network rules](/docs/guides/network-rules) to select which flows
Transparent Mode intercepts. On Linux, match a hostname or
`is_llm_hostname`. Linux has no process signing identity.

<Tip>
  Read service logs with `journalctl --user -u formal.service`. Set
  `XDG_RUNTIME_DIR` first when your shell has no session bus.
</Tip>

## Troubleshooting

<AccordionGroup>
  <Accordion title="The user service is not running">
    Confirm lingering is enabled with `loginctl show-user "$(id -un)"`. Set
    `XDG_RUNTIME_DIR="/run/user/$(id -u)"` and read failures with
    `journalctl --user -u formal.service`. Then run
    `systemctl --user enable --now formal.service`.
  </Accordion>

  <Accordion title="CLI cannot connect to the Formal app">
    **Error:** `WARNING: CLI cannot connect to the Formal app.`

    The CLI talks to the user service over a local socket. Confirm
    `formal.service` is active, then retry `formal auth whoami`.
  </Accordion>

  <Accordion title="The local CA directory is not writable">
    The Endpoint must write `/var/lib/formal/ca`. Re-run:

    ```bash theme={"languages":{"custom":["/languages/cel.json","/languages/rego.json"]}}
    sudo chgrp "$(id -gn)" /var/lib/formal/ca
    sudo chmod 0775 /var/lib/formal/ca
    ```

    Then restart the service.
  </Accordion>

  <Accordion title="Transparent Mode does not intercept traffic">
    Confirm `~/.formal/config.toml` sets `transparent_proxy.enable = true`.
    Confirm `formal transparent-proxy status` is enabled. Confirm a
    [network rule](/docs/guides/network-rules) matches the destination.
    Without a matching rule, the Endpoint forwards the connection without
    inspecting it.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Formal Endpoint" icon="desktop" href="/docs/guides/client-apps/desktop-app">
    Review authentication and connection options
  </Card>

  <Card title="Configuration" icon="sliders" href="/docs/guides/client-apps/configuration">
    Set config.toml keys for the Endpoint
  </Card>

  <Card title="Network Rules" icon="filter" href="/docs/guides/network-rules">
    Select which traffic Transparent Mode intercepts
  </Card>

  <Card title="Cloud Agents" icon="cloud" href="/docs/guides/example-use-cases/formal-endpoint-cloud-agents">
    Run the Endpoint inside Cursor and Devin agents
  </Card>
</CardGroup>
