Agent SQL RBAC Filtering
Audience: security and API contributors designing future authorization-aware SQL filtering. Start with Security, Privacy, And Retention for current user-facing security guidance.
Agent SQL access is powerful and must not bypass Kubernetes RBAC.
The current PoC exposes read-only SQL for local development. Before this is served to untrusted users, API and MCP queries must be rewritten or constrained so every returned row is authorized for the caller.
An agent can ask flexible SQL questions, but the answer contains only resources,facts, changes, edges, and versions the caller could read through Kubernetes.Enforcement Shape
Section titled “Enforcement Shape”Use three layers:
- Authenticate the caller and resolve Kubernetes user, groups, extras, and target cluster.
- Build an authorization scope from Kubernetes SelfSubjectAccessReview or SubjectAccessReview results.
- Execute SQL through authorized views or a query rewriter, never directly against base tables for remote users.
Authorized Object View
Section titled “Authorized Object View”Every query should be constrained by authorized object IDs:
authorized_objects(object_id)That set is built from resource permissions:
list pods in namespace default -> all matching Pod objects in defaultget pod default/api-1 -> only that Pod objectget nodes cluster-scope -> matching Node objectsThe base view is:
select o.idfrom objects ojoin object_kinds ok on ok.id = o.kind_idjoin api_resources ar on ar.id = ok.api_resource_idjoin clusters c on c.id = o.cluster_idwhere allowed(c.name, ar.api_group, ar.resource, o.namespace, o.name)allowed(...) is conceptual. SQLite PoC can materialize a temp table. Postgres
and Cockroach can use session-local temp tables, CTEs, or security-barrier
views.
Table Rules
Section titled “Table Rules”| Table | Filter rule |
|---|---|
latest_index | object_id in authorized_objects |
objects | id in authorized_objects |
versions | object_id in authorized_objects |
object_facts | object_id in authorized_objects and related object IDs if present |
object_changes | object_id in authorized_objects |
object_edges | src_id in authorized_objects and dst_id in authorized_objects |
blobs | only reachable through authorized versions.blob_ref |
filter_decisions | filter by authorized resource scope before exposing |
api_resources | safe to expose, but may reveal installed CRDs; make this policy-controlled |
ingestion_offsets | safe for operators; policy-controlled for tenant users |
SQL Interface Contract
Section titled “SQL Interface Contract”Remote API/MCP SQL must not execute arbitrary SQL against base tables. It should either:
- expose only authorized views with the same logical column names, or
- rewrite user SQL to inject joins against
authorized_objects.
The safer first version is view-based:
latest_index -> visible_latest_indexobjects -> visible_objectsversions -> visible_versionsobject_facts -> visible_object_factsobject_changes -> visible_object_changesobject_edges -> visible_object_edgesAgents can still inspect schema, but schema should describe visible views for remote identities.
Edge Leakage
Section titled “Edge Leakage”An edge leaks both endpoints. Default rule:
return edge only when src and dst are both authorizedA future UI may show a hidden endpoint marker, but SQL tools should start with strict omission.
Historical RBAC
Section titled “Historical RBAC”MVP uses current RBAC:
If the caller can read the resource now, they can read retained history for thesame object.Historical RBAC replay is future work and requires retaining RBAC state over time.