Column-Level Security in the AI Era: Why Row Filters Are Not Enough When Agents Query Your Data

Column-Level Security in the AI Era: Why Row Filters Are Not Enough When Agents Query Your Data

Row-level security decides which rows an AI agent sees. It says nothing about which columns the agent may combine, and combinations are where salary bands, health inferences, and identities leak. A worked attack and a control checklist for AI workloads.

By

Billy Allocca

Table of Contents

Column-Level Security in the AI Era: Why Row Filters Are Not Enough When Agents Query Your Data

Column-level security controls which fields a subject reads in clear text, masked, or at all, evaluated on every query regardless of the engine or agent that produced it. Row-level security only restricts which records return. Because AI agents that generate SQL exploit column combinations, enterprises need dynamic masking, column-group attribute-based policies, and one enforcement point across all engines.

The European Data Protection Board adopted Guidelines 01/2025 on pseudonymisation on 16 January 2025. Paragraph 22 states that pseudonymised data attributable to a person "by the use of additional information" remains personal data, and paragraph 101 names attribute combinations such as demographics, role, and income as quasi-identifiers [1]. A quasi-identifier is a column that identifies a person only in combination with other columns. Latanya Sweeney's 2000 study found 87% of the US population (216 million of 248 million people) likely unique on five-digit ZIP, sex, and date of birth [3], and Rocher, Hendrickx, and de Montjoye showed in Nature Communications in 2019 that 15 demographic attributes make 99.98% of Massachusetts residents unique [2]. Every one of those attributes is a column a row filter returns. The post on one governance model for data and AI is the companion to this guide.

What Is the Difference Between Row-Level Security and Column-Level Security?

Row-level security answers "which records," column-level security answers "which fields and in what form," and column-group attribute-based access control answers "which fields together, for whom." Only the third addresses inference.

Row-level security (RLS) is a predicate the engine appends to every query so a subject receives only rows matching a condition such as region = 'WEST'. Column-level security (CLS) is a per-column decision to return the true value, a transformed value, or nothing. Attribute-based access control (ABAC), per NIST SP 800-162, determines authorization "by evaluating attributes associated with the subject, object, requested operations, and, in some cases, environment conditions against policy" [5]. Applied to column groups, one policy on a classification such as PII_DIRECT masks every column carrying it for every role lacking the matching attribute.

Control

What it evaluates

What it stops

What it does not stop

Row-level security

A predicate on each row

Reads outside the agent's customer subset, region, or tenant

Inference from the columns of permitted rows

Column-level security (grant or dynamic mask)

Each column, per subject, at query time

Clear-text reads of a named field such as ssn

Correlation across individually unremarkable columns

Column-group ABAC

Subject, classification, action, and environment together

Reads of any column tagged with a class the subject lacks, including columns added later

Leakage through columns never classified, so cataloging comes first

How Can an AI Agent Bypass Row Filters Through Column Correlation?

An agent that stays inside its row filter the entire time can still produce salary bands and protected-category inferences for identifiable people, because the leak lives in the joins and group-bys. The retail-banking schema below is illustrative, but each column appears in typical core-banking and CRM tables.

A customer-success agent's service account carries a Ranger row filter of region = 'WEST' on customers and transactions. Name and account number are masked. Its task is "find at-risk West-region customers and recommend a retention offer."

Column

Table

Classification as written

What it yields in combination

zip5

customers

Location, unrestricted

Quasi-identifier (Sweeney's first attribute)

birth_date

customers

Demographic, unrestricted

Quasi-identifier (Sweeney's second attribute)

sex

customers

Demographic, unrestricted

Quasi-identifier (Sweeney's third attribute)

employer_name

customers

Business, unrestricted

Collapses remaining groups to one person; anchors a pay band

deposit_amount

transactions

Financial, unrestricted

Recurring amount times frequency equals net salary

deposit_frequency

transactions

Operational, unrestricted

Pay cadence

merchant_category_code

transactions

Operational, unrestricted

Pharmacy, clinic, and place-of-worship codes expose health and religion

  1. The agent runs SELECT employer_name, deposit_frequency, AVG(deposit_amount) FROM customers JOIN transactions USING (customer_id) WHERE txn_type = 'PAYROLL' GROUP BY 1, 2. The row filter passes. No column named "salary" exists, yet the agent now holds net pay bands for every employer in the region.

  2. The agent groups the same rows by zip5, EXTRACT(YEAR FROM birth_date), sex, and employer_name. Sweeney's 87% applies before the employer column is added [3]; with it, most groups contain one person.

  3. The agent profiles each near-unique group by merchant_category_code frequency over 12 months. Recurring pharmacy codes become a health feature; recurring donations to religious organizations become an affiliation feature. GDPR Article 9 treats both as special categories, and neither field was labeled sensitive because the codes were operational metadata.

  4. The agent writes a ranked "retention priority" list to a shared workspace, ordered by inferred income and annotated with inferred life circumstances. Every query cleared the row filter, none touched a masked column, and the audit log shows legitimate aggregation.

Column-level controls stop each step: band deposit_amount for the agent's role (step 1 loses precision), reduce birth_date to year and zip5 to three digits (step 2 stops producing singletons), and mask merchant_category_code to a top-level category for non-fraud roles (step 3 loses its content). NIST SP 800-188 lists these generalization and suppression transforms as standard de-identification technique [14].

Why Does Column-Level Security Matter More for AI Agents Than for Human Analysts?

Human analysts write a small, predictable set of queries against designed views; agents write whatever SQL the task and schema suggest, so the control has to sit on the columns, where query shape is irrelevant. Spider 2.0, the enterprise text-to-SQL benchmark published at ICLR 2025, drew 632 tasks from real BigQuery and Snowflake databases "often containing over 1,000 columns" and found agents had to "generate multiple SQL queries with diverse operations, often exceeding 100 lines" [6]. The strongest model tested, o1-preview, completed 21.3% of those tasks against 91.2% on Spider 1.0 [6]. Agents explore the schema widely when the task is hard, and they fail in ways their authors did not script.

OWASP's LLM02:2025 (Sensitive Information Disclosure) lists least-privilege data access as a primary mitigation and warns that application-level restrictions "may not always be honored" under prompt injection [7]. So the policy enforcement point, the component that intercepts a request and applies the access decision, has to be the query engine or the layer in front of it. The guides on what multi-agent systems need from the data layer and the MCP trust problem cover the identity half.

What Does Data Masking for AI Agents Look Like in Practice?

Every major engine offers dynamic masking; the implementations differ in where the policy lives and how far it travels. Dynamic data masking transforms a column's value at query time based on who is asking, so different roles see different results from the same stored data.

Apache Ranger's masking policies support partial masks such as last-four-digits, date-to-year, nullification, hashing, and custom expressions [8]. The Trino Ranger plugin, bundled from Ranger 2.5.0, "supports column-masking, row-filtering and audit logging" [11], and the Apache Kyuubi AuthZ plugin applies the same policies to Spark SQL [12]. Ranger tag-based policies let one policy for a tag such as PII cover every tagged resource across services [13], the mechanism behind column-group ABAC. Snowflake applies a schema-level masking policy "to the column at every location where the column appears" [9]; BigQuery checks taxonomy policy tags against the Fine-Grained Reader role on views, copies, and time-travel queries [10]. Both stop at their own boundary, and the gap opens when the same table also lives in an Iceberg lake read by Spark and Trino.

Checklist for column-level policy on AI workloads:

  • Dynamic masking on every direct identifier and financial column, mask type chosen per role (band, hash, last four, year only).

  • Redaction by default for columns no agent role needs, lifted per role.

  • Column-group policies attached to catalog classifications, so a new column inherits its group's mask when tagged.

  • Quasi-identifier generalization (ZIP to three digits, birth date to year) for every role without a documented need for the full value.

  • Engine-independent enforcement: the same policy object evaluated for Trino, Spark, Kyuubi, notebooks, and direct object-storage reads.

  • Query logging of subject, columns touched, masks applied, and row count, retained long enough to reconstruct an inference chain.

GDPR Article 32(1)(a) names pseudonymisation as a security measure [15], and the EDPB adds that it counts only when the information that reverses it is protected too [1]. Masking one column while its quasi-identifier neighbors stay in clear text fails that test.

Why Not Just Put Row-Level Security on the Warehouse?

Row-level security on the warehouse is necessary, and it does what it was designed for: tenant and territory isolation. It fails AI workloads on two structural counts.

First, a row filter is blind to correlation. Denning, Denning, and Schwartz showed in 1979 that a statistical database enforcing query-set-size limits could still be compromised through "tracker" formulas that recover an individual's confidential value from a few aggregate answers [4]. The scenario above is that attack with an LLM composing the formulas. Second, the warehouse is one of several enforcement points. Agents also read the Iceberg lake, operational replicas, and vector stores built from all three, and a filter written in one engine's syntax does not follow a Parquet file an agent reads directly from a bucket. The guide on policy-as-code for AI data access covers keeping definitions from diverging.

NexusOne Enforces Column Policy Once Across Every Engine and Agent

NexusOne applies column masking and row filtering from a single Apache Ranger policy to Trino, Apache Spark, Apache Kyuubi, and S3 object storage per object at the same time, so the mask an agent receives does not depend on which engine its SQL reached. Identity arrives from Active Directory, Okta, LDAP, or SAML through one Keycloak layer, and agents authenticate as users, groups, and roles in the same tenant-scoped model as people. Tag a column group as PII_DIRECT in DataHub, map roles to tags, and masking policies generate in Ranger at bucket, schema, and table level; a new column joining the group inherits them.

The AI & Data Control Plane classifies each agent or MCP request before any engine runs it, blocks jailbreak and PII-exfiltration attempts with the reason logged, redacts PII before egress to a frontier model, applies per-role token budgets, and records every request. The stack runs identically on-prem, cloud, hybrid, or air-gapped on open formats such as Iceberg, and is currently the data and AI layer for a Top 3 US bank. The post on one control plane for enterprise AI governance covers the routing layer. To review your column classifications and agent roles, book an expert consultation.

Key Takeaways

  • Row-level security limits which records an agent sees and has no view of what the agent infers by combining the columns in those records.

  • ZIP, sex, and date of birth identify 87% of Americans, and 15 demographic attributes identify 99.98%, so quasi-identifiers must be masked or generalized alongside direct identifiers.

  • Agents generating SQL against thousand-column schemas produce query shapes no one reviewed, which makes the column the only stable place to enforce policy.

  • Column-group ABAC attaches one policy to a classification tag so every column in the group, including columns added later, is masked for roles lacking the attribute.

  • Enforcement must be engine-independent; a mask defined only in the warehouse does not follow the data into Spark, Kyuubi, or a direct object-storage read.

FAQ

What Is Column-Level Security for AI Workloads on Enterprise Data?

Column-level security is a per-field access decision, evaluated at query time, that returns a column in clear text, in masked or generalized form, or not at all depending on the subject's role and attributes. It matters for AI because agents write exploratory SQL that combines columns in ways no analyst planned, and inference from column combinations is the dominant leak path. It complements row-level security, which only restricts which records return.

How Does Fine-Grained Access Control Work on an AI Data Platform?

Fine-grained access control combines row filters, column masks, and attribute conditions into policies attached to data classifications, so one policy covers every table carrying the class. The policy engine intercepts every query, from a person or an agent, resolves the subject's role, and rewrites the query so filtered rows are excluded and sensitive columns arrive masked. Apache Ranger does this with row-filter, data-masking, and tag-based policies across Trino, Spark, and Kyuubi [8][11][12][13].

How Should Enterprises Apply Data Masking to AI Agents?

Give each agent a service identity in the same identity model as human users, assign a role with the minimum column attributes its task needs, and apply dynamic masks by default: bands for amounts, year-only for dates, three-digit ZIP, hashes for identifiers. Attach masks to classification tags so new columns inherit them. Enforce at the query engine and object storage, because OWASP notes prompt-level restrictions can be bypassed [7], and log columns and masks per request.

What Is Attribute-Based Access Control in a Data Warehouse?

Attribute-based access control decides authorization by evaluating attributes of the subject (role, department, clearance), the resource (classification tag, sensitivity level), the action, and the environment against a policy, as NIST SP 800-162 defines it [5]. In a warehouse this means tagging columns with classifications and writing policies such as "roles without FINANCIAL_CLEAR see deposit_amount as a band," so one policy governs every table and every new column carrying the tag.

References

  1. Guidelines 01/2025 on Pseudonymisation, European Data Protection Board, adopted 16 January 2025. https://www.edpb.europa.eu/system/files/2025-01/edpb_guidelines_202501_pseudonymisation_en.pdf

  2. Estimating the success of re-identifications in incomplete datasets using generative models, Rocher, Hendrickx, and de Montjoye, Nature Communications, 2019. https://www.nature.com/articles/s41467-019-10933-3

  3. Simple Demographics Often Identify People Uniquely, Latanya Sweeney, Carnegie Mellon University Data Privacy Working Paper 3, 2000. https://dataprivacylab.org/projects/identifiability/paper1.pdf

  4. The Tracker: A Threat to Statistical Database Security, Denning, Denning, and Schwartz, ACM Transactions on Database Systems, March 1979. https://faculty.nps.edu/dedennin/publications/TrackerThreat.pdf

  5. SP 800-162, Guide to Attribute Based Access Control (ABAC) Definition and Considerations, NIST, 2014 (updated 2019). https://csrc.nist.gov/pubs/sp/800/162/upd2/final

  6. Spider 2.0: Evaluating Language Models on Real-World Enterprise Text-to-SQL Workflows, Lei et al., ICLR 2025 (arXiv 2411.07763). https://arxiv.org/abs/2411.07763

  7. LLM02:2025 Sensitive Information Disclosure, OWASP Top 10 for LLM Applications. https://genai.owasp.org/llmrisk/llm022025-sensitive-information-disclosure/

  8. Row-level filtering and column-masking using Apache Ranger policies in Apache Hive, Apache Ranger wiki. https://cwiki.apache.org/confluence/display/RANGER/Row-level+filtering+and+column-masking+using+Apache+Ranger+policies+in+Apache+Hive

  9. Understanding Dynamic Data Masking, Snowflake Documentation. https://docs.snowflake.com/en/user-guide/security-column-ddm-intro

  10. Introduction to column-level access control, BigQuery Documentation, Google Cloud. https://docs.cloud.google.com/bigquery/docs/column-level-security-intro

  11. Ranger access control, Trino Documentation. https://trino.io/docs/current/security/ranger-access-control.html

  12. Kyuubi Spark AuthZ Plugin Overview, Apache Kyuubi Documentation. https://kyuubi.readthedocs.io/en/master/security/authorization/spark/overview.html

  13. Tag Based Policies, Apache Ranger wiki. https://cwiki.apache.org/confluence/display/RANGER/Tag+Based+Policies

  14. SP 800-188, De-Identifying Government Datasets: Techniques and Governance, NIST, September 2023. https://csrc.nist.gov/pubs/sp/800/188/final

  15. Article 32 GDPR, Security of processing, gdpr-info.eu. https://gdpr-info.eu/art-32-gdpr/

ABOUT

1115 Howell Mill Rd
Suite 430,
Atlanta, GA 30318
An Insight Partners Company


Product Updates and News

@2026 NexusOneยฎ - All rights reserved.

ABOUT

1115 Howell Mill Rd
Suite 430,
Atlanta, GA 30318
An Insight Partners Company


Product Updates and News

@2026 NexusOneยฎ - All rights reserved.

ABOUT

1115 Howell Mill Rd
Suite 430,
Atlanta, GA 30318
An Insight Partners Company


Product Updates and News

@2026 NexusOneยฎ - All rights reserved.