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:
- Binary —
/usr/bin/oxicrab(Linux) or/usr/local/bin/oxicrab(macOS) - Service file — systemd unit (DEB/RPM) or launchd plist (DMG)
- Example config —
config.example.tomlwith all fields and placeholder values - Post-install scripts (DEB/RPM) — create
oxicrabsystem user, set up/etc/oxicraband/var/lib/oxicrab, enable the systemd service - Pre-remove scripts (DEB/RPM) — stop and disable the service on uninstall
/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
- Rust stable — version pinned in
rust-toolchain.toml. Install via rustup. - cmake — required by native dependencies.
- ffmpeg (optional) — only needed for local voice transcription.
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
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
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.
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)
/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/
/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
[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:
- StartLimitBurst=5 — prevents crash loops from hammering restarts (max 5 restarts in 5 minutes)
- ProtectSystem=strict — mounts
/read-only except explicitly allowed paths - ReadWritePaths=%h/.oxicrab —
%hexpands to the user's home directory - MemoryDenyWriteExecute — prevents dynamic code generation exploits
- LimitNOFILE=65536 — enough file descriptors for many concurrent connections
- SyslogIdentifier=oxicrab — clean log filtering with
journalctl -t oxicrab
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)
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/
/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
<?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:
- KeepAlive / SuccessfulExit=false — restarts only on crash (exit code != 0), not on clean shutdown
- ThrottleInterval=5 — minimum 5 seconds between restart attempts (crash loop protection)
- NumberOfFiles=65536 — raises the file descriptor limit for many concurrent connections
- ProcessType=Background — tells macOS this is a low-priority background service (won't contend with foreground apps)
- Unified log path — stdout and stderr both go to
/usr/local/var/log/oxicrab.log
echo '/usr/local/var/log/oxicrab.log 644 7 1000 * J' | sudo tee -a /etc/newsyslog.confThis 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:
- OXICRAB_HOME — host directory mounted as the data volume (default:
~/.oxicrab). Set this to use a different path, e.g.OXICRAB_HOME=/opt/oxicrab/data docker compose up -d. - OXICRAB_PORT — host port mapped to the gateway (default:
18790). The container always listens on port 18790 internally.
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:
[gateway]
host = "100.x.x.x"
apiKey = "your-secret-api-key"
With this configuration:
- The gateway only listens on the Tailscale interface — not reachable from the public internet.
- The
apiKeyadds a second layer: requests must includeAuthorization: Bearer your-secret-api-keyorX-API-Key: your-secret-api-key. - SSH access should also be restricted to the tailnet by configuring Tailscale SSH or firewall rules that only allow Tailscale IPs.
/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:
- Both VPSes must be on the same Tailscale network.
- SSH key authentication must be set up between the monitor and the primary (or use Tailscale SSH).
- Replace
100.x.x.xwith the primary VPS's Tailscale IP and/path/to/oxicrabwith the actual clone directory.