Data Sovereignty

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.

DataLeaves network?
Table namesCloud model only
Column names + SQL typesCloud model only
Natural-language questionCloud model only
Schema context (markdown)Cloud model only
Row data (SELECT results)Never
Database passwordsNever
Schema graph / embeddingsNever
Query history / resultsNever

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 egress
model_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 egress
base_url: "http://host.docker.internal:11434/v1"

Zero bytes leave your network. Fully on-premise.

Private Azure OpenAI

Tenant-scoped
base_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