bharos commented on code in PR #11790: URL: https://github.com/apache/gravitino/pull/11790#discussion_r3494355258
########## design-docs/gravitino-role-assumption.md: ########## @@ -0,0 +1,334 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> + +# Design: Role Assumption (SET ROLE) — Narrowing Effective Permissions + +| Field | Value | +| ---------- | ------------------------------------------------------------------------- | +| Status | Draft | +| Authors | @bharos | +| Created | 2026-06-24 | +| Discussion | [#10894](https://github.com/apache/gravitino/discussions/10894) | +| Scope | Native authorization path (Iceberg REST catalog + native Gravitino API) | + +--- + +## 1. Summary + +When a user holds multiple roles, Gravitino always enforces the union of all of them. A workload has no +way to run with a narrower subset of the access its identity could reach. + +This document proposes **role assumption** — the analog of Snowflake's `USE ROLE` and Hive's `SET ROLE`. +A caller declares which role(s) should be active for a request, Gravitino verifies the caller actually +holds them, and authorization is evaluated against only that active set. The feature can only *reduce* a +caller's effective permissions, never expand them. If no role is declared, behavior is exactly as it is +today. + +The mechanism is intentionally simple: a request header, `X-Gravitino-Active-Role`, carries the active +role(s), and the server narrows enforcement to match — across access checks, list results, and credential +vending alike. Section 3 defines the header and its values; Section 4 explains how the server enforces +it. Transport is the easy part — the common instinct is to treat this as "just a Trino change," but the +substance is server-side. + +--- + +## 2. Motivation + +### 2.1 The problem + +A pipeline or AI agent that only needs 5 tables still runs with access to every table (say 105) its +identity can reach. If that workload misbehaves — a logic bug, a bad query, a leaked credential, or an +LLM agent over-reaching — the blast radius is everything the identity could touch, and out-of-scope +access **succeeds silently** instead of being denied and surfaced. + +### 2.2 Why it matters now + +A few things make this worth doing now. It gives workloads real runtime least-privilege: a job can drop +to exactly the access it needs without anyone having to mint a separate narrowly-scoped identity for it. +It also produces a much cleaner audit signal — with narrowing on, out-of-scope access turns into a hard +deny you can alert on, instead of a successful-but-unexpected access buried in the logs. AI agents are +the sharpest version of the same need: you want an agent to operate inside a declared, minimal scope and +to fail the moment it steps outside it. There's also a concrete migration angle — Hive's SQL Standard +Authorization supports `SET ROLE`, so teams moving HMS tables to Iceberg behind Gravitino lose that +capability today, and this restores it. + +### 2.3 Goals + +- Let a caller narrow the active role set for the native authorization path (Iceberg REST + native + API). +- Guarantee narrowing is **subtractive only** — it can never grant access the caller lacks. +- Apply the narrowing consistently everywhere authorization is consulted: direct access checks **and** + list-result filtering **and** credential vending. +- Be **fully backward compatible**: no declared role ⇒ today's union behavior, byte-for-byte. + +### 2.4 Non-goals (initial) + +- Dynamic in-session `SET ROLE` switching mid-connection (deferred to a later phase — see Section 11). +- Narrowing for **pushdown-authorized** catalogs (Hive/JDBC via Ranger/JDBC plugins), where + enforcement happens in the external system — see Section 6. +- Changing how ownership is modeled (its *interaction* with narrowing is an explicit open decision — + see Section 5). +- Write/`CREATE` semantics (which role owns newly created objects) — flagged for forward-compat only. + +--- + +## 3. The active-role header + +The interface is a single request header: + +``` +X-Gravitino-Active-Role: <value> +``` + +The caller sets it to declare which of its roles should be active for that request. The server validates +the value against the roles the caller actually holds, then evaluates authorization against only those +roles. + +### 3.1 Accepted values + +A value is either a role name, a comma-separated list of role names, or one of the reserved keywords +`ALL` / `NONE`: + +| Value | Meaning | +|---|---| +| `<role>` (e.g. `analyst`) | Activate a single named role. | +| `<role>,<role>` (e.g. `analyst,reader`) | Activate a list of roles; effective access is the union of just these. | +| `ALL` | Activate every role the caller holds — identical to today's behavior. | +| `NONE` | Activate no roles; all role-derived access is denied. | Review Comment: NONE is the only way to request the empty active set: an absent header already means ALL, so without an explicit keyword there's no way to say "use none of my roles." It's useful for owner-only execution (a job/agent that should touch nothing its roles grant) and for verifying deny paths, and costs nothing — an empty set just means no role policies are consulted. I see similar pattern in snowflake USE SECONDARY ROLES as well: https://docs.snowflake.com/en/sql-reference/sql/use-secondary-roles This is not a top-priority to support for now, but we can do it as it's not that hard to support as well. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
