{"slug": "show-hn-dbward-approval-workflows-for-production-databases", "title": "Show HN: Dbward – Approval workflows for production databases", "summary": "Dbward, an open-core project, has launched approval workflows and audit logs for production databases, featuring multi-step approvals, tamper-evident audit trails, and AI agent guardrails. The core components are Apache-2.0 licensed, with some features under a commercial license. The tool includes standalone Rust binaries with embedded SQLite, MCP-native integration, Slack approvals, and a break-glass emergency bypass, aiming to prevent accidental or unauthorized database operations.", "body_md": "Open-core project— core components are[Apache-2.0]. Some features and pre-built binaries include code under the[dbward Commercial License]. See[License]for details.\n\n**Approval workflows and audit logs for your production database.**\n\nStop accidents before they hit production. Add approval gates, audit trails, and AI agent guardrails to every database operation — with standalone binaries and embedded SQLite. No external control-plane DB required.\n\n- 🔐\n**Approval workflows**— multi-step, conditional auto-approve, TOML policy engine - 📋\n**Audit logs**— tamper-evident hash chain, 24 event types, SQL redaction - 🤖\n**MCP-native**— 12 tools, 6 prompts, elicitation support. AI agents operate safely. Remote HTTP transport for team setups - ⚡\n**Standalone binaries**— CLI, server, and agent ship as self-contained Rust binaries with embedded SQLite. No external control-plane DB - 🔒\n**Agent isolation**— DB credentials never leave the agent. CLI/AI never touch your database directly - 🛡️\n**SQL safety review**— risk classification, DDL detection,`DROP`\n\nblocking. Auto-approve safe queries, require approval for risky ones - 🔍\n**Preflight**— analyze SQL before submitting. Get risk level, EXPLAIN plan, review findings, and fix hints without creating a request. AI agents converge on safe SQL before asking for approval - 🧠\n**Auto schema context**— the agent collects table structures, columns, FKs, and row counts automatically. AI tools access schema via MCP resources — no manual documentation needed - 💬\n**Slack approvals**— approve/reject from Slack with one click.`dbward slack init`\n\ngenerates the app manifest - 🚨\n**Break-glass**— emergency bypass with mandatory reason and audit. Operator/admin only, not available via MCP - 🆓\n**Core features free**— approval, audit, MCP, Slack, break-glass all included under[Apache-2.0](/dbward-dev/dbward/blob/main/LICENSE-APACHE). Team features (OIDC, group auth) require a[commercial license](/dbward-dev/dbward/blob/main/LICENSE-COMMERCIAL)\n\n```\n┌─────────────────────────────────────────────────────────┐\n│              dbward client (CLI / MCP)                    │\n│  No DB credentials — sends requests, receives results    │\n└──────────┬───────────────────────────────────────────────┘\n           │ REST API\n           ▼\n┌─────────────────────────────────────────────────────────┐\n│                    dbward server                          │\n│  Approval engine │ Policy engine │ Audit log (hash chain) │\n│  Ed25519 token signing │ OIDC/API auth │ Webhooks        │\n│  In-memory result relay │ NO database credentials        │\n└─────────────────────────────────────────────────────────┘\n           ▲ Agent polls (outbound HTTPS)\n           │\n┌──────────┴───────────────────────────────────────────────┐\n│                    dbward agent                           │\n│  DB credentials here only │ Executes approved operations  │\n│  Token verification (Ed25519) │ Multiple DB support       │\n└──────────┬───────────────────────────────────────────────┘\n           │\n           ▼\n      Target Database (PostgreSQL / MySQL)\n```\n\n**Key principle**: The client requests. The server decides. The agent executes. No component has more access than it needs.\n\n**Try the approval flow in 2 minutes (Docker):**\n\n```\ngit clone https://github.com/dbward-dev/dbward.git && cd dbward/examples/quickstart\ndocker compose up -d\ndocker compose run --rm alice execute \"SELECT version()\" -e development\n```\n\nThen submit → approve → execute → audit. Full walkthrough: [Quickstart with Docker](https://dbward.dev/docs/quickstart-docker/)\n\n**Quick smoke test (local install):**\n\n```\ncurl -fsSL https://dbward.dev/install.sh | sh\ndbward dev --database-url \"postgres://user:pass@localhost:5432/mydb\"\n# In another terminal:\ndbward --config ~/.dbward/dev/client.toml --database app execute \"SELECT 1\"\n```\n\nDev mode auto-approves everything for fast iteration. See [Connect Your Database](https://dbward.dev/docs/quickstart-local/) for details.\n\nFull reference:\n\n[docs/reference/mcp.md]\n\n```\n{\n  \"mcpServers\": {\n    \"dbward\": {\n      \"command\": \"dbward\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\n**MCP Tools (12):**\n\n| Tool | Description |\n|---|---|\n`dbward_execute_query` |\nExecute SQL (SELECT/DML) via approval workflow |\n`dbward_migrate_status` |\nShow migration status |\n`dbward_migrate_up` |\nApply pending migrations |\n`dbward_migrate_down` |\nRollback migrations |\n`dbward_migrate_create` |\nCreate migration file (local) |\n`dbward_wait_request` |\nWait for request completion and return result |\n`dbward_list_pending` |\nList pending approval requests |\n`dbward_who_can_approve` |\nShow who can approve a request |\n`dbward_find_similar_requests` |\nFind similar past requests |\n`dbward_preflight_sql` |\nAnalyze SQL safety without creating a request |\n`dbward_explain_policy_failure` |\nExplain why approval is needed |\n`dbward_inspect_schema` |\nInspect database schema (list tables or describe columns) |\n\n**MCP Prompts (6):** `review_migration`\n\n, `explain_request`\n\n, `draft_migration`\n\n, `draft_rollback`\n\n, `summarize_audit_trail`\n\n, `prepare_approval_comment`\n\n**Elicitation:** On production operations, dbward asks the AI client for a reason before proceeding (if the client supports MCP elicitation).\n\n**Remote MCP (HTTP):** For team setups, the server exposes MCP over HTTP — no local binary needed (9 tools, excludes local-only migration tools):\n\n```\n{\n  \"mcpServers\": {\n    \"dbward\": {\n      \"type\": \"streamable-http\",\n      \"url\": \"https://your-server.example.com/mcp\"\n    }\n  }\n}\n```\n\ndbward uses **on-demand execution**: the agent does not execute on approval. Instead, the client explicitly resumes the request when ready to receive the result.\n\n```\n1. Client creates request → server evaluates policy → pending / auto_approved\n2. (If pending) Human approves via CLI\n3. Client resumes (`dbward request resume <id>`) → server marks as \"dispatched\"\n4. Agent polls, claims, executes on DB → returns result to server\n5. Server relays result in-memory to waiting client (long poll)\n6. Client displays result (server persists to local FS or S3)\n```\n\nResults are persisted on the server by default (local filesystem or S3, configurable via `[result_storage]`\n\n). The in-memory relay has a 10-minute TTL for streaming delivery. Use `--no-result-store`\n\nto skip persistence for a single request.\n\nDefined in `server.toml`\n\nand hot-reloaded via SIGHUP. See [Configuration Reference](/dbward-dev/dbward/blob/main/docs/reference/configuration.md).\n\nControl whether operations require approval:\n\n```\n[[workflows]]\ndatabase = \"*\"\nenvironment = \"production\"\noperations = [\"execute_select\", \"migrate_up\", \"migrate_down\"]\n\n[[workflows.steps]]\ntype = \"approval\"\n\n[[workflows.steps.approvers]]\nrole = \"admin\"\nmin = 1\n\n# Auto-approve low-risk queries in staging; risky ones still need approval\n[[workflows]]\ndatabase = \"*\"\nenvironment = \"staging\"\n\n[workflows.auto_approve]\nmode = \"risk_based\"\nrisk = \"low\"\n\n[[workflows.steps]]\ntype = \"approval\"\n\n[[workflows.steps.approvers]]\nrole = \"admin\"\nmin = 1\n```\n\nControl re-execution limits (rate limiting):\n\n```\n[[execution_policies]]\ndatabase = \"primary\"\nenvironment = \"production\"\nmax_executions = 10\nexecution_window_secs = 3600\nretry_on_failure = false\n```\n\nControl who can access results and storage:\n\n```\n[[result_policies]]\ndatabase = \"primary\"\nenvironment = \"production\"\ndelivery_mode = \"stream\"\naccess = [\"requester\", \"admin\"]\n```\n\nRoute webhooks per database × environment:\n\n```\n[[notification_policies]]\ndatabase = \"primary\"\nenvironment = \"production\"\n\n[[notification_policies.webhooks]]\nurl = \"https://hooks.slack.com/services/...\"\nformat = \"slack\"\n```\n\nFull reference:\n\n[docs/reference/cli.md]\n\n```\ndbward [OPTIONS] <COMMAND>\n\nCommands:\n  init          Interactive setup wizard\n  doctor        Diagnose connectivity and configuration\n  login         OIDC login (browser or --device for headless)\n  logout        Revoke tokens and delete credentials\n  whoami        Show current identity and role\n  migrate       Run migrations (up/down/status/create)\n  execute       Execute SQL (--emergency --reason for break-glass)\n  audit         Search audit log (--verify for hash chain check)\n  mcp           Start MCP stdio server\n  server        Server management (start, token create/revoke, reload)\n  agent         Start the agent\n  dev           Start local dev server + agent\n  self-update   Update dbward to the latest version\n  request       Manage requests:\n    list          List requests (--pending-for-me, --status)\n    show          Show request detail\n    approve       Approve a pending request\n    reject        Reject a pending request\n    resume        Resume and wait for result\n    cancel        Cancel a pending request\n  token         Manage API tokens (create/list/revoke)\n  user          Manage users (list/suspend/activate)\n  slack         Slack integration:\n    init          Generate app manifest and creation URL\n  policy        Policy tools:\n    resolve       Resolve effective policy for a request\n\nGlobal Options:\n  --version, -v            Show version and exit\n  --config <PATH>          Config file (standalone mode; omit for auto-detect)\n  --database <NAME>        Target database [env: DBWARD_DATABASE]\n  --environment <ENV>      Environment [env: DBWARD_ENV]\n```\n\nFull reference:\n\n[docs/reference/api.md]\n\n| Method | Path | Description |\n|---|---|---|\n| POST | `/api/requests` |\nCreate request |\n| POST | `/api/requests/:id/approve` |\nApprove |\n| POST | `/api/requests/:id/resume` |\nResume for on-demand execution |\n| GET | `/api/requests/:id/result/stream` |\nLong-poll for result |\n| GET | `/api/audit/events` |\nAudit events |\n| GET | `/api/audit/verify` |\nVerify hash chain integrity |\n| POST | `/api/tokens` |\nCreate API token |\n| GET | `/api/databases` |\nList configured databases |\n| GET | `/api/agents` |\nList connected agents |\n| POST | `/mcp` |\nRemote MCP (HTTP) |\n\nSee [full API reference](/dbward-dev/dbward/blob/main/docs/reference/api.md) for all endpoints, parameters, permissions, and response formats.\n\nThreat model and hardening guide:\n\n[docs/security/]\n\n**Zero-trust client**— developer machines never have DB credentials** Signed execution tokens**— Ed25519. Token includes SHA-256 hash of SQL + target database** Token replay prevention**— executed/failed requests don't issue new tokens** Multi-statement rejection**— prevents SQL injection via statement chaining** Writable CTE detection**—`WITH x AS (DELETE ...) SELECT ...`\n\nclassified as DML**RBAC**— admin (system management), requester (SQL operations), operator (monitoring + break-glass), approver (review)** Network isolation**— server has no DB credentials; agent connects outbound only** API token auth**— SHA-256 hashed, prefix+hash composite lookup** OIDC auth**— JWT verification with JWKS caching, RS256/ES256, PKCE for CLI (Team)** Audit hash chain**— SHA-256 chain linking all events, tamper-evident\n\n| Target | Status |\n|---|---|\n| Linux x86_64 (glibc) | ✅ Supported |\n| Linux aarch64 (glibc) | ✅ Supported |\n| macOS Apple Silicon | ✅ Supported |\n| macOS Intel | ✅ Supported |\n| Windows | ❌ Not supported |\n\nPre-built binaries are available on [GitHub Releases](https://github.com/dbward-dev/dbward/releases). Docker images are published for `linux/amd64`\n\nand `linux/arm64`\n\n.\n\nNote:Pre-built binaries and Docker images include commercial-licensed components. They are free to use within Free plan limits. See[LICENSE]for details.\n\n| Database | Status |\n|---|---|\n| PostgreSQL | ✅ Supported |\n| MySQL | ✅ Supported |\n\nAuto-detected from URL scheme (`postgres://`\n\nor `mysql://`\n\n).\n\nFull guide:\n\n[docs/guides/authentication.md]\n\n```\n# Initial tokens created automatically on first server start:\ncat ./data/admin-token     # admin token\ncat ./data/agent-token     # agent token\n\n# Additional tokens via API:\ndbward token create --subject alice --role admin\ndbward login              # Browser-based (PKCE)\ndbward login --device     # Headless (SSH, containers)\ndbward whoami             # Check identity\ndbward logout             # Revoke + delete tokens\n```\n\nApprove and reject requests directly from Slack with interactive buttons:\n\n```\ndbward slack init --server-url https://your-server.example.com\n# → generates Slack App Manifest, opens creation URL\n```\n\nConfigure in `server.toml`\n\n:\n\n```\n[slack]\nbot_token = \"${SLACK_BOT_TOKEN}\"\nsigning_secret = \"${SLACK_SIGNING_SECRET}\"\nchannel = \"C0123ABC456\"\n```\n\nSee [Notifications Guide](/dbward-dev/dbward/blob/main/docs/guides/notifications.md) for setup details.\n\n```\n[[webhooks]]\nurl = \"https://internal.example.com/dbward\"\nformat = \"generic\"\nsecret = \"whsec_xxxx\"  # HMAC-SHA256 in X-Dbward-Signature header\n```\n\nEvents: `request.created`\n\n, `request.approved`\n\n, `request.rejected`\n\n, `execution.completed`\n\n, `request.break_glass`\n\n.\n\nFree: unlimited webhook destinations.\n\n```\ndbward execute \"SELECT pg_terminate_backend(12345)\" \\\n  --emergency --reason \"connection pool exhausted at 3am\"\n```\n\n- Skips approval — agent executes immediately when dispatched\n- Fires\n`request.break_glass`\n\nwebhook (🚨 in Slack) - Reason recorded in audit log\n**Operator or admin role**(requires`request.break_glass_query`\n\nfor SELECT,`request.break_glass_dml`\n\nfor writes)**Not available via MCP**(AI agents cannot trigger break-glass)\n\nFull reference:\n\n[docs/reference/configuration.md]\n\nConfig is resolved in two layers:\n\n**Global**(`~/.config/dbward/config.toml`\n\n): server URL, token/OIDC**Project**(`./dbward.toml`\n\n): databases, migrations\n\n```\n[server]\nurl = \"http://localhost:3000\"\ntoken = \"dbw_...\"\ndefault_database = \"app\"\nmigrations_dir = \"db/migrations\"\n\n[databases.app]\n# No DB URL here — agent handles connections\nagent_id = \"agent-prod\"\npoll_interval_ms = 1000\nmax_concurrent_tasks = 2\n\n[server]\nurl = \"https://dbward.internal:3000\"\nagent_token = \"${DBWARD_AGENT_TOKEN}\"\n\n[databases.primary.production]\nurl = \"${DATABASE_URL_PRIMARY}\"\n\n[databases.analytics.production]\nurl = \"${DATABASE_URL_ANALYTICS}\"\n# Start: dbward-server start --config server.toml --listen 0.0.0.0:3000\nstate_dir = \"/data\"\n\n[auth]\n# OIDC enabled when [auth.oidc] section is present\n\n[[webhooks]]\nurl = \"https://hooks.slack.com/services/...\"\nformat = \"slack\"\n\n[[workflows]]\ndatabase = \"*\"\nenvironment = \"production\"\noperations = [\"execute_select\", \"migrate_up\", \"migrate_down\"]\n\n[[workflows.steps]]\ntype = \"approval\"\n\n[[workflows.steps.approvers]]\nrole = \"admin\"\nmin = 1\n\n[[execution_policies]]\ndatabase = \"*\"\nenvironment = \"production\"\nmax_executions = 10\nexecution_window_secs = 3600\n\n[logging]\noutput = \"stderr\"              # \"stderr\" (default) or \"file\"\n# file_path = \"/var/log/dbward/server.log\"  # only when output = \"file\"\n# rotation = \"daily\"           # \"daily\" (default), \"hourly\", \"never\"\n\n# Environment variables:\n#   DBWARD_LOG_FORMAT=json     → JSON output (production)\n#   RUST_LOG=info              → log level filter (default: info)\n```\n\n| Free | Team ($149/mo) | |\n|---|---|---|\n| Database connections | 3 | 20 |\n| Active users | 20 | 50 |\n| Workflow rules | Unlimited | Unlimited |\n| Webhooks | Unlimited | Unlimited |\n| Agents | Unlimited | Unlimited |\n| Approval + Audit + MCP + Break-glass | ✅ | ✅ |\n| Slack approval UI | ✅ | ✅ |\n| Result policies | ✅ | ✅ |\n| Notification policies | ✅ | ✅ |\n| OIDC / SSO | — | ✅ |\n| Group-based authorization | — | ✅ |\n| Audit export (CSV/JSON) | — | ✅ |\n\nSafety features are always free. You pay for scale and organizational complexity.\n\nTeam plan is not yet available.[Join the waitlist]to get notified.\n\nMigrations use single-file [dbmate-compatible format](https://github.com/amacneil/dbmate):\n\n```\nmigrations/\n├── 20260501120000_create_users.sql\n└── 20260502090000_add_email.sql\n-- migrate:up\nCREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT NOT NULL);\n\n-- migrate:down\nDROP TABLE users;\n```\n\ndbward uses an open-core licensing model.\n\n**Core**(`crates/`\n\n):[Apache-2.0](/dbward-dev/dbward/blob/main/LICENSE-APACHE)— approval workflows, audit logs, MCP, SQL review, agent execution, break-glass. Use, modify, and redistribute freely.**Commercial**(`commercial/`\n\n):[dbward Commercial License](/dbward-dev/dbward/blob/main/LICENSE-COMMERCIAL)— OIDC/SSO, group authorization, Team/Enterprise plan enforcement. Requires a paid subscription for production use.\n\nNo license key = Free plan. All core features work without restriction.\n\nSee [LICENSE](/dbward-dev/dbward/blob/main/LICENSE) for the full structure.", "url": "https://wpnews.pro/news/show-hn-dbward-approval-workflows-for-production-databases", "canonical_source": "https://github.com/dbward-dev/dbward", "published_at": "2026-08-11 13:26:59+00:00", "updated_at": "2026-08-11 13:41:29.021090+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools"], "entities": ["Dbward", "Apache-2.0", "MCP", "Slack", "Rust", "SQLite", "PostgreSQL", "MySQL"], "alternates": {"html": "https://wpnews.pro/news/show-hn-dbward-approval-workflows-for-production-databases", "markdown": "https://wpnews.pro/news/show-hn-dbward-approval-workflows-for-production-databases.md", "text": "https://wpnews.pro/news/show-hn-dbward-approval-workflows-for-production-databases.txt", "jsonld": "https://wpnews.pro/news/show-hn-dbward-approval-workflows-for-production-databases.jsonld"}}