# OpenClaw on a VPS: Telegram, Discord, updates and security

> Day two OpenClaw guide for a VPS: connect Telegram and Discord with allowlists, update and roll back, lock down the gateway, size the server and fix errors.

Your agent is installed and answers its first message. Now it has to keep working for months on a public server without letting strangers drive it. This guide covers what comes after [installing OpenClaw on a VPS](https://datapasa.com/wiki/guides/install-openclaw-on-vps): locking Telegram down to your own account, adding a Discord bot, updating without breaking anything, restricting what the agent may execute, and the commands to reach for when a channel goes quiet.

OpenClaw moves fast and its docs change weekly. Everything below was checked against [docs.openclaw.ai](https://docs.openclaw.ai) in November 2026. If a command behaves differently on your version, the official page for that command wins.

## Before you start

- **OpenClaw is installed and the gateway runs as a service.** If not, start with the [installation guide](https://datapasa.com/wiki/guides/install-openclaw-on-vps).
- **You can log in over SSH**, ideally with keys. See [how to set up SSH keys](https://datapasa.com/wiki/server-management/set-up-ssh-keys).
- **Node.js is current.** Recent OpenClaw releases need Node 24.16.0 or newer on the 24.x line, or 26.1.0 or newer. Check with `node -v` and upgrade Node first if it is older, otherwise updates will refuse to run.

The main config file is `~/.openclaw/openclaw.json` (JSON5, so comments and trailing commas are fine). With the default hot reload, the running gateway picks up most channel changes without a restart.

## Lock Telegram to your own account

A Telegram bot username is public. Anyone who guesses it can open a chat, so the question is what happens when a stranger writes to your agent.

OpenClaw answers that with `channels.telegram.dmPolicy`. It accepts four values:

| Value | Who can talk to the bot in private chat |
|---|---|
| `pairing` (default) | Unknown senders get a pairing code and nothing else until you approve it on the server |
| `allowlist` | Only the numeric user IDs listed in `allowFrom` |
| `open` | Anyone, and only if `allowFrom` contains `"*"` |
| `disabled` | Nobody |

Pairing is what you used during installation. It is fine to start with, but for a bot that only you use, an explicit allowlist is tighter: there is no pairing prompt for strangers to poke at, and your access does not depend on what is stored in the pairing database.

### Step 1. Find your Telegram user ID

You need the numeric ID, not your @username or phone number. The private way is to read it from OpenClaw itself: while the policy is still `pairing`, the bot's pairing reply contains your user ID. You can also watch the log on the server while you send the bot a message:

```bash
openclaw logs --follow
```

Look for `senderUserId` in the `telegram pairing request` entry, then stop following with Ctrl+C.

### Step 2. Switch to an allowlist

Open the config:

```bash
nano ~/.openclaw/openclaw.json
```

Set the Telegram block like this, with your own ID:

```json5
{
  channels: {
    telegram: {
      enabled: true,
      dmPolicy: "allowlist",
      allowFrom: ["123456789"],
    },
  },
}
```

Keep `botToken` (or `tokenFile`) as onboarding wrote it. If onboarding added a `groups` entry with `"*"`, decide whether you want that (see Groups below). An `allowlist` with an empty `allowFrom` is rejected by config validation, so you cannot lock yourself out by accident. Then confirm the channel is healthy:

```bash
openclaw channels status --probe
```

> **Pending pairing requests.** If you stay on `pairing`, list and approve requests with `openclaw pairing list telegram` and `openclaw pairing approve telegram <CODE>`. Codes expire after one hour. Approving someone gives them private chat access only, not group or owner rights.

### Groups

Group access is a separate check. By default `groupPolicy` is `allowlist`: without a `groups` map the bot ignores every group, and with one it accepts only the listed group chat IDs (the negative numbers starting with `-100`) or every group if the map contains `"*"`. Inside an allowed group, only senders from `groupAllowFrom` can trigger it, and when that is unset OpenClaw falls back to your `allowFrom`. With `requireMention: true` it only reacts when someone mentions `@your_bot`. If you want it to read every message in a group, disable privacy mode in BotFather with `/setprivacy`, then remove the bot from the group and add it again.

Do not put group IDs in `allowFrom` or `groupAllowFrom`. Those fields take user IDs only.

## Add a Discord bot

Discord is the natural second channel: you can give each topic its own text channel, and each channel becomes a separate agent session.

### Step 1. Create the application

1. Open the [Discord Developer Portal](https://discord.com/developers/applications) and click **New Application**.
2. On the **Bot** page set the username, then under **Privileged Gateway Intents** turn on **Message Content Intent**. Turn on **Server Members Intent** too if you plan to allow users by role or name. **Presence Intent** is not needed.
3. Still on **Bot**, click **Reset Token** and copy the token. Despite the label, this creates your first token.
4. In **OAuth2**, open the URL generator, tick the `bot` and `applications.commands` scopes, and give at least View Channels, Send Messages, Read Message History, Embed Links and Attach Files. Add Send Messages in Threads if the bot will reply in threads.
5. Open the generated URL and add the bot to a server you control. A private server just for you and the bot is the safest choice.

In the Discord app, enable **Developer Mode** (User Settings, Developer) and copy your **Server ID** and your own **User ID**. In the server's **Privacy Settings**, allow direct messages so the bot can send you the pairing code.

### Step 2. Give OpenClaw the token

Keep the token out of chat messages and out of shell history where you can. A clean way is to put it in the global env file that the service reads:

```bash
echo 'DISCORD_BOT_TOKEN=YOUR_BOT_TOKEN' >> ~/.openclaw/.env
chmod 600 ~/.openclaw/.env
```

Then reference it from the config instead of pasting the value in:

```json5
{
  channels: {
    discord: {
      enabled: true,
      token: { source: "env", provider: "default", id: "DISCORD_BOT_TOKEN" },
      groupPolicy: "allowlist",
      guilds: {
        "YOUR_SERVER_ID": {
          requireMention: true,
          users: ["YOUR_USER_ID"],
        },
      },
    },
  },
}
```

Discord ships as an official plugin. If `openclaw channels status --probe` reports it as missing, run `openclaw channels add` and pick Discord from the list, which installs it on demand. Restart the gateway so the service loads the new environment value:

```bash
openclaw gateway restart
```

### Step 3. Pair your account

Send the bot a direct message in Discord. It replies with a code, which you approve on the server:

```bash
openclaw pairing list discord
openclaw pairing approve discord <CODE>
```

Discord DMs follow the same `dmPolicy` values as Telegram (`pairing` by default). Once it works, you can switch Discord to `allowlist` with your user ID in `channels.discord.allowFrom`. On a private server you can also set `requireMention: false` for the guild so the agent answers every message without a mention.

> **Message Content Intent.** If the bot is online but never reacts to normal server messages, the Message Content Intent is almost always the cause. Enable it in the Developer Portal and restart the gateway.

### Other channels

The official channel list is long. Besides Telegram and Discord it includes WhatsApp, Signal, Slack, Matrix, Microsoft Teams, Google Chat, Mattermost, IRC, LINE, iMessage, Nextcloud Talk, Twitch, SMS through Twilio and several more. Run `openclaw channels add` without flags to choose one interactively. Signal and WhatsApp keep extra state on disk, and iMessage needs a Mac, so they are less convenient on a headless VPS than bot token channels.

## Keep OpenClaw up to date

Releases come out often and many include security fixes, so plan on updating regularly. The supported path is the built in updater: it detects how OpenClaw was installed, checks the new version while the old gateway keeps serving, then switches over and verifies the result.

### Step 1. Check what you are running

```bash
openclaw --version
openclaw status
```

The first command shows the CLI version. `openclaw status` also shows what the gateway service runs. If the two disagree, you have two installs (for example after switching Node versions), and you should fix that before updating.

### Step 2. Back up, then preview

The updater keeps a copy of your config, but that is not a full recovery point. Before a significant update, create a verified archive:

```bash
mkdir -p ~/Backups/openclaw
openclaw backup create --output ~/Backups/openclaw --verify
openclaw update --dry-run
```

The dry run prints the target version and any preflight check that would block the update, without changing anything.

### Step 3. Update

```bash
openclaw update
```

Run it as the same Linux user that owns the gateway. When it finishes, `openclaw update status` shows the result and the history of earlier runs. By default you follow the **stable** channel. `beta` gets releases earlier, and `dev` tracks the main branch and is not meant for an agent you rely on.

> **Prefer the updater over raw npm.** `npm install -g openclaw@latest` replaces the package but skips the migration checks and the rollback copy the updater keeps. If you do use npm manually, follow it with `openclaw doctor --fix` and `openclaw gateway restart`.

### Rolling back

If a release misbehaves and the older version can still read your data, the updater can go back to a specific version and asks for confirmation first:

```bash
openclaw update --tag <known-good-version> --dry-run
openclaw update --tag <known-good-version>
```

Downgrading the package does not undo config or database migrations. If the older version refuses the newer state, the supported route is restoring the backup you made before updating, together with the matching OpenClaw version. That is why the backup step above matters.

## Harden the VPS and the agent

OpenClaw's defaults are conservative: the gateway listens on localhost only, unknown senders get a pairing code, and groups need an allowlist. Most security problems come from loosening those defaults or from giving the agent more power than the job needs. Start with the built in audit:

```bash
openclaw security audit
openclaw security audit --deep
```

It checks who can reach the bot, whether the gateway is exposed, file permissions and risky tool settings, and lists findings by severity. `openclaw security audit --fix` applies only the safe fixes, such as switching open group policies to allowlists and setting `600` on config files and `700` on directories. Run the audit again after every config change.

### Keep the gateway on localhost

The gateway serves the dashboard and its API on port `18789`. On a normal install `gateway.bind` is `loopback` and onboarding generates an auth token. Leave it that way. The dashboard is an admin panel that can change config and approve commands, and the docs are clear that it should not be public.

Reach it through an SSH tunnel from your own computer:

```bash
ssh -N -L 18789:127.0.0.1:18789 openclaw@YOUR_SERVER_IP
```

Then open `http://127.0.0.1:18789/`. If the dashboard asks for the gateway secret, print the token on the server with `openclaw gateway auth-token --show` and paste it into the login screen. To rotate a weak or leaked token, run `openclaw doctor --generate-gateway-token` and restart the gateway.

A reverse proxy is possible, but it is more work than it looks. The gateway needs `gateway.trustedProxies` set to the proxy address, the proxy must overwrite `X-Forwarded-For` rather than append to it, and token or password auth stays mandatory for any bind other than loopback. For a single owner, the SSH tunnel is simpler and safer.

### Firewall

Telegram uses long polling by default and Discord connects outward to Discord's servers, so neither channel needs an inbound port. The only port that should be open is SSH:

```bash
ufw allow OpenSSH
ufw enable
ufw status
```

Never open `18789`. For fail2ban and a fuller UFW setup, see [how to secure a VPS with UFW and fail2ban](https://datapasa.com/wiki/server-management/secure-vps-ufw-fail2ban).

### Run OpenClaw as a non root user

The agent can run shell commands. Under root, a single bad instruction can touch the whole system. The OpenClaw VPS docs recommend using root only for system setup and running the gateway as an ordinary user, whose state then lives in `/home/openclaw/.openclaw/`:

```bash
adduser openclaw
usermod -aG sudo openclaw
loginctl enable-linger openclaw
su - openclaw
openclaw onboard --install-daemon
```

`enable-linger` keeps the user's systemd service running after you log out. Leave the `sudo` group out if the agent account never needs admin rights. If your agent currently runs as root, the simplest move is: make a backup, run `openclaw gateway stop` and `openclaw gateway uninstall` as root, then onboard again as the new user and reconnect your channels.

### Limit what the agent can execute

By default, commands the agent runs on the host are allowed without prompts (exec security `full`, ask `off`). That suits a trusted owner, but you can make it ask first. OpenClaw has built in presets. Stop the gateway, apply one, start it again:

```bash
openclaw gateway stop
openclaw exec-policy preset cautious
openclaw gateway start
```

`cautious` allows only commands on the allowlist and asks for approval for everything else. `deny-all` blocks host commands completely. Telegram can deliver approval prompts to the bot owner in a private chat (see `channels.telegram.execApprovals` in the docs), so you do not need the dashboard open. Check the result with `openclaw exec-policy show`.

Two more layers are worth knowing:

- **Tool profiles.** `tools.profile` controls which tools the agent sees at all. `messaging` leaves out file and shell tools, `coding` includes them, and onboarding sets `full` when nothing is configured.
- **Sandboxing.** With `agents.defaults.sandbox.mode` set to `non-main`, every session except your main one (group chats included) runs its tools in a container. `all` sandboxes everything. The default backend is Docker, so install it first with [our Docker guide](https://datapasa.com/wiki/server-management/install-docker-on-ubuntu). Use `openclaw sandbox explain` to see what actually applies to a session.

### API keys

- Keep provider keys in `~/.openclaw/.env` (the docs recommend it for API keys) or in config SecretRefs, not in workspace files the agent edits.
- Set a monthly spending limit with your model provider. If something goes wrong, the damage stops at the limit.
- Remember that everything under `~/.openclaw` can hold secrets: config, channel credentials, the SQLite databases with pairing approvals and model auth profiles. Never commit it to git.

### Backups

Two things need protecting: the state directory `~/.openclaw` and the agent workspace (by default `~/.openclaw/workspace`, with AGENTS.md, SOUL.md and memory files). `openclaw backup create` covers state, config, credentials, sessions and the workspace in one archive, and handles the live SQLite databases correctly, which a plain file copy does not:

```bash
openclaw backup create --output ~/Backups/openclaw --verify
```

The archive contains credentials, so keep it at `600` and copy it off the server. Restore always goes into a fresh directory with `openclaw backup restore <archive> --target <new-directory>` and never overwrites live data. For server level snapshots on top of that, see [how to back up your VPS](https://datapasa.com/wiki/server-management/back-up-your-vps).

## How much server OpenClaw needs

OpenClaw sends prompts to a hosted model through an API, so the VPS does not run the model and needs no GPU. Memory goes to Node.js, plugins and, above all, a headless browser or sandbox containers if you use them. The official FAQ puts the absolute minimum at 1 GB of RAM and one core, and the docs' 1 GB VPS walkthrough adds 2 GB of swap to stay stable.

| Your setup | DataPasa plan |
|---|---|
| One channel, cloud model, no browser, testing | VPS-1: 1 vCPU, 1 GB, $1.81/mo, add swap |
| Telegram and Discord, cloud model, no browser | VPS-2: 1 vCPU, 2 GB, $3.54/mo |
| Browser automation or Docker sandboxing (needs 4 GB or more) | VPS-3: 2 vCPU, 4 GB, $7.09/mo |
| Several agents, heavy browsing, extra services | VPS-4: 4 vCPU, 8 GB, $12.16/mo |

Browser automation is the line that matters most: a headless Chromium alone can take more than a gigabyte, so plan on 4 GB of RAM or more (VPS-3 and up) as soon as the agent drives a browser. 4 GB is also the comfortable minimum if you want headroom for skills and updates, which is why our [OpenClaw hosting page](https://datapasa.com/en/openclaw-hosting) starts there.

Local models change the picture completely: even small ones need several gigabytes of RAM on top of OpenClaw. See [running Ollama on a CPU VPS](https://datapasa.com/wiki/guides/run-ollama-on-cpu-vps) and [how much RAM a VPS needs](https://datapasa.com/wiki/getting-started/how-much-ram-does-my-vps-need). All DataPasa servers are KVM VMs with NVMe in Falkenstein, Germany, billed by the hour from a prepaid balance, so you can start on a small plan and move up when the agent grows. Plans and details are on the [OpenClaw hosting page](https://datapasa.com/en/openclaw-hosting) and the [pricing page](https://datapasa.com/en/pricing).

> **Acceptable use.** The agent runs on your server under your account. DataPasa does not allow VPN or proxy services or crypto mining without prior approval, and that applies to anything an agent sets up as well.

## Troubleshooting

When something stops working, run the official command ladder in this order. Each step narrows the problem down:

```bash
openclaw status
openclaw gateway status
openclaw logs --follow
openclaw doctor
openclaw channels status --probe
```

A healthy gateway shows `Runtime: running` in `openclaw gateway status`, and `doctor` reports no blocking issues. Common cases:

**Telegram bot is silent and the log shows `getMe returned 401`.** The token is wrong or was revoked. Regenerate it in BotFather and update `botToken` (or `TELEGRAM_BOT_TOKEN`).

**Telegram replies are slow or fail with `fetch failed`.** Some hosts prefer IPv6 for `api.telegram.org`, and broken IPv6 egress causes intermittent errors. Set `channels.telegram.network.dnsResultOrder` to `"ipv4first"` in the config.

**The bot ignores a Telegram group.** The group ID is missing from `channels.telegram.groups`, or `requireMention` is on and nobody mentioned the bot. Check `openclaw logs --follow` for the skip reason.

**Discord bot is online but blind to server messages.** Enable Message Content Intent, check that your server ID is under `channels.discord.guilds` and restart the gateway. If a guild has a `channels` map, only the listed channels work.

**Gateway will not start: `refusing to bind gateway ... without auth`.** Someone changed `gateway.bind` away from loopback without a token or password. Put it back to `loopback` or configure auth.

**`EADDRINUSE` or `another gateway instance is already listening`.** Two gateways compete for port 18789, often a leftover root service next to a new user service. `openclaw gateway status --deep` lists them, so remove the extra one.

**Things broke right after an update.** Run `openclaw update status`, then `openclaw doctor --fix` and `openclaw gateway restart`. If `which openclaw` and `openclaw --version` point to an older binary than the one that last wrote the config, fix PATH so the newer install is used.

**The gateway disappears under load.** Usually the server ran out of memory, often during browser automation. Check with `free -h`, add swap or move to a plan with more RAM.

## Summary

After installation, four habits keep an OpenClaw agent healthy on a VPS: restrict channels to your own account with allowlists, update through `openclaw update` with a verified backup beforehand, keep the gateway on localhost behind an SSH tunnel with the agent running as a non root user, and run `openclaw security audit` after every config change. If you still need a server, a plan with 2 to 4 GB of RAM is a good start, and the [OpenClaw hosting page](https://datapasa.com/en/openclaw-hosting) explains which one fits your agent.
