dbbat

command module
v0.10.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 11, 2026 License: AGPL-3.0 Imports: 20 Imported by: 0

README

DBBat - Database Observability Proxy

Give your devs access to prod.

A transparent database proxy for query observability, access control, and safety. Speaks PostgreSQL, Oracle, and MySQL/MariaDB wire protocols. Every query logged. Every connection tracked.

Documentation

Full documentation is available at dbbat.com:

Why DBBat?

The Problem:

  • Production databases should not be directly accessible to developers for security and compliance reasons
  • Developers often need access to production data to diagnose issues, debug problems, and understand user behavior
  • Traditional solutions are binary: either full access (risky) or no access (blocks troubleshooting)

The Solution:

DBBat acts as a monitoring proxy that allows controlled developer access to production databases with:

  • Complete monitoring: Every query and result is logged with full traceability
  • Strict limitations: Time-windowed access, fine-grained controls, query quotas, and data transfer limits
  • Full audit trail: Track who accessed what, when, and what data they retrieved
  • Encrypted credentials: Database passwords never exposed to users
  • Granular access control: Grant temporary access to specific databases with precise permissions

Supported Databases

Engine Protocol Default proxy port Notes
PostgreSQL PostgreSQL wire (pgx/v5) :5434 (DBB_LISTEN_PG) First-class support; auth terminated at proxy
Oracle TNS / TTC :1522 (DBB_LISTEN_ORA) O5LOGON proxy auth; go-ora end-to-end (other clients reach AUTH only — see docs/oracle.md)
MySQL MySQL wire (go-mysql-org/go-mysql) :3307 (DBB_LISTEN_MYSQL) caching_sha2_password (default), mysql_clear_password; TLS terminated at proxy
MariaDB MySQL wire (same listener) :3307 (DBB_LISTEN_MYSQL) Same as MySQL — mysql_native_password not supported, STMT_BULK_EXECUTE refused

Each engine has its own listener; enable only the ones you need by setting the matching DBB_LISTEN_* environment variable. PostgreSQL is enabled by default; Oracle/MySQL listen on their default ports unless explicitly disabled in config.

Features

  • Multi-engine proxy: PostgreSQL, Oracle, MySQL/MariaDB on independent listeners
  • User Management: Local user database with username/password (Argon2id) and admin/viewer/connector roles
  • API Keys: Long-lived bearer tokens (dbb_…) for programmatic access; cannot create or revoke other keys (security restriction)
  • Slack OAuth (optional): Sign-in via Slack workspace, optional auto-provisioning
  • Database Configuration: Store target database connections with AES-256-GCM encrypted credentials; protocol field per database (postgresql, oracle, mysql, mariadb)
  • Connection & Query Tracking: Logs every connection, every query (SQL text, parameters, duration, rows affected, errors), and optionally captures result rows (query_rows table) up to configurable size limits
  • Access Control: Time-windowed grants (starts_at / expires_at), independent controls (read_only, block_copy, block_ddl), and optional quotas (max_query_counts, max_bytes_transferred)
  • Read-only enforcement: Defense in depth — SQL inspection, PostgreSQL default_transaction_read_only, MySQL/MariaDB blocks for LOAD DATA/SELECT … INTO OUTFILE/etc., and proxy-side opt-out from LOCAL INFILE
  • Audit Trail: Append-only audit log of user, grant, and database changes
  • Rate Limiting: Per-user request limits and exponential backoff on failed login
  • Authentication Cache: Optional in-memory cache (TTL + max size) shared across REST and proxy auth paths
  • Session Packet Dumps: Optional binary capture of post-auth session traffic (.dbbat-dump files); same format across all protocols (see docs/dump-format.md) with dbbat dump anonymise for sharing
  • REST API: OpenAPI 3.0 documented (/api/docs), versioned under /api/v1/
  • Web UI: Embedded React frontend served at /app
  • Demo / Test modes: Self-provisioning sample data for safe trials and E2E testing

Quick Start

Running with Docker
docker run -d \
  -e DBB_DSN="postgres://user:pass@host:5432/dbbat?sslmode=require" \
  -p 5434:5434 \
  -p 1522:1522 \
  -p 3307:3307 \
  -p 4200:4200 \
  ghcr.io/fclairamb/dbbat

Ports: 5434 PostgreSQL proxy, 1522 Oracle proxy, 3307 MySQL/MariaDB proxy, 4200 REST API + web UI.

Running with Docker Compose

See docker-compose installation for a complete example.

Usage Example

All API endpoints are under /api/v1/. See the API Reference for complete documentation.

1. Login and get a token
TOKEN=$(curl -s -X POST http://localhost:4200/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "admin"}' | jq -r '.token')
2. Create a User
curl -X POST http://localhost:4200/api/v1/users \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "developer",
    "password": "temppass123",
    "roles": ["connector"]
  }'
3. Configure a Target Database
curl -X POST http://localhost:4200/api/v1/databases \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "production",
    "description": "Production database",
    "protocol": "postgresql",
    "host": "db.example.com",
    "port": 5432,
    "database_name": "myapp",
    "username": "readonly_user",
    "password": "dbpass",
    "ssl_mode": "require"
  }'

For Oracle, set "protocol": "oracle" and add "oracle_service_name": "ORCL". For MySQL/MariaDB, set "protocol": "mysql" (or "mariadb") and use port 3306.

4. Grant Access
curl -X POST http://localhost:4200/api/v1/grants \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "<user-uid>",
    "database_id": "<database-uid>",
    "controls": ["read_only"],
    "starts_at": "2024-01-01T00:00:00Z",
    "expires_at": "2024-12-31T23:59:59Z",
    "max_query_counts": 1000,
    "max_bytes_transferred": 10485760
  }'

controls accepts any combination of read_only, block_copy, block_ddl. An empty array means full write access.

5. Connect via Proxy
# PostgreSQL
psql -h localhost -p 5434 -U developer -d production

# Oracle (go-ora-style easy connect)
# Use the database name (or its oracle_service_name) as SERVICE_NAME
# Example with sqlplus: developer/temppass123@//localhost:1522/production

# MySQL / MariaDB
mysql -h 127.0.0.1 -P 3307 -u developer -p production

Configuration

Variable Description Default
DBB_DSN PostgreSQL DSN for DBBat storage Required
DBB_LISTEN_PG PostgreSQL proxy listen address :5434
DBB_LISTEN_ORA Oracle proxy listen address (empty disables) :1522
DBB_LISTEN_MYSQL MySQL/MariaDB proxy listen address (empty disables) :3307
DBB_LISTEN_API REST API listen address :4200
DBB_KEY Base64-encoded AES-256 encryption key Auto-generated at ~/.dbbat/key
DBB_KEYFILE Path to file containing encryption key -
DBB_RUN_MODE Run mode: empty (production), test, or demo -
DBB_LOG_LEVEL debug, info, warn, error info
DBB_DUMP_DIR Directory for session packet dumps (empty disables) -
DBB_DUMP_MAX_SIZE Max dump file size per session, in bytes 10485760 (10 MB)
DBB_DUMP_RETENTION Auto-delete dumps older than this (Go duration) 24h
DBB_MYSQL_TLS_DISABLE Disable MySQL TLS termination at the proxy false
DBB_MYSQL_TLS_CERT_FILE PEM cert for MySQL TLS (auto self-signed if empty) -
DBB_MYSQL_TLS_KEY_FILE PEM RSA key for MySQL TLS (auto-generated if empty) -

See Configuration for the full set, including rate limiting, query storage, hash presets, auth cache, Slack OAuth, demo target, and dev redirects.

Security

  • User passwords are hashed with Argon2id
  • Database credentials are encrypted with AES-256-GCM (AAD-bound to the database UID)
  • API keys (dbb_…) are stored as encrypted blobs and cannot create or revoke other keys
  • Failed logins trigger per-username exponential backoff
  • Default admin user (admin / admin) is created on first startup — change it immediately

Architecture

psql / pg client     ─►  DBBat (auth + grant check + log) ─► PostgreSQL upstream
sqlplus / go-ora     ─►  DBBat (TNS service-name routing)  ─► Oracle upstream
mysql / mariadb cli  ─►  DBBat (caching_sha2_password)     ─► MySQL / MariaDB upstream

DBBat is a single Go binary backed by a PostgreSQL store (users, databases, grants, connections, queries, audit, dumps).

Development

make dev          # Start dev environment with hot reload (Air + Vite)
make test         # Run Go tests (uses testcontainers)
make test-e2e     # Run Playwright E2E tests
make build-app    # Build frontend + backend
make lint         # Run golangci-lint

See CLAUDE.md for development documentation.

License

AGPL-3.0

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal
api
notify
Package notify implements outbound notification channels for grant request lifecycle events.
Package notify implements outbound notification channels for grant request lifecycle events.
store
Package store provides database access and persistence for DBBat.
Package store provides database access and persistence for DBBat.
version
Package version contains build version information set via ldflags.
Package version contains build version information set via ldflags.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL