Skip to main content

Security

Datafala does not see your data​

The API never connects to your database and never receives its credentials. It only knows the DDL, descriptions, context and examples you registered in the panel. Query results stay only in your system.

SQL Guard​

Every SQL generated by the LLM, every example saved in the panel and every evaluation case goes through the SQL Guard, which analyzes the query as a syntax tree (not as text) in your schema's dialect. It rejects everything that is not explicitly allowed:

  1. A single statement, and it has to be a SELECT (non-recursive CTEs are accepted). INSERT, UPDATE, DELETE, DDL, SELECT ... INTO, locks (FOR UPDATE) and multiple statements are rejected.
  2. Only registered and visible tables. System tables (pg_catalog, information_schema, mysql, performance_schema, sys) are never accepted. In Firebird, objects with the RDB$, MON$ and SEC$ prefixes are ignored on import and cannot be queried.
  3. Only registered and visible columns. SELECT * is expanded and rejected if it reaches a hidden column.
  4. Functions from an allowlist per dialect (aggregation, date, text, math and conditionals). Dangerous functions such as pg_sleep, pg_read_file, dblink, SLEEP, BENCHMARK and LOAD_FILE are blocked, as are @@/@ variables and executable comments /*! */ in MySQL. In Firebird, GEN_ID, NEXT VALUE FOR, RDB$GET_CONTEXT, RDB$SET_CONTEXT and calls to procedures/UDFs that are not allowed are rejected.
  5. Placeholders and parameters match: every %(name)s has a value in params, and vice versa.
  6. LIMIT always applied, rewritten in the tree, except in aggregations that provably return one row. A LIMIT larger than max_rows is reduced. In Firebird, the Guard limits with FIRST/SKIP or ROWS depending on the query.

In Firebird, queries without a FROM are also rejected; do not use RDB$DATABASE to get around the requirement to query a registered table. EXECUTE BLOCK, EXECUTE PROCEDURE, SELECT ... WITH LOCK, PLAN and other forms that are not an allowed SELECT are also blocked.

If the first SQL is rejected, the API asks the LLM for a correction only once, informing only generic codes, so that the LLM never discovers what you hid.

Defense in depth

The Guard is the first layer. The second is yours: a read-only database user, with access only to the registered tables and a maximum time per query. See Run the SQL.

Keys and secrets​

  • API keys: 256 random bits, stored only as a SHA-256 hash and shown only once.
  • Your LLM key: stored encrypted (Fernet) and decrypted only at the moment of the call to the provider.
  • Panel passwords: Argon2, with a strong password policy and a limit on login attempts.

What goes to the LLM​

The prompt includes the visible schema (without hidden tables and columns), the context, the examples, today's date and the question. Feedback comments and evaluation cases never go into the prompt. Because the explanation may repeat snippets of the prompt, do not put secrets in the context of the panel.

Data sent to the LLM follows the policy of the provider you chose, on your account. The tenant administrator can see in the panel's History exactly the prompt sent for each question.

Transport and headers​

Every call uses HTTPS. The /v1 responses carry Cache-Control: no-store; do not rely on HTTP cache to reuse answers, use the history or your own cache by request_id.