Self-hosted natural-language-to-SQL: ask questions in plain English, get dialect-aware SQL, results, and a feedback loop that improves future answers.
Security: AstraSQL ships with a local admin account. Sign in as
admin/AstraSQL-change-meand change the password on first use. Prefer TLS at a reverse proxy; do not expose the UI or API on the public internet without HTTPS.
- Auth — local admin login (HttpOnly session cookie), forced password change after first setup
- Chat — natural-language questions with SSE streaming, SQL preview, results table/charts
- Connections — connect to PostgreSQL, test, and scan schema metadata
- Context — enrichments, business rules, and golden Q→SQL records (FAISS retrieval)
- Feedback — thumbs up/down promotes useful answers into golden records
- History — review past queries, re-run, export CSV/JSON/XLSX
- Docker (recommended) or Python 3.11+ and Node.js 20+
- An OpenAI API key
- A PostgreSQL database you can connect to (MySQL / MSSQL are on the roadmap)
cp .env.example .env
# set OPENAI_API_KEY and a strong ENCRYPTION_KEY (required when DEBUG=false)
docker compose up --build- Open the UI and sign in as
admin/AstraSQL-change-me. - Set a new password (12+ characters, not the default).
- Add a PostgreSQL connection and start chatting.
- UI: http://localhost:3000
- API: http://localhost:8000
- Health: http://localhost:8000/health
Persistent data (SQLite + FAISS indexes) lives in the astrasql_data volume at /app/data.
Requires Python 3.11+ and uv.
cd backend
uv sync --extra dev
cp ../.env.example ../.env # or place .env in backend/
uv run uvicorn src.api.app:app --reload --host 0.0.0.0 --port 8000cd frontend
npm install
npm run devVite proxies /api to the backend in development. Open the printed local URL (typically http://localhost:5173).
- Open Connections in the UI.
- Create a PostgreSQL connection (host, port, database, user, password, SSL).
- Test connectivity, then Scan to ingest table metadata for the context layer.
- Use Chat with that connection selected.
Supported today: PostgreSQL only. MySQL and Microsoft SQL Server providers are stubs on the roadmap.
- Enrichments — human descriptions, aliases, and example values for tables/columns so the agent links schema more accurately.
- Business rules — free-text constraints (e.g. “active customers means status = 'A'”) injected into generation.
- Golden records — curated question → SQL pairs; indexed with FAISS and retrieved as few-shot examples.
- Feedback loop — thumbs-up on History promotes that Q/SQL into golden records and rebuilds the index; thumbs-down records a negative rating for filtering and review.
Manage context under Context; review past runs under History.
| Layer | Role |
|---|---|
| Frontend | React + Vite UI (Chat, Connections, Context, History, Settings) |
| API | FastAPI (/api/*), SSE streaming for query runs |
| Agent | LangGraph pipeline: intent → schema link → SQL generate → validate → execute → format |
| Context Layer | Schema enrichments, business rules, golden Q→SQL records, FAISS retrieval |
| Providers | Pluggable LLM (OpenAI) and database drivers (PostgreSQL today) |
| Storage | SQLite metadata (connections, history, context) + encrypted credentials |
Question → LangGraph agent → Context retrieval → Dialect SQL → Readonly execute → Answer + confidence
↑
enrichments / rules / golden records / ratings
- Local admin auth — the API and UI require a session cookie. First boot creates
adminwithDEFAULT_ADMIN_PASSWORD(AstraSQL-change-me) and blocks the rest of the app until that password is changed. - Five failed logins lock the account for 15 minutes.
- Set a unique
ENCRYPTION_KEYbefore production-like use. The app refuses to start whenDEBUG=falseand the default placeholder key is still set. - Prefer TLS termination at a reverse proxy if you leave localhost. Session cookies are
SecurewhenDEBUG=false. - See SECURITY.md for reporting vulnerabilities.
| Variable | Description | Default |
|---|---|---|
OPENAI_API_KEY |
OpenAI API key | (empty) |
OPENAI_MODEL |
Chat model | gpt-5.6-luna |
LLM_PROVIDER |
LLM provider key | openai |
ENCRYPTION_KEY |
Secret used to derive Fernet key for DB passwords | (must set when DEBUG=false) |
SQLITE_URL |
Async SQLAlchemy URL for app metadata | sqlite+aiosqlite:///./data/astrasql.db |
DATABASE_URL |
Optional alias of SQLITE_URL (future Postgres metadata) |
(empty → use SQLITE_URL) |
DEFAULT_ADMIN_USERNAME |
Bootstrap admin username | admin |
DEFAULT_ADMIN_PASSWORD |
Bootstrap admin password (must change on first login) | AstraSQL-change-me |
SESSION_TTL_DAYS |
Sliding session lifetime | 7 |
DATA_DIR |
Data directory (SQLite path relative, FAISS indexes) | ./data |
CORS_ORIGINS |
Comma-separated browser origins | http://localhost:5173,http://localhost:3000 |
MAX_RESULT_ROWS |
Cap on query result rows | 500 |
DEBUG |
SQL echo / allow default encryption key / insecure cookies | false |
Copy .env.example to .env before docker compose up. Never commit real API keys.
Three steps:
- Implement a class extending
BaseDatabaseProviderinbackend/src/providers/database/(setavailable = True, dialect prompts, sqlglot dialect, async engine, schema introspection, readonly execute, EXPLAIN, test). - Register it in
backend/src/providers/database/registry.py(_REGISTRYand optional aliases). - Export from
backend/src/providers/database/__init__.pyif you want a public import path.
The new type appears in GET /api/settings/public → database_types and in the Connections UI once it is marked available.
- Multi-user access control, SSO/OIDC, and API keys
- MySQL and Microsoft SQL Server connectors
- Additional LLM providers (Azure OpenAI, Anthropic, local models)
- Stronger governance (audit log, row/column policies)
- Evaluation tooling around golden records
AstraSQL/
├── backend/ # FastAPI + LangGraph + providers
├── frontend/ # React SPA (nginx in Docker)
├── docker-compose.yml
├── .env.example
├── LICENSE
└── README.md
See CONTRIBUTING.md. Bug reports and pull requests are welcome.
Copyright 2026 AstraSQL contributors.
Licensed under the Apache License, Version 2.0.