OxiBot runs autonomous agent loops that can execute shell commands, read/write files, and interact with external APIs. This guide covers how to deploy it safely.
- Reporting Vulnerabilities
- Threat Model
- Workspace Sandbox
- User Allowlists
- API Key Management
- Docker Hardening
- Network Security
- Tool Restrictions
- Logging & Auditing
- Security Checklist
If you discover a security issue, please do NOT open a public GitHub issue.
Instead, email security@diocrafts.com with:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
We will respond within 72 hours and aim to release a patch within 7 days for critical issues.
OxiBot is designed as a personal assistant β typically running on your own machine or a private server. The primary threats are:
| Threat | Vector | Mitigation |
|---|---|---|
| Prompt injection | Malicious user messages trick the agent into unsafe actions | allowedUsers whitelist, workspace sandbox |
| Data exfiltration | Agent reads sensitive files and leaks them via tool output | restrictToWorkspace, filesystem permissions |
| Command injection | Agent constructs dangerous shell commands | Workspace sandbox, Docker isolation |
| API key theft | Keys stored in plaintext config | File permissions, env vars, Docker secrets |
| Unauthorized access | Unknown users message the bot | allowedUsers per channel |
| Dependency supply chain | Compromised crate or npm package | Cargo.lock pinning, minimal dependencies |
The most important security control. When enabled, the agent's file/directory tools are restricted to ~/.oxibot/workspace/.
{
"tools": {
"restrictToWorkspace": true
}
}Or via environment variable:
export OXIBOT_TOOLS__RESTRICT_TO_WORKSPACE=true| Tool | Unrestricted | Sandboxed |
|---|---|---|
| File read/write | Entire filesystem | ~/.oxibot/workspace/ only |
| Directory listing | Entire filesystem | ~/.oxibot/workspace/ only |
| Shell commands | Full system access | CWD forced to workspace |
Important
Always enable restrictToWorkspace in production. The default is false to make development easier, but this gives the agent unrestricted filesystem access.
Each channel supports an allowedUsers array. When set, only listed users can interact with the bot.
{
"channels": {
"telegram": {
"token": "...",
"allowedUsers": ["123456789"]
},
"discord": {
"token": "...",
"allowedUsers": ["987654321"]
},
"whatsapp": {
"bridgeUrl": "ws://localhost:3001",
"allowedUsers": ["+1234567890"]
},
"slack": {
"botToken": "xoxb-...",
"appToken": "xapp-...",
"allowedUsers": ["U01ABCDEF"]
},
"email": {
"allowedUsers": ["trusted@example.com"]
}
}
}Warning
An empty allowedUsers array (or omitting it) means all users are allowed. Always configure allowlists in production.
| Channel | How to find your ID |
|---|---|
| Telegram | Message @userinfobot or @RawDataBot |
| Discord | Settings β Advanced β Developer Mode ON β Right-click yourself β "Copy User ID" |
Your phone number with country code (e.g., +34612345678) |
|
| Slack | Click your profile β "Copy member ID" |
| Your email address |
# Hardcoding keys in shell history
export OXIBOT_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-abc123 # In .bashrcOption 1: Config file with proper permissions
chmod 600 ~/.oxibot/config.jsonOption 2: Environment variables from a secrets manager
# From 1Password
export OXIBOT_PROVIDERS__OPENROUTER__API_KEY=$(op read "op://Private/OxiBot/api-key")Option 3: Docker secrets
# docker-compose.yml
services:
oxibot:
image: oxibot
secrets:
- oxibot_api_key
environment:
OXIBOT_PROVIDERS__OPENROUTER__API_KEY_FILE: /run/secrets/oxibot_api_key
secrets:
oxibot_api_key:
file: ./api_key.txtRotate API keys periodically:
- Generate new key at provider dashboard
- Update
config.jsonor environment variable - Restart OxiBot (
oxibot gateway) - Revoke old key at provider dashboard
The OxiBot Dockerfile already runs as non-root user oxibot. Additional hardening:
docker run -d \
--name oxibot \
--read-only \
--tmpfs /tmp \
--security-opt no-new-privileges:true \
--cap-drop ALL \
--memory 128m \
--cpus 0.5 \
-v ~/.oxibot:/home/oxibot/.oxibot:rw \
-p 127.0.0.1:18790:18790 \
oxibot gateway| Flag | Purpose |
|---|---|
--read-only |
Immutable container filesystem |
--tmpfs /tmp |
Writable temp directory (in RAM) |
--no-new-privileges |
Prevent privilege escalation |
--cap-drop ALL |
Remove all Linux capabilities |
--memory 128m |
Limit memory usage |
--cpus 0.5 |
Limit CPU usage |
-p 127.0.0.1:18790 |
Bind only to localhost |
version: "3.8"
services:
oxibot:
build: .
restart: unless-stopped
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
mem_limit: 128m
cpus: 0.5
tmpfs:
- /tmp
volumes:
- ~/.oxibot:/home/oxibot/.oxibot:rw
ports:
- "127.0.0.1:18790:18790"OxiBot makes outbound HTTPS calls to:
- LLM provider APIs (OpenRouter, Anthropic, OpenAI, etc.)
- Channel APIs (Telegram Bot API, Discord Gateway, etc.)
- Tool URLs (web_get, web_search via Brave)
OxiBot does not expose any HTTP server by default. All channels use outbound polling or WebSocket connections:
| Channel | Connection Type |
|---|---|
| Telegram | Long-polling (outbound) |
| Discord | WebSocket (outbound) |
| WebSocket to local bridge | |
| Slack | Socket Mode (outbound) |
| IMAP polling (outbound) |
The only inbound port is the heartbeat/health endpoint on port 18790 (configurable, optional).
# Allow outbound HTTPS only
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 993 -j ACCEPT # IMAP (if using email)
iptables -A OUTPUT -p tcp --dport 587 -j ACCEPT # SMTP (if using email)
# Block all other outbound
iptables -A OUTPUT -j DROPThe agent has access to these built-in tools:
| Tool | Risk Level | Notes |
|---|---|---|
bash |
π΄ High | Executes arbitrary shell commands |
read_file |
π‘ Medium | Can read sensitive files |
write_file |
π‘ Medium | Can overwrite files |
list_dir |
π’ Low | Directory listing |
web_get |
π‘ Medium | HTTP requests to arbitrary URLs |
web_search |
π’ Low | Search via Brave API |
Mitigations:
- Enable
restrictToWorkspaceto sandbox file/dir tools - Use
allowedUsersto restrict who can trigger tool use - Run in Docker with minimal capabilities
- Monitor agent logs for suspicious activity
Enable verbose logging to track agent activity:
# Full debug logs
RUST_LOG=debug oxibot gateway
# Agent-specific logs
RUST_LOG=oxibot_agent=debug oxibot gateway
# Log to file
RUST_LOG=info oxibot gateway 2>&1 | tee -a /var/log/oxibot.logKey events to monitor:
tool_call: bashβ Shell commands executedtool_call: write_fileβ Files modifiedincoming_messageβ User messages receivedauth_rejectedβ Unauthorized access attempts
Use this checklist before deploying OxiBot in production:
- Set
restrictToWorkspace: true - Configure
allowedUsersfor every channel - Set
chmod 600 ~/.oxibot/config.json - Use environment variables or secrets manager for API keys
- Run as non-root user (Docker image does this by default)
- Run in Docker with hardening flags
- Use
--read-onlycontainer filesystem - Limit container memory and CPU
- Bind health port to localhost only
- Enable verbose logging for auditing
- Set up log rotation
- Use Docker secrets for API keys
- Configure firewall rules (outbound HTTPS only)
- Run in dedicated VM or namespace
- Set up alerting on
auth_rejectedevents - Regular API key rotation schedule
- Periodic dependency audit (
cargo audit)
Security is a shared responsibility. If you find a vulnerability, please report it responsibly.