Options

Verifying Downloads

All release artifacts (binaries, packages, checksums) and Docker images are signed with Sigstore cosign using keyless OIDC signing. Each artifact has a .bundle file containing the signature, certificate, and Rekor transparency log entry. No GPG keys to manage — signing identity is cryptographically tied to the GitHub Actions release workflow.

Verify a release artifact

# Install cosign: https://docs.sigstore.dev/cosign/system_config/installation/
# Download the artifact and its .bundle file, then verify:
cosign verify-blob \
  --bundle oxicrab-0.11.7-linux-x86_64.tar.gz.bundle \
  --certificate-identity-regexp "https://github.com/oxicrab/oxicrab/.github/workflows/release.yml@refs/tags/v.*" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  oxicrab-0.11.7-linux-x86_64.tar.gz

Verify the Docker image

cosign verify \
  --certificate-identity-regexp "https://github.com/oxicrab/oxicrab/.github/workflows/release.yml@refs/tags/v.*" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  ghcr.io/oxicrab/oxicrab:latest

Verify checksums, then binary

For an extra layer of assurance, verify the signed checksums file first, then check your binary against it:

# 1. Verify the checksums file's signature
cosign verify-blob \
  --bundle checksums-sha256.txt.bundle \
  --certificate-identity-regexp "https://github.com/oxicrab/oxicrab/.github/workflows/release.yml@refs/tags/v.*" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  checksums-sha256.txt

# 2. Verify your binary against the signed checksums
grep "oxicrab-0.11.7-linux-x86_64.tar.gz$" checksums-sha256.txt | sha256sum --check --strict

Native Packages (DEB / RPM / DMG)

Pre-built packages are published with every GitHub Release. Linux packages include a systemd service file, example config, and post-install scripts that create a dedicated oxicrab system user.

Debian / Ubuntu (.deb)

Available for x86_64 (amd64) and ARM64 (arm64).

# Download the .deb for your architecture
curl -LO https://github.com/oxicrab/oxicrab/releases/latest/download/oxicrab_VERSION_amd64.deb

# Install (creates oxicrab user, installs systemd service, copies example config)
sudo dpkg -i oxicrab_*_amd64.deb

# Edit config with your API keys
sudo nano /etc/oxicrab/config.toml

# Start the service
sudo systemctl start oxicrab

Fedora / RHEL (.rpm)

Available for x86_64 and aarch64.

# Download the .rpm for your architecture
curl -LO https://github.com/oxicrab/oxicrab/releases/latest/download/oxicrab-VERSION.x86_64.rpm

# Install (creates oxicrab user, installs systemd service, copies example config)
sudo rpm -i oxicrab-*.x86_64.rpm

# Edit config with your API keys
sudo nano /etc/oxicrab/config.toml

# Start the service
sudo systemctl start oxicrab

macOS (.dmg)

Available for Apple Silicon (ARM64). Includes the launchd plist and example config.

# Download the DMG
curl -LO https://github.com/oxicrab/oxicrab/releases/latest/download/oxicrab-VERSION-arm64.dmg

# Mount and install
hdiutil attach oxicrab-*-arm64.dmg
sudo cp "/Volumes/Oxicrab "*/oxicrab /usr/local/bin/

# Install launchd plist
cp "/Volumes/Oxicrab "*/com.oxicrab.gateway.plist ~/Library/LaunchAgents/

# Copy example config
mkdir -p ~/.oxicrab
cp "/Volumes/Oxicrab "*/config.example.toml ~/.oxicrab/config.toml

hdiutil detach "/Volumes/Oxicrab "*

# Edit config with your API keys, then load the service
nano ~/.oxicrab/config.toml
launchctl load ~/Library/LaunchAgents/com.oxicrab.gateway.plist

What the packages include

All native packages ship more than just the binary:

Note: The DEB/RPM post-install enables the service but does not start it. Edit /etc/oxicrab/config.toml with your API keys first, then run systemctl start oxicrab.

Building from Source

If you prefer to compile oxicrab yourself, or need to customise feature flags.

Prerequisites

Build

# Clone
git clone https://github.com/oxicrab/oxicrab.git
cd oxicrab

# All channels (default)
cargo build --release

# Specific channels only (smaller binary)
cargo build --release --no-default-features \
  --features channel-telegram,channel-slack

# Agent CLI only (no channels)
cargo build --release --no-default-features

Install

# Linux
sudo cp target/release/oxicrab /usr/local/bin/

# macOS
cp target/release/oxicrab /usr/local/bin/

Then run oxicrab onboard to create your config, or see the systemd / launchd sections below to deploy as a service.

Docker

The included Dockerfile uses a multi-stage build: Rust stable for compilation, Debian slim for runtime.

Build the image

# All channels (default)
docker build -t oxicrab .

# Specific channels only (smaller image)
docker build -t oxicrab --build-arg FEATURES="channel-telegram,channel-slack" .

Run

# Mount your config directory
docker run -d \
  --name oxicrab \
  --restart unless-stopped \
  -v ~/.oxicrab:/home/oxicrab/.oxicrab \
  -p 18790:18790 \
  oxicrab

The -p 18790:18790 port mapping is needed for the gateway HTTP API (chat, health, webhooks, A2A). Other channels use outbound connections only.

CLI mode

For the full command list and flags, see CLI Reference.

# Single message
docker run --rm \
  -v ~/.oxicrab:/home/oxicrab/.oxicrab \
  oxicrab agent -m "What's the weather?"

# Interactive
docker run --rm -it \
  -v ~/.oxicrab:/home/oxicrab/.oxicrab \
  oxicrab agent

View logs

docker logs -f oxicrab

# Debug logging
docker run -d \
  --name oxicrab \
  -e RUST_LOG=debug \
  -v ~/.oxicrab:/home/oxicrab/.oxicrab \
  oxicrab
WhatsApp: The first run displays a QR code in the terminal. Use docker run -it (interactive) for the initial link, then switch to -d (detached) for subsequent runs. The session is persisted in the mounted volume.

Authentication

Google OAuth and other interactive auth commands need to run inside the container. Use --headless since there is no browser in the container — it prints a URL to open on your host machine.

# Google OAuth (while the container is running)
docker exec -it oxicrab oxicrab auth google --headless

Credentials are saved to the mounted volume and persist across container restarts. If you add new OAuth scopes (e.g. Google Tasks), re-run the auth command to pick them up.

Docker Compose

docker-compose.yml
services:
  oxicrab:
    image: ghcr.io/oxicrab/oxicrab:${OXICRAB_TAG:-latest}
    restart: unless-stopped
    volumes:
      - ${OXICRAB_HOME:-~/.oxicrab}:/home/oxicrab/.oxicrab
    ports:
      - "${OXICRAB_PORT:-18790}:18790"
    environment:
      - OXICRAB_PORT=18790
    healthcheck:
      test: ["CMD", "/usr/local/bin/healthcheck.sh"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s

OXICRAB_TAG selects the image tag. Defaults to latest (all channels). A slack-only tag is also published — it includes only the Slack channel and omits Whisper, producing a smaller image.

Docker healthcheck: The container includes a healthcheck.sh script that calls /api/health. Docker marks the container as unhealthy after 3 consecutive failures (checked every 30s). Use docker compose ps to see health status.
# Start
docker compose up -d

# Logs
docker compose logs -f

# Pull latest image and restart
docker compose pull && docker compose up -d

# Run auth commands (e.g. Google OAuth)
docker exec -it oxicrab oxicrab auth google --headless

systemd (Linux)

Installed via DEB/RPM? The package already installed a system-wide service (/lib/systemd/system/oxicrab.service), created the oxicrab user, and set up /etc/oxicrab. Just edit your config and run systemctl start oxicrab. The manual steps below are for source builds only.

A user-level service file ships with the repo at deploy/oxicrab.service — no root required.

1. Build and install the binary

cargo build --release
sudo cp target/release/oxicrab /usr/local/bin/oxicrab

2. Install the user service

mkdir -p ~/.config/systemd/user
cp deploy/oxicrab.service ~/.config/systemd/user/
Binary path: The shipped service file expects /usr/local/bin/oxicrab. If your binary is elsewhere, edit the ExecStart line before installing.

3. Enable and start

systemctl --user daemon-reload
systemctl --user enable oxicrab
systemctl --user start oxicrab

# Enable lingering so the service runs without an active login session
loginctl enable-linger $USER

4. Manage

# Check status
systemctl --user status oxicrab

# View logs (syslog identifier: oxicrab)
journalctl --user -u oxicrab -f

# Restart after config changes
systemctl --user restart oxicrab

# Stop
systemctl --user stop oxicrab

What the service file does

deploy/oxicrab.service
[Unit]
Description=oxicrab AI assistant gateway
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=300
StartLimitBurst=5

[Service]
Type=simple
ExecStart=/usr/local/bin/oxicrab gateway
Restart=on-failure
RestartSec=5

Environment=RUST_LOG=info
Environment=RUST_BACKTRACE=1

# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=oxicrab

# Hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=%h/.oxicrab
PrivateTmp=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictNamespaces=true
RestrictSUIDSGID=true
MemoryDenyWriteExecute=true
LockPersonality=true

# Resource limits
LimitNOFILE=65536
TimeoutStopSec=30

[Install]
WantedBy=default.target

Key hardening features:

System-wide service (alternative)

To run as a dedicated system user instead:

# Create service user
sudo useradd -r -m -s /usr/sbin/nologin oxicrab
sudo mkdir -p /home/oxicrab/.oxicrab
sudo cp ~/.oxicrab/config.toml /home/oxicrab/.oxicrab/config.toml
sudo chown -R oxicrab:oxicrab /home/oxicrab/.oxicrab

# Install as system service
sudo cp deploy/oxicrab.service /etc/systemd/system/
# Edit to add User=oxicrab and Group=oxicrab under [Service]
# Change WantedBy=default.target to WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable oxicrab
sudo systemctl start oxicrab

launchd (macOS)

Installed via DMG? The DMG includes com.oxicrab.gateway.plist and config.example.toml. Copy them into place as shown in the Native Packages section above.

A ready-to-use plist ships with the repo at deploy/com.oxicrab.gateway.plist. It runs as a launch agent (per-user, starts on login).

1. Build and install the binary

cargo build --release
cp target/release/oxicrab /usr/local/bin/oxicrab

2. Create the log directory

sudo mkdir -p /usr/local/var/log

3. Install the plist

cp deploy/com.oxicrab.gateway.plist ~/Library/LaunchAgents/
Binary path: The shipped plist expects /usr/local/bin/oxicrab. If your binary is elsewhere, edit the ProgramArguments before installing.

4. Load and start

launchctl load ~/Library/LaunchAgents/com.oxicrab.gateway.plist

5. Manage

# Check status
launchctl list | grep oxicrab

# View logs
tail -f /usr/local/var/log/oxicrab.log

# Restart after config changes
launchctl unload ~/Library/LaunchAgents/com.oxicrab.gateway.plist
launchctl load ~/Library/LaunchAgents/com.oxicrab.gateway.plist

# Stop permanently
launchctl unload ~/Library/LaunchAgents/com.oxicrab.gateway.plist

What the plist does

deploy/com.oxicrab.gateway.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.oxicrab.gateway</string>

  <key>ProgramArguments</key>
  <array>
    <string>/usr/local/bin/oxicrab</string>
    <string>gateway</string>
  </array>

  <key>EnvironmentVariables</key>
  <dict>
    <key>RUST_LOG</key>
    <string>info</string>
    <key>RUST_BACKTRACE</key>
    <string>1</string>
  </dict>

  <key>RunAtLoad</key>
  <true/>

  <key>KeepAlive</key>
  <dict>
    <key>SuccessfulExit</key>
    <false/>
  </dict>

  <key>ThrottleInterval</key>
  <integer>5</integer>

  <key>StandardOutPath</key>
  <string>/usr/local/var/log/oxicrab.log</string>

  <key>StandardErrorPath</key>
  <string>/usr/local/var/log/oxicrab.log</string>

  <key>SoftResourceLimits</key>
  <dict>
    <key>NumberOfFiles</key>
    <integer>65536</integer>
  </dict>

  <key>HardResourceLimits</key>
  <dict>
    <key>NumberOfFiles</key>
    <integer>65536</integer>
  </dict>

  <key>ProcessType</key>
  <string>Background</string>
</dict>
</plist>

Key features:

Log rotation: macOS doesn't rotate launch agent logs automatically. Add a newsyslog entry or use a cron job:
echo '/usr/local/var/log/oxicrab.log 644 7 1000 * J' | sudo tee -a /etc/newsyslog.conf
This keeps 7 rotated copies, rotating when the file exceeds 1 MB.

VPS Deployment

Deploy oxicrab on a cloud VPS (Hetzner, DigitalOcean, Vultr, etc.) using Docker Compose. This section covers the initial setup, securing with Tailscale, and monitoring from a second VPS.

VPS Quick Start

Five commands to go from a fresh VPS to a running oxicrab instance:

ssh root@your-vps
curl -fsSL https://get.docker.com | sh
mkdir -p ~/.oxicrab
curl -LO https://raw.githubusercontent.com/oxicrab/oxicrab/main/config.example.toml
cp config.example.toml ~/.oxicrab/config.toml
curl -LO https://raw.githubusercontent.com/oxicrab/oxicrab/main/docker-compose.yml
docker compose up -d

Edit ~/.oxicrab/config.toml with your API keys before starting. The ~/.oxicrab directory is bind-mounted into the container at /home/oxicrab/.oxicrab, so config, memory, and workspace files persist across restarts.

docker-compose Configuration

The repository includes a docker-compose.yml at the project root. Key configuration is controlled through environment variables:

The service uses restart: unless-stopped, so it survives reboots and only stays down if you explicitly stop it. The health check calls /api/health every 30 seconds and marks the container unhealthy after 3 consecutive failures.

# Custom data directory and port
OXICRAB_HOME=/opt/oxicrab/data OXICRAB_PORT=9090 docker compose up -d

# View health status
docker compose ps

# Pull latest image and restart
docker compose pull && docker compose up -d

Securing with Tailscale

Bind the gateway to your Tailscale IP so it is only reachable over your private tailnet. This removes the need for public-facing ports or firewall rules.

# Install Tailscale on the VPS
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up

Once Tailscale is running, note your Tailscale IP (e.g. 100.x.x.x) and configure the gateway to bind to it. Edit ./data/config.toml:

config.toml (gateway section)
[gateway]
host = "100.x.x.x"
apiKey = "your-secret-api-key"

With this configuration:

Note: The /api/health endpoint is always public (no auth required) so that monitoring tools can check it without credentials. Webhook endpoints (/api/webhook/{name}) use their own HMAC authentication.

Dual-VPS Health Monitoring

The scripts/healthcheck.sh script checks the /api/health endpoint and exits non-zero on failure. It is used by the Docker HEALTHCHECK directive, but can also be called remotely from a second VPS for cross-node monitoring.

On a second VPS (connected to the same Tailscale network), set up a cron watchdog that checks the primary and restarts it if unhealthy:

*/5 * * * * curl -sf http://100.x.x.x:18790/api/health || ssh root@100.x.x.x 'cd /path/to/oxicrab && docker compose restart'

This cron job runs every 5 minutes. If the health endpoint does not return a success response, it SSHs into the primary VPS (over Tailscale) and restarts the container. For this to work:

Warning: This is a basic watchdog. For production deployments, consider a proper monitoring stack (Prometheus, Uptime Kuma, etc.) with alerting so you are notified of failures, not just auto-restarted.