| → / Space | Next slide |
| ← | Previous slide |
| Home | First slide |
| End | Last slide |
| Swipe | Touch navigation |
Companion to token fundamentals. That covers how you get the token; this covers what each resource enforces once it arrives.
1. OAuth scopes — what they control, the endpoint vs scope confusion, M2M vs OBO tokens
2. Serving endpoints, Genie Agents, Vector Search — identity model for each
3. UC Functions and HTTP Connections — safe boundaries for writes and external systems
4. Tables — row filters, column masks, current_user() vs is_member()
5. Lakebase — PostgreSQL-native grants and RLS, not Unity Catalog
6. Decision guide and production-readiness checklist
Before you trust the result, know: which endpoint issued the token, which resource is enforcing it, and what identity it sees.
| Resource | Path | current_user() | #1 gotcha |
|---|---|---|---|
| Serving Endpoints | OBO or M2M | Human (OBO) / SP (M2M) | ModelServingUserCredentials() only in serving context |
| Genie Agents | OBO | Human email | Both genie + dashboards.genie scopes required |
| Vector Search | M2M | App SP UUID | No native OBO — apply pre/post-filter in app layer |
| UC Functions | Inherits caller | Caller identity | Grant EXECUTE, never INSERT/UPDATE on table directly |
| HTTP Connections | M2M + auth | Databricks side only | Only U2M Per User / Managed OAuth pass identity to external service |
| Tables | Any | Caller identity | is_member() breaks in Genie Agents + Agent Bricks OBO |
| Lakebase | M2M | SP client ID (PG role) | PG GRANT + RLS, not UC policy |
Authorization: Bearer {token} headerModelServingUserCredentials() extracts user identitymodel-servingModelServingUserCredentials() only works in Model Serving context. In Databricks Apps, it silently falls back to SP credentials — wrong identity, no error.
Fix: In apps, read X-Forwarded-Access-Token and pass explicitly to the endpoint.
Authorization: Bearer {user_token}genie AND dashboards.genie scopes required (UI doesn't show both)current_user() = caller human emailis_member() = Genie Agents execution service (not the caller)App integration UI lists only dashboards.genie. Genie Agents API checks for both. Missing genie scope = 403 with cryptic error.
Fix: Add both scopes via account API or CLI, not the UI.
CAN_SELECT on the indexWorkspaceClient() auto-discovers SP credentialsvector-searchcurrent_user() = App SP UUID (not per-user)No native per-user identity. Vector Search returns the same top-K to all users. Per-user access is your responsibility.
| Pre-filter | Include user/group metadata in index, filter in query. Fast but requires data enrichment. |
| Post-filter | App retrieves results, checks each against user ACL. Flexible, uses retrieval budget. |
| Shared KB | M2M as-is: everyone sees same docs, no filtering needed. |
CREATE FUNCTION prod.auth.approve( deal_id STRING ) RETURNS STRING LANGUAGE SQL RETURN ( UPDATE prod.sales.deals SET status = 'approved' WHERE id = deal_id AND current_user() IN ( SELECT email FROM prod.sales.approvers ) );
| Agent SP | Has EXECUTE on function only |
| Agent SP | NO UPDATE/INSERT on table |
| Function | Checks current_user() internally |
| Audit log | Function calls appear in system.access.audit |
Function is the authorization boundary. Agent never has direct write access.
| Method | External sees | Use case |
|---|---|---|
| Bearer Token | Shared static token | Simple integrations, static API keys |
| OAuth M2M | Shared app credentials | Service-to-service at org level |
| OAuth U2M Shared | One admin's delegated token | Shared admin access |
| U2M Per User | User's own identity ✓ | As the user (Jira, GitHub, etc.) |
| Managed OAuth | User's own identity ✓ | Google, Microsoft Graph — Databricks handles OAuth flow |
Kill switch. REVOKE USE CONNECTION immediately blocks agent access — no redeploy needed.
No granular scopes. UC controls WHO can use connection. For different operations (read vs write), create separate connections with different credentials.
| Access path | current_user() | is_member() |
|---|---|---|
| Notebook | Human ✓ | Human groups ✓ |
| App SQL (OBO) | Human ✓ | Human groups ✓ |
| Genie Agents (OBO) | Human ✓ | Genie Agents service ✗ |
| Agent Bricks (OBO) | Human ✓ | Agent service ✗ |
Rule: Use current_user() everywhere. It works in all paths. is_member() breaks silently in Genie Agents and Agent Bricks OBO — no error, just wrong rows.
postgres (for management API only)Direct PG connection: PG roles + GRANT + RLS enforce access.
Via lakehouse API: Unity Catalog policies apply.
Same table. Different authorization model per access path.
A row filter using is_member() in Genie Agents leaks data silently — no error, just wrong rows to the wrong user.
Lakebase data behind both UC and PG policies. Auditors need to know which layer enforced which control. You need to know too.
UC Function as authorization boundary means every new agent gets the same safety boundary without re-derivation.
Authorization lives at the resource. The right token path is only the first check. Know which resource enforces which control.
Serving Endpoints, Genie Agents, Vector Search, Functions, HTTP Connections, Tables — UC + scopes.
Lakebase — PG GRANT + RLS, not UC.
Yes — U2M Per User or Managed OAuth connection.
No — Bearer token or M2M OAuth.
Yes — UC Function with EXECUTE grant (boundary for writes).
No — Row filters and column masks on the table.
| Resource | Checklist item |
|---|---|
| Serving Endpoints | Use ModelServingUserCredentials() inside Model Serving only. From apps, read X-Forwarded-Access-Token header explicitly. |
| Genie Agents | Both genie + dashboards.genie scopes present (add via CLI, not UI). Row filters use current_user(), not is_member(). |
| Vector Search | Pre-filter or post-filter implemented in application — M2M SP retrieval returns same results to all users by default. |
| UC Functions | Agent SP has EXECUTE only. No INSERT/UPDATE/DELETE direct on table. Grant is on the function. |
| HTTP Connections | Connection owner = app SP. GRANT USE CONNECTION re-run after each redeploy (new SP = new grants needed). |
| Tables | Row filter audit: grep for is_member(), especially if table queried via Genie Agents. Use current_user() instead. |
| Databricks Apps | Apps declare least-privilege user API scopes (e.g. sql, files, genie, ai-gateway) for OBO user authorization calls. M2M app identity (service principal) handles background operations. Scope consent is managed by admins. Both identity models share UC governance rules. |
| Lakebase | PG GRANT and RLS policies configured per table. Do NOT assume UC row filters apply to direct PG connections. |