On the agent result path, FutrixData replaces sensitive result values with secret-derived, salted pseudonymous hash strings before returning the row to MCP, Skill, or CLI callers. The substitution uses a secret-backed deterministic hashing algorithm, with the key derived from a local secret stored in OS-level secret storage. Determinism is the point: agents can still join, group, and count without ever seeing raw values.
Traditional masking rewrites a value before storage or before it appears on a UI. PII masking for AI agents moves the rewrite to the data egress — the moment a row leaves your database for an LLM context. The agent still gets a row with the correct format, the right joins, and stable equality semantics; it just gets masked:v1:8f3a1c9b72e04d11 instead of alice@example.com.
This matters because once data enters an agent's context, it can flow on to external models, plugins, log systems, debug captures, and token relay services — places enterprise governance does not reach.
FutrixData ships with an L1–L5 sensitivity model. Levels are configurable; defaults are below.
| Level | Meaning | Examples |
|---|---|---|
| L1 Public | Non-sensitive business data | id, status, created_at |
| L2 Internal | Internal identifiers and metadata | user_id, session_id, request_id |
| L3 Confidential | Indirect personal info, behavior, location | ip_address, user_agent, device_id |
| L4 Sensitive | Direct personal info, financial, medical | email, phone, salary, date_of_birth |
| L5 Critical | Credentials, payment instruments, high-sensitivity PII | password, credit_card, api_secret, home_address |
By default, agents receive L1–L3 in the clear. L4 and L5 are replaced with stable hashes before reaching the agent. The agent-accessible range is editable — you can, for example, restrict an agent to L1–L2 only.
Masking is computed deterministically per value:
masked:v1: and return the masked value to the agent.The same input produces the same key-derived output inside an install, so agents can join, group by, count distinct, and reason about equality without ever seeing the raw value. The mapping is one-way without the local secret. Deterministic masking reduces leakage surface — it is not full anonymization. See masking limitations for the inverse.
FutrixData supports two ways to assign sensitivity levels — both writing to the same classification store.
GDPR Article 5(1)(c) requires data minimization — processing only what's necessary. The European Data Protection Board has clarified that pseudonymized data remains personal data when it can still be linked through additional information. PII masking does not "make compliance disappear"; it reduces the leakage surface and makes data egress easier to audit and govern. The audit log records which columns were masked on each query, which gives the security team something concrete to attest to.
// Raw row from PostgreSQL
{ "id": 1042, "email": "alice@example.com", "phone": "+14155550123", "status": "active" }
// Row delivered to the agent (default L1–L3 access)
{ "id": 1042, "email": "masked:v1:8f3a1c9b72e04d11", "phone": "masked:v1:b219ac74e1d908f2", "status": "active" }{
"data_source": "prod-postgres",
"table": "users",
"fields": [
{ "name": "id", "type": "bigint" },
{ "name": "email", "type": "varchar(254)" },
{ "name": "phone", "type": "varchar(20)" },
{ "name": "status", "type": "varchar(16)" }
]
}L4 (email, phone, salary, date_of_birth, etc.) and L5 (password, credit_card, api_secret, home_address) are masked before reaching the agent. L1–L3 are returned in the clear. You can edit the accessible range per agent.
Not without the local key. Masking is a secret-backed deterministic HMAC-SHA256; the HMAC key is derived per (data source, field) from a local secret stored in OS-level secret storage and never leaves the host. The same input produces the same hash value inside an install, but reversing a hash requires the local key — and because FutrixData truncates to the first 16 hex characters, the collision probability is extremely low and effective reversal is not practical. One important caveat: low-cardinality input spaces (booleans, gender, age in years, small enums) remain vulnerable to enumeration — anyone who can submit known inputs through the gateway, or who holds the local secret, can build a lookup table for such fields. The Console (authorized human) path returns raw rows by default; only the agent result path is masked. See limitations — deterministic masking reduces leakage surface, it does not anonymize a dataset for public release.
No. The same input produces the same masked output, so joins, group-bys, count-distinct, and equality predicates still work on masked columns. You lose ordering and substring operations on masked fields — those should run inside the proxy, not in the agent.
Yes. Level names, descriptions, example fields, and the agent-accessible range are editable. You can also add per-source or per-table overrides — for example, classify orders.notes as L4 in production and L1 in the staging copy.
Generally yes. The European Data Protection Board treats pseudonymized data as personal data when it can be linked back through additional information. Masking is a leakage-surface reduction, not a magic compliance switch — but it is a defensible technical measure under GDPR Article 32.
Per-row masking is one secret-backed HMAC per sensitive field — sub-millisecond for typical row sizes. The dominant cost on most queries is the database itself and the LLM round-trip, not the masking step.
It can, on the AI Chat / schema knowledge / table-relationship assistance paths — and it is a separate path from query result rows. Schema metadata may include table names, column names, types, indexes, and comments. Result masking does not automatically cover schema metadata, because the schema is the structure the AI needs to understand, not the data. The desktop app exposes a per-data-source toggle for schema-to-LLM transmission, and each transmission is recorded so you can audit it. If your schema itself encodes business secrets (KYC tables, regulatory codes, internal product names), disable the toggle for that data source. See trust for the full data-path map.
No — by design. The Console is the path for authorized humans running queries. The engineer at the keyboard is the inspector. Masking applies on the agent result path (MCP, Skill, agent CLI). If you do not want a given user to see raw values, control access at the data source itself, not at the Console.
Free desktop app on macOS, Windows, and Linux. Self-hosted Enterprise Edition for production deployments.