14 LAUNCHES IN 14 DAYS

SEE WHAT’S NEW

Row-Level Security for AI Agents: Permissions a Prompt Can't Override

Row-Level Security for AI Agents: Permissions a Prompt Can't Override

Row-Level Security for AI Agents: Permissions a Prompt Can't Override

All Posts

Why AI agents can't enforce their own data permissions, and how server-side row-level security isolates tenants before any query runs.

Ka Ling Wu

Co-Founder & CEO, Upsolve AI

10 min

Title card for Upsolve Row-Level Security, Feature 02 of 14 in The Complete Agent Stack

The Complete Agent Stack · Part 02 of 14 · Ontology layer

This guide is one part of a 14-part series on what a production data agent needs, from the data model it reads to the agent that keeps it accurate. Each part stands on its own, and they build on each other in order.

← Previous: Part 01: AI Agent Data Model · Next: Part 03: MCP vs SQL for Data Agents →

Row-level security for AI agents filters every query by the user's identity before it reaches the database, so the permissions hold no matter what the agent writes or what a user asks it to do.

Part 01 covered the AI agent data model that tells an agent what your data means; Part 02 covers the rules that decide which rows each person may see.

Key Takeaways

  • A system prompt is not an access control. The OWASP Top 10 for LLM Applications states that the system prompt should not "be used as a security control" and that privilege separation and authorisation checks "must not be delegated to the LLM" (OWASP LLM07).

  • Prompt injection may never be fully solved. The UK National Cyber Security Centre argues that because a language model draws no line between data and instructions, prompt injection attacks "may never be totally mitigated" (NCSC).

  • Access controls are the common gap in AI breaches. In IBM's Cost of a Data Breach research, 13% of organisations reported breaches of AI models or applications, and 97% of those said they lacked AI access controls (IBM).

  • Good row-level security fails closed. In PostgreSQL, a table with row security enabled and no policy uses a default-deny policy, so no rows are visible until a rule allows them (PostgreSQL docs).

The 45-second version:

What Is Row-Level Security for AI Agents?

Row-level security (RLS) restricts which rows of a table a given user can read. Two people can run the same query against the same table and get different results, because each query is filtered by attributes of the person running it, such as their tenant, country or role.

Diagram of The Complete Agent Stack: four layers and 14 features, with Row-Level Security highlighted in the ontology layer

For an AI agent, the stakes are higher. A data agent writes SQL on the user's behalf, often against tables that hold many customers' data. If permissions depend on the agent choosing to add the right WHERE clause, every answer depends on the model behaving correctly under every possible input. Row-level security for AI agents moves that decision out of the model and into a deterministic layer that applies the filter to every query, whoever or whatever wrote it.

The mechanism is well established in databases. PostgreSQL evaluates a policy expression "for each row prior to any conditions or functions coming from the user's query", and rows for which the expression is not true are never processed (PostgreSQL docs). Snowflake's row access policies work by creating a dynamic secure view of the table at query runtime and returning only rows where the policy evaluates to true (Snowflake docs). For agent builders, the question is where that enforcement sits.

Why Can't an AI Agent Enforce Its Own Permissions?

The simplest design puts the rules in the system prompt: "Only return data for the user's own company." It works in a demo and fails as a security model for three reasons.

First, models can be manipulated. OWASP ranks prompt injection as LLM01, its first risk for LLM applications, and states that "it is unclear if there are fool-proof methods of prevention" (OWASP LLM01). The NCSC explains the root cause: under the hood of a model there is no distinction between data and instructions, only the next token, so the strict separation of data and instructions that fixed SQL injection is not available (NCSC).

Second, the attack does not need to come from the user. Greshake and colleagues showed that LLM-integrated applications "blur the line between data and instructions", so malicious text placed in content the model later retrieves, such as a web page or document, can redirect its behaviour (Greshake et al.). A data agent that reads free-text fields, such as supplier notes or support tickets, handles untrusted input as part of its normal work.

Third, the path from prompt to SQL is itself an attack surface. Research presented at the International Conference on Software Engineering found LangChain-based applications "highly susceptible" to prompt-to-SQL injection across seven models, where crafted natural-language input leads the model to generate malicious SQL (Pedro et al.).

Even without an attacker, a model can simply be wrong. It can forget the filter on a subquery, join through a table that has no tenant column, or apply the user's region to the wrong field. A permission system that is correct only when the model is correct is a probabilistic control, which is why security frameworks do not accept it as an access control.

The guidance from security bodies converges on one principle. OWASP's advice on excessive agency is to "implement authorization in downstream systems rather than relying on an LLM to decide if an action is allowed", and to execute actions in the context of the specific user with the minimum privileges necessary (OWASP LLM06). The NCSC likewise recommends deterministic, non-LLM safeguards.

How Do You Isolate Tenant Data in a Multi-Tenant AI Agent?

Multi-tenant SaaS products usually choose between isolating tenants in separate infrastructure and pooling them in shared tables. AWS describes the pooled approach as a table "indexed by individual tenant identifiers", and notes that sharing "increases the chance for cross-tenant access", so it requires especially careful isolation (AWS). AWS also lists compliance pushback as a cost of pooling, since some customers are unwilling to share infrastructure at all.

An AI agent adds a new consumer to whichever model you choose. The question is where the tenant filter is enforced, and whether the agent can reach data without passing through it.

Enforcement point

Who applies the rule

Can a prompt get around it?

Fit for one agent serving many tenants

Main trade-off

Instructions in the system prompt

The model

Yes, through injection or simple error

Poor

No setup, but provides no guarantee

Separate database per tenant

Infrastructure

No

Strong isolation

Cost and operational work grow with every tenant

Database-native RLS

The database engine

No, when each query runs under the user's identity

Good

Needs per-user identity or session context in the database; privileged roles bypass it

Server-side pre-filter in the agent platform

The query layer, before the database

No, and the rules sit outside the agent's context

Good

Every query path must pass through the layer

Database-native RLS is a strong foundation, with one important caveat for agents. Superusers, roles with BYPASSRLS and, by default, table owners bypass PostgreSQL policies (PostgreSQL docs). If the agent connects through a single privileged service account, the database sees one user and the policies never fire. A platform-level pre-filter solves this by attaching the end user's identity to each query before it leaves the application, and the two approaches can be layered.

How to Design Row-Level Security Rules for an AI Agent

Good RLS for agents starts with identity and ends with testing. The rules themselves are usually short.

Model Users and Organisations with Properties

Every rule needs something to compare against. Register organisations and users, and give them properties such as tenant, country, region or role. Organisation properties describe a whole customer or team, and user properties describe the individual. Keep these properties in a system the agent cannot edit.

Write Global Rules Where Columns Repeat

Most schemas reuse the same filtering columns across many tables, such as tenant_id, country or region. A global rule such as "the country column must equal user.country" can apply automatically to every table that has that column. This prevents a common mistake: a new table that nobody remembered to protect.

Use Custom SQL Rules for Joins and Exceptions

Some tables have no direct tenant column. A line-items table may only be linked to a tenant through its order, or a supplier may belong to a region through a mapping table. These cases need a table-specific rule written in SQL that performs the join and reads the user's property. Snowflake's documentation describes the same pattern with mapping tables and recommends keeping them centralised alongside the protected table (Snowflake docs).

Decide What Happens When a Property Is Missing

How to treat a user without a country property is a design decision that deserves an explicit answer. A rule can be optional, so a missing property skips it, or required, so a missing property blocks the data entirely. Tables that hold sensitive or tenant-specific data should fail closed, in line with PostgreSQL's default-deny behaviour. Tables that genuinely hold shared reference data can have no rule by design, as long as that choice is visible.

Test as Real Users Before Anything Ships

The best evidence that RLS works is the final SQL. For any query, a builder should be able to choose a user, see that user's properties, and read the exact WHERE clause that will be applied. Testing as several users with different properties catches rules that are too broad as well as rules that block too much.

Cover Every Surface the Agent Publishes To

Agents publish answers in many places: chat, dashboards, scheduled reports, apps and connections to other assistants. A dashboard built by one user and opened by another must re-run under the viewer's permissions, or a shared link becomes a way around the rules. This matters for the later guides on AI-generated dashboards and governed data in Claude.

PostgreSQL's documentation adds one subtle warning. Referential integrity checks such as unique and foreign-key constraints always bypass row security, so schemas should be designed to avoid "covert channel" leaks through those checks (PostgreSQL docs). The risk is small for read-only analytics agents and grows once an agent can write data.

What Should a Security Review See Before an Agent Ships?

Security reviews tend to stall AI projects when nobody can show exactly what each user is able to see. IBM's research suggests the concern is justified: of the organisations that reported a breach of an AI model or application, 97% lacked AI access controls, and 60% of AI-related incidents led to compromised data (IBM).

A review moves faster when the team can answer five questions with evidence:

  1. Where is the filter applied? Show that every query, whether written by the agent or by a person, passes through the same enforcement point before reaching the database.

  2. Can the agent see or change the rules? Show that rules live outside the agent's context and that the agent cannot edit user properties.

  3. What happens when identity data is missing? Show which rules are required and which are optional, and why.

  4. What does a specific user actually get? Show the generated WHERE clause for representative users in different tenants.

  5. Do shared outputs respect the viewer? Show that dashboards, reports and connected assistants re-run under the viewer's own permissions.

Answers are most convincing when demonstrated live. Logging the applied filter with each query also gives auditors a trail, a topic for our guide on AI agent observability.

How Upsolve Approaches Row-Level Security for AI Agents

Upsolve enforces row-level security server side, as a pre-filter applied before any query reaches your database. The same rules apply whether the agent generated the SQL or a person wrote it by hand, and the agent never sees them. This keeps deterministic security separate from the agentic parts of the system, which can keep learning and changing without touching who can see what.

The setup follows the pattern above. In our procurement demo project, organisations such as supplier managers and vendors are registered with properties like country, and users carry their own properties. Rules live in a data security tab on the data model. A global rule such as country = user.country applies to every table with a country column, and Upsolve shows exactly which tables it will affect. Each rule can be optional or required.

The demo also shows the exceptions. The sample contracts table has neither a country nor a supplier country column, so zero of the two global rules apply to it, which can be a deliberate choice for shared data. The suppliers table uses a custom SQL rule instead, the right tool when a filter needs a join to read the user's property from another table.

Testing happens as a specific user. Viewing the data as Grace Tan, a sample user, the engine adds a filter limiting country to India, Australia, Singapore and Japan. Switching to Carlos Ruiz, a sample user based in Brazil, the same query returns a single supplier from São Paulo, with a WHERE clause limited to Brazil. Live views on shared canvases re-run under the viewer's own permissions, so one agent can serve many tenants, each seeing only their own rows.

As Serguei Balanovich, Upsolve, explains in the demo: "The agent never even sees these rules, because we want a clear separation between agentic workflows and deterministic workflows."

Frequently Asked Questions

What is row-level security for AI agents?

Row-level security for AI agents is a set of rules that filter each query by the identity of the person asking, so an agent can only return rows that person is allowed to see. The filter is applied by a deterministic layer, either the database or a query layer in front of it, instead of by the model. That way the permissions hold even if the agent writes unexpected SQL, misreads an instruction or is targeted by prompt injection. It is the standard way to put one agent in front of many users or tenants safely.

Can prompt injection bypass row-level security?

Not if the rules are enforced outside the model. Prompt injection changes what the model writes, so it can defeat permissions that live in the system prompt. It cannot remove a filter that a database or query layer adds after the model has produced its SQL, provided every query passes through that layer and the agent cannot edit user properties or rules. OWASP and the UK NCSC both recommend this design: assume the model can be manipulated, and put authorisation in deterministic systems downstream of it.

How do you isolate tenant data in a multi-tenant AI agent?

Give every user a tenant property, then apply a rule on every table that compares the table's tenant column with that property. For tables without a direct tenant column, write a custom rule that joins to a table that has one. Make tenant rules required, so a user with no tenant sees nothing. Finally, test as users from several tenants and confirm the generated WHERE clause for each. Separate databases per tenant also work, but cost and operational effort grow with every customer you add.

Is database-native row-level security enough for an AI agent?

It can be, if every agent query runs under the end user's own identity. Many agent architectures connect through a single service account, and in PostgreSQL superusers, roles with the BYPASSRLS attribute and table owners bypass row security by default. In that setup the database sees one privileged user and its policies never apply. A pre-filter in the agent platform, which attaches the end user's properties to each query, closes that gap. The two approaches can be combined for defence in depth.

What should happen when a user is missing a required property?

Decide per rule. For tenant-specific or sensitive data, the safe default is to block access entirely, so a user without the property sees no rows from that table. For rules that narrow an already-safe view, such as an optional regional filter, skipping the rule may be acceptable. The important thing is that the behaviour is explicit and visible to reviewers. A silent default that returns all rows when a property is missing lets row-level security fail without anyone noticing.

Does row-level security apply to dashboards an agent creates?

It should. When an agent builds a dashboard or report and someone shares it, the live data must re-run under the viewer's permissions instead of the author's. Otherwise, a user with broad access can share a view that exposes rows a colleague or customer should never see. Check this for every surface the agent publishes to, including scheduled reports, embedded apps and connections to other assistants as well as the chat window.

Sources

  1. OWASP Gen AI Security Project: LLM01:2025 Prompt Injection. https://genai.owasp.org/llmrisk/llm01-prompt-injection/

  2. OWASP Gen AI Security Project: LLM06:2025 Excessive Agency. https://genai.owasp.org/llmrisk/llm062025-excessive-agency/

  3. OWASP Gen AI Security Project: LLM07:2025 System Prompt Leakage. https://genai.owasp.org/llmrisk/llm072025-system-prompt-leakage/

  4. UK National Cyber Security Centre: Prompt injection is not SQL injection (it may be worse). https://www.ncsc.gov.uk/blog-post/prompt-injection-is-not-sql-injection

  5. arXiv / Greshake et al.: Not what you've signed up for: Compromising Real-World LLM-Integrated Applications with Indirect Prompt Injection. https://arxiv.org/abs/2302.12173

  6. ICSE / Pedro et al.: From Prompt Injections to SQL Injection Attacks: How Protected is Your LLM-Integrated Web Application? https://arxiv.org/abs/2308.01990

  7. PostgreSQL Documentation: Row Security Policies. https://www.postgresql.org/docs/current/ddl-rowsecurity.html

  8. Snowflake Documentation: Understanding row access policies. https://docs.snowflake.com/en/user-guide/security-row-intro

  9. AWS Whitepaper: SaaS Tenant Isolation Strategies, Pool isolation. https://docs.aws.amazon.com/whitepapers/latest/saas-tenant-isolation-strategies/pool-isolation.html

  10. IBM Newsroom: IBM Report: 13% of Organizations Reported Breaches of AI Models or Applications, 97% of Which Reported Lacking Proper AI Access Controls. https://newsroom.ibm.com/2025-07-30-ibm-report-13-of-organizations-reported-breaches-of-ai-models-or-applications,-97-of-which-reported-lacking-proper-ai-access-controls

Put one agent in front of every customer, with permissions it can't talk its way past. Start free at upsolve.ai with 2,000 free AI credits and test your first rules as any user. Working through a security review? Talk to our team. Read more about Upsolve Row-Level Security, and continue with Part 03: MCP vs SQL for Data Agents.

Try Upsolve for Embedded Dashboards & AI Insights

Embed dashboards and AI insights directly into your product, with no heavy engineering required.

Fast setup

Built for SaaS products

30‑day free trial

See Upsolve in Action

Launch customizable dashboards and AI‑powered insights inside your app, fast and with minimal engineering effort. No code.

Follow us

Related Articles

Stop answering the same 10 questions today.

The Platform for Accurate, Reliable, and Trustworthy AI Analytics.

Agent Studio for Data Teams. Encode context. Deploy agents. Deliver clarity.

© 2026 Upsolve AI, Inc.  

|