Skip to main content
How-To Guides Last updated: 5 March 2026

Security hardening

Untether gives remote access to coding agents on your server, so locking down who can interact with the bot and what files they can access is important. This...

Untether gives remote access to coding agents on your server, so locking down who can interact with the bot and what files they can access is important. This guide covers the key security controls — all manageable from Telegram on any device.

Restrict access

By default, anyone who can message your bot can start agent runs. To restrict access to specific Telegram users, set allowed_user_ids:

=== “untether config”

```sh
untether config set transports.telegram.allowed_user_ids "[12345, 67890]"
```

=== “toml”

```toml title="~/.untether/untether.toml"
[transports.telegram]
allowed_user_ids = [12345, 67890]
```

When this list is non-empty, only the listed user IDs can interact with the bot. Messages from everyone else are silently ignored.

To find your Telegram user ID:

untether chat-id

Send a message in the target chat and Untether prints the chat ID and sender ID.

Empty list means open access If allowed_user_ids is empty (the default), anyone who discovers your bot’s username can start runs. Always set this in production.

Protect your bot token

Your Telegram bot token grants full control over the bot. Keep it safe:

  • Never commit it to git — add your config path to .gitignore
  • Never share it publicly — anyone with the token can impersonate your bot
  • Restrict file permissions on your config file:
chmod 600 ~/.untether/untether.toml

If you store your config in a non-standard location, set the UNTETHER_CONFIG_PATH environment variable:

export UNTETHER_CONFIG_PATH=/path/to/untether.toml

File transfer deny globs

File transfer includes a deny list that blocks access to sensitive paths. The defaults are:

[transports.telegram.files]
deny_globs = [".git/**", ".env", ".envrc", "**/*.pem", "**/.ssh/**"]

Add more patterns as needed:

=== “toml”

```toml title="~/.untether/untether.toml"
[transports.telegram.files]
deny_globs = [
    ".git/**",
    ".env",
    ".envrc",
    "**/*.pem",
    "**/.ssh/**",
    "**/*.key",
    "**/secrets/**",
    "**/.aws/**",
]
```

Defence in depth Deny globs protect against accidental file exfiltration via /file get. They do not prevent the coding agent itself from reading files — the agent runs with full filesystem access in the project directory.

Secure webhook endpoints

If you use webhooks to trigger runs from external services, always configure authentication:

=== “toml”

```toml title="~/.untether/untether.toml"
[[triggers.webhooks]]
id = "github-push"
path = "/hooks/github"
auth = "hmac-sha256"
secret = "whsec_your_github_secret"
```

Available authentication modes:

ModeUse case
hmac-sha256GitHub webhooks (recommended)
hmac-sha1Legacy GitHub webhooks
bearerSimple shared secret
noneLocal testing only

*Never use `auth = * Without authentication, anyone who can reach the webhook endpoint can trigger arbitrary agent runs on your server.

Bind webhook server to localhost

The webhook server should only listen on localhost. Put it behind a reverse proxy (nginx, Caddy) with TLS for external access:

=== “toml”

```toml title="~/.untether/untether.toml"
[triggers.server]
host = "127.0.0.1"
port = 9876
```

The server includes rate limiting (token-bucket, per-webhook and global) and timing-safe secret comparison by default.

Run untether doctor

After any configuration change, run the built-in preflight check:

untether doctor

This validates:

  • Telegram bot token is valid
  • Chat ID is reachable
  • Topics setup (if enabled)
  • File transfer permissions and deny globs
  • Voice transcription configuration
  • Engine availability

Fix any issues reported before putting the instance into production.

Was this helpful?

Related Articles