Skip to content

Pass users original role for impersonation#25371

Merged
kokosing merged 1 commit into
trinodb:masterfrom
homar:homar/add_set_original_role
Apr 10, 2025
Merged

Pass users original role for impersonation#25371
kokosing merged 1 commit into
trinodb:masterfrom
homar:homar/add_set_original_role

Conversation

@homar
Copy link
Copy Markdown
Member

@homar homar commented Mar 20, 2025

Description

Pass users original role for impersonation

Without this the way impersonation work is broken.
Considering followin scenarion

  • there are 2 users: alice and bob
  • there is a role alice_role that allows for bob impersonation

If alice sets alice_role and then calls SET SESSION AUTHORIZATION bob
access control will make a check canImpersonateUser, because alice_role
allows for that impersonation it will succeed.
However every next query will also call this canImpersonateUser check
and because alice_role is not assigned anymore it will fail every time.

The idea behind the fix is to pass roles of the original user, alice
from the example above, between server and clients using new headers
X-Trino-Set-Original-Roles. Then roles obtained in this way can be used
in the checkCanImpersonate to make sure it passes

Additional context and related issues

Release notes

( ) This is not user-visible or is docs only, and no release notes are required.
( ) Release notes are required. Please propose a release note for me.
(x) Release notes are required, with the following suggested text:

## Section 
* Fix impersonation access control when access is granted via through the role. [issue](https://github.com/trinodb/trino/issues/25166)

Fixes #25166

@cla-bot cla-bot Bot added the cla-signed label Mar 20, 2025
@github-actions github-actions Bot added the jdbc Relates to Trino JDBC driver label Mar 20, 2025
@homar homar force-pushed the homar/add_set_original_role branch 2 times, most recently from 32c54d4 to e1f25b2 Compare March 21, 2025 09:06
@github-actions github-actions Bot added the docs label Mar 21, 2025
@homar homar force-pushed the homar/add_set_original_role branch from e1f25b2 to e66a3e1 Compare March 21, 2025 09:09
@homar homar changed the title Homar/add set original role Pass users original role for impersonation Mar 21, 2025
@homar homar force-pushed the homar/add_set_original_role branch from e66a3e1 to bd91d3a Compare March 21, 2025 09:59
@kokosing
Copy link
Copy Markdown
Member

This relates to #25166

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How do we pass original user info?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Via sessionUser AFAIK, see

this.originalUser = Stream.of(session.getSessionUser(), session.getUser())

Comment thread core/trino-main/src/main/java/io/trino/execution/SetSessionAuthorizationTask.java Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

extract this lambda as method

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Optional collection is smelly. Can we remove the optional here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

ok so actually this is a little hack. The idea is to have one field instead of two to make code simpler.

  • if optional is empty this impersonation mechanism is disabled
  • it it is not empty but it doesn't contain checked role then impersonation check fails
  • if it contains role then impersonation is allowed.
    Alternatively you would need one variable to check if this mechanism is enabled at all and if it is enabled then a Set to check if specific role allows for impersonation.
    If you believe having 2 variables is better I will change.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Remove the comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Why? It is explains why it is done this way. Assuming we will stay with Optional<Set>>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see exactly the same in line below in java. I mean the comment is obvious. It is a nit btw.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

testImpersonationAllowedByRole

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Also this should be something that holds authorization trinity. You need to have subject, action (here it is know that it is impersonation) and entity. So you need to hold pair of who (subject) can impersonate who (entity). And subject here is an (user with his roles), entity is just user.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Why? That would make this much more complex. Here I only store roles that allow impersonations, this is for tests only and trino doesn't even have good support for roles in general..

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let's sync on that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I mean there is some thinking here in the class and you are introducing new concept of access control to this testing class which makes it harder. I would like us to reuse what we have and rewrite the test.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Add also testImpersonationAllowedByUser

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

What is the point? If I understand correctly there are such tests here: TestSetSessionAuthorization

The entire point of this change is to fix the scenario that is role based not user based.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How do these two differ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we have some utilities for that in trino-jdbc tests.

@homar homar force-pushed the homar/add_set_original_role branch from bd91d3a to 02a102f Compare March 21, 2025 21:34
@homar homar marked this pull request as ready for review March 24, 2025 13:37
@kokosing
Copy link
Copy Markdown
Member

kokosing commented Mar 28, 2025

@wendigo can you please take a look too?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

separate commit for the refactor or undo

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I wouldn't say it is a refactor but sure I will undo this

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It can depend on scope tests right?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please add more tests. For impersonation with user, with role none and all roles.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I am not sure I understand the part about impersonation with user :/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I mean when grant for impersonation is given to the user directly, not to the role.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

  1. This PR is about roles not grants, so I am not sure why this would matter here
  2. I am not sure I even know how to do that. TestingSystemSecurityMetadata doesn't support that and TestingAccessControlManager only supports denies

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see exactly the same in line below in java. I mean the comment is obvious. It is a nit btw.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let's sync on that.

@homar homar force-pushed the homar/add_set_original_role branch 2 times, most recently from c8dcf21 to 8d27298 Compare March 31, 2025 22:53
Without this the way impersonation work is broken.
Considering followin scenarion
- there are 2 users: alice and bob
- there is a role alice_role that allows for bob impersonation

If alice sets alice_role and then calls SET SESSION AUTHORIZATION `bob`
access control will make a check `canImpersonateUser`, because alice_role
allows for that impersonation it will succeed.
However every next query will also call this `canImpersonateUser` check
and because alice_role is not assigned anymore it will fail every time.

The idea behind the fix is to pass roles of the original user, alice
from the example above, between server and clients using new headers
X-Trino-Set-Original-Roles. Then roles obtained in this way can be used
in the checkCanImpersonate to make sure it passes.
@homar homar force-pushed the homar/add_set_original_role branch 3 times, most recently from 2b21afd to e5dda50 Compare April 8, 2025 07:25
@homar homar requested a review from kokosing April 8, 2025 10:58
Copy link
Copy Markdown
Member

@kokosing kokosing left a comment

Choose a reason for hiding this comment

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

Good job!

@kokosing kokosing merged commit 3b251c6 into trinodb:master Apr 10, 2025
286 of 289 checks passed
@github-actions github-actions Bot added this to the 475 milestone Apr 10, 2025
@kokosing
Copy link
Copy Markdown
Member

@homar let's rename original roles to authorization roles to match the authorization user term and terminology in #2512

Also let's add a test for RESET AUTHORIZATION to make sure authorization roles and user are cleared.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed docs jdbc Relates to Trino JDBC driver

Development

Successfully merging this pull request may close these issues.

Roles of original users are not persisted through SET SESSION AUTHORIZATION calls

2 participants