Skip to content

CONCEPT Cited by 1 source

Session identity evaluation (for views and functions)

What it is

Session identity evaluation is the rule that policies inside a SQL view or function evaluate against the identity of the user running the outer query — not the identity of the view creator — when looking up current_user(), current_user_groups(), or any attribute-based access-control predicate that depends on the calling principal.

The flag matters because the natural SQL evaluation model is the opposite: a view acts as a stored query, and stored queries historically execute with the privileges (and identity context) of the creator. Without an explicit session-identity rule, per-user masks and per-user row filters defined inside views silently resolve every caller to the same identity (the creator's), defeating the access control.

The view-as-bypass failure mode

-- Without session identity evaluation:
CREATE VIEW customers_redacted AS
  SELECT
    name,
    CASE
      WHEN current_user() IN (SELECT user FROM compliance_team)
      THEN ssn
      ELSE mask(ssn)
    END AS ssn
  FROM customers;
-- view created by alice, who IS in compliance_team

-- Bob (not in compliance_team) queries the view:
SELECT * FROM customers_redacted;
--   `current_user()` resolves to ALICE (the creator)
--   compliance_team check passes
--   Bob sees real SSNs.   ← FAILURE

Equivalent failure exists with row filters: a view filtering rows based on current_user()'s region resolves the region for the creator, not the caller.

The fix

Under session identity evaluation, the view-internal current_user() resolves to the caller's identity at the outer query, propagating through nested view + function calls. "ABAC policies now evaluate against the identity of the user running the query. Users see exactly what their own permissions allow them to see, even when they query through a view or function" (Source: sources/2026-05-13-databricks-abac-row-filtering-and-column-masking-policies-governed-tags).

The same query above now correctly mask SSNs for Bob and reveal them for Alice.

Why this is hard

Three reasons session-identity evaluation is non-trivial to implement:

  1. Plan reuse / caching. Query planners cache parsed plans and reuse them across users for cost reasons. Per-call identity substitution forces either per-user plan binding or identity-as-runtime-parameter at every reference point in the plan.
  2. Nested views and functions. The identity must propagate through arbitrary-depth nesting; a view calling a function that calls another view should resolve the same identity at every layer.
  3. Stored procedures and DDL contexts. Some stored-procedure contexts have legitimate need to act as the creator (e.g., privileged maintenance jobs); the language must distinguish.

Distinct from sibling primitives

  • DEFINER vs INVOKER security context (MySQL stored procedures) — the SQL-procedure-language analogue. INVOKER is the session-identity equivalent; DEFINER is the view-creator equivalent. Per-procedure or per-view configuration.
  • PostgreSQL SECURITY DEFINER vs SECURITY INVOKER — same distinction, same per-function configuration.
  • AWS IAM Principal vs Resource-based identity — adjacent but at the API authorization altitude.

The Unity Catalog framing makes session-identity the default evaluation mode for ABAC, eliminating the per-view configuration trap.

Composition with ABAC policies

Session identity evaluation is what makes ABAC policies on views behave the same as on tables. Without it, the architectural promise of "a single ABAC policy covers all matching tables" would break the moment a view is layered on top — every analyst's per-user mask would fail. With it, ABAC policies hold their semantics through arbitrary view chains.

Operational properties

  • Default-on vs opt-in: not disclosed in the source whether session identity is the default for newly created views or whether legacy views require migration.
  • Backwards compatibility: views authored before session-identity evaluation become user-scoped after the change, which can produce fewer rows / more masks for analysts using views that previously bypassed enforcement. The change is therefore a security improvement that may surface as a "my view returns less data than before" support escalation.
  • Audit clarity: current_user() in audit logs becomes the caller's identity rather than the view creator's, which is what audit reviewers actually want.

Seen in

Last updated · 542 distilled / 1,571 read