Security & Data Sovereignty
askLenny runs entirely inside your own infrastructure. Your row data never leaves your network — ever. Schema names and questions only leave if you choose a cloud AI model. Switch to a local model and nothing crosses your perimeter at all.
Run with zero egress
Set base_url in connectors.yaml to point at a local model (Ollama, vLLM, LM Studio) and nothing leaves your network -not schema names, not questions, not results. The entire pipeline runs on your hardware.
When using a cloud model (Gemini, Claude, OpenAI), schema names and your questions are sent to that provider's API. Row data and query results are never sent anywhere, regardless of AI provider.
Row data: stays in your network
The Rust graph engine only stores schema metadata -table names, column types, descriptions. The Python app executes SQL and returns results to your browser. No row data is ever stored or forwarded to any external service.
Passwords: never transmitted
Database credentials live in connectors.yaml on your host and are bind-mounted into the app container at runtime. They are never sent to any external service, never logged, and never leave your machine.
Graph engine: fully isolated
The Rust engine container has no external network access. It cannot reach your databases, the internet, or any LLM. It only responds to the Python app container over the internal Docker bridge.
Container trust boundaries
Frontend Container
Host port :80 (nginx)
Outbound connections
- →Python app layer API only (internal Docker network)
Holds in memory / disk
- ·No credentials
- ·No database access
- ·No persistent storage
App Layer Container
:8000 (internal only -not exposed to host)
Outbound connections
- →Your databases (INFORMATION_SCHEMA + SELECT)
- →AI endpoint (cloud or local -your choice)
- →Rust engine :3000 (internal Docker network)
Holds in memory / disk
- ·DB credentials (from connectors.yaml)
- ·Temporary query results (in memory)
Graph Engine Container
:3000 (internal only -not exposed to host)
Outbound connections
- →No external connections whatsoever
Holds in memory / disk
- ·Schema graph (.dat files on named volume)
- ·Vector embeddings
- ·No credentials
What leaves your network
Every category of data askLenny handles -where it goes, which container handles it, and whether a local AI model eliminates the egress entirely.
| Data | Leaves network? |
|---|---|
| Table names | Cloud model only |
| Column names + SQL types | Cloud model only |
| Natural-language question | Cloud model only |
| Schema context (markdown) | Cloud model only |
| Row data (SELECT results) | Never |
| Database passwords | Never |
| Schema graph / embeddings | Never |
| Query history / results | Never |
Controlling the AI endpoint
Only the Python app container makes LLM calls -for description generation during schema enrichment and for SQL generation at query time. All other containers are completely isolated from external networks.
Set model_to_use in connectors.yaml to choose your AI provider. Add an optional base_url to route through any OpenAI-compatible server for full on-premise operation. The API key is supplied via the AI_API_KEY environment variable and never written to disk.
Cloud AI (Gemini / Claude / OpenAI)
Partial egressmodel_to_use: "gemini-2.0-flash-lite" (or claude-*, gpt-4o)Schema names and your question are sent to the provider API. Row data never leaves.
Ollama (local)
Zero egressbase_url: "http://host.docker.internal:11434/v1"Zero bytes leave your network. Fully on-premise.
Private Azure OpenAI
Tenant-scopedbase_url: "https://your-resource.openai.azure.com/..."Data stays within your Azure tenant under your own data terms.
Network isolation
Exposed ports
- :80Frontend dashboard (nginx) -the only port exposed to your host. Run behind a VPN or internal network boundary. Never expose to the public internet.
- :8000Python app layer -internal Docker network only. Not accessible from your host machine.
- :3000Rust graph engine -internal Docker network only. Accessible only from the Python app container.
askLenny never calls home
- ✓No telemetry or usage reporting
- ✓No licence check or phone-home
- ✓No package downloads at runtime -all dependencies baked into the image
- ✓MIT licensed -audit the full source code on GitHub