Deployment
Deploy Ashlr AO for team use with Docker, HTTPS, and multi-user authentication.
Deployment Options
| Method | Best For | HTTPS | Multi-User |
|---|---|---|---|
| Local (pip install) | Solo developer | No | Optional |
| Local (from source) | Development / contributing | No | Optional |
| Docker Compose | Team deployment | Yes (Caddy) | Yes |
| Desktop App | macOS native experience | No | No |
Docker Compose + Caddy HTTPS
The recommended production deployment uses Docker Compose with Caddy as a reverse proxy. Caddy automatically provisions Let's Encrypt HTTPS certificates.
Prerequisites
- Docker and Docker Compose installed
- A domain name pointing to your server's IP address
- Port 80 and 443 open on your firewall
- tmux installed on the host (agents run on the host, not inside containers)
docker-compose.yml
version: "3.8"
services:
ashlr:
build: .
restart: unless-stopped
ports:
- "5111:5111"
environment:
- ASHLR_HOST=0.0.0.0
- ASHLR_PORT=5111
- ASHLR_ALLOWED_ORIGINS=https://ashlr.yourdomain.com
- XAI_API_KEY=${XAI_API_KEY:-}
volumes:
- ashlr-data:/root/.ashlr
- /tmp:/tmp
network_mode: host
caddy:
image: caddy:2-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy-data:/data
- caddy-config:/config
volumes:
ashlr-data:
caddy-data:
caddy-config:
Caddyfile
ashlr.yourdomain.com {
reverse_proxy localhost:5111
}
Replace ashlr.yourdomain.com with your actual domain. Caddy handles TLS certificate provisioning and renewal automatically.
Dockerfile
FROM python:3.12-slim
RUN apt-get update && apt-get install -y tmux && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY . .
RUN pip install --no-cache-dir -e .
EXPOSE 5111
CMD ["ashlr"]
Launch
# Set your domain
export ASHLR_DOMAIN=ashlr.yourdomain.com
# Optional: enable intelligence layer
export XAI_API_KEY=your-xai-api-key
# Start services
docker compose up -d
# Check logs
docker compose logs -f ashlr
Your Ashlr instance will be available at https://ashlr.yourdomain.com with auto-provisioned HTTPS.
Production Environment Variables
| Variable | Required | Description |
|---|---|---|
ASHLR_HOST | Yes (Docker) | Set to 0.0.0.0 to accept connections from all interfaces. |
ASHLR_PORT | No | HTTP port (default: 5111). |
ASHLR_ALLOWED_ORIGINS | Yes | Set to your domain (e.g., https://ashlr.yourdomain.com). Do NOT use * in production. |
XAI_API_KEY | No | Enables intelligence features (summaries, NLU, fleet analysis). |
Security: Always set ASHLR_ALLOWED_ORIGINS to your specific domain in production. The default * allows any origin to make requests to your Ashlr instance.
Multi-User Authentication
Ashlr AO supports session-based multi-user authentication with bcrypt password hashing. This is a Pro tier feature.
How Auth Works
- The first user to register becomes the admin and automatically creates the organization.
- The admin can invite additional users via
POST /api/auth/invite, which generates a temporary password. - Invited users log in with their email and temporary password, then change their password.
- All organization members can view all agents (the whole point of a command center), but only the agent owner or admin can control (send, pause, kill) an agent.
Setting Up Auth
Auth activates automatically when the first user registers:
# 1. Register the admin user
curl -X POST https://ashlr.yourdomain.com/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "admin@yourcompany.com",
"password": "strong-password-here",
"name": "Admin"
}'
# 2. Login to get a session cookie
curl -X POST https://ashlr.yourdomain.com/api/auth/login \
-H "Content-Type: application/json" \
-c cookies.txt \
-d '{"email": "admin@yourcompany.com", "password": "strong-password-here"}'
# 3. Invite a team member (admin only)
curl -X POST https://ashlr.yourdomain.com/api/auth/invite \
-H "Content-Type: application/json" \
-b cookies.txt \
-d '{"email": "dev@yourcompany.com", "name": "Developer"}'
# Returns: {"email": "dev@yourcompany.com", "temp_password": "..."}
Session Security
Authentication sessions use secure cookies:
- HttpOnly — Not accessible via JavaScript (prevents XSS token theft)
- SameSite=Strict — Only sent on same-origin requests (prevents CSRF)
- Secure — Only sent over HTTPS (when behind Caddy or another TLS proxy)
For API/CLI access, Ashlr also supports Authorization: Bearer <token> headers as a fallback.
Agent Ownership
When auth is enabled, every spawned agent is tagged with the owner's email. Ownership rules:
- All org members can view all agents and their output
- Only the owner can send messages, pause, resume, or kill their agent
- Admins can control any agent
- The
PUT /api/configendpoint requires admin role
License Activation
For team deployments, you will need a Pro license to unlock multi-user auth, workflows, fleet templates, and the intelligence layer.
# Activate a license key (admin only)
curl -X POST https://ashlr.yourdomain.com/api/license/activate \
-H "Content-Type: application/json" \
-b cookies.txt \
-d '{"key": "eyJhbGciOiJFZERTQSIs..."}'
# Check license status
curl https://ashlr.yourdomain.com/api/license/status
License keys are Ed25519-signed JWTs that are validated offline. There is no phone-home or license server.
Data Persistence
Ashlr stores all persistent data in two files under ~/.ashlr/:
| File | Contents |
|---|---|
~/.ashlr/ashlr.yaml | Configuration (server, agents, backends, auto-pilot, display, licensing) |
~/.ashlr/ashlr.db | SQLite database (agent history, projects, workflows, users, organizations, fleet templates) |
In Docker, mount /root/.ashlr as a named volume to persist data across container restarts:
volumes:
- ashlr-data:/root/.ashlr
Security Hardening Checklist
Before exposing Ashlr AO to the network, verify these security measures:
- Set ASHLR_ALLOWED_ORIGINS to your specific domain
- Enable auth by registering an admin user
- Use HTTPS via Caddy or another TLS proxy
- Activate a Pro license to enforce multi-user auth and agent ownership
- Review auto-pilot settings — disable auto-approve in shared environments unless you trust all patterns
- Restrict working directories — Ashlr enforces
~/and/tmprestrictions, but verify no sensitive symlinks exist - Set memory limits — Configure
agents.memory_limit_mbto prevent runaway agents
Built-in Security Features
Ashlr AO includes several security measures by default:
- CSP headers — Content Security Policy restricts script sources
- Rate limiting — Request rate limiting via middleware
- Request size limits — Maximum request body size enforced
- Secret redaction — API keys and passwords are redacted in error responses and logs
- Path traversal protection — Working directory paths are validated with
os.path.realpathand restricted to allowed prefixes - Message size limits — Agent messages capped at 50,000 characters
- Compression — Response compression via middleware
Monitoring
Monitor your Ashlr instance health via these endpoints:
GET /api/health— Returns{"status": "ok"}when the server is runningGET /api/system— CPU, memory, active agent count, uptimeGET /api/costs— Estimated cost tracking for all agents
The WebSocket connection at /ws broadcasts system metrics every 2 seconds, making it suitable for real-time monitoring dashboards.
Backup & Restore
To backup your Ashlr instance, copy the ~/.ashlr/ directory:
# Backup
cp -r ~/.ashlr ~/.ashlr-backup-$(date +%Y%m%d)
# Restore
cp -r ~/.ashlr-backup-20260308 ~/.ashlr
The SQLite database supports online backup. For Docker deployments, you can also use docker cp to extract the volume data.