Security
qLLM is built for limited, intentional exposure: read-only queries, required limits, secrets in env vars, and loopback bind until you opt into a wider surface.
Read-only and bounded
- Reads Agents query the catalog; writes and DDL are out of the agent contract.
-
Limits
Row
limitis required and capped. Default total budgetmaxSyncMs≈ 15000 ms (15 s); typedTIMEOUTon cancel. -
Secrets
Connection material via
*Env/${QLLM_…}— not pasted into agent prompts.
Bearer auth
Set serve.authTokenEnv (or --auth-token-env) to an env var that
holds the shared Bearer token for HTTP /v1 and MCP HTTP. If the env name is
set, the variable must be non-empty or serve refuses to start. Stdio MCP is unaffected.
export QLLM_AUTH_TOKEN=dev-secret
curl -s -H "Authorization: Bearer $QLLM_AUTH_TOKEN" http://127.0.0.1:8088/v1/catalog
GET /v1/health stays unauthenticated. For per-app table scopes, use
qllm.access.yaml instead of a single token — see
Configure.
Bind loopback
Defaults: 127.0.0.1:8088 and 127.0.0.1:8089. Binding a
non-loopback address without auth requires --insecure-bind or
serve.insecureBind: true — an explicit opt-in, not a silent default.
CORS — MCP browser clients only
CORS is off when origins is empty. Wildcard * is rejected. Enable
an allowlist only if a browser client needs Streamable HTTP / SSE against MCP HTTP —
typical server-side agents do not need CORS.
serve:
cors:
origins: [] # empty = CORS off
Write denylist
- SQL Catalog SQL and planning reject write/DDL shapes; connectors stay on read paths (Redis never deletes/pops/KEYS; Kafka never produces).
- GraphQL As a source, only query documents are accepted. Mutations and write operations are forbidden at the document gate.
Deep reference for multi-user scoped credentials: docs/en/multi-user-safety.md.