You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 34a0aeb
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: apps/sim/content/library/postgres-mcp-server-ai-agents/index.mdx
+16-3Lines changed: 16 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -208,14 +208,27 @@ USING (tenant_id = app_current_tenant_id());
208
208
209
209
The helper returns `NULL` when the setting is missing, empty, or not a UUID, so the policy matches no rows instead of raising a cast error.
210
210
211
+
A view normally reads its base tables with its owner's privileges and row-security context, not the caller's, so a policy scoped to `agent_reader` does not protect a curated view owned by an administrator. On PostgreSQL 15 or later, create agent-facing views with `security_invoker` so the policy applies to the querying role, and grant that role `SELECT` only on the base-table columns each view exposes:
212
+
213
+
```sql
214
+
CREATEVIEWagent_api.agent_memory_summary
215
+
WITH (security_invoker = true) AS
216
+
SELECT tenant_id, memory_id, summary, created_at
217
+
FROM agent_memory;
218
+
219
+
GRANTSELECT (tenant_id, memory_id, summary, created_at) ON agent_memory TO agent_reader;
220
+
GRANTSELECTONagent_api.agent_memory_summary TO agent_reader;
221
+
```
222
+
211
223
Use this tenant-isolation checklist:
212
224
213
225
1. Derive tenant identity from authenticated server-side context, never from a model argument.
214
226
2. Set tenant context locally inside the same transaction as the query when using connection pooling.
215
227
3. Connect through a non-owner role without superuser or `BYPASSRLS` privileges.
216
-
4. Enable and force row-level security on every tenant-scoped table the role can query.
217
-
5. Make missing or invalid tenant context return no rows.
218
-
6. Test with at least two tenants and confirm that neither can read or infer the other's records.
228
+
4. Create every agent-facing view with `security_invoker = true` so row-level security evaluates the querying role.
229
+
5. Enable and force row-level security on every tenant-scoped table the role can query.
230
+
6. Make missing or invalid tenant context return no rows.
231
+
7. Test with at least two tenants and confirm that neither can read or infer the other's records.
219
232
220
233
PostgreSQL explains policy behavior and role exceptions in its [row security documentation](https://www.postgresql.org/docs/current/ddl-rowsecurity.html). Views and MCP tool filters can narrow the interface further, but PostgreSQL should make the final row-level access decision.
0 commit comments