Skip to content

[#12095] feat(auth): parse X-Gravitino-Active-Roles into the request path#12096

Open
bharos wants to merge 4 commits into
apache:mainfrom
bharos:active-roles-wiring-11969
Open

[#12095] feat(auth): parse X-Gravitino-Active-Roles into the request path#12096
bharos wants to merge 4 commits into
apache:mainfrom
bharos:active-roles-wiring-11969

Conversation

@bharos

@bharos bharos commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Parse the X-Gravitino-Active-Roles header and carry the declared active roles on the UserPrincipal, so the narrowing from #11967 takes effect.

  • UserPrincipal: carry an immutable ActiveRoles (defaults to ALL) alongside the existing per-request accessToken; withActiveRoles() attaches the parsed value.
  • AuthenticationFilter: parse the header after authentication and attach it to the principal. A malformed value maps to 400 (the Lance filter maps the same).
  • AuthorizationRequestContext: read activeRoles from the current UserPrincipal, so every authorization decision uses the request's declaration.

Membership validation (403 for an unheld role) is metalake-scoped and follows in a later PR. Part of #11965.

Why are the changes needed?

#11967 added the narrowing enforcement, but nothing populated the active roles, so it never activated. This wires the header through the request path.

Does this PR introduce any user-facing change?

Yes, additive and backward compatible. A request may send X-Gravitino-Active-Roles: <role>[,<role>] | ALL | NONE to narrow the roles used for authorization; a malformed value returns 400. An absent header behaves as before (ALL).

How was this patch tested?

New unit tests for UserPrincipal.withActiveRoles, the filter's header parsing (valid / absent / malformed → 400), and AuthorizationRequestContext reading the active roles from the principal. Verified with the module test and spotlessCheck tasks for core, server-common, and lance-rest-server.

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown

Code Coverage Report

Overall Project 67.78% +0.04% 🟢
Files changed 81.56% 🟢

Module Coverage
aliyun 1.72% 🔴
api 47.82% 🟢
authorization-common 85.96% 🟢
aws 42.04% 🟢
azure 2.47% 🔴
catalog-common 9.92% 🔴
catalog-fileset 79.74% 🟢
catalog-glue 66.91% 🟢
catalog-hive 79.4% 🟢
catalog-jdbc-common 45.7% 🟢
catalog-jdbc-doris 81.72% 🟢
catalog-jdbc-mysql 79.33% 🟢
catalog-jdbc-postgresql 83.39% 🟢
catalog-jdbc-starrocks 79.16% 🟢
catalog-kafka 77.01% 🟢
catalog-lakehouse-generic 59.18% 🟢
catalog-lakehouse-hudi 79.1% 🟢
catalog-lakehouse-iceberg 85.93% 🟢
catalog-lakehouse-paimon 84.23% 🟢
catalog-model 77.72% 🟢
cli 44.5% 🟢
client-java 78.27% 🟢
common 51.95% 🟢
core 82.55% -0.04% 🟢
filesystem-hadoop3 77.28% 🟢
flink 0.0% 🔴
flink-common 47.09% 🟢
flink-runtime 0.0% 🔴
gcp 14.12% 🔴
hadoop-auth 68.0% 🟢
hadoop-common 12.7% 🔴
hive-metastore-common 53.4% 🟢
iceberg-common 64.65% 🟢
iceberg-rest-server 74.95% +0.31% 🟢
idp-basic 86.02% 🟢
integration-test-common 0.0% 🔴
jobs 66.17% 🟢
lance-common 20.67% 🔴
lance-rest-server 64.23% +1.73% 🟢
lineage 53.02% 🟢
optimizer 83.17% 🟢
optimizer-api 21.95% 🔴
server 85.92% 🟢
server-common 76.31% +0.2% 🟢
spark 28.57% 🔴
spark-common 46.01% 🟢
tencent 69.84% 🟢
trino-connector 40.29% 🟢
Files
Module File Coverage
core AuthorizationRequestContext.java 69.23% 🟢
UserPrincipal.java 68.75% 🟢
iceberg-rest-server IcebergExceptionMapper.java 98.15% 🟢
lance-rest-server LanceAuthenticationFilter.java 81.82% 🟢
server-common AuthenticationFilter.java 83.56% 🟢

@bharos
bharos force-pushed the active-roles-wiring-11969 branch 5 times, most recently from 05cae48 to 5ac66cc Compare July 20, 2026 20:41
@bharos bharos self-assigned this Jul 20, 2026
@bharos
bharos marked this pull request as ready for review July 20, 2026 20:46
@bharos
bharos requested a review from roryqi July 20, 2026 20:46
@bharos
bharos force-pushed the active-roles-wiring-11969 branch 2 times, most recently from f72d5e6 to a637b61 Compare July 20, 2026 20:52
* <p>Backed by a {@link ThreadLocal}; the value must be {@link #clear() cleared} when the request
* completes so it never leaks to the next request on a pooled thread.
*/
public final class ActiveRolesContext {

@roryqi roryqi Jul 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer moving this into UserPrincipal instead of thread local variable.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done , moved active roles onto UserPrincipal instead of a thread-local. Since UserPrincipal is immutable, withActiveRoles(...) returns a copy with the roles attached, and the filter binds that copy before doAs. Hope creating and returning a copy is OK here ? Otherwise please let me know if you think of any better way.

@bharos
bharos force-pushed the active-roles-wiring-11969 branch 2 times, most recently from 09388c5 to ac91af3 Compare July 21, 2026 18:34
…quest path

Parse the X-Gravitino-Active-Roles header once per request and carry the declared
active roles on the UserPrincipal, activating the narrowing enforcement.

- UserPrincipal: carry an immutable ActiveRoles (defaults to ALL) alongside the
  existing per-request accessToken; add withActiveRoles() to attach the parsed value.
- AuthenticationFilter: parse the header after authentication and attach it to the
  principal; a malformed value maps to 400 via IllegalActiveRolesException (the Lance
  filter maps the same).
- AuthorizationRequestContext: read activeRoles from the current UserPrincipal so
  every authorization decision uses the request's declaration.

Absent header behaves as ALL (no narrowing). Membership validation (403 for an
unheld role) is metalake-scoped and follows in a later PR. Part of apache#12095.
@bharos
bharos force-pushed the active-roles-wiring-11969 branch from ac91af3 to 27f2777 Compare July 21, 2026 18:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants