Server Setup
Server Setup
Section titled “Server Setup”The dbward server manages approval state, audit logs, and coordinates agents. It does not connect to your database.
Configuration reference
Section titled “Configuration reference”Full configuration reference with all options: Configuration
Top-level settings
Section titled “Top-level settings”# Required: directory for server state (SQLite DB, signing keys, agent-token)state_dir = "/data"
trusted_proxies = ["10.0.0.0/8"] # Trust X-Forwarded-For from these CIDRsNote: The server has a 64MB request body size limit.
Authentication
Section titled “Authentication”[auth]mode = "token" # "token" | "oidc" | "both"# break_glass: any user with --emergency flag # Roles allowed to use --emergencyFor OIDC setup, see Authentication.
Retention
Section titled “Retention”[retention]request_ttl_days = 90 # Auto-delete completed requests (default: 90)audit_ttl_days = 365 # Audit log retention (default: 365)result_ttl_days = 30 # Stored results retention (default: 30)approval_ttl_secs = 86400 # Approval expiry — re-approval needed after (default: 24h)[audit]redaction = "literals" # "literals" (mask SQL values) | "none" (default: literals)# IP recorded automatically via trusted_proxies # Record client IP in audit events (default: true)Result storage
Section titled “Result storage”# Local (default) — omit root_dir to use {state_dir}/results[result_storage]backend = "local"root_dir = "/data/results"
# S3[result_storage]backend = "s3"bucket = "my-dbward-results"region = "us-east-1"# endpoint = "http://minio:9000" # For S3-compatible storageS3 configuration options
Section titled “S3 configuration options”| Field | Description | Default |
|---|---|---|
bucket | S3 bucket name | dbward |
region | AWS region | us-east-1 |
endpoint | Custom endpoint (MinIO, LocalStack) | — |
access_key_id | AWS access key (falls back to env/instance role) | — |
secret_access_key | AWS secret key | — |
path_style | Use path-style URLs (required for MinIO) | false |
prefix | Key prefix for all objects (e.g. prod/) | — |
S3 Lifecycle Policy (recommended)
Section titled “S3 Lifecycle Policy (recommended)”Configure an S3 Lifecycle Rule as a safety net for expired results.
dbward tags each stored result with dbward-expires containing the RFC 3339 expiry timestamp.
The background job deletes expired results, but a lifecycle rule provides defense-in-depth:
{ "Rules": [ { "ID": "dbward-result-expiry", "Filter": { "Prefix": "results/" }, "Status": "Enabled", "Expiration": { "Days": 91 } } ]}Set Expiration.Days to retention_days + 1 (default retention is 30 days for Free, configurable via result policies for Team).
Webhooks
Section titled “Webhooks”[[webhooks]]url = "https://hooks.slack.com/services/T.../B.../xxx"events = ["request_created", "request_approved", "request_rejected", "request_completed"]format = "slack"# secret = "whsec_..." # HMAC-SHA256 signature (optional)Workflows
Section titled “Workflows”See Workflows guide for full configuration.
# Production: require admin approval[[workflows]]database = "*"environment = "production"require_reason = true
[[workflows.steps]]type = "approval"[[workflows.steps.approvers]]role = "admin"min = 1
# Development: auto-approve (no steps = no approval needed)[[workflows]]database = "*"environment = "development"Auto-Approve
Section titled “Auto-Approve”# Auto-approve low-risk requests globally[[auto_approve]]database = "*"environment = "*"risk = "low"allow_read_only = trueallow_safe_ddl = true
# Production: never auto-approve[[auto_approve]]database = "*"environment = "production"risk = "none"Execution policies
Section titled “Execution policies”[[execution_policies]]database = "*"environment = "production"max_executions = 1 # One-shot execution (default: 1)execution_window_secs = 3600 # Must execute within 1 hour of approval (default: 86400)retry_on_failure = false # Allow re-execution on failure only (default: false)Result policies
Section titled “Result policies”Result policies are managed via the REST API, not TOML. See Result Policies.
Notification policies
Section titled “Notification policies”Notification policies are managed via the REST API, not TOML. See Notification Policies.
Running with systemd
Section titled “Running with systemd”[Unit]Description=dbward serverAfter=network.target
[Service]Type=simpleUser=dbwardExecStart=/usr/local/bin/dbward-server \ --config /etc/dbward/dbward-server.toml \ --listen 0.0.0.0:3000Restart=alwaysRestartSec=5
[Install]WantedBy=multi-user.targetRunning with Docker
Section titled “Running with Docker”docker run -d \ --name dbward-server \ -p 3000:3000 \ -v dbward-data:/data \ -v ./dbward-server.toml:/etc/dbward/dbward-server.toml:ro \ ghcr.io/dbward-dev/dbward-server:latest \ --config /etc/dbward/dbward-server.toml \ --listen 0.0.0.0:3000Token management
Section titled “Token management”Create tokens for users and agents:
# Initial tokens created automatically on first server start.# Read them from files:cat /data/admin-token # admin tokencat /data/agent-token # agent token
# Additional tokens via CLI (requires admin token):dbward token create --subject alice --role admindbward token create --subject bob --role developerdbward token create --subject prod-agent --role agent-default --subject-type agentFor API-based token management, see REST API Reference.
Health checks
Section titled “Health checks”Two endpoints are available without authentication:
| Endpoint | Purpose | Use for |
|---|---|---|
GET /health | Process liveness — always returns 200 if the server is running | Container liveness probes, external uptime monitors |
GET /ready | Service readiness — returns 503 when degraded or draining | Load balancer target health, rollout gating |
curl http://localhost:3000/health# → {"status":"ok","version":"0.1.5","min_agent_version":"0.1.5"}
curl http://localhost:3000/ready# → {"status":"ok","checks":{"sqlite":"ok","result_store":"ok"}}# → 503 {"status":"degraded",...} when SQLite or result store is unavailableChoosing between them: Use /health for restart decisions and “is it up at all?” checks. Use /ready for load balancer health and traffic routing — it intentionally returns 503 during graceful shutdown and maintenance drains.
For external uptime monitoring (e.g., Route53 Health Check, UptimeRobot), point at /health. This avoids false alerts during planned rolling deploys where /ready temporarily returns 503.
All responses include an X-Dbward-Version header.
Agent status
Section titled “Agent status”The server tracks agent liveness via poll heartbeats. Query the fleet status with:
curl http://localhost:3000/api/agents -H "Authorization: Bearer $TOKEN"# Requires metrics.view permissionEach agent has a status field:
| Status | Meaning |
|---|---|
healthy | Polling and has spare capacity |
saturated | Polling but at max concurrency (in_flight >= max_concurrent) |
offline | No poll received for 60+ seconds |
draining | Graceful shutdown in progress |
Note: An agent in degraded mode (e.g., lost DB connection) still polls with
limit=0and appearshealthyhere. Check application logs or the agent’s readiness probe for degraded state.
This is the best available fleet-level view. Local probe files (/tmp/dbward-agent-alive, /tmp/dbward-agent-ready) are for the container runtime only.
Metrics
Section titled “Metrics”# Requires metrics.view permissioncurl http://localhost:3000/metrics -H "Authorization: Bearer $TOKEN"# → Prometheus text formatIf you use Prometheus/Grafana, scrape /metrics for request queue depth (dbward_requests_current) and general activity. Note that /metrics does not reflect agent offline state — the dbward_agents_active gauge counts configured agents regardless of last_seen. For offline detection, poll GET /api/agents which applies the 60-second heartbeat check.
Backup
Section titled “Backup”The server stores all state in a single SQLite file. Back it up with:
# Simple copy (while server is running — SQLite WAL mode is safe)cp /data/dbward.db /backup/dbward-$(date +%Y%m%d).db
# Or use Litestream for continuous replication to S3# See: https://litestream.ioEnvironment variables
Section titled “Environment variables”All TOML string values support ${ENV_VAR} expansion:
[[webhooks]]url = "${SLACK_WEBHOOK_URL}"secret = "${WEBHOOK_SECRET}"See also
Section titled “See also”- Agent setup — Connect agents to your databases
- Authentication — Configure OIDC or manage tokens
- Workflows — Set up approval rules
- Troubleshooting — Common deployment issues