Publish governed SQL as secure, observable APIs—without building a backend service for every endpoint.
Live demo · Architecture · Deployment · Security
DDAG is a self-hosted control plane and data plane for database-backed APIs. Define an HTTP route, bind typed request parameters to parameterized SQL, apply access policies, and publish. DDAG handles authentication, authorization, execution, caching, audit records, metrics, and OpenAPI documentation.
It is designed for teams that need a consistent API layer across PostgreSQL, MySQL/MariaDB, Oracle, and SQL Server without maintaining a separate service for every query.
Project status: DDAG is pre-1.0. PostgreSQL is the primary end-to-end development path. The MySQL, Oracle, and SQL Server connectors build from the shared connector architecture, but broader live-engine integration coverage is still wanted. Pin deployments to a reviewed commit and test against your own database versions and drivers.
| Area | Capability |
|---|---|
| API lifecycle | Draft, validate, publish, deprecate, and retire route definitions |
| Database access | PostgreSQL, MySQL/MariaDB, Oracle, and SQL Server connectors |
| Query safety | Typed parameters, dialect-aware binding, query timeout, row limits, and operation validation |
| Identity and policy | OAuth 2.0 client credentials, RS256 JWTs, scopes, API grants, RBAC, IP allowlists, and rate limits |
| Security | Envelope-encrypted secrets, AAD-bound ciphertext for new writes, internal HMAC authentication, and replay protection |
| Reliability | Connection pools, circuit breakers, backpressure, read-only response caching, and corrupt-cache fallback |
| Observability | Request IDs, structured logs, audit records, Prometheus metrics, and operation-aware request logs |
| API contract | Generated OpenAPI 3 documentation, Swagger UI, and HTTP QUERY support based on RFC 10008 |
Client
│ OAuth bearer token
▼
API Gateway ──► policy checks ──► read cache ──► database connector ──► source database
│ │
├─► request/audit logs └─ parameter binding + timeout + row limit
└─► OpenAPI catalog
Admin
▼
Dashboard ──► control-plane API ──► metadata PostgreSQL
The gateway verifies JWTs locally from JWKS, matches a published route, evaluates policy, and dispatches parameterized SQL to the connector for the selected database engine. Write operations never use the response cache and are not classified as safe for automatic retry.
Read the detailed architecture and HTTP QUERY compatibility notes.
- Docker Engine or Docker Desktop
- Docker Compose v2
- Git
git clone https://github.com/RiprLutuk/DDAG.git
cd DDAG
./scripts/quickstart.shThe launcher creates a local .env with generated credentials, builds the stack, waits for readiness, and prints the dashboard password.
Dashboard: http://localhost
Gateway: http://localhost/api/v1/...
Health: http://localhost/healthz
Useful commands:
./scripts/quickstart.sh status
./scripts/quickstart.sh logs
./scripts/quickstart.sh stop # preserve local data
./scripts/quickstart.sh reset # delete local Postgres and Redis volumesThe root docker-compose.yml is the single Compose definition for local evaluation. Optional MySQL, Oracle, and SQL Server connector services are available through the connectors profile:
docker compose --profile connectors up --buildThe profile starts connector services; you still need reachable source databases and compatible credentials.
A typical workflow is:
- Register a source database connection and test connectivity.
- Create an API definition with an HTTP method, route, SQL template, and typed parameters.
- Configure scopes, client access, limits, and an optional cache rule for read operations.
- Validate and publish the definition.
- Use the generated OpenAPI catalog as the contract for consumers.
Example parameterized SQL:
SELECT site_id, name, status
FROM sites
WHERE site_id = :site_id
LIMIT :ddag_limitDDAG rewrites named parameters to the target driver's placeholder format and sends values as bound arguments. Do not interpolate untrusted values into SQL templates.
For a native single-VPS installation behind Caddy and systemd, follow the VPS deployment guide. Helm manifests and container assets are available under deploy/.
Before exposing DDAG publicly:
- use TLS and private networking for metadata PostgreSQL, Redis, and connector ports;
- give every source connection a least-privilege database role;
- replace all development secrets and back up
DDAG_MASTER_KEYseparately; - restrict dashboard and metrics access;
- configure off-host backups and perform a restore drill;
- pin a reviewed commit or release and run tests against your database engines.
See the security policy, operations guide, and backup and recovery runbook.
| Document | Audience |
|---|---|
| Architecture | Engineers evaluating the design and security boundaries |
| VPS deployment | Operators deploying without Kubernetes |
| Operations | On-call and platform operators |
| Backup and recovery | Operators validating disaster recovery |
HTTP QUERY |
API consumers and compatibility reviewers |
| Testing | Contributors running functional and load checks |
| Metrics catalog | Observability and SRE teams |
| Contributing | Contributors and integration testers |
make build
make test
make vet
cd apps/dashboard
corepack enable
pnpm install --frozen-lockfile
pnpm run buildSee CONTRIBUTING.md before opening a pull request. Live integration coverage for MySQL, Oracle, and SQL Server is particularly valuable.
DDAG reduces repeated API infrastructure work; it is not a substitute for database design, least-privilege roles, network controls, backups, or application-specific business logic. Complex workflows and multi-step transactions may still belong in a dedicated service.
Performance and resource use depend on enabled services, connector count, pool sizes, traffic, cache policy, and source-query cost. Benchmark your own workload rather than relying on a universal footprint claim.
DDAG is available under the MIT License.