Keep sensitive columns out of prompts
Run in production
Some columns, such as a social security number or an email address, shouldn’t reach your model provider, even by name. Mark them sensitive in the schema artifact. AskDB can then leave them out of every prompt, flag the SQL that reads them, and keep them out of the RAG index. Their values never reach the model either way: AskDB doesn’t read your rows.
Before you start
Section titled “Before you start”- A schema artifact for your database, from
askdb introspect. - A list of the tables and columns that are sensitive.
1. Mark the tables and columns
Section titled “1. Mark the tables and columns”In Studio, open the table in Tables and use its Sensitivity tab. Or write the mark in the table’s markdown front-matter:
---id: table:public.usersname: usersschemaId: my-appcolumns: - id: table:public.users#email sensitive: true---A table-level sensitive: true marks every column in the table. schema.json can carry the same marks, and Sensitivity rules says how the two combine.
2. Leave them out of the prompt
Section titled “2. Leave them out of the prompt”By default, the prompt keeps sensitive columns, each tagged (sensitive). To leave them out, set the floor in askdb.config.ts:
export default defineConfig({ // ... modes: { omitSensitiveFromPrompt: true },});The model then sees neither the sensitive columns nor the text that names them. Privacy model says exactly what each mode sends, and the one exception.
The config setting is a floor: a single call can turn omission on, but not off. Each surface has its own switch:
| Surface | Turn omission on |
|---|---|
askdb.config.ts | modes.omitSensitiveFromPrompt: true, for the CLI, Studio, the HTTP API and createAskDb() |
askdb ask | --omit-sensitive-from-prompt |
askdb.ask() or core’s ask() | omitSensitiveIdentifiersFromNlToSqlPrompt: true |
| HTTP API | "omitSensitiveFromPrompt": true in the request body |
planChart() in @askdb/client/charts (experimental) | omitSensitiveIdentifiers: true, with the schema artifact as schema |
Studio’s Playground, Suggest and Draft with AI follow the config setting.
3. Check the SQL for them
Section titled “3. Check the SQL for them”ask() checks the SQL it returns for sensitive tables and columns, and reports what it finds in result.sensitiveGuardrail:
// askdb initialized at startup with createAskDb() — see Embed in a Node app.const result = await askdb.ask(question);if (result.sensitiveGuardrail && !result.sensitiveGuardrail.passed) { // The SQL reads a sensitive table or column: review it before you run it. console.warn(result.sensitiveGuardrail.references);}To refuse that SQL instead, pass sensitiveGuardrailMode: "strict", and the call throws SensitiveReferenceError. A rebind with askdb.bind() runs the same check again.
SQL that reaches your database without ask() or a rebind isn’t checked, such as a statement you cache and replay. Run validateSensitiveReferences() on every such path:
import { validateSensitiveReferences } from "@askdb/core";
const { passed, references } = validateSensitiveReferences(cachedSql, schema);if (!passed) { throw new Error(`refusing to replay: ${references.map((r) => r.column).join(", ")}`);}The check is heuristic, not a SQL parser — a review and enforcement aid, not a substitute for database-side column privileges. Conservative failure says how it reports a statement it can’t fully read.
4. Keep them out of the database role
Section titled “4. Keep them out of the database role”Leaving a column out of the prompt, and checking the SQL, don’t stop a query from reading it. Leave sensitive tables out of the grants of the read-only role that runs AskDB’s SQL, as Database role shows. On Postgres you can also grant SELECT on chosen columns of a table only (GRANT).
5. Keep them out of the RAG index
Section titled “5. Keep them out of the RAG index”With @askdb/rag, sensitive tables and columns, and any text that names a sensitive column, stay out of the index by default, so your embedding provider never receives them. chunkOptions: { includeSensitiveDescribable: true } puts them in. See RAG for large schemas.
If it fails
Section titled “If it fails”| Error | Fix |
|---|---|
SensitiveReferenceError | With sensitiveGuardrailMode: "strict", the SQL reads a sensitive table or column (rule is SENSITIVE_TABLE_REFERENCED or SENSITIVE_COLUMN_REFERENCED), or the check couldn’t tell which tables a column belongs to (UNRESOLVED_TABLE_SCOPE). Ask the question another way, or review the SQL and decide whether to run it. |
SensitiveEnrichmentTargetError, or an error from Studio’s Suggest | With omission on, AskDB won’t ask the model to describe a sensitive column. Write that column’s description yourself. |
Read next
Section titled “Read next”© 2026 Yahya Gilany

