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

# Agent Vault with the OpenClaw gateway

> Learn how to run the OpenClaw gateway through Agent Vault so OpenClaw can make authenticated API requests from a messaging platform without ever seeing your credentials.

This guide walks you through running the [OpenClaw](https://docs.openclaw.ai/) [gateway](https://docs.openclaw.ai/gateway) through Agent Vault, so OpenClaw can make authenticated API calls without holding any real credentials. The gateway connects OpenClaw to a messaging platform such as Slack or Telegram.

<Tip>
  If you use OpenClaw in your terminal, follow [Agent Vault with OpenClaw](/docs/documentation/platform/agent-vault/guides/openclaw) instead.
</Tip>

<Accordion title="How it works">
  OpenClaw is an AI assistant that runs continuously on its own machine. Its gateway is a long-running service that connects OpenClaw to a messaging platform such as Slack, Telegram, or Discord, and makes OpenClaw's requests to its model provider and other APIs.

  By default, OpenClaw keeps the API keys for its model provider, its messaging platform, and its other tools on that machine.

  By the end of this guide, those keys will be placeholders instead of real API keys. Every request the gateway makes goes through an Agent Vault [proxy](/docs/documentation/platform/agent-vault/proxies) on a second machine, which attaches the real credential before forwarding the request to the API.

  ```mermaid theme={"dark"}
  flowchart LR
    subgraph network["Private network"]
      subgraph openclaw["OpenClaw machine"]
        subgraph gateway["OpenClaw gateway"]
          agent["OpenClaw agent"]
        end
      end
      subgraph av["Agent Vault machine"]
        proxy["Agent Vault proxy"]
      end
    end
    gateway -- "Requests with placeholders" --> proxy
    proxy -- "Requests with real credentials" --> apis["Model provider, messaging platform, and other APIs"]
    style network fill:#ffffde,stroke:#aaaa33,color:#000
    style openclaw fill:#ffffff,stroke:#757575,color:#000
    style av fill:#ffffff,stroke:#757575,color:#000
    style gateway fill:#e1f5fe,stroke:#01579b,color:#000
    style agent fill:#ececff,stroke:#9370db,color:#000
    style proxy fill:#ececff,stroke:#9370db,color:#000
    style apis fill:#ececff,stroke:#9370db,color:#000
    linkStyle default stroke:#757575
  ```

  <Info>
    For more information about how Agent Vault handles credential brokering, check out the
    [How it works](/docs/documentation/platform/agent-vault/how-it-works) page.
  </Info>
</Accordion>

## Prerequisites

* An Infisical organization where you're an Agent Vault admin
* Two machines on the same private network, one for the Agent Vault proxy and one for OpenClaw (physical machines, virtual machines, or containers)
* [OpenClaw](https://docs.openclaw.ai/start/getting-started) installed on the OpenClaw machine, with the gateway installed as a service (`openclaw onboard --install-daemon`) and a messaging platform set up and working with your real API keys
* The [Infisical CLI](/docs/cli/install) 0.43.133 or later installed on the Agent Vault machine (earlier versions don't apply [substitutions](/docs/documentation/platform/agent-vault/services#substitutions))
* [`curl`](https://curl.se/download.html) and [`jq`](https://jqlang.org/download/) installed on the OpenClaw machine

<Note>
  We recommend running the proxy on a different machine than the agent. If they run on the same machine, the agent could read the proxy's [state directory](/docs/documentation/platform/agent-vault/proxies#state-directory). That directory contains sensitive values,
  like the proxy's access token and the private key of its certificate authority.

  We also recommend keeping both machines on the same private network. This is because every request the agent makes goes through the proxy, and a round trip between networks adds latency to every request.
</Note>

## Step 1: List the API keys OpenClaw uses

OpenClaw can keep API keys in three places. Check each one on the OpenClaw machine:

* **Keys saved during onboarding:** onboarding saves model provider keys in OpenClaw's credential store. Run `openclaw models auth list` to list them without printing their values
* **Channel tokens in OpenClaw's config:** such as `channels.telegram.botToken` for Telegram
* **`~/.openclaw/.env`:** if you added keys to this file yourself, list their names without printing their values by running `grep -o '^[A-Za-z_][A-Za-z0-9_]*=' ~/.openclaw/.env | tr -d '='`

Take note of each key that holds a credential for an API. In [Step 2](#step-2-set-up-agent-vault), you'll create
[services](/docs/documentation/platform/agent-vault/services) that hold these keys.

<Accordion title="How do I know which keys to use?">
  Most OpenClaw setups have three kinds of API keys:

  | Kind | Example keys | Service to add in Step 2 |
  | - | - | - |
  | Model provider (the LLM API OpenClaw sends its prompts to) | `OPENROUTER_API_KEY`, `ANTHROPIC_API_KEY`, `OPENAI_API_KEY` | The provider's template, such as **OpenRouter**, **Anthropic**, or **OpenAI** |
  | Messaging platform (where you chat with OpenClaw) | `channels.telegram.botToken` or `TELEGRAM_BOT_TOKEN` | A **Custom** service for `api.telegram.org`, or the platform's template, such as **Slack** |
  | External APIs | `GITHUB_TOKEN` | The API's template, such as **GitHub** (or a **Custom** service if Infisical has no template for the API) |

  <Note>
    Settings that hold non-sensitive information don't need services in Agent Vault. This includes settings like allowed user IDs and channel IDs.
  </Note>
</Accordion>

## Step 2: Set up Agent Vault

### Create an access bundle

First, create an [access bundle](/docs/documentation/platform/agent-vault/access-bundles) that holds a service for each API from [Step 1](#step-1-list-the-api-keys-openclaw-uses).

<Steps>
  <Step>
    In Infisical, open **Agent Vault** from the product switcher and go to **Access Bundles**.
  </Step>

  <Step>
    Select **Create Access Bundle**. Give the access bundle a **Name**, such as `openclaw-gateway`, then select **Create Access Bundle**.
  </Step>

  <Step>
    Select the access bundle you just created, then select **Add Service**.
  </Step>

  <Step>
    On the **Choose a template** panel, pick the template for the API, or select **Custom** and enter the API's host.
  </Step>

  <Step>
    On the **Credential** step, paste the real value of the API key.

    <Note>
      [Add a substitution](/docs/documentation/platform/agent-vault/services#add-a-substitution) for each key instead if either of these is true:

      * The API expects the key outside a header, such as in the URL path. For example, Telegram's bot token goes in the URL of every request: `https://api.telegram.org/bot<token>/getUpdates`
      * The API uses more than one key, such as Slack's bot token and app token (one service can hold a substitution for each key, and an access bundle can't have two services for the same host)

      Note the placeholder you enter in **Replace**, because you'll give it to OpenClaw in [Step 3](#replace-the-api-keys-with-placeholders).
    </Note>
  </Step>

  <Step>
    Select **Add Service**. Repeat from the third step for each remaining API.
  </Step>
</Steps>

### Enroll a proxy

Next, enroll a [proxy](/docs/documentation/platform/agent-vault/proxies) on the Agent Vault machine. Every request OpenClaw makes will go through this proxy first. The proxy gets the real credential from the access bundle you just created. It attaches the credential to the request, then forwards the request to the API.

<Steps>
  <Step>
    Go to **Proxies** and select **Create Proxy**.
  </Step>

  <Step>
    Give the proxy a **Name**.

    <Note>
      Under the default [traffic policy](/docs/documentation/platform/agent-vault/proxies#traffic-policy), **Any host**, the proxy forwards requests to any host the Agent Vault machine can reach, including internal systems on your private network. If OpenClaw shouldn't reach those systems, expand **Advanced Options** and select **Access bundle hosts only**. Then list any other hosts OpenClaw needs, such as package registries, in **Exceptions**.
    </Note>
  </Step>

  <Step>
    Select **Create**.
  </Step>

  <Step>
    In the **Enrollment Token** dialog, open the **systemd** or **Docker** tab and copy what it shows. The enrollment token expires in an hour.
  </Step>
</Steps>

The gateway runs all the time, so run the proxy as a service that starts again when the machine restarts. On the Agent Vault machine:

<Tabs>
  <Tab title="systemd">
    Save the unit from the dialog as `/etc/systemd/system/agent-vault-proxy.service`, then enable and start the proxy:

    ```bash theme={"dark"}
    sudo systemctl daemon-reload
    sudo systemctl enable --now agent-vault-proxy
    ```

    `enable` starts the proxy every time the machine boots, and `--now` also starts it right away.
  </Tab>

  <Tab title="Docker">
    In the command from the dialog, add `--restart unless-stopped` after `docker run -d`, and change `-p 17323:17323` to `-p <private-ip>:17323:17323`, replacing `<private-ip>` with the Agent Vault machine's private address. Then run the command. For example:

    ```bash theme={"dark"}
    docker run -d --restart unless-stopped --name agent-vault-proxy \
      -p <private-ip>:17323:17323 \
      -v agent-vault-proxy:/etc/infisical/agent-vault \
      infisical/cli agent-vault proxy \
      --enrollment-token <enrollment-token> \
      --domain <your-instance-url>
    ```

    With `--restart unless-stopped`, Docker starts the proxy again whenever Docker itself starts, unless you stopped the container yourself. Docker must also start at boot, which you can turn on with `sudo systemctl enable docker` on most Linux machines. Publishing the port on the private address keeps the proxy off any public network interface the machine has.
  </Tab>
</Tabs>

The proxy listens on port `17323`. Make sure the OpenClaw machine can reach that port on the Agent Vault machine's private address.

<Warning>
  Don't let anything outside your private network reach port `17323`. OpenClaw proves its identity to the proxy with a token it sends unencrypted on every request, so anyone who can see that traffic and reach the proxy can use the token to call every API in your access bundle.
</Warning>

### Create a session

Finally, create a [session](/docs/documentation/platform/agent-vault/sessions) for the gateway. This will generate a token that OpenClaw can use to make authenticated requests via the proxy you enrolled.

<Steps>
  <Step>
    Go to **Sessions** and select **Create Session**.
  </Step>

  <Step>
    Pick the access bundle you created, set **Expires** to **Never**, then select **Create Session**.
  </Step>

  <Step>
    Copy the session token from the command in the dialog. It's the value after `--session-token`. The token appears once and can't be retrieved again.
  </Step>
</Steps>

<Tip>
  A session that never expires keeps working until you revoke it. Create a session for this gateway alone, so that revoking it doesn't affect your other agents.
</Tip>

## Step 3: Point the OpenClaw gateway at the proxy

Run the commands in this step on the OpenClaw machine. In each command, replace `<proxy-host>` with the Agent Vault machine's private address.

### Trust the proxy's certificate

To attach the real credentials, the proxy decrypts the HTTPS requests OpenClaw sends, so OpenClaw has to trust the proxy's certificate authority. Download the certificate from the proxy:

```bash theme={"dark"}
mkdir -p ~/.openclaw/agent-vault
curl -fsS http://<proxy-host>:17323/_agent-vault/ca | jq -er .certificate > ~/.openclaw/agent-vault/ca.pem
```

The certificate travels over plain HTTP, so check that it came from your proxy before you trust it. Print its fingerprint:

```bash theme={"dark"}
openssl x509 -in ~/.openclaw/agent-vault/ca.pem -noout -fingerprint -sha256
```

Compare the colon-separated value with the proxy's fingerprint in Infisical. On the **Proxies** page, the **Certificate Authority** column shows the start of the fingerprint, and hovering over it shows the full value. If the values don't match, or either command reports an error, don't use the file. Check that `<proxy-host>` is the Agent Vault machine's address, then download the certificate again.

OpenClaw's gateway runs on Node.js, which only reads its trusted certificates when the service starts, so add the certificate where the gateway service looks for it:

<Tabs>
  <Tab title="macOS">
    On macOS, the gateway service uses the system's trusted certificates. Add the certificate to your login keychain:

    ```bash theme={"dark"}
    security add-trusted-cert -r trustRoot -k ~/Library/Keychains/login.keychain-db ~/.openclaw/agent-vault/ca.pem
    ```

    macOS asks for your password to approve the change.
  </Tab>

  <Tab title="Linux">
    On Linux, point the gateway service at the certificate with a systemd drop-in:

    ```bash theme={"dark"}
    systemctl --user edit openclaw-gateway.service
    ```

    In the editor that opens, add these lines, replacing `<path-to-ca.pem>` with the absolute path of the certificate you downloaded, such as `/home/openclaw/.openclaw/agent-vault/ca.pem`:

    ```ini theme={"dark"}
    [Service]
    Environment=NODE_EXTRA_CA_CERTS=<path-to-ca.pem>
    ```

    Save and close the editor. A drop-in is separate from the unit OpenClaw generates, so reinstalling the gateway doesn't remove it.
  </Tab>
</Tabs>

### Replace the API keys with placeholders

Replace each API key you added a service for in [Step 2](#create-an-access-bundle) with a placeholder, wherever OpenClaw keeps it:

* **For a service that attaches the credential to a header:** use any value (the proxy replaces the header with the real credential)
* **For a service with a substitution:** use the exact placeholder you entered in **Replace**

For model provider keys saved during onboarding, run `openclaw models auth list` to find the saved profile, then remove it with `openclaw models auth logout <profile-id>`. Then create `~/.openclaw/.env`, or add to it if it already exists, with the provider's placeholder. If you added keys to that file yourself, replace their values there too. For example:

```bash theme={"dark"}
OPENROUTER_API_KEY=agent-vault-openrouter
```

For channel tokens in OpenClaw's config, set the placeholder with `openclaw config set`. For example:

```bash theme={"dark"}
openclaw config set channels.telegram.botToken __TELEGRAM_BOT_TOKEN__
```

<Note>
  If the channel's service uses a substitution, make sure you set the token to the exact value you entered in **Replace** in [Step 2](#create-an-access-bundle).
</Note>

The real values are now stored in Infisical, so you don't need to keep them on the OpenClaw machine.

### Route the gateway through the proxy

Set OpenClaw's proxy URL, replacing `<session-token>` with the token from [Step 2](#create-a-session):

```bash theme={"dark"}
openclaw config set proxy.proxyUrl http://x-agent-vault:<session-token>@<proxy-host>:17323
```

OpenClaw routes all of the gateway's outbound HTTP and WebSocket traffic through this proxy, including traffic from its messaging platform clients. Then reinstall the gateway service so it picks up the new settings. This also restarts the gateway.

```bash theme={"dark"}
openclaw gateway install --force
```

## Step 4: Verify it works

On the Agent Vault machine, follow the proxy's logs:

<Tabs>
  <Tab title="systemd">
    ```bash theme={"dark"}
    sudo journalctl -u agent-vault-proxy -f
    ```
  </Tab>

  <Tab title="Docker">
    ```bash theme={"dark"}
    docker logs -f agent-vault-proxy
    ```
  </Tab>
</Tabs>

### Check the model provider

Send OpenClaw a message through your messaging platform. If OpenClaw replies, both the messaging platform and the model provider received the real credentials, and the proxy [logs those requests as `brokered`](/docs/documentation/platform/agent-vault/session-logs#what-gets-recorded).

### Check API calls

To check the credential for another API in your access bundle, ask OpenClaw to call that API. For example, if your access bundle has a GitHub service:

> Run `curl -sS https://api.github.com/user` and show me the output.

GitHub returns your account. If you run the same request in a terminal outside OpenClaw, GitHub responds with a 401.

<Check>
  The OpenClaw gateway now runs with placeholders instead of API keys. The only credential on the OpenClaw machine is the session token, and if you revoke the session, the proxy stops attaching credentials to any request from OpenClaw.
</Check>

## Revoke or replace the session

To stop OpenClaw from using the real credentials, open **Agent Vault** in Infisical and go to **Sessions**. Open the session's menu and select **Revoke Session**. The proxy stops attaching credentials within one [poll interval](/docs/documentation/platform/agent-vault/proxies#poll-interval), and OpenClaw stops replying because its requests to the model provider fail.

To give the gateway a new session, [create a session](#create-a-session) in Infisical. Then, on the OpenClaw machine, run `openclaw config set proxy.proxyUrl` again with the new token, and run `openclaw gateway restart`.

## Troubleshooting

To follow the gateway's logs, run `openclaw logs --follow`. To check the gateway's configuration and service, run `openclaw doctor`.

### Setting up the proxy

<AccordionGroup>
  <Accordion title="The proxy's systemd service fails to start">
    If `sudo systemctl status agent-vault-proxy` shows `status=203/EXEC`, systemd couldn't find the Infisical CLI. The unit from the enrollment dialog starts the proxy with `/usr/local/bin/infisical`, but your CLI may be installed somewhere else.

    Run `which infisical` to find your CLI's path. In `/etc/systemd/system/agent-vault-proxy.service`, replace `/usr/local/bin/infisical` at the start of the `ExecStart=` line with that path, then reload and restart the proxy:

    ```bash theme={"dark"}
    sudo systemctl daemon-reload
    sudo systemctl restart agent-vault-proxy
    ```
  </Accordion>
</AccordionGroup>

### Requests that skip the proxy

<AccordionGroup>
  <Accordion title="The proxy logs no requests from OpenClaw">
    By default, the proxy only logs the requests it brokers, blocks, or can't complete. If no service matches a request, the proxy forwards the request unchanged and doesn't log it. To see every request, restart the proxy with `--log-level debug` added to its command.

    If the proxy still logs nothing from OpenClaw, the gateway isn't using the proxy. `openclaw config get proxy` hides the proxy URL because it contains your session token, so check the value in OpenClaw's config file instead. This command prints the URL with the session token removed:

    ```bash theme={"dark"}
    jq -r '.proxy.proxyUrl' ~/.openclaw/openclaw.json | sed -E 's#//[^@]*@#//#'
    ```

    Check that it prints `http://<proxy-host>:17323` with the Agent Vault machine's address.

    If the URL is wrong, set it again with `openclaw config set proxy.proxyUrl`, then run `openclaw gateway restart`.
  </Accordion>

  <Accordion title="The messaging platform's requests skip the proxy">
    OpenClaw has proxy settings for individual channels, such as `channels.telegram.proxy`. If one of these is set, that channel's requests use it instead of the proxy URL from [Step 3](#route-the-gateway-through-the-proxy). Remove the setting for your channel, then run `openclaw gateway restart`.
  </Accordion>
</AccordionGroup>

### Errors from the proxy

<AccordionGroup>
  <Accordion title="407 from the proxy">
    The session token was missing from the request. Check that `proxy.proxyUrl` includes the token as the password, like `http://x-agent-vault:<session-token>@<proxy-host>:17323`.
  </Accordion>

  <Accordion title="403 from the proxy">
    This could be for a few reasons:

    * The session was revoked or has expired (check the **Sessions** page in Infisical, and [replace the session](#revoke-or-replace-the-session) if needed)
    * Under the proxy's [strict traffic policy](/docs/documentation/platform/agent-vault/proxies#traffic-policy), no service in the bundle covers the host OpenClaw called (add a service that does, or use a pass-through service)
    * The service covers the host, but doesn't allow the request's method or path (check the service's [methods and paths](/docs/documentation/platform/agent-vault/services#methods-and-paths))
  </Accordion>
</AccordionGroup>

### Errors in OpenClaw

<AccordionGroup>
  <Accordion title="The gateway logs certificate verification errors">
    OpenClaw doesn't trust the proxy's certificate. On macOS, check that the certificate is in your login keychain. On Linux, check that the drop-in sets `NODE_EXTRA_CA_CERTS` to an absolute path and that `ca.pem` isn't empty, then run `systemctl --user daemon-reload` and `openclaw gateway restart`.
  </Accordion>

  <Accordion title="Authentication error from an upstream API">
    The credential wasn't applied. Open your access bundle and confirm a service covers the host OpenClaw called. If one does, the stored credential is likely wrong. If the service uses a substitution, check that OpenClaw's placeholder matches **Replace** exactly.
  </Accordion>

  <Accordion title="OpenClaw still uses a real key">
    A key saved during onboarding can take priority over the placeholder in `~/.openclaw/.env`. Run `openclaw models auth list`, remove any saved profile for that provider with `openclaw models auth logout <profile-id>`, then run `openclaw gateway restart`.
  </Accordion>

  <Accordion title="A messaging platform rejects the channel's token">
    The platform received the placeholder instead of the real token, because the placeholder in the channel's config doesn't match **Replace** in the service's substitution. For example, Telegram reports `getMe returned 404`. Set the channel's token to the exact **Replace** value with `openclaw config set`.

    After a rejected token, OpenClaw stops the channel and doesn't start it again on its own. Once the placeholder matches, start the channel, replacing `<channel>` with its name, such as `telegram`:

    ```bash theme={"dark"}
    openclaw gateway call channels.start --params '{"channel":"<channel>"}'
    ```
  </Accordion>

  <Accordion title="Channels don't start after several gateway restarts">
    If the gateway restarts several times within five minutes, OpenClaw stops starting channels automatically, and its logs mention a crash-loop breaker. Start each channel yourself, replacing `<channel>` with its name:

    ```bash theme={"dark"}
    openclaw gateway call channels.start --params '{"channel":"<channel>"}'
    ```
  </Accordion>

  <Accordion title="The gateway is stuck waiting for state ownership">
    Another OpenClaw process may be using OpenClaw's state, usually an `openclaw tui --local` session from the [terminal guide](/docs/documentation/platform/agent-vault/guides/openclaw). The gateway waits for that process to exit. Quit the terminal session, then run `openclaw gateway restart`.
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Services" icon="plug" href="/docs/documentation/platform/agent-vault/services">
    Credential types, substitutions, and limits on the methods and paths an agent can use.
  </Card>

  <Card title="Sessions" icon="monitor" href="/docs/documentation/platform/agent-vault/sessions">
    Time-bound grants that let AI agents access services without holding real credentials.
  </Card>

  <Card title="Proxies" icon="route" href="/docs/documentation/platform/agent-vault/proxies">
    Traffic policies, poll intervals, and certificate trust for the proxy.
  </Card>

  <Card title="Session logs" icon="scroll-text" href="/docs/documentation/platform/agent-vault/session-logs">
    Every request an agent makes during a session.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.