Skip to content

crs7617/goto

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GoTo - SQL Sandbox API

A secure, read-only SQL sandbox API service for running ad-hoc queries against a sample PostgreSQL database. It enforces timeouts, rate limits, and query safety, and returns JSON-formatted results and query plans.

Features

  • REST API: POST /api/query, GET /api/health
  • Read-only sandbox over PostgreSQL with schema isolation via search_path
  • Query validation (whitelist SELECT/WITH/EXPLAIN, forbid dangerous keywords)
  • Statement timeout (5s), result row limit (100), query length limit (1000 chars)
  • Connection pooling and context timeouts
  • EXPLAIN (ANALYZE, FORMAT JSON) parsing for planning/execution metrics
  • Nginx reverse proxy with rate limiting, CORS, request logging
  • Docker Compose for one-command startup

Quickstart

# From repo root
docker compose up --build
# API on http://localhost:80 via Nginx (or http://localhost:8080 directly to app)

Environment

The API reads the following env vars (see docker-compose.yml):

  • DB_HOST (default: postgres)
  • DB_PORT (default: 5432)
  • DB_USER (default: sandbox_ro)
  • DB_PASSWORD (default: sandbox_ro)
  • DB_NAME (default: goto)
  • DB_SSLMODE (default: disable)
  • API_PORT (default: 8080)

API

Health

GET /api/health

Response: { "status": "ok" }

Execute Query

POST /api/query
Content-Type: application/json

{ "query": "SELECT * FROM users LIMIT 10" }

Response:

{
  "execution_time_ms": 12,
  "rows_affected": 10,
  "query_plan": { "Plan": { "Node Type": "Limit", "Total Cost": 123.45 }},
  "plan_metrics": {"planning_time_ms": 0.12, "execution_time_ms": 1.23, "total_cost": 123.45},
  "results": [{"id":1, "name":"User 1", "email":"user1@example.com"}]
}

Errors return with HTTP 4xx/5xx and { "error": "message" }.

Sample curl

# Health
curl -s http://localhost/api/health | jq

# Simple SELECT
curl -s -X POST http://localhost/api/query \
  -H 'Content-Type: application/json' \
  -d '{"query":"SELECT id, name, email FROM users ORDER BY id LIMIT 10"}' | jq

# Join query
curl -s -X POST http://localhost/api/query \
  -H 'Content-Type: application/json' \
  -d '{"query":"SELECT o.id, u.email, o.amount FROM orders o JOIN users u ON u.id=o.user_id ORDER BY o.id LIMIT 10"}' | jq

Development

  • Go 1.21+
  • Chi router, pq driver, godotenv

Run locally without Docker:

export DB_HOST=localhost DB_USER=sandbox_ro DB_PASSWORD=sandbox_ro DB_NAME=goto DB_SSLMODE=disable
go run ./cmd/api

Security Notes

  • Read-only DB user with RLS; no write grants
  • Server-side statement_timeout set per transaction
  • Query whitelist and blocklist enforced in API
  • Nginx rate limiting at 10 req/sec per IP

License

MIT

About

Interactive PostgreSQL sandbox for safe query experimentation and performance profiling

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published