How do I enforce RBAC for AI agents accessing a database?
Traditional RBAC binds permissions to a user. With LLM agents, the meaningful subject is the *(user, agent, request)* tuple — the same DB connection is reused across users, and the agent's intent varies per request. The defensible pattern:
1. Per-agent DB role. reporting_agent role with SELECT on views.reporting_* only. Never share roles across agents.
2. Request-scoped context. On every request, set app.user_id, app.tenant_id, app.agent_id as session variables. RLS policies and the AST policy engine reference these.
3. Per-agent policy file. A declarative policy per agent specifying allowed tables, required predicates, allowed statement types, max row count.
4. Deny by default. Unknown table in AST → reject. Unknown column → reject. No WHERE on a sensitive table → reject.
QueryShield's policy DSL is YAML/JSON, version-controlled, and evaluated per request. The policy engine sees the AST + the request context and renders a single decision: allow, reject, or rewrite (e.g., inject the missing tenant_id predicate).